comparison src/glyphs-x.c @ 442:abe6d1db359e r21-2-36

Import from CVS: tag r21-2-36
author cvs
date Mon, 13 Aug 2007 11:35:02 +0200
parents 8de8e3f6228a
children 576fb035e263
comparison
equal deleted inserted replaced
441:72a7cfa4a488 442:abe6d1db359e
15 15
16 XEmacs is distributed in the hope that it will be useful, but WITHOUT 16 XEmacs is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 for more details. 19 for more details.
20
21 You should have received a copy of the GNU General Public License 20 You should have received a copy of the GNU General Public License
22 along with XEmacs; see the file COPYING. If not, write to 21 along with XEmacs; see the file COPYING. If not, write to
23 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 Boston, MA 02111-1307, USA. */ 23 Boston, MA 02111-1307, USA. */
25 24
26 /* Synched up with: Not in FSF. */ 25 /* Synched up with: Not in FSF. */
26
27 /* 7-8-00 This file is more or less Mule-ized in my Mule workspace. */
27 28
28 /* Original author: Jamie Zawinski for 19.8 29 /* Original author: Jamie Zawinski for 19.8
29 font-truename stuff added by Jamie Zawinski for 19.10 30 font-truename stuff added by Jamie Zawinski for 19.10
30 subwindow support added by Chuck Thompson 31 subwindow support added by Chuck Thompson
31 additional XPM support added by Chuck Thompson 32 additional XPM support added by Chuck Thompson
96 97
97 DECLARE_IMAGE_INSTANTIATOR_FORMAT (nothing); 98 DECLARE_IMAGE_INSTANTIATOR_FORMAT (nothing);
98 DECLARE_IMAGE_INSTANTIATOR_FORMAT (string); 99 DECLARE_IMAGE_INSTANTIATOR_FORMAT (string);
99 DECLARE_IMAGE_INSTANTIATOR_FORMAT (formatted_string); 100 DECLARE_IMAGE_INSTANTIATOR_FORMAT (formatted_string);
100 DECLARE_IMAGE_INSTANTIATOR_FORMAT (inherit); 101 DECLARE_IMAGE_INSTANTIATOR_FORMAT (inherit);
101 DECLARE_IMAGE_INSTANTIATOR_FORMAT (layout);
102 #ifdef HAVE_JPEG 102 #ifdef HAVE_JPEG
103 DECLARE_IMAGE_INSTANTIATOR_FORMAT (jpeg); 103 DECLARE_IMAGE_INSTANTIATOR_FORMAT (jpeg);
104 #endif 104 #endif
105 #ifdef HAVE_TIFF 105 #ifdef HAVE_TIFF
106 DECLARE_IMAGE_INSTANTIATOR_FORMAT (tiff); 106 DECLARE_IMAGE_INSTANTIATOR_FORMAT (tiff);
126 DEFINE_IMAGE_INSTANTIATOR_FORMAT (font); 126 DEFINE_IMAGE_INSTANTIATOR_FORMAT (font);
127 127
128 DEFINE_IMAGE_INSTANTIATOR_FORMAT (autodetect); 128 DEFINE_IMAGE_INSTANTIATOR_FORMAT (autodetect);
129 129
130 #ifdef HAVE_WIDGETS 130 #ifdef HAVE_WIDGETS
131 DECLARE_IMAGE_INSTANTIATOR_FORMAT (layout);
131 DEFINE_DEVICE_IIFORMAT (x, widget); 132 DEFINE_DEVICE_IIFORMAT (x, widget);
133 DEFINE_DEVICE_IIFORMAT (x, native_layout);
132 DEFINE_DEVICE_IIFORMAT (x, button); 134 DEFINE_DEVICE_IIFORMAT (x, button);
133 DEFINE_DEVICE_IIFORMAT (x, progress_gauge); 135 DEFINE_DEVICE_IIFORMAT (x, progress_gauge);
134 DEFINE_DEVICE_IIFORMAT (x, edit_field); 136 DEFINE_DEVICE_IIFORMAT (x, edit_field);
135 #if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1 137 #if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1
136 DEFINE_DEVICE_IIFORMAT (x, combo_box); 138 DEFINE_DEVICE_IIFORMAT (x, combo_box);
262 { 264 {
263 rd = *ip++; 265 rd = *ip++;
264 gr = *ip++; 266 gr = *ip++;
265 bl = *ip++; 267 bl = *ip++;
266 conv.val = pixarray[QUANT_GET_COLOR(qtable,rd,gr,bl)]; 268 conv.val = pixarray[QUANT_GET_COLOR(qtable,rd,gr,bl)];
267 #if WORDS_BIGENDIAN 269 #ifdef WORDS_BIGENDIAN
268 if (outimg->byte_order == MSBFirst) 270 if (outimg->byte_order == MSBFirst)
269 for (q = 4-byte_cnt; q < 4; q++) *dp++ = conv.cp[q]; 271 for (q = 4-byte_cnt; q < 4; q++) *dp++ = conv.cp[q];
270 else 272 else
271 for (q = 3; q >= 4-byte_cnt; q--) *dp++ = conv.cp[q]; 273 for (q = 3; q >= 4-byte_cnt; q--) *dp++ = conv.cp[q];
272 #else 274 #else
337 bl = *ip++ << (bbits - 8); 339 bl = *ip++ << (bbits - 8);
338 else 340 else
339 bl = *ip++ >> (8 - bbits); 341 bl = *ip++ >> (8 - bbits);
340 342
341 conv.val = (rd << rshift) | (gr << gshift) | (bl << bshift); 343 conv.val = (rd << rshift) | (gr << gshift) | (bl << bshift);
342 #if WORDS_BIGENDIAN 344 #ifdef WORDS_BIGENDIAN
343 if (outimg->byte_order == MSBFirst) 345 if (outimg->byte_order == MSBFirst)
344 for (q = 4-byte_cnt; q < 4; q++) *dp++ = conv.cp[q]; 346 for (q = 4-byte_cnt; q < 4; q++) *dp++ = conv.cp[q];
345 else 347 else
346 for (q = 3; q >= 4-byte_cnt; q--) *dp++ = conv.cp[q]; 348 for (q = 3; q >= 4-byte_cnt; q--) *dp++ = conv.cp[q];
347 #else 349 #else
392 x_finalize_image_instance (Lisp_Image_Instance *p) 394 x_finalize_image_instance (Lisp_Image_Instance *p)
393 { 395 {
394 if (!p->data) 396 if (!p->data)
395 return; 397 return;
396 398
397 if (DEVICE_LIVE_P (XDEVICE (p->device))) 399 if (DEVICE_LIVE_P (XDEVICE (IMAGE_INSTANCE_DEVICE (p))))
398 { 400 {
399 Display *dpy = DEVICE_X_DISPLAY (XDEVICE (p->device)); 401 Display *dpy = DEVICE_X_DISPLAY
400 402 (XDEVICE (IMAGE_INSTANCE_DEVICE (p)));
401 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET) 403 if (0)
404 ;
405 #ifdef HAVE_WIDGETS
406 else if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET)
402 { 407 {
403 if (IMAGE_INSTANCE_SUBWINDOW_ID (p)) 408 if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
404 { 409 {
405 #ifdef DEBUG_WIDGETS 410 #ifdef DEBUG_WIDGETS
406 debug_widget_instances--; 411 debug_widget_instances--;
407 stderr_out ("widget destroyed, %d left\n", debug_widget_instances); 412 stderr_out ("widget destroyed, %d left\n", debug_widget_instances);
408 #endif 413 #endif
409 lw_destroy_widget (IMAGE_INSTANCE_X_WIDGET_ID (p)); 414 lw_destroy_widget (IMAGE_INSTANCE_X_WIDGET_ID (p));
410 lw_destroy_widget (IMAGE_INSTANCE_X_CLIPWIDGET (p)); 415 lw_destroy_widget (IMAGE_INSTANCE_X_CLIPWIDGET (p));
411 IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0; 416
417 /* We can release the callbacks again. */
418 ungcpro_popup_callbacks (IMAGE_INSTANCE_X_WIDGET_LWID (p));
419
420 IMAGE_INSTANCE_X_WIDGET_ID (p) = 0;
421 IMAGE_INSTANCE_X_CLIPWIDGET (p) = 0;
412 } 422 }
413 } 423 }
424 #endif
414 else if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW) 425 else if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW)
415 { 426 {
416 if (IMAGE_INSTANCE_SUBWINDOW_ID (p)) 427 if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
417 XDestroyWindow (dpy, IMAGE_INSTANCE_X_SUBWINDOW_ID (p)); 428 XDestroyWindow (dpy, IMAGE_INSTANCE_X_SUBWINDOW_ID (p));
418 IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0; 429 IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0;
973 ximage = 0; 984 ximage = 0;
974 } 985 }
975 } 986 }
976 } 987 }
977 988
978 int read_bitmap_data_from_file (CONST char *filename, unsigned int *width, 989 int read_bitmap_data_from_file (const char *filename, unsigned int *width,
979 unsigned int *height, unsigned char **datap, 990 unsigned int *height, unsigned char **datap,
980 int *x_hot, int *y_hot) 991 int *x_hot, int *y_hot)
981 { 992 {
982 return XmuReadBitmapDataFromFile (filename, width, height, 993 return XmuReadBitmapDataFromFile (filename, width, height,
983 datap, x_hot, y_hot); 994 datap, x_hot, y_hot);
987 corresponding X object. */ 998 corresponding X object. */
988 999
989 static Pixmap 1000 static Pixmap
990 pixmap_from_xbm_inline (Lisp_Object device, int width, int height, 1001 pixmap_from_xbm_inline (Lisp_Object device, int width, int height,
991 /* Note that data is in ext-format! */ 1002 /* Note that data is in ext-format! */
992 CONST Extbyte *bits) 1003 const Extbyte *bits)
993 { 1004 {
994 return XCreatePixmapFromBitmapData (DEVICE_X_DISPLAY (XDEVICE(device)), 1005 return XCreatePixmapFromBitmapData (DEVICE_X_DISPLAY (XDEVICE(device)),
995 XtWindow (DEVICE_XT_APP_SHELL (XDEVICE (device))), 1006 XtWindow (DEVICE_XT_APP_SHELL (XDEVICE (device))),
996 (char *) bits, width, height, 1007 (char *) bits, width, height,
997 1, 0, 1); 1008 1, 0, 1);
1002 1013
1003 static void 1014 static void
1004 init_image_instance_from_xbm_inline (Lisp_Image_Instance *ii, 1015 init_image_instance_from_xbm_inline (Lisp_Image_Instance *ii,
1005 int width, int height, 1016 int width, int height,
1006 /* Note that data is in ext-format! */ 1017 /* Note that data is in ext-format! */
1007 CONST char *bits, 1018 const char *bits,
1008 Lisp_Object instantiator, 1019 Lisp_Object instantiator,
1009 Lisp_Object pointer_fg, 1020 Lisp_Object pointer_fg,
1010 Lisp_Object pointer_bg, 1021 Lisp_Object pointer_bg,
1011 int dest_mask, 1022 int dest_mask,
1012 Pixmap mask, 1023 Pixmap mask,
1140 static void 1151 static void
1141 xbm_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator, 1152 xbm_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
1142 Lisp_Object pointer_fg, Lisp_Object pointer_bg, 1153 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1143 int dest_mask, int width, int height, 1154 int dest_mask, int width, int height,
1144 /* Note that data is in ext-format! */ 1155 /* Note that data is in ext-format! */
1145 CONST char *bits) 1156 const char *bits)
1146 { 1157 {
1147 Lisp_Object mask_data = find_keyword_in_vector (instantiator, Q_mask_data); 1158 Lisp_Object mask_data = find_keyword_in_vector (instantiator, Q_mask_data);
1148 Lisp_Object mask_file = find_keyword_in_vector (instantiator, Q_mask_file); 1159 Lisp_Object mask_file = find_keyword_in_vector (instantiator, Q_mask_file);
1149 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 1160 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1150 Pixmap mask = 0; 1161 Pixmap mask = 0;
1151 1162
1152 if (!NILP (mask_data)) 1163 if (!NILP (mask_data))
1153 { 1164 {
1154 CONST char *ext_data; 1165 const char *ext_data;
1155 1166
1156 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (XCDR (XCDR (mask_data))), 1167 LISP_STRING_TO_EXTERNAL (XCAR (XCDR (XCDR (mask_data))), ext_data, Qbinary);
1157 C_STRING_ALLOCA, ext_data,
1158 Qbinary);
1159 mask = pixmap_from_xbm_inline (IMAGE_INSTANCE_DEVICE (ii), 1168 mask = pixmap_from_xbm_inline (IMAGE_INSTANCE_DEVICE (ii),
1160 XINT (XCAR (mask_data)), 1169 XINT (XCAR (mask_data)),
1161 XINT (XCAR (XCDR (mask_data))), 1170 XINT (XCAR (XCDR (mask_data))),
1162 (CONST unsigned char *) ext_data); 1171 (const unsigned char *) ext_data);
1163 } 1172 }
1164 1173
1165 init_image_instance_from_xbm_inline (ii, width, height, bits, 1174 init_image_instance_from_xbm_inline (ii, width, height, bits,
1166 instantiator, pointer_fg, pointer_bg, 1175 instantiator, pointer_fg, pointer_bg,
1167 dest_mask, mask, mask_file); 1176 dest_mask, mask, mask_file);
1173 x_xbm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, 1182 x_xbm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1174 Lisp_Object pointer_fg, Lisp_Object pointer_bg, 1183 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1175 int dest_mask, Lisp_Object domain) 1184 int dest_mask, Lisp_Object domain)
1176 { 1185 {
1177 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); 1186 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1178 CONST char *ext_data; 1187 const char *ext_data;
1179 1188
1180 assert (!NILP (data)); 1189 assert (!NILP (data));
1181 1190
1182 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (XCDR (XCDR (data))), 1191 LISP_STRING_TO_EXTERNAL (XCAR (XCDR (XCDR (data))), ext_data, Qbinary);
1183 C_STRING_ALLOCA, ext_data,
1184 Qbinary);
1185 1192
1186 xbm_instantiate_1 (image_instance, instantiator, pointer_fg, 1193 xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
1187 pointer_bg, dest_mask, XINT (XCAR (data)), 1194 pointer_bg, dest_mask, XINT (XCAR (data)),
1188 XINT (XCAR (XCDR (data))), ext_data); 1195 XINT (XCAR (XCDR (data))), ext_data);
1189 } 1196 }
1658 Lisp_Object pointer_fg, Lisp_Object pointer_bg, 1665 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1659 int dest_mask, Lisp_Object domain) 1666 int dest_mask, Lisp_Object domain)
1660 { 1667 {
1661 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); 1668 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1662 int i, stattis; 1669 int i, stattis;
1663 char *p, *bits, *bp; 1670 char *bits, *bp;
1664 CONST char * volatile emsg = 0; 1671 const char *p;
1665 CONST char * volatile dstring; 1672 const char * volatile emsg = 0;
1673 const char * volatile dstring;
1666 1674
1667 assert (!NILP (data)); 1675 assert (!NILP (data));
1668 1676
1669 TO_EXTERNAL_FORMAT (LISP_STRING, data, 1677 LISP_STRING_TO_EXTERNAL (data, dstring, Qbinary);
1670 C_STRING_ALLOCA, dstring,
1671 Qbinary);
1672 1678
1673 if ((p = strchr (dstring, ':'))) 1679 if ((p = strchr (dstring, ':')))
1674 { 1680 {
1675 dstring = p + 1; 1681 dstring = p + 1;
1676 } 1682 }
1730 data_must_be_present (instantiator); 1736 data_must_be_present (instantiator);
1731 } 1737 }
1732 1738
1733 static Lisp_Object 1739 static Lisp_Object
1734 autodetect_normalize (Lisp_Object instantiator, 1740 autodetect_normalize (Lisp_Object instantiator,
1735 Lisp_Object console_type) 1741 Lisp_Object console_type,
1742 Lisp_Object dest_mask)
1736 { 1743 {
1737 Lisp_Object file = find_keyword_in_vector (instantiator, Q_data); 1744 Lisp_Object file = find_keyword_in_vector (instantiator, Q_data);
1738 Lisp_Object filename = Qnil; 1745 Lisp_Object filename = Qnil;
1739 Lisp_Object data = Qnil; 1746 Lisp_Object data = Qnil;
1740 struct gcpro gcpro1, gcpro2, gcpro3; 1747 struct gcpro gcpro1, gcpro2, gcpro3;
1837 GCPRO3 (data, alist, result); 1844 GCPRO3 (data, alist, result);
1838 1845
1839 alist = tagged_vector_to_alist (instantiator); 1846 alist = tagged_vector_to_alist (instantiator);
1840 if (dest_mask & IMAGE_POINTER_MASK) 1847 if (dest_mask & IMAGE_POINTER_MASK)
1841 { 1848 {
1842 CONST char *name_ext; 1849 const char *name_ext;
1843 TO_EXTERNAL_FORMAT (LISP_STRING, data, 1850 LISP_STRING_TO_EXTERNAL (data, name_ext, Qfile_name);
1844 C_STRING_ALLOCA, name_ext,
1845 Qfile_name);
1846 if (XmuCursorNameToIndex (name_ext) != -1) 1851 if (XmuCursorNameToIndex (name_ext) != -1)
1847 { 1852 {
1848 result = alist_to_tagged_vector (Qcursor_font, alist); 1853 result = alist_to_tagged_vector (Qcursor_font, alist);
1849 is_cursor_font = 1; 1854 is_cursor_font = 1;
1850 } 1855 }
2029 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); 2034 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
2030 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 2035 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2031 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); 2036 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
2032 Display *dpy; 2037 Display *dpy;
2033 int i; 2038 int i;
2034 CONST char *name_ext; 2039 const char *name_ext;
2035 Lisp_Object foreground, background; 2040 Lisp_Object foreground, background;
2036 2041
2037 if (!DEVICE_X_P (XDEVICE (device))) 2042 if (!DEVICE_X_P (XDEVICE (device)))
2038 signal_simple_error ("Not an X device", device); 2043 signal_simple_error ("Not an X device", device);
2039 2044
2040 dpy = DEVICE_X_DISPLAY (XDEVICE (device)); 2045 dpy = DEVICE_X_DISPLAY (XDEVICE (device));
2041 2046
2042 if (!(dest_mask & IMAGE_POINTER_MASK)) 2047 if (!(dest_mask & IMAGE_POINTER_MASK))
2043 incompatible_image_types (instantiator, dest_mask, IMAGE_POINTER_MASK); 2048 incompatible_image_types (instantiator, dest_mask, IMAGE_POINTER_MASK);
2044 2049
2045 TO_EXTERNAL_FORMAT (LISP_STRING, data, 2050 LISP_STRING_TO_EXTERNAL (data, name_ext, Qfile_name);
2046 C_STRING_ALLOCA, name_ext,
2047 Qfile_name);
2048 if ((i = XmuCursorNameToIndex (name_ext)) == -1) 2051 if ((i = XmuCursorNameToIndex (name_ext)) == -1)
2049 signal_simple_error ("Unrecognized cursor-font name", data); 2052 signal_simple_error ("Unrecognized cursor-font name", data);
2050 2053
2051 x_initialize_pixmap_image_instance (ii, 1, IMAGE_POINTER); 2054 x_initialize_pixmap_image_instance (ii, 1, IMAGE_POINTER);
2052 IMAGE_INSTANCE_X_CURSOR (ii) = XCreateFontCursor (dpy, i); 2055 IMAGE_INSTANCE_X_CURSOR (ii) = XCreateFontCursor (dpy, i);
2142 XMoveResizeWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), 2145 XMoveResizeWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p),
2143 IMAGE_INSTANCE_X_CLIPWINDOW (p), 2146 IMAGE_INSTANCE_X_CLIPWINDOW (p),
2144 x, y, dga->width, dga->height); 2147 x, y, dga->width, dga->height);
2145 XMoveWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), 2148 XMoveWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p),
2146 subwindow, -dga->xoffset, -dga->yoffset); 2149 subwindow, -dga->xoffset, -dga->yoffset);
2147 XMapWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), 2150 if (!IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (p))
2148 IMAGE_INSTANCE_X_CLIPWINDOW (p)); 2151 XMapWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p),
2152 IMAGE_INSTANCE_X_CLIPWINDOW (p));
2149 } 2153 }
2150 else /* must be a widget */ 2154 else /* must be a widget */
2151 { 2155 {
2152 XtConfigureWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p), 2156 XtConfigureWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p),
2153 x + IMAGE_INSTANCE_X_WIDGET_XOFFSET (p), 2157 x + IMAGE_INSTANCE_X_WIDGET_XOFFSET (p),
2154 y + IMAGE_INSTANCE_X_WIDGET_YOFFSET (p), 2158 y + IMAGE_INSTANCE_X_WIDGET_YOFFSET (p),
2155 dga->width, dga->height, 0); 2159 dga->width, dga->height, 0);
2156 XtMoveWidget (IMAGE_INSTANCE_X_WIDGET_ID (p), 2160 XtMoveWidget (IMAGE_INSTANCE_X_WIDGET_ID (p),
2157 -dga->xoffset, -dga->yoffset); 2161 -dga->xoffset, -dga->yoffset);
2158 XtMapWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p)); 2162 if (!IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (p))
2163 XtMapWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p));
2159 } 2164 }
2160 } 2165 }
2161 2166
2162 /* when you click on a widget you may activate another widget this 2167 /* when you click on a widget you may activate another widget this
2163 needs to be checked and all appropriate widgets updated */ 2168 needs to be checked and all appropriate widgets updated */
2164 static void 2169 static void
2165 x_update_subwindow (Lisp_Image_Instance *p) 2170 x_redisplay_subwindow (Lisp_Image_Instance *p)
2166 { 2171 {
2172 /* Update the subwindow size if necessary. */
2173 if (IMAGE_INSTANCE_SIZE_CHANGED (p))
2174 {
2175 XResizeWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p),
2176 IMAGE_INSTANCE_X_SUBWINDOW_ID (p),
2177 IMAGE_INSTANCE_WIDTH (p),
2178 IMAGE_INSTANCE_HEIGHT (p));
2179 }
2180 }
2181
2182 /* Update all attributes that have changed. Lwlib actually does most
2183 of this for us. */
2184 static void
2185 x_redisplay_widget (Lisp_Image_Instance *p)
2186 {
2187 /* This function can GC if IN_REDISPLAY is false. */
2167 #ifdef HAVE_WIDGETS 2188 #ifdef HAVE_WIDGETS
2168 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET) 2189 widget_value* wv = 0;
2169 { 2190
2170 widget_value* wv = gui_items_to_widget_values 2191 /* First get the items if they have changed since this is a
2171 (IMAGE_INSTANCE_WIDGET_ITEMS (p)); 2192 structural change. As such it will nuke all added values so we
2172 2193 need to update most other things after the items have changed.*/
2173 /* This seems ugly, but I'm not sure what else to do. */ 2194 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p))
2174 if (EQ (IMAGE_INSTANCE_WIDGET_TYPE (p), Qtab_control)) 2195 {
2196 Lisp_Object image_instance;
2197
2198 XSETIMAGE_INSTANCE (image_instance, p);
2199 wv = gui_items_to_widget_values
2200 (image_instance, IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (p),
2201 /* #### this is not right; we need to keep track of which widgets
2202 want accelerators and which don't */ 0);
2203 wv->change = STRUCTURAL_CHANGE;
2204 }
2205 else
2206 {
2207 /* Assume the lotus position, breath deeply and chant to
2208 yourself lwlibsux, lwlibsux ... lw_get_all_values returns a
2209 reference to the real values rather than a copy thus any
2210 changes we make to the values we get back will look like they
2211 have already been applied. If we rebuild the widget tree then
2212 we may lose propertie. */
2213 wv = copy_widget_value_tree (lw_get_all_values
2214 (IMAGE_INSTANCE_X_WIDGET_LWID (p)),
2215 NO_CHANGE);
2216 }
2217
2218 /* Possibly update the colors and font */
2219 if (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p)
2220 ||
2221 XFRAME (IMAGE_INSTANCE_FRAME (p))->faces_changed
2222 ||
2223 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p))
2224 {
2225 update_widget_face (wv, p, IMAGE_INSTANCE_FRAME (p));
2226 }
2227
2228 /* Possibly update the text. */
2229 if (IMAGE_INSTANCE_TEXT_CHANGED (p))
2230 {
2231 char* str;
2232 Lisp_Object val = IMAGE_INSTANCE_WIDGET_TEXT (p);
2233 LISP_STRING_TO_EXTERNAL (val, str, Qnative);
2234 wv->value = str;
2235 }
2236
2237 /* Possibly update the size. */
2238 if (IMAGE_INSTANCE_SIZE_CHANGED (p)
2239 ||
2240 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)
2241 ||
2242 IMAGE_INSTANCE_TEXT_CHANGED (p))
2243 {
2244 assert (IMAGE_INSTANCE_X_WIDGET_ID (p) &&
2245 IMAGE_INSTANCE_X_CLIPWIDGET (p)) ;
2246
2247 if (IMAGE_INSTANCE_X_WIDGET_ID (p)->core.being_destroyed
2248 || !XtIsManaged(IMAGE_INSTANCE_X_WIDGET_ID (p)))
2175 { 2249 {
2176 update_tab_widget_face (wv, p, 2250 Lisp_Object sw;
2177 IMAGE_INSTANCE_SUBWINDOW_FRAME (p)); 2251 XSETIMAGE_INSTANCE (sw, p);
2252 signal_simple_error ("XEmacs bug: subwindow is deleted", sw);
2178 } 2253 }
2179 /* update the colors and font */ 2254
2180 update_widget_face (wv, p, IMAGE_INSTANCE_SUBWINDOW_FRAME (p)); 2255 lw_add_widget_value_arg (wv, XtNwidth,
2181 2256 (Dimension)IMAGE_INSTANCE_WIDTH (p));
2182 /* now modify the widget */ 2257 lw_add_widget_value_arg (wv, XtNheight,
2183 lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (p), 2258 (Dimension)IMAGE_INSTANCE_HEIGHT (p));
2184 wv, True); 2259 }
2185 free_widget_value_tree (wv); 2260
2186 /* subwindow resizing now gets done by the parent function. */ 2261 /* now modify the widget */
2187 } 2262 lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (p),
2263 wv, True);
2264 free_widget_value_tree (wv);
2188 #endif 2265 #endif
2189 } 2266 }
2190 2267
2191 /* instantiate and x type subwindow */ 2268 /* instantiate and x type subwindow */
2192 static void 2269 static void
2195 int dest_mask, Lisp_Object domain) 2272 int dest_mask, Lisp_Object domain)
2196 { 2273 {
2197 /* This function can GC */ 2274 /* This function can GC */
2198 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 2275 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2199 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); 2276 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
2200 Lisp_Object frame = FW_FRAME (domain); 2277 Lisp_Object frame = DOMAIN_FRAME (domain);
2201 struct frame* f = XFRAME (frame); 2278 struct frame* f = XFRAME (frame);
2202 Display *dpy; 2279 Display *dpy;
2203 Screen *xs; 2280 Screen *xs;
2204 Window pw, win; 2281 Window pw, win;
2205 XSetWindowAttributes xswa; 2282 XSetWindowAttributes xswa;
2206 Mask valueMask = 0; 2283 Mask valueMask = 0;
2207 unsigned int w = IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii), 2284 unsigned int w = IMAGE_INSTANCE_WIDTH (ii),
2208 h = IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii); 2285 h = IMAGE_INSTANCE_HEIGHT (ii);
2209 2286
2210 if (!DEVICE_X_P (XDEVICE (device))) 2287 if (!DEVICE_X_P (XDEVICE (device)))
2211 signal_simple_error ("Not an X device", device); 2288 signal_simple_error ("Not an X device", device);
2212 2289
2213 dpy = DEVICE_X_DISPLAY (XDEVICE (device)); 2290 dpy = DEVICE_X_DISPLAY (XDEVICE (device));
2269 XSTRING_LENGTH (data)); 2346 XSTRING_LENGTH (data));
2270 2347
2271 return property; 2348 return property;
2272 } 2349 }
2273 #endif 2350 #endif
2274
2275 static void
2276 x_resize_subwindow (Lisp_Image_Instance* ii, int w, int h)
2277 {
2278 if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW)
2279 {
2280 XResizeWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (ii),
2281 IMAGE_INSTANCE_X_SUBWINDOW_ID (ii),
2282 w, h);
2283 }
2284 else /* must be a widget */
2285 {
2286 Arg al[2];
2287
2288 if ( !XtIsManaged(IMAGE_INSTANCE_X_WIDGET_ID (ii))
2289 ||
2290 IMAGE_INSTANCE_X_WIDGET_ID (ii)->core.being_destroyed )
2291 {
2292 Lisp_Object sw;
2293 XSETIMAGE_INSTANCE (sw, ii);
2294 signal_simple_error ("XEmacs bug: subwindow is deleted", sw);
2295 }
2296
2297 XtSetArg (al [0], XtNwidth, (Dimension)w);
2298 XtSetArg (al [1], XtNheight, (Dimension)h);
2299 XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, 2);
2300 }
2301 }
2302 2351
2303 2352
2304 #ifdef HAVE_WIDGETS 2353 #ifdef HAVE_WIDGETS
2305 2354
2306 /************************************************************************/ 2355 /************************************************************************/
2340 (wv, XtNfont, (XtArgVal)FONT_INSTANCE_X_FONT 2389 (wv, XtNfont, (XtArgVal)FONT_INSTANCE_X_FONT
2341 (XFONT_INSTANCE (query_string_font 2390 (XFONT_INSTANCE (query_string_font
2342 (IMAGE_INSTANCE_WIDGET_TEXT (ii), 2391 (IMAGE_INSTANCE_WIDGET_TEXT (ii),
2343 IMAGE_INSTANCE_WIDGET_FACE (ii), 2392 IMAGE_INSTANCE_WIDGET_FACE (ii),
2344 domain)))); 2393 domain))));
2394 wv->change = VISIBLE_CHANGE;
2395 /* #### Megahack - but its just getting too complicated to do this
2396 in the right place. */
2397 if (EQ (IMAGE_INSTANCE_WIDGET_TYPE (ii), Qtab_control))
2398 update_tab_widget_face (wv, ii, domain);
2345 } 2399 }
2346 2400
2347 static void 2401 static void
2348 update_tab_widget_face (widget_value* wv, Lisp_Image_Instance *ii, 2402 update_tab_widget_face (widget_value* wv, Lisp_Image_Instance *ii,
2349 Lisp_Object domain) 2403 Lisp_Object domain)
2356 Lisp_Object pixel = FACE_FOREGROUND 2410 Lisp_Object pixel = FACE_FOREGROUND
2357 (IMAGE_INSTANCE_WIDGET_FACE (ii), 2411 (IMAGE_INSTANCE_WIDGET_FACE (ii),
2358 domain); 2412 domain);
2359 XColor fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); 2413 XColor fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel));
2360 lw_add_widget_value_arg (val, XtNtabForeground, fcolor.pixel); 2414 lw_add_widget_value_arg (val, XtNtabForeground, fcolor.pixel);
2415 wv->change = VISIBLE_CHANGE;
2416 val->change = VISIBLE_CHANGE;
2361 2417
2362 for (cur = val->next; cur; cur = cur->next) 2418 for (cur = val->next; cur; cur = cur->next)
2363 { 2419 {
2420 cur->change = VISIBLE_CHANGE;
2364 if (cur->value) 2421 if (cur->value)
2365 { 2422 {
2366 lw_copy_widget_value_args (val, cur); 2423 lw_copy_widget_value_args (val, cur);
2367 } 2424 }
2368 } 2425 }
2371 2428
2372 static void 2429 static void
2373 x_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, 2430 x_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2374 Lisp_Object pointer_fg, Lisp_Object pointer_bg, 2431 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2375 int dest_mask, Lisp_Object domain, 2432 int dest_mask, Lisp_Object domain,
2376 CONST char* type, widget_value* wv) 2433 const char* type, widget_value* wv)
2377 { 2434 {
2378 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 2435 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2379 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), pixel; 2436 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), pixel;
2380 struct device* d = XDEVICE (device); 2437 struct device* d = XDEVICE (device);
2381 Lisp_Object frame = FW_FRAME (domain); 2438 Lisp_Object frame = DOMAIN_FRAME (domain);
2382 struct frame* f = XFRAME (frame); 2439 struct frame* f = XFRAME (frame);
2383 char* nm=0; 2440 char* nm=0;
2384 Widget wid; 2441 Widget wid;
2385 Arg al [32]; 2442 Arg al [32];
2386 int ac = 0; 2443 int ac = 0;
2395 instantiation for a widget. But we can go ahead and do it without 2452 instantiation for a widget. But we can go ahead and do it without
2396 checking because there is always a generic instantiator. */ 2453 checking because there is always a generic instantiator. */
2397 IMAGE_INSTANCE_TYPE (ii) = IMAGE_WIDGET; 2454 IMAGE_INSTANCE_TYPE (ii) = IMAGE_WIDGET;
2398 2455
2399 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii))) 2456 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
2400 TO_EXTERNAL_FORMAT (LISP_STRING, IMAGE_INSTANCE_WIDGET_TEXT (ii), 2457 LISP_STRING_TO_EXTERNAL (IMAGE_INSTANCE_WIDGET_TEXT (ii), nm, Qnative);
2401 C_STRING_ALLOCA, nm,
2402 Qnative);
2403 2458
2404 ii->data = xnew_and_zero (struct x_subwindow_data); 2459 ii->data = xnew_and_zero (struct x_subwindow_data);
2405 2460
2406 /* Create a clip window to contain the subwidget. Incredibly the 2461 /* Create a clip window to contain the subwidget. Incredibly the
2407 XEmacs manager seems to be the most appropriate widget for 2462 XEmacs manager seems to be the most appropriate widget for
2409 required. */ 2464 required. */
2410 clip_wv = xmalloc_widget_value (); 2465 clip_wv = xmalloc_widget_value ();
2411 2466
2412 lw_add_widget_value_arg (clip_wv, XtNresize, False); 2467 lw_add_widget_value_arg (clip_wv, XtNresize, False);
2413 lw_add_widget_value_arg (clip_wv, XtNwidth, 2468 lw_add_widget_value_arg (clip_wv, XtNwidth,
2414 (Dimension)IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii)); 2469 (Dimension)IMAGE_INSTANCE_WIDTH (ii));
2415 lw_add_widget_value_arg (clip_wv, XtNheight, 2470 lw_add_widget_value_arg (clip_wv, XtNheight,
2416 (Dimension)IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); 2471 (Dimension)IMAGE_INSTANCE_HEIGHT (ii));
2417 clip_wv->enabled = True; 2472 clip_wv->enabled = True;
2418 2473
2419 clip_wv->name = xstrdup ("clip-window"); 2474 clip_wv->name = xstrdup ("clip-window");
2420 clip_wv->value = xstrdup ("clip-window"); 2475 clip_wv->value = xstrdup ("clip-window");
2421 2476
2434 created so that Motif will fix up the shadow colors 2489 created so that Motif will fix up the shadow colors
2435 correctly. Once the widget is created Motif won't do this 2490 correctly. Once the widget is created Motif won't do this
2436 anymore...*/ 2491 anymore...*/
2437 pixel = FACE_FOREGROUND 2492 pixel = FACE_FOREGROUND
2438 (IMAGE_INSTANCE_WIDGET_FACE (ii), 2493 (IMAGE_INSTANCE_WIDGET_FACE (ii),
2439 IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); 2494 IMAGE_INSTANCE_FRAME (ii));
2440 fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); 2495 fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel));
2441 2496
2442 pixel = FACE_BACKGROUND 2497 pixel = FACE_BACKGROUND
2443 (IMAGE_INSTANCE_WIDGET_FACE (ii), 2498 (IMAGE_INSTANCE_WIDGET_FACE (ii),
2444 IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); 2499 IMAGE_INSTANCE_FRAME (ii));
2445 bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); 2500 bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel));
2446 2501
2447 lw_add_widget_value_arg (wv, XtNbackground, bcolor.pixel); 2502 lw_add_widget_value_arg (wv, XtNbackground, bcolor.pixel);
2448 lw_add_widget_value_arg (wv, XtNforeground, fcolor.pixel); 2503 lw_add_widget_value_arg (wv, XtNforeground, fcolor.pixel);
2449 /* we cannot allow widgets to resize themselves */ 2504 /* we cannot allow widgets to resize themselves */
2450 lw_add_widget_value_arg (wv, XtNresize, False); 2505 lw_add_widget_value_arg (wv, XtNresize, False);
2451 lw_add_widget_value_arg (wv, XtNwidth, 2506 lw_add_widget_value_arg (wv, XtNwidth,
2452 (Dimension)IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii)); 2507 (Dimension)IMAGE_INSTANCE_WIDTH (ii));
2453 lw_add_widget_value_arg (wv, XtNheight, 2508 lw_add_widget_value_arg (wv, XtNheight,
2454 (Dimension)IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); 2509 (Dimension)IMAGE_INSTANCE_HEIGHT (ii));
2455 /* update the font. */ 2510 /* update the font. */
2456 update_widget_face (wv, ii, domain); 2511 update_widget_face (wv, ii, domain);
2457 2512
2458 wid = lw_create_widget (type, wv->name, id, wv, IMAGE_INSTANCE_X_CLIPWIDGET (ii), 2513 wid = lw_create_widget (type, wv->name, id, wv, IMAGE_INSTANCE_X_CLIPWIDGET (ii),
2459 False, 0, popup_selection_callback, 0); 2514 False, 0, popup_selection_callback, 0);
2460 2515
2461 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void*)wid; 2516 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void*)wid;
2462 IMAGE_INSTANCE_X_WIDGET_LWID (ii) = id; 2517 IMAGE_INSTANCE_X_WIDGET_LWID (ii) = id;
2463
2464 /* Resize the widget here so that the values do not get copied by
2465 lwlib. */
2466 ac = 0;
2467 XtSetArg (al [ac], XtNwidth,
2468 (Dimension)IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii)); ac++;
2469 XtSetArg (al [ac], XtNheight,
2470 (Dimension)IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); ac++;
2471 XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, ac);
2472 /* because the EmacsManager is the widgets parent we have to 2518 /* because the EmacsManager is the widgets parent we have to
2473 offset the redisplay of the widget by the amount the text 2519 offset the redisplay of the widget by the amount the text
2474 widget is inside the manager. */ 2520 widget is inside the manager. */
2475 ac = 0; 2521 ac = 0;
2476 XtSetArg (al [ac], XtNx, &IMAGE_INSTANCE_X_WIDGET_XOFFSET (ii)); ac++; 2522 XtSetArg (al [ac], XtNx, &IMAGE_INSTANCE_X_WIDGET_XOFFSET (ii)); ac++;
2478 XtGetValues (FRAME_X_TEXT_WIDGET (f), al, ac); 2524 XtGetValues (FRAME_X_TEXT_WIDGET (f), al, ac);
2479 2525
2480 XtSetMappedWhenManaged (wid, TRUE); 2526 XtSetMappedWhenManaged (wid, TRUE);
2481 2527
2482 free_widget_value_tree (wv); 2528 free_widget_value_tree (wv);
2483 } 2529 /* A kludgy but simple way to make sure the callback for a widget
2484 2530 doesn't get deleted. */
2485 static Lisp_Object 2531 gcpro_popup_callbacks (id);
2486 x_widget_set_property (Lisp_Object image_instance, Lisp_Object prop,
2487 Lisp_Object val)
2488 {
2489 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2490
2491 /* Modify the text properties of the widget */
2492 if (EQ (prop, Q_text))
2493 {
2494 char* str;
2495 widget_value* wv = lw_get_all_values (IMAGE_INSTANCE_X_WIDGET_LWID (ii));
2496 CHECK_STRING (val);
2497 TO_EXTERNAL_FORMAT (LISP_STRING, val,
2498 C_STRING_ALLOCA, str,
2499 Qnative);
2500 wv->value = str;
2501 lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (ii), wv, False);
2502 }
2503
2504 /* Modify the text properties of the widget */
2505 else if (EQ (prop, Q_face))
2506 {
2507 widget_value* wv = lw_get_all_values (IMAGE_INSTANCE_X_WIDGET_LWID (ii));
2508 update_widget_face (wv, ii, IMAGE_INSTANCE_SUBWINDOW_FRAME (ii));
2509 lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (ii), wv, False);
2510 }
2511 return Qunbound;
2512 } 2532 }
2513 2533
2514 /* get properties of a control */ 2534 /* get properties of a control */
2515 static Lisp_Object 2535 static Lisp_Object
2516 x_widget_property (Lisp_Object image_instance, Lisp_Object prop) 2536 x_widget_property (Lisp_Object image_instance, Lisp_Object prop)
2521 { 2541 {
2522 widget_value* wv = lw_get_all_values (IMAGE_INSTANCE_X_WIDGET_LWID (ii)); 2542 widget_value* wv = lw_get_all_values (IMAGE_INSTANCE_X_WIDGET_LWID (ii));
2523 return build_ext_string (wv->value, Qnative); 2543 return build_ext_string (wv->value, Qnative);
2524 } 2544 }
2525 return Qunbound; 2545 return Qunbound;
2546 }
2547
2548 /* Instantiate a layout control for putting other widgets in. */
2549 static void
2550 x_native_layout_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2551 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2552 int dest_mask, Lisp_Object domain)
2553 {
2554 x_widget_instantiate (image_instance, instantiator, pointer_fg,
2555 pointer_bg, dest_mask, domain, "layout", 0);
2526 } 2556 }
2527 2557
2528 /* Instantiate a button widget. Unfortunately instantiated widgets are 2558 /* Instantiate a button widget. Unfortunately instantiated widgets are
2529 particular to a frame since they need to have a parent. It's not 2559 particular to a frame since they need to have a parent. It's not
2530 like images where you just select the image into the context you 2560 like images where you just select the image into the context you
2537 int dest_mask, Lisp_Object domain) 2567 int dest_mask, Lisp_Object domain)
2538 { 2568 {
2539 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 2569 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2540 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); 2570 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
2541 Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image); 2571 Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image);
2542 widget_value* wv = xmalloc_widget_value (); 2572 widget_value* wv = gui_items_to_widget_values (image_instance, gui, 1);
2543
2544 button_item_to_widget_value (gui, wv, 1, 1);
2545 2573
2546 if (!NILP (glyph)) 2574 if (!NILP (glyph))
2547 { 2575 {
2548 if (!IMAGE_INSTANCEP (glyph)) 2576 if (!IMAGE_INSTANCEP (glyph))
2549 glyph = glyph_image_instance (glyph, domain, ERROR_ME, 1); 2577 glyph = glyph_image_instance (glyph, domain, ERROR_ME, 1);
2566 #endif 2594 #endif
2567 XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, ac); 2595 XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, ac);
2568 } 2596 }
2569 } 2597 }
2570 2598
2599 /* Update a button's clicked state.
2600
2601 #### This is overkill, but it works. Right now this causes all
2602 button instances to flash for some reason buried deep in lwlib. In
2603 theory this should be the Right Thing to do since lwlib should only
2604 merge in changed values - and if nothing has changed then nothing
2605 should get done. This may be because of the args stuff,
2606 i.e. although the arg contents may be the same the args look
2607 different and so are re-applied to the widget. */
2608 static void
2609 x_button_redisplay (Lisp_Object image_instance)
2610 {
2611 /* This function can GC if IN_REDISPLAY is false. */
2612 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
2613 widget_value* wv =
2614 gui_items_to_widget_values (image_instance,
2615 IMAGE_INSTANCE_WIDGET_ITEMS (p), 1);
2616
2617 /* now modify the widget */
2618 lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (p),
2619 wv, True);
2620 free_widget_value_tree (wv);
2621 }
2622
2571 /* get properties of a button */ 2623 /* get properties of a button */
2572 static Lisp_Object 2624 static Lisp_Object
2573 x_button_property (Lisp_Object image_instance, Lisp_Object prop) 2625 x_button_property (Lisp_Object image_instance, Lisp_Object prop)
2574 { 2626 {
2575 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 2627 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2592 Lisp_Object pointer_fg, Lisp_Object pointer_bg, 2644 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2593 int dest_mask, Lisp_Object domain) 2645 int dest_mask, Lisp_Object domain)
2594 { 2646 {
2595 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 2647 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2596 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); 2648 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
2597 widget_value* wv = xmalloc_widget_value (); 2649 widget_value* wv = gui_items_to_widget_values (image_instance, gui, 0);
2598
2599 button_item_to_widget_value (gui, wv, 1, 1);
2600 2650
2601 x_widget_instantiate (image_instance, instantiator, pointer_fg, 2651 x_widget_instantiate (image_instance, instantiator, pointer_fg,
2602 pointer_bg, dest_mask, domain, "progress", wv); 2652 pointer_bg, dest_mask, domain, "progress", wv);
2603 } 2653 }
2604 2654
2605 /* set the properties of a progres guage */ 2655 /* set the properties of a progress gauge */
2606 static Lisp_Object 2656 static void
2607 x_progress_gauge_set_property (Lisp_Object image_instance, Lisp_Object prop, 2657 x_progress_gauge_redisplay (Lisp_Object image_instance)
2608 Lisp_Object val)
2609 { 2658 {
2610 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 2659 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2611 2660
2612 if (EQ (prop, Q_percent)) 2661 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii))
2613 { 2662 {
2614 Arg al [1]; 2663 Arg al [1];
2615 CHECK_INT (val); 2664 Lisp_Object val;
2665 #ifdef ERROR_CHECK_GLYPHS
2666 assert (GUI_ITEMP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)));
2667 #endif
2668 val = XGUI_ITEM (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))->value;
2616 XtSetArg (al[0], XtNvalue, XINT (val)); 2669 XtSetArg (al[0], XtNvalue, XINT (val));
2617 XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, 1); 2670 XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, 1);
2618 return Qt; 2671 }
2619 }
2620 return Qunbound;
2621 } 2672 }
2622 2673
2623 /* instantiate an edit control */ 2674 /* instantiate an edit control */
2624 static void 2675 static void
2625 x_edit_field_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, 2676 x_edit_field_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2626 Lisp_Object pointer_fg, Lisp_Object pointer_bg, 2677 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2627 int dest_mask, Lisp_Object domain) 2678 int dest_mask, Lisp_Object domain)
2628 { 2679 {
2629 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 2680 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2630 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); 2681 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
2631 widget_value* wv = xmalloc_widget_value (); 2682 widget_value* wv = gui_items_to_widget_values (image_instance, gui, 0);
2632
2633 button_item_to_widget_value (gui, wv, 1, 1);
2634 2683
2635 x_widget_instantiate (image_instance, instantiator, pointer_fg, 2684 x_widget_instantiate (image_instance, instantiator, pointer_fg,
2636 pointer_bg, dest_mask, domain, "text-field", wv); 2685 pointer_bg, dest_mask, domain, "text-field", wv);
2637 } 2686 }
2638 2687
2648 /* This is not done generically because of sizing problems under 2697 /* This is not done generically because of sizing problems under
2649 mswindows. */ 2698 mswindows. */
2650 widget_instantiate (image_instance, instantiator, pointer_fg, 2699 widget_instantiate (image_instance, instantiator, pointer_fg,
2651 pointer_bg, dest_mask, domain); 2700 pointer_bg, dest_mask, domain);
2652 2701
2653 wv = gui_items_to_widget_values (IMAGE_INSTANCE_WIDGET_ITEMS (ii)); 2702 wv = gui_items_to_widget_values (image_instance,
2703 IMAGE_INSTANCE_WIDGET_ITEMS (ii), 0);
2654 2704
2655 x_widget_instantiate (image_instance, instantiator, pointer_fg, 2705 x_widget_instantiate (image_instance, instantiator, pointer_fg,
2656 pointer_bg, dest_mask, domain, "combo-box", wv); 2706 pointer_bg, dest_mask, domain, "combo-box", wv);
2657 } 2707 }
2658 #endif 2708 #endif
2662 Lisp_Object pointer_fg, Lisp_Object pointer_bg, 2712 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2663 int dest_mask, Lisp_Object domain) 2713 int dest_mask, Lisp_Object domain)
2664 { 2714 {
2665 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 2715 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2666 widget_value * wv = 2716 widget_value * wv =
2667 gui_items_to_widget_values (IMAGE_INSTANCE_WIDGET_ITEMS (ii)); 2717 gui_items_to_widget_values (image_instance,
2668 2718 IMAGE_INSTANCE_WIDGET_ITEMS (ii), 0);
2669 update_tab_widget_face (wv, ii, 2719 update_tab_widget_face (wv, ii,
2670 IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); 2720 IMAGE_INSTANCE_FRAME (ii));
2671
2672 x_widget_instantiate (image_instance, instantiator, pointer_fg, 2721 x_widget_instantiate (image_instance, instantiator, pointer_fg,
2673 pointer_bg, dest_mask, domain, "tab-control", wv); 2722 pointer_bg, dest_mask, domain, "tab-control", wv);
2674 } 2723 }
2675 2724
2676 /* set the properties of a tab control */ 2725 /* Set the properties of a tab control */
2677 static Lisp_Object 2726 static void
2678 x_tab_control_set_property (Lisp_Object image_instance, Lisp_Object prop, 2727 x_tab_control_redisplay (Lisp_Object image_instance)
2679 Lisp_Object val)
2680 { 2728 {
2681 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 2729 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2682 2730
2683 if (EQ (prop, Q_items)) 2731 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)
2684 { 2732 ||
2685 widget_value * wv = 0; 2733 IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (ii))
2686 check_valid_item_list_1 (val); 2734 {
2687 2735 /* If only the order has changed then simply select the first
2688 IMAGE_INSTANCE_WIDGET_ITEMS (ii) = 2736 one of the pending set. This stops horrendous rebuilding -
2689 Fcons (XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)), 2737 and hence flicker - of the tabs each time you click on
2690 parse_gui_item_tree_children (val)); 2738 one. */
2691 2739 if (tab_control_order_only_changed (image_instance))
2692 wv = gui_items_to_widget_values (IMAGE_INSTANCE_WIDGET_ITEMS (ii)); 2740 {
2741 Lisp_Object rest, selected =
2742 gui_item_list_find_selected
2743 (NILP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)) ?
2744 XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)) :
2745 XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)));
2746
2747 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
2748 {
2749 if (gui_item_equal_sans_selected (XCAR (rest), selected, 0))
2750 {
2751 /* There may be an encapsulated way of doing this,
2752 but I couldn't find it. */
2753 Lisp_Object old_selected =gui_item_list_find_selected
2754 (XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)));
2755 Arg al [1];
2756 char* name;
2757 unsigned int num_children, i;
2758 Widget* children;
2759
2760 LISP_STRING_TO_EXTERNAL (XGUI_ITEM (XCAR (rest))->name,
2761 name, Qnative);
2762 /* The name may contain a `.' which confuses
2763 XtNameToWidget, so we do it ourselves. */
2764 children = XtCompositeChildren (IMAGE_INSTANCE_X_WIDGET_ID (ii),
2765 &num_children);
2766 for (i = 0; i < num_children; i++)
2767 {
2768 if (!strcmp (XtName (children [i]), name))
2769 {
2770 XtSetArg (al [0], XtNtopWidget, children [i]);
2771 XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, 1);
2772 break;
2773 }
2774 }
2775 /* Pick up the new selected item. */
2776 XGUI_ITEM (old_selected)->selected =
2777 XGUI_ITEM (XCAR (rest))->selected;
2778 XGUI_ITEM (XCAR (rest))->selected =
2779 XGUI_ITEM (selected)->selected;
2780 /* We're not actually changing the items anymore. */
2781 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0;
2782 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil;
2783 break;
2784 }
2785 }
2786 }
2787 }
2788 /* Possibly update the face. */
2789 if (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii)
2790 ||
2791 XFRAME (IMAGE_INSTANCE_FRAME (ii))->faces_changed
2792 ||
2793 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii))
2794 {
2795 /* See previous comments on the brokeness of lwlib.
2796
2797 #### There's actually not much point in doing this here
2798 since, colors will have been set appropriately by
2799 x_redisplay_widget. */
2800 widget_value* wv =copy_widget_value_tree
2801 (lw_get_all_values
2802 (IMAGE_INSTANCE_X_WIDGET_LWID (ii)),
2803 NO_CHANGE);
2693 2804
2694 update_tab_widget_face (wv, ii, 2805 update_tab_widget_face (wv, ii,
2695 IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); 2806 IMAGE_INSTANCE_FRAME (ii));
2696 2807
2697 lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (ii), wv, True); 2808 lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (ii), wv, True);
2698
2699 free_widget_value_tree (wv); 2809 free_widget_value_tree (wv);
2700 return Qt; 2810 }
2701 }
2702
2703 return Qunbound;
2704 } 2811 }
2705 2812
2706 /* instantiate a static control possible for putting other things in */ 2813 /* instantiate a static control possible for putting other things in */
2707 static void 2814 static void
2708 x_label_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, 2815 x_label_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
2709 Lisp_Object pointer_fg, Lisp_Object pointer_bg, 2816 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
2710 int dest_mask, Lisp_Object domain) 2817 int dest_mask, Lisp_Object domain)
2711 { 2818 {
2712 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 2819 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2713 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); 2820 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
2714 widget_value* wv = xmalloc_widget_value (); 2821 widget_value* wv = gui_items_to_widget_values (image_instance, gui, 0);
2715
2716 button_item_to_widget_value (gui, wv, 1, 1);
2717 2822
2718 x_widget_instantiate (image_instance, instantiator, pointer_fg, 2823 x_widget_instantiate (image_instance, instantiator, pointer_fg,
2719 pointer_bg, dest_mask, domain, "button", wv); 2824 pointer_bg, dest_mask, domain, "button", wv);
2720 } 2825 }
2721 #endif /* HAVE_WIDGETS */ 2826 #endif /* HAVE_WIDGETS */
2745 CONSOLE_HAS_METHOD (x, colorize_image_instance); 2850 CONSOLE_HAS_METHOD (x, colorize_image_instance);
2746 CONSOLE_HAS_METHOD (x, init_image_instance_from_eimage); 2851 CONSOLE_HAS_METHOD (x, init_image_instance_from_eimage);
2747 CONSOLE_HAS_METHOD (x, locate_pixmap_file); 2852 CONSOLE_HAS_METHOD (x, locate_pixmap_file);
2748 CONSOLE_HAS_METHOD (x, unmap_subwindow); 2853 CONSOLE_HAS_METHOD (x, unmap_subwindow);
2749 CONSOLE_HAS_METHOD (x, map_subwindow); 2854 CONSOLE_HAS_METHOD (x, map_subwindow);
2750 CONSOLE_HAS_METHOD (x, resize_subwindow); 2855 CONSOLE_HAS_METHOD (x, redisplay_widget);
2751 CONSOLE_HAS_METHOD (x, update_subwindow); 2856 CONSOLE_HAS_METHOD (x, redisplay_subwindow);
2752 } 2857 }
2753 2858
2754 void 2859 void
2755 image_instantiator_format_create_glyphs_x (void) 2860 image_instantiator_format_create_glyphs_x (void)
2756 { 2861 {
2757 IIFORMAT_VALID_CONSOLE (x, nothing); 2862 IIFORMAT_VALID_CONSOLE (x, nothing);
2758 IIFORMAT_VALID_CONSOLE (x, string); 2863 IIFORMAT_VALID_CONSOLE (x, string);
2864 #ifdef HAVE_WIDGETS
2759 IIFORMAT_VALID_CONSOLE (x, layout); 2865 IIFORMAT_VALID_CONSOLE (x, layout);
2866 #endif
2760 IIFORMAT_VALID_CONSOLE (x, formatted_string); 2867 IIFORMAT_VALID_CONSOLE (x, formatted_string);
2761 IIFORMAT_VALID_CONSOLE (x, inherit); 2868 IIFORMAT_VALID_CONSOLE (x, inherit);
2762 #ifdef HAVE_XPM 2869 #ifdef HAVE_XPM
2763 INITIALIZE_DEVICE_IIFORMAT (x, xpm); 2870 INITIALIZE_DEVICE_IIFORMAT (x, xpm);
2764 IIFORMAT_HAS_DEVMETHOD (x, xpm, instantiate); 2871 IIFORMAT_HAS_DEVMETHOD (x, xpm, instantiate);
2779 IIFORMAT_HAS_DEVMETHOD (x, xbm, instantiate); 2886 IIFORMAT_HAS_DEVMETHOD (x, xbm, instantiate);
2780 2887
2781 INITIALIZE_DEVICE_IIFORMAT (x, subwindow); 2888 INITIALIZE_DEVICE_IIFORMAT (x, subwindow);
2782 IIFORMAT_HAS_DEVMETHOD (x, subwindow, instantiate); 2889 IIFORMAT_HAS_DEVMETHOD (x, subwindow, instantiate);
2783 #ifdef HAVE_WIDGETS 2890 #ifdef HAVE_WIDGETS
2891 /* layout widget */
2892 INITIALIZE_DEVICE_IIFORMAT (x, native_layout);
2893 IIFORMAT_HAS_DEVMETHOD (x, native_layout, instantiate);
2784 /* button widget */ 2894 /* button widget */
2785 INITIALIZE_DEVICE_IIFORMAT (x, button); 2895 INITIALIZE_DEVICE_IIFORMAT (x, button);
2786 IIFORMAT_HAS_DEVMETHOD (x, button, property); 2896 IIFORMAT_HAS_DEVMETHOD (x, button, property);
2787 IIFORMAT_HAS_DEVMETHOD (x, button, instantiate); 2897 IIFORMAT_HAS_DEVMETHOD (x, button, instantiate);
2788 2898 IIFORMAT_HAS_DEVMETHOD (x, button, redisplay);
2899 /* general widget methods. */
2789 INITIALIZE_DEVICE_IIFORMAT (x, widget); 2900 INITIALIZE_DEVICE_IIFORMAT (x, widget);
2790 IIFORMAT_HAS_DEVMETHOD (x, widget, property); 2901 IIFORMAT_HAS_DEVMETHOD (x, widget, property);
2791 IIFORMAT_HAS_DEVMETHOD (x, widget, set_property);
2792 /* progress gauge */ 2902 /* progress gauge */
2793 INITIALIZE_DEVICE_IIFORMAT (x, progress_gauge); 2903 INITIALIZE_DEVICE_IIFORMAT (x, progress_gauge);
2794 IIFORMAT_HAS_DEVMETHOD (x, progress_gauge, set_property); 2904 IIFORMAT_HAS_DEVMETHOD (x, progress_gauge, redisplay);
2795 IIFORMAT_HAS_DEVMETHOD (x, progress_gauge, instantiate); 2905 IIFORMAT_HAS_DEVMETHOD (x, progress_gauge, instantiate);
2796 /* text field */ 2906 /* text field */
2797 INITIALIZE_DEVICE_IIFORMAT (x, edit_field); 2907 INITIALIZE_DEVICE_IIFORMAT (x, edit_field);
2798 IIFORMAT_HAS_DEVMETHOD (x, edit_field, instantiate); 2908 IIFORMAT_HAS_DEVMETHOD (x, edit_field, instantiate);
2799 #if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1 2909 #if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1
2800 /* combo box */ 2910 /* combo box */
2801 INITIALIZE_DEVICE_IIFORMAT (x, combo_box); 2911 INITIALIZE_DEVICE_IIFORMAT (x, combo_box);
2802 IIFORMAT_HAS_DEVMETHOD (x, combo_box, instantiate); 2912 IIFORMAT_HAS_DEVMETHOD (x, combo_box, instantiate);
2803 IIFORMAT_HAS_SHARED_DEVMETHOD (x, combo_box, set_property, tab_control); 2913 IIFORMAT_HAS_SHARED_DEVMETHOD (x, combo_box, redisplay, tab_control);
2804 #endif 2914 #endif
2805 /* tab control widget */ 2915 /* tab control widget */
2806 INITIALIZE_DEVICE_IIFORMAT (x, tab_control); 2916 INITIALIZE_DEVICE_IIFORMAT (x, tab_control);
2807 IIFORMAT_HAS_DEVMETHOD (x, tab_control, instantiate); 2917 IIFORMAT_HAS_DEVMETHOD (x, tab_control, instantiate);
2808 IIFORMAT_HAS_DEVMETHOD (x, tab_control, set_property); 2918 IIFORMAT_HAS_DEVMETHOD (x, tab_control, redisplay);
2809 /* label */ 2919 /* label */
2810 INITIALIZE_DEVICE_IIFORMAT (x, label); 2920 INITIALIZE_DEVICE_IIFORMAT (x, label);
2811 IIFORMAT_HAS_DEVMETHOD (x, label, instantiate); 2921 IIFORMAT_HAS_DEVMETHOD (x, label, instantiate);
2812 #endif 2922 #endif
2813 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (cursor_font, "cursor-font"); 2923 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (cursor_font, "cursor-font");