update.
[chise/xemacs-chise.git.1] / src / glyphs-x.c
index 9ce627b..105bbff 100644 (file)
@@ -4,7 +4,7 @@
    Copyright (C) 1995 Tinker Systems
    Copyright (C) 1995, 1996 Ben Wing
    Copyright (C) 1995 Sun Microsystems
    Copyright (C) 1995 Tinker Systems
    Copyright (C) 1995, 1996 Ben Wing
    Copyright (C) 1995 Sun Microsystems
-   Copyright (C) 1999, 2000 Andy Piper
+   Copyright (C) 1999, 2000, 2002 Andy Piper
 
 This file is part of XEmacs.
 
 
 This file is part of XEmacs.
 
@@ -156,6 +156,10 @@ static void
 update_tab_widget_face (widget_value* wv,
                        Lisp_Image_Instance* ii, Lisp_Object domain);
 #endif
 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);
+void
+enqueue_focus_event (Widget wants_it, Lisp_Object frame, int in_p);
 
 #include "bitmaps.h"
 
 
 #include "bitmaps.h"
 
@@ -229,7 +233,8 @@ convert_EImage_to_XImage (Lisp_Object device, int width, int height,
   if (vis->class == PseudoColor)
     {
       unsigned long pixarray[256];
   if (vis->class == PseudoColor)
     {
       unsigned long pixarray[256];
-      int pixcount, n;
+      int pixcount;
+      unsigned int n;
       /* use our quantize table to allocate the colors */
       pixcount = 32;
       *pixtbl = xnew_array (unsigned long, pixcount);
       /* use our quantize table to allocate the colors */
       pixcount = 32;
       *pixtbl = xnew_array (unsigned long, pixcount);
@@ -430,7 +435,7 @@ x_finalize_image_instance (Lisp_Image_Instance *p)
        }
       else
        {
        }
       else
        {
-         int i;
+         unsigned int i;
          if (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p))
            disable_glyph_animated_timeout (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p));
 
          if (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p))
            disable_glyph_animated_timeout (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p));
 
@@ -701,7 +706,7 @@ write_lisp_string_to_temp_file (Lisp_Object string, char *filename_out)
   /* Get the data while doing the conversion */
   while (1)
     {
   /* 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... */
       if (!size_in_bytes)
        break;
       /* It does seem the flushes are necessary... */
@@ -796,7 +801,7 @@ generate_cursor_fg_bg (Lisp_Object device, Lisp_Object *foreground,
   else
     {
       xbg->pixel = 0;
   else
     {
       xbg->pixel = 0;
-      xbg->red = xbg->green = xbg->blue = ~0;
+      xbg->red = xbg->green = xbg->blue = USHRT_MAX;
     }
 }
 
     }
 }
 
@@ -1000,12 +1005,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! */
 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
 }
 
 /* Given inline data for a mono pixmap, initialize the given
@@ -1144,7 +1150,7 @@ init_image_instance_from_xbm_inline (Lisp_Image_Instance *ii,
       break;
 
     default:
       break;
 
     default:
-      abort ();
+      ABORT ();
     }
 }
 
     }
 }
 
@@ -1168,7 +1174,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))),
       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,
     }
 
   init_image_instance_from_xbm_inline (ii, width, height, bits,
@@ -1271,7 +1277,7 @@ extract_xpm_color_names (XpmAttributes *xpmattrs, Lisp_Object device,
       /* Duplicate the pixel value so that we still have a lock on it if
         the pixel we were passed is later freed. */
       if (! XAllocColor (dpy, cmap, &color))
       /* Duplicate the pixel value so that we still have a lock on it if
         the pixel we were passed is later freed. */
       if (! XAllocColor (dpy, cmap, &color))
-       abort ();  /* it must be allocable since we're just duplicating it */
+       ABORT ();  /* it must be allocable since we're just duplicating it */
 
       symbols [i].name = (char *) XSTRING_DATA (XCAR (cons));
       symbols [i].pixel = color.pixel;
 
       symbols [i].name = (char *) XSTRING_DATA (XCAR (cons));
       symbols [i].pixel = color.pixel;
@@ -1626,7 +1632,7 @@ x_xpm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
       break;
 
     default:
       break;
 
     default:
-      abort ();
+      ABORT ();
     }
 
   xpm_free (&xpmattrs);        /* after we've read pixels and hotspot */
     }
 
   xpm_free (&xpmattrs);        /* after we've read pixels and hotspot */
@@ -2129,6 +2135,12 @@ x_unmap_subwindow (Lisp_Image_Instance *p)
     }
   else                         /* must be a widget */
     {
     }
   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));
     }
 }
       XtUnmapWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p));
     }
 }
