/[emacs]/emacs/src/w32fns.c
ViewVC logotype

Diff of /emacs/src/w32fns.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.173 by jasonr, Wed May 22 19:35:48 2002 UTC revision 1.173.2.1 by miles, Fri Apr 4 06:21:04 2003 UTC
# Line 52  Boston, MA 02111-1307, USA.  */ Line 52  Boston, MA 02111-1307, USA.  */
52  #include <shellapi.h>  #include <shellapi.h>
53  #include <ctype.h>  #include <ctype.h>
54    
55    #include <dlgs.h>
56    #define FILE_NAME_TEXT_FIELD edt1
57    
58    void syms_of_w32fns ();
59    void globals_of_w32fns ();
60    static void init_external_image_libraries ();
61    
62  extern void free_frame_menubar ();  extern void free_frame_menubar ();
 extern void x_compute_fringe_widths P_ ((struct frame *, int));  
63  extern double atof ();  extern double atof ();
64  extern int w32_console_toggle_lock_key P_ ((int, Lisp_Object));  extern int w32_console_toggle_lock_key P_ ((int, Lisp_Object));
65  extern void w32_menu_display_help P_ ((HWND, HMENU, UINT, UINT));  extern void w32_menu_display_help P_ ((HWND, HMENU, UINT, UINT));
# Line 61  extern void w32_free_menu_strings P_ ((H Line 67  extern void w32_free_menu_strings P_ ((H
67    
68  extern int quit_char;  extern int quit_char;
69    
 /* A definition of XColor for non-X frames.  */  
 #ifndef HAVE_X_WINDOWS  
 typedef struct {  
   unsigned long pixel;  
   unsigned short red, green, blue;  
   char flags;  
   char pad;  
 } XColor;  
 #endif  
   
70  extern char *lispy_function_keys[];  extern char *lispy_function_keys[];
71    
72  /* The gray bitmap `bitmaps/gray'.  This is done because w32term.c uses  /* The gray bitmap `bitmaps/gray'.  This is done because w32term.c uses
# Line 145  Lisp_Object Vw32_mouse_move_interval; Line 141  Lisp_Object Vw32_mouse_move_interval;
141  /* Flag to indicate if XBUTTON events should be passed on to Windows.  */  /* Flag to indicate if XBUTTON events should be passed on to Windows.  */
142  int w32_pass_extra_mouse_buttons_to_system;  int w32_pass_extra_mouse_buttons_to_system;
143    
 /* The name we're using in resource queries.  */  
 Lisp_Object Vx_resource_name;  
   
144  /* Non nil if no window manager is in use.  */  /* Non nil if no window manager is in use.  */
145  Lisp_Object Vx_no_window_manager;  Lisp_Object Vx_no_window_manager;
146    
# Line 159  int display_hourglass_p; Line 152  int display_hourglass_p;
152     over text or in the modeline.  */     over text or in the modeline.  */
153    
154  Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;  Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
155  Lisp_Object Vx_hourglass_pointer_shape, Vx_window_horizontal_drag_shape;  Lisp_Object Vx_hourglass_pointer_shape, Vx_window_horizontal_drag_shape, Vx_hand_shape;
156    
157  /* The shape when over mouse-sensitive text.  */  /* The shape when over mouse-sensitive text.  */
158    
159  Lisp_Object Vx_sensitive_text_pointer_shape;  Lisp_Object Vx_sensitive_text_pointer_shape;
160    
161    #ifndef IDC_HAND
162    #define IDC_HAND MAKEINTRESOURCE(32649)
163    #endif
164    
165  /* Color of chars displayed in cursor box.  */  /* Color of chars displayed in cursor box.  */
166    
167  Lisp_Object Vx_cursor_fore_pixel;  Lisp_Object Vx_cursor_fore_pixel;
# Line 199  Lisp_Object Vw32_charset_info_alist; Line 196  Lisp_Object Vw32_charset_info_alist;
196  #define VIETNAMESE_CHARSET 163  #define VIETNAMESE_CHARSET 163
197  #endif  #endif
198    
 Lisp_Object Qauto_raise;  
 Lisp_Object Qauto_lower;  
 Lisp_Object Qbar, Qhbar;  
 Lisp_Object Qborder_color;  
 Lisp_Object Qborder_width;  
 Lisp_Object Qbox;  
 Lisp_Object Qcursor_color;  
 Lisp_Object Qcursor_type;  
 Lisp_Object Qgeometry;  
 Lisp_Object Qicon_left;  
 Lisp_Object Qicon_top;  
 Lisp_Object Qicon_type;  
 Lisp_Object Qicon_name;  
 Lisp_Object Qinternal_border_width;  
 Lisp_Object Qleft;  
 Lisp_Object Qright;  
 Lisp_Object Qmouse_color;  
199  Lisp_Object Qnone;  Lisp_Object Qnone;
 Lisp_Object Qparent_id;  
 Lisp_Object Qscroll_bar_width;  
200  Lisp_Object Qsuppress_icon;  Lisp_Object Qsuppress_icon;
201  Lisp_Object Qundefined_color;  Lisp_Object Qundefined_color;
 Lisp_Object Qvertical_scroll_bars;  
 Lisp_Object Qvisibility;  
 Lisp_Object Qwindow_id;  
 Lisp_Object Qx_frame_parameter;  
 Lisp_Object Qx_resource_name;  
 Lisp_Object Quser_position;  
 Lisp_Object Quser_size;  
 Lisp_Object Qscreen_gamma;  
 Lisp_Object Qline_spacing;  
202  Lisp_Object Qcenter;  Lisp_Object Qcenter;
203  Lisp_Object Qcancel_timer;  Lisp_Object Qcancel_timer;
204  Lisp_Object Qhyper;  Lisp_Object Qhyper;
# Line 270  Lisp_Object Qw32_charset_mac; Line 239  Lisp_Object Qw32_charset_mac;
239  Lisp_Object Qw32_charset_unicode;  Lisp_Object Qw32_charset_unicode;
240  #endif  #endif
241    
 Lisp_Object Qfullscreen;  
 Lisp_Object Qfullwidth;  
 Lisp_Object Qfullheight;  
 Lisp_Object Qfullboth;  
   
 extern Lisp_Object Qtop;  
 extern Lisp_Object Qdisplay;  
   
242  /* State variables for emulating a three button mouse. */  /* State variables for emulating a three button mouse. */
243  #define LMOUSE 1  #define LMOUSE 1
244  #define MMOUSE 2  #define MMOUSE 2
# Line 291  static unsigned mouse_move_timer = 0; Line 252  static unsigned mouse_move_timer = 0;
252    
253  /* Window that is tracking the mouse.  */  /* Window that is tracking the mouse.  */
254  static HWND track_mouse_window;  static HWND track_mouse_window;
255  FARPROC track_mouse_event_fn;  
256    typedef BOOL (WINAPI * TrackMouseEvent_Proc) (
257        IN OUT LPTRACKMOUSEEVENT lpEventTrack
258        );
259    
260    TrackMouseEvent_Proc track_mouse_event_fn=NULL;
261    
262  /* W95 mousewheel handler */  /* W95 mousewheel handler */
263  unsigned int msh_mousewheel = 0;          unsigned int msh_mousewheel = 0;
264    
265  /* Timers */  /* Timers */
266  #define MOUSE_BUTTON_ID 1  #define MOUSE_BUTTON_ID 1
# Line 307  static unsigned menu_free_timer = 0; Line 273  static unsigned menu_free_timer = 0;
273    
274  /* The below are defined in frame.c.  */  /* The below are defined in frame.c.  */
275    
 extern Lisp_Object Qheight, Qminibuffer, Qname, Qonly, Qwidth;  
 extern Lisp_Object Qunsplittable, Qmenu_bar_lines, Qbuffer_predicate, Qtitle;  
 extern Lisp_Object Qtool_bar_lines;  
   
276  extern Lisp_Object Vwindow_system_version;  extern Lisp_Object Vwindow_system_version;
277    
 Lisp_Object Qface_set_after_frame_default;  
   
278  #ifdef GLYPH_DEBUG  #ifdef GLYPH_DEBUG
279  int image_cache_refcount, dpyinfo_refcount;  int image_cache_refcount, dpyinfo_refcount;
280  #endif  #endif
# Line 344  check_w32 () Line 304  check_w32 ()
304    
305  /* Nonzero if we can use mouse menus.  /* Nonzero if we can use mouse menus.
306     You should not call this unless HAVE_MENUS is defined.  */     You should not call this unless HAVE_MENUS is defined.  */
307      
308  int  int
309  have_menus_p ()  have_menus_p ()
310  {  {
# Line 369  check_x_frame (frame) Line 329  check_x_frame (frame)
329    return f;    return f;
330  }  }
331    
332  /* Let the user specify an display with a frame.  /* Let the user specify a display with a frame.
333     nil stands for the selected frame--or, if that is not a w32 frame,     nil stands for the selected frame--or, if that is not a w32 frame,
334     the first display on the list.  */     the first display on the list.  */
335    
336  static struct w32_display_info *  struct w32_display_info *
337  check_x_display_info (frame)  check_x_display_info (frame)
338       Lisp_Object frame;       Lisp_Object frame;
339  {  {
340    if (NILP (frame))    if (NILP (frame))
341      {      {
342        struct frame *sf = XFRAME (selected_frame);        struct frame *sf = XFRAME (selected_frame);
343          
344        if (FRAME_W32_P (sf) && FRAME_LIVE_P (sf))        if (FRAME_W32_P (sf) && FRAME_LIVE_P (sf))
345          return FRAME_W32_DISPLAY_INFO (sf);          return FRAME_W32_DISPLAY_INFO (sf);
346        else        else
# Line 568  x_create_bitmap_from_file (f, file) Line 528  x_create_bitmap_from_file (f, file)
528      {      {
529        if (dpyinfo->bitmaps[id].refcount        if (dpyinfo->bitmaps[id].refcount
530            && dpyinfo->bitmaps[id].file            && dpyinfo->bitmaps[id].file
531            && !strcmp (dpyinfo->bitmaps[id].file, (char *) XSTRING (file)->data))            && !strcmp (dpyinfo->bitmaps[id].file, (char *) SDATA (file)))
532          {          {
533            ++dpyinfo->bitmaps[id].refcount;            ++dpyinfo->bitmaps[id].refcount;
534            return id + 1;            return id + 1;
# Line 581  x_create_bitmap_from_file (f, file) Line 541  x_create_bitmap_from_file (f, file)
541      return -1;      return -1;
542    emacs_close (fd);    emacs_close (fd);
543    
544    filename = (char *) XSTRING (found)->data;    filename = (char *) SDATA (found);
545    
546    hinst = LoadLibraryEx (filename, NULL, LOAD_LIBRARY_AS_DATAFILE);    hinst = LoadLibraryEx (filename, NULL, LOAD_LIBRARY_AS_DATAFILE);
547    
548    if (hinst == NULL)    if (hinst == NULL)
549        return -1;        return -1;
550    
551      
552    result = XReadBitmapFile (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),    result = XReadBitmapFile (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
553                              filename, &width, &height, &bitmap, &xhot, &yhot);                              filename, &width, &height, &bitmap, &xhot, &yhot);
554    if (result != BitmapSuccess)    if (result != BitmapSuccess)
# Line 597  x_create_bitmap_from_file (f, file) Line 557  x_create_bitmap_from_file (f, file)
557    id = x_allocate_bitmap_record (f);    id = x_allocate_bitmap_record (f);
558    dpyinfo->bitmaps[id - 1].pixmap = bitmap;    dpyinfo->bitmaps[id - 1].pixmap = bitmap;
559    dpyinfo->bitmaps[id - 1].refcount = 1;    dpyinfo->bitmaps[id - 1].refcount = 1;
560    dpyinfo->bitmaps[id - 1].file = (char *) xmalloc (XSTRING (file)->size + 1);    dpyinfo->bitmaps[id - 1].file = (char *) xmalloc (SCHARS (file) + 1);
561    dpyinfo->bitmaps[id - 1].depth = 1;    dpyinfo->bitmaps[id - 1].depth = 1;
562    dpyinfo->bitmaps[id - 1].height = height;    dpyinfo->bitmaps[id - 1].height = height;
563    dpyinfo->bitmaps[id - 1].width = width;    dpyinfo->bitmaps[id - 1].width = width;
564    strcpy (dpyinfo->bitmaps[id - 1].file, XSTRING (file)->data);    strcpy (dpyinfo->bitmaps[id - 1].file, SDATA (file));
565    
566    return id;    return id;
567  #endif  /* TODO */  #endif  /* TODO */
# Line 650  x_destroy_all_bitmaps (dpyinfo) Line 610  x_destroy_all_bitmaps (dpyinfo)
610    dpyinfo->bitmaps_last = 0;    dpyinfo->bitmaps_last = 0;
611  }  }
612    
 /* Connect the frame-parameter names for W32 frames  
    to the ways of passing the parameter values to the window system.  
   
    The name of a parameter, as a Lisp symbol,  
    has an `x-frame-parameter' property which is an integer in Lisp  
    but can be interpreted as an `enum x_frame_parm' in C.  */  
   
 enum x_frame_parm  
 {  
   X_PARM_FOREGROUND_COLOR,  
   X_PARM_BACKGROUND_COLOR,  
   X_PARM_MOUSE_COLOR,  
   X_PARM_CURSOR_COLOR,  
   X_PARM_BORDER_COLOR,  
   X_PARM_ICON_TYPE,  
   X_PARM_FONT,  
   X_PARM_BORDER_WIDTH,  
   X_PARM_INTERNAL_BORDER_WIDTH,  
   X_PARM_NAME,  
   X_PARM_AUTORAISE,  
   X_PARM_AUTOLOWER,  
   X_PARM_VERT_SCROLL_BAR,  
   X_PARM_VISIBILITY,  
   X_PARM_MENU_BAR_LINES  
 };  
   
   
 struct x_frame_parm_table  
 {  
   char *name;  
   void (*setter) P_ ((struct frame *, Lisp_Object, Lisp_Object));  
 };  
   
613  BOOL my_show_window P_ ((struct frame *, HWND, int));  BOOL my_show_window P_ ((struct frame *, HWND, int));
614  void my_set_window_pos P_ ((HWND, HWND, int, int, int, int, UINT));  void my_set_window_pos P_ ((HWND, HWND, int, int, int, int, UINT));
615  static Lisp_Object unwind_create_frame P_ ((Lisp_Object));  static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
616  static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));  static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
617  static void x_change_window_heights P_ ((Lisp_Object, int));  
618  /* TODO: Native Input Method support; see x_create_im.  */  /* TODO: Native Input Method support; see x_create_im.  */
619  void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));  void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
 static void x_set_line_spacing P_ ((struct frame *, Lisp_Object, Lisp_Object));  
 static void x_set_fullscreen P_ ((struct frame *, Lisp_Object, Lisp_Object));  
620  void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));  void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
621  void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));  void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
622  void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));  void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
# Line 699  void x_set_border_color P_ ((struct fram Line 624  void x_set_border_color P_ ((struct fram
624  void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));  void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
625  void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));  void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
626  void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));  void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_font P_ ((struct frame *, Lisp_Object, Lisp_Object));  
 static void x_set_fringe_width P_ ((struct frame *, Lisp_Object, Lisp_Object));  
 void x_set_border_width P_ ((struct frame *, Lisp_Object, Lisp_Object));  
 void x_set_internal_border_width P_ ((struct frame *, Lisp_Object,  
                                       Lisp_Object));  
627  void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));  void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_autoraise P_ ((struct frame *, Lisp_Object, Lisp_Object));  
 void x_set_autolower P_ ((struct frame *, Lisp_Object, Lisp_Object));  
 void x_set_vertical_scroll_bars P_ ((struct frame *, Lisp_Object,  
                                      Lisp_Object));  
 void x_set_visibility P_ ((struct frame *, Lisp_Object, Lisp_Object));  
628  void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));  void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_scroll_bar_width P_ ((struct frame *, Lisp_Object, Lisp_Object));  
629  void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));  void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
 void x_set_unsplittable P_ ((struct frame *, Lisp_Object, Lisp_Object));  
630  void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));  void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
 static void x_set_screen_gamma P_ ((struct frame *, Lisp_Object, Lisp_Object));  
631  static void x_edge_detection P_ ((struct frame *, struct image *, Lisp_Object,  static void x_edge_detection P_ ((struct frame *, struct image *, Lisp_Object,
632                                    Lisp_Object));                                    Lisp_Object));
633    
 static struct x_frame_parm_table x_frame_parms[] =  
 {  
   {"auto-raise", x_set_autoraise},  
   {"auto-lower", x_set_autolower},  
   {"background-color", x_set_background_color},  
   {"border-color", x_set_border_color},  
   {"border-width", x_set_border_width},  
   {"cursor-color", x_set_cursor_color},  
   {"cursor-type", x_set_cursor_type},  
   {"font", x_set_font},  
   {"foreground-color", x_set_foreground_color},  
   {"icon-name", x_set_icon_name},  
   {"icon-type", x_set_icon_type},  
   {"internal-border-width", x_set_internal_border_width},  
   {"menu-bar-lines", x_set_menu_bar_lines},  
   {"mouse-color", x_set_mouse_color},  
   {"name", x_explicitly_set_name},  
   {"scroll-bar-width", x_set_scroll_bar_width},  
   {"title", x_set_title},  
   {"unsplittable", x_set_unsplittable},  
   {"vertical-scroll-bars", x_set_vertical_scroll_bars},  
   {"visibility", x_set_visibility},  
   {"tool-bar-lines", x_set_tool_bar_lines},  
   {"screen-gamma", x_set_screen_gamma},  
   {"line-spacing", x_set_line_spacing},  
   {"left-fringe", x_set_fringe_width},  
   {"right-fringe", x_set_fringe_width},  
   {"fullscreen", x_set_fullscreen},  
 };  
   
 /* Attach the `x-frame-parameter' properties to  
    the Lisp symbol names of parameters relevant to W32.  */  
   
 void  
 init_x_parm_symbols ()  
 {  
   int i;  
634    
   for (i = 0; i < sizeof (x_frame_parms) / sizeof (x_frame_parms[0]); i++)  
     Fput (intern (x_frame_parms[i].name), Qx_frame_parameter,  
           make_number (i));  
 }  
635    
 /* Really try to move where we want to be in case of fullscreen.  Some WMs  
    moves the window where we tell them.  Some (mwm, twm) moves the outer  
    window manager window there instead.  
    Try to compensate for those WM here. */  
 static void  
 x_fullscreen_move (f, new_top, new_left)  
      struct frame *f;  
      int new_top;  
      int new_left;  
 {  
   if (new_top != f->output_data.w32->top_pos  
       || new_left != f->output_data.w32->left_pos)  
     {  
       int move_x = new_left;  
       int move_y = new_top;  
   
       f->output_data.w32->want_fullscreen |= FULLSCREEN_MOVE_WAIT;  
       x_set_offset (f, move_x, move_y, 1);  
     }  
 }  
   
 /* Change the parameters of frame F as specified by ALIST.  
    If a parameter is not specially recognized, do nothing;  
    otherwise call the `x_set_...' function for that parameter.  */  
   
 void  
 x_set_frame_parameters (f, alist)  
      FRAME_PTR f;  
      Lisp_Object alist;  
 {  
   Lisp_Object tail;  
   
   /* If both of these parameters are present, it's more efficient to  
      set them both at once.  So we wait until we've looked at the  
      entire list before we set them.  */  
   int width, height;  
   
   /* Same here.  */  
   Lisp_Object left, top;  
   
   /* Same with these.  */  
   Lisp_Object icon_left, icon_top;  
   
   /* Record in these vectors all the parms specified.  */  
   Lisp_Object *parms;  
   Lisp_Object *values;  
   int i, p;  
   int left_no_change = 0, top_no_change = 0;  
   int icon_left_no_change = 0, icon_top_no_change = 0;  
   int fullscreen_is_being_set = 0;  
   
   struct gcpro gcpro1, gcpro2;  
   
   i = 0;  
   for (tail = alist; CONSP (tail); tail = Fcdr (tail))  
     i++;  
   
   parms = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));  
   values = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));  
   
   /* Extract parm names and values into those vectors.  */  
   
   i = 0;  
   for (tail = alist; CONSP (tail); tail = Fcdr (tail))  
     {  
       Lisp_Object elt;  
   
       elt = Fcar (tail);  
       parms[i] = Fcar (elt);  
       values[i] = Fcdr (elt);  
       i++;  
     }  
   /* TAIL and ALIST are not used again below here.  */  
   alist = tail = Qnil;  
   
   GCPRO2 (*parms, *values);  
   gcpro1.nvars = i;  
   gcpro2.nvars = i;  
   
   /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,  
      because their values appear in VALUES and strings are not valid.  */  
   top = left = Qunbound;  
   icon_left = icon_top = Qunbound;  
   
   /* Provide default values for HEIGHT and WIDTH.  */  
   if (FRAME_NEW_WIDTH (f))  
     width = FRAME_NEW_WIDTH (f);  
   else  
     width = FRAME_WIDTH (f);  
   
   if (FRAME_NEW_HEIGHT (f))  
     height = FRAME_NEW_HEIGHT (f);  
   else  
     height = FRAME_HEIGHT (f);  
   
   /* Process foreground_color and background_color before anything else.  
      They are independent of other properties, but other properties (e.g.,  
      cursor_color) are dependent upon them.  */  
   /* Process default font as well, since fringe widths depends on it.  */  
   for (p = 0; p < i; p++)  
     {  
       Lisp_Object prop, val;  
   
       prop = parms[p];  
       val = values[p];  
       if (EQ (prop, Qforeground_color)  
           || EQ (prop, Qbackground_color)  
           || EQ (prop, Qfont)  
           || EQ (prop, Qfullscreen))  
         {  
           register Lisp_Object param_index, old_value;  
   
           old_value = get_frame_param (f, prop);  
           fullscreen_is_being_set |= EQ (prop, Qfullscreen);  
   
           if (NILP (Fequal (val, old_value)))  
             {  
               store_frame_param (f, prop, val);  
                 
               param_index = Fget (prop, Qx_frame_parameter);  
               if (NATNUMP (param_index)  
                   && (XFASTINT (param_index)  
                       < sizeof (x_frame_parms)/sizeof (x_frame_parms[0])))  
                 (*x_frame_parms[XINT (param_index)].setter)(f, val, old_value);  
             }  
         }  
     }  
   
   /* Now process them in reverse of specified order.  */  
   for (i--; i >= 0; i--)  
     {  
       Lisp_Object prop, val;  
   
       prop = parms[i];  
       val = values[i];  
   
       if (EQ (prop, Qwidth) && NUMBERP (val))  
         width = XFASTINT (val);  
       else if (EQ (prop, Qheight) && NUMBERP (val))  
         height = XFASTINT (val);  
       else if (EQ (prop, Qtop))  
         top = val;  
       else if (EQ (prop, Qleft))  
         left = val;  
       else if (EQ (prop, Qicon_top))  
         icon_top = val;  
       else if (EQ (prop, Qicon_left))  
         icon_left = val;  
       else if (EQ (prop, Qforeground_color)  
                || EQ (prop, Qbackground_color)  
                || EQ (prop, Qfont)  
                || EQ (prop, Qfullscreen))  
         /* Processed above.  */  
         continue;  
       else  
         {  
           register Lisp_Object param_index, old_value;  
   
           old_value = get_frame_param (f, prop);  
   
           store_frame_param (f, prop, val);  
   
           param_index = Fget (prop, Qx_frame_parameter);  
           if (NATNUMP (param_index)  
               && (XFASTINT (param_index)  
                   < sizeof (x_frame_parms)/sizeof (x_frame_parms[0])))  
             (*x_frame_parms[XINT (param_index)].setter)(f, val, old_value);  
         }  
     }  
   
   /* Don't die if just one of these was set.  */  
   if (EQ (left, Qunbound))  
     {  
       left_no_change = 1;  
       if (f->output_data.w32->left_pos < 0)  
         left = Fcons (Qplus, Fcons (make_number (f->output_data.w32->left_pos), Qnil));  
       else  
         XSETINT (left, f->output_data.w32->left_pos);  
     }  
   if (EQ (top, Qunbound))  
     {  
       top_no_change = 1;  
       if (f->output_data.w32->top_pos < 0)  
         top = Fcons (Qplus, Fcons (make_number (f->output_data.w32->top_pos), Qnil));  
       else  
         XSETINT (top, f->output_data.w32->top_pos);  
     }  
   
   /* If one of the icon positions was not set, preserve or default it.  */  
   if (EQ (icon_left, Qunbound) || ! INTEGERP (icon_left))  
     {  
       icon_left_no_change = 1;  
       icon_left = Fcdr (Fassq (Qicon_left, f->param_alist));  
       if (NILP (icon_left))  
         XSETINT (icon_left, 0);  
     }  
   if (EQ (icon_top, Qunbound) || ! INTEGERP (icon_top))  
     {  
       icon_top_no_change = 1;  
       icon_top = Fcdr (Fassq (Qicon_top, f->param_alist));  
       if (NILP (icon_top))  
         XSETINT (icon_top, 0);  
     }  
   
   if (FRAME_VISIBLE_P (f) && fullscreen_is_being_set)  
     {  
             /* If the frame is visible already and the fullscreen parameter is  
          being set, it is too late to set WM manager hints to specify  
          size and position.  
          Here we first get the width, height and position that applies to  
          fullscreen.  We then move the frame to the appropriate  
          position.  Resize of the frame is taken care of in the code after  
          this if-statement. */  
       int new_left, new_top;  
         
       x_fullscreen_adjust (f, &width, &height, &new_top, &new_left);  
       x_fullscreen_move (f, new_top, new_left);  
     }  
   
   /* Don't set these parameters unless they've been explicitly  
      specified.  The window might be mapped or resized while we're in  
      this function, and we don't want to override that unless the lisp  
      code has asked for it.  
   
      Don't set these parameters unless they actually differ from the  
      window's current parameters; the window may not actually exist  
      yet.  */  
   {  
     Lisp_Object frame;  
   
     check_frame_size (f, &height, &width);  
   
     XSETFRAME (frame, f);  
   
     if (width != FRAME_WIDTH (f)  
         || height != FRAME_HEIGHT (f)  
         || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))  
       Fset_frame_size (frame, make_number (width), make_number (height));  
   
     if ((!NILP (left) || !NILP (top))  
         && ! (left_no_change && top_no_change)  
         && ! (NUMBERP (left) && XINT (left) == f->output_data.w32->left_pos  
               && NUMBERP (top) && XINT (top) == f->output_data.w32->top_pos))  
       {  
         int leftpos = 0;  
         int toppos = 0;  
   
         /* Record the signs.  */  
         f->output_data.w32->size_hint_flags &= ~ (XNegative | YNegative);  
         if (EQ (left, Qminus))  
           f->output_data.w32->size_hint_flags |= XNegative;  
         else if (INTEGERP (left))  
           {  
             leftpos = XINT (left);  
             if (leftpos < 0)  
               f->output_data.w32->size_hint_flags |= XNegative;  
           }  
         else if (CONSP (left) && EQ (XCAR (left), Qminus)  
                  && CONSP (XCDR (left))  
                  && INTEGERP (XCAR (XCDR (left))))  
           {  
             leftpos = - XINT (XCAR (XCDR (left)));  
             f->output_data.w32->size_hint_flags |= XNegative;  
           }  
         else if (CONSP (left) && EQ (XCAR (left), Qplus)  
                  && CONSP (XCDR (left))  
                  && INTEGERP (XCAR (XCDR (left))))  
           {  
             leftpos = XINT (XCAR (XCDR (left)));  
           }  
   
         if (EQ (top, Qminus))  
           f->output_data.w32->size_hint_flags |= YNegative;  
         else if (INTEGERP (top))  
           {  
             toppos = XINT (top);  
             if (toppos < 0)  
               f->output_data.w32->size_hint_flags |= YNegative;  
           }  
         else if (CONSP (top) && EQ (XCAR (top), Qminus)  
                  && CONSP (XCDR (top))  
                  && INTEGERP (XCAR (XCDR (top))))  
           {  
             toppos = - XINT (XCAR (XCDR (top)));  
             f->output_data.w32->size_hint_flags |= YNegative;  
           }  
         else if (CONSP (top) && EQ (XCAR (top), Qplus)  
                  && CONSP (XCDR (top))  
                  && INTEGERP (XCAR (XCDR (top))))  
           {  
             toppos = XINT (XCAR (XCDR (top)));  
           }  
   
   
         /* Store the numeric value of the position.  */  
         f->output_data.w32->top_pos = toppos;  
         f->output_data.w32->left_pos = leftpos;  
   
         f->output_data.w32->win_gravity = NorthWestGravity;  
   
         /* Actually set that position, and convert to absolute.  */  
         x_set_offset (f, leftpos, toppos, -1);  
       }  
   
     if ((!NILP (icon_left) || !NILP (icon_top))  
         && ! (icon_left_no_change && icon_top_no_change))  
       x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));  
   }  
   
   UNGCPRO;  
 }  
636    
637  /* Store the screen positions of frame F into XPTR and YPTR.  /* Store the screen positions of frame F into XPTR and YPTR.
638     These are the positions of the containing window manager window,     These are the positions of the containing window manager window,
# Line 1102  x_real_positions (f, xptr, yptr) Line 662  x_real_positions (f, xptr, yptr)
662    *yptr = pt.y;    *yptr = pt.y;
663  }  }
664    
 /* Insert a description of internally-recorded parameters of frame X  
    into the parameter alist *ALISTPTR that is to be given to the user.  
    Only parameters that are specific to W32  
    and whose values are not correctly recorded in the frame's  
    param_alist need to be considered here.  */  
   
 void  
 x_report_frame_params (f, alistptr)  
      struct frame *f;  
      Lisp_Object *alistptr;  
 {  
   char buf[16];  
   Lisp_Object tem;  
   
   /* Represent negative positions (off the top or left screen edge)  
      in a way that Fmodify_frame_parameters will understand correctly.  */  
   XSETINT (tem, f->output_data.w32->left_pos);  
   if (f->output_data.w32->left_pos >= 0)  
     store_in_alist (alistptr, Qleft, tem);  
   else  
     store_in_alist (alistptr, Qleft, Fcons (Qplus, Fcons (tem, Qnil)));  
   
   XSETINT (tem, f->output_data.w32->top_pos);  
   if (f->output_data.w32->top_pos >= 0)  
     store_in_alist (alistptr, Qtop, tem);  
   else  
     store_in_alist (alistptr, Qtop, Fcons (Qplus, Fcons (tem, Qnil)));  
   
   store_in_alist (alistptr, Qborder_width,  
            make_number (f->output_data.w32->border_width));  
   store_in_alist (alistptr, Qinternal_border_width,  
            make_number (f->output_data.w32->internal_border_width));  
   store_in_alist (alistptr, Qleft_fringe,  
            make_number (f->output_data.w32->left_fringe_width));  
   store_in_alist (alistptr, Qright_fringe,  
            make_number (f->output_data.w32->right_fringe_width));  
   store_in_alist (alistptr, Qscroll_bar_width,  
            make_number (FRAME_HAS_VERTICAL_SCROLL_BARS (f)  
                         ? FRAME_SCROLL_BAR_PIXEL_WIDTH(f)  
                         : 0));  
   sprintf (buf, "%ld", (long) FRAME_W32_WINDOW (f));  
   store_in_alist (alistptr, Qwindow_id,  
            build_string (buf));  
   store_in_alist (alistptr, Qicon_name, f->icon_name);  
   FRAME_SAMPLE_VISIBILITY (f);  
   store_in_alist (alistptr, Qvisibility,  
                   (FRAME_VISIBLE_P (f) ? Qt  
                    : FRAME_ICONIFIED_P (f) ? Qicon : Qnil));  
   store_in_alist (alistptr, Qdisplay,  
                   XCAR (FRAME_W32_DISPLAY_INFO (f)->name_list_element));  
 }  
665    
666    
667  DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color,  DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color,
# Line 1213  where R,G,B are numbers between 0 and 25 Line 722  where R,G,B are numbers between 0 and 25
722    CHECK_STRING (filename);    CHECK_STRING (filename);
723    abspath = Fexpand_file_name (filename, Qnil);    abspath = Fexpand_file_name (filename, Qnil);
724    
725    fp = fopen (XSTRING (filename)->data, "rt");    fp = fopen (SDATA (filename), "rt");
726    if (fp)    if (fp)
727      {      {
728        char buf[512];        char buf[512];
# Line 1243  where R,G,B are numbers between 0 and 25 Line 752  where R,G,B are numbers between 0 and 25
752  }  }
753    
754  /* The default colors for the w32 color map */  /* The default colors for the w32 color map */
755  typedef struct colormap_t  typedef struct colormap_t
756  {  {
757    char *name;    char *name;
758    COLORREF colorref;    COLORREF colorref;
759  } colormap_t;  } colormap_t;
760    
761  colormap_t w32_color_map[] =  colormap_t w32_color_map[] =
762  {  {
763    {"snow"                      , PALETTERGB (255,250,250)},    {"snow"                      , PALETTERGB (255,250,250)},
764    {"ghost white"               , PALETTERGB (248,248,255)},    {"ghost white"               , PALETTERGB (248,248,255)},
# Line 1500  DEFUN ("w32-default-color-map", Fw32_def Line 1009  DEFUN ("w32-default-color-map", Fw32_def
1009    int i;    int i;
1010    colormap_t *pc = w32_color_map;    colormap_t *pc = w32_color_map;
1011    Lisp_Object cmap;    Lisp_Object cmap;
1012      
1013    BLOCK_INPUT;    BLOCK_INPUT;
1014      
1015    cmap = Qnil;    cmap = Qnil;
1016      
1017    for (i = 0; i < sizeof (w32_color_map) / sizeof (w32_color_map[0]);    for (i = 0; i < sizeof (w32_color_map) / sizeof (w32_color_map[0]);
1018         pc++, i++)         pc++, i++)
1019      cmap = Fcons (Fcons (build_string (pc->name),      cmap = Fcons (Fcons (build_string (pc->name),
1020                           make_number (pc->colorref)),                           make_number (pc->colorref)),
1021                    cmap);                    cmap);
1022      
1023    UNBLOCK_INPUT;    UNBLOCK_INPUT;
1024      
1025    return (cmap);    return (cmap);
1026  }  }
1027    
1028  Lisp_Object  Lisp_Object
1029  w32_to_x_color (rgb)  w32_to_x_color (rgb)
1030       Lisp_Object rgb;       Lisp_Object rgb;
1031  {  {
1032    Lisp_Object color;    Lisp_Object color;
1033      
1034    CHECK_NUMBER (rgb);    CHECK_NUMBER (rgb);
1035      
1036    BLOCK_INPUT;    BLOCK_INPUT;
1037      
1038    color = Frassq (rgb, Vw32_color_map);    color = Frassq (rgb, Vw32_color_map);
1039      
1040    UNBLOCK_INPUT;    UNBLOCK_INPUT;
1041      
1042    if (!NILP (color))    if (!NILP (color))
1043      return (Fcar (color));      return (Fcar (color));
1044    else    else
# Line 1553  w32_color_map_lookup (colorname) Line 1062  w32_color_map_lookup (colorname)
1062    
1063        tem = Fcar (elt);        tem = Fcar (elt);
1064    
1065        if (lstrcmpi (XSTRING (tem)->data, colorname) == 0)        if (lstrcmpi (SDATA (tem), colorname) == 0)
1066          {          {
1067            ret = XUINT (Fcdr (elt));            ret = XUINT (Fcdr (elt));
1068            break;            break;
# Line 1568  w32_color_map_lookup (colorname) Line 1077  w32_color_map_lookup (colorname)
1077    return ret;    return ret;
1078  }  }
1079    
1080  COLORREF  COLORREF
1081  x_to_w32_color (colorname)  x_to_w32_color (colorname)
1082       char * colorname;       char * colorname;
1083  {  {
# Line 1582  x_to_w32_color (colorname) Line 1091  x_to_w32_color (colorname)
1091        char *color;        char *color;
1092        int size;        int size;
1093        color = colorname + 1;        color = colorname + 1;
1094          
1095        size = strlen(color);        size = strlen(color);
1096        if (size == 3 || size == 6 || size == 9 || size == 12)        if (size == 3 || size == 6 || size == 9 || size == 12)
1097          {          {
# Line 1591  x_to_w32_color (colorname) Line 1100  x_to_w32_color (colorname)
1100            pos = 0;            pos = 0;
1101            size /= 3;            size /= 3;
1102            colorval = 0;            colorval = 0;
1103              
1104            for (i = 0; i < 3; i++)            for (i = 0; i < 3; i++)
1105              {              {
1106                char *end;                char *end;
# Line 1647  x_to_w32_color (colorname) Line 1156  x_to_w32_color (colorname)
1156          {          {
1157            char *end;            char *end;
1158            unsigned long value;            unsigned long value;
1159              
1160            /* The check for 'x' in the following conditional takes into            /* The check for 'x' in the following conditional takes into
1161               account the fact that strtol allows a "0x" in front of               account the fact that strtol allows a "0x" in front of
1162               our numbers, and we don't.  */               our numbers, and we don't.  */
# Line 1710  x_to_w32_color (colorname) Line 1219  x_to_w32_color (colorname)
1219            if (value < 0.0 || value > 1.0)            if (value < 0.0 || value > 1.0)
1220              break;              break;
1221            val = (UINT)(0x100 * value);            val = (UINT)(0x100 * value);
1222            /* We used 0x100 instead of 0xFF to give an continuous            /* We used 0x100 instead of 0xFF to give a continuous
1223               range between 0.0 and 1.0 inclusive.  The next statement               range between 0.0 and 1.0 inclusive.  The next statement
1224               fixes the 1.0 case.  */               fixes the 1.0 case.  */
1225            if (val == 0x100)            if (val == 0x100)
# Line 1734  x_to_w32_color (colorname) Line 1243  x_to_w32_color (colorname)
1243       RGB.  */       RGB.  */
1244    
1245    /* If we fail to lookup the color name in w32_color_map, then check the    /* If we fail to lookup the color name in w32_color_map, then check the
1246       colorname to see if it can be crudely approximated: If the X color       colorname to see if it can be crudely approximated: If the X color
1247       ends in a number (e.g., "darkseagreen2"), strip the number and       ends in a number (e.g., "darkseagreen2"), strip the number and
1248       return the result of looking up the base color name.  */       return the result of looking up the base color name.  */
1249    ret = w32_color_map_lookup (colorname);    ret = w32_color_map_lookup (colorname);
1250    if (NILP (ret))    if (NILP (ret))
1251      {      {
1252        int len = strlen (colorname);        int len = strlen (colorname);
1253    
1254        if (isdigit (colorname[len - 1]))        if (isdigit (colorname[len - 1]))
1255          {          {
1256            char *ptr, *approx = alloca (len + 1);            char *ptr, *approx = alloca (len + 1);
1257    
1258            strcpy (approx, colorname);            strcpy (approx, colorname);
1259            ptr = &approx[len - 1];            ptr = &approx[len - 1];
1260            while (ptr > approx && isdigit (*ptr))            while (ptr > approx && isdigit (*ptr))
1261                *ptr-- = '\0';                *ptr-- = '\0';
1262    
1263            ret = w32_color_map_lookup (approx);            ret = w32_color_map_lookup (approx);
1264          }          }
1265      }      }
1266      
1267    UNBLOCK_INPUT;    UNBLOCK_INPUT;
1268    return ret;    return ret;
1269  }  }
# Line 1909  w32_defined_color (f, color, color_def, Line 1418  w32_defined_color (f, color, color_def,
1418    
1419    tem = x_to_w32_color (color);    tem = x_to_w32_color (color);
1420    
1421    if (!NILP (tem))    if (!NILP (tem))
1422      {      {
1423        if (f)        if (f)
1424          {          {
# Line 1926  w32_defined_color (f, color, color_def, Line 1435  w32_defined_color (f, color, color_def,
1435              one_w32_display_info.color_list;              one_w32_display_info.color_list;
1436            struct w32_palette_entry ** prev =            struct w32_palette_entry ** prev =
1437              &one_w32_display_info.color_list;              &one_w32_display_info.color_list;
1438          
1439            /* check if color is already mapped */            /* check if color is already mapped */
1440            while (entry)            while (entry)
1441              {              {
# Line 1956  w32_defined_color (f, color, color_def, Line 1465  w32_defined_color (f, color, color_def,
1465        w32_color_ref = XUINT (tem) | 0x2000000;        w32_color_ref = XUINT (tem) | 0x2000000;
1466    
1467        color_def->pixel = w32_color_ref;        color_def->pixel = w32_color_ref;
1468        color_def->red = GetRValue (w32_color_ref);        color_def->red = GetRValue (w32_color_ref) * 256;
1469        color_def->green = GetGValue (w32_color_ref);        color_def->green = GetGValue (w32_color_ref) * 256;
1470        color_def->blue = GetBValue (w32_color_ref);        color_def->blue = GetBValue (w32_color_ref) * 256;
1471    
1472        return 1;        return 1;
1473      }      }
1474    else    else
1475      {      {
1476        return 0;        return 0;
1477      }      }
# Line 1983  x_decode_color (f, arg, def) Line 1492  x_decode_color (f, arg, def)
1492    
1493    CHECK_STRING (arg);    CHECK_STRING (arg);
1494    
1495    if (strcmp (XSTRING (arg)->data, "black") == 0)    if (strcmp (SDATA (arg), "black") == 0)
1496      return BLACK_PIX_DEFAULT (f);      return BLACK_PIX_DEFAULT (f);
1497    else if (strcmp (XSTRING (arg)->data, "white") == 0)    else if (strcmp (SDATA (arg), "white") == 0)
1498      return WHITE_PIX_DEFAULT (f);      return WHITE_PIX_DEFAULT (f);
1499    
1500    if ((FRAME_W32_DISPLAY_INFO (f)->n_planes * FRAME_W32_DISPLAY_INFO (f)->n_cbits) == 1)    if ((FRAME_W32_DISPLAY_INFO (f)->n_planes * FRAME_W32_DISPLAY_INFO (f)->n_cbits) == 1)
# Line 1993  x_decode_color (f, arg, def) Line 1502  x_decode_color (f, arg, def)
1502    
1503    /* w32_defined_color is responsible for coping with failures    /* w32_defined_color is responsible for coping with failures
1504       by looking for a near-miss.  */       by looking for a near-miss.  */
1505    if (w32_defined_color (f, XSTRING (arg)->data, &cdef, 1))    if (w32_defined_color (f, SDATA (arg), &cdef, 1))
1506      return cdef.pixel;      return cdef.pixel;
1507    
1508    /* defined_color failed; return an ultimate default.  */    /* defined_color failed; return an ultimate default.  */
1509    return def;    return def;
1510  }  }
1511    
 /* Change the `line-spacing' frame parameter of frame F.  OLD_VALUE is  
    the previous value of that parameter, NEW_VALUE is the new value.  */  
   
 static void  
 x_set_line_spacing (f, new_value, old_value)  
      struct frame *f;  
      Lisp_Object new_value, old_value;  
 {  
   if (NILP (new_value))  
     f->extra_line_spacing = 0;  
   else if (NATNUMP (new_value))  
     f->extra_line_spacing = XFASTINT (new_value);  
   else  
     Fsignal (Qerror, Fcons (build_string ("Invalid line-spacing"),  
                             Fcons (new_value, Qnil)));  
   if (FRAME_VISIBLE_P (f))  
     redraw_frame (f);  
 }  
   
   
 /* Change the `fullscreen' frame parameter of frame F.  OLD_VALUE is  
    the previous value of that parameter, NEW_VALUE is the new value. */  
   
 static void  
 x_set_fullscreen (f, new_value, old_value)  
      struct frame *f;  
      Lisp_Object new_value, old_value;  
 {  
   if (NILP (new_value))  
     f->output_data.w32->want_fullscreen = FULLSCREEN_NONE;  
   else if (EQ (new_value, Qfullboth))  
     f->output_data.w32->want_fullscreen = FULLSCREEN_BOTH;  
   else if (EQ (new_value, Qfullwidth))  
     f->output_data.w32->want_fullscreen = FULLSCREEN_WIDTH;  
   else if (EQ (new_value, Qfullheight))  
     f->output_data.w32->want_fullscreen = FULLSCREEN_HEIGHT;  
 }  
   
   
 /* Change the `screen-gamma' frame parameter of frame F.  OLD_VALUE is  
    the previous value of that parameter, NEW_VALUE is the new value.  */  
   
 static void  
 x_set_screen_gamma (f, new_value, old_value)  
      struct frame *f;  
      Lisp_Object new_value, old_value;  
 {  
   if (NILP (new_value))  
     f->gamma = 0;  
   else if (NUMBERP (new_value) && XFLOATINT (new_value) > 0)  
     /* The value 0.4545 is the normal viewing gamma.  */  
     f->gamma = 1.0 / (0.4545 * XFLOATINT (new_value));  
   else  
     Fsignal (Qerror, Fcons (build_string ("Invalid screen-gamma"),  
                             Fcons (new_value, Qnil)));  
   
   clear_face_cache (0);  
 }  
1512    
1513    
1514  /* Functions called only from `x_set_frame_param'  /* Functions called only from `x_set_frame_param'
# Line 2116  x_set_mouse_color (f, arg, oldval) Line 1567  x_set_mouse_color (f, arg, oldval)
1567       struct frame *f;       struct frame *f;
1568       Lisp_Object arg, oldval;       Lisp_Object arg, oldval;
1569  {  {
1570    Cursor cursor, nontext_cursor, mode_cursor, cross_cursor;    Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
1571    int count;    int count;
1572    int mask_color;    int mask_color;
1573    
# Line 2164  x_set_mouse_color (f, arg, oldval) Line 1615  x_set_mouse_color (f, arg, oldval)
1615    else    else
1616      hourglass_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_watch);      hourglass_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_watch);
1617    x_check_errors (FRAME_W32_DISPLAY (f), "bad busy pointer cursor: %s");    x_check_errors (FRAME_W32_DISPLAY (f), "bad busy pointer cursor: %s");
1618      
1619    x_check_errors (FRAME_W32_DISPLAY (f), "bad nontext pointer cursor: %s");    x_check_errors (FRAME_W32_DISPLAY (f), "bad nontext pointer cursor: %s");
1620    if (!EQ (Qnil, Vx_mode_pointer_shape))    if (!EQ (Qnil, Vx_mode_pointer_shape))
1621      {      {
# Line 2179  x_set_mouse_color (f, arg, oldval) Line 1630  x_set_mouse_color (f, arg, oldval)
1630    if (!EQ (Qnil, Vx_sensitive_text_pointer_shape))    if (!EQ (Qnil, Vx_sensitive_text_pointer_shape))
1631      {      {
1632        CHECK_NUMBER (Vx_sensitive_text_pointer_shape);        CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
1633        cross_cursor        hand_cursor
1634          = XCreateFontCursor (FRAME_W32_DISPLAY (f),          = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1635                               XINT (Vx_sensitive_text_pointer_shape));                               XINT (Vx_sensitive_text_pointer_shape));
1636      }      }
1637    else    else
1638      cross_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_crosshair);      hand_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_crosshair);
1639    
1640    if (!NILP (Vx_window_horizontal_drag_shape))    if (!NILP (Vx_window_horizontal_drag_shape))
1641      {      {
# Line 2220  x_set_mouse_color (f, arg, oldval) Line 1671  x_set_mouse_color (f, arg, oldval)
1671                      &fore_color, &back_color);                      &fore_color, &back_color);
1672      XRecolorCursor (FRAME_W32_DISPLAY (f), mode_cursor,      XRecolorCursor (FRAME_W32_DISPLAY (f), mode_cursor,
1673                      &fore_color, &back_color);                      &fore_color, &back_color);
1674      XRecolorCursor (FRAME_W32_DISPLAY (f), cross_cursor,      XRecolorCursor (FRAME_W32_DISPLAY (f), hand_cursor,
1675                      &fore_color, &back_color);                      &fore_color, &back_color);
1676      XRecolorCursor (FRAME_W32_DISPLAY (f), hourglass_cursor,      XRecolorCursor (FRAME_W32_DISPLAY (f), hourglass_cursor,
1677                      &fore_color, &back_color);                      &fore_color, &back_color);
# Line 2247  x_set_mouse_color (f, arg, oldval) Line 1698  x_set_mouse_color (f, arg, oldval)
1698        && f->output_data.w32->modeline_cursor != 0)        && f->output_data.w32->modeline_cursor != 0)
1699      XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->modeline_cursor);      XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->modeline_cursor);
1700    f->output_data.w32->modeline_cursor = mode_cursor;    f->output_data.w32->modeline_cursor = mode_cursor;
1701      
1702    if (cross_cursor != f->output_data.w32->cross_cursor    if (hand_cursor != f->output_data.w32->hand_cursor
1703        && f->output_data.w32->cross_cursor != 0)        && f->output_data.w32->hand_cursor != 0)
1704      XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->cross_cursor);      XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->hand_cursor);
1705    f->output_data.w32->cross_cursor = cross_cursor;    f->output_data.w32->hand_cursor = hand_cursor;
1706    
1707    XFlush (FRAME_W32_DISPLAY (f));    XFlush (FRAME_W32_DISPLAY (f));
1708    UNBLOCK_INPUT;    UNBLOCK_INPUT;
# Line 2261  x_set_mouse_color (f, arg, oldval) Line 1712  x_set_mouse_color (f, arg, oldval)
1712  }  }
1713    
1714  /* Defined in w32term.c. */  /* Defined in w32term.c. */
 void x_update_cursor (struct frame *f, int on_p);  
   
1715  void  void
1716  x_set_cursor_color (f, arg, oldval)  x_set_cursor_color (f, arg, oldval)
1717       struct frame *f;       struct frame *f;
# Line 2277  x_set_cursor_color (f, arg, oldval) Line 1726  x_set_cursor_color (f, arg, oldval)
1726      fore_pixel = FRAME_BACKGROUND_PIXEL (f);      fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1727    
1728    pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));    pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1729      
1730    /* Make sure that the cursor color differs from the background color.  */    /* Make sure that the cursor color differs from the background color.  */
1731    if (pixel == FRAME_BACKGROUND_PIXEL (f))    if (pixel == FRAME_BACKGROUND_PIXEL (f))
1732      {      {
# Line 2310  x_set_cursor_color (f, arg, oldval) Line 1759  x_set_cursor_color (f, arg, oldval)
1759    
1760  /* Set the border-color of frame F to pixel value PIX.  /* Set the border-color of frame F to pixel value PIX.
1761     Note that this does not fully take effect if done before     Note that this does not fully take effect if done before
1762     F has an window.  */     F has a window.  */
1763    
1764  void  void
1765  x_set_border_pixel (f, pix)  x_set_border_pixel (f, pix)
1766       struct frame *f;       struct frame *f;
1767       int pix;       int pix;
1768  {  {
1769    
1770    f->output_data.w32->border_pixel = pix;    f->output_data.w32->border_pixel = pix;
1771    
1772    if (FRAME_W32_WINDOW (f) != 0 && f->output_data.w32->border_width > 0)    if (FRAME_W32_WINDOW (f) != 0 && f->output_data.w32->border_width > 0)
# Line 2344  x_set_border_color (f, arg, oldval) Line 1795  x_set_border_color (f, arg, oldval)
1795    update_face_from_frame_parameter (f, Qborder_color, arg);    update_face_from_frame_parameter (f, Qborder_color, arg);
1796  }  }
1797    
 /* Value is the internal representation of the specified cursor type  
    ARG.  If type is BAR_CURSOR, return in *WIDTH the specified width  
    of the bar cursor.  */  
   
 enum text_cursor_kinds  
 x_specified_cursor_type (arg, width)  
      Lisp_Object arg;  
      int *width;  
 {  
   enum text_cursor_kinds type;  
     
   if (EQ (arg, Qbar))  
     {  
       type = BAR_CURSOR;  
       *width = 2;  
     }  
   else if (CONSP (arg)  
            && EQ (XCAR (arg), Qbar)  
            && INTEGERP (XCDR (arg))  
            && XINT (XCDR (arg)) >= 0)  
     {  
       type = BAR_CURSOR;  
       *width = XINT (XCDR (arg));  
     }  
   else if (EQ (arg, Qhbar))  
     {  
       type = HBAR_CURSOR;  
       *width = 2;  
     }  
   else if (CONSP (arg)  
            && EQ (XCAR (arg), Qhbar)  
            && INTEGERP (XCDR (arg))  
            && XINT (XCDR (arg)) >= 0)  
     {  
       type = HBAR_CURSOR;  
       *width = XINT (XCDR (arg));  
     }  
   else if (NILP (arg))  
     type = NO_CURSOR;  
   else  
     /* Treat anything unknown as "box cursor".  
        It was bad to signal an error; people have trouble fixing  
        .Xdefaults with Emacs, when it has something bad in it.  */  
     type = FILLED_BOX_CURSOR;  
   
   return type;  
 }  
1798    
1799  void  void
1800  x_set_cursor_type (f, arg, oldval)  x_set_cursor_type (f, arg, oldval)
1801       FRAME_PTR f;       FRAME_PTR f;
1802       Lisp_Object arg, oldval;       Lisp_Object arg, oldval;
1803  {  {
1804    int width;    set_frame_cursor_types (f, arg);
1805      
1806    FRAME_DESIRED_CURSOR (f) = x_specified_cursor_type (arg, &width);    /* Make sure the cursor gets redrawn.  */
1807    f->output_data.w32->cursor_width = width;    cursor_type_changed = 1;
   
   /* Make sure the cursor gets redrawn.  This is overkill, but how  
      often do people change cursor types?  */  
   update_mode_lines++;  
1808  }  }
1809    
1810  void  void
# Line 2417  x_set_icon_type (f, arg, oldval) Line 1817  x_set_icon_type (f, arg, oldval)
1817    if (NILP (arg) && NILP (oldval))    if (NILP (arg) && NILP (oldval))
1818      return;      return;
1819    
1820    if (STRINGP (arg) && STRINGP (oldval)    if (STRINGP (arg) && STRINGP (oldval)
1821        && EQ (Fstring_equal (oldval, arg), Qt))        && EQ (Fstring_equal (oldval, arg), Qt))
1822      return;      return;
1823    
# Line 2436  x_set_icon_type (f, arg, oldval) Line 1836  x_set_icon_type (f, arg, oldval)
1836    UNBLOCK_INPUT;    UNBLOCK_INPUT;
1837  }  }
1838    
 /* Return non-nil if frame F wants a bitmap icon.  */  
   
 Lisp_Object  
 x_icon_type (f)  
      FRAME_PTR f;  
 {  
   Lisp_Object tem;  
   
   tem = assq_no_quit (Qicon_type, f->param_alist);  
   if (CONSP (tem))  
     return XCDR (tem);  
   else  
     return Qnil;  
 }  
   
1839  void  void
1840  x_set_icon_name (f, arg, oldval)  x_set_icon_name (f, arg, oldval)
1841       struct frame *f;       struct frame *f;
# Line 2473  x_set_icon_name (f, arg, oldval) Line 1858  x_set_icon_name (f, arg, oldval)
1858    BLOCK_INPUT;    BLOCK_INPUT;
1859    
1860    result = x_text_icon (f,    result = x_text_icon (f,
1861                          (char *) XSTRING ((!NILP (f->icon_name)                          (char *) SDATA ((!NILP (f->icon_name)
1862                                             ? f->icon_name                                           ? f->icon_name
1863                                             : !NILP (f->title)                                           : !NILP (f->title)
1864                                             ? f->title                                           ? f->title
1865                                             : f->name))->data);                                           : f->name)));
1866    
1867    if (result)    if (result)
1868      {      {
# Line 2500  x_set_icon_name (f, arg, oldval) Line 1885  x_set_icon_name (f, arg, oldval)
1885  #endif  #endif
1886  }  }
1887    
 extern Lisp_Object x_new_font ();  
 extern Lisp_Object x_new_fontset();  
   
 void  
 x_set_font (f, arg, oldval)  
      struct frame *f;  
      Lisp_Object arg, oldval;  
 {  
   Lisp_Object result;  
   Lisp_Object fontset_name;  
   Lisp_Object frame;  
   int old_fontset = FRAME_FONTSET(f);  
   
   CHECK_STRING (arg);  
   
   fontset_name = Fquery_fontset (arg, Qnil);  
   
   BLOCK_INPUT;  
   result = (STRINGP (fontset_name)  
             ? x_new_fontset (f, XSTRING (fontset_name)->data)  
             : x_new_font (f, XSTRING (arg)->data));  
   UNBLOCK_INPUT;  
     
   if (EQ (result, Qnil))  
     error ("Font `%s' is not defined", XSTRING (arg)->data);  
   else if (EQ (result, Qt))  
     error ("The characters of the given font have varying widths");  
   else if (STRINGP (result))  
     {  
       if (STRINGP (fontset_name))  
         {  
           /* Fontset names are built from ASCII font names, so the  
              names may be equal despite there was a change.  */  
           if (old_fontset == FRAME_FONTSET (f))  
             return;  
         }  
       else if (!NILP (Fequal (result, oldval)))  
         return;  
   
       store_frame_param (f, Qfont, result);  
       recompute_basic_faces (f);  
     }  
   else  
     abort ();  
   
   do_pending_window_change (0);  
   
   /* Don't call `face-set-after-frame-default' when faces haven't been  
      initialized yet.  This is the case when called from  
      Fx_create_frame.  In that case, the X widget or window doesn't  
      exist either, and we can end up in x_report_frame_params with a  
      null widget which gives a segfault.  */  
   if (FRAME_FACE_CACHE (f))  
     {  
       XSETFRAME (frame, f);  
       call1 (Qface_set_after_frame_default, frame);  
     }  
 }  
   
 static void  
 x_set_fringe_width (f, new_value, old_value)  
      struct frame *f;  
      Lisp_Object new_value, old_value;  
 {  
   x_compute_fringe_widths (f, 1);  
 }  
   
 void  
 x_set_border_width (f, arg, oldval)  
      struct frame *f;  
      Lisp_Object arg, oldval;  
 {  
   CHECK_NUMBER (arg);  
   
   if (XINT (arg) == f->output_data.w32->border_width)  
     return;  
   
   if (FRAME_W32_WINDOW (f) != 0)  
     error ("Cannot change the border width of a window");  
   
   f->output_data.w32->border_width = XINT (arg);  
 }  
   
 void  
 x_set_internal_border_width (f, arg, oldval)  
      struct frame *f;  
      Lisp_Object arg, oldval;  
 {  
   int old = f->output_data.w32->internal_border_width;  
   
   CHECK_NUMBER (arg);  
   f->output_data.w32->internal_border_width = XINT (arg);  
   if (f->output_data.w32->internal_border_width < 0)  
     f->output_data.w32->internal_border_width = 0;  
   
   if (f->output_data.w32->internal_border_width == old)  
     return;  
   
   if (FRAME_W32_WINDOW (f) != 0)  
     {  
       x_set_window_size (f, 0, f->width, f->height);  
       SET_FRAME_GARBAGED (f);  
       do_pending_window_change (0);  
     }  
   else  
     SET_FRAME_GARBAGED (f);  
 }  
   
 void  
 x_set_visibility (f, value, oldval)  
      struct frame *f;  
      Lisp_Object value, oldval;  
 {  
   Lisp_Object frame;  
   XSETFRAME (frame, f);  
   
   if (NILP (value))  
     Fmake_frame_invisible (frame, Qt);  
   else if (EQ (value, Qicon))  
     Ficonify_frame (frame);  
   else  
     Fmake_frame_visible (frame);  
 }  
   
1888    
 /* Change window heights in windows rooted in WINDOW by N lines.  */  
   
 static void  
 x_change_window_heights (window, n)  
   Lisp_Object window;  
   int n;  
 {  
   struct window *w = XWINDOW (window);  
   
   XSETFASTINT (w->top, XFASTINT (w->top) + n);  
   XSETFASTINT (w->height, XFASTINT (w->height) - n);  
   
   if (INTEGERP (w->orig_top))  
     XSETFASTINT (w->orig_top, XFASTINT (w->orig_top) + n);  
   if (INTEGERP (w->orig_height))  
     XSETFASTINT (w->orig_height, XFASTINT (w->orig_height) - n);  
   
   /* Handle just the top child in a vertical split.  */  
   if (!NILP (w->vchild))  
     x_change_window_heights (w->vchild, n);  
   
   /* Adjust all children in a horizontal split.  */  
   for (window = w->hchild; !NILP (window); window = w->next)  
     {  
       w = XWINDOW (window);  
       x_change_window_heights (window, n);  
     }  
 }  
   
1889  void  void
1890  x_set_menu_bar_lines (f, value, oldval)  x_set_menu_bar_lines (f, value, oldval)
1891       struct frame *f;       struct frame *f;
# Line 2732  x_set_tool_bar_lines (f, value, oldval) Line 1964  x_set_tool_bar_lines (f, value, oldval)
1964      }      }
1965    
1966    FRAME_TOOL_BAR_LINES (f) = nlines;    FRAME_TOOL_BAR_LINES (f) = nlines;
1967    x_change_window_heights (root_window, delta);    change_window_heights (root_window, delta);
1968    adjust_glyphs (f);    adjust_glyphs (f);
1969    
1970    /* We also have to make sure that the internal border at the top of    /* We also have to make sure that the internal border at the top of
# Line 2789  x_set_name (f, name, explicit) Line 2021  x_set_name (f, name, explicit)
2021       Lisp_Object name;       Lisp_Object name;
2022       int explicit;       int explicit;
2023  {  {
2024    /* Make sure that requests from lisp code override requests from    /* Make sure that requests from lisp code override requests from
2025       Emacs redisplay code.  */       Emacs redisplay code.  */
2026    if (explicit)    if (explicit)
2027      {      {
# Line 2809  x_set_name (f, name, explicit) Line 2041  x_set_name (f, name, explicit)
2041        /* Check for no change needed in this very common case        /* Check for no change needed in this very common case
2042           before we do any consing.  */           before we do any consing.  */
2043        if (!strcmp (FRAME_W32_DISPLAY_INFO (f)->w32_id_name,        if (!strcmp (FRAME_W32_DISPLAY_INFO (f)->w32_id_name,
2044                     XSTRING (f->name)->data))                     SDATA (f->name)))
2045          return;          return;
2046        name = build_string (FRAME_W32_DISPLAY_INFO (f)->w32_id_name);        name = build_string (FRAME_W32_DISPLAY_INFO (f)->w32_id_name);
2047      }      }
# Line 2833  x_set_name (f, name, explicit) Line 2065  x_set_name (f, name, explicit)
2065          name = ENCODE_SYSTEM (name);          name = ENCODE_SYSTEM (name);
2066    
2067        BLOCK_INPUT;        BLOCK_INPUT;
2068        SetWindowText(FRAME_W32_WINDOW (f), XSTRING (name)->data);        SetWindowText(FRAME_W32_WINDOW (f), SDATA (name));
2069        UNBLOCK_INPUT;        UNBLOCK_INPUT;
2070      }      }
2071  }  }
# Line 2893  x_set_title (f, name, old_name) Line 2125  x_set_title (f, name, old_name)
2125          name = ENCODE_SYSTEM (name);          name = ENCODE_SYSTEM (name);
2126    
2127        BLOCK_INPUT;        BLOCK_INPUT;
2128        SetWindowText(FRAME_W32_WINDOW (f), XSTRING (name)->data);        SetWindowText(FRAME_W32_WINDOW (f), SDATA (name));
2129        UNBLOCK_INPUT;        UNBLOCK_INPUT;
2130      }      }
2131  }  }
   
 void  
 x_set_autoraise (f, arg, oldval)  
      struct frame *f;  
      Lisp_Object arg, oldval;  
 {  
   f->auto_raise = !EQ (Qnil, arg);  
 }  
   
 void  
 x_set_autolower (f, arg, oldval)  
      struct frame *f;  
      Lisp_Object arg, oldval;  
 {  
   f->auto_lower = !EQ (Qnil, arg);  
 }  
   
 void  
 x_set_unsplittable (f, arg, oldval)  
      struct frame *f;  
      Lisp_Object arg, oldval;  
 {  
   f->no_split = !NILP (arg);  
 }  
2132    
 void  
 x_set_vertical_scroll_bars (f, arg, oldval)  
      struct frame *f;  
      Lisp_Object arg, oldval;  
 {  
   if ((EQ (arg, Qleft) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))  
       || (EQ (arg, Qright) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))  
       || (NILP (arg) && FRAME_HAS_VERTICAL_SCROLL_BARS (f))  
       || (!NILP (arg) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f)))  
     {  
       FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = NILP (arg) ?  
         vertical_scroll_bar_none :  
         /* Put scroll bars on the right by default, as is conventional  
            on MS-Windows.  */  
         EQ (Qleft, arg)  
         ? vertical_scroll_bar_left  
         : vertical_scroll_bar_right;  
   
       /* We set this parameter before creating the window for the  
          frame, so we can get the geometry right from the start.  
          However, if the window hasn't been created yet, we shouldn't  
          call x_set_window_size.  */  
       if (FRAME_W32_WINDOW (f))  
         x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f));  
       do_pending_window_change (0);  
     }  
 }  
2133    
2134  void  void x_set_scroll_bar_default_width (f)
 x_set_scroll_bar_width (f, arg, oldval)  
2135       struct frame *f;       struct frame *f;
      Lisp_Object arg, oldval;  
2136  {  {
2137    int wid = FONT_WIDTH (f->output_data.w32->font);    int wid = FONT_WIDTH (f->output_data.w32->font);
2138    
2139    if (NILP (arg))    FRAME_SCROLL_BAR_PIXEL_WIDTH (f) = GetSystemMetrics (SM_CXVSCROLL);
2140      {    FRAME_SCROLL_BAR_COLS (f) = (FRAME_SCROLL_BAR_PIXEL_WIDTH (f) +
2141        FRAME_SCROLL_BAR_PIXEL_WIDTH (f) = GetSystemMetrics (SM_CXVSCROLL);                                 wid - 1) / wid;
       FRAME_SCROLL_BAR_COLS (f) = (FRAME_SCROLL_BAR_PIXEL_WIDTH (f) +  
                                    wid - 1) / wid;  
       if (FRAME_W32_WINDOW (f))  
         x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f));  
       do_pending_window_change (0);  
     }  
   else if (INTEGERP (arg) && XINT (arg) > 0  
            && XFASTINT (arg) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f))  
     {  
       FRAME_SCROLL_BAR_PIXEL_WIDTH (f) = XFASTINT (arg);  
       FRAME_SCROLL_BAR_COLS (f) = (FRAME_SCROLL_BAR_PIXEL_WIDTH (f)  
                                    + wid-1) / wid;  
       if (FRAME_W32_WINDOW (f))  
         x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f));  
       do_pending_window_change (0);  
     }  
   change_frame_size (f, 0, FRAME_WIDTH (f), 0, 0, 0);  
   XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0;  
   XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0;  
 }  
   
 /* Subroutines of creating an frame.  */  
   
 /* Make sure that Vx_resource_name is set to a reasonable value.  
    Fix it up, or set it to `emacs' if it is too hopeless.  */  
   
 static void  
 validate_x_resource_name ()  
 {  
   int len = 0;  
   /* Number of valid characters in the resource name.  */  
   int good_count = 0;  
   /* Number of invalid characters in the resource name.  */  
   int bad_count = 0;  
   Lisp_Object new;  
   int i;  
   
   if (STRINGP (Vx_resource_name))  
     {  
       unsigned char *p = XSTRING (Vx_resource_name)->data;  
       int i;  
   
       len = STRING_BYTES (XSTRING (Vx_resource_name));  
   
       /* Only letters, digits, - and _ are valid in resource names.  
          Count the valid characters and count the invalid ones.  */  
       for (i = 0; i < len; i++)  
         {  
           int c = p[i];  
           if (! ((c >= 'a' && c <= 'z')  
                  || (c >= 'A' && c <= 'Z')  
                  || (c >= '0' && c <= '9')  
                  || c == '-' || c == '_'))  
             bad_count++;  
           else  
             good_count++;  
         }  
     }  
   else  
     /* Not a string => completely invalid.  */  
     bad_count = 5, good_count = 0;  
   
   /* If name is valid already, return.  */  
   if (bad_count == 0)  
     return;  
   
   /* If name is entirely invalid, or nearly so, use `emacs'.  */  
   if (good_count == 0  
       || (good_count == 1 && bad_count > 0))  
     {  
       Vx_resource_name = build_string ("emacs");  
       return;  
     }  
   
   /* Name is partly valid.  Copy it and replace the invalid characters  
      with underscores.  */  
   
   Vx_resource_name = new = Fcopy_sequence (Vx_resource_name);  
   
   for (i = 0; i < len; i++)  
     {  
       int c = XSTRING (new)->data[i];  
       if (! ((c >= 'a' && c <= 'z')  
              || (c >= 'A' && c <= 'Z')  
              || (c >= '0' && c <= '9')  
              || c == '-' || c == '_'))  
         XSTRING (new)->data[i] = '_';  
     }  
 }  
   
   
 extern char *x_get_string_resource ();  
   
 DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,  
        doc: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.  
 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the  
 class, where INSTANCE is the name under which Emacs was invoked, or  
 the name specified by the `-name' or `-rn' command-line arguments.  
   
 The optional arguments COMPONENT and SUBCLASS add to the key and the  
 class, respectively.  You must specify both of them or neither.  
 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'  
 and the class is `Emacs.CLASS.SUBCLASS'.  */)  
   (attribute, class, component, subclass)  
      Lisp_Object attribute, class, component, subclass;  
 {  
   register char *value;  
   char *name_key;  
   char *class_key;  
   
   CHECK_STRING (attribute);  
   CHECK_STRING (class);  
   
   if (!NILP (component))  
     CHECK_STRING (component);  
   if (!NILP (subclass))  
     CHECK_STRING (subclass);  
   if (NILP (component) != NILP (subclass))  
     error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");  
   
   validate_x_resource_name ();  
   
   /* Allocate space for the components, the dots which separate them,  
      and the final '\0'.  Make them big enough for the worst case.  */  
   name_key = (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_name))  
                               + (STRINGP (component)  
                                  ? STRING_BYTES (XSTRING (component)) : 0)  
                               + STRING_BYTES (XSTRING (attribute))  
                               + 3);  
   
   class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)  
                                + STRING_BYTES (XSTRING (class))  
                                + (STRINGP (subclass)  
                                   ? STRING_BYTES (XSTRING (subclass)) : 0)  
                                + 3);  
   
   /* Start with emacs.FRAMENAME for the name (the specific one)  
      and with `Emacs' for the class key (the general one).  */  
   strcpy (name_key, XSTRING (Vx_resource_name)->data);  
   strcpy (class_key, EMACS_CLASS);  
   
   strcat (class_key, ".");  
   strcat (class_key, XSTRING (class)->data);  
   
   if (!NILP (component))  
     {  
       strcat (class_key, ".");  
       strcat (class_key, XSTRING (subclass)->data);  
   
       strcat (name_key, ".");  
       strcat (name_key, XSTRING (component)->data);  
     }  
   
   strcat (name_key, ".");  
   strcat (name_key, XSTRING (attribute)->data);  
   
   value = x_get_string_resource (Qnil,  
                                  name_key, class_key);  
   
   if (value != (char *) 0)  
     return build_string (value);  
   else  
     return Qnil;  
2142  }  }
2143    
2144  /* Used when C code wants a resource value.  */  
2145    /* Subroutines of creating a frame.  */
2146    
 char *  
 x_get_resource_string (attribute, class)  
      char *attribute, *class;  
 {  
   char *name_key;  
   char *class_key;  
   struct frame *sf = SELECTED_FRAME ();  
   
   /* Allocate space for the components, the dots which separate them,  
      and the final '\0'.  */  
   name_key = (char *) alloca (STRING_BYTES (XSTRING (Vinvocation_name))  
                               + strlen (attribute) + 2);  
   class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)  
                                + strlen (class) + 2);  
   
   sprintf (name_key, "%s.%s",  
            XSTRING (Vinvocation_name)->data,  
            attribute);  
   sprintf (class_key, "%s.%s", EMACS_CLASS, class);  
   
   return x_get_string_resource (sf, name_key, class_key);  
 }  
   
 /* Types we might convert a resource string into.  */  
 enum resource_types  
 {  
   RES_TYPE_NUMBER,  
   RES_TYPE_FLOAT,  
   RES_TYPE_BOOLEAN,  
   RES_TYPE_STRING,  
   RES_TYPE_SYMBOL  
 };  
2147    
2148  /* Return the value of parameter PARAM.  /* Return the value of parameter PARAM.
2149    
# Line 3178  w32_get_arg (alist, param, attribute, cl Line 2163  w32_get_arg (alist, param, attribute, cl
2163       char *class;       char *class;
2164       enum resource_types type;       enum resource_types type;
2165  {  {
2166    register Lisp_Object tem;    return x_get_arg (check_x_display_info (Qnil),
2167                        alist, param, attribute, class, type);
   tem = Fassq (param, alist);  
   if (EQ (tem, Qnil))  
     tem = Fassq (param, Vdefault_frame_alist);  
   if (EQ (tem, Qnil))  
     {  
   
       if (attribute)  
         {  
           tem = Fx_get_resource (build_string (attribute),  
                                  build_string (class),  
                                  Qnil, Qnil);  
   
           if (NILP (tem))  
             return Qunbound;  
   
           switch (type)  
             {  
             case RES_TYPE_NUMBER:  
               return make_number (atoi (XSTRING (tem)->data));  
   
             case RES_TYPE_FLOAT:  
               return make_float (atof (XSTRING (tem)->data));  
   
             case RES_TYPE_BOOLEAN:  
               tem = Fdowncase (tem);  
               if (!strcmp (XSTRING (tem)->data, "on")  
                   || !strcmp (XSTRING (tem)->data, "true"))  
                 return Qt;  
               else  
                 return Qnil;  
   
             case RES_TYPE_STRING:  
               return tem;  
   
             case RES_TYPE_SYMBOL:  
               /* As a special case, we map the values `true' and `on'  
                  to Qt, and `false' and `off' to Qnil.  */  
               {  
                 Lisp_Object lower;  
                 lower = Fdowncase (tem);  
                 if (!strcmp (XSTRING (lower)->data, "on")  
                     || !strcmp (XSTRING (lower)->data, "true"))  
                   return Qt;  
                 else if (!strcmp (XSTRING (lower)->data, "off")  
                       || !strcmp (XSTRING (lower)->data, "false"))  
                   return Qnil;  
                 else  
                   return Fintern (tem, Qnil);  
               }  
   
             default:  
               abort ();  
             }  
         }  
       else  
         return Qunbound;  
     }  
   return Fcdr (tem);  
2168  }  }
2169    
2170  /* Record in frame F the specified or default value according to ALIST  
2171     of the parameter named PROP (a Lisp symbol).  Cursor
2172     If no value is specified for PROP, look for an X default for XPROP  w32_load_cursor (LPCTSTR name)
    on the frame named NAME.  
    If that is not found either, use the value DEFLT.  */  
   
 static Lisp_Object  
 x_default_parameter (f, alist, prop, deflt, xprop, xclass, type)  
      struct frame *f;  
      Lisp_Object alist;  
      Lisp_Object prop;  
      Lisp_Object deflt;  
      char *xprop;  
      char *xclass;  
      enum resource_types type;  
 {  
   Lisp_Object tem;  
   
   tem = w32_get_arg (alist, prop, xprop, xclass, type);  
   if (EQ (tem, Qunbound))  
     tem = deflt;  
   x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));  
   return tem;  
 }  
   
 DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,  
        doc: /* Parse an X-style geometry string STRING.  
 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).  
 The properties returned may include `top', `left', `height', and `width'.  
 The value of `left' or `top' may be an integer,  
 or a list (+ N) meaning N pixels relative to top/left corner,  
 or a list (- N) meaning -N pixels relative to bottom/right corner.  */)  
      (string)  
      Lisp_Object string;  
 {  
   int geometry, x, y;  
   unsigned int width, height;  
   Lisp_Object result;  
   
   CHECK_STRING (string);  
   
   geometry = XParseGeometry ((char *) XSTRING (string)->data,  
                              &x, &y, &width, &height);  
   
   result = Qnil;  
   if (geometry & XValue)  
     {  
       Lisp_Object element;  
   
       if (x >= 0 && (geometry & XNegative))  
         element = Fcons (Qleft, Fcons (Qminus, Fcons (make_number (-x), Qnil)));  
       else if (x < 0 && ! (geometry & XNegative))  
         element = Fcons (Qleft, Fcons (Qplus, Fcons (make_number (x), Qnil)));  
       else  
         element = Fcons (Qleft, make_number (x));  
       result = Fcons (element, result);  
     }  
   
   if (geometry & YValue)  
     {  
       Lisp_Object element;  
   
       if (y >= 0 && (geometry & YNegative))  
         element = Fcons (Qtop, Fcons (Qminus, Fcons (make_number (-y), Qnil)));  
       else if (y < 0 && ! (geometry & YNegative))  
         element = Fcons (Qtop, Fcons (Qplus, Fcons (make_number (y), Qnil)));  
       else  
         element = Fcons (Qtop, make_number (y));  
       result = Fcons (element, result);  
     }  
   
   if (geometry & WidthValue)  
     result = Fcons (Fcons (Qwidth, make_number (width)), result);  
   if (geometry & HeightValue)  
     result = Fcons (Fcons (Qheight, make_number (height)), result);  
   
   return result;  
 }  
   
 /* Calculate the desired size and position of this window,  
    and return the flags saying which aspects were specified.  
   
    This function does not make the coordinates positive.  */  
   
 #define DEFAULT_ROWS 40  
 #define DEFAULT_COLS 80  
   
 static int  
 x_figure_window_size (f, parms)  
      struct frame *f;  
      Lisp_Object parms;  
2173  {  {
2174    register Lisp_Object tem0, tem1, tem2;    /* Try first to load cursor from application resource.  */
2175    long window_prompting = 0;    Cursor cursor = LoadImage ((HINSTANCE) GetModuleHandle(NULL),
2176                                 name, IMAGE_CURSOR, 0, 0,
2177    /* Default values if we fall through.                               LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_SHARED);
2178       Actually, if that happens we should get    if (!cursor)
      window manager prompting.  */  
   SET_FRAME_WIDTH (f, DEFAULT_COLS);  
   f->height = DEFAULT_ROWS;  
   /* Window managers expect that if program-specified  
      positions are not (0,0), they're intentional, not defaults.  */  
   f->output_data.w32->top_pos = 0;  
   f->output_data.w32->left_pos = 0;  
   
   /* Ensure that old new_width and new_height will not override the  
      values set here.  */  
   FRAME_NEW_WIDTH (f) = 0;  
   FRAME_NEW_HEIGHT (f) = 0;  
   
   tem0 = w32_get_arg (parms, Qheight, 0, 0, RES_TYPE_NUMBER);  
   tem1 = w32_get_arg (parms, Qwidth, 0, 0, RES_TYPE_NUMBER);  
   tem2 = w32_get_arg (parms, Quser_size, 0, 0, RES_TYPE_NUMBER);  
   if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))  
     {  
       if (!EQ (tem0, Qunbound))  
         {  
           CHECK_NUMBER (tem0);  
           f->height = XINT (tem0);  
         }  
       if (!EQ (tem1, Qunbound))  
         {  
           CHECK_NUMBER (tem1);  
           SET_FRAME_WIDTH (f, XINT (tem1));  
         }  
       if (!NILP (tem2) && !EQ (tem2, Qunbound))  
         window_prompting |= USSize;  
       else  
         window_prompting |= PSize;  
     }  
   
   f->output_data.w32->vertical_scroll_bar_extra  
     = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)  
        ? 0  
        : FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0  
        ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f)  
        : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.w32->font)));  
   
   x_compute_fringe_widths (f, 0);  
   
   f->output_data.w32->pixel_width = CHAR_TO_PIXEL_WIDTH (f, f->width);  
   f->output_data.w32->pixel_height = CHAR_TO_PIXEL_HEIGHT (f, f->height);  
   
   tem0 = w32_get_arg (parms, Qtop, 0, 0, RES_TYPE_NUMBER);  
   tem1 = w32_get_arg (parms, Qleft, 0, 0, RES_TYPE_NUMBER);  
   tem2 = w32_get_arg (parms, Quser_position, 0, 0, RES_TYPE_NUMBER);  
   if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))  
     {  
       if (EQ (tem0, Qminus))  
         {  
           f->output_data.w32->top_pos = 0;  
           window_prompting |= YNegative;  
         }  
       else if (CONSP (tem0) && EQ (XCAR (tem0), Qminus)  
                && CONSP (XCDR (tem0))  
                && INTEGERP (XCAR (XCDR (tem0))))  
         {  
           f->output_data.w32->top_pos = - XINT (XCAR (XCDR (tem0)));  
           window_prompting |= YNegative;  
         }  
       else if (CONSP (tem0) && EQ (XCAR (tem0), Qplus)  
                && CONSP (XCDR (tem0))  
                && INTEGERP (XCAR (XCDR (tem0))))  
         {  
           f->output_data.w32->top_pos = XINT (XCAR (XCDR (tem0)));  
         }  
       else if (EQ (tem0, Qunbound))  
         f->output_data.w32->top_pos = 0;  
       else  
         {  
           CHECK_NUMBER (tem0);  
           f->output_data.w32->top_pos = XINT (tem0);  
           if (f->output_data.w32->top_pos < 0)  
             window_prompting |= YNegative;  
         }  
   
       if (EQ (tem1, Qminus))  
         {  
           f->output_data.w32->left_pos = 0;  
           window_prompting |= XNegative;  
         }  
       else if (CONSP (tem1) && EQ (XCAR (tem1), Qminus)  
                && CONSP (XCDR (tem1))  
                && INTEGERP (XCAR (XCDR (tem1))))  
         {  
           f->output_data.w32->left_pos = - XINT (XCAR (XCDR (tem1)));  
           window_prompting |= XNegative;  
         }  
       else if (CONSP (tem1) && EQ (XCAR (tem1), Qplus)  
                && CONSP (XCDR (tem1))  
                && INTEGERP (XCAR (XCDR (tem1))))  
         {  
           f->output_data.w32->left_pos = XINT (XCAR (XCDR (tem1)));  
         }  
       else if (EQ (tem1, Qunbound))  
         f->output_data.w32->left_pos = 0;  
       else  
         {  
           CHECK_NUMBER (tem1);  
           f->output_data.w32->left_pos = XINT (tem1);  
           if (f->output_data.w32->left_pos < 0)  
             window_prompting |= XNegative;  
         }  
   
       if (!NILP (tem2) && ! EQ (tem2, Qunbound))  
         window_prompting |= USPosition;  
       else  
         window_prompting |= PPosition;  
     }  
   
   if (f->output_data.w32->want_fullscreen != FULLSCREEN_NONE)  
2179      {      {
2180        int left, top;        /* Then try to load a shared predefined cursor.  */
2181        int width, height;        cursor = LoadImage (NULL, name, IMAGE_CURSOR, 0, 0,
2182                              LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_SHARED);
       /* It takes both for some WM:s to place it where we want */  
       window_prompting = USPosition | PPosition;  
       x_fullscreen_adjust (f, &width, &height, &top, &left);  
       f->width = width;  
       f->height = height;  
       f->output_data.w32->pixel_width = CHAR_TO_PIXEL_WIDTH (f, f->width);  
       f->output_data.w32->pixel_height = CHAR_TO_PIXEL_HEIGHT (f, f->height);  
       f->output_data.w32->left_pos = left;  
       f->output_data.w32->top_pos = top;  
2183      }      }
2184      return cursor;
   return window_prompting;  
2185  }  }
2186    
   
   
2187  extern LRESULT CALLBACK w32_wnd_proc ();  extern LRESULT CALLBACK w32_wnd_proc ();
2188    
2189  BOOL  BOOL
2190  w32_init_class (hinst)  w32_init_class (hinst)
2191       HINSTANCE hinst;       HINSTANCE hinst;
2192  {  {
# Line 3485  w32_init_class (hinst) Line 2198  w32_init_class (hinst)
2198    wc.cbWndExtra = WND_EXTRA_BYTES;    wc.cbWndExtra = WND_EXTRA_BYTES;
2199    wc.hInstance = hinst;    wc.hInstance = hinst;
2200    wc.hIcon = LoadIcon (hinst, EMACS_CLASS);    wc.hIcon = LoadIcon (hinst, EMACS_CLASS);
2201    wc.hCursor = LoadCursor (NULL, IDC_ARROW);    wc.hCursor = w32_load_cursor (IDC_ARROW);
2202    wc.hbrBackground = NULL; /* GetStockObject (WHITE_BRUSH);  */    wc.hbrBackground = NULL; /* GetStockObject (WHITE_BRUSH);  */
2203    wc.lpszMenuName = NULL;    wc.lpszMenuName = NULL;
2204    wc.lpszClassName = EMACS_CLASS;    wc.lpszClassName = EMACS_CLASS;
# Line 3493  w32_init_class (hinst) Line 2206  w32_init_class (hinst)
2206    return (RegisterClass (&wc));    return (RegisterClass (&wc));
2207  }  }
2208    
2209  HWND  HWND
2210  w32_createscrollbar (f, bar)  w32_createscrollbar (f, bar)
2211       struct frame *f;       struct frame *f;
2212       struct scroll_bar * bar;       struct scroll_bar * bar;
# Line 3501  w32_createscrollbar (f, bar) Line 2214  w32_createscrollbar (f, bar)
2214    return (CreateWindow ("SCROLLBAR", "", SBS_VERT | WS_CHILD | WS_VISIBLE,    return (CreateWindow ("SCROLLBAR", "", SBS_VERT | WS_CHILD | WS_VISIBLE,
2215                          /* Position and size of scroll bar.  */                          /* Position and size of scroll bar.  */
2216                          XINT(bar->left) + VERTICAL_SCROLL_BAR_WIDTH_TRIM,                          XINT(bar->left) + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
2217                          XINT(bar->top),                          XINT(bar->top),
2218                          XINT(bar->width) - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,                          XINT(bar->width) - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
2219                          XINT(bar->height),                          XINT(bar->height),
2220                          FRAME_W32_WINDOW (f),                          FRAME_W32_WINDOW (f),
# Line 3510  w32_createscrollbar (f, bar) Line 2223  w32_createscrollbar (f, bar)
2223                          NULL));                          NULL));
2224  }  }
2225    
2226  void  void
2227  w32_createwindow (f)  w32_createwindow (f)
2228       struct frame *f;       struct frame *f;
2229  {  {
# Line 3520  w32_createwindow (f) Line 2233  w32_createwindow (f)
2233    rect.left = rect.top = 0;    rect.left = rect.top = 0;
2234    rect.right = PIXEL_WIDTH (f);    rect.right = PIXEL_WIDTH (f);
2235    rect.bottom = PIXEL_HEIGHT (f);    rect.bottom = PIXEL_HEIGHT (f);
2236          
2237    AdjustWindowRect (&rect, f->output_data.w32->dwStyle,    AdjustWindowRect (&rect, f->output_data.w32->dwStyle,
2238                      FRAME_EXTERNAL_MENU_BAR (f));                      FRAME_EXTERNAL_MENU_BAR (f));
2239      
2240    /* Do first time app init */    /* Do first time app init */
2241      
2242    if (!hprevinst)    if (!hprevinst)
2243      {      {
2244        w32_init_class (hinst);        w32_init_class (hinst);
2245      }      }
2246      
2247    FRAME_W32_WINDOW (f) = hwnd    FRAME_W32_WINDOW (f) = hwnd
2248      = CreateWindow (EMACS_CLASS,      = CreateWindow (EMACS_CLASS,
2249                      f->namebuf,                      f->namebuf,
# Line 3554  w32_createwindow (f) Line 2267  w32_createwindow (f)
2267    
2268        /* Enable drag-n-drop.  */        /* Enable drag-n-drop.  */
2269        DragAcceptFiles (hwnd, TRUE);        DragAcceptFiles (hwnd, TRUE);
2270          
2271        /* Do this to discard the default setting specified by our parent. */        /* Do this to discard the default setting specified by our parent. */
2272        ShowWindow (hwnd, SW_HIDE);        ShowWindow (hwnd, SW_HIDE);
2273      }      }
2274  }  }
2275    
2276  void  void
2277  my_post_msg (wmsg, hwnd, msg, wParam, lParam)  my_post_msg (wmsg, hwnd, msg, wParam, lParam)
2278       W32Msg * wmsg;       W32Msg * wmsg;
2279       HWND hwnd;       HWND hwnd;
# Line 3657  record_keyup (unsigned int wparam, unsig Line 2370  record_keyup (unsigned int wparam, unsig
2370  }  }
2371    
2372  /* Emacs can lose focus while a modifier key has been pressed.  When  /* Emacs can lose focus while a modifier key has been pressed.  When
2373     it regains focus, be conservative and clear all modifiers since     it regains focus, be conservative and clear all modifiers since
2374     we cannot reconstruct the left and right modifier state.  */     we cannot reconstruct the left and right modifier state.  */
2375  static void  static void
2376  reset_modifiers ()  reset_modifiers ()
# Line 3712  sync_modifiers () Line 2425  sync_modifiers ()
2425    if (!modifiers_recorded)    if (!modifiers_recorded)
2426      return;      return;
2427    
2428    if (!(GetKeyState (VK_CONTROL) & 0x8000))    if (!(GetKeyState (VK_CONTROL) & 0x8000))
2429      modifiers[EMACS_RCONTROL] = modifiers[EMACS_LCONTROL] = 0;      modifiers[EMACS_RCONTROL] = modifiers[EMACS_LCONTROL] = 0;
2430    
2431    if (!(GetKeyState (VK_MENU) & 0x8000))    if (!(GetKeyState (VK_MENU) & 0x8000))
2432      modifiers[EMACS_RMENU] = modifiers[EMACS_LMENU] = 0;      modifiers[EMACS_RMENU] = modifiers[EMACS_LMENU] = 0;
2433  }  }
2434    
# Line 3925  w32_msg_pump (deferred_msg * msg_buf) Line 2638  w32_msg_pump (deferred_msg * msg_buf)
2638    HWND focus_window;    HWND focus_window;
2639    
2640    msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL);    msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL);
2641      
2642    while (GetMessage (&msg, NULL, 0, 0))    while (GetMessage (&msg, NULL, 0, 0))
2643      {      {
2644        if (msg.hwnd == NULL)        if (msg.hwnd == NULL)
# Line 4115  cancel_all_deferred_msgs () Line 2828  cancel_all_deferred_msgs ()
2828    PostThreadMessage (dwWindowsThreadId, WM_NULL, 0, 0);    PostThreadMessage (dwWindowsThreadId, WM_NULL, 0, 0);
2829  }  }
2830    
2831  DWORD  DWORD
2832  w32_msg_worker (dw)  w32_msg_worker (dw)
2833       DWORD dw;       DWORD dw;
2834  {  {
# Line 4123  w32_msg_worker (dw) Line 2836  w32_msg_worker (dw)
2836    deferred_msg dummy_buf;    deferred_msg dummy_buf;
2837    
2838    /* Ensure our message queue is created */    /* Ensure our message queue is created */
2839      
2840    PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);    PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
2841      
2842    if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))    if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
2843      abort ();      abort ();
2844    
# Line 4204  post_character_message (hwnd, msg, wPara Line 2917  post_character_message (hwnd, msg, wPara
2917    
2918  /* Main window procedure */  /* Main window procedure */
2919    
2920  LRESULT CALLBACK  LRESULT CALLBACK
2921  w32_wnd_proc (hwnd, msg, wParam, lParam)  w32_wnd_proc (hwnd, msg, wParam, lParam)
2922       HWND hwnd;       HWND hwnd;
2923       UINT msg;       UINT msg;
# Line 4233  w32_wnd_proc (hwnd, msg, wParam, lParam) Line 2946  w32_wnd_proc (hwnd, msg, wParam, lParam)
2946       w32_clear_rect, because these functions must obtain a DC handle       w32_clear_rect, because these functions must obtain a DC handle
2947       from the frame struct using get_frame_dc which is thread-aware.  */       from the frame struct using get_frame_dc which is thread-aware.  */
2948    
2949    switch (msg)    switch (msg)
2950      {      {
2951      case WM_ERASEBKGND:      case WM_ERASEBKGND:
2952        f = x_window_to_frame (dpyinfo, hwnd);        f = x_window_to_frame (dpyinfo, hwnd);
# Line 4302  w32_wnd_proc (hwnd, msg, wParam, lParam) Line 3015  w32_wnd_proc (hwnd, msg, wParam, lParam)
3015              leave_crit ();              leave_crit ();
3016    
3017              my_post_msg (&wmsg, hwnd, msg, wParam, lParam);              my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3018              
3019              return 0;              return 0;
3020            }            }
3021    
# Line 4422  w32_wnd_proc (hwnd, msg, wParam, lParam) Line 3135  w32_wnd_proc (hwnd, msg, wParam, lParam)
3135              return 0;              return 0;
3136            break;            break;
3137          case VK_MENU:          case VK_MENU:
3138            if (NILP (Vw32_pass_alt_to_system))            if (NILP (Vw32_pass_alt_to_system))
3139              /* Prevent DefWindowProc from activating the menu bar if an              /* Prevent DefWindowProc from activating the menu bar if an
3140                 Alt key is pressed and released by itself.  */                 Alt key is pressed and released by itself.  */
3141              return 0;              return 0;
3142            windows_translate = 1;            windows_translate = 1;
3143            break;            break;
3144          case VK_CAPITAL:          case VK_CAPITAL:
3145            /* Decide whether to treat as modifier or function key.  */            /* Decide whether to treat as modifier or function key.  */
3146            if (NILP (Vw32_enable_caps_lock))            if (NILP (Vw32_enable_caps_lock))
3147              goto disable_lock_key;              goto disable_lock_key;
# Line 4465  w32_wnd_proc (hwnd, msg, wParam, lParam) Line 3178  w32_wnd_proc (hwnd, msg, wParam, lParam)
3178                                    w32_get_key_modifiers (wParam, lParam));                                    w32_get_key_modifiers (wParam, lParam));
3179            windows_translate = 1;            windows_translate = 1;
3180            break;            break;
3181          case VK_CONTROL:          case VK_CONTROL:
3182          case VK_SHIFT:          case VK_SHIFT:
3183          case VK_PROCESSKEY:  /* Generated by IME.  */          case VK_PROCESSKEY:  /* Generated by IME.  */
3184            windows_translate = 1;            windows_translate = 1;
# Line 4523  w32_wnd_proc (hwnd, msg, wParam, lParam) Line 3236  w32_wnd_proc (hwnd, msg, wParam, lParam)
3236                        int add;                        int add;
3237                        int isdead = 0;                        int isdead = 0;
3238                        KEY_EVENT_RECORD key;                        KEY_EVENT_RECORD key;
3239                      
3240                        key.bKeyDown = TRUE;                        key.bKeyDown = TRUE;
3241                        key.wRepeatCount = 1;                        key.wRepeatCount = 1;
3242                        key.wVirtualKeyCode = wParam;                        key.wVirtualKeyCode = wParam;
# Line 4564  w32_wnd_proc (hwnd, msg, wParam, lParam) Line 3277  w32_wnd_proc (hwnd, msg, wParam, lParam)
3277          }          }
3278    
3279        /* Fall through */        /* Fall through */
3280          
3281      case WM_SYSCHAR:      case WM_SYSCHAR:
3282      case WM_CHAR:      case WM_CHAR:
3283        post_character_message (hwnd, msg, wParam, lParam,        post_character_message (hwnd, msg, wParam, lParam,
# Line 4700  w32_wnd_proc (hwnd, msg, wParam, lParam) Line 3413  w32_wnd_proc (hwnd, msg, wParam, lParam)
3413            {            {
3414              if (up) ReleaseCapture ();              if (up) ReleaseCapture ();
3415              else SetCapture (hwnd);              else SetCapture (hwnd);
3416              button = (button == 0) ? LMOUSE :              button = (button == 0) ? LMOUSE :
3417                ((button == 1) ? MMOUSE  : RMOUSE);                ((button == 1) ? MMOUSE  : RMOUSE);
3418              if (up)              if (up)
3419                button_state &= ~button;                button_state &= ~button;
# Line 4708  w32_wnd_proc (hwnd, msg, wParam, lParam) Line 3421  w32_wnd_proc (hwnd, msg, wParam, lParam)
3421                button_state |= button;                button_state |= button;
3422            }            }
3423        }        }
3424          
3425        wmsg.dwModifiers = w32_get_modifiers ();        wmsg.dwModifiers = w32_get_modifiers ();
3426        my_post_msg (&wmsg, hwnd, msg, wParam, lParam);        my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3427    
# Line 4741  w32_wnd_proc (hwnd, msg, wParam, lParam) Line 3454  w32_wnd_proc (hwnd, msg, wParam, lParam)
3454            my_post_msg (&wmsg, hwnd, msg, wParam, lParam);            my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3455            return 0;            return 0;
3456          }          }
3457      
3458        /* Hang onto mouse move and scroll messages for a bit, to avoid        /* Hang onto mouse move and scroll messages for a bit, to avoid
3459           sending such events to Emacs faster than it can process them.           sending such events to Emacs faster than it can process them.
3460           If we get more events before the timer from the first message           If we get more events before the timer from the first message
# Line 4759  w32_wnd_proc (hwnd, msg, wParam, lParam) Line 3472  w32_wnd_proc (hwnd, msg, wParam, lParam)
3472        saved_mouse_move_msg.msg.lParam = lParam;        saved_mouse_move_msg.msg.lParam = lParam;
3473        saved_mouse_move_msg.msg.time = GetMessageTime ();        saved_mouse_move_msg.msg.time = GetMessageTime ();
3474        saved_mouse_move_msg.dwModifiers = w32_get_modifiers ();        saved_mouse_move_msg.dwModifiers = w32_get_modifiers ();
3475      
3476        return 0;        return 0;
3477    
3478      case WM_MOUSEWHEEL:      case WM_MOUSEWHEEL:
# Line 4807  w32_wnd_proc (hwnd, msg, wParam, lParam) Line 3520  w32_wnd_proc (hwnd, msg, wParam, lParam)
3520              }              }
3521          }          }
3522        return 0;        return 0;
3523      
3524      case WM_NCACTIVATE:      case WM_NCACTIVATE:
3525        /* Windows doesn't send us focus messages when putting up and        /* Windows doesn't send us focus messages when putting up and
3526           taking down a system popup dialog as for Ctrl-Alt-Del on Windows 95.           taking down a system popup dialog as for Ctrl-Alt-Del on Windows 95.
# Line 5011  w32_wnd_proc (hwnd, msg, wParam, lParam) Line 3724  w32_wnd_proc (hwnd, msg, wParam, lParam)
3724            if (menu_free_timer)            if (menu_free_timer)
3725              {              {
3726                KillTimer (hwnd, menu_free_timer);                KillTimer (hwnd, menu_free_timer);
3727                menu_free_timer = 0;                        menu_free_timer = 0;
3728              }              }
3729          }          }
3730      case WM_MOVE:      case WM_MOVE:
# Line 5036  w32_wnd_proc (hwnd, msg, wParam, lParam) Line 3749  w32_wnd_proc (hwnd, msg, wParam, lParam)
3749    
3750          wp.length = sizeof (WINDOWPLACEMENT);          wp.length = sizeof (WINDOWPLACEMENT);
3751          GetWindowPlacement (hwnd, &wp);          GetWindowPlacement (hwnd, &wp);
3752            
3753          if (wp.showCmd != SW_SHOWMINIMIZED && (lppos->flags & SWP_NOSIZE) == 0)          if (wp.showCmd != SW_SHOWMINIMIZED && (lppos->flags & SWP_NOSIZE) == 0)
3754            {            {
3755              RECT rect;              RECT rect;
# Line 5047  w32_wnd_proc (hwnd, msg, wParam, lParam) Line 3760  w32_wnd_proc (hwnd, msg, wParam, lParam)
3760              DWORD internal_border;              DWORD internal_border;
3761              DWORD scrollbar_extra;              DWORD scrollbar_extra;
3762              RECT wr;              RECT wr;
3763                
3764              wp.length = sizeof(wp);              wp.length = sizeof(wp);
3765              GetWindowRect (hwnd, &wr);              GetWindowRect (hwnd, &wr);
3766                
3767              enter_crit ();              enter_crit ();
3768                
3769              font_width = GetWindowLong (hwnd, WND_FONTWIDTH_INDEX);              font_width = GetWindowLong (hwnd, WND_FONTWIDTH_INDEX);
3770              line_height = GetWindowLong (hwnd, WND_LINEHEIGHT_INDEX);              line_height = GetWindowLong (hwnd, WND_LINEHEIGHT_INDEX);
3771              internal_border = GetWindowLong (hwnd, WND_BORDER_INDEX);              internal_border = GetWindowLong (hwnd, WND_BORDER_INDEX);
3772              scrollbar_extra = GetWindowLong (hwnd, WND_SCROLLBAR_INDEX);              scrollbar_extra = GetWindowLong (hwnd, WND_SCROLLBAR_INDEX);
3773                
3774              leave_crit ();              leave_crit ();
3775                
3776              memset (&rect, 0, sizeof (rect));              memset (&rect, 0, sizeof (rect));
3777              AdjustWindowRect (&rect, GetWindowLong (hwnd, GWL_STYLE),              AdjustWindowRect (&rect, GetWindowLong (hwnd, GWL_STYLE),
3778                                GetMenu (hwnd) != NULL);                                GetMenu (hwnd) != NULL);
3779    
3780              /* Force width and height of client area to be exact              /* Force width and height of client area to be exact
# Line 5072  w32_wnd_proc (hwnd, msg, wParam, lParam) Line 3785  w32_wnd_proc (hwnd, msg, wParam, lParam)
3785              hdiff = (lppos->cy - (rect.bottom - rect.top)              hdiff = (lppos->cy - (rect.bottom - rect.top)
3786                       - 2 * internal_border)                       - 2 * internal_border)
3787                % line_height;                % line_height;
3788                
3789              if (wdiff || hdiff)              if (wdiff || hdiff)
3790                {                {
3791                  /* For right/bottom sizing we can just fix the sizes.                    /* For right/bottom sizing we can just fix the sizes.
3792                     However for top/left sizing we will need to fix the X                     However for top/left sizing we will need to fix the X
3793                     and Y positions as well.  */                     and Y positions as well.  */
3794                    
3795                  lppos->cx -= wdiff;                  lppos->cx -= wdiff;
3796                  lppos->cy -= hdiff;                  lppos->cy -= hdiff;
3797                    
3798                  if (wp.showCmd != SW_SHOWMAXIMIZED                  if (wp.showCmd != SW_SHOWMAXIMIZED
3799                      && (lppos->flags & SWP_NOMOVE) == 0)                      && (lppos->flags & SWP_NOMOVE) == 0)
3800                    {                    {
3801                      if (lppos->x != wr.left || lppos->y != wr.top)                      if (lppos->x != wr.left || lppos->y != wr.top)
# Line 5095  w32_wnd_proc (hwnd, msg, wParam, lParam) Line 3808  w32_wnd_proc (hwnd, msg, wParam, lParam)
3808                          lppos->flags |= SWP_NOMOVE;                          lppos->flags |= SWP_NOMOVE;
3809                        }                        }
3810                    }                    }
3811                    
3812                  return 0;                  return 0;
3813                }                }
3814            }            }
3815        }        }
3816          
3817        goto dflt;        goto dflt;
3818    
3819      case WM_GETMINMAXINFO:      case WM_GETMINMAXINFO:
# Line 5113  w32_wnd_proc (hwnd, msg, wParam, lParam) Line 3826  w32_wnd_proc (hwnd, msg, wParam, lParam)
3826        ((LPMINMAXINFO) lParam)->ptMaxTrackSize.y = 32767;        ((LPMINMAXINFO) lParam)->ptMaxTrackSize.y = 32767;
3827        return 0;        return 0;
3828    
3829        case WM_SETCURSOR:
3830          if (LOWORD (lParam) == HTCLIENT)
3831            return 0;
3832    
3833          goto dflt;
3834    
3835        case WM_EMACS_SETCURSOR:
3836          {
3837            Cursor cursor = (Cursor) wParam;
3838            if (cursor)
3839              SetCursor (cursor);
3840            return 0;
3841          }
3842    
3843      case WM_EMACS_CREATESCROLLBAR:      case WM_EMACS_CREATESCROLLBAR:
3844        return (LRESULT) w32_createscrollbar ((struct frame *) wParam,        return (LRESULT) w32_createscrollbar ((struct frame *) wParam,
3845                                              (struct scroll_bar *) lParam);                                              (struct scroll_bar *) lParam);
# Line 5178  w32_wnd_proc (hwnd, msg, wParam, lParam) Line 3905  w32_wnd_proc (hwnd, msg, wParam, lParam)
3905            CreateCaret (hwnd, NULL, 0,            CreateCaret (hwnd, NULL, 0,
3906                         w32_system_caret_height);                         w32_system_caret_height);
3907          }          }
3908          
3909        if (!SetCaretPos (w32_system_caret_x, w32_system_caret_y))        if (!SetCaretPos (w32_system_caret_x, w32_system_caret_y))
3910          return 0;          return 0;
3911        /* Ensure visible caret gets turned on when requested.  */        /* Ensure visible caret gets turned on when requested.  */
# Line 5209  w32_wnd_proc (hwnd, msg, wParam, lParam) Line 3936  w32_wnd_proc (hwnd, msg, wParam, lParam)
3936            flags |= TPM_LEFTBUTTON;            flags |= TPM_LEFTBUTTON;
3937          else if (button_state & RMOUSE)          else if (button_state & RMOUSE)
3938            flags |= TPM_RIGHTBUTTON;            flags |= TPM_RIGHTBUTTON;
3939            
3940          /* Remember we did a SetCapture on the initial mouse down event,          /* Remember we did a SetCapture on the initial mouse down event,
3941             so for safety, we make sure the capture is cancelled now.  */             so for safety, we make sure the capture is cancelled now.  */
3942          ReleaseCapture ();          ReleaseCapture ();
# Line 5220  w32_wnd_proc (hwnd, msg, wParam, lParam) Line 3947  w32_wnd_proc (hwnd, msg, wParam, lParam)
3947          f = x_window_to_frame (dpyinfo, hwnd);          f = x_window_to_frame (dpyinfo, hwnd);
3948          if (f)          if (f)
3949            f->output_data.w32->menubar_active = 1;            f->output_data.w32->menubar_active = 1;
3950            
3951          if (TrackPopupMenu ((HMENU)wParam, flags, pos->x, pos->y,          if (TrackPopupMenu ((HMENU)wParam, flags, pos->x, pos->y,
3952                              0, hwnd, NULL))                              0, hwnd, NULL))
3953            {            {
3954              MSG amsg;              MSG amsg;
# Line 5254  w32_wnd_proc (hwnd, msg, wParam, lParam) Line 3981  w32_wnd_proc (hwnd, msg, wParam, lParam)
3981            my_post_msg (&wmsg, hwnd, msg, wParam, lParam);            my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3982            return 0;            return 0;
3983          }          }
3984          
3985      dflt:      dflt:
3986        return DefWindowProc (hwnd, msg, wParam, lParam);        return DefWindowProc (hwnd, msg, wParam, lParam);
3987      }      }
3988      
3989    
3990    /* The most common default return code for handled messages is 0.  */    /* The most common default return code for handled messages is 0.  */
3991    return 0;    return 0;
3992  }  }
3993    
3994  void  void
3995  my_create_window (f)  my_create_window (f)
3996       struct frame * f;       struct frame * f;
3997  {  {
# Line 5280  my_create_window (f) Line 4007  my_create_window (f)
4007     indirectly via the Window thread, as we do not need to process Window     indirectly via the Window thread, as we do not need to process Window
4008     messages for the tooltip.  Creating tooltips indirectly also creates     messages for the tooltip.  Creating tooltips indirectly also creates
4009     deadlocks when tooltips are created for menu items.  */     deadlocks when tooltips are created for menu items.  */
4010  void  void
4011  my_create_tip_window (f)  my_create_tip_window (f)
4012       struct frame *f;       struct frame *f;
4013  {  {
# Line 5337  w32_window (f, window_prompting, minibuf Line 4064  w32_window (f, window_prompting, minibuf
4064       for the window manager, so GC relocation won't bother it.       for the window manager, so GC relocation won't bother it.
4065    
4066       Elsewhere we specify the window name for the window manager.  */       Elsewhere we specify the window name for the window manager.  */
4067        
4068    {    {
4069      char *str = (char *) XSTRING (Vx_resource_name)->data;      char *str = (char *) SDATA (Vx_resource_name);
4070      f->namebuf = (char *) xmalloc (strlen (str) + 1);      f->namebuf = (char *) xmalloc (strlen (str) + 1);
4071      strcpy (f->namebuf, str);      strcpy (f->namebuf, str);
4072    }    }
# Line 5406  x_icon (f, parms) Line 4133  x_icon (f, parms)
4133           ? IconicState           ? IconicState
4134           : NormalState));           : NormalState));
4135    
4136    x_text_icon (f, (char *) XSTRING ((!NILP (f->icon_name)    x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
4137                                       ? f->icon_name                                       ? f->icon_name
4138                                       : f->name))->data);                                       : f->name)));
4139  #endif  #endif
4140    
4141    UNBLOCK_INPUT;    UNBLOCK_INPUT;
# Line 5461  unwind_create_frame (frame) Line 4188  unwind_create_frame (frame)
4188  #ifdef GLYPH_DEBUG  #ifdef GLYPH_DEBUG
4189        struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);        struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
4190  #endif  #endif
4191          
4192        x_free_frame_resources (f);        x_free_frame_resources (f);
4193    
4194        /* Check that reference counts are indeed correct.  */        /* Check that reference counts are indeed correct.  */
# Line 5470  unwind_create_frame (frame) Line 4197  unwind_create_frame (frame)
4197    
4198        return Qt;        return Qt;
4199      }      }
4200      
4201    return Qnil;    return Qnil;
4202  }  }
4203    
# Line 5495  This function is an internal primitive-- Line 4222  This function is an internal primitive--
4222    int minibuffer_only = 0;    int minibuffer_only = 0;
4223    long window_prompting = 0;    long window_prompting = 0;
4224    int width, height;    int width, height;
4225    int count = BINDING_STACK_SIZE ();    int count = SPECPDL_INDEX ();
4226    struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;    struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4227    Lisp_Object display;    Lisp_Object display;
4228    struct w32_display_info *dpyinfo = NULL;    struct w32_display_info *dpyinfo = NULL;
# Line 5557  This function is an internal primitive-- Line 4284  This function is an internal primitive--
4284    
4285    /* Note that Windows does support scroll bars.  */    /* Note that Windows does support scroll bars.  */
4286    FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;    FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
4287    
4288    /* By default, make scrollbars the system standard width. */    /* By default, make scrollbars the system standard width. */
4289    f->scroll_bar_pixel_width = GetSystemMetrics (SM_CXVSCROLL);    f->scroll_bar_pixel_width = GetSystemMetrics (SM_CXVSCROLL);
4290    
# Line 5618  This function is an internal primitive-- Line 4346  This function is an internal primitive--
4346        {        {
4347          tem = Fquery_fontset (font, Qnil);          tem = Fquery_fontset (font, Qnil);
4348          if (STRINGP (tem))          if (STRINGP (tem))
4349            font = x_new_fontset (f, XSTRING (tem)->data);            font = x_new_fontset (f, SDATA (tem));
4350          else          else
4351            font = x_new_font (f, XSTRING (font)->data);            font = x_new_font (f, SDATA (font));
4352        }        }
4353      /* Try out a font which we hope has bold and italic variations.  */      /* Try out a font which we hope has bold and italic variations.  */
4354      if (!STRINGP (font))      if (!STRINGP (font))
# Line 5634  This function is an internal primitive-- Line 4362  This function is an internal primitive--
4362      if (! STRINGP (font))      if (! STRINGP (font))
4363        font = build_string ("Fixedsys");        font = build_string ("Fixedsys");
4364    
4365      x_default_parameter (f, parms, Qfont, font,      x_default_parameter (f, parms, Qfont, font,
4366                           "font", "Font", RES_TYPE_STRING);                           "font", "Font", RES_TYPE_STRING);
4367    }    }
4368    
# Line 5687  This function is an internal primitive-- Line 4415  This function is an internal primitive--
4415       end up in init_iterator with a null face cache, which should not       end up in init_iterator with a null face cache, which should not
4416       happen.  */       happen.  */
4417    init_frame_faces (f);    init_frame_faces (f);
4418      
4419    x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),    x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
4420                         "menuBar", "MenuBar", RES_TYPE_NUMBER);                         "menuBar", "MenuBar", RES_TYPE_NUMBER);
4421    x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),    x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
# Line 5703  This function is an internal primitive-- Line 4431  This function is an internal primitive--
4431    f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW;    f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW;
4432    f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;    f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;
4433    
4434    /* Add the tool-bar height to the initial frame height so that the    f->output_data.w32->text_cursor = w32_load_cursor (IDC_IBEAM);
4435       user gets a text display area of the size he specified with -g or    f->output_data.w32->nontext_cursor = w32_load_cursor (IDC_ARROW);
4436       via .Xdefaults.  Later changes of the tool-bar height don't    f->output_data.w32->modeline_cursor = w32_load_cursor (IDC_ARROW);
4437       change the frame size.  This is done so that users can create    f->output_data.w32->hand_cursor = w32_load_cursor (IDC_HAND);
4438       tall Emacs frames without having to guess how tall the tool-bar    f->output_data.w32->hourglass_cursor = w32_load_cursor (IDC_WAIT);
4439       will get.  */    f->output_data.w32->horizontal_drag_cursor = w32_load_cursor (IDC_SIZEWE);
   if (FRAME_TOOL_BAR_LINES (f))  
     {  
       int margin, relief, bar_height;  
         
       relief = (tool_bar_button_relief >= 0  
                 ? tool_bar_button_relief  
                 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);  
   
       if (INTEGERP (Vtool_bar_button_margin)  
           && XINT (Vtool_bar_button_margin) > 0)  
         margin = XFASTINT (Vtool_bar_button_margin);  
       else if (CONSP (Vtool_bar_button_margin)  
                && INTEGERP (XCDR (Vtool_bar_button_margin))  
                && XINT (XCDR (Vtool_bar_button_margin)) > 0)  
         margin = XFASTINT (XCDR (Vtool_bar_button_margin));  
       else  
         margin = 0;  
             
       bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief;  
       f->height += (bar_height + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f);  
     }  
   
   window_prompting = x_figure_window_size (f, parms);  
   
   if (window_prompting & XNegative)  
     {  
       if (window_prompting & YNegative)  
         f->output_data.w32->win_gravity = SouthEastGravity;  
       else  
         f->output_data.w32->win_gravity = NorthEastGravity;  
     }  
   else  
     {  
       if (window_prompting & YNegative)  
         f->output_data.w32->win_gravity = SouthWestGravity;  
       else  
         f->output_data.w32->win_gravity = NorthWestGravity;  
     }  
4440    
4441    f->output_data.w32->size_hint_flags = window_prompting;    window_prompting = x_figure_window_size (f, parms, 1);
4442    
4443    tem = w32_get_arg (parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);    tem = w32_get_arg (parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
4444    f->no_split = minibuffer_only || EQ (tem, Qt);    f->no_split = minibuffer_only || EQ (tem, Qt);
# Line 5824  This function is an internal primitive-- Line 4514  This function is an internal primitive--
4514          ;          ;
4515      }      }
4516    UNGCPRO;    UNGCPRO;
4517      
4518    /* Make sure windows on this frame appear in calls to next-window    /* Make sure windows on this frame appear in calls to next-window
4519       and similar functions.  */       and similar functions.  */
4520    Vwindow_list = Qnil;    Vwindow_list = Qnil;
4521      
4522    return unbind_to (count, frame);    return unbind_to (count, frame);
4523  }  }
4524    
# Line 5909  w32_load_system_font (f,fontname,size) Line 4599  w32_load_system_font (f,fontname,size)
4599          for (tail = font_names; CONSP (tail); tail = XCDR (tail))          for (tail = font_names; CONSP (tail); tail = XCDR (tail))
4600            if (dpyinfo->font_table[i].name            if (dpyinfo->font_table[i].name
4601                && (!strcmp (dpyinfo->font_table[i].name,                && (!strcmp (dpyinfo->font_table[i].name,
4602                             XSTRING (XCAR (tail))->data)                             SDATA (XCAR (tail)))
4603                    || !strcmp (dpyinfo->font_table[i].full_name,                    || !strcmp (dpyinfo->font_table[i].full_name,
4604                                XSTRING (XCAR (tail))->data)))                                SDATA (XCAR (tail)))))
4605              return (dpyinfo->font_table + i);              return (dpyinfo->font_table + i);
4606    
4607        fontname = (char *) XSTRING (XCAR (font_names))->data;        fontname = (char *) SDATA (XCAR (font_names));
4608      }      }
4609    else if (w32_strict_fontnames)    else if (w32_strict_fontnames)
4610      {      {
# Line 5951  w32_load_system_font (f,fontname,size) Line 4641  w32_load_system_font (f,fontname,size)
4641             ended up with. */             ended up with. */
4642        return NULL;        return NULL;
4643    
4644      /* Specify anti-aliasing to prevent Cleartype fonts being used,      lf.lfQuality = DEFAULT_QUALITY;
        since those fonts leave garbage behind.  */  
     lf.lfQuality = ANTIALIASED_QUALITY;  
4645    
4646      font = (XFontStruct *) xmalloc (sizeof (XFontStruct));      font = (XFontStruct *) xmalloc (sizeof (XFontStruct));
4647      bzero (font, sizeof (*font));      bzero (font, sizeof (*font));
# Line 5965  w32_load_system_font (f,fontname,size) Line 4653  w32_load_system_font (f,fontname,size)
4653    
4654      font->hfont = CreateFontIndirect (&lf);      font->hfont = CreateFontIndirect (&lf);
4655    
4656      if (font->hfont == NULL)      if (font->hfont == NULL)
4657        {        {
4658          ok = FALSE;          ok = FALSE;
4659        }        }
4660      else      else
4661        {        {
4662          HDC hdc;          HDC hdc;
4663          HANDLE oldobj;          HANDLE oldobj;
# Line 6122  int size; Line 4810  int size;
4810        char *bdf_name, *bdf_file;        char *bdf_name, *bdf_file;
4811        Lisp_Object bdf_pair;        Lisp_Object bdf_pair;
4812    
4813        bdf_name = XSTRING (XCAR (bdf_fonts))->data;        bdf_name = SDATA (XCAR (bdf_fonts));
4814        bdf_pair = Fassoc (XCAR (bdf_fonts), Vw32_bdf_filename_alist);        bdf_pair = Fassoc (XCAR (bdf_fonts), Vw32_bdf_filename_alist);
4815        bdf_file = XSTRING (XCDR (bdf_pair))->data;        bdf_file = SDATA (XCDR (bdf_pair));
4816    
4817        retval = w32_load_bdf_font (f, bdf_name, size, bdf_file);        retval = w32_load_bdf_font (f, bdf_name, size, bdf_file);
4818    
# Line 6138  int size; Line 4826  int size;
4826  }  }
4827    
4828    
4829  void  void
4830  w32_unload_font (dpyinfo, font)  w32_unload_font (dpyinfo, font)
4831       struct w32_display_info *dpyinfo;       struct w32_display_info *dpyinfo;
4832       XFontStruct * font;       XFontStruct * font;
4833  {  {
4834    if (font)    if (font)
4835      {      {
4836        if (font->per_char) xfree (font->per_char);        if (font->per_char) xfree (font->per_char);
4837        if (font->bdf) w32_free_bdf_font (font->bdf);        if (font->bdf) w32_free_bdf_font (font->bdf);
# Line 6176  w32_unload_font (dpyinfo, font) Line 4864  w32_unload_font (dpyinfo, font)
4864   *      )   *      )
4865   */   */
4866    
4867  static LONG  static LONG
4868  x_to_w32_weight (lpw)  x_to_w32_weight (lpw)
4869       char * lpw;       char * lpw;
4870  {  {
# Line 6197  x_to_w32_weight (lpw) Line 4885  x_to_w32_weight (lpw)
4885  }  }
4886    
4887    
4888  static char *  static char *
4889  w32_to_x_weight (fnweight)  w32_to_x_weight (fnweight)
4890       int fnweight;       int fnweight;
4891  {  {
# Line 6384  w32_to_x_charset (fncharset) Line 5072  w32_to_x_charset (fncharset)
5072        sprintf (buf, "*-#%u", fncharset);        sprintf (buf, "*-#%u", fncharset);
5073        return buf;        return buf;
5074      }      }
5075      
5076    {    {
5077      Lisp_Object rest;      Lisp_Object rest;
5078      char * best_match = NULL;      char * best_match = NULL;
# Line 6410  w32_to_x_charset (fncharset) Line 5098  w32_to_x_charset (fncharset)
5098              || !SYMBOLP (XCAR (XCDR (this_entry))))              || !SYMBOLP (XCAR (XCDR (this_entry))))
5099            continue;            continue;
5100    
5101          x_charset = XSTRING (XCAR (this_entry))->data;          x_charset = SDATA (XCAR (this_entry));
5102          w32_charset = XCAR (XCDR (this_entry));          w32_charset = XCAR (XCDR (this_entry));
5103          codepage = XCDR (XCDR (this_entry));          codepage = XCDR (XCDR (this_entry));
5104    
# Line 6438  w32_to_x_charset (fncharset) Line 5126  w32_to_x_charset (fncharset)
5126                  int this_enc = atoi (x_charset + 8);                  int this_enc = atoi (x_charset + 8);
5127                  if (this_enc > 0 && this_enc < best_enc)                  if (this_enc > 0 && this_enc < best_enc)
5128                    best_match = x_charset;                    best_match = x_charset;
5129                }                                }
5130            }            }
5131        }        }
5132    
# Line 6545  w32_to_all_x_charsets (fncharset) Line 5233  w32_to_all_x_charsets (fncharset)
5233        sprintf (buf, "*-#%u", fncharset);        sprintf (buf, "*-#%u", fncharset);
5234        return Fcons (build_string (buf), Qnil);        return Fcons (build_string (buf), Qnil);
5235      }      }
5236      
5237    {    {
5238      Lisp_Object rest;      Lisp_Object rest;
5239      /* Look through w32-charset-info-alist for the character set.      /* Look through w32-charset-info-alist for the character set.
# Line 6596  w32_to_all_x_charsets (fncharset) Line 5284  w32_to_all_x_charsets (fncharset)
5284  /* Get the Windows codepage corresponding to the specified font.  The  /* Get the Windows codepage corresponding to the specified font.  The
5285     charset info in the font name is used to look up     charset info in the font name is used to look up
5286     w32-charset-to-codepage-alist.  */     w32-charset-to-codepage-alist.  */
5287  int  int
5288  w32_codepage_for_font (char *fontname)  w32_codepage_for_font (char *fontname)
5289  {  {
5290    Lisp_Object codepage, entry;    Lisp_Object codepage, entry;
# Line 6647  w32_codepage_for_font (char *fontname) Line 5335  w32_codepage_for_font (char *fontname)
5335  }  }
5336    
5337    
5338  static BOOL  static BOOL
5339  w32_to_x_font (lplogfont, lpxstr, len, specific_charset)  w32_to_x_font (lplogfont, lpxstr, len, specific_charset)
5340       LOGFONT * lplogfont;       LOGFONT * lplogfont;
5341       char * lpxstr;       char * lpxstr;
# Line 6682  w32_to_x_font (lplogfont, lpxstr, len, s Line 5370  w32_to_x_font (lplogfont, lpxstr, len, s
5370    coding.src_multibyte = 0;    coding.src_multibyte = 0;
5371    coding.dst_multibyte = 1;    coding.dst_multibyte = 1;
5372    coding.mode |= CODING_MODE_LAST_BLOCK;    coding.mode |= CODING_MODE_LAST_BLOCK;
5373      /* We explicitely disable composition handling because selection
5374         data should not contain any composition sequence.  */
5375      coding.composing = COMPOSITION_DISABLED;
5376    bufsz = decoding_buffer_size (&coding, LF_FACESIZE);    bufsz = decoding_buffer_size (&coding, LF_FACESIZE);
5377    
5378    fontname = alloca(sizeof(*fontname) * bufsz);    fontname = alloca(sizeof(*fontname) * bufsz);
# Line 6727  w32_to_x_font (lplogfont, lpxstr, len, s Line 5418  w32_to_x_font (lplogfont, lpxstr, len, s
5418               ? 'p' : 'c',                            /* spacing */               ? 'p' : 'c',                            /* spacing */
5419               width_pixels,                           /* avg width */               width_pixels,                           /* avg width */
5420               specific_charset ? specific_charset               specific_charset ? specific_charset
5421               : w32_to_x_charset (lplogfont->lfCharSet)               : w32_to_x_charset (lplogfont->lfCharSet)
5422               /* charset registry and encoding */               /* charset registry and encoding */
5423               );               );
5424    
# Line 6735  w32_to_x_font (lplogfont, lpxstr, len, s Line 5426  w32_to_x_font (lplogfont, lpxstr, len, s
5426    return (TRUE);    return (TRUE);
5427  }  }
5428    
5429  static BOOL  static BOOL
5430  x_to_w32_font (lpxstr, lplogfont)  x_to_w32_font (lpxstr, lplogfont)
5431       char * lpxstr;       char * lpxstr;
5432       LOGFONT * lplogfont;       LOGFONT * lplogfont;
# Line 6770  x_to_w32_font (lpxstr, lplogfont) Line 5461  x_to_w32_font (lpxstr, lplogfont)
5461     * format:     * format:
5462     *   "<font name>[:height in pixels[:width in pixels[:weight]]]"     *   "<font name>[:height in pixels[:width in pixels[:weight]]]"
5463     */     */
5464      
5465    if (*lpxstr == '-')    if (*lpxstr == '-')
5466      {      {
5467        int fields, tem;        int fields, tem;
# Line 7038  xlfd_strip_height (char *fontname) Line 5729  xlfd_strip_height (char *fontname)
5729  }  }
5730    
5731  /* Assume parameter 1 is fully qualified, no wildcards. */  /* Assume parameter 1 is fully qualified, no wildcards. */
5732  static BOOL  static BOOL
5733  w32_font_match (fontname, pattern)  w32_font_match (fontname, pattern)
5734      char * fontname;      char * fontname;
5735      char * pattern;      char * pattern;
# Line 7100  w32_font_match (fontname, pattern) Line 5791  w32_font_match (fontname, pattern)
5791     font from each family, the second pass lists all the fonts from     font from each family, the second pass lists all the fonts from
5792     each family.  */     each family.  */
5793    
5794  typedef struct enumfont_t  typedef struct enumfont_t
5795  {  {
5796    HDC hdc;    HDC hdc;
5797    int numFonts;    int numFonts;
# Line 7115  static void Line 5806  static void
5806  enum_font_maybe_add_to_list (enumfont_t *, LOGFONT *, char *, Lisp_Object);  enum_font_maybe_add_to_list (enumfont_t *, LOGFONT *, char *, Lisp_Object);
5807    
5808    
5809  static int CALLBACK  static int CALLBACK
5810  enum_font_cb2 (lplf, lptm, FontType, lpef)  enum_font_cb2 (lplf, lptm, FontType, lpef)
5811      ENUMLOGFONT * lplf;      ENUMLOGFONT * lplf;
5812      NEWTEXTMETRIC * lptm;      NEWTEXTMETRIC * lptm;
# Line 7190  enum_font_cb2 (lplf, lptm, FontType, lpe Line 5881  enum_font_cb2 (lplf, lptm, FontType, lpe
5881    
5882      if (!NILP (lpef->pattern))      if (!NILP (lpef->pattern))
5883        {        {
5884          charset = xlfd_charset_of_font (XSTRING(lpef->pattern)->data);          charset = xlfd_charset_of_font (SDATA (lpef->pattern));
5885    
5886          /* We already checked charsets above, but DEFAULT_CHARSET          /* We already checked charsets above, but DEFAULT_CHARSET
5887             slipped through.  So only allow exact matches for DEFAULT_CHARSET.  */             slipped through.  So only allow exact matches for DEFAULT_CHARSET.  */
# Line 7210  enum_font_cb2 (lplf, lptm, FontType, lpe Line 5901  enum_font_cb2 (lplf, lptm, FontType, lpe
5901      for ( ; CONSP (charset_list); charset_list = Fcdr (charset_list))      for ( ; CONSP (charset_list); charset_list = Fcdr (charset_list))
5902        {        {
5903          Lisp_Object this_charset = Fcar (charset_list);          Lisp_Object this_charset = Fcar (charset_list);
5904          charset = XSTRING (this_charset)->data;          charset = SDATA (this_charset);
5905    
5906          /* List bold and italic variations if w32-enable-synthesized-fonts          /* List bold and italic variations if w32-enable-synthesized-fonts
5907             is non-nil and this is a plain font.  */             is non-nil and this is a plain font.  */
# Line 7255  enum_font_maybe_add_to_list (lpef, logfo Line 5946  enum_font_maybe_add_to_list (lpef, logfo
5946      return;      return;
5947    
5948    if (NILP (lpef->pattern)    if (NILP (lpef->pattern)
5949        || w32_font_match (buf, XSTRING (lpef->pattern)->data))        || w32_font_match (buf, SDATA (lpef->pattern)))
5950      {      {
5951        /* Check if we already listed this font.  This may happen if        /* Check if we already listed this font.  This may happen if
5952           w32_enable_synthesized_fonts is non-nil, and there are real           w32_enable_synthesized_fonts is non-nil, and there are real
# Line 7271  enum_font_maybe_add_to_list (lpef, logfo Line 5962  enum_font_maybe_add_to_list (lpef, logfo
5962  }  }
5963    
5964    
5965  static int CALLBACK  static int CALLBACK
5966  enum_font_cb1 (lplf, lptm, FontType, lpef)  enum_font_cb1 (lplf, lptm, FontType, lpef)
5967       ENUMLOGFONT * lplf;       ENUMLOGFONT * lplf;
5968       NEWTEXTMETRIC * lptm;       NEWTEXTMETRIC * lptm;
# Line 7329  static Lisp_Object w32_list_bdf_fonts (L Line 6020  static Lisp_Object w32_list_bdf_fonts (L
6020    int n_fonts = 0;    int n_fonts = 0;
6021    
6022    list = Vw32_bdf_filename_alist;    list = Vw32_bdf_filename_alist;
6023    ptnstr = XSTRING (pattern)->data;    ptnstr = SDATA (pattern);
6024    
6025    for ( ; CONSP (list); list = XCDR (list))    for ( ; CONSP (list); list = XCDR (list))
6026      {      {
6027        tem = XCAR (list);        tem = XCAR (list);
6028        if (CONSP (tem))        if (CONSP (tem))
6029          fontname = XSTRING (XCAR (tem))->data;          fontname = SDATA (XCAR (tem));
6030        else if (STRINGP (tem))        else if (STRINGP (tem))
6031          fontname = XSTRING (tem)->data;          fontname = SDATA (tem);
6032        else        else
6033          continue;          continue;
6034    
# Line 7345  static Lisp_Object w32_list_bdf_fonts (L Line 6036  static Lisp_Object w32_list_bdf_fonts (L
6036          {          {
6037            newlist = Fcons (XCAR (tem), newlist);            newlist = Fcons (XCAR (tem), newlist);
6038            n_fonts++;            n_fonts++;
6039            if (n_fonts >= max_names)            if (max_names >= 0 && n_fonts >= max_names)
6040              break;              break;
6041          }          }
6042      }      }
# Line 7359  static Lisp_Object w32_list_bdf_fonts (L Line 6050  static Lisp_Object w32_list_bdf_fonts (L
6050     to be listed.  Frame F NULL means we have not yet created any     to be listed.  Frame F NULL means we have not yet created any
6051     frame, which means we can't get proper size info, as we don't have     frame, which means we can't get proper size info, as we don't have
6052     a device context to use for GetTextMetrics.     a device context to use for GetTextMetrics.
6053     MAXNAMES sets a limit on how many fonts to match.  */     MAXNAMES sets a limit on how many fonts to match.  If MAXNAMES is
6054       negative, then all matching fonts are returned.  */
6055    
6056  Lisp_Object  Lisp_Object
6057  w32_list_fonts (f, pattern, size, maxnames)  w32_list_fonts (f, pattern, size, maxnames)
# Line 7389  w32_list_fonts (f, pattern, size, maxnam Line 6081  w32_list_fonts (f, pattern, size, maxnam
6081    
6082        /* Avoid expensive EnumFontFamilies functions if we are not        /* Avoid expensive EnumFontFamilies functions if we are not
6083           going to be able to output one of these anyway. */           going to be able to output one of these anyway. */
6084        codepage = w32_codepage_for_font (XSTRING (tpat)->data);        codepage = w32_codepage_for_font (SDATA (tpat));
6085        if (codepage != CP_8BIT && codepage != CP_UNICODE        if (codepage != CP_8BIT && codepage != CP_UNICODE
6086            && codepage != CP_DEFAULT && codepage != CP_UNKNOWN            && codepage != CP_DEFAULT && codepage != CP_UNKNOWN
6087            && !IsValidCodePage(codepage))            && !IsValidCodePage(codepage))
# Line 7416  w32_list_fonts (f, pattern, size, maxnam Line 6108  w32_list_fonts (f, pattern, size, maxnam
6108        /* Use EnumFontFamiliesEx where it is available, as it knows        /* Use EnumFontFamiliesEx where it is available, as it knows
6109           about character sets.  Fall back to EnumFontFamilies for           about character sets.  Fall back to EnumFontFamilies for
6110           older versions of NT that don't support the 'Ex function.  */           older versions of NT that don't support the 'Ex function.  */
6111        x_to_w32_font (XSTRING (tpat)->data, &ef.logfont);        x_to_w32_font (SDATA (tpat), &ef.logfont);
6112        {        {
6113          LOGFONT font_match_pattern;          LOGFONT font_match_pattern;
6114          HMODULE gdi32 = GetModuleHandle ("gdi32.dll");          HMODULE gdi32 = GetModuleHandle ("gdi32.dll");
# Line 7458  w32_list_fonts (f, pattern, size, maxnam Line 6150  w32_list_fonts (f, pattern, size, maxnam
6150    
6151        newlist = second_best = Qnil;        newlist = second_best = Qnil;
6152    
6153        /* Make a list of the fonts that have the right width.  */                  /* Make a list of the fonts that have the right width.  */
6154        for (; CONSP (list); list = XCDR (list))        for (; CONSP (list); list = XCDR (list))
6155          {          {
6156            int found_size;            int found_size;
# Line 7472  w32_list_fonts (f, pattern, size, maxnam Line 6164  w32_list_fonts (f, pattern, size, maxnam
6164              {              {
6165                newlist = Fcons (XCAR (tem), newlist);                newlist = Fcons (XCAR (tem), newlist);
6166                n_fonts++;                n_fonts++;
6167                if (n_fonts >= maxnames)                if (maxnames >= 0 && n_fonts >= maxnames)
6168                  break;                  break;
6169                else                else
6170                  continue;                  continue;
# Line 7486  w32_list_fonts (f, pattern, size, maxnam Line 6178  w32_list_fonts (f, pattern, size, maxnam
6178                HDC hdc;                HDC hdc;
6179                HANDLE oldobj;                HANDLE oldobj;
6180    
6181                if (!x_to_w32_font (XSTRING (XCAR (tem))->data, &lf))                if (!x_to_w32_font (SDATA (XCAR (tem)), &lf))
6182                  continue;                  continue;
6183    
6184                BLOCK_INPUT;                BLOCK_INPUT;
# Line 7511  w32_list_fonts (f, pattern, size, maxnam Line 6203  w32_list_fonts (f, pattern, size, maxnam
6203              {              {
6204                newlist = Fcons (XCAR (tem), newlist);                newlist = Fcons (XCAR (tem), newlist);
6205                n_fonts++;                n_fonts++;
6206                if (n_fonts >= maxnames)                if (maxnames >= 0 && n_fonts >= maxnames)
6207                  break;                  break;
6208              }              }
6209            /* keep track of the closest matching size in case            /* keep track of the closest matching size in case
# Line 7520  w32_list_fonts (f, pattern, size, maxnam Line 6212  w32_list_fonts (f, pattern, size, maxnam
6212              {              {
6213                if (NILP (second_best))                if (NILP (second_best))
6214                  second_best = tem;                  second_best = tem;
6215                      
6216                else if (found_size < size)                else if (found_size < size)
6217                  {                  {
6218                    if (XINT (XCDR (second_best)) > size                    if (XINT (XCDR (second_best)) > size
# Line 7547  w32_list_fonts (f, pattern, size, maxnam Line 6239  w32_list_fonts (f, pattern, size, maxnam
6239      }      }
6240    
6241    /* Include any bdf fonts.  */    /* Include any bdf fonts.  */
6242    if (n_fonts < maxnames)    if (n_fonts < maxnames || maxnames < 0)
6243    {    {
6244      Lisp_Object combined[2];      Lisp_Object combined[2];
6245      combined[0] = w32_list_bdf_fonts (pattern, maxnames - n_fonts);      combined[0] = w32_list_bdf_fonts (pattern, maxnames - n_fonts);
# Line 7633  w32_find_bdf_fonts_in_dir (Lisp_Object d Line 6325  w32_find_bdf_fonts_in_dir (Lisp_Object d
6325    for ( ; CONSP(filelist); filelist = XCDR (filelist))    for ( ; CONSP(filelist); filelist = XCDR (filelist))
6326      {      {
6327        Lisp_Object filename = XCAR (filelist);        Lisp_Object filename = XCAR (filelist);
6328        if (w32_BDF_to_x_font (XSTRING (filename)->data, fontname, 100))        if (w32_BDF_to_x_font (SDATA (filename), fontname, 100))
6329            store_in_alist (&list, build_string (fontname), filename);            store_in_alist (&list, build_string (fontname), filename);
6330      }      }
6331    return list;    return list;
# Line 7678  DEFUN ("xw-color-defined-p", Fxw_color_d Line 6370  DEFUN ("xw-color-defined-p", Fxw_color_d
6370    
6371    CHECK_STRING (color);    CHECK_STRING (color);
6372    
6373    if (w32_defined_color (f, XSTRING (color)->data, &foo, 0))    if (w32_defined_color (f, SDATA (color), &foo, 0))
6374      return Qt;      return Qt;
6375    else    else
6376      return Qnil;      return Qnil;
# Line 7694  DEFUN ("xw-color-values", Fxw_color_valu Line 6386  DEFUN ("xw-color-values", Fxw_color_valu
6386    
6387    CHECK_STRING (color);    CHECK_STRING (color);
6388    
6389    if (w32_defined_color (f, XSTRING (color)->data, &foo, 0))    if (w32_defined_color (f, SDATA (color), &foo, 0))
6390      {      {
6391        Lisp_Object rgb[3];        Lisp_Object rgb[3];
6392    
# Line 7806  If omitted or nil, that stands for the s Line 6498  If omitted or nil, that stands for the s
6498       and because probably is more meaningful on Windows anyway */       and because probably is more meaningful on Windows anyway */
6499    if (cap < 0)    if (cap < 0)
6500      cap = 1 << min(dpyinfo->n_planes * dpyinfo->n_cbits, 24);      cap = 1 << min(dpyinfo->n_planes * dpyinfo->n_cbits, 24);
6501      
6502    ReleaseDC (dpyinfo->root_window, hdc);    ReleaseDC (dpyinfo->root_window, hdc);
6503      
6504    return make_number (cap);    return make_number (cap);
6505  }  }
6506    
# Line 7880  If omitted or nil, that stands for the s Line 6572  If omitted or nil, that stands for the s
6572    int cap;    int cap;
6573    
6574    hdc = GetDC (dpyinfo->root_window);    hdc = GetDC (dpyinfo->root_window);
6575      
6576    cap = GetDeviceCaps (hdc, VERTSIZE);    cap = GetDeviceCaps (hdc, VERTSIZE);
6577      
6578    ReleaseDC (dpyinfo->root_window, hdc);    ReleaseDC (dpyinfo->root_window, hdc);
6579      
6580    return make_number (cap);    return make_number (cap);
6581  }  }
6582    
# Line 7902  If omitted or nil, that stands for the s Line 6594  If omitted or nil, that stands for the s
6594    int cap;    int cap;
6595    
6596    hdc = GetDC (dpyinfo->root_window);    hdc = GetDC (dpyinfo->root_window);
6597      
6598    cap = GetDeviceCaps (hdc, HORZSIZE);    cap = GetDeviceCaps (hdc, HORZSIZE);
6599      
6600    ReleaseDC (dpyinfo->root_window, hdc);    ReleaseDC (dpyinfo->root_window, hdc);
6601      
6602    return make_number (cap);    return make_number (cap);
6603  }  }
6604    
# Line 8025  x_display_info_for_name (name) Line 6717  x_display_info_for_name (name)
6717    validate_x_resource_name ();    validate_x_resource_name ();
6718    
6719    dpyinfo = w32_term_init (name, (unsigned char *)0,    dpyinfo = w32_term_init (name, (unsigned char *)0,
6720                               (char *) XSTRING (Vx_resource_name)->data);                               (char *) SDATA (Vx_resource_name));
6721    
6722    if (dpyinfo == 0)    if (dpyinfo == 0)
6723      error ("Cannot connect to server %s", XSTRING (name)->data);      error ("Cannot connect to server %s", SDATA (name));
6724    
6725    w32_in_use = 1;    w32_in_use = 1;
6726    XSETFASTINT (Vwindow_system_version, 3);    XSETFASTINT (Vwindow_system_version, 3);
# Line 8083  terminate Emacs if we can't open the con Line 6775  terminate Emacs if we can't open the con
6775      Vw32_color_map = Fw32_default_color_map ();      Vw32_color_map = Fw32_default_color_map ();
6776    
6777    if (! NILP (xrm_string))    if (! NILP (xrm_string))
6778      xrm_option = (unsigned char *) XSTRING (xrm_string)->data;      xrm_option = (unsigned char *) SDATA (xrm_string);
6779    else    else
6780      xrm_option = (unsigned char *) 0;      xrm_option = (unsigned char *) 0;
6781    
# Line 8092  terminate Emacs if we can't open the con Line 6784  terminate Emacs if we can't open the con
6784    {    {
6785      char basename[ MAX_PATH ], *str;      char basename[ MAX_PATH ], *str;
6786    
6787      strcpy (basename, XSTRING (Vinvocation_name)->data);      strcpy (basename, SDATA (Vinvocation_name));
6788      str = strrchr (basename, '.');      str = strrchr (basename, '.');
6789      if (str) *str = 0;      if (str) *str = 0;
6790      Vinvocation_name = build_string (basename);      Vinvocation_name = build_string (basename);
# Line 8104  terminate Emacs if we can't open the con Line 6796  terminate Emacs if we can't open the con
6796    /* This is what opens the connection and sets x_current_display.    /* This is what opens the connection and sets x_current_display.
6797       This also initializes many symbols, such as those used for input.  */       This also initializes many symbols, such as those used for input.  */
6798    dpyinfo = w32_term_init (display, xrm_option,    dpyinfo = w32_term_init (display, xrm_option,
6799                               (char *) XSTRING (Vx_resource_name)->data);                               (char *) SDATA (Vx_resource_name));
6800    
6801    if (dpyinfo == 0)    if (dpyinfo == 0)
6802      {      {
6803        if (!NILP (must_succeed))        if (!NILP (must_succeed))
6804          fatal ("Cannot connect to server %s.\n",          fatal ("Cannot connect to server %s.\n",
6805                 XSTRING (display)->data);                 SDATA (display));
6806        else        else
6807          error ("Cannot connect to server %s", XSTRING (display)->data);          error ("Cannot connect to server %s", SDATA (display));
6808      }      }
6809    
6810    w32_in_use = 1;    w32_in_use = 1;
# Line 8271  valid_image_p (object) Line 6963  valid_image_p (object)
6963       Lisp_Object object;       Lisp_Object object;
6964  {  {
6965    int valid_p = 0;    int valid_p = 0;
6966      
6967    if (CONSP (object) && EQ (XCAR (object), Qimage))    if (CONSP (object) && EQ (XCAR (object), Qimage))
6968      {      {
6969        Lisp_Object tem;        Lisp_Object tem;
# Line 8396  parse_image_spec (spec, keywords, nkeywo Line 7088  parse_image_spec (spec, keywords, nkeywo
7088    
7089        /* Find key in KEYWORDS.  Error if not found.  */        /* Find key in KEYWORDS.  Error if not found.  */
7090        for (i = 0; i < nkeywords; ++i)        for (i = 0; i < nkeywords; ++i)
7091          if (strcmp (keywords[i].name, XSTRING (SYMBOL_NAME (key))->data) == 0)          if (strcmp (keywords[i].name, SDATA (SYMBOL_NAME (key))) == 0)
7092            break;            break;
7093    
7094        if (i == nkeywords)        if (i == nkeywords)
# Line 8406  parse_image_spec (spec, keywords, nkeywo Line 7098  parse_image_spec (spec, keywords, nkeywo
7098           was found more than once, it's an error.  */           was found more than once, it's an error.  */
7099        keywords[i].value = value;        keywords[i].value = value;
7100        ++keywords[i].count;        ++keywords[i].count;
7101          
7102        if (keywords[i].count > 1)        if (keywords[i].count > 1)
7103          return 0;          return 0;
7104    
# Line 8461  parse_image_spec (spec, keywords, nkeywo Line 7153  parse_image_spec (spec, keywords, nkeywo
7153    
7154          case IMAGE_FUNCTION_VALUE:          case IMAGE_FUNCTION_VALUE:
7155            value = indirect_function (value);            value = indirect_function (value);
7156            if (SUBRP (value)            if (SUBRP (value)
7157                || COMPILEDP (value)                || COMPILEDP (value)
7158                || (CONSP (value) && EQ (XCAR (value), Qlambda)))                || (CONSP (value) && EQ (XCAR (value), Qlambda)))
7159              break;              break;
# Line 8510  image_spec_value (spec, key, found) Line 7202  image_spec_value (spec, key, found)
7202       int *found;       int *found;
7203  {  {
7204    Lisp_Object tail;    Lisp_Object tail;
7205      
7206    xassert (valid_image_p (spec));    xassert (valid_image_p (spec));
7207    
7208    for (tail = XCDR (spec);    for (tail = XCDR (spec);
# Line 8524  image_spec_value (spec, key, found) Line 7216  image_spec_value (spec, key, found)
7216            return XCAR (XCDR (tail));            return XCAR (XCDR (tail));
7217          }          }
7218      }      }
7219      
7220    if (found)    if (found)
7221      *found = 0;      *found = 0;
7222    return Qnil;    return Qnil;
7223  }  }
7224        
7225    
7226  DEFUN ("image-size", Fimage_size, Simage_size, 1, 3, 0,  DEFUN ("image-size", Fimage_size, Simage_size, 1, 3, 0,
7227         doc: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).         doc: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
# Line 8550  or omitted means use the selected frame. Line 7242  or omitted means use the selected frame.
7242        struct image *img = IMAGE_FROM_ID (f, id);        struct image *img = IMAGE_FROM_ID (f, id);
7243        int width = img->width + 2 * img->hmargin;        int width = img->width + 2 * img->hmargin;
7244        int height = img->height + 2 * img->vmargin;        int height = img->height + 2 * img->vmargin;
7245      
7246        if (NILP (pixels))        if (NILP (pixels))
7247          size = Fcons (make_float ((double) width / CANON_X_UNIT (f)),          size = Fcons (make_float ((double) width / CANON_X_UNIT (f)),
7248                        make_float ((double) height / CANON_Y_UNIT (f)));                        make_float ((double) height / CANON_Y_UNIT (f)));
# Line 8595  or omitted means use the selected frame. Line 7287  or omitted means use the selected frame.
7287    
7288  static struct image *make_image P_ ((Lisp_Object spec, unsigned hash));  static struct image *make_image P_ ((Lisp_Object spec, unsigned hash));
7289  static void free_image P_ ((struct frame *f, struct image *img));  static void free_image P_ ((struct frame *f, struct image *img));
7290    static void x_destroy_x_image P_ ((XImage *));
7291    
7292    
7293  /* Allocate and return a new image structure for image specification  /* Allocate and return a new image structure for image specification
# Line 8606  make_image (spec, hash) Line 7299  make_image (spec, hash)
7299       unsigned hash;       unsigned hash;
7300  {  {
7301    struct image *img = (struct image *) xmalloc (sizeof *img);    struct image *img = (struct image *) xmalloc (sizeof *img);
7302      
7303    xassert (valid_image_p (spec));    xassert (valid_image_p (spec));
7304    bzero (img, sizeof *img);    bzero (img, sizeof *img);
7305    img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL));    img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL));
# Line 8667  prepare_image_for_display (f, img) Line 7360  prepare_image_for_display (f, img)
7360    if (img->pixmap == 0 && !img->load_failed_p)    if (img->pixmap == 0 && !img->load_failed_p)
7361      img->load_failed_p = img->type->load (f, img) == 0;      img->load_failed_p = img->type->load (f, img) == 0;
7362  }  }
7363        
7364    
7365  /* Value is the number of pixels for the ascent of image IMG when  /* Value is the number of pixels for the ascent of image IMG when
7366     drawn in face FACE.  */     drawn in face FACE.  */
# Line 8701  image_ascent (img, face) Line 7394  image_ascent (img, face)
7394  /* Find the "best" corner color of a bitmap.  XIMG is assumed to a device  /* Find the "best" corner color of a bitmap.  XIMG is assumed to a device
7395     context with the bitmap selected.  */     context with the bitmap selected.  */
7396  static COLORREF  static COLORREF
7397  four_corners_best (ximg, width, height)  four_corners_best (img_dc, width, height)
7398       HDC ximg;       HDC img_dc;
7399       unsigned long width, height;       unsigned long width, height;
7400  {  {
7401    COLORREF corners[4], best;    COLORREF corners[4], best;
7402    int i, best_count;    int i, best_count;
7403    
7404    /* Get the colors at the corners of ximg.  */    /* Get the colors at the corners of img_dc.  */
7405    corners[0] = GetPixel (ximg, 0, 0);    corners[0] = GetPixel (img_dc, 0, 0);
7406    corners[1] = GetPixel (ximg, width - 1, 0);    corners[1] = GetPixel (img_dc, width - 1, 0);
7407    corners[2] = GetPixel (ximg, width - 1, height - 1);    corners[2] = GetPixel (img_dc, width - 1, height - 1);
7408    corners[3] = GetPixel (ximg, 0, height - 1);    corners[3] = GetPixel (img_dc, 0, height - 1);
7409    
7410    /* Choose the most frequently found color as background.  */    /* Choose the most frequently found color as background.  */
7411    for (i = best_count = 0; i < 4; ++i)    for (i = best_count = 0; i < 4; ++i)
7412      {      {
7413        int j, n;        int j, n;
7414              
7415        for (j = n = 0; j < 4; ++j)        for (j = n = 0; j < 4; ++j)
7416          if (corners[i] == corners[j])          if (corners[i] == corners[j])
7417            ++n;            ++n;
# Line 8731  four_corners_best (ximg, width, height) Line 7424  four_corners_best (ximg, width, height)
7424  }  }
7425    
7426  /* Return the `background' field of IMG.  If IMG doesn't have one yet,  /* Return the `background' field of IMG.  If IMG doesn't have one yet,
7427     it is guessed heuristically.  If non-zero, XIMG is an existing XImage     it is guessed heuristically.  If non-zero, IMG_DC is an existing
7428     object to use for the heuristic.  */     device context with the image selected to use for the heuristic.  */
7429    
7430  unsigned long  unsigned long
7431  image_background (img, f, ximg)  image_background (img, f, img_dc)
7432       struct image *img;       struct image *img;
7433       struct frame *f;       struct frame *f;
7434       XImage *ximg;       HDC img_dc;
7435  {  {
7436    if (! img->background_valid)    if (! img->background_valid)
7437      /* IMG doesn't have a background yet, try to guess a reasonable value.  */      /* IMG doesn't have a background yet, try to guess a reasonable value.  */
7438      {      {
7439  #if 0 /* TODO: Image support.  */        int free_ximg = !img_dc;
7440        int free_ximg = !ximg;        HGDIOBJ prev;
7441    
7442          if (free_ximg)
7443            {
7444              HDC frame_dc = get_frame_dc (f);
7445              img_dc = CreateCompatibleDC (frame_dc);
7446              release_frame_dc (f, frame_dc);
7447    
7448        if (! ximg)            prev = SelectObject (img_dc, img->pixmap);
7449          ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,          }
                           0, 0, img->width, img->height, ~0, ZPixmap);  
7450    
7451        img->background = four_corners_best (ximg, img->width, img->height);        img->background = four_corners_best (img_dc, img->width, img->height);
7452    
7453        if (free_ximg)        if (free_ximg)
7454          XDestroyImage (ximg);          {
7455              SelectObject (img_dc, prev);
7456              DeleteDC (img_dc);
7457            }
7458    
7459        img->background_valid = 1;        img->background_valid = 1;
 #endif  
7460      }      }
7461    
7462    return img->background;    return img->background;
# Line 8770  int Line 7470  int
7470  image_background_transparent (img, f, mask)  image_background_transparent (img, f, mask)
7471       struct image *img;       struct image *img;
7472       struct frame *f;       struct frame *f;
7473       XImage *mask;       HDC mask;
7474  {  {
7475    if (! img->background_transparent_valid)    if (! img->background_transparent_valid)
7476      /* IMG doesn't have a background yet, try to guess a reasonable value.  */      /* IMG doesn't have a background yet, try to guess a reasonable value.  */
7477      {      {
 #if 0 /* TODO: Image support.  */  
7478        if (img->mask)        if (img->mask)
7479          {          {
7480            int free_mask = !mask;            int free_mask = !mask;
7481              HGDIOBJ prev;
7482    
7483            if (! mask)            if (free_mask)
7484              mask = XGetImage (FRAME_X_DISPLAY (f), img->mask,              {
7485                                0, 0, img->width, img->height, ~0, ZPixmap);                HDC frame_dc = get_frame_dc (f);
7486                  mask = CreateCompatibleDC (frame_dc);
7487                  release_frame_dc (f, frame_dc);
7488    
7489                  prev = SelectObject (mask, img->mask);
7490                }
7491    
7492            img->background_transparent            img->background_transparent
7493              = !four_corners_best (mask, img->width, img->height);              = !four_corners_best (mask, img->width, img->height);
7494    
7495            if (free_mask)            if (free_mask)
7496              XDestroyImage (mask);              {
7497                  SelectObject (mask, prev);
7498                  DeleteDC (mask);
7499                }
7500          }          }
7501        else        else
 #endif  
7502          img->background_transparent = 0;          img->background_transparent = 0;
7503    
7504        img->background_transparent_valid = 1;        img->background_transparent_valid = 1;
# Line 8838  x_clear_image_1 (f, img, pixmap_p, mask_ Line 7545  x_clear_image_1 (f, img, pixmap_p, mask_
7545        img->mask = NULL;        img->mask = NULL;
7546        img->background_transparent_valid = 0;        img->background_transparent_valid = 0;
7547      }      }
7548          
7549    if (colors_p && img->ncolors)    if (colors_p && img->ncolors)
7550      {      {
7551  #if 0  /* TODO: color table support.  */  #if 0  /* TODO: color table support.  */
# Line 8870  x_clear_image (f, img) Line 7577  x_clear_image (f, img)
7577  #if 0 /* TODO: color table support  */  #if 0 /* TODO: color table support  */
7578    
7579        int class = FRAME_W32_DISPLAY_INFO (f)->visual->class;        int class = FRAME_W32_DISPLAY_INFO (f)->visual->class;
7580          
7581        /* If display has an immutable color map, freeing colors is not        /* If display has an immutable color map, freeing colors is not
7582           necessary and some servers don't allow it.  So don't do it.  */           necessary and some servers don't allow it.  So don't do it.  */
7583        if (class != StaticColor        if (class != StaticColor
# Line 8885  x_clear_image (f, img) Line 7592  x_clear_image (f, img)
7592            UNBLOCK_INPUT;            UNBLOCK_INPUT;
7593          }          }
7594  #endif  #endif
7595          
7596        xfree (img->colors);        xfree (img->colors);
7597        img->colors = NULL;        img->colors = NULL;
7598        img->ncolors = 0;        img->ncolors = 0;
# Line 8910  x_alloc_image_color (f, img, color_name, Line 7617  x_alloc_image_color (f, img, color_name,
7617    
7618    xassert (STRINGP (color_name));    xassert (STRINGP (color_name));
7619    
7620    if (w32_defined_color (f, XSTRING (color_name)->data, &color, 1))    if (w32_defined_color (f, SDATA (color_name), &color, 1))
7621      {      {
7622        /* This isn't called frequently so we get away with simply        /* This isn't called frequently so we get away with simply
7623           reallocating the color vector to the needed size, here.  */           reallocating the color vector to the needed size, here.  */
# Line 8934  x_alloc_image_color (f, img, color_name, Line 7641  x_alloc_image_color (f, img, color_name,
7641    
7642  static void cache_image P_ ((struct frame *f, struct image *img));  static void cache_image P_ ((struct frame *f, struct image *img));
7643  static void postprocess_image P_ ((struct frame *, struct image *));  static void postprocess_image P_ ((struct frame *, struct image *));
7644    static void x_disable_image P_ ((struct frame *, struct image *));
7645    
7646    
7647  /* Return a new, initialized image cache that is allocated from the  /* Return a new, initialized image cache that is allocated from the
# Line 8944  make_image_cache () Line 7652  make_image_cache ()
7652  {  {
7653    struct image_cache *c = (struct image_cache *) xmalloc (sizeof *c);    struct image_cache *c = (struct image_cache *) xmalloc (sizeof *c);
7654    int size;    int size;
7655      
7656    bzero (c, sizeof *c);    bzero (c, sizeof *c);
7657    c->size = 50;    c->size = 50;
7658    c->images = (struct image **) xmalloc (c->size * sizeof *c->images);    c->images = (struct image **) xmalloc (c->size * sizeof *c->images);
# Line 8969  free_image_cache (f) Line 7677  free_image_cache (f)
7677    
7678        /* Cache should not be referenced by any frame when freed.  */        /* Cache should not be referenced by any frame when freed.  */
7679        xassert (c->refcount == 0);        xassert (c->refcount == 0);
7680          
7681        for (i = 0; i < c->used; ++i)        for (i = 0; i < c->used; ++i)
7682          free_image (f, c->images[i]);          free_image (f, c->images[i]);
7683        xfree (c->images);        xfree (c->images);
# Line 9002  clear_image_cache (f, force_p) Line 7710  clear_image_cache (f, force_p)
7710    
7711        EMACS_GET_TIME (t);        EMACS_GET_TIME (t);
7712        old = EMACS_SECS (t) - XFASTINT (Vimage_cache_eviction_delay);        old = EMACS_SECS (t) - XFASTINT (Vimage_cache_eviction_delay);
7713          
7714        /* Block input so that we won't be interrupted by a SIGIO        /* Block input so that we won't be interrupted by a SIGIO
7715           while being in an inconsistent state.  */           while being in an inconsistent state.  */
7716        BLOCK_INPUT;        BLOCK_INPUT;
7717          
7718        for (i = nfreed = 0; i < c->used; ++i)        for (i = nfreed = 0; i < c->used; ++i)
7719          {          {
7720            struct image *img = c->images[i];            struct image *img = c->images[i];
# Line 9025  clear_image_cache (f, force_p) Line 7733  clear_image_cache (f, force_p)
7733        if (nfreed)        if (nfreed)
7734          {          {
7735            Lisp_Object tail, frame;            Lisp_Object tail, frame;
7736              
7737            FOR_EACH_FRAME (tail, frame)            FOR_EACH_FRAME (tail, frame)
7738              {              {
7739                struct frame *f = XFRAME (frame);                struct frame *f = XFRAME (frame);
# Line 9053  FRAME t means clear the image caches of Line 7761  FRAME t means clear the image caches of
7761    if (EQ (frame, Qt))    if (EQ (frame, Qt))
7762      {      {
7763        Lisp_Object tail;        Lisp_Object tail;
7764          
7765        FOR_EACH_FRAME (tail, frame)        FOR_EACH_FRAME (tail, frame)
7766          if (FRAME_W32_P (XFRAME (frame)))          if (FRAME_W32_P (XFRAME (frame)))
7767            clear_image_cache (XFRAME (frame), 1);            clear_image_cache (XFRAME (frame), 1);
# Line 9073  postprocess_image (f, img) Line 7781  postprocess_image (f, img)
7781       struct frame *f;       struct frame *f;
7782       struct image *img;       struct image *img;
7783  {  {
 #if 0  /* TODO: image support.  */  
7784    /* Manipulation of the image's mask.  */    /* Manipulation of the image's mask.  */
7785    if (img->pixmap)    if (img->pixmap)
7786      {      {
# Line 9081  postprocess_image (f, img) Line 7788  postprocess_image (f, img)
7788        Lisp_Object mask;        Lisp_Object mask;
7789    
7790        spec = img->spec;        spec = img->spec;
7791          
7792        /* `:heuristic-mask t'        /* `:heuristic-mask t'
7793           `:mask heuristic'           `:mask heuristic'
7794           means build a mask heuristically.           means build a mask heuristically.
# Line 9091  postprocess_image (f, img) Line 7798  postprocess_image (f, img)
7798           image.           image.
7799           `:mask nil'           `:mask nil'
7800           means remove a mask, if any.  */           means remove a mask, if any.  */
7801                  
7802        mask = image_spec_value (spec, QCheuristic_mask, NULL);        mask = image_spec_value (spec, QCheuristic_mask, NULL);
7803        if (!NILP (mask))        if (!NILP (mask))
7804          x_build_heuristic_mask (f, img, mask);          x_build_heuristic_mask (f, img, mask);
7805        else        else
7806          {          {
7807            int found_p;            int found_p;
7808                        
7809            mask = image_spec_value (spec, QCmask, &found_p);            mask = image_spec_value (spec, QCmask, &found_p);
7810                      
7811            if (EQ (mask, Qheuristic))            if (EQ (mask, Qheuristic))
7812              x_build_heuristic_mask (f, img, Qt);              x_build_heuristic_mask (f, img, Qt);
7813            else if (CONSP (mask)            else if (CONSP (mask)
# Line 9117  postprocess_image (f, img) Line 7824  postprocess_image (f, img)
7824                img->mask = NULL;                img->mask = NULL;
7825              }              }
7826          }          }
7827    
7828              
7829        /* Should we apply an image transformation algorithm?  */        /* Should we apply an image transformation algorithm?  */
7830        conversion = image_spec_value (spec, QCconversion, NULL);        conversion = image_spec_value (spec, QCconversion, NULL);
7831        if (EQ (conversion, Qdisabled))        if (EQ (conversion, Qdisabled))
# Line 9138  postprocess_image (f, img) Line 7845  postprocess_image (f, img)
7845                                Fplist_get (tem, QCcolor_adjustment));                                Fplist_get (tem, QCcolor_adjustment));
7846          }          }
7847      }      }
 #endif  
7848  }  }
7849    
7850    
# Line 9161  lookup_image (f, spec) Line 7867  lookup_image (f, spec)
7867       specification.  */       specification.  */
7868    xassert (FRAME_WINDOW_P (f));    xassert (FRAME_WINDOW_P (f));
7869    xassert (valid_image_p (spec));    xassert (valid_image_p (spec));
7870      
7871    GCPRO1 (spec);    GCPRO1 (spec);
7872    
7873    /* Look up SPEC in the hash table of the image cache.  */    /* Look up SPEC in the hash table of the image cache.  */
# Line 9199  lookup_image (f, spec) Line 7905  lookup_image (f, spec)
7905        else        else
7906          {          {
7907            /* Handle image type independent image attributes            /* Handle image type independent image attributes
7908               `:ascent PERCENT', `:margin MARGIN', `:relief RELIEF',               `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
7909               `:background COLOR'.  */               `:background COLOR'.  */
7910            Lisp_Object ascent, margin, relief, bg;            Lisp_Object ascent, margin, relief, bg;
7911    
# Line 9220  lookup_image (f, spec) Line 7926  lookup_image (f, spec)
7926                if (XINT (XCDR (margin)) > 0)                if (XINT (XCDR (margin)) > 0)
7927                  img->vmargin = XFASTINT (XCDR (margin));                  img->vmargin = XFASTINT (XCDR (margin));
7928              }              }
7929              
7930            relief = image_spec_value (spec, QCrelief, NULL);            relief = image_spec_value (spec, QCrelief, NULL);
7931            if (INTEGERP (relief))            if (INTEGERP (relief))
7932              {              {
# Line 9254  lookup_image (f, spec) Line 7960  lookup_image (f, spec)
7960    /* We're using IMG, so set its timestamp to `now'.  */    /* We're using IMG, so set its timestamp to `now'.  */
7961    EMACS_GET_TIME (now);    EMACS_GET_TIME (now);
7962    img->timestamp = EMACS_SECS (now);    img->timestamp = EMACS_SECS (now);
7963      
7964    UNGCPRO;    UNGCPRO;
7965      
7966    /* Value is the image id.  */    /* Value is the image id.  */
7967    return img->id;    return img->id;
7968  }  }
# Line 9328  forall_images_in_image_cache (f, fn) Line 8034  forall_images_in_image_cache (f, fn)
8034                              W32 support code                              W32 support code
8035   ***********************************************************************/   ***********************************************************************/
8036    
8037    /* Macro for defining functions that will be loaded from image DLLs.  */
8038    #define DEF_IMGLIB_FN(func) FARPROC fn_##func
8039    
8040    /* Macro for loading those image functions from the library.  */
8041    #define LOAD_IMGLIB_FN(lib,func) {                                      \
8042        fn_##func = (void *) GetProcAddress (lib, #func);                   \
8043        if (!fn_##func) return 0;                                           \
8044      }
8045    
8046  static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int,  static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int,
8047                                              XImage **, Pixmap *));                                              XImage **, Pixmap *));
 static void x_destroy_x_image P_ ((XImage *));  
8048  static void x_put_x_image P_ ((struct frame *, XImage *, Pixmap, int, int));  static void x_put_x_image P_ ((struct frame *, XImage *, Pixmap, int, int));
8049    
8050    
# Line 9393  x_create_x_image_and_pixmap (f, width, h Line 8107  x_create_x_image_and_pixmap (f, width, h
8107    header->biCompression = BI_RGB;    header->biCompression = BI_RGB;
8108    header->biClrUsed = palette_colors;    header->biClrUsed = palette_colors;
8109    
8110      /* TODO: fill in palette.  */
8111      if (depth == 1)
8112        {
8113          (*ximg)->info.bmiColors[0].rgbBlue = 0;
8114          (*ximg)->info.bmiColors[0].rgbGreen = 0;
8115          (*ximg)->info.bmiColors[0].rgbRed = 0;
8116          (*ximg)->info.bmiColors[0].rgbReserved = 0;
8117          (*ximg)->info.bmiColors[1].rgbBlue = 255;
8118          (*ximg)->info.bmiColors[1].rgbGreen = 255;
8119          (*ximg)->info.bmiColors[1].rgbRed = 255;
8120          (*ximg)->info.bmiColors[1].rgbReserved = 0;
8121        }
8122    
8123    hdc = get_frame_dc (f);    hdc = get_frame_dc (f);
8124    
8125    /* Create a DIBSection and raster array for the bitmap,    /* Create a DIBSection and raster array for the bitmap,
8126       and store its handle in *pixmap.  */       and store its handle in *pixmap.  */
8127    *pixmap = CreateDIBSection (hdc, &((*ximg)->info), DIB_RGB_COLORS,    *pixmap = CreateDIBSection (hdc, &((*ximg)->info),
8128                                  (depth < 16) ? DIB_PAL_COLORS : DIB_RGB_COLORS,
8129                                &((*ximg)->data), NULL, 0);                                &((*ximg)->data), NULL, 0);
8130    
8131    /* Realize display palette and garbage all frames. */    /* Realize display palette and garbage all frames. */
# Line 9442  x_put_x_image (f, ximg, pixmap, width, h Line 8170  x_put_x_image (f, ximg, pixmap, width, h
8170       struct frame *f;       struct frame *f;
8171       XImage *ximg;       XImage *ximg;
8172       Pixmap pixmap;       Pixmap pixmap;
8173         int width, height;
8174  {  {
8175    #if 0  /* I don't think this is necessary looking at where it is used.  */
8176  #if TODO  /* W32 specific image code.  */    HDC hdc = get_frame_dc (f);
8177    GC gc;    SetDIBits (hdc, pixmap, 0, height, ximg->data, &(ximg->info), DIB_RGB_COLORS);
8178      release_frame_dc (f, hdc);
   xassert (interrupt_input_blocked);  
   gc = XCreateGC (NULL, pixmap, 0, NULL);  
   XPutImage (NULL, pixmap, gc, ximg, 0, 0, 0, 0, width, height);  
   XFreeGC (NULL, gc);  
8179  #endif  #endif
8180  }  }
8181    
# Line 9481  x_find_image_file (file) Line 8206  x_find_image_file (file)
8206    
8207    /* Try to find FILE in data-directory, then x-bitmap-file-path.  */    /* Try to find FILE in data-directory, then x-bitmap-file-path.  */
8208    fd = openp (search_path, file, Qnil, &file_found, Qnil);    fd = openp (search_path, file, Qnil, &file_found, Qnil);
8209      
8210    if (fd == -1)    if (fd == -1)
8211      file_found = Qnil;      file_found = Qnil;
8212    else    else
# Line 9506  slurp_file (file, size) Line 8231  slurp_file (file, size)
8231    struct stat st;    struct stat st;
8232    
8233    if (stat (file, &st) == 0    if (stat (file, &st) == 0
8234        && (fp = fopen (file, "r")) != NULL        && (fp = fopen (file, "rb")) != NULL
8235        && (buf = (char *) xmalloc (st.st_size),        && (buf = (char *) xmalloc (st.st_size),
8236            fread (buf, 1, st.st_size, fp) == st.st_size))            fread (buf, 1, st.st_size, fp) == st.st_size))
8237      {      {
# Line 9523  slurp_file (file, size) Line 8248  slurp_file (file, size)
8248            buf = NULL;            buf = NULL;
8249          }          }
8250      }      }
8251      
8252    return buf;    return buf;
8253  }  }
8254    
# Line 9602  enum xbm_token Line 8327  enum xbm_token
8327    XBM_TK_NUMBER    XBM_TK_NUMBER
8328  };  };
8329    
8330      
8331  /* Return non-zero if OBJECT is a valid XBM-type image specification.  /* Return non-zero if OBJECT is a valid XBM-type image specification.
8332     A valid specification is a list starting with the symbol `image'     A valid specification is a list starting with the symbol `image'
8333     The rest of the list is a property list which must contain an     The rest of the list is a property list which must contain an
# Line 9637  xbm_image_p (object) Line 8362  xbm_image_p (object)
8362       Lisp_Object object;       Lisp_Object object;
8363  {  {
8364    struct image_keyword kw[XBM_LAST];    struct image_keyword kw[XBM_LAST];
8365      
8366    bcopy (xbm_format, kw, sizeof kw);    bcopy (xbm_format, kw, sizeof kw);
8367    if (!parse_image_spec (object, kw, XBM_LAST, Qxbm))    if (!parse_image_spec (object, kw, XBM_LAST, Qxbm))
8368      return 0;      return 0;
# Line 9669  xbm_image_p (object) Line 8394  xbm_image_p (object)
8394        data = kw[XBM_DATA].value;        data = kw[XBM_DATA].value;
8395        width = XFASTINT (kw[XBM_WIDTH].value);        width = XFASTINT (kw[XBM_WIDTH].value);
8396        height = XFASTINT (kw[XBM_HEIGHT].value);        height = XFASTINT (kw[XBM_HEIGHT].value);
8397          
8398        /* Check type of data, and width and height against contents of        /* Check type of data, and width and height against contents of
8399           data.  */           data.  */
8400        if (VECTORP (data))        if (VECTORP (data))
8401          {          {
8402            int i;            int i;
8403              
8404            /* Number of elements of the vector must be >= height.  */            /* Number of elements of the vector must be >= height.  */
8405            if (XVECTOR (data)->size < height)            if (XVECTOR (data)->size < height)
8406              return 0;              return 0;
# Line 9688  xbm_image_p (object) Line 8413  xbm_image_p (object)
8413    
8414                if (STRINGP (elt))                if (STRINGP (elt))
8415                  {                  {
8416                    if (XSTRING (elt)->size                    if (SCHARS (elt)
8417                        < (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR)                        < (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR)
8418                      return 0;                      return 0;
8419                  }                  }
# Line 9703  xbm_image_p (object) Line 8428  xbm_image_p (object)
8428          }          }
8429        else if (STRINGP (data))        else if (STRINGP (data))
8430          {          {
8431            if (XSTRING (data)->size            if (SCHARS (data)
8432                < (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR * height)                < (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR * height)
8433              return 0;              return 0;
8434          }          }
# Line 9745  xbm_scan (s, end, sval, ival) Line 8470  xbm_scan (s, end, sval, ival)
8470    else if (isdigit (c))    else if (isdigit (c))
8471      {      {
8472        int value = 0, digit;        int value = 0, digit;
8473          
8474        if (c == '0' && *s < end)        if (c == '0' && *s < end)
8475          {          {
8476            c = *(*s)++;            c = *(*s)++;
# Line 9839  w32_create_pixmap_from_bitmap_data (int Line 8564  w32_create_pixmap_from_bitmap_data (int
8564    
8565    w1 = (width + 7) / 8;         /* nb of 8bits elt in X bitmap */    w1 = (width + 7) / 8;         /* nb of 8bits elt in X bitmap */
8566    w2 = ((width + 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */    w2 = ((width + 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */
8567    bits = (char *) xmalloc (height * w2);    bits = (char *) alloca (height * w2);
8568    bzero (bits, height * w2);    bzero (bits, height * w2);
8569    for (i = 0; i < height; i++)    for (i = 0; i < height; i++)
8570      {      {
# Line 9848  w32_create_pixmap_from_bitmap_data (int Line 8573  w32_create_pixmap_from_bitmap_data (int
8573          *p++ = reflect_byte(*data++);          *p++ = reflect_byte(*data++);
8574      }      }
8575    bmp = CreateBitmap (width, height, 1, 1, bits);    bmp = CreateBitmap (width, height, 1, 1, bits);
   xfree (bits);  
8576    
8577    return bmp;    return bmp;
8578  }  }
# Line 9883  xbm_read_bitmap_data (contents, end, wid Line 8607  xbm_read_bitmap_data (contents, end, wid
8607       if (LA1 != (TOKEN))        \       if (LA1 != (TOKEN))        \
8608         goto failure;            \         goto failure;            \
8609       else                       \       else                       \
8610         match ()         match ()
8611    
8612  #define expect_ident(IDENT)                                     \  #define expect_ident(IDENT)                                     \
8613       if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0)  \       if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0)  \
# Line 9926  xbm_read_bitmap_data (contents, end, wid Line 8650  xbm_read_bitmap_data (contents, end, wid
8650      {      {
8651        if (strcmp (buffer, "unsigned") == 0)        if (strcmp (buffer, "unsigned") == 0)
8652          {          {
8653            match ();            match ();
8654            expect_ident ("char");            expect_ident ("char");
8655          }          }
8656        else if (strcmp (buffer, "short") == 0)        else if (strcmp (buffer, "short") == 0)
# Line 9941  xbm_read_bitmap_data (contents, end, wid Line 8665  xbm_read_bitmap_data (contents, end, wid
8665        else        else
8666          goto failure;          goto failure;
8667      }      }
8668    else    else
8669      goto failure;      goto failure;
8670    
8671    expect (XBM_TK_IDENT);    expect (XBM_TK_IDENT);
# Line 9961  xbm_read_bitmap_data (contents, end, wid Line 8685  xbm_read_bitmap_data (contents, end, wid
8685            int val = value;            int val = value;
8686            expect (XBM_TK_NUMBER);            expect (XBM_TK_NUMBER);
8687    
8688            *p++ = val;            *p++ = ~ val;
8689            if (!padding_p || ((i + 2) % bytes_per_line))            if (!padding_p || ((i + 2) % bytes_per_line))
8690              *p++ = value >> 8;              *p++ = ~ (value >> 8);
8691              
8692            if (LA1 == ',' || LA1 == '}')            if (LA1 == ',' || LA1 == '}')
8693              match ();              match ();
8694            else            else
# Line 9977  xbm_read_bitmap_data (contents, end, wid Line 8701  xbm_read_bitmap_data (contents, end, wid
8701          {          {
8702            int val = value;            int val = value;
8703            expect (XBM_TK_NUMBER);            expect (XBM_TK_NUMBER);
8704              
8705            *p++ = val;            *p++ = ~ val;
8706    
8707            if (LA1 == ',' || LA1 == '}')            if (LA1 == ',' || LA1 == '}')
8708              match ();              match ();
# Line 10004  xbm_read_bitmap_data (contents, end, wid Line 8728  xbm_read_bitmap_data (contents, end, wid
8728  #undef expect_ident  #undef expect_ident
8729  }  }
8730    
8731    static void convert_mono_to_color_image (f, img, foreground, background)
8732         struct frame *f;
8733         struct image *img;
8734         COLORREF foreground, background;
8735    {
8736      HDC hdc, old_img_dc, new_img_dc;
8737      HGDIOBJ old_prev, new_prev;
8738      HBITMAP new_pixmap;
8739    
8740      hdc = get_frame_dc (f);
8741      old_img_dc = CreateCompatibleDC (hdc);
8742      new_img_dc = CreateCompatibleDC (hdc);
8743      new_pixmap = CreateCompatibleBitmap (hdc, img->width, img->height);
8744      release_frame_dc (f, hdc);
8745      old_prev = SelectObject (old_img_dc, img->pixmap);
8746      new_prev = SelectObject (new_img_dc, new_pixmap);
8747      SetTextColor (new_img_dc, foreground);
8748      SetBkColor (new_img_dc, background);
8749    
8750      BitBlt (new_img_dc, 0, 0, img->width, img->height, old_img_dc,
8751              0, 0, SRCCOPY);
8752    
8753      SelectObject (old_img_dc, old_prev);
8754      SelectObject (new_img_dc, new_prev);
8755      DeleteDC (old_img_dc);
8756      DeleteDC (new_img_dc);
8757      DeleteObject (img->pixmap);
8758      if (new_pixmap == 0)
8759        fprintf (stderr, "Failed to convert image to color.\n");
8760      else
8761        img->pixmap = new_pixmap;
8762    }
8763    
8764  /* Load XBM image IMG which will be displayed on frame F from buffer  /* Load XBM image IMG which will be displayed on frame F from buffer
8765     CONTENTS.  END is the end of the buffer. Value is non-zero if     CONTENTS.  END is the end of the buffer. Value is non-zero if
# Line 10018  xbm_load_image (f, img, contents, end) Line 8774  xbm_load_image (f, img, contents, end)
8774    int rc;    int rc;
8775    unsigned char *data;    unsigned char *data;
8776    int success_p = 0;    int success_p = 0;
8777      
8778    rc = xbm_read_bitmap_data (contents, end, &img->width, &img->height, &data);    rc = xbm_read_bitmap_data (contents, end, &img->width, &img->height, &data);
8779    if (rc)    if (rc)
8780      {      {
8781        unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);        unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);
8782        unsigned long background = FRAME_BACKGROUND_PIXEL (f);        unsigned long background = FRAME_BACKGROUND_PIXEL (f);
8783          int non_default_colors = 0;
8784        Lisp_Object value;        Lisp_Object value;
8785          
8786        xassert (img->width > 0 && img->height > 0);        xassert (img->width > 0 && img->height > 0);
8787    
8788        /* Get foreground and background colors, maybe allocate colors.  */        /* Get foreground and background colors, maybe allocate colors.  */
8789        value = image_spec_value (img->spec, QCforeground, NULL);        value = image_spec_value (img->spec, QCforeground, NULL);
8790        if (!NILP (value))        if (!NILP (value))
8791          foreground = x_alloc_image_color (f, img, value, foreground);          {
8792              foreground = x_alloc_image_color (f, img, value, foreground);
8793              non_default_colors = 1;
8794            }
8795        value = image_spec_value (img->spec, QCbackground, NULL);        value = image_spec_value (img->spec, QCbackground, NULL);
8796        if (!NILP (value))        if (!NILP (value))
8797          {          {
8798            background = x_alloc_image_color (f, img, value, background);            background = x_alloc_image_color (f, img, value, background);
8799            img->background = background;            img->background = background;
8800            img->background_valid = 1;            img->background_valid = 1;
8801              non_default_colors = 1;
8802          }          }
8803        img->pixmap        img->pixmap
8804          = w32_create_pixmap_from_bitmap_data (img->width, img->height, data);          = w32_create_pixmap_from_bitmap_data (img->width, img->height, data);
8805    
8806          /* If colors were specified, transfer the bitmap to a color one.  */
8807          if (non_default_colors)
8808            convert_mono_to_color_image (f, img, foreground, background);
8809    
8810        xfree (data);        xfree (data);
8811    
8812        if (img->pixmap == 0)        if (img->pixmap == 0)
# Line 10067  xbm_file_p (data) Line 8832  xbm_file_p (data)
8832  {  {
8833    int w, h;    int w, h;
8834    return (STRINGP (data)    return (STRINGP (data)
8835            && xbm_read_bitmap_data (XSTRING (data)->data,            && xbm_read_bitmap_data (SDATA (data),
8836                                     (XSTRING (data)->data                                     (SDATA (data)
8837                                      + STRING_BYTES (XSTRING (data))),                                      + SBYTES (data)),
8838                                     &w, &h, NULL));                                     &w, &h, NULL));
8839  }  }
8840    
8841        
8842  /* Fill image IMG which is used on frame F with pixmap data.  Value is  /* Fill image IMG which is used on frame F with pixmap data.  Value is
8843     non-zero if successful.  */     non-zero if successful.  */
8844    
# Line 10105  xbm_load (f, img) Line 8870  xbm_load (f, img)
8870            return 0;            return 0;
8871          }          }
8872    
8873        contents = slurp_file (XSTRING (file)->data, &size);        contents = slurp_file (SDATA (file), &size);
8874        if (contents == NULL)        if (contents == NULL)
8875          {          {
8876            image_error ("Error loading XBM image `%s'", img->spec, Qnil);            image_error ("Error loading XBM image `%s'", img->spec, Qnil);
# Line 10120  xbm_load (f, img) Line 8885  xbm_load (f, img)
8885      {      {
8886        struct image_keyword fmt[XBM_LAST];        struct image_keyword fmt[XBM_LAST];
8887        Lisp_Object data;        Lisp_Object data;
       int depth;  
8888        unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);        unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);
8889        unsigned long background = FRAME_BACKGROUND_PIXEL (f);        unsigned long background = FRAME_BACKGROUND_PIXEL (f);
8890          int non_default_colors = 0;
8891        char *bits;        char *bits;
8892        int parsed_p;        int parsed_p;
8893        int in_memory_file_p = 0;        int in_memory_file_p = 0;
# Line 10147  xbm_load (f, img) Line 8912  xbm_load (f, img)
8912        /* Get foreground and background colors, maybe allocate colors.  */        /* Get foreground and background colors, maybe allocate colors.  */
8913        if (fmt[XBM_FOREGROUND].count        if (fmt[XBM_FOREGROUND].count
8914            && STRINGP (fmt[XBM_FOREGROUND].value))            && STRINGP (fmt[XBM_FOREGROUND].value))
8915          foreground = x_alloc_image_color (f, img, fmt[XBM_FOREGROUND].value,          {
8916                                            foreground);            foreground = x_alloc_image_color (f, img, fmt[XBM_FOREGROUND].value,
8917                                                foreground);
8918              non_default_colors = 1;
8919            }
8920    
8921        if (fmt[XBM_BACKGROUND].count        if (fmt[XBM_BACKGROUND].count
8922            && STRINGP (fmt[XBM_BACKGROUND].value))            && STRINGP (fmt[XBM_BACKGROUND].value))
8923          background = x_alloc_image_color (f, img, fmt[XBM_BACKGROUND].value,          {
8924                                            background);            background = x_alloc_image_color (f, img, fmt[XBM_BACKGROUND].value,
8925                                                background);
8926              non_default_colors = 1;
8927            }
8928    
8929        if (in_memory_file_p)        if (in_memory_file_p)
8930          success_p = xbm_load_image (f, img, XSTRING (data)->data,          success_p = xbm_load_image (f, img, SDATA (data),
8931                                      (XSTRING (data)->data                                      (SDATA (data)
8932                                       + STRING_BYTES (XSTRING (data))));                                       + SBYTES (data)));
8933        else        else
8934          {          {
8935            if (VECTORP (data))            if (VECTORP (data))
# Line 10165  xbm_load (f, img) Line 8937  xbm_load (f, img)
8937                int i;                int i;
8938                char *p;                char *p;
8939                int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR;                int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
8940              
8941                p = bits = (char *) alloca (nbytes * img->height);                p = bits = (char *) alloca (nbytes * img->height);
8942                for (i = 0; i < img->height; ++i, p += nbytes)                for (i = 0; i < img->height; ++i, p += nbytes)
8943                  {                  {
8944                    Lisp_Object line = XVECTOR (data)->contents[i];                    Lisp_Object line = XVECTOR (data)->contents[i];
8945                    if (STRINGP (line))                    if (STRINGP (line))
8946                      bcopy (XSTRING (line)->data, p, nbytes);                      bcopy (SDATA (line), p, nbytes);
8947                    else                    else
8948                      bcopy (XBOOL_VECTOR (line)->data, p, nbytes);                      bcopy (XBOOL_VECTOR (line)->data, p, nbytes);
8949                  }                  }
8950              }              }
8951            else if (STRINGP (data))            else if (STRINGP (data))
8952              bits = XSTRING (data)->data;              bits = SDATA (data);
8953            else            else
8954              bits = XBOOL_VECTOR (data)->data;              bits = XBOOL_VECTOR (data)->data;
8955    
8956            /* Create the pixmap.  */            /* Create the pixmap.  */
           depth = one_w32_display_info.n_cbits;  
8957            img->pixmap            img->pixmap
8958              = w32_create_pixmap_from_bitmap_data (img->width, img->height,              = w32_create_pixmap_from_bitmap_data (img->width, img->height,
8959                                                    bits);                                                    bits);
8960    
8961              /* If colors were specified, transfer the bitmap to a color one.  */
8962              if (non_default_colors)
8963                convert_mono_to_color_image (f, img, foreground, background);
8964    
8965            if (img->pixmap)            if (img->pixmap)
8966              success_p = 1;              success_p = 1;
8967            else            else
# Line 10200  xbm_load (f, img) Line 8975  xbm_load (f, img)
8975    
8976    return success_p;    return success_p;
8977  }  }
8978      
8979    
8980    
8981  /***********************************************************************  /***********************************************************************
8982                                XPM images                                XPM images
8983   ***********************************************************************/   ***********************************************************************/
8984    
8985  #if HAVE_XPM  #if HAVE_XPM
8986    
8987  static int xpm_image_p P_ ((Lisp_Object object));  static int xpm_image_p P_ ((Lisp_Object object));
8988  static int xpm_load P_ ((struct frame *f, struct image *img));  static int xpm_load P_ ((struct frame *f, struct image *img));
8989  static int xpm_valid_color_symbols_p P_ ((Lisp_Object));  static int xpm_valid_color_symbols_p P_ ((Lisp_Object));
8990    
8991    /* Indicate to xpm.h that we don't have Xlib.  */
8992    #define FOR_MSW
8993    /* simx.h in xpm defines XColor and XImage differently than Emacs.  */
8994    #define XColor xpm_XColor
8995    #define XImage xpm_XImage
8996    #define PIXEL_ALREADY_TYPEDEFED
8997  #include "X11/xpm.h"  #include "X11/xpm.h"
8998    #undef FOR_MSW
8999    #undef XColor
9000    #undef XImage
9001    #undef PIXEL_ALREADY_TYPEDEFED
9002    
9003  /* The symbol `xpm' identifying XPM-format images.  */  /* The symbol `xpm' identifying XPM-format images.  */
9004    
# Line 10245  static struct image_keyword xpm_format[X Line 9030  static struct image_keyword xpm_format[X
9030    {":type",             IMAGE_SYMBOL_VALUE,                     1},    {":type",             IMAGE_SYMBOL_VALUE,                     1},
9031    {":file",             IMAGE_STRING_VALUE,                     0},    {":file",             IMAGE_STRING_VALUE,                     0},
9032    {":data",             IMAGE_STRING_VALUE,                     0},    {":data",             IMAGE_STRING_VALUE,                     0},
9033    {":ascent",           IMAGE_NON_NEGATIVE_INTEGER_VALUE,       0},    {":ascent",           IMAGE_ASCENT_VALUE,                     0},
9034    {":margin",           IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},    {":margin",           IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
9035    {":relief",           IMAGE_INTEGER_VALUE,                    0},    {":relief",           IMAGE_INTEGER_VALUE,                    0},
9036    {":conversion",       IMAGE_DONT_CHECK_VALUE_TYPE,            0},    {":conversion",       IMAGE_DONT_CHECK_VALUE_TYPE,            0},
# Line 10255  static struct image_keyword xpm_format[X Line 9040  static struct image_keyword xpm_format[X
9040    {":background",       IMAGE_STRING_OR_NIL_VALUE,              0}    {":background",       IMAGE_STRING_OR_NIL_VALUE,              0}
9041  };  };
9042    
9043  /* Structure describing the image type XBM.  */  /* Structure describing the image type XPM.  */
9044    
9045  static struct image_type xpm_type =  static struct image_type xpm_type =
9046  {  {
# Line 10267  static struct image_type xpm_type = Line 9052  static struct image_type xpm_type =
9052  };  };
9053    
9054    
9055    /* XPM library details.  */
9056    
9057    DEF_IMGLIB_FN (XpmFreeAttributes);
9058    DEF_IMGLIB_FN (XpmCreateImageFromBuffer);
9059    DEF_IMGLIB_FN (XpmReadFileToImage);
9060    DEF_IMGLIB_FN (XImageFree);
9061    
9062    
9063    static int
9064    init_xpm_functions (library)
9065         HMODULE library;
9066    {
9067      LOAD_IMGLIB_FN (library, XpmFreeAttributes);
9068      LOAD_IMGLIB_FN (library, XpmCreateImageFromBuffer);
9069      LOAD_IMGLIB_FN (library, XpmReadFileToImage);
9070      LOAD_IMGLIB_FN (library, XImageFree);
9071    
9072      return 1;
9073    }
9074    
9075  /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list  /* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
9076     for XPM images.  Such a list must consist of conses whose car and     for XPM images.  Such a list must consist of conses whose car and
9077     cdr are strings.  */     cdr are strings.  */
# Line 10303  xpm_image_p (object) Line 9108  xpm_image_p (object)
9108            /* Either no `:color-symbols' or it's a list of conses            /* Either no `:color-symbols' or it's a list of conses
9109               whose car and cdr are strings.  */               whose car and cdr are strings.  */
9110            && (fmt[XPM_COLOR_SYMBOLS].count == 0            && (fmt[XPM_COLOR_SYMBOLS].count == 0
9111                || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value))                || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value)));
           && (fmt[XPM_ASCENT].count == 0  
               || XFASTINT (fmt[XPM_ASCENT].value) < 100));  
9112  }  }
9113    
9114    
# Line 10317  xpm_load (f, img) Line 9120  xpm_load (f, img)
9120       struct frame *f;       struct frame *f;
9121       struct image *img;       struct image *img;
9122  {  {
9123    int rc, i;    HDC hdc;
9124      int rc;
9125    XpmAttributes attrs;    XpmAttributes attrs;
9126    Lisp_Object specified_file, color_symbols;    Lisp_Object specified_file, color_symbols;
9127      xpm_XImage * xpm_image, * xpm_mask;
9128    
9129    /* Configure the XPM lib.  Use the visual of frame F.  Allocate    /* Configure the XPM lib.  Use the visual of frame F.  Allocate
9130       close colors.  Return colors allocated.  */       close colors.  Return colors allocated.  */
9131    bzero (&attrs, sizeof attrs);    bzero (&attrs, sizeof attrs);
9132      xpm_image = xpm_mask = NULL;
9133    
9134    #if 0
9135    attrs.visual = FRAME_X_VISUAL (f);    attrs.visual = FRAME_X_VISUAL (f);
9136    attrs.colormap = FRAME_X_COLORMAP (f);    attrs.colormap = FRAME_X_COLORMAP (f);
9137    attrs.valuemask |= XpmVisual;    attrs.valuemask |= XpmVisual;
9138    attrs.valuemask |= XpmColormap;    attrs.valuemask |= XpmColormap;
9139    #endif
9140    attrs.valuemask |= XpmReturnAllocPixels;    attrs.valuemask |= XpmReturnAllocPixels;
9141  #ifdef XpmAllocCloseColors  #ifdef XpmAllocCloseColors
9142    attrs.alloc_close_colors = 1;    attrs.alloc_close_colors = 1;
# Line 10345  xpm_load (f, img) Line 9154  xpm_load (f, img)
9154        Lisp_Object tail;        Lisp_Object tail;
9155        XpmColorSymbol *xpm_syms;        XpmColorSymbol *xpm_syms;
9156        int i, size;        int i, size;
9157          
9158        attrs.valuemask |= XpmColorSymbols;        attrs.valuemask |= XpmColorSymbols;
9159    
9160        /* Count number of symbols.  */        /* Count number of symbols.  */
# Line 10366  xpm_load (f, img) Line 9175  xpm_load (f, img)
9175          {          {
9176            Lisp_Object name = XCAR (XCAR (tail));            Lisp_Object name = XCAR (XCAR (tail));
9177            Lisp_Object color = XCDR (XCAR (tail));            Lisp_Object color = XCDR (XCAR (tail));
9178            xpm_syms[i].name = (char *) alloca (XSTRING (name)->size + 1);            xpm_syms[i].name = (char *) alloca (SCHARS (name) + 1);
9179            strcpy (xpm_syms[i].name, XSTRING (name)->data);            strcpy (xpm_syms[i].name, SDATA (name));
9180            xpm_syms[i].value = (char *) alloca (XSTRING (color)->size + 1);            xpm_syms[i].value = (char *) alloca (SCHARS (color) + 1);
9181            strcpy (xpm_syms[i].value, XSTRING (color)->data);            strcpy (xpm_syms[i].value, SDATA (color));
9182          }          }
9183      }      }
9184    
9185    /* Create a pixmap for the image, either from a file, or from a    /* Create a pixmap for the image, either from a file, or from a
9186       string buffer containing data in the same format as an XPM file.  */       string buffer containing data in the same format as an XPM file.  */
9187    BLOCK_INPUT;  
9188    specified_file = image_spec_value (img->spec, QCfile, NULL);    specified_file = image_spec_value (img->spec, QCfile, NULL);
9189    
9190      {
9191        HDC frame_dc = get_frame_dc (f);
9192        hdc = CreateCompatibleDC (frame_dc);
9193        release_frame_dc (f, frame_dc);
9194      }
9195    
9196    if (STRINGP (specified_file))    if (STRINGP (specified_file))
9197      {      {
9198        Lisp_Object file = x_find_image_file (specified_file);        Lisp_Object file = x_find_image_file (specified_file);
9199        if (!STRINGP (file))        if (!STRINGP (file))
9200          {          {
9201            image_error ("Cannot find image file `%s'", specified_file, Qnil);            image_error ("Cannot find image file `%s'", specified_file, Qnil);
           UNBLOCK_INPUT;  
9202            return 0;            return 0;
9203          }          }
9204          
9205        rc = XpmReadFileToPixmap (NULL, FRAME_W32_WINDOW (f),        /* XpmReadFileToPixmap is not available in the Windows port of
9206                                  XSTRING (file)->data, &img->pixmap, &img->mask,           libxpm.  But XpmReadFileToImage almost does what we want.  */
9207                                  &attrs);        rc = fn_XpmReadFileToImage (&hdc, SDATA (file),
9208                                      &xpm_image, &xpm_mask,
9209                                      &attrs);
9210      }      }
9211    else    else
9212      {      {
9213        Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL);        Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL);
9214        rc = XpmCreatePixmapFromBuffer (NULL, FRAME_W32_WINDOW (f),        /* XpmCreatePixmapFromBuffer is not available in the Windows port
9215                                        XSTRING (buffer)->data,           of libxpm.  But XpmCreateImageFromBuffer almost does what we want.  */
9216                                        &img->pixmap, &img->mask,        rc = fn_XpmCreateImageFromBuffer (&hdc, SDATA (buffer),
9217                                        &attrs);                                          &xpm_image, &xpm_mask,
9218                                            &attrs);
9219      }      }
   UNBLOCK_INPUT;  
9220    
9221    if (rc == XpmSuccess)    if (rc == XpmSuccess)
9222      {      {
9223          int i;
9224    
9225          /* W32 XPM uses XImage to wrap what W32 Emacs calls a Pixmap,
9226             plus some duplicate attributes.  */
9227          if (xpm_image && xpm_image->bitmap)
9228            {
9229              img->pixmap = xpm_image->bitmap;
9230              /* XImageFree in libXpm frees XImage struct without destroying
9231                 the bitmap, which is what we want.  */
9232              fn_XImageFree (xpm_image);
9233            }
9234          if (xpm_mask && xpm_mask->bitmap)
9235            {
9236              /* The mask appears to be inverted compared with what we expect.
9237                 TODO: invert our expectations.  See other places where we
9238                 have to invert bits because our idea of masks is backwards.  */
9239              HGDIOBJ old_obj;
9240              old_obj = SelectObject (hdc, xpm_mask->bitmap);
9241    
9242              PatBlt (hdc, 0, 0, xpm_mask->width, xpm_mask->height, DSTINVERT);
9243              SelectObject (hdc, old_obj);
9244    
9245              img->mask = xpm_mask->bitmap;
9246              fn_XImageFree (xpm_mask);
9247              DeleteDC (hdc);
9248            }
9249    
9250          DeleteDC (hdc);
9251    
9252        /* Remember allocated colors.  */        /* Remember allocated colors.  */
9253        img->ncolors = attrs.nalloc_pixels;        img->ncolors = attrs.nalloc_pixels;
9254        img->colors = (unsigned long *) xmalloc (img->ncolors        img->colors = (unsigned long *) xmalloc (img->ncolors
# Line 10415  xpm_load (f, img) Line 9261  xpm_load (f, img)
9261        xassert (img->width > 0 && img->height > 0);        xassert (img->width > 0 && img->height > 0);
9262    
9263        /* The call to XpmFreeAttributes below frees attrs.alloc_pixels.  */        /* The call to XpmFreeAttributes below frees attrs.alloc_pixels.  */
9264        BLOCK_INPUT;        fn_XpmFreeAttributes (&attrs);
       XpmFreeAttributes (&attrs);  
       UNBLOCK_INPUT;  
9265      }      }
9266    else    else
9267      {      {
9268          DeleteDC (hdc);
9269    
9270        switch (rc)        switch (rc)
9271          {          {
9272          case XpmOpenFailed:          case XpmOpenFailed:
9273            image_error ("Error opening XPM file (%s)", img->spec, Qnil);            image_error ("Error opening XPM file (%s)", img->spec, Qnil);
9274            break;            break;
9275              
9276          case XpmFileInvalid:          case XpmFileInvalid:
9277            image_error ("Invalid XPM file (%s)", img->spec, Qnil);            image_error ("Invalid XPM file (%s)", img->spec, Qnil);
9278            break;            break;
9279              
9280          case XpmNoMemory:          case XpmNoMemory:
9281            image_error ("Out of memory (%s)", img->spec, Qnil);            image_error ("Out of memory (%s)", img->spec, Qnil);
9282            break;            break;
9283              
9284          case XpmColorFailed:          case XpmColorFailed:
9285            image_error ("Color allocation error (%s)", img->spec, Qnil);            image_error ("Color allocation error (%s)", img->spec, Qnil);
9286            break;            break;
9287              
9288          default:          default:
9289            image_error ("Unknown error (%s)", img->spec, Qnil);            image_error ("Unknown error (%s)", img->spec, Qnil);
9290            break;            break;
# Line 10587  lookup_pixel_color (f, pixel) Line 9433  lookup_pixel_color (f, pixel)
9433        int rc;        int rc;
9434    
9435        BLOCK_INPUT;        BLOCK_INPUT;
9436          
9437        cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f));        cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f));
9438        color.pixel = pixel;        color.pixel = pixel;
9439        XQueryColor (NULL, cmap, &color);        XQueryColor (NULL, cmap, &color);
# Line 10597  lookup_pixel_color (f, pixel) Line 9443  lookup_pixel_color (f, pixel)
9443        if (rc)        if (rc)
9444          {          {
9445            ++ct_colors_allocated;            ++ct_colors_allocated;
9446          
9447            p = (struct ct_color *) xmalloc (sizeof *p);            p = (struct ct_color *) xmalloc (sizeof *p);
9448            p->r = color.red;            p->r = color.red;
9449            p->g = color.green;            p->g = color.green;
# Line 10634  colors_in_color_table (n) Line 9480  colors_in_color_table (n)
9480        colors = (unsigned long *) xmalloc (ct_colors_allocated        colors = (unsigned long *) xmalloc (ct_colors_allocated
9481                                            * sizeof *colors);                                            * sizeof *colors);
9482        *n = ct_colors_allocated;        *n = ct_colors_allocated;
9483          
9484        for (i = j = 0; i < CT_SIZE; ++i)        for (i = j = 0; i < CT_SIZE; ++i)
9485          for (p = ct_table[i]; p; p = p->next)          for (p = ct_table[i]; p; p = p->next)
9486            colors[j++] = p->pixel;            colors[j++] = p->pixel;
# Line 10696  x_to_xcolors (f, img, rgb_p) Line 9542  x_to_xcolors (f, img, rgb_p)
9542  {  {
9543    int x, y;    int x, y;
9544    XColor *colors, *p;    XColor *colors, *p;
9545    XImage *ximg;    HDC hdc, bmpdc;
9546      HGDIOBJ prev;
9547    
9548    colors = (XColor *) xmalloc (img->width * img->height * sizeof *colors);    colors = (XColor *) xmalloc (img->width * img->height * sizeof *colors);
9549  #if 0 /* TODO: implement image colors.  */  
9550    /* Get the X image IMG->pixmap.  */    /* Load the image into a memory device context.  */
9551    ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,    hdc = get_frame_dc (f);
9552                      0, 0, img->width, img->height, ~0, ZPixmap);    bmpdc = CreateCompatibleDC (hdc);
9553      release_frame_dc (f, hdc);
9554      prev = SelectObject (bmpdc, img->pixmap);
9555    
9556    /* Fill the `pixel' members of the XColor array.  I wished there    /* Fill the `pixel' members of the XColor array.  I wished there
9557       were an easy and portable way to circumvent XGetPixel.  */       were an easy and portable way to circumvent XGetPixel.  */
# Line 10710  x_to_xcolors (f, img, rgb_p) Line 9559  x_to_xcolors (f, img, rgb_p)
9559    for (y = 0; y < img->height; ++y)    for (y = 0; y < img->height; ++y)
9560      {      {
9561        XColor *row = p;        XColor *row = p;
9562          
9563        for (x = 0; x < img->width; ++x, ++p)        for (x = 0; x < img->width; ++x, ++p)
9564          p->pixel = XGetPixel (ximg, x, y);          {
9565              /* TODO: palette support needed here?  */
9566              p->pixel = GetPixel (bmpdc, x, y);
9567    
9568        if (rgb_p)            if (rgb_p)
9569          x_query_colors (f, row, img->width);              {
9570                  p->red = 256 * GetRValue (p->pixel);
9571                  p->green = 256 * GetGValue (p->pixel);
9572                  p->blue = 256 * GetBValue (p->pixel);
9573                }
9574            }
9575      }      }
9576    
9577    XDestroyImage (ximg);    SelectObject (bmpdc, prev);
9578  #endif    DeleteDC (bmpdc);
9579    
9580    return colors;    return colors;
9581  }  }
9582    
# Line 10734  static void XPutPixel (ximg, x, y, color Line 9591  static void XPutPixel (ximg, x, y, color
9591  {  {
9592    int width = ximg->info.bmiHeader.biWidth;    int width = ximg->info.bmiHeader.biWidth;
9593    int height = ximg->info.bmiHeader.biHeight;    int height = ximg->info.bmiHeader.biHeight;
   int rowbytes = width * 3;  
9594    unsigned char * pixel;    unsigned char * pixel;
9595    
9596    /* Don't support putting pixels in images with palettes.  */    /* True color images.  */
9597    xassert (ximg->info.bmiHeader.biBitCount == 24);    if (ximg->info.bmiHeader.biBitCount == 24)
9598        {
9599    /* Ensure scanlines are aligned on 4 byte boundaries.  */        int rowbytes = width * 3;
9600    if (rowbytes % 4)        /* Ensure scanlines are aligned on 4 byte boundaries.  */
9601      rowbytes += 4 - (rowbytes % 4);        if (rowbytes % 4)
9602            rowbytes += 4 - (rowbytes % 4);
9603    pixel = ximg->data + y * rowbytes + x * 3;  
9604    *pixel = 255 - GetRValue (color);        pixel = ximg->data + y * rowbytes + x * 3;
9605    *(pixel + 1) = 255 - GetGValue (color);        /* Windows bitmaps are in BGR order.  */
9606    *(pixel + 2) = 255 - GetBValue (color);        *pixel = GetBValue (color);
9607          *(pixel + 1) = GetGValue (color);
9608          *(pixel + 2) = GetRValue (color);
9609        }
9610      /* Monochrome images.  */
9611      else if (ximg->info.bmiHeader.biBitCount == 1)
9612        {
9613          int rowbytes = width / 8;
9614          /* Ensure scanlines are aligned on 4 byte boundaries.  */
9615          if (rowbytes % 4)
9616            rowbytes += 4 - (rowbytes % 4);
9617          pixel = ximg->data + y * rowbytes + x / 8;
9618          /* Filter out palette info.  */
9619          if (color & 0x00ffffff)
9620            *pixel = *pixel | (1 << x % 8);
9621          else
9622            *pixel = *pixel & ~(1 << x % 8);
9623        }
9624      else
9625        image_error ("XPutPixel: palette image not supported.", Qnil, Qnil);
9626  }  }
9627    
   
9628  /* Create IMG->pixmap from an array COLORS of XColor structures, whose  /* Create IMG->pixmap from an array COLORS of XColor structures, whose
9629     RGB members are set.  F is the frame on which this all happens.     RGB members are set.  F is the frame on which this all happens.
9630     COLORS will be freed; an existing IMG->pixmap will be freed, too.  */     COLORS will be freed; an existing IMG->pixmap will be freed, too.  */
# Line 10778  x_from_xcolors (f, img, colors) Line 9652  x_from_xcolors (f, img, colors)
9652  #if 0  /* TODO: color tables.  */  #if 0  /* TODO: color tables.  */
9653          pixel = lookup_rgb_color (f, p->red, p->green, p->blue);          pixel = lookup_rgb_color (f, p->red, p->green, p->blue);
9654  #else  #else
9655          pixel = PALETTERGB (p->red, p->green, p->blue);          pixel = PALETTERGB (p->red / 256, p->green / 256, p->blue / 256);
9656  #endif  #endif
9657          XPutPixel (oimg, x, y, pixel);          XPutPixel (oimg, x, y, pixel);
9658        }        }
# Line 10800  x_from_xcolors (f, img, colors) Line 9674  x_from_xcolors (f, img, colors)
9674    
9675     MATRIX is a nine-element array specifying the transformation     MATRIX is a nine-element array specifying the transformation
9676     matrix.  See emboss_matrix for an example.     matrix.  See emboss_matrix for an example.
9677      
9678     COLOR_ADJUST is a color adjustment added to each pixel of the     COLOR_ADJUST is a color adjustment added to each pixel of the
9679     outgoing image.  */     outgoing image.  */
9680    
# Line 10828  x_detect_edges (f, img, matrix, color_ad Line 9702  x_detect_edges (f, img, matrix, color_ad
9702        p = COLOR (new, img->width - 1, y);        p = COLOR (new, img->width - 1, y);
9703        p->red = p->green = p->blue = 0xffff/2;        p->red = p->green = p->blue = 0xffff/2;
9704      }      }
9705      
9706    for (x = 1; x < img->width - 1; ++x)    for (x = 1; x < img->width - 1; ++x)
9707      {      {
9708        p = COLOR (new, x, 0);        p = COLOR (new, x, 0);
# Line 10840  x_detect_edges (f, img, matrix, color_ad Line 9714  x_detect_edges (f, img, matrix, color_ad
9714    for (y = 1; y < img->height - 1; ++y)    for (y = 1; y < img->height - 1; ++y)
9715      {      {
9716        p = COLOR (new, 1, y);        p = COLOR (new, 1, y);
9717          
9718        for (x = 1; x < img->width - 1; ++x, ++p)        for (x = 1; x < img->width - 1; ++x, ++p)
9719          {          {
9720            int r, g, b, y1, x1;            int r, g, b, y1, x1;
# Line 10914  x_edge_detection (f, img, matrix, color_ Line 9788  x_edge_detection (f, img, matrix, color_
9788  {  {
9789    int i = 0;    int i = 0;
9790    int trans[9];    int trans[9];
9791      
9792    if (CONSP (matrix))    if (CONSP (matrix))
9793      {      {
9794        for (i = 0;        for (i = 0;
# Line 10971  x_disable_image (f, img) Line 9845  x_disable_image (f, img)
9845       should.  */       should.  */
9846    if (dpyinfo->n_planes * dpyinfo->n_cbits < 2 || cross_disabled_images)    if (dpyinfo->n_planes * dpyinfo->n_cbits < 2 || cross_disabled_images)
9847      {      {
9848  #if 0 /* TODO: full image support  */        HDC hdc, bmpdc;
9849        Display *dpy = FRAME_X_DISPLAY (f);        HGDIOBJ prev;
9850        GC gc;  
9851          hdc = get_frame_dc (f);
9852        gc = XCreateGC (dpy, img->pixmap, 0, NULL);        bmpdc = CreateCompatibleDC (hdc);
9853        XSetForeground (dpy, gc, BLACK_PIX_DEFAULT (f));        release_frame_dc (f, hdc);
9854        XDrawLine (dpy, img->pixmap, gc, 0, 0,  
9855                   img->width - 1, img->height - 1);        prev = SelectObject (bmpdc, img->pixmap);
9856        XDrawLine (dpy, img->pixmap, gc, 0, img->height - 1,  
9857                   img->width - 1, 0);        SetTextColor (bmpdc, BLACK_PIX_DEFAULT (f));
9858        XFreeGC (dpy, gc);        MoveToEx (bmpdc, 0, 0, NULL);
9859          LineTo (bmpdc, img->width - 1, img->height - 1);
9860          MoveToEx (bmpdc, 0, img->height - 1, NULL);
9861          LineTo (bmpdc, img->width - 1, 0);
9862    
9863        if (img->mask)        if (img->mask)
9864          {          {
9865            gc = XCreateGC (dpy, img->mask, 0, NULL);            SelectObject (bmpdc, img->mask);
9866            XSetForeground (dpy, gc, WHITE_PIX_DEFAULT (f));            SetTextColor (bmpdc, WHITE_PIX_DEFAULT (f));
9867            XDrawLine (dpy, img->mask, gc, 0, 0,            MoveToEx (bmpdc, 0, 0, NULL);
9868                       img->width - 1, img->height - 1);            LineTo (bmpdc, img->width - 1, img->height - 1);
9869            XDrawLine (dpy, img->mask, gc, 0, img->height - 1,            MoveToEx (bmpdc, 0, img->height - 1, NULL);
9870                       img->width - 1, 0);            LineTo (bmpdc, img->width - 1, 0);
           XFreeGC (dpy, gc);  
9871          }          }
9872  #endif        SelectObject (bmpdc, prev);
9873          DeleteDC (bmpdc);
9874      }      }
9875  }  }
9876    
# Line 11011  x_build_heuristic_mask (f, img, how) Line 9888  x_build_heuristic_mask (f, img, how)
9888       struct image *img;       struct image *img;
9889       Lisp_Object how;       Lisp_Object how;
9890  {  {
9891  #if 0 /* TODO: full image support.  */    HDC img_dc, frame_dc;
9892    Display *dpy = FRAME_W32_DISPLAY (f);    HGDIOBJ prev;
9893    XImage *ximg, *mask_img;    char *mask_img;
9894    int x, y, rc, use_img_background;    int x, y, rc, use_img_background;
9895    unsigned long bg = 0;    unsigned long bg = 0;
9896      int row_width;
9897    
9898    if (img->mask)    if (img->mask)
9899      {      {
9900        XFreePixmap (FRAME_X_DISPLAY (f), img->mask);        DeleteObject (img->mask);
9901        img->mask = None;        img->mask = NULL;
9902        img->background_transparent_valid = 0;        img->background_transparent_valid = 0;
9903      }      }
9904    
9905    /* Create an image and pixmap serving as mask.  */    /* Create the bit array serving as mask.  */
9906    rc = x_create_x_image_and_pixmap (f, img->width, img->height, 1,    row_width = (img->width + 7) / 8;
9907                                      &mask_img, &img->mask);    mask_img = xmalloc (row_width * img->height);
9908    if (!rc)    bzero (mask_img, row_width * img->height);
9909      return 0;  
9910      /* Create a memory device context for IMG->pixmap.  */
9911    /* Get the X image of IMG->pixmap.  */    frame_dc = get_frame_dc (f);
9912    ximg = XGetImage (dpy, img->pixmap, 0, 0, img->width, img->height,    img_dc = CreateCompatibleDC (frame_dc);
9913                      ~0, ZPixmap);    release_frame_dc (f, frame_dc);
9914      prev = SelectObject (img_dc, img->pixmap);
9915    
9916    /* Determine the background color of ximg.  If HOW is `(R G B)'    /* Determine the background color of img_dc.  If HOW is `(R G B)'
9917       take that as color.  Otherwise, use the image's background color.  */       take that as color.  Otherwise, use the image's background color.  */
9918    use_img_background = 1;    use_img_background = 1;
9919      
9920    if (CONSP (how))    if (CONSP (how))
9921      {      {
9922        int rgb[3], i;        int rgb[3], i;
# Line 11052  x_build_heuristic_mask (f, img, how) Line 9931  x_build_heuristic_mask (f, img, how)
9931          {          {
9932            char color_name[30];            char color_name[30];
9933            sprintf (color_name, "#%04x%04x%04x", rgb[0], rgb[1], rgb[2]);            sprintf (color_name, "#%04x%04x%04x", rgb[0], rgb[1], rgb[2]);
9934            bg = x_alloc_image_color (f, img, build_string (color_name), 0);            bg = x_alloc_image_color (f, img, build_string (color_name), 0)
9935                & 0x00ffffff; /* Filter out palette info.  */
9936            use_img_background = 0;            use_img_background = 0;
9937          }          }
9938      }      }
9939      
9940    if (use_img_background)    if (use_img_background)
9941      bg = four_corners_best (ximg, img->width, img->height);      bg = four_corners_best (img_dc, img->width, img->height);
9942    
9943    /* Set all bits in mask_img to 1 whose color in ximg is different    /* Set all bits in mask_img to 1 whose color in ximg is different
9944       from the background color bg.  */       from the background color bg.  */
9945    for (y = 0; y < img->height; ++y)    for (y = 0; y < img->height; ++y)
9946      for (x = 0; x < img->width; ++x)      for (x = 0; x < img->width; ++x)
9947        XPutPixel (mask_img, x, y, XGetPixel (ximg, x, y) != bg);        {
9948            COLORREF p = GetPixel (img_dc, x, y);
9949            if (p != bg)
9950              mask_img[y * row_width + x / 8] |= 1 << (x % 8);
9951          }
9952    
9953      /* Create the mask image.  */
9954      img->mask = w32_create_pixmap_from_bitmap_data (img->width, img->height,
9955                                                      mask_img);
9956    
9957    /* Fill in the background_transparent field while we have the mask handy. */    /* Fill in the background_transparent field while we have the mask handy. */
9958    image_background_transparent (img, f, mask_img);    SelectObject (img_dc, img->mask);
9959    
9960      image_background_transparent (img, f, img_dc);
9961    
9962    /* Put mask_img into img->mask.  */    /* Put mask_img into img->mask.  */
9963    x_put_x_image (f, mask_img, img->mask, img->width, img->height);    x_destroy_x_image ((XImage *)mask_img);
9964    x_destroy_x_image (mask_img);    SelectObject (img_dc, prev);
9965    XDestroyImage (ximg);    DeleteDC (img_dc);
9966    
9967    return 1;    return 1;
 #else  
   return 0;  
 #endif  
9968  }  }
9969    
9970    
# Line 11119  static struct image_keyword pbm_format[P Line 10006  static struct image_keyword pbm_format[P
10006    {":type",             IMAGE_SYMBOL_VALUE,                     1},    {":type",             IMAGE_SYMBOL_VALUE,                     1},
10007    {":file",             IMAGE_STRING_VALUE,                     0},    {":file",             IMAGE_STRING_VALUE,                     0},
10008    {":data",             IMAGE_STRING_VALUE,                     0},    {":data",             IMAGE_STRING_VALUE,                     0},
10009    {":ascent",           IMAGE_NON_NEGATIVE_INTEGER_VALUE,       0},    {":ascent",           IMAGE_ASCENT_VALUE,                     0},
10010    {":margin",           IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},    {":margin",           IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
10011    {":relief",           IMAGE_INTEGER_VALUE,                    0},    {":relief",           IMAGE_INTEGER_VALUE,                    0},
10012    {":conversion",       IMAGE_DONT_CHECK_VALUE_TYPE,            0},    {":conversion",       IMAGE_DONT_CHECK_VALUE_TYPE,            0},
# Line 11148  pbm_image_p (object) Line 10035  pbm_image_p (object)
10035       Lisp_Object object;       Lisp_Object object;
10036  {  {
10037    struct image_keyword fmt[PBM_LAST];    struct image_keyword fmt[PBM_LAST];
10038      
10039    bcopy (pbm_format, fmt, sizeof fmt);    bcopy (pbm_format, fmt, sizeof fmt);
10040      
10041    if (!parse_image_spec (object, fmt, PBM_LAST, Qpbm)    if (!parse_image_spec (object, fmt, PBM_LAST, Qpbm))
       || (fmt[PBM_ASCENT].count  
           && XFASTINT (fmt[PBM_ASCENT].value) > 100))  
10042      return 0;      return 0;
10043    
10044    /* Must specify either :data or :file.  */    /* Must specify either :data or :file.  */
# Line 11201  pbm_scan_number (s, end) Line 10086  pbm_scan_number (s, end)
10086    
10087  /* Read FILE into memory.  Value is a pointer to a buffer allocated  /* Read FILE into memory.  Value is a pointer to a buffer allocated
10088     with xmalloc holding FILE's contents.  Value is null if an error     with xmalloc holding FILE's contents.  Value is null if an error
10089     occured.  *SIZE is set to the size of the file.  */     occurred.  *SIZE is set to the size of the file.  */
10090    
10091  static char *  static char *
10092  pbm_read_file (file, size)  pbm_read_file (file, size)
# Line 11212  pbm_read_file (file, size) Line 10097  pbm_read_file (file, size)
10097    char *buf = NULL;    char *buf = NULL;
10098    struct stat st;    struct stat st;
10099    
10100    if (stat (XSTRING (file)->data, &st) == 0    if (stat (SDATA (file), &st) == 0
10101        && (fp = fopen (XSTRING (file)->data, "r")) != NULL        && (fp = fopen (SDATA (file), "rb")) != NULL
10102        && (buf = (char *) xmalloc (st.st_size),        && (buf = (char *) xmalloc (st.st_size),
10103            fread (buf, 1, st.st_size, fp) == st.st_size))            fread (buf, 1, st.st_size, fp) == st.st_size))
10104      {      {
# Line 11230  pbm_read_file (file, size) Line 10115  pbm_read_file (file, size)
10115            buf = NULL;            buf = NULL;
10116          }          }
10117      }      }
10118      
10119    return buf;    return buf;
10120  }  }
10121    
10122    
10123  /* Load PBM image IMG for use on frame F.  */  /* Load PBM image IMG for use on frame F.  */
10124    
10125  static int  static int
10126  pbm_load (f, img)  pbm_load (f, img)
10127       struct frame *f;       struct frame *f;
10128       struct image *img;       struct image *img;
# Line 11266  pbm_load (f, img) Line 10151  pbm_load (f, img)
10151            return 0;            return 0;
10152          }          }
10153    
10154        contents = slurp_file (XSTRING (file)->data, &size);        contents = slurp_file (SDATA (file), &size);
10155        if (contents == NULL)        if (contents == NULL)
10156          {          {
10157            image_error ("Error reading `%s'", file, Qnil);            image_error ("Error reading `%s'", file, Qnil);
# Line 11281  pbm_load (f, img) Line 10166  pbm_load (f, img)
10166      {      {
10167        Lisp_Object data;        Lisp_Object data;
10168        data = image_spec_value (img->spec, QCdata, NULL);        data = image_spec_value (img->spec, QCdata, NULL);
10169        p = XSTRING (data)->data;        p = SDATA (data);
10170        end = p + STRING_BYTES (XSTRING (data));        end = p + SBYTES (data);
10171      }      }
10172    
10173    /* Check magic number.  */    /* Check magic number.  */
# Line 11300  pbm_load (f, img) Line 10185  pbm_load (f, img)
10185      case '1':      case '1':
10186        raw_p = 0, type = PBM_MONO;        raw_p = 0, type = PBM_MONO;
10187        break;        break;
10188          
10189      case '2':      case '2':
10190        raw_p = 0, type = PBM_GRAY;        raw_p = 0, type = PBM_GRAY;
10191        break;        break;
# Line 11312  pbm_load (f, img) Line 10197  pbm_load (f, img)
10197      case '4':      case '4':
10198        raw_p = 1, type = PBM_MONO;        raw_p = 1, type = PBM_MONO;
10199        break;        break;
10200          
10201      case '5':      case '5':
10202        raw_p = 1, type = PBM_GRAY;        raw_p = 1, type = PBM_GRAY;
10203        break;        break;
10204          
10205      case '6':      case '6':
10206        raw_p = 1, type = PBM_COLOR;        raw_p = 1, type = PBM_COLOR;
10207        break;        break;
# Line 11337  pbm_load (f, img) Line 10222  pbm_load (f, img)
10222        if (raw_p && max_color_idx > 255)        if (raw_p && max_color_idx > 255)
10223          max_color_idx = 255;          max_color_idx = 255;
10224      }      }
10225      
10226    if (width < 0    if (width < 0
10227        || height < 0        || height < 0
10228        || (type != PBM_MONO && max_color_idx < 0))        || (type != PBM_MONO && max_color_idx < 0))
# Line 11361  pbm_load (f, img) Line 10246  pbm_load (f, img)
10246        /* Parse the image specification.  */        /* Parse the image specification.  */
10247        bcopy (pbm_format, fmt, sizeof fmt);        bcopy (pbm_format, fmt, sizeof fmt);
10248        parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm);        parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm);
10249          
10250        /* Get foreground and background colors, maybe allocate colors.  */        /* Get foreground and background colors, maybe allocate colors.  */
10251        if (fmt[PBM_FOREGROUND].count        if (fmt[PBM_FOREGROUND].count
10252            && STRINGP (fmt[PBM_FOREGROUND].value))            && STRINGP (fmt[PBM_FOREGROUND].value))
# Line 11396  pbm_load (f, img) Line 10281  pbm_load (f, img)
10281          for (x = 0; x < width; ++x)          for (x = 0; x < width; ++x)
10282            {            {
10283              int r, g, b;              int r, g, b;
10284                
10285              if (type == PBM_GRAY)              if (type == PBM_GRAY)
10286                r = g = b = raw_p ? *p++ : pbm_scan_number (&p, end);                r = g = b = raw_p ? *p++ : pbm_scan_number (&p, end);
10287              else if (raw_p)              else if (raw_p)
# Line 11411  pbm_load (f, img) Line 10296  pbm_load (f, img)
10296                  g = pbm_scan_number (&p, end);                  g = pbm_scan_number (&p, end);
10297                  b = pbm_scan_number (&p, end);                  b = pbm_scan_number (&p, end);
10298                }                }
10299                
10300              if (r < 0 || g < 0 || b < 0)              if (r < 0 || g < 0 || b < 0)
10301                {                {
10302                  x_destroy_x_image (ximg);                  x_destroy_x_image (ximg);
# Line 11419  pbm_load (f, img) Line 10304  pbm_load (f, img)
10304                               img->spec, Qnil);                               img->spec, Qnil);
10305                  goto error;                  goto error;
10306                }                }
10307                
10308              /* RGB values are now in the range 0..max_color_idx.              /* RGB values are now in the range 0..max_color_idx.
10309                 Scale this to the range 0..0xff supported by W32.  */                 Scale this to the range 0..0xff supported by W32.  */
10310              r = (int) ((double) r * 255 / max_color_idx);              r = (int) ((double) r * 255 / max_color_idx);
# Line 11443  pbm_load (f, img) Line 10328  pbm_load (f, img)
10328    /* Maybe fill in the background field while we have ximg handy.  */    /* Maybe fill in the background field while we have ximg handy.  */
10329    if (NILP (image_spec_value (img->spec, QCbackground, NULL)))    if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
10330      IMAGE_BACKGROUND (img, f, ximg);      IMAGE_BACKGROUND (img, f, ximg);
10331      
10332    /* Put the image into a pixmap.  */    /* Put the image into a pixmap.  */
10333    x_put_x_image (f, ximg, img->pixmap, width, height);    x_put_x_image (f, ximg, img->pixmap, width, height);
10334    x_destroy_x_image (ximg);    x_destroy_x_image (ximg);
10335          
10336    img->width = width;    img->width = width;
10337    img->height = height;    img->height = height;
10338    
# Line 11499  static struct image_keyword png_format[P Line 10384  static struct image_keyword png_format[P
10384    {":type",             IMAGE_SYMBOL_VALUE,                     1},    {":type",             IMAGE_SYMBOL_VALUE,                     1},
10385    {":data",             IMAGE_STRING_VALUE,                     0},    {":data",             IMAGE_STRING_VALUE,                     0},
10386    {":file",             IMAGE_STRING_VALUE,                     0},    {":file",             IMAGE_STRING_VALUE,                     0},
10387    {":ascent",           IMAGE_NON_NEGATIVE_INTEGER_VALUE,       0},    {":ascent",           IMAGE_ASCENT_VALUE,                     0},
10388    {":margin",           IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},    {":margin",           IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
10389    {":relief",           IMAGE_INTEGER_VALUE,                    0},    {":relief",           IMAGE_INTEGER_VALUE,                    0},
10390    {":conversion",       IMAGE_DONT_CHECK_VALUE_TYPE,            0},    {":conversion",       IMAGE_DONT_CHECK_VALUE_TYPE,            0},
# Line 11519  static struct image_type png_type = Line 10404  static struct image_type png_type =
10404    NULL    NULL
10405  };  };
10406    
10407    /* PNG library details.  */
10408    
10409    DEF_IMGLIB_FN (png_get_io_ptr);
10410    DEF_IMGLIB_FN (png_check_sig);
10411    DEF_IMGLIB_FN (png_create_read_struct);
10412    DEF_IMGLIB_FN (png_create_info_struct);
10413    DEF_IMGLIB_FN (png_destroy_read_struct);
10414    DEF_IMGLIB_FN (png_set_read_fn);
10415    DEF_IMGLIB_FN (png_init_io);
10416    DEF_IMGLIB_FN (png_set_sig_bytes);
10417    DEF_IMGLIB_FN (png_read_info);
10418    DEF_IMGLIB_FN (png_get_IHDR);
10419    DEF_IMGLIB_FN (png_get_valid);
10420    DEF_IMGLIB_FN (png_set_strip_16);
10421    DEF_IMGLIB_FN (png_set_expand);
10422    DEF_IMGLIB_FN (png_set_gray_to_rgb);
10423    DEF_IMGLIB_FN (png_set_background);
10424    DEF_IMGLIB_FN (png_get_bKGD);
10425    DEF_IMGLIB_FN (png_read_update_info);
10426    DEF_IMGLIB_FN (png_get_channels);
10427    DEF_IMGLIB_FN (png_get_rowbytes);
10428    DEF_IMGLIB_FN (png_read_image);
10429    DEF_IMGLIB_FN (png_read_end);
10430    DEF_IMGLIB_FN (png_error);
10431    
10432    static int
10433    init_png_functions (library)
10434         HMODULE library;
10435    {
10436      LOAD_IMGLIB_FN (library, png_get_io_ptr);
10437      LOAD_IMGLIB_FN (library, png_check_sig);
10438      LOAD_IMGLIB_FN (library, png_create_read_struct);
10439      LOAD_IMGLIB_FN (library, png_create_info_struct);
10440      LOAD_IMGLIB_FN (library, png_destroy_read_struct);
10441      LOAD_IMGLIB_FN (library, png_set_read_fn);
10442      LOAD_IMGLIB_FN (library, png_init_io);
10443      LOAD_IMGLIB_FN (library, png_set_sig_bytes);
10444      LOAD_IMGLIB_FN (library, png_read_info);
10445      LOAD_IMGLIB_FN (library, png_get_IHDR);
10446      LOAD_IMGLIB_FN (library, png_get_valid);
10447      LOAD_IMGLIB_FN (library, png_set_strip_16);
10448      LOAD_IMGLIB_FN (library, png_set_expand);
10449      LOAD_IMGLIB_FN (library, png_set_gray_to_rgb);
10450      LOAD_IMGLIB_FN (library, png_set_background);
10451      LOAD_IMGLIB_FN (library, png_get_bKGD);
10452      LOAD_IMGLIB_FN (library, png_read_update_info);
10453      LOAD_IMGLIB_FN (library, png_get_channels);
10454      LOAD_IMGLIB_FN (library, png_get_rowbytes);
10455      LOAD_IMGLIB_FN (library, png_read_image);
10456      LOAD_IMGLIB_FN (library, png_read_end);
10457      LOAD_IMGLIB_FN (library, png_error);
10458      return 1;
10459    }
10460    
10461  /* Return non-zero if OBJECT is a valid PNG image specification.  */  /* Return non-zero if OBJECT is a valid PNG image specification.  */
10462    
# Line 11528  png_image_p (object) Line 10466  png_image_p (object)
10466  {  {
10467    struct image_keyword fmt[PNG_LAST];    struct image_keyword fmt[PNG_LAST];
10468    bcopy (png_format, fmt, sizeof fmt);    bcopy (png_format, fmt, sizeof fmt);
10469      
10470    if (!parse_image_spec (object, fmt, PNG_LAST, Qpng)    if (!parse_image_spec (object, fmt, PNG_LAST, Qpng))
       || (fmt[PNG_ASCENT].count  
           && XFASTINT (fmt[PNG_ASCENT].value) > 100))  
10471      return 0;      return 0;
10472    
10473    /* Must specify either the :data or :file keyword.  */    /* Must specify either the :data or :file keyword.  */
# Line 11583  png_read_from_memory (png_ptr, data, len Line 10519  png_read_from_memory (png_ptr, data, len
10519       png_size_t length;       png_size_t length;
10520  {  {
10521    struct png_memory_storage *tbr    struct png_memory_storage *tbr
10522      = (struct png_memory_storage *) png_get_io_ptr (png_ptr);      = (struct png_memory_storage *) fn_png_get_io_ptr (png_ptr);
10523    
10524    if (length > tbr->len - tbr->index)    if (length > tbr->len - tbr->index)
10525      png_error (png_ptr, "Read error");      fn_png_error (png_ptr, "Read error");
10526      
10527    bcopy (tbr->bytes + tbr->index, data, length);    bcopy (tbr->bytes + tbr->index, data, length);
10528    tbr->index = tbr->index + length;    tbr->index = tbr->index + length;
10529  }  }
# Line 11609  png_load (f, img) Line 10545  png_load (f, img)
10545    png_info *info_ptr = NULL, *end_info = NULL;    png_info *info_ptr = NULL, *end_info = NULL;
10546    FILE *volatile fp = NULL;    FILE *volatile fp = NULL;
10547    png_byte sig[8];    png_byte sig[8];
10548    png_byte *volatile pixels = NULL;    png_byte * volatile pixels = NULL;
10549    png_byte **volatile rows = NULL;    png_byte ** volatile rows = NULL;
10550    png_uint_32 width, height;    png_uint_32 width, height;
10551    int bit_depth, color_type, interlace_type;    int bit_depth, color_type, interlace_type;
10552    png_byte channels;    png_byte channels;
10553    png_uint_32 row_bytes;    png_uint_32 row_bytes;
10554    int transparent_p;    int transparent_p;
   char *gamma_str;  
10555    double screen_gamma, image_gamma;    double screen_gamma, image_gamma;
10556    int intent;    int intent;
10557    struct png_memory_storage tbr;  /* Data to be read */    struct png_memory_storage tbr;  /* Data to be read */
# Line 11631  png_load (f, img) Line 10566  png_load (f, img)
10566      {      {
10567        file = x_find_image_file (specified_file);        file = x_find_image_file (specified_file);
10568        if (!STRINGP (file))        if (!STRINGP (file))
10569          {          {
10570            image_error ("Cannot find image file `%s'", specified_file, Qnil);            image_error ("Cannot find image file `%s'", specified_file, Qnil);
10571            UNGCPRO;            UNGCPRO;
10572            return 0;            return 0;
10573          }          }
10574    
10575        /* Open the image file.  */        /* Open the image file.  */
10576        fp = fopen (XSTRING (file)->data, "rb");        fp = fopen (SDATA (file), "rb");
10577        if (!fp)        if (!fp)
10578          {          {
10579            image_error ("Cannot open image file `%s'", file, Qnil);            image_error ("Cannot open image file `%s'", file, Qnil);
10580            UNGCPRO;            UNGCPRO;
10581            fclose (fp);            fclose (fp);
10582            return 0;            return 0;
10583          }          }
10584    
10585        /* Check PNG signature.  */        /* Check PNG signature.  */
10586        if (fread (sig, 1, sizeof sig, fp) != sizeof sig        if (fread (sig, 1, sizeof sig, fp) != sizeof sig
10587            || !png_check_sig (sig, sizeof sig))            || !fn_png_check_sig (sig, sizeof sig))
10588          {          {
10589            image_error ("Not a PNG file:` %s'", file, Qnil);            image_error ("Not a PNG file: `%s'", file, Qnil);
10590            UNGCPRO;            UNGCPRO;
10591            fclose (fp);            fclose (fp);
10592            return 0;            return 0;
10593          }          }
10594      }      }
10595    else    else
10596      {      {
10597        /* Read from memory.  */        /* Read from memory.  */
10598        tbr.bytes = XSTRING (specified_data)->data;        tbr.bytes = SDATA (specified_data);
10599        tbr.len = STRING_BYTES (XSTRING (specified_data));        tbr.len = SBYTES (specified_data);
10600        tbr.index = 0;        tbr.index = 0;
10601    
10602        /* Check PNG signature.  */        /* Check PNG signature.  */
10603        if (tbr.len < sizeof sig        if (tbr.len < sizeof sig
10604            || !png_check_sig (tbr.bytes, sizeof sig))            || !fn_png_check_sig (tbr.bytes, sizeof sig))
10605          {          {
10606            image_error ("Not a PNG image: `%s'", img->spec, Qnil);            image_error ("Not a PNG image: `%s'", img->spec, Qnil);
10607            UNGCPRO;            UNGCPRO;
# Line 11678  png_load (f, img) Line 10613  png_load (f, img)
10613      }      }
10614    
10615    /* Initialize read and info structs for PNG lib.  */    /* Initialize read and info structs for PNG lib.  */
10616    png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL,    png_ptr = fn_png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL,
10617                                      my_png_error, my_png_warning);                                         my_png_error, my_png_warning);
10618    if (!png_ptr)    if (!png_ptr)
10619      {      {
10620        if (fp) fclose (fp);        if (fp) fclose (fp);
# Line 11687  png_load (f, img) Line 10622  png_load (f, img)
10622        return 0;        return 0;
10623      }      }
10624    
10625    info_ptr = png_create_info_struct (png_ptr);    info_ptr = fn_png_create_info_struct (png_ptr);
10626    if (!info_ptr)    if (!info_ptr)
10627      {      {
10628        png_destroy_read_struct (&png_ptr, NULL, NULL);        fn_png_destroy_read_struct (&png_ptr, NULL, NULL);
10629        if (fp) fclose (fp);        if (fp) fclose (fp);
10630        UNGCPRO;        UNGCPRO;
10631        return 0;        return 0;
10632      }      }
10633    
10634    end_info = png_create_info_struct (png_ptr);    end_info = fn_png_create_info_struct (png_ptr);
10635    if (!end_info)    if (!end_info)
10636      {      {
10637        png_destroy_read_struct (&png_ptr, &info_ptr, NULL);        fn_png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
10638        if (fp) fclose (fp);        if (fp) fclose (fp);
10639        UNGCPRO;        UNGCPRO;
10640        return 0;        return 0;
# Line 11711  png_load (f, img) Line 10646  png_load (f, img)
10646      {      {
10647      error:      error:
10648        if (png_ptr)        if (png_ptr)
10649          png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);          fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
10650        xfree (pixels);        xfree (pixels);
10651        xfree (rows);        xfree (rows);
10652        if (fp) fclose (fp);        if (fp) fclose (fp);
# Line 11721  png_load (f, img) Line 10656  png_load (f, img)
10656    
10657    /* Read image info.  */    /* Read image info.  */
10658    if (!NILP (specified_data))    if (!NILP (specified_data))
10659      png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory);      fn_png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory);
10660    else    else
10661      png_init_io (png_ptr, fp);      fn_png_init_io (png_ptr, fp);
10662    
10663    png_set_sig_bytes (png_ptr, sizeof sig);    fn_png_set_sig_bytes (png_ptr, sizeof sig);
10664    png_read_info (png_ptr, info_ptr);    fn_png_read_info (png_ptr, info_ptr);
10665    png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,    fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
10666                  &interlace_type, NULL, NULL);                     &interlace_type, NULL, NULL);
10667    
10668    /* If image contains simply transparency data, we prefer to    /* If image contains simply transparency data, we prefer to
10669       construct a clipping mask.  */       construct a clipping mask.  */
10670    if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))    if (fn_png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
10671      transparent_p = 1;      transparent_p = 1;
10672    else    else
10673      transparent_p = 0;      transparent_p = 0;
10674    
10675    /* This function is easier to write if we only have to handle    /* This function is easier to write if we only have to handle
10676       one data format: RGB or RGBA with 8 bits per channel.  Let's       one data format: RGB or RGBA with 8 bits per channel.  Let's
10677       transform other formats into that format.  */       transform other formats into that format.  */
10678    
10679    /* Strip more than 8 bits per channel.  */    /* Strip more than 8 bits per channel.  */
10680    if (bit_depth == 16)    if (bit_depth == 16)
10681      png_set_strip_16 (png_ptr);      fn_png_set_strip_16 (png_ptr);
10682    
10683    /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel    /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
10684       if available.  */       if available.  */
10685    png_set_expand (png_ptr);    fn_png_set_expand (png_ptr);
10686    
10687    /* Convert grayscale images to RGB.  */    /* Convert grayscale images to RGB.  */
10688    if (color_type == PNG_COLOR_TYPE_GRAY    if (color_type == PNG_COLOR_TYPE_GRAY
10689        || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)        || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
10690      png_set_gray_to_rgb (png_ptr);      fn_png_set_gray_to_rgb (png_ptr);
10691    
10692    /* The value 2.2 is a guess for PC monitors from PNG example.c.  */    screen_gamma = (f->gamma ? 1 / f->gamma / 0.45455 : 2.2);
   gamma_str = getenv ("SCREEN_GAMMA");  
   screen_gamma = gamma_str ? atof (gamma_str) : 2.2;  
10693    
10694    #if 0 /* Avoid double gamma correction for PNG images. */
10695    /* Tell the PNG lib to handle gamma correction for us.  */    /* Tell the PNG lib to handle gamma correction for us.  */
   
10696  #if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)  #if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
10697    if (png_get_sRGB (png_ptr, info_ptr, &intent))    if (png_get_sRGB (png_ptr, info_ptr, &intent))
10698      /* There is a special chunk in the image specifying the gamma.  */      /* The libpng documentation says this is right in this case.  */
10699      png_set_sRGB (png_ptr, info_ptr, intent);      png_set_gamma (png_ptr, screen_gamma, 0.45455);
10700    else    else
10701  #endif  #endif
10702    if (png_get_gAMA (png_ptr, info_ptr, &image_gamma))    if (png_get_gAMA (png_ptr, info_ptr, &image_gamma))
10703      /* Image contains gamma information.  */      /* Image contains gamma information.  */
10704      png_set_gamma (png_ptr, screen_gamma, image_gamma);      png_set_gamma (png_ptr, screen_gamma, image_gamma);
10705    else    else
10706      /* Use a default of 0.5 for the image gamma.  */      /* Use the standard default for the image gamma.  */
10707      png_set_gamma (png_ptr, screen_gamma, 0.5);      png_set_gamma (png_ptr, screen_gamma, 0.45455);
10708    #endif /* if 0 */
10709    
10710    /* Handle alpha channel by combining the image with a background    /* Handle alpha channel by combining the image with a background
10711       color.  Do this only if a real alpha channel is supplied.  For       color.  Do this only if a real alpha channel is supplied.  For
10712       simple transparency, we prefer a clipping mask.  */       simple transparency, we prefer a clipping mask.  */
10713    if (!transparent_p)    if (!transparent_p)
10714      {      {
10715        png_color_16 *image_background;        png_color_16 *image_bg;
10716        Lisp_Object specified_bg        Lisp_Object specified_bg
10717          = image_spec_value (img->spec, QCbackground, NULL);          = image_spec_value (img->spec, QCbackground, NULL);
10718    
   
10719        if (STRINGP (specified_bg))        if (STRINGP (specified_bg))
10720          /* The user specified `:background', use that.  */          /* The user specified `:background', use that.  */
10721          {          {
10722            COLORREF color;            COLORREF color;
10723            if (w32_defined_color (f, XSTRING (specified_bg)->data, &color, 0))            if (w32_defined_color (f, SDATA (specified_bg), &color, 0))
10724              {              {
10725                png_color_16 user_bg;                png_color_16 user_bg;
10726    
10727                bzero (&user_bg, sizeof user_bg);                bzero (&user_bg, sizeof user_bg);
10728                user_bg.red = color.red;                user_bg.red = 256 * GetRValue (color);
10729                user_bg.green = color.green;                user_bg.green = 256 * GetGValue (color);
10730                user_bg.blue = color.blue;                user_bg.blue = 256 * GetBValue (color);
10731    
10732                png_set_background (png_ptr, &user_bg,                fn_png_set_background (png_ptr, &user_bg,
10733                                    PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);                                       PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
10734              }              }
10735          }          }
10736        else if (png_get_bKGD (png_ptr, info_ptr, &image_background))        else if (fn_png_get_bKGD (png_ptr, info_ptr, &image_bg))
10737          /* Image contains a background color with which to          /* Image contains a background color with which to
10738             combine the image.  */             combine the image.  */
10739          png_set_background (png_ptr, image_background,          fn_png_set_background (png_ptr, image_bg,
10740                              PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);                                 PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
10741        else        else
10742          {          {
10743            /* Image does not contain a background color with which            /* Image does not contain a background color with which
10744               to combine the image data via an alpha channel.  Use               to combine the image data via an alpha channel.  Use
10745               the frame's background instead.  */               the frame's background instead.  */
10746            XColor color;            COLORREF color;
           Colormap cmap;  
10747            png_color_16 frame_background;            png_color_16 frame_background;
10748              color = FRAME_BACKGROUND_PIXEL (f);
10749    #if 0 /* TODO : Colormap support.  */
10750              Colormap cmap;
10751    
10752            cmap = FRAME_X_COLORMAP (f);            cmap = FRAME_X_COLORMAP (f);
           color.pixel = FRAME_BACKGROUND_PIXEL (f);  
10753            x_query_color (f, &color);            x_query_color (f, &color);
10754    #endif
10755    
10756            bzero (&frame_background, sizeof frame_background);            bzero (&frame_background, sizeof frame_background);
10757            frame_background.red = color.red;            frame_background.red = 256 * GetRValue (color);
10758            frame_background.green = color.green;            frame_background.green = 256 * GetGValue (color);
10759            frame_background.blue = color.blue;            frame_background.blue = 256 * GetBValue (color);
10760    
10761            png_set_background (png_ptr, &frame_background,            fn_png_set_background (png_ptr, &frame_background,
10762                                PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);                                   PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
10763          }          }
10764      }      }
10765    
10766    /* Update info structure.  */    /* Update info structure.  */
10767    png_read_update_info (png_ptr, info_ptr);    fn_png_read_update_info (png_ptr, info_ptr);
10768    
10769    /* Get number of channels.  Valid values are 1 for grayscale images    /* Get number of channels.  Valid values are 1 for grayscale images
10770       and images with a palette, 2 for grayscale images with transparency       and images with a palette, 2 for grayscale images with transparency
10771       information (alpha channel), 3 for RGB images, and 4 for RGB       information (alpha channel), 3 for RGB images, and 4 for RGB
10772       images with alpha channel, i.e. RGBA.  If conversions above were       images with alpha channel, i.e. RGBA.  If conversions above were
10773       sufficient we should only have 3 or 4 channels here.  */       sufficient we should only have 3 or 4 channels here.  */
10774    channels = png_get_channels (png_ptr, info_ptr);    channels = fn_png_get_channels (png_ptr, info_ptr);
10775    xassert (channels == 3 || channels == 4);    xassert (channels == 3 || channels == 4);
10776    
10777    /* Number of bytes needed for one row of the image.  */    /* Number of bytes needed for one row of the image.  */
10778    row_bytes = png_get_rowbytes (png_ptr, info_ptr);    row_bytes = fn_png_get_rowbytes (png_ptr, info_ptr);
10779    
10780    /* Allocate memory for the image.  */    /* Allocate memory for the image.  */
10781    pixels = (png_byte *) xmalloc (row_bytes * height * sizeof *pixels);    pixels = (png_byte *) xmalloc (row_bytes * height * sizeof *pixels);
# Line 11849  png_load (f, img) Line 10784  png_load (f, img)
10784      rows[i] = pixels + i * row_bytes;      rows[i] = pixels + i * row_bytes;
10785    
10786    /* Read the entire image.  */    /* Read the entire image.  */
10787    png_read_image (png_ptr, rows);    fn_png_read_image (png_ptr, rows);
10788    png_read_end (png_ptr, info_ptr);    fn_png_read_end (png_ptr, info_ptr);
10789    if (fp)    if (fp)
10790      {      {
10791        fclose (fp);        fclose (fp);
# Line 11861  png_load (f, img) Line 10796  png_load (f, img)
10796    if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg,    if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg,
10797                                      &img->pixmap))                                      &img->pixmap))
10798      goto error;      goto error;
10799      
10800    /* Create an image and pixmap serving as mask if the PNG image    /* Create an image and pixmap serving as mask if the PNG image
10801       contains an alpha channel.  */       contains an alpha channel.  */
10802    if (channels == 4    if (channels == 4
# Line 11870  png_load (f, img) Line 10805  png_load (f, img)
10805                                         &mask_img, &img->mask))                                         &mask_img, &img->mask))
10806      {      {
10807        x_destroy_x_image (ximg);        x_destroy_x_image (ximg);
10808        XFreePixmap (FRAME_W32_DISPLAY (f), img->pixmap);        DeleteObject (img->pixmap);
10809        img->pixmap = 0;        img->pixmap = 0;
10810        goto error;        goto error;
10811      }      }
   
10812    /* Fill the X image and mask from PNG data.  */    /* Fill the X image and mask from PNG data.  */
10813    #if 0 /* TODO: Color tables.  */
10814    init_color_table ();    init_color_table ();
10815    #endif
10816    
10817    for (y = 0; y < height; ++y)    for (y = 0; y < height; ++y)
10818      {      {
# Line 11886  png_load (f, img) Line 10822  png_load (f, img)
10822          {          {
10823            unsigned r, g, b;            unsigned r, g, b;
10824    
10825            r = *p++ << 8;            r = *p++;
10826            g = *p++ << 8;            g = *p++;
10827            b = *p++ << 8;            b = *p++;
10828    #if 0 /* TODO: Color tables.  */
10829            XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b));            XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b));
10830    #else
10831              XPutPixel (ximg, x, y, PALETTERGB (r, g, b));
10832    #endif
10833            /* An alpha channel, aka mask channel, associates variable            /* An alpha channel, aka mask channel, associates variable
10834               transparency with an image.  Where other image formats               transparency with an image.  Where other image formats
10835               support binary transparency---fully transparent or fully               support binary transparency---fully transparent or fully
10836               opaque---PNG allows up to 254 levels of partial transparency.               opaque---PNG allows up to 254 levels of partial transparency.
10837               The PNG library implements partial transparency by combining               The PNG library implements partial transparency by combining
10838               the image with a specified background color.               the image with a specified background color.
10839    
10840               I'm not sure how to handle this here nicely: because the               I'm not sure how to handle this here nicely: because the
10841               background on which the image is displayed may change, for               background on which the image is displayed may change, for
10842               real alpha channel support, it would be necessary to create               real alpha channel support, it would be necessary to create
10843               a new image for each possible background.                 a new image for each possible background.
10844    
10845               What I'm doing now is that a mask is created if we have               What I'm doing now is that a mask is created if we have
10846               boolean transparency information.  Otherwise I'm using               boolean transparency information.  Otherwise I'm using
# Line 11921  png_load (f, img) Line 10860  png_load (f, img)
10860         overrode it.  */         overrode it.  */
10861      {      {
10862        png_color_16 *bg;        png_color_16 *bg;
10863        if (png_get_bKGD (png_ptr, info_ptr, &bg))        if (fn_png_get_bKGD (png_ptr, info_ptr, &bg))
10864          {          {
10865    #if 0 /* TODO: Color tables.  */
10866            img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue);            img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue);
10867    #else
10868              img->background = PALETTERGB (bg->red / 256, bg->green / 256,
10869                                            bg->blue / 256);
10870    #endif
10871            img->background_valid = 1;            img->background_valid = 1;
10872          }          }
10873      }      }
10874    
10875    #if 0 /* TODO: Color tables.  */
10876    /* Remember colors allocated for this image.  */    /* Remember colors allocated for this image.  */
10877    img->colors = colors_in_color_table (&img->ncolors);    img->colors = colors_in_color_table (&img->ncolors);
10878    free_color_table ();    free_color_table ();
10879    #endif
10880    
10881    /* Clean up.  */    /* Clean up.  */
10882    png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);    fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
10883    xfree (rows);    xfree (rows);
10884    xfree (pixels);    xfree (pixels);
10885    
# Line 12019  static struct image_keyword jpeg_format[ Line 10965  static struct image_keyword jpeg_format[
10965    {":type",             IMAGE_SYMBOL_VALUE,                     1},    {":type",             IMAGE_SYMBOL_VALUE,                     1},
10966    {":data",             IMAGE_STRING_VALUE,                     0},    {":data",             IMAGE_STRING_VALUE,                     0},
10967    {":file",             IMAGE_STRING_VALUE,                     0},    {":file",             IMAGE_STRING_VALUE,                     0},
10968    {":ascent",           IMAGE_NON_NEGATIVE_INTEGER_VALUE,       0},    {":ascent",           IMAGE_ASCENT_VALUE,                     0},
10969    {":margin",           IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},    {":margin",           IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
10970    {":relief",           IMAGE_INTEGER_VALUE,                    0},    {":relief",           IMAGE_INTEGER_VALUE,                    0},
10971    {":conversions",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},    {":conversions",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
# Line 12040  static struct image_type jpeg_type = Line 10986  static struct image_type jpeg_type =
10986  };  };
10987    
10988    
10989    /* JPEG library details.  */
10990    DEF_IMGLIB_FN (jpeg_CreateDecompress);
10991    DEF_IMGLIB_FN (jpeg_start_decompress);
10992    DEF_IMGLIB_FN (jpeg_finish_decompress);
10993    DEF_IMGLIB_FN (jpeg_destroy_decompress);
10994    DEF_IMGLIB_FN (jpeg_read_header);
10995    DEF_IMGLIB_FN (jpeg_read_scanlines);
10996    DEF_IMGLIB_FN (jpeg_stdio_src);
10997    DEF_IMGLIB_FN (jpeg_std_error);
10998    DEF_IMGLIB_FN (jpeg_resync_to_restart);
10999    
11000    static int
11001    init_jpeg_functions (library)
11002         HMODULE library;
11003    {
11004      LOAD_IMGLIB_FN (library, jpeg_finish_decompress);
11005      LOAD_IMGLIB_FN (library, jpeg_read_scanlines);
11006      LOAD_IMGLIB_FN (library, jpeg_start_decompress);
11007      LOAD_IMGLIB_FN (library, jpeg_read_header);
11008      LOAD_IMGLIB_FN (library, jpeg_stdio_src);
11009      LOAD_IMGLIB_FN (library, jpeg_CreateDecompress);
11010      LOAD_IMGLIB_FN (library, jpeg_destroy_decompress);
11011      LOAD_IMGLIB_FN (library, jpeg_std_error);
11012      LOAD_IMGLIB_FN (library, jpeg_resync_to_restart);
11013      return 1;
11014    }
11015    
11016    /* Wrapper since we can't directly assign the function pointer
11017       to another function pointer that was declared more completely easily.  */
11018    static boolean
11019    jpeg_resync_to_restart_wrapper(cinfo, desired)
11020         j_decompress_ptr cinfo;
11021         int desired;
11022    {
11023      return fn_jpeg_resync_to_restart (cinfo, desired);
11024    }
11025    
11026    
11027  /* Return non-zero if OBJECT is a valid JPEG image specification.  */  /* Return non-zero if OBJECT is a valid JPEG image specification.  */
11028    
11029  static int  static int
# Line 12047  jpeg_image_p (object) Line 11031  jpeg_image_p (object)
11031       Lisp_Object object;       Lisp_Object object;
11032  {  {
11033    struct image_keyword fmt[JPEG_LAST];    struct image_keyword fmt[JPEG_LAST];
11034      
11035    bcopy (jpeg_format, fmt, sizeof fmt);    bcopy (jpeg_format, fmt, sizeof fmt);
11036      
11037    if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg)    if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg))
       || (fmt[JPEG_ASCENT].count  
           && XFASTINT (fmt[JPEG_ASCENT].value) > 100))  
11038      return 0;      return 0;
11039    
11040    /* Must specify either the :data or :file keyword.  */    /* Must specify either the :data or :file keyword.  */
# Line 12066  struct my_jpeg_error_mgr Line 11048  struct my_jpeg_error_mgr
11048    jmp_buf setjmp_buffer;    jmp_buf setjmp_buffer;
11049  };  };
11050    
11051    
11052  static void  static void
11053  my_error_exit (cinfo)  my_error_exit (cinfo)
11054       j_common_ptr cinfo;       j_common_ptr cinfo;
# Line 12074  my_error_exit (cinfo) Line 11057  my_error_exit (cinfo)
11057    longjmp (mgr->setjmp_buffer, 1);    longjmp (mgr->setjmp_buffer, 1);
11058  }  }
11059    
11060    
11061  /* Init source method for JPEG data source manager.  Called by  /* Init source method for JPEG data source manager.  Called by
11062     jpeg_read_header() before any data is actually read.  See     jpeg_read_header() before any data is actually read.  See
11063     libjpeg.doc from the JPEG lib distribution.  */     libjpeg.doc from the JPEG lib distribution.  */
# Line 12120  our_skip_input_data (cinfo, num_bytes) Line 11104  our_skip_input_data (cinfo, num_bytes)
11104      {      {
11105        if (num_bytes > src->bytes_in_buffer)        if (num_bytes > src->bytes_in_buffer)
11106          ERREXIT (cinfo, JERR_INPUT_EOF);          ERREXIT (cinfo, JERR_INPUT_EOF);
11107          
11108        src->bytes_in_buffer -= num_bytes;        src->bytes_in_buffer -= num_bytes;
11109        src->next_input_byte += num_bytes;        src->next_input_byte += num_bytes;
11110      }      }
# Line 12158  jpeg_memory_src (cinfo, data, len) Line 11142  jpeg_memory_src (cinfo, data, len)
11142        src = (struct jpeg_source_mgr *) cinfo->src;        src = (struct jpeg_source_mgr *) cinfo->src;
11143        src->next_input_byte = data;        src->next_input_byte = data;
11144      }      }
11145      
11146    src = (struct jpeg_source_mgr *) cinfo->src;    src = (struct jpeg_source_mgr *) cinfo->src;
11147    src->init_source = our_init_source;    src->init_source = our_init_source;
11148    src->fill_input_buffer = our_fill_input_buffer;    src->fill_input_buffer = our_fill_input_buffer;
11149    src->skip_input_data = our_skip_input_data;    src->skip_input_data = our_skip_input_data;
11150    src->resync_to_restart = jpeg_resync_to_restart; /* Use default method.  */    src->resync_to_restart = jpeg_resync_to_restart_wrapper; /* Use default method.  */
11151    src->term_source = our_term_source;    src->term_source = our_term_source;
11152    src->bytes_in_buffer = len;    src->bytes_in_buffer = len;
11153    src->next_input_byte = data;    src->next_input_byte = data;
# Line 12173  jpeg_memory_src (cinfo, data, len) Line 11157  jpeg_memory_src (cinfo, data, len)
11157  /* Load image IMG for use on frame F.  Patterned after example.c  /* Load image IMG for use on frame F.  Patterned after example.c
11158     from the JPEG lib.  */     from the JPEG lib.  */
11159    
11160  static int  static int
11161  jpeg_load (f, img)  jpeg_load (f, img)
11162       struct frame *f;       struct frame *f;
11163       struct image *img;       struct image *img;
# Line 12201  jpeg_load (f, img) Line 11185  jpeg_load (f, img)
11185      {      {
11186        file = x_find_image_file (specified_file);        file = x_find_image_file (specified_file);
11187        if (!STRINGP (file))        if (!STRINGP (file))
11188          {          {
11189            image_error ("Cannot find image file `%s'", specified_file, Qnil);            image_error ("Cannot find image file `%s'", specified_file, Qnil);
11190            UNGCPRO;            UNGCPRO;
11191            return 0;            return 0;
11192          }          }
11193      
11194        fp = fopen (XSTRING (file)->data, "r");        fp = fopen (SDATA (file), "rb");
11195        if (fp == NULL)        if (fp == NULL)
11196          {          {
11197            image_error ("Cannot open `%s'", file, Qnil);            image_error ("Cannot open `%s'", file, Qnil);
11198            UNGCPRO;            UNGCPRO;
11199            return 0;            return 0;
11200          }          }
11201      }      }
11202      
11203    /* Customize libjpeg's error handling to call my_error_exit when an    /* Customize libjpeg's error handling to call my_error_exit when an
11204       error is detected. This function will perform a longjmp. */       error is detected.  This function will perform a longjmp.  */
11205    cinfo.err = jpeg_std_error (&mgr.pub);    cinfo.err = fn_jpeg_std_error (&mgr.pub);
11206    mgr.pub.error_exit = my_error_exit;    mgr.pub.error_exit = my_error_exit;
11207      
11208    if ((rc = setjmp (mgr.setjmp_buffer)) != 0)    if ((rc = setjmp (mgr.setjmp_buffer)) != 0)
11209      {      {
11210        if (rc == 1)        if (rc == 1)
# Line 12231  jpeg_load (f, img) Line 11215  jpeg_load (f, img)
11215            image_error ("Error reading JPEG image `%s': %s", img->spec,            image_error ("Error reading JPEG image `%s': %s", img->spec,
11216                         build_string (buffer));                         build_string (buffer));
11217          }          }
11218              
11219        /* Close the input file and destroy the JPEG object.  */        /* Close the input file and destroy the JPEG object.  */
11220        if (fp)        if (fp)
11221          fclose (fp);          fclose ((FILE *) fp);
11222        jpeg_destroy_decompress (&cinfo);        fn_jpeg_destroy_decompress (&cinfo);
11223          
11224        /* If we already have an XImage, free that.  */        /* If we already have an XImage, free that.  */
11225        x_destroy_x_image (ximg);        x_destroy_x_image (ximg);
11226    
11227        /* Free pixmap and colors.  */        /* Free pixmap and colors.  */
11228        x_clear_image (f, img);        x_clear_image (f, img);
11229          
11230        UNGCPRO;        UNGCPRO;
11231        return 0;        return 0;
11232      }      }
11233    
11234    /* Create the JPEG decompression object.  Let it read from fp.    /* Create the JPEG decompression object.  Let it read from fp.
11235       Read the JPEG image header.  */           Read the JPEG image header.  */
11236    jpeg_create_decompress (&cinfo);    fn_jpeg_CreateDecompress (&cinfo, JPEG_LIB_VERSION, sizeof (cinfo));
11237    
11238    if (NILP (specified_data))    if (NILP (specified_data))
11239      jpeg_stdio_src (&cinfo, fp);      fn_jpeg_stdio_src (&cinfo, (FILE *) fp);
11240    else    else
11241      jpeg_memory_src (&cinfo, XSTRING (specified_data)->data,      jpeg_memory_src (&cinfo, SDATA (specified_data),
11242                       STRING_BYTES (XSTRING (specified_data)));                       SBYTES (specified_data));
11243    
11244    jpeg_read_header (&cinfo, TRUE);    fn_jpeg_read_header (&cinfo, TRUE);
11245    
11246    /* Customize decompression so that color quantization will be used.    /* Customize decompression so that color quantization will be used.
11247       Start decompression.  */           Start decompression.  */
11248    cinfo.quantize_colors = TRUE;    cinfo.quantize_colors = TRUE;
11249    jpeg_start_decompress (&cinfo);    fn_jpeg_start_decompress (&cinfo);
11250    width = img->width = cinfo.output_width;    width = img->width = cinfo.output_width;
11251    height = img->height = cinfo.output_height;    height = img->height = cinfo.output_height;
11252    
11253    /* Create X image and pixmap.  */    /* Create X image and pixmap.  */
11254    if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg,    if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
                                     &img->pixmap))  
11255      longjmp (mgr.setjmp_buffer, 2);      longjmp (mgr.setjmp_buffer, 2);
11256    
11257    /* Allocate colors.  When color quantization is used,    /* Allocate colors.  When color quantization is used,
# Line 12286  jpeg_load (f, img) Line 11269  jpeg_load (f, img)
11269      else      else
11270        ir = 0, ig = 0, ib = 0;        ir = 0, ig = 0, ib = 0;
11271    
11272    #if 0 /* TODO: Color tables.  */
11273      /* Use the color table mechanism because it handles colors that      /* Use the color table mechanism because it handles colors that
11274         cannot be allocated nicely.  Such colors will be replaced with         cannot be allocated nicely.  Such colors will be replaced with
11275         a default color, and we don't have to care about which colors         a default color, and we don't have to care about which colors
11276         can be freed safely, and which can't.  */         can be freed safely, and which can't.  */
11277      init_color_table ();      init_color_table ();
11278    #endif
11279      colors = (unsigned long *) alloca (cinfo.actual_number_of_colors      colors = (unsigned long *) alloca (cinfo.actual_number_of_colors
11280                                         * sizeof *colors);                                         * sizeof *colors);
11281      
11282      for (i = 0; i < cinfo.actual_number_of_colors; ++i)      for (i = 0; i < cinfo.actual_number_of_colors; ++i)
11283        {        {
11284          /* Multiply RGB values with 255 because X expects RGB values          int r = cinfo.colormap[ir][i];
11285             in the range 0..0xffff.  */          int g = cinfo.colormap[ig][i];
11286          int r = cinfo.colormap[ir][i] << 8;          int b = cinfo.colormap[ib][i];
11287          int g = cinfo.colormap[ig][i] << 8;  #if 0 /* TODO: Color tables.  */
         int b = cinfo.colormap[ib][i] << 8;  
11288          colors[i] = lookup_rgb_color (f, r, g, b);          colors[i] = lookup_rgb_color (f, r, g, b);
11289    #else
11290            colors[i] = PALETTERGB (r, g, b);
11291    #endif
11292        }        }
11293    
11294    #if 0 /* TODO: Color tables.  */
11295      /* Remember those colors actually allocated.  */      /* Remember those colors actually allocated.  */
11296      img->colors = colors_in_color_table (&img->ncolors);      img->colors = colors_in_color_table (&img->ncolors);
11297      free_color_table ();      free_color_table ();
11298    #endif
11299    }    }
11300    
11301    /* Read pixels.  */    /* Read pixels.  */
# Line 12315  jpeg_load (f, img) Line 11304  jpeg_load (f, img)
11304                                      row_stride, 1);                                      row_stride, 1);
11305    for (y = 0; y < height; ++y)    for (y = 0; y < height; ++y)
11306      {      {
11307        jpeg_read_scanlines (&cinfo, buffer, 1);        fn_jpeg_read_scanlines (&cinfo, buffer, 1);
11308        for (x = 0; x < cinfo.output_width; ++x)        for (x = 0; x < cinfo.output_width; ++x)
11309          XPutPixel (ximg, x, y, colors[buffer[0][x]]);          XPutPixel (ximg, x, y, colors[buffer[0][x]]);
11310      }      }
11311    
11312    /* Clean up.  */    /* Clean up.  */
11313    jpeg_finish_decompress (&cinfo);    fn_jpeg_finish_decompress (&cinfo);
11314    jpeg_destroy_decompress (&cinfo);    fn_jpeg_destroy_decompress (&cinfo);
11315    if (fp)    if (fp)
11316      fclose (fp);      fclose ((FILE *) fp);
11317      
11318    /* Maybe fill in the background field while we have ximg handy. */    /* Maybe fill in the background field while we have ximg handy. */
11319    if (NILP (image_spec_value (img->spec, QCbackground, NULL)))    if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
11320      IMAGE_BACKGROUND (img, f, ximg);      IMAGE_BACKGROUND (img, f, ximg);
11321      
11322    /* Put the image into the pixmap.  */    /* Put the image into the pixmap.  */
11323    x_put_x_image (f, ximg, img->pixmap, width, height);    x_put_x_image (f, ximg, img->pixmap, width, height);
11324    x_destroy_x_image (ximg);    x_destroy_x_image (ximg);
   UNBLOCK_INPUT;  
11325    UNGCPRO;    UNGCPRO;
11326    return 1;    return 1;
11327  }  }
# Line 12382  static struct image_keyword tiff_format[ Line 11370  static struct image_keyword tiff_format[
11370    {":type",             IMAGE_SYMBOL_VALUE,                     1},    {":type",             IMAGE_SYMBOL_VALUE,                     1},
11371    {":data",             IMAGE_STRING_VALUE,                     0},    {":data",             IMAGE_STRING_VALUE,                     0},
11372    {":file",             IMAGE_STRING_VALUE,                     0},    {":file",             IMAGE_STRING_VALUE,                     0},
11373    {":ascent",           IMAGE_NON_NEGATIVE_INTEGER_VALUE,       0},    {":ascent",           IMAGE_ASCENT_VALUE,                     0},
11374    {":margin",           IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},    {":margin",           IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
11375    {":relief",           IMAGE_INTEGER_VALUE,                    0},    {":relief",           IMAGE_INTEGER_VALUE,                    0},
11376    {":conversions",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},    {":conversions",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
# Line 12402  static struct image_type tiff_type = Line 11390  static struct image_type tiff_type =
11390    NULL    NULL
11391  };  };
11392    
11393    /* TIFF library details.  */
11394    DEF_IMGLIB_FN (TIFFSetErrorHandler);
11395    DEF_IMGLIB_FN (TIFFSetWarningHandler);
11396    DEF_IMGLIB_FN (TIFFOpen);
11397    DEF_IMGLIB_FN (TIFFClientOpen);
11398    DEF_IMGLIB_FN (TIFFGetField);
11399    DEF_IMGLIB_FN (TIFFReadRGBAImage);
11400    DEF_IMGLIB_FN (TIFFClose);
11401    
11402    static int
11403    init_tiff_functions (library)
11404         HMODULE library;
11405    {
11406      LOAD_IMGLIB_FN (library, TIFFSetErrorHandler);
11407      LOAD_IMGLIB_FN (library, TIFFSetWarningHandler);
11408      LOAD_IMGLIB_FN (library, TIFFOpen);
11409      LOAD_IMGLIB_FN (library, TIFFClientOpen);
11410      LOAD_IMGLIB_FN (library, TIFFGetField);
11411      LOAD_IMGLIB_FN (library, TIFFReadRGBAImage);
11412      LOAD_IMGLIB_FN (library, TIFFClose);
11413      return 1;
11414    }
11415    
11416  /* Return non-zero if OBJECT is a valid TIFF image specification.  */  /* Return non-zero if OBJECT is a valid TIFF image specification.  */
11417    
# Line 12411  tiff_image_p (object) Line 11421  tiff_image_p (object)
11421  {  {
11422    struct image_keyword fmt[TIFF_LAST];    struct image_keyword fmt[TIFF_LAST];
11423    bcopy (tiff_format, fmt, sizeof fmt);    bcopy (tiff_format, fmt, sizeof fmt);
11424      
11425    if (!parse_image_spec (object, fmt, TIFF_LAST, Qtiff)    if (!parse_image_spec (object, fmt, TIFF_LAST, Qtiff))
       || (fmt[TIFF_ASCENT].count  
           && XFASTINT (fmt[TIFF_ASCENT].value) > 100))  
11426      return 0;      return 0;
11427      
11428    /* Must specify either the :data or :file keyword.  */    /* Must specify either the :data or :file keyword.  */
11429    return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1;    return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1;
11430  }  }
# Line 12477  tiff_seek_in_memory (data, off, whence) Line 11485  tiff_seek_in_memory (data, off, whence)
11485      case SEEK_SET:              /* Go from beginning of source.  */      case SEEK_SET:              /* Go from beginning of source.  */
11486        idx = off;        idx = off;
11487        break;        break;
11488          
11489      case SEEK_END:              /* Go from end of source.  */      case SEEK_END:              /* Go from end of source.  */
11490        idx = src->len + off;        idx = src->len + off;
11491        break;        break;
11492          
11493      case SEEK_CUR:              /* Go from current position.  */      case SEEK_CUR:              /* Go from current position.  */
11494        idx = src->index + off;        idx = src->index + off;
11495        break;        break;
11496          
11497      default:                    /* Invalid `whence'.   */      default:                    /* Invalid `whence'.   */
11498        return -1;        return -1;
11499      }      }
11500      
11501    if (idx > src->len || idx < 0)    if (idx > src->len || idx < 0)
11502      return -1;      return -1;
11503      
11504    src->index = idx;    src->index = idx;
11505    return src->index;    return src->index;
11506  }  }
# Line 12539  tiff_error_handler (title, format, ap) Line 11547  tiff_error_handler (title, format, ap)
11547  {  {
11548    char buf[512];    char buf[512];
11549    int len;    int len;
11550      
11551    len = sprintf (buf, "TIFF error: %s ", title);    len = sprintf (buf, "TIFF error: %s ", title);
11552    vsprintf (buf + len, format, ap);    vsprintf (buf + len, format, ap);
11553    add_to_log (buf, Qnil, Qnil);    add_to_log (buf, Qnil, Qnil);
# Line 12553  tiff_warning_handler (title, format, ap) Line 11561  tiff_warning_handler (title, format, ap)
11561  {  {
11562    char buf[512];    char buf[512];
11563    int len;    int len;
11564      
11565    len = sprintf (buf, "TIFF warning: %s ", title);    len = sprintf (buf, "TIFF warning: %s ", title);
11566    vsprintf (buf + len, format, ap);    vsprintf (buf + len, format, ap);
11567    add_to_log (buf, Qnil, Qnil);    add_to_log (buf, Qnil, Qnil);
# Line 12583  tiff_load (f, img) Line 11591  tiff_load (f, img)
11591    file = Qnil;    file = Qnil;
11592    GCPRO1 (file);    GCPRO1 (file);
11593    
11594    TIFFSetErrorHandler (tiff_error_handler);    fn_TIFFSetErrorHandler (tiff_error_handler);
11595    TIFFSetWarningHandler (tiff_warning_handler);    fn_TIFFSetWarningHandler (tiff_warning_handler);
11596    
11597    if (NILP (specified_data))    if (NILP (specified_data))
11598      {      {
# Line 12596  tiff_load (f, img) Line 11604  tiff_load (f, img)
11604            UNGCPRO;            UNGCPRO;
11605            return 0;            return 0;
11606          }          }
11607              
11608        /* Try to open the image file.  */        /* Try to open the image file.  */
11609        tiff = TIFFOpen (XSTRING (file)->data, "r");        tiff = fn_TIFFOpen (SDATA (file), "r");
11610        if (tiff == NULL)        if (tiff == NULL)
11611          {          {
11612            image_error ("Cannot open `%s'", file, Qnil);            image_error ("Cannot open `%s'", file, Qnil);
# Line 12609  tiff_load (f, img) Line 11617  tiff_load (f, img)
11617    else    else
11618      {      {
11619        /* Memory source! */        /* Memory source! */
11620        memsrc.bytes = XSTRING (specified_data)->data;        memsrc.bytes = SDATA (specified_data);
11621        memsrc.len = STRING_BYTES (XSTRING (specified_data));        memsrc.len = SBYTES (specified_data);
11622        memsrc.index = 0;        memsrc.index = 0;
11623    
11624        tiff = TIFFClientOpen ("memory_source", "r", &memsrc,        tiff = fn_TIFFClientOpen ("memory_source", "r", &memsrc,
11625                               (TIFFReadWriteProc) tiff_read_from_memory,                                  (TIFFReadWriteProc) tiff_read_from_memory,
11626                               (TIFFReadWriteProc) tiff_write_from_memory,                                  (TIFFReadWriteProc) tiff_write_from_memory,
11627                               tiff_seek_in_memory,                                  tiff_seek_in_memory,
11628                               tiff_close_memory,                                  tiff_close_memory,
11629                               tiff_size_of_memory,                                  tiff_size_of_memory,
11630                               tiff_mmap_memory,                                  tiff_mmap_memory,
11631                               tiff_unmap_memory);                                  tiff_unmap_memory);
11632    
11633        if (!tiff)        if (!tiff)
11634          {          {
# Line 12632  tiff_load (f, img) Line 11640  tiff_load (f, img)
11640    
11641    /* Get width and height of the image, and allocate a raster buffer    /* Get width and height of the image, and allocate a raster buffer
11642       of width x height 32-bit values.  */       of width x height 32-bit values.  */
11643    TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width);    fn_TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width);
11644    TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height);    fn_TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height);
11645    buf = (uint32 *) xmalloc (width * height * sizeof *buf);    buf = (uint32 *) xmalloc (width * height * sizeof *buf);
11646      
11647    rc = TIFFReadRGBAImage (tiff, width, height, buf, 0);    rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0);
11648    TIFFClose (tiff);    fn_TIFFClose (tiff);
11649    if (!rc)    if (!rc)
11650      {      {
11651        image_error ("Error reading TIFF image `%s'", img->spec, Qnil);        image_error ("Error reading TIFF image `%s'", img->spec, Qnil);
# Line 12654  tiff_load (f, img) Line 11662  tiff_load (f, img)
11662        return 0;        return 0;
11663      }      }
11664    
11665    #if 0 /* TODO: Color tables.  */
11666    /* Initialize the color table.  */    /* Initialize the color table.  */
11667    init_color_table ();    init_color_table ();
11668    #endif
11669    
11670    /* Process the pixel raster.  Origin is in the lower-left corner.  */    /* Process the pixel raster.  Origin is in the lower-left corner.  */
11671    for (y = 0; y < height; ++y)    for (y = 0; y < height; ++y)
11672      {      {
11673        uint32 *row = buf + y * width;        uint32 *row = buf + y * width;
11674          
11675        for (x = 0; x < width; ++x)        for (x = 0; x < width; ++x)
11676          {          {
11677            uint32 abgr = row[x];            uint32 abgr = row[x];
11678            int r = TIFFGetR (abgr) << 8;            int r = TIFFGetR (abgr);
11679            int g = TIFFGetG (abgr) << 8;            int g = TIFFGetG (abgr);
11680            int b = TIFFGetB (abgr) << 8;            int b = TIFFGetB (abgr);
11681            XPutPixel (ximg, x, height - 1 - y, lookup_rgb_color (f, r, g, b));  #if 0 /* TODO: Color tables.  */
11682              XPutPixel (ximg, x, height - 1 - y, lookup_rgb_color (f, r, g, b));
11683    #else
11684              XPutPixel (ximg, x, height - 1 - y, PALETTERGB (r, g, b));
11685    #endif
11686          }          }
11687      }      }
11688    
11689    #if 0 /* TODO: Color tables.  */
11690    /* Remember the colors allocated for the image.  Free the color table.  */    /* Remember the colors allocated for the image.  Free the color table.  */
11691    img->colors = colors_in_color_table (&img->ncolors);    img->colors = colors_in_color_table (&img->ncolors);
11692    free_color_table ();    free_color_table ();
11693    #endif
11694    
11695    img->width = width;    img->width = width;
11696    img->height = height;    img->height = height;
# Line 12702  tiff_load (f, img) Line 11718  tiff_load (f, img)
11718    
11719  #if HAVE_GIF  #if HAVE_GIF
11720    
11721    #define DrawText gif_DrawText
11722  #include <gif_lib.h>  #include <gif_lib.h>
11723    #undef DrawText
11724    
11725  static int gif_image_p P_ ((Lisp_Object object));  static int gif_image_p P_ ((Lisp_Object object));
11726  static int gif_load P_ ((struct frame *f, struct image *img));  static int gif_load P_ ((struct frame *f, struct image *img));
# Line 12737  static struct image_keyword gif_format[G Line 11755  static struct image_keyword gif_format[G
11755    {":type",             IMAGE_SYMBOL_VALUE,                     1},    {":type",             IMAGE_SYMBOL_VALUE,                     1},
11756    {":data",             IMAGE_STRING_VALUE,                     0},    {":data",             IMAGE_STRING_VALUE,                     0},
11757    {":file",             IMAGE_STRING_VALUE,                     0},    {":file",             IMAGE_STRING_VALUE,                     0},
11758    {":ascent",           IMAGE_NON_NEGATIVE_INTEGER_VALUE,       0},    {":ascent",           IMAGE_ASCENT_VALUE,                     0},
11759    {":margin",           IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},    {":margin",           IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
11760    {":relief",           IMAGE_INTEGER_VALUE,                    0},    {":relief",           IMAGE_INTEGER_VALUE,                    0},
11761    {":conversion",       IMAGE_DONT_CHECK_VALUE_TYPE,            0},    {":conversion",       IMAGE_DONT_CHECK_VALUE_TYPE,            0},
# Line 12758  static struct image_type gif_type = Line 11776  static struct image_type gif_type =
11776    NULL    NULL
11777  };  };
11778    
11779    
11780    /* GIF library details.  */
11781    DEF_IMGLIB_FN (DGifCloseFile);
11782    DEF_IMGLIB_FN (DGifSlurp);
11783    DEF_IMGLIB_FN (DGifOpen);
11784    DEF_IMGLIB_FN (DGifOpenFileName);
11785    
11786    static int
11787    init_gif_functions (library)
11788         HMODULE library;
11789    {
11790      LOAD_IMGLIB_FN (library, DGifCloseFile);
11791      LOAD_IMGLIB_FN (library, DGifSlurp);
11792      LOAD_IMGLIB_FN (library, DGifOpen);
11793      LOAD_IMGLIB_FN (library, DGifOpenFileName);
11794      return 1;
11795    }
11796    
11797    
11798  /* Return non-zero if OBJECT is a valid GIF image specification.  */  /* Return non-zero if OBJECT is a valid GIF image specification.  */
11799    
11800  static int  static int
# Line 12766  gif_image_p (object) Line 11803  gif_image_p (object)
11803  {  {
11804    struct image_keyword fmt[GIF_LAST];    struct image_keyword fmt[GIF_LAST];
11805    bcopy (gif_format, fmt, sizeof fmt);    bcopy (gif_format, fmt, sizeof fmt);
11806      
11807    if (!parse_image_spec (object, fmt, GIF_LAST, Qgif)    if (!parse_image_spec (object, fmt, GIF_LAST, Qgif))
       || (fmt[GIF_ASCENT].count  
           && XFASTINT (fmt[GIF_ASCENT].value) > 100))  
11808      return 0;      return 0;
11809      
11810    /* Must specify either the :data or :file keyword.  */    /* Must specify either the :data or :file keyword.  */
11811    return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1;    return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1;
11812  }  }
# Line 12844  gif_load (f, img) Line 11879  gif_load (f, img)
11879            UNGCPRO;            UNGCPRO;
11880            return 0;            return 0;
11881          }          }
11882      
11883        /* Open the GIF file.  */        /* Open the GIF file.  */
11884        gif = DGifOpenFileName (XSTRING (file)->data);        gif = fn_DGifOpenFileName (SDATA (file));
11885        if (gif == NULL)        if (gif == NULL)
11886          {          {
11887            image_error ("Cannot open `%s'", file, Qnil);            image_error ("Cannot open `%s'", file, Qnil);
# Line 12858  gif_load (f, img) Line 11893  gif_load (f, img)
11893      {      {
11894        /* Read from memory! */        /* Read from memory! */
11895        current_gif_memory_src = &memsrc;        current_gif_memory_src = &memsrc;
11896        memsrc.bytes = XSTRING (specified_data)->data;        memsrc.bytes = SDATA (specified_data);
11897        memsrc.len = STRING_BYTES (XSTRING (specified_data));        memsrc.len = SBYTES (specified_data);
11898        memsrc.index = 0;        memsrc.index = 0;
11899    
11900        gif = DGifOpen(&memsrc, gif_read_from_memory);        gif = fn_DGifOpen(&memsrc, gif_read_from_memory);
11901        if (!gif)        if (!gif)
11902          {          {
11903            image_error ("Cannot open memory source `%s'", img->spec, Qnil);            image_error ("Cannot open memory source `%s'", img->spec, Qnil);
# Line 12872  gif_load (f, img) Line 11907  gif_load (f, img)
11907      }      }
11908    
11909    /* Read entire contents.  */    /* Read entire contents.  */
11910    rc = DGifSlurp (gif);    rc = fn_DGifSlurp (gif);
11911    if (rc == GIF_ERROR)    if (rc == GIF_ERROR)
11912      {      {
11913        image_error ("Error reading `%s'", img->spec, Qnil);        image_error ("Error reading `%s'", img->spec, Qnil);
11914        DGifCloseFile (gif);        fn_DGifCloseFile (gif);
11915        UNGCPRO;        UNGCPRO;
11916        return 0;        return 0;
11917      }      }
# Line 12887  gif_load (f, img) Line 11922  gif_load (f, img)
11922      {      {
11923        image_error ("Invalid image number `%s' in image `%s'",        image_error ("Invalid image number `%s' in image `%s'",
11924                     image, img->spec);                     image, img->spec);
11925        DGifCloseFile (gif);        fn_DGifCloseFile (gif);
11926        UNGCPRO;        UNGCPRO;
11927        return 0;        return 0;
11928      }      }
11929    
11930    width = img->width = gif->SWidth;    width = img->width = max (gif->SWidth, gif->Image.Left + gif->Image.Width);
11931    height = img->height = gif->SHeight;    height = img->height = max (gif->SHeight, gif->Image.Top + gif->Image.Height);
11932    
11933    /* Create the X image and pixmap.  */    /* Create the X image and pixmap.  */
11934    if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))    if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
11935      {      {
11936        DGifCloseFile (gif);        fn_DGifCloseFile (gif);
11937        UNGCPRO;        UNGCPRO;
11938        return 0;        return 0;
11939      }      }
11940      
11941    /* Allocate colors.  */    /* Allocate colors.  */
11942    gif_color_map = gif->SavedImages[ino].ImageDesc.ColorMap;    gif_color_map = gif->SavedImages[ino].ImageDesc.ColorMap;
11943    if (!gif_color_map)    if (!gif_color_map)
11944      gif_color_map = gif->SColorMap;      gif_color_map = gif->SColorMap;
11945    #if 0 /* TODO: Color tables */
11946    init_color_table ();    init_color_table ();
11947    #endif
11948    bzero (pixel_colors, sizeof pixel_colors);    bzero (pixel_colors, sizeof pixel_colors);
11949      
11950    for (i = 0; i < gif_color_map->ColorCount; ++i)    for (i = 0; i < gif_color_map->ColorCount; ++i)
11951      {      {
11952        int r = gif_color_map->Colors[i].Red << 8;        int r = gif_color_map->Colors[i].Red;
11953        int g = gif_color_map->Colors[i].Green << 8;        int g = gif_color_map->Colors[i].Green;
11954        int b = gif_color_map->Colors[i].Blue << 8;        int b = gif_color_map->Colors[i].Blue;
11955    #if 0 /* TODO: Color tables */
11956        pixel_colors[i] = lookup_rgb_color (f, r, g, b);        pixel_colors[i] = lookup_rgb_color (f, r, g, b);
11957    #else
11958          pixel_colors[i] = PALETTERGB (r, g, b);
11959    #endif
11960      }      }
11961    
11962    #if 0 /* TODO: Color tables */
11963    img->colors = colors_in_color_table (&img->ncolors);    img->colors = colors_in_color_table (&img->ncolors);
11964    free_color_table ();    free_color_table ();
11965    #endif
11966    
11967    /* Clear the part of the screen image that are not covered by    /* Clear the part of the screen image that are not covered by
11968       the image from the GIF file.  Full animated GIF support       the image from the GIF file.  Full animated GIF support
11969       requires more than can be done here (see the gif89 spec,       requires more than can be done here (see the gif89 spec,
11970       disposal methods).  Let's simply assume that the part       disposal methods).  Let's simply assume that the part
11971       not covered by a sub-image is in the frame's background color.  */       not covered by a sub-image is in the frame's background color.  */
# Line 12969  gif_load (f, img) Line 12012  gif_load (f, img)
12012                while (row >= image_height)                while (row >= image_height)
12013                  row = interlace_start[++pass];                  row = interlace_start[++pass];
12014              }              }
12015              
12016            for (x = 0; x < image_width; x++)            for (x = 0; x < image_width; x++)
12017              {              {
12018                int i = raster[(y * image_width) + x];                int i = raster[(y * image_width) + x];
12019                XPutPixel (ximg, x + image_left, row + image_top,                XPutPixel (ximg, x + image_left, row + image_top,
12020                           pixel_colors[i]);                           pixel_colors[i]);
12021              }              }
12022              
12023            row += interlace_increment[pass];            row += interlace_increment[pass];
12024          }          }
12025      }      }
# Line 12989  gif_load (f, img) Line 12032  gif_load (f, img)
12032              XPutPixel (ximg, x + image_left, y + image_top, pixel_colors[i]);              XPutPixel (ximg, x + image_left, y + image_top, pixel_colors[i]);
12033            }            }
12034      }      }
12035      
12036    DGifCloseFile (gif);    fn_DGifCloseFile (gif);
12037    
12038    /* Maybe fill in the background field while we have ximg handy. */    /* Maybe fill in the background field while we have ximg handy. */
12039    if (NILP (image_spec_value (img->spec, QCbackground, NULL)))    if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
# Line 12999  gif_load (f, img) Line 12042  gif_load (f, img)
12042    /* Put the image into the pixmap, then free the X image and its buffer.  */    /* Put the image into the pixmap, then free the X image and its buffer.  */
12043    x_put_x_image (f, ximg, img->pixmap, width, height);    x_put_x_image (f, ximg, img->pixmap, width, height);
12044    x_destroy_x_image (ximg);    x_destroy_x_image (ximg);
12045          
12046    UNGCPRO;    UNGCPRO;
12047    return 1;    return 1;
12048  }  }
# Line 13014  gif_load (f, img) Line 12057  gif_load (f, img)
12057    
12058  Lisp_Object Qpostscript;  Lisp_Object Qpostscript;
12059    
12060    /* Keyword symbols.  */
12061    
12062    Lisp_Object QCloader, QCbounding_box, QCpt_width, QCpt_height;
12063    
12064  #ifdef HAVE_GHOSTSCRIPT  #ifdef HAVE_GHOSTSCRIPT
12065  static int gs_image_p P_ ((Lisp_Object object));  static int gs_image_p P_ ((Lisp_Object object));
12066  static int gs_load P_ ((struct frame *f, struct image *img));  static int gs_load P_ ((struct frame *f, struct image *img));
# Line 13056  static struct image_keyword gs_format[GS Line 12103  static struct image_keyword gs_format[GS
12103    {":file",             IMAGE_STRING_VALUE,                     1},    {":file",             IMAGE_STRING_VALUE,                     1},
12104    {":loader",           IMAGE_FUNCTION_VALUE,                   0},    {":loader",           IMAGE_FUNCTION_VALUE,                   0},
12105    {":bounding-box",     IMAGE_DONT_CHECK_VALUE_TYPE,            1},    {":bounding-box",     IMAGE_DONT_CHECK_VALUE_TYPE,            1},
12106    {":ascent",           IMAGE_NON_NEGATIVE_INTEGER_VALUE,       0},    {":ascent",           IMAGE_ASCENT_VALUE,                     0},
12107    {":margin",           IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},    {":margin",           IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
12108    {":relief",           IMAGE_INTEGER_VALUE,                    0},    {":relief",           IMAGE_INTEGER_VALUE,                    0},
12109    {":conversion",       IMAGE_DONT_CHECK_VALUE_TYPE,            0},    {":conversion",       IMAGE_DONT_CHECK_VALUE_TYPE,            0},
# Line 13100  gs_image_p (object) Line 12147  gs_image_p (object)
12147    struct image_keyword fmt[GS_LAST];    struct image_keyword fmt[GS_LAST];
12148    Lisp_Object tem;    Lisp_Object tem;
12149    int i;    int i;
12150      
12151    bcopy (gs_format, fmt, sizeof fmt);    bcopy (gs_format, fmt, sizeof fmt);
12152      
12153    if (!parse_image_spec (object, fmt, GS_LAST, Qpostscript)    if (!parse_image_spec (object, fmt, GS_LAST, Qpostscript))
       || (fmt[GS_ASCENT].count  
           && XFASTINT (fmt[GS_ASCENT].value) > 100))  
12154      return 0;      return 0;
12155    
12156    /* Bounding box must be a list or vector containing 4 integers.  */    /* Bounding box must be a list or vector containing 4 integers.  */
# Line 13172  gs_load (f, img) Line 12217  gs_load (f, img)
12217        image_error ("Unable to create pixmap for `%s'", img->spec, Qnil);        image_error ("Unable to create pixmap for `%s'", img->spec, Qnil);
12218        return 0;        return 0;
12219      }      }
12220        
12221    /* Call the loader to fill the pixmap.  It returns a process object    /* Call the loader to fill the pixmap.  It returns a process object
12222       if successful.  We do not record_unwind_protect here because       if successful.  We do not record_unwind_protect here because
12223       other places in redisplay like calling window scroll functions       other places in redisplay like calling window scroll functions
# Line 13183  gs_load (f, img) Line 12228  gs_load (f, img)
12228             (unsigned long) FRAME_W32_WINDOW (f),             (unsigned long) FRAME_W32_WINDOW (f),
12229             (unsigned long) img->pixmap);             (unsigned long) img->pixmap);
12230    window_and_pixmap_id = build_string (buffer);    window_and_pixmap_id = build_string (buffer);
12231      
12232    sprintf (buffer, "%lu %lu",    sprintf (buffer, "%lu %lu",
12233             FRAME_FOREGROUND_PIXEL (f),             FRAME_FOREGROUND_PIXEL (f),
12234             FRAME_BACKGROUND_PIXEL (f));             FRAME_BACKGROUND_PIXEL (f));
12235    pixel_colors = build_string (buffer);    pixel_colors = build_string (buffer);
12236      
12237    XSETFRAME (frame, f);    XSETFRAME (frame, f);
12238    loader = image_spec_value (img->spec, QCloader, NULL);    loader = image_spec_value (img->spec, QCloader, NULL);
12239    if (NILP (loader))    if (NILP (loader))
# Line 13250  x_kill_gs_process (pixmap, f) Line 12295  x_kill_gs_process (pixmap, f)
12295        if (ximg)        if (ximg)
12296          {          {
12297            int x, y;            int x, y;
12298              
12299            /* Initialize the color table.  */            /* Initialize the color table.  */
12300            init_color_table ();            init_color_table ();
12301          
12302            /* For each pixel of the image, look its color up in the            /* For each pixel of the image, look its color up in the
12303               color table.  After having done so, the color table will               color table.  After having done so, the color table will
12304               contain an entry for each color used by the image.  */               contain an entry for each color used by the image.  */
# Line 13283  x_kill_gs_process (pixmap, f) Line 12328  x_kill_gs_process (pixmap, f)
12328        else        else
12329          image_error ("Cannot get X image of `%s'; colors will not be freed",          image_error ("Cannot get X image of `%s'; colors will not be freed",
12330                       img->spec, Qnil);                       img->spec, Qnil);
12331          
12332        UNBLOCK_INPUT;        UNBLOCK_INPUT;
12333      }      }
12334    
# Line 13317  selected frame.  Value is VALUE.  */) Line 12362  selected frame.  Value is VALUE.  */)
12362    CHECK_STRING (value);    CHECK_STRING (value);
12363    
12364    BLOCK_INPUT;    BLOCK_INPUT;
12365    prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), XSTRING (prop)->data, False);    prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
12366    XChangeProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),    XChangeProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
12367                     prop_atom, XA_STRING, 8, PropModeReplace,                     prop_atom, XA_STRING, 8, PropModeReplace,
12368                     XSTRING (value)->data, XSTRING (value)->size);                     SDATA (value), SCHARS (value));
12369    
12370    /* Make sure the property is set when we return.  */    /* Make sure the property is set when we return.  */
12371    XFlush (FRAME_W32_DISPLAY (f));    XFlush (FRAME_W32_DISPLAY (f));
# Line 13346  FRAME nil or omitted means use the selec Line 12391  FRAME nil or omitted means use the selec
12391    
12392    CHECK_STRING (prop);    CHECK_STRING (prop);
12393    BLOCK_INPUT;    BLOCK_INPUT;
12394    prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), XSTRING (prop)->data, False);    prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
12395    XDeleteProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), prop_atom);    XDeleteProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), prop_atom);
12396    
12397    /* Make sure the property is removed when we return.  */    /* Make sure the property is removed when we return.  */
# Line 13380  value.  */) Line 12425  value.  */)
12425    
12426    CHECK_STRING (prop);    CHECK_STRING (prop);
12427    BLOCK_INPUT;    BLOCK_INPUT;
12428    prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), XSTRING (prop)->data, False);    prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
12429    rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),    rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
12430                             prop_atom, 0, 0, False, XA_STRING,                             prop_atom, 0, 0, False, XA_STRING,
12431                             &actual_type, &actual_format, &actual_size,                             &actual_type, &actual_format, &actual_size,
# Line 13395  value.  */) Line 12440  value.  */)
12440        rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),        rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
12441                                 prop_atom, 0, bytes_remaining,                                 prop_atom, 0, bytes_remaining,
12442                                 False, XA_STRING,                                 False, XA_STRING,
12443                                 &actual_type, &actual_format,                                 &actual_type, &actual_format,
12444                                 &actual_size, &bytes_remaining,                                 &actual_size, &bytes_remaining,
12445                                 (unsigned char **) &tmp_data);                                 (unsigned char **) &tmp_data);
12446        if (rc == Success)        if (rc == Success)
12447          prop_value = make_string (tmp_data, size);          prop_value = make_string (tmp_data, size);
# Line 13450  start_hourglass () Line 12495  start_hourglass ()
12495  #if 0 /* TODO: cursor shape changes.  */  #if 0 /* TODO: cursor shape changes.  */
12496    EMACS_TIME delay;    EMACS_TIME delay;
12497    int secs, usecs = 0;    int secs, usecs = 0;
12498      
12499    cancel_hourglass ();    cancel_hourglass ();
12500    
12501    if (INTEGERP (Vhourglass_delay)    if (INTEGERP (Vhourglass_delay)
# Line 13466  start_hourglass () Line 12511  start_hourglass ()
12511      }      }
12512    else    else
12513      secs = DEFAULT_HOURGLASS_DELAY;      secs = DEFAULT_HOURGLASS_DELAY;
12514      
12515    EMACS_SET_SECS_USECS (delay, secs, usecs);    EMACS_SET_SECS_USECS (delay, secs, usecs);
12516    hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,    hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
12517                                     show_hourglass, NULL);                                     show_hourglass, NULL);
# Line 13485  cancel_hourglass () Line 12530  cancel_hourglass ()
12530        cancel_atimer (hourglass_atimer);        cancel_atimer (hourglass_atimer);
12531        hourglass_atimer = NULL;        hourglass_atimer = NULL;
12532      }      }
12533      
12534    if (hourglass_shown_p)    if (hourglass_shown_p)
12535      hide_hourglass ();      hide_hourglass ();
12536  }  }
# Line 13512  show_hourglass (timer) Line 12557  show_hourglass (timer)
12557    if (!hourglass_shown_p)    if (!hourglass_shown_p)
12558      {      {
12559        Lisp_Object rest, frame;        Lisp_Object rest, frame;
12560      
12561        BLOCK_INPUT;        BLOCK_INPUT;
12562      
12563        FOR_EACH_FRAME (rest, frame)        FOR_EACH_FRAME (rest, frame)
12564          if (FRAME_W32_P (XFRAME (frame)))          if (FRAME_W32_P (XFRAME (frame)))
12565            {            {
12566              struct frame *f = XFRAME (frame);              struct frame *f = XFRAME (frame);
12567            
12568              f->output_data.w32->hourglass_p = 1;              f->output_data.w32->hourglass_p = 1;
12569            
12570              if (!f->output_data.w32->hourglass_window)              if (!f->output_data.w32->hourglass_window)
12571                {                {
12572                  unsigned long mask = CWCursor;                  unsigned long mask = CWCursor;
12573                  XSetWindowAttributes attrs;                  XSetWindowAttributes attrs;
12574                
12575                  attrs.cursor = f->output_data.w32->hourglass_cursor;                  attrs.cursor = f->output_data.w32->hourglass_cursor;
12576                
12577                  f->output_data.w32->hourglass_window                  f->output_data.w32->hourglass_window
12578                    = XCreateWindow (FRAME_X_DISPLAY (f),                    = XCreateWindow (FRAME_X_DISPLAY (f),
12579                                     FRAME_OUTER_WINDOW (f),                                     FRAME_OUTER_WINDOW (f),
# Line 13537  show_hourglass (timer) Line 12582  show_hourglass (timer)
12582                                     CopyFromParent,                                     CopyFromParent,
12583                                     mask, &attrs);                                     mask, &attrs);
12584                }                }
12585            
12586              XMapRaised (FRAME_X_DISPLAY (f),              XMapRaised (FRAME_X_DISPLAY (f),
12587                          f->output_data.w32->hourglass_window);                          f->output_data.w32->hourglass_window);
12588              XFlush (FRAME_X_DISPLAY (f));              XFlush (FRAME_X_DISPLAY (f));
# Line 13564  hide_hourglass () Line 12609  hide_hourglass ()
12609        FOR_EACH_FRAME (rest, frame)        FOR_EACH_FRAME (rest, frame)
12610          {          {
12611            struct frame *f = XFRAME (frame);            struct frame *f = XFRAME (frame);
12612          
12613            if (FRAME_W32_P (f)            if (FRAME_W32_P (f)
12614                /* Watch out for newly created frames.  */                /* Watch out for newly created frames.  */
12615                && f->output_data.x->hourglass_window)                && f->output_data.x->hourglass_window)
# Line 13594  static Lisp_Object x_create_tip_frame P_ Line 12639  static Lisp_Object x_create_tip_frame P_
12639                                             Lisp_Object, Lisp_Object));                                             Lisp_Object, Lisp_Object));
12640  static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,  static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
12641                                  Lisp_Object, int, int, int *, int *));                                  Lisp_Object, int, int, int *, int *));
12642        
12643  /* The frame of a currently visible tooltip.  */  /* The frame of a currently visible tooltip.  */
12644    
12645  Lisp_Object tip_frame;  Lisp_Object tip_frame;
# Line 13627  unwind_create_tip_frame (frame) Line 12672  unwind_create_tip_frame (frame)
12672        tip_window = NULL;        tip_window = NULL;
12673        tip_frame = Qnil;        tip_frame = Qnil;
12674      }      }
12675      
12676    return deleted;    return deleted;
12677  }  }
12678    
# Line 13651  x_create_tip_frame (dpyinfo, parms, text Line 12696  x_create_tip_frame (dpyinfo, parms, text
12696    Lisp_Object name;    Lisp_Object name;
12697    long window_prompting = 0;    long window_prompting = 0;
12698    int width, height;    int width, height;
12699    int count = BINDING_STACK_SIZE ();    int count = SPECPDL_INDEX ();
12700    struct gcpro gcpro1, gcpro2, gcpro3;    struct gcpro gcpro1, gcpro2, gcpro3;
12701    struct kboard *kb;    struct kboard *kb;
12702    int face_change_count_before = face_change_count;    int face_change_count_before = face_change_count;
# Line 13693  x_create_tip_frame (dpyinfo, parms, text Line 12738  x_create_tip_frame (dpyinfo, parms, text
12738    Ferase_buffer ();    Ferase_buffer ();
12739    Finsert (1, &text);    Finsert (1, &text);
12740    set_buffer_internal_1 (old_buffer);    set_buffer_internal_1 (old_buffer);
12741      
12742    FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;    FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
12743    record_unwind_protect (unwind_create_tip_frame, frame);    record_unwind_protect (unwind_create_tip_frame, frame);
12744    
# Line 13747  x_create_tip_frame (dpyinfo, parms, text Line 12792  x_create_tip_frame (dpyinfo, parms, text
12792        {        {
12793          tem = Fquery_fontset (font, Qnil);          tem = Fquery_fontset (font, Qnil);
12794          if (STRINGP (tem))          if (STRINGP (tem))
12795            font = x_new_fontset (f, XSTRING (tem)->data);            font = x_new_fontset (f, SDATA (tem));
12796          else          else
12797            font = x_new_font (f, XSTRING (font)->data);            font = x_new_font (f, SDATA (font));
12798        }        }
12799        
12800      /* Try out a font which we hope has bold and italic variations.  */      /* Try out a font which we hope has bold and italic variations.  */
12801      if (!STRINGP (font))      if (!STRINGP (font))
12802        font = x_new_font (f, "-*-Courier New-normal-r-*-*-*-100-*-*-c-*-iso8859-1");        font = x_new_font (f, "-*-Courier New-normal-r-*-*-*-100-*-*-c-*-iso8859-1");
# Line 13810  x_create_tip_frame (dpyinfo, parms, text Line 12855  x_create_tip_frame (dpyinfo, parms, text
12855    f->output_data.w32->dwStyle = WS_BORDER | WS_POPUP | WS_DISABLED;    f->output_data.w32->dwStyle = WS_BORDER | WS_POPUP | WS_DISABLED;
12856    f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;    f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;
12857    
12858    window_prompting = x_figure_window_size (f, parms);    window_prompting = x_figure_window_size (f, parms, 0);
12859    
12860    /* No fringes on tip frame.  */    /* No fringes on tip frame.  */
12861    f->output_data.w32->fringes_extra = 0;    f->output_data.w32->fringes_extra = 0;
# Line 13818  x_create_tip_frame (dpyinfo, parms, text Line 12863  x_create_tip_frame (dpyinfo, parms, text
12863    f->output_data.w32->left_fringe_width = 0;    f->output_data.w32->left_fringe_width = 0;
12864    f->output_data.w32->right_fringe_width = 0;    f->output_data.w32->right_fringe_width = 0;
12865    
   if (window_prompting & XNegative)  
     {  
       if (window_prompting & YNegative)  
         f->output_data.w32->win_gravity = SouthEastGravity;  
       else  
         f->output_data.w32->win_gravity = NorthEastGravity;  
     }  
   else  
     {  
       if (window_prompting & YNegative)  
         f->output_data.w32->win_gravity = SouthWestGravity;  
       else  
         f->output_data.w32->win_gravity = NorthWestGravity;  
     }  
   
   f->output_data.w32->size_hint_flags = window_prompting;  
   
12866    BLOCK_INPUT;    BLOCK_INPUT;
12867    my_create_tip_window (f);    my_create_tip_window (f);
12868    UNBLOCK_INPUT;    UNBLOCK_INPUT;
# Line 13857  x_create_tip_frame (dpyinfo, parms, text Line 12885  x_create_tip_frame (dpyinfo, parms, text
12885    SET_FRAME_WIDTH (f, 0);    SET_FRAME_WIDTH (f, 0);
12886    change_frame_size (f, height, width, 1, 0, 0);    change_frame_size (f, height, width, 1, 0, 0);
12887    
12888      /* Add `tooltip' frame parameter's default value. */
12889      if (NILP (Fframe_parameter (frame, intern ("tooltip"))))
12890        Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt),
12891                                                Qnil));
12892    
12893    /* Set up faces after all frame parameters are known.  This call    /* Set up faces after all frame parameters are known.  This call
12894       also merges in face attributes specified for new frames.       also merges in face attributes specified for new frames.
12895    
# Line 13871  x_create_tip_frame (dpyinfo, parms, text Line 12904  x_create_tip_frame (dpyinfo, parms, text
12904      /* Set tip_frame here, so that */      /* Set tip_frame here, so that */
12905      tip_frame = frame;      tip_frame = frame;
12906      call1 (Qface_set_after_frame_default, frame);      call1 (Qface_set_after_frame_default, frame);
12907        
12908      if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))      if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
12909        Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),        Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
12910                                                Qnil));                                                Qnil));
12911    }    }
12912      
12913    f->no_split = 1;    f->no_split = 1;
12914    
12915    UNGCPRO;    UNGCPRO;
# Line 13916  compute_tip_xy (f, parms, dx, dy, width, Line 12949  compute_tip_xy (f, parms, dx, dy, width,
12949       int *root_x, *root_y;       int *root_x, *root_y;
12950  {  {
12951    Lisp_Object left, top;    Lisp_Object left, top;
12952      
12953    /* User-specified position?  */    /* User-specified position?  */
12954    left = Fcdr (Fassq (Qleft, parms));    left = Fcdr (Fassq (Qleft, parms));
12955    top  = Fcdr (Fassq (Qtop, parms));    top  = Fcdr (Fassq (Qtop, parms));
12956      
12957    /* Move the tooltip window where the mouse pointer is.  Resize and    /* Move the tooltip window where the mouse pointer is.  Resize and
12958       show it.  */       show it.  */
12959    if (!INTEGERP (left) || !INTEGERP (top))    if (!INTEGERP (left) || !INTEGERP (top))
# Line 13991  Text larger than the specified size is c Line 13024  Text larger than the specified size is c
13024    int i, width, height;    int i, width, height;
13025    struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;    struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
13026    int old_windows_or_buffers_changed = windows_or_buffers_changed;    int old_windows_or_buffers_changed = windows_or_buffers_changed;
13027    int count = BINDING_STACK_SIZE ();    int count = SPECPDL_INDEX ();
13028      
13029    specbind (Qinhibit_redisplay, Qt);    specbind (Qinhibit_redisplay, Qt);
13030    
13031    GCPRO4 (string, parms, frame, timeout);    GCPRO4 (string, parms, frame, timeout);
# Line 14008  Text larger than the specified size is c Line 13041  Text larger than the specified size is c
13041      dx = make_number (5);      dx = make_number (5);
13042    else    else
13043      CHECK_NUMBER (dx);      CHECK_NUMBER (dx);
13044      
13045    if (NILP (dy))    if (NILP (dy))
13046      dy = make_number (-10);      dy = make_number (-10);
13047    else    else
# Line 14028  Text larger than the specified size is c Line 13061  Text larger than the specified size is c
13061            && !NILP (Fequal (last_parms, parms)))            && !NILP (Fequal (last_parms, parms)))
13062          {          {
13063            struct frame *f = XFRAME (tip_frame);            struct frame *f = XFRAME (tip_frame);
13064              
13065            /* Only DX and DY have changed.  */            /* Only DX and DY have changed.  */
13066            if (!NILP (tip_timer))            if (!NILP (tip_timer))
13067              {              {
# Line 14103  Text larger than the specified size is c Line 13136  Text larger than the specified size is c
13136        w->width = make_number (80);        w->width = make_number (80);
13137        w->height = make_number (40);        w->height = make_number (40);
13138      }      }
13139      
13140    f->window_width = XINT (w->width);    f->window_width = XINT (w->width);
13141    adjust_glyphs (f);    adjust_glyphs (f);
13142    w->pseudo_window_p = 1;    w->pseudo_window_p = 1;
# Line 14144  Text larger than the specified size is c Line 13177  Text larger than the specified size is c
13177        else        else
13178  #endif  #endif
13179          row_width = row->pixel_width;          row_width = row->pixel_width;
13180          
13181        /* TODO: find why tips do not draw along baseline as instructed.  */        /* TODO: find why tips do not draw along baseline as instructed.  */
13182        height += row->height;        height += row->height;
13183        width = max (width, row_width);        width = max (width, row_width);
# Line 14216  Value is t if tooltip was open, nil othe Line 13249  Value is t if tooltip was open, nil othe
13249    /* Return quickly if nothing to do.  */    /* Return quickly if nothing to do.  */
13250    if (NILP (tip_timer) && NILP (tip_frame))    if (NILP (tip_timer) && NILP (tip_frame))
13251      return Qnil;      return Qnil;
13252      
13253    frame = tip_frame;    frame = tip_frame;
13254    timer = tip_timer;    timer = tip_timer;
13255    GCPRO2 (frame, timer);    GCPRO2 (frame, timer);
13256    tip_frame = tip_timer = deleted = Qnil;    tip_frame = tip_timer = deleted = Qnil;
13257      
13258    count = BINDING_STACK_SIZE ();    count = SPECPDL_INDEX ();
13259    specbind (Qinhibit_redisplay, Qt);    specbind (Qinhibit_redisplay, Qt);
13260    specbind (Qinhibit_quit, Qt);    specbind (Qinhibit_quit, Qt);
13261      
13262    if (!NILP (timer))    if (!NILP (timer))
13263      call1 (Qcancel_timer, timer);      call1 (Qcancel_timer, timer);
13264    
# Line 14244  Value is t if tooltip was open, nil othe Line 13277  Value is t if tooltip was open, nil othe
13277  /***********************************************************************  /***********************************************************************
13278                          File selection dialog                          File selection dialog
13279   ***********************************************************************/   ***********************************************************************/
   
13280  extern Lisp_Object Qfile_name_history;  extern Lisp_Object Qfile_name_history;
13281    
13282    /* Callback for altering the behaviour of the Open File dialog.
13283       Makes the Filename text field contain "Current Directory" and be
13284       read-only when "Directories" is selected in the filter.  This
13285       allows us to work around the fact that the standard Open File
13286       dialog does not support directories.  */
13287    UINT CALLBACK
13288    file_dialog_callback (hwnd, msg, wParam, lParam)
13289         HWND hwnd;
13290         UINT msg;
13291         WPARAM wParam;
13292         LPARAM lParam;
13293    {
13294      if (msg == WM_NOTIFY)
13295        {
13296          OFNOTIFY * notify = (OFNOTIFY *)lParam;
13297          /* Detect when the Filter dropdown is changed.  */
13298          if (notify->hdr.code == CDN_TYPECHANGE)
13299            {
13300              HWND dialog = GetParent (hwnd);
13301              HWND edit_control = GetDlgItem (dialog, FILE_NAME_TEXT_FIELD);
13302    
13303              /* Directories is in index 2.  */
13304              if (notify->lpOFN->nFilterIndex == 2)
13305                {
13306                  CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD,
13307                                                   "Current Directory");
13308                  EnableWindow (edit_control, FALSE);
13309                }
13310              else
13311                {
13312                  CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD,
13313                                                   "");
13314                  EnableWindow (edit_control, TRUE);
13315                }
13316            }
13317        }
13318      return 0;
13319    }
13320    
13321  DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0,  DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0,
13322         doc: /* Read file name, prompting with PROMPT in directory DIR.         doc: /* Read file name, prompting with PROMPT in directory DIR.
13323  Use a file selection dialog.  Use a file selection dialog.
# Line 14257  specified.  Ensure that file exists if M Line 13328  specified.  Ensure that file exists if M
13328  {  {
13329    struct frame *f = SELECTED_FRAME ();    struct frame *f = SELECTED_FRAME ();
13330    Lisp_Object file = Qnil;    Lisp_Object file = Qnil;
13331    int count = specpdl_ptr - specpdl;    int count = SPECPDL_INDEX ();
13332    struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;    struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
13333    char filename[MAX_PATH + 1];    char filename[MAX_PATH + 1];
13334    char init_dir[MAX_PATH + 1];    char init_dir[MAX_PATH + 1];
   int use_dialog_p = 1;  
13335    
13336    GCPRO5 (prompt, dir, default_filename, mustmatch, file);    GCPRO5 (prompt, dir, default_filename, mustmatch, file);
13337    CHECK_STRING (prompt);    CHECK_STRING (prompt);
# Line 14270  specified.  Ensure that file exists if M Line 13340  specified.  Ensure that file exists if M
13340    /* Create the dialog with PROMPT as title, using DIR as initial    /* Create the dialog with PROMPT as title, using DIR as initial
13341       directory and using "*" as pattern.  */       directory and using "*" as pattern.  */
13342    dir = Fexpand_file_name (dir, Qnil);    dir = Fexpand_file_name (dir, Qnil);
13343    strncpy (init_dir, XSTRING (dir)->data, MAX_PATH);    strncpy (init_dir, SDATA (dir), MAX_PATH);
13344    init_dir[MAX_PATH] = '\0';    init_dir[MAX_PATH] = '\0';
13345    unixtodos_filename (init_dir);    unixtodos_filename (init_dir);
13346    
13347    if (STRINGP (default_filename))    if (STRINGP (default_filename))
13348      {      {
13349        char *file_name_only;        char *file_name_only;
13350        char *full_path_name = XSTRING (default_filename)->data;        char *full_path_name = SDATA (default_filename);
13351    
13352        unixtodos_filename (full_path_name);        unixtodos_filename (full_path_name);
13353    
# Line 14287  specified.  Ensure that file exists if M Line 13357  specified.  Ensure that file exists if M
13357        else        else
13358          {          {
13359            file_name_only++;            file_name_only++;
   
           /* If default_file_name is a directory, don't use the open  
              file dialog, as it does not support selecting  
              directories. */  
           if (!(*file_name_only))  
             use_dialog_p = 0;  
13360          }          }
13361    
13362        strncpy (filename, file_name_only, MAX_PATH);        strncpy (filename, file_name_only, MAX_PATH);
# Line 14301  specified.  Ensure that file exists if M Line 13365  specified.  Ensure that file exists if M
13365    else    else
13366      filename[0] = '\0';      filename[0] = '\0';
13367    
13368    if (use_dialog_p)    {
13369      {      OPENFILENAME file_details;
       OPENFILENAME file_details;  
13370    
13371        /* Prevent redisplay.  */      /* Prevent redisplay.  */
13372        specbind (Qinhibit_redisplay, Qt);      specbind (Qinhibit_redisplay, Qt);
13373        BLOCK_INPUT;      BLOCK_INPUT;
13374    
13375        bzero (&file_details, sizeof (file_details));      bzero (&file_details, sizeof (file_details));
13376        file_details.lStructSize = sizeof (file_details);      file_details.lStructSize = sizeof (file_details);
13377        file_details.hwndOwner = FRAME_W32_WINDOW (f);      file_details.hwndOwner = FRAME_W32_WINDOW (f);
13378        /* Undocumented Bug in Common File Dialog:      /* Undocumented Bug in Common File Dialog:
13379           If a filter is not specified, shell links are not resolved.  */         If a filter is not specified, shell links are not resolved.  */
13380        file_details.lpstrFilter = "ALL Files (*.*)\0*.*\0\0";      file_details.lpstrFilter = "All Files (*.*)\0*.*\0Directories\0*|*\0\0";
13381        file_details.lpstrFile = filename;      file_details.lpstrFile = filename;
13382        file_details.nMaxFile = sizeof (filename);      file_details.nMaxFile = sizeof (filename);
13383        file_details.lpstrInitialDir = init_dir;      file_details.lpstrInitialDir = init_dir;
13384        file_details.lpstrTitle = XSTRING (prompt)->data;      file_details.lpstrTitle = SDATA (prompt);
13385        file_details.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR;      file_details.Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR
13386                              | OFN_EXPLORER | OFN_ENABLEHOOK);
13387        if (!NILP (mustmatch))
13388          file_details.Flags |= OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
13389    
13390        if (!NILP (mustmatch))      file_details.lpfnHook = (LPOFNHOOKPROC) file_dialog_callback;
         file_details.Flags |= OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;  
13391    
13392        if (GetOpenFileName (&file_details))      if (GetOpenFileName (&file_details))
13393          {        {
13394            dostounix_filename (filename);          dostounix_filename (filename);
13395            file = DECODE_FILE(build_string (filename));          if (file_details.nFilterIndex == 2)
13396          }            {
13397        else              /* "Folder Only" selected - strip dummy file name.  */
13398          file = Qnil;              char * last = strrchr (filename, '/');
13399                *last = '\0';
13400              }
13401    
13402        UNBLOCK_INPUT;          file = DECODE_FILE(build_string (filename));
13403        file = unbind_to (count, file);        }
13404      }      /* User cancelled the dialog without making a selection.  */
13405    /* Open File dialog will not allow folders to be selected, so resort      else if (!CommDlgExtendedError ())
13406       to minibuffer completing reads for directories. */        file = Qnil;
13407    else      /* An error occurred, fallback on reading from the mini-buffer.  */
13408      file = Fcompleting_read (prompt, intern ("read-file-name-internal"),      else
13409                               dir, mustmatch, dir, Qfile_name_history,        file = Fcompleting_read (prompt, intern ("read-file-name-internal"),
13410                               default_filename, Qnil);                                 dir, mustmatch, dir, Qfile_name_history,
13411                                   default_filename, Qnil);
13412    
13413        UNBLOCK_INPUT;
13414        file = unbind_to (count, file);
13415      }
13416    
13417    UNGCPRO;    UNGCPRO;
13418    
# Line 14462  otherwise it is an integer representing Line 13534  otherwise it is an integer representing
13534    document = ENCODE_FILE (document);    document = ENCODE_FILE (document);
13535    if ((int) ShellExecute (NULL,    if ((int) ShellExecute (NULL,
13536                            (STRINGP (operation) ?                            (STRINGP (operation) ?
13537                             XSTRING (operation)->data : NULL),                             SDATA (operation) : NULL),
13538                            XSTRING (document)->data,                            SDATA (document),
13539                            (STRINGP (parameters) ?                            (STRINGP (parameters) ?
13540                             XSTRING (parameters)->data : NULL),                             SDATA (parameters) : NULL),
13541                            XSTRING (current_dir)->data,                            SDATA (current_dir),
13542                            (INTEGERP (show_flag) ?                            (INTEGERP (show_flag) ?
13543                             XINT (show_flag) : SW_SHOWDEFAULT))                             XINT (show_flag) : SW_SHOWDEFAULT))
13544        > 32)        > 32)
# Line 14528  w32_parse_hot_key (key) Line 13600  w32_parse_hot_key (key)
13600        c = Fcar (c);        c = Fcar (c);
13601        if (!SYMBOLP (c))        if (!SYMBOLP (c))
13602          abort ();          abort ();
13603        vk_code = lookup_vk_code (XSTRING (SYMBOL_NAME (c))->data);        vk_code = lookup_vk_code (SDATA (SYMBOL_NAME (c)));
13604      }      }
13605    else if (INTEGERP (c))    else if (INTEGERP (c))
13606      {      {
# Line 14732  If the underlying system call fails, val Line 13804  If the underlying system call fails, val
13804      /* On Windows, we may need to specify the root directory of the      /* On Windows, we may need to specify the root directory of the
13805         volume holding FILENAME.  */         volume holding FILENAME.  */
13806      char rootname[MAX_PATH];      char rootname[MAX_PATH];
13807      char *name = XSTRING (encoded)->data;      char *name = SDATA (encoded);
13808    
13809      /* find the root name of the volume if given */      /* find the root name of the volume if given */
13810      if (isalpha (name[0]) && name[1] == ':')      if (isalpha (name[0]) && name[1] == ':')
# Line 14802  If the underlying system call fails, val Line 13874  If the underlying system call fails, val
13874                              Initialization                              Initialization
13875   ***********************************************************************/   ***********************************************************************/
13876    
13877    /* Keep this list in the same order as frame_parms in frame.c.
13878       Use 0 for unsupported frame parameters.  */
13879    
13880    frame_parm_handler w32_frame_parm_handlers[] =
13881    {
13882      x_set_autoraise,
13883      x_set_autolower,
13884      x_set_background_color,
13885      x_set_border_color,
13886      x_set_border_width,
13887      x_set_cursor_color,
13888      x_set_cursor_type,
13889      x_set_font,
13890      x_set_foreground_color,
13891      x_set_icon_name,
13892      x_set_icon_type,
13893      x_set_internal_border_width,
13894      x_set_menu_bar_lines,
13895      x_set_mouse_color,
13896      x_explicitly_set_name,
13897      x_set_scroll_bar_width,
13898      x_set_title,
13899      x_set_unsplittable,
13900      x_set_vertical_scroll_bars,
13901      x_set_visibility,
13902      x_set_tool_bar_lines,
13903      0, /* x_set_scroll_bar_foreground, */
13904      0, /* x_set_scroll_bar_background, */
13905      x_set_screen_gamma,
13906      x_set_line_spacing,
13907      x_set_fringe_width,
13908      x_set_fringe_width,
13909      0, /* x_set_wait_for_wm, */
13910      x_set_fullscreen,
13911    };
13912    
13913  void  void
13914  syms_of_w32fns ()  syms_of_w32fns ()
13915  {  {
13916    HMODULE user32_lib = GetModuleHandle ("user32.dll");    globals_of_w32fns ();
   
13917    /* This is zero if not using MS-Windows.  */    /* This is zero if not using MS-Windows.  */
13918    w32_in_use = 0;    w32_in_use = 0;
   
   /* TrackMouseEvent not available in all versions of Windows, so must load  
      it dynamically.  Do it once, here, instead of every time it is used.  */  
   track_mouse_event_fn = GetProcAddress (user32_lib, "TrackMouseEvent");  
13919    track_mouse_window = NULL;    track_mouse_window = NULL;
13920    
13921    w32_visible_system_caret_hwnd = NULL;    w32_visible_system_caret_hwnd = NULL;
13922    
   Qauto_raise = intern ("auto-raise");  
   staticpro (&Qauto_raise);  
   Qauto_lower = intern ("auto-lower");  
   staticpro (&Qauto_lower);  
   Qbar = intern ("bar");  
   staticpro (&Qbar);  
   Qhbar = intern ("hbar");  
   staticpro (&Qhbar);  
   Qborder_color = intern ("border-color");  
   staticpro (&Qborder_color);  
   Qborder_width = intern ("border-width");  
   staticpro (&Qborder_width);  
   Qbox = intern ("box");  
   staticpro (&Qbox);  
   Qcursor_color = intern ("cursor-color");  
   staticpro (&Qcursor_color);  
   Qcursor_type = intern ("cursor-type");  
   staticpro (&Qcursor_type);  
   Qgeometry = intern ("geometry");  
   staticpro (&Qgeometry);  
   Qicon_left = intern ("icon-left");  
   staticpro (&Qicon_left);  
   Qicon_top = intern ("icon-top");  
   staticpro (&Qicon_top);  
   Qicon_type = intern ("icon-type");  
   staticpro (&Qicon_type);  
   Qicon_name = intern ("icon-name");  
   staticpro (&Qicon_name);  
   Qinternal_border_width = intern ("internal-border-width");  
   staticpro (&Qinternal_border_width);  
   Qleft = intern ("left");  
   staticpro (&Qleft);  
   Qright = intern ("right");  
   staticpro (&Qright);  
   Qmouse_color = intern ("mouse-color");  
   staticpro (&Qmouse_color);  
13923    Qnone = intern ("none");    Qnone = intern ("none");
13924    staticpro (&Qnone);    staticpro (&Qnone);
   Qparent_id = intern ("parent-id");  
   staticpro (&Qparent_id);  
   Qscroll_bar_width = intern ("scroll-bar-width");  
   staticpro (&Qscroll_bar_width);  
13925    Qsuppress_icon = intern ("suppress-icon");    Qsuppress_icon = intern ("suppress-icon");
13926    staticpro (&Qsuppress_icon);    staticpro (&Qsuppress_icon);
13927    Qundefined_color = intern ("undefined-color");    Qundefined_color = intern ("undefined-color");
13928    staticpro (&Qundefined_color);    staticpro (&Qundefined_color);
   Qvertical_scroll_bars = intern ("vertical-scroll-bars");  
   staticpro (&Qvertical_scroll_bars);  
   Qvisibility = intern ("visibility");  
   staticpro (&Qvisibility);  
   Qwindow_id = intern ("window-id");  
   staticpro (&Qwindow_id);  
   Qx_frame_parameter = intern ("x-frame-parameter");  
   staticpro (&Qx_frame_parameter);  
   Qx_resource_name = intern ("x-resource-name");  
   staticpro (&Qx_resource_name);  
   Quser_position = intern ("user-position");  
   staticpro (&Quser_position);  
   Quser_size = intern ("user-size");  
   staticpro (&Quser_size);  
   Qscreen_gamma = intern ("screen-gamma");  
   staticpro (&Qscreen_gamma);  
   Qline_spacing = intern ("line-spacing");  
   staticpro (&Qline_spacing);  
13929    Qcenter = intern ("center");    Qcenter = intern ("center");
13930    staticpro (&Qcenter);    staticpro (&Qcenter);
13931    Qcancel_timer = intern ("cancel-timer");    Qcancel_timer = intern ("cancel-timer");
13932    staticpro (&Qcancel_timer);    staticpro (&Qcancel_timer);
   Qfullscreen = intern ("fullscreen");  
   staticpro (&Qfullscreen);  
   Qfullwidth = intern ("fullwidth");  
   staticpro (&Qfullwidth);  
   Qfullheight = intern ("fullheight");  
   staticpro (&Qfullheight);  
   Qfullboth = intern ("fullboth");  
   staticpro (&Qfullboth);  
13933    
13934    Qhyper = intern ("hyper");    Qhyper = intern ("hyper");
13935    staticpro (&Qhyper);    staticpro (&Qhyper);
# Line 14930  syms_of_w32fns () Line 13967  syms_of_w32fns ()
13967    QCmask = intern (":mask");    QCmask = intern (":mask");
13968    staticpro (&QCmask);    staticpro (&QCmask);
13969    
   Qface_set_after_frame_default = intern ("face-set-after-frame-default");  
   staticpro (&Qface_set_after_frame_default);  
   
13970    Fput (Qundefined_color, Qerror_conditions,    Fput (Qundefined_color, Qerror_conditions,
13971          Fcons (Qundefined_color, Fcons (Qerror, Qnil)));          Fcons (Qundefined_color, Fcons (Qerror, Qnil)));
13972    Fput (Qundefined_color, Qerror_message,    Fput (Qundefined_color, Qerror_message,
# Line 14960  When nil, Emacs will translate the alt k Line 13994  When nil, Emacs will translate the alt k
13994                doc: /* If non-zero, the virtual key code for an alternative quit key.  */);                doc: /* If non-zero, the virtual key code for an alternative quit key.  */);
13995    XSETINT (Vw32_quit_key, 0);    XSETINT (Vw32_quit_key, 0);
13996    
13997    DEFVAR_LISP ("w32-pass-lwindow-to-system",    DEFVAR_LISP ("w32-pass-lwindow-to-system",
13998                 &Vw32_pass_lwindow_to_system,                 &Vw32_pass_lwindow_to_system,
13999                 doc: /* Non-nil if the left \"Windows\" key is passed on to Windows.                 doc: /* Non-nil if the left \"Windows\" key is passed on to Windows.
14000  When non-nil, the Start menu is opened by tapping the key.  */);  When non-nil, the Start menu is opened by tapping the key.  */);
14001    Vw32_pass_lwindow_to_system = Qt;    Vw32_pass_lwindow_to_system = Qt;
14002    
14003    DEFVAR_LISP ("w32-pass-rwindow-to-system",    DEFVAR_LISP ("w32-pass-rwindow-to-system",
14004                 &Vw32_pass_rwindow_to_system,                 &Vw32_pass_rwindow_to_system,
14005                 doc: /* Non-nil if the right \"Windows\" key is passed on to Windows.                 doc: /* Non-nil if the right \"Windows\" key is passed on to Windows.
14006  When non-nil, the Start menu is opened by tapping the key.  */);  When non-nil, the Start menu is opened by tapping the key.  */);
# Line 14984  acting on \"Windows\" key events when `w Line 14018  acting on \"Windows\" key events when `w
14018       means that this hack won't interfere with any real key code.  */       means that this hack won't interfere with any real key code.  */
14019    Vw32_phantom_key_code = 255;    Vw32_phantom_key_code = 255;
14020    
14021    DEFVAR_LISP ("w32-enable-num-lock",    DEFVAR_LISP ("w32-enable-num-lock",
14022                 &Vw32_enable_num_lock,                 &Vw32_enable_num_lock,
14023                 doc: /* Non-nil if Num Lock should act normally.                 doc: /* Non-nil if Num Lock should act normally.
14024  Set to nil to see Num Lock as the key `kp-numlock'.  */);  Set to nil to see Num Lock as the key `kp-numlock'.  */);
14025    Vw32_enable_num_lock = Qt;    Vw32_enable_num_lock = Qt;
14026    
14027    DEFVAR_LISP ("w32-enable-caps-lock",    DEFVAR_LISP ("w32-enable-caps-lock",
14028                 &Vw32_enable_caps_lock,                 &Vw32_enable_caps_lock,
14029                 doc: /* Non-nil if Caps Lock should act normally.                 doc: /* Non-nil if Caps Lock should act normally.
14030  Set to nil to see Caps Lock as the key `capslock'.  */);  Set to nil to see Caps Lock as the key `capslock'.  */);
# Line 15063  If this variable is non-nil, Emacs will Line 14097  If this variable is non-nil, Emacs will
14097  system to handle them.  */);  system to handle them.  */);
14098    w32_pass_extra_mouse_buttons_to_system = 0;    w32_pass_extra_mouse_buttons_to_system = 0;
14099    
   init_x_parm_symbols ();  
   
14100    DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,    DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
14101                 doc: /* List of directories to search for bitmap files for w32.  */);                 doc: /* List of directories to search for window system bitmap files.  */);
14102    Vx_bitmap_file_path = decode_env_path ((char *) 0, "PATH");    Vx_bitmap_file_path = decode_env_path ((char *) 0, "PATH");
14103    
14104    DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,    DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
# Line 15075  Changing the value does not affect exist Line 14107  Changing the value does not affect exist
14107  unless you set the mouse color.  */);  unless you set the mouse color.  */);
14108    Vx_pointer_shape = Qnil;    Vx_pointer_shape = Qnil;
14109    
   DEFVAR_LISP ("x-resource-name", &Vx_resource_name,  
                doc: /* The name Emacs uses to look up resources; for internal use only.  
 `x-get-resource' uses this as the first component of the instance name  
 when requesting resource values.  
 Emacs initially sets `x-resource-name' to the name under which Emacs  
 was invoked, or to the value specified with the `-name' or `-rn'  
 switches, if present.  */);  
   Vx_resource_name = Qnil;  
   
14110    Vx_nontext_pointer_shape = Qnil;    Vx_nontext_pointer_shape = Qnil;
14111    
14112    Vx_mode_pointer_shape = Qnil;    Vx_mode_pointer_shape = Qnil;
# Line 15097  or when you set the mouse color.  */); Line 14120  or when you set the mouse color.  */);
14120    DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,    DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
14121                 doc: /* Non-zero means Emacs displays an hourglass pointer on window systems.  */);                 doc: /* Non-zero means Emacs displays an hourglass pointer on window systems.  */);
14122    display_hourglass_p = 1;    display_hourglass_p = 1;
14123      
14124    DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,    DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
14125                 doc: /* *Seconds to wait before displaying an hourglass pointer.                 doc: /* *Seconds to wait before displaying an hourglass pointer.
14126  Value must be an integer or float.  */);  Value must be an integer or float.  */);
# Line 15125  or when you set the mouse color.  */); Line 14148  or when you set the mouse color.  */);
14148                 doc: /* Maximum size for tooltips.                 doc: /* Maximum size for tooltips.
14149  Value is a pair (COLUMNS . ROWS). Text larger than this is clipped.  */);  Value is a pair (COLUMNS . ROWS). Text larger than this is clipped.  */);
14150    Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));    Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
14151      
14152    DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,    DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
14153                 doc: /* Non-nil if no window manager is in use.                 doc: /* Non-nil if no window manager is in use.
14154  Emacs doesn't try to figure this out; this is always nil  Emacs doesn't try to figure this out; this is always nil
# Line 15258  versions of Windows) characters.  */); Line 14281  versions of Windows) characters.  */);
14281      Qw32_charset_unicode = intern ("w32-charset-unicode");      Qw32_charset_unicode = intern ("w32-charset-unicode");
14282  #endif  #endif
14283    
   defsubr (&Sx_get_resource);  
14284  #if 0 /* TODO: Port to W32 */  #if 0 /* TODO: Port to W32 */
14285    defsubr (&Sx_change_window_property);    defsubr (&Sx_change_window_property);
14286    defsubr (&Sx_delete_window_property);    defsubr (&Sx_delete_window_property);
# Line 15281  versions of Windows) characters.  */); Line 14303  versions of Windows) characters.  */);
14303    defsubr (&Sx_display_visual_class);    defsubr (&Sx_display_visual_class);
14304    defsubr (&Sx_display_backing_store);    defsubr (&Sx_display_backing_store);
14305    defsubr (&Sx_display_save_under);    defsubr (&Sx_display_save_under);
   defsubr (&Sx_parse_geometry);  
14306    defsubr (&Sx_create_frame);    defsubr (&Sx_create_frame);
14307    defsubr (&Sx_open_connection);    defsubr (&Sx_open_connection);
14308    defsubr (&Sx_close_connection);    defsubr (&Sx_close_connection);
# Line 15337  versions of Windows) characters.  */); Line 14358  versions of Windows) characters.  */);
14358    staticpro (&QCrelief);    staticpro (&QCrelief);
14359    Qpostscript = intern ("postscript");    Qpostscript = intern ("postscript");
14360    staticpro (&Qpostscript);    staticpro (&Qpostscript);
 #if 0 /* TODO: These need entries at top of file.  */  
14361    QCloader = intern (":loader");    QCloader = intern (":loader");
14362    staticpro (&QCloader);    staticpro (&QCloader);
14363    QCbounding_box = intern (":bounding-box");    QCbounding_box = intern (":bounding-box");
# Line 15346  versions of Windows) characters.  */); Line 14366  versions of Windows) characters.  */);
14366    staticpro (&QCpt_width);    staticpro (&QCpt_width);
14367    QCpt_height = intern (":pt-height");    QCpt_height = intern (":pt-height");
14368    staticpro (&QCpt_height);    staticpro (&QCpt_height);
 #endif  
14369    QCindex = intern (":index");    QCindex = intern (":index");
14370    staticpro (&QCindex);    staticpro (&QCindex);
14371    Qpbm = intern ("pbm");    Qpbm = intern ("pbm");
# Line 15356  versions of Windows) characters.  */); Line 14375  versions of Windows) characters.  */);
14375    Qxpm = intern ("xpm");    Qxpm = intern ("xpm");
14376    staticpro (&Qxpm);    staticpro (&Qxpm);
14377  #endif  #endif
14378      
14379  #if HAVE_JPEG  #if HAVE_JPEG
14380    Qjpeg = intern ("jpeg");    Qjpeg = intern ("jpeg");
14381    staticpro (&Qjpeg);    staticpro (&Qjpeg);
14382  #endif  #endif
14383    
14384  #if HAVE_TIFF  #if HAVE_TIFF
14385    Qtiff = intern ("tiff");    Qtiff = intern ("tiff");
14386    staticpro (&Qtiff);    staticpro (&Qtiff);
14387  #endif  #endif
14388    
14389  #if HAVE_GIF  #if HAVE_GIF
14390    Qgif = intern ("gif");    Qgif = intern ("gif");
# Line 15402  versions of Windows) characters.  */); Line 14421  versions of Windows) characters.  */);
14421  }  }
14422    
14423    
14424  void  /*
14425  init_xfns ()          globals_of_w32fns is used to initialize those global variables that
14426            must always be initialized on startup even when the global variable
14427            initialized is non zero (see the function main in emacs.c).
14428            globals_of_w32fns is called from syms_of_w32fns when the global
14429            variable initialized is 0 and directly from main when initialized
14430            is non zero.
14431     */
14432    void globals_of_w32fns ()
14433  {  {
14434    image_types = NULL;    HMODULE user32_lib = GetModuleHandle ("user32.dll");
14435    Vimage_types = Qnil;          /*
14436                    TrackMouseEvent not available in all versions of Windows, so must load
14437                    it dynamically.  Do it once, here, instead of every time it is used.
14438      */
14439      track_mouse_event_fn = (TrackMouseEvent_Proc) GetProcAddress (user32_lib, "TrackMouseEvent");
14440    }
14441    
14442    /* Initialize image types. Based on which libraries are available.  */
14443    static void
14444    init_external_image_libraries ()
14445    {
14446      HINSTANCE library;
14447    
   define_image_type (&pbm_type);  
   define_image_type (&xbm_type);  
 #if 0 /* TODO : Image support for W32 */  
   define_image_type (&gs_type);  
 #endif  
     
14448  #if HAVE_XPM  #if HAVE_XPM
14449    define_image_type (&xpm_type);    if ((library = LoadLibrary ("libXpm.dll")))
14450        {
14451          if (init_xpm_functions (library))
14452            define_image_type (&xpm_type);
14453        }
14454    
14455  #endif  #endif
14456      
14457  #if HAVE_JPEG  #if HAVE_JPEG
14458    define_image_type (&jpeg_type);    /* Try loading jpeg library under probable names.  */
14459      if ((library = LoadLibrary ("libjpeg.dll"))
14460          || (library = LoadLibrary ("jpeg-62.dll"))
14461          || (library = LoadLibrary ("jpeg.dll")))
14462        {
14463          if (init_jpeg_functions (library))
14464            define_image_type (&jpeg_type);
14465        }
14466  #endif  #endif
14467      
14468  #if HAVE_TIFF  #if HAVE_TIFF
14469    define_image_type (&tiff_type);    if (library = LoadLibrary ("libtiff.dll"))
14470        {
14471          if (init_tiff_functions (library))
14472            define_image_type (&tiff_type);
14473        }
14474  #endif  #endif
14475    
14476  #if HAVE_GIF  #if HAVE_GIF
14477    define_image_type (&gif_type);    if (library = LoadLibrary ("libungif.dll"))
14478        {
14479          if (init_gif_functions (library))
14480            define_image_type (&gif_type);
14481        }
14482  #endif  #endif
14483      
14484  #if HAVE_PNG  #if HAVE_PNG
14485    define_image_type (&png_type);    /* Ensure zlib is loaded.  Try debug version first.  */
14486      if (!LoadLibrary ("zlibd.dll"))
14487        LoadLibrary ("zlib.dll");
14488    
14489      /* Try loading libpng under probable names.  */
14490      if ((library = LoadLibrary ("libpng13d.dll"))
14491          || (library = LoadLibrary ("libpng13.dll"))
14492          || (library = LoadLibrary ("libpng12d.dll"))
14493          || (library = LoadLibrary ("libpng12.dll"))
14494          || (library = LoadLibrary ("libpng.dll")))
14495        {
14496          if (init_png_functions (library))
14497            define_image_type (&png_type);
14498        }
14499  #endif  #endif
14500  }  }
14501    
14502    void
14503    init_xfns ()
14504    {
14505      image_types = NULL;
14506      Vimage_types = Qnil;
14507    
14508      define_image_type (&pbm_type);
14509      define_image_type (&xbm_type);
14510    
14511    #if 0 /* TODO : Ghostscript support for W32 */
14512      define_image_type (&gs_type);
14513    #endif
14514    
14515      /* Image types that rely on external libraries are loaded dynamically
14516         if the library is available.  */
14517      init_external_image_libraries ();
14518    }
14519    
14520  #undef abort  #undef abort
14521    
14522  void  void
14523  w32_abort()  w32_abort()
14524  {  {
14525    int button;    int button;

Legend:
Removed from v.1.173  
changed lines
  Added in v.1.173.2.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26