XEmacs 21.4.5 "Civil Service".
[chise/xemacs-chise.git.1] / src / glyphs-x.c
index 9ce627b..ae7d3be 100644 (file)
@@ -156,6 +156,8 @@ static void
 update_tab_widget_face (widget_value* wv,
                        Lisp_Image_Instance* ii, Lisp_Object domain);
 #endif
+void
+emacs_Xt_handle_widget_losing_focus (struct frame* f, Widget losing_widget);
 
 #include "bitmaps.h"
 
@@ -701,7 +703,7 @@ write_lisp_string_to_temp_file (Lisp_Object string, char *filename_out)
   /* Get the data while doing the conversion */
   while (1)
     {
-      ssize_t size_in_bytes = Lstream_read (istr, tempbuf, sizeof (tempbuf));
+      Lstream_data_count size_in_bytes = Lstream_read (istr, tempbuf, sizeof (tempbuf));
       if (!size_in_bytes)
        break;
       /* It does seem the flushes are necessary... */
@@ -796,7 +798,7 @@ generate_cursor_fg_bg (Lisp_Object device, Lisp_Object *foreground,
   else
     {
       xbg->pixel = 0;
-      xbg->red = xbg->green = xbg->blue = ~0;
+      xbg->red = xbg->green = xbg->blue = USHRT_MAX;
     }
 }
 
@@ -1000,12 +1002,13 @@ int read_bitmap_data_from_file (const char *filename, unsigned int *width,
 static Pixmap
 pixmap_from_xbm_inline (Lisp_Object device, int width, int height,
                        /* Note that data is in ext-format! */
-                       const Extbyte *bits)
+                       const char *bits)
 {
-  return XCreatePixmapFromBitmapData (DEVICE_X_DISPLAY (XDEVICE(device)),
-                                     XtWindow (DEVICE_XT_APP_SHELL (XDEVICE (device))),
-                                     (char *) bits, width, height,
-                                     1, 0, 1);
+  return XCreatePixmapFromBitmapData
+    (DEVICE_X_DISPLAY (XDEVICE (device)),
+     XtWindow (DEVICE_XT_APP_SHELL (XDEVICE (device))),
+     (char *) bits, width, height,
+     1, 0, 1);
 }
 
 /* Given inline data for a mono pixmap, initialize the given
@@ -1168,7 +1171,7 @@ xbm_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
       mask = pixmap_from_xbm_inline (IMAGE_INSTANCE_DEVICE (ii),
                                     XINT (XCAR (mask_data)),
                                     XINT (XCAR (XCDR (mask_data))),
-                                    (const unsigned char *) ext_data);
+                                    ext_data);
     }
 
   init_image_instance_from_xbm_inline (ii, width, height, bits,
@@ -2129,6 +2132,12 @@ x_unmap_subwindow (Lisp_Image_Instance *p)
     }
   else                         /* must be a widget */
     {
+      /* Since we are being unmapped we want the enclosing frame to
+        get focus. The losing with simple scrolling but is the safest
+        thing to do. */
+      emacs_Xt_handle_widget_losing_focus 
+       ( XFRAME (IMAGE_INSTANCE_FRAME (p)),
+         IMAGE_INSTANCE_X_WIDGET_ID (p));
       XtUnmapWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p));
     }
 }