@@ -2139,6 +2151,7 @@ static void
 x_map_subwindow (Lisp_Image_Instance *p, int x, int y,
                 struct display_glyph_area* dga)
 {
 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);
   if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW)
     {
       Window subwindow = IMAGE_INSTANCE_X_SUBWINDOW_ID (p);
@@ -2161,6 +2174,14 @@ x_map_subwindow (Lisp_Image_Instance *p, int x, int y,
                    -dga->xoffset, -dga->yoffset);
       if (!IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (p))
        XtMapWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p));
                    -dga->xoffset, -dga->yoffset);
       if (!IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (p))
        XtMapWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p));
+      /* See comments in glyphs-msw.c about keyboard focus. */
+      if (IMAGE_INSTANCE_WANTS_INITIAL_FOCUS (p)) {
+       /* #### FIXME to pop-up the find dialog we map the text-field
+          seven times! This doesn't show on a fast linux box but does
+          under X on windows. */
+       enqueue_focus_event (IMAGE_INSTANCE_X_WIDGET_ID (p),
+                            IMAGE_INSTANCE_FRAME (p), 1);
+      }
     }
 }
 
     }
 }
 
@@ -2209,8 +2230,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
         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);
     }
                                   (IMAGE_INSTANCE_X_WIDGET_LWID (p)),
                                   NO_CHANGE);
     }
@@ -2218,8 +2239,14 @@ x_redisplay_widget (Lisp_Image_Instance *p)
   /* Possibly update the colors and font */
   if (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (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))->faces_changed
       ||
+      XFRAME (IMAGE_INSTANCE_FRAME (p))->frame_changed
+      ||
       IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p))
     {
       update_widget_face (wv, p, IMAGE_INSTANCE_FRAME (p));
       IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p))
     {
       update_widget_face (wv, p, IMAGE_INSTANCE_FRAME (p));
@@ -2258,6 +2285,16 @@ x_redisplay_widget (Lisp_Image_Instance *p)
                               (Dimension)IMAGE_INSTANCE_HEIGHT (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);
   /* now modify the widget */
   lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (p),
                         wv, True);
@@ -2319,6 +2356,14 @@ x_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
   IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void*)win;
 }
 
   IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void*)win;
 }
 
+/* Account for some of the limitations with widget images. */
+static int
+x_widget_border_width (void)
+{
+  return DEFAULT_WIDGET_BORDER_WIDTH * 2;
+}
+
+
 #if 0
 /* #### Should this function exist? If there's any doubt I'm not implementing it --andyp */
 DEFUN ("change-subwindow-property", Fchange_subwindow_property, 3, 3, 0, /*
 #if 0
 /* #### Should this function exist? If there's any doubt I'm not implementing it --andyp */
 DEFUN ("change-subwindow-property", Fchange_subwindow_property, 3, 3, 0, /*
@@ -2481,6 +2526,10 @@ x_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
 
   free_widget_value_tree (clip_wv);
 
 
   free_widget_value_tree (clip_wv);
 
+  /* create a sensible name. */
+  if (wv->name == 0 || strcmp(wv->name, "") == 0)
+    wv->name = xstrdup (type);
+
   /* copy any args we were given */
   ac = 0;
   lw_add_value_args_to_args (wv, al, &ac);
   /* copy any args we were given */
   ac = 0;
   lw_add_value_args_to_args (wv, al, &ac);
@@ -2752,7 +2801,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)));
                     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;
                  char* name;
                  unsigned int num_children, i;
                  Widget* children;
@@ -2768,7 +2817,9 @@ x_tab_control_redisplay (Lisp_Object image_instance)
                      if (!strcmp (XtName (children [i]), name))
                        {
                          XtSetArg (al [0], XtNtopWidget, children [i]);
                      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;
                        }
                    }
                          break;
                        }
                    }
@@ -2854,6 +2905,7 @@ console_type_create_glyphs_x (void)
   CONSOLE_HAS_METHOD (x, map_subwindow);
   CONSOLE_HAS_METHOD (x, redisplay_widget);
   CONSOLE_HAS_METHOD (x, redisplay_subwindow);
   CONSOLE_HAS_METHOD (x, map_subwindow);
   CONSOLE_HAS_METHOD (x, redisplay_widget);
   CONSOLE_HAS_METHOD (x, redisplay_subwindow);
+  CONSOLE_HAS_METHOD (x, widget_border_width);
 }
 
 void
 }
 
 void
@@ -2953,6 +3005,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);
   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);
 
   IIFORMAT_HAS_METHOD (autodetect, instantiate);
   IIFORMAT_VALID_CONSOLE (x, autodetect);
 
@@ -2980,7 +3043,7 @@ complex_vars_of_glyphs_x (void)
      vector3 (Qxbm, Q_data,                                    \
              list3 (make_int (name##_width),                   \
                     make_int (name##_height),                  \
      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)
                                      sizeof (name##_bits),     \
                                      Qbinary))),               \
      Qglobal, Qx, Qnil)