@@ -2139,6 +2148,7 @@ static void
 x_map_subwindow (Lisp_Image_Instance *p, int x, int y,
                 struct display_glyph_area* dga)
 {
+  assert (dga->width > 0 && dga->height > 0);
   if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW)
     {
       Window subwindow = IMAGE_INSTANCE_X_SUBWINDOW_ID (p);
@@ -2209,8 +2219,8 @@ x_redisplay_widget (Lisp_Image_Instance *p)
         reference to the real values rather than a copy thus any
         changes we make to the values we get back will look like they
         have already been applied. If we rebuild the widget tree then
-        we may lose propertie. */
-      wv = copy_widget_value_tree (lw_get_all_values
+        we may lose properties. */
+      wv = copy_widget_value_tree (lw_get_all_values 
                                   (IMAGE_INSTANCE_X_WIDGET_LWID (p)),
                                   NO_CHANGE);
     }
@@ -2218,8 +2228,14 @@ x_redisplay_widget (Lisp_Image_Instance *p)
   /* Possibly update the colors and font */
   if (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p)
       ||
+      /* #### This is not sufficient because it will not cope with widgets
+        that are not currently visible. Once redisplay has done the
+        visible ones it will clear this flag so that when new ones
+        become visible they will not be updated. */
       XFRAME (IMAGE_INSTANCE_FRAME (p))->faces_changed
       ||
+      XFRAME (IMAGE_INSTANCE_FRAME (p))->frame_changed
+      ||
       IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p))
     {
       update_widget_face (wv, p, IMAGE_INSTANCE_FRAME (p));
@@ -2258,6 +2274,16 @@ x_redisplay_widget (Lisp_Image_Instance *p)
                               (Dimension)IMAGE_INSTANCE_HEIGHT (p));
     }
 
+  /* Adjust offsets within the frame. */
+  if (XFRAME (IMAGE_INSTANCE_FRAME (p))->size_changed)
+    {
+      Arg al[2];
+      XtSetArg (al [0], XtNx, &IMAGE_INSTANCE_X_WIDGET_XOFFSET (p));
+      XtSetArg (al [1], XtNy, &IMAGE_INSTANCE_X_WIDGET_YOFFSET (p));
+      XtGetValues (FRAME_X_TEXT_WIDGET 
+                  (XFRAME (IMAGE_INSTANCE_FRAME (p))), al, 2);
+    }
+
   /* now modify the widget */
   lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (p),
                         wv, True);
@@ -2752,7 +2778,7 @@ x_tab_control_redisplay (Lisp_Object image_instance)
                     but I couldn't find it. */
                  Lisp_Object old_selected =gui_item_list_find_selected
                    (XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)));
-                 Arg al [1];
+                 Arg al [2];
                  char* name;
                  unsigned int num_children, i;
                  Widget* children;
@@ -2768,7 +2794,9 @@ x_tab_control_redisplay (Lisp_Object image_instance)
                      if (!strcmp (XtName (children [i]), name))
                        {
                          XtSetArg (al [0], XtNtopWidget, children [i]);
-                         XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, 1);
+                         XtSetArg (al [1], XtNhighlightWidget,
+                                   children [i]);
+                         XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, 2);
                          break;
                        }
                    }
@@ -2953,6 +2981,17 @@ image_instantiator_format_create_glyphs_x (void)
   IIFORMAT_HAS_METHOD (autodetect, validate);
   IIFORMAT_HAS_METHOD (autodetect, normalize);
   IIFORMAT_HAS_METHOD (autodetect, possible_dest_types);
+  /* #### autodetect is flawed IMO: 
+  1. It makes the assumption that you can detect whether the user
+  wanted a cursor or a string based on the data, since the data is a
+  string you have to prioritise cursors. Instead we will force users
+  to pick the appropriate image type, this is what we do under
+  MS-Windows anyway.
+  2. It doesn't fit with the new domain model - you cannot tell which
+  domain it needs to be instantiated in until you've actually
+  instantiated it, which mucks up caching.
+  3. It only copes with cursors and strings which seems bogus. */
+  IIFORMAT_HAS_SHARED_METHOD (autodetect, governing_domain, subwindow);
   IIFORMAT_HAS_METHOD (autodetect, instantiate);
   IIFORMAT_VALID_CONSOLE (x, autodetect);
 
@@ -2980,7 +3019,7 @@ complex_vars_of_glyphs_x (void)
      vector3 (Qxbm, Q_data,                                    \
              list3 (make_int (name##_width),                   \
                     make_int (name##_height),                  \
-                    make_ext_string (name##_bits,              \
+                    make_ext_string ((Extbyte *) name##_bits,  \
                                      sizeof (name##_bits),     \
                                      Qbinary))),               \
      Qglobal, Qx, Qnil)