X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fglyphs-x.c;h=2b6d35079a9af726a3d35a5497c45f7430b26a86;hb=76759ab036458c54499a454399e19602b8ae6ce3;hp=6124be40898ad836779f6fcbb0a7c63b4e493fd9;hpb=a7bf8d60d66c38f62928b171842d1b45d4539077;p=chise%2Fxemacs-chise.git.1 diff --git a/src/glyphs-x.c b/src/glyphs-x.c index 6124be4..2b6d350 100644 --- a/src/glyphs-x.c +++ b/src/glyphs-x.c @@ -98,7 +98,6 @@ DECLARE_IMAGE_INSTANTIATOR_FORMAT (nothing); DECLARE_IMAGE_INSTANTIATOR_FORMAT (string); DECLARE_IMAGE_INSTANTIATOR_FORMAT (formatted_string); DECLARE_IMAGE_INSTANTIATOR_FORMAT (inherit); -DECLARE_IMAGE_INSTANTIATOR_FORMAT (layout); #ifdef HAVE_JPEG DECLARE_IMAGE_INSTANTIATOR_FORMAT (jpeg); #endif @@ -128,7 +127,9 @@ DEFINE_IMAGE_INSTANTIATOR_FORMAT (font); DEFINE_IMAGE_INSTANTIATOR_FORMAT (autodetect); #ifdef HAVE_WIDGETS +DECLARE_IMAGE_INSTANTIATOR_FORMAT (layout); DEFINE_DEVICE_IIFORMAT (x, widget); +DEFINE_DEVICE_IIFORMAT (x, native_layout); DEFINE_DEVICE_IIFORMAT (x, button); DEFINE_DEVICE_IIFORMAT (x, progress_gauge); DEFINE_DEVICE_IIFORMAT (x, edit_field); @@ -264,7 +265,7 @@ convert_EImage_to_XImage (Lisp_Object device, int width, int height, gr = *ip++; bl = *ip++; conv.val = pixarray[QUANT_GET_COLOR(qtable,rd,gr,bl)]; -#if WORDS_BIGENDIAN +#ifdef WORDS_BIGENDIAN if (outimg->byte_order == MSBFirst) for (q = 4-byte_cnt; q < 4; q++) *dp++ = conv.cp[q]; else @@ -339,7 +340,7 @@ convert_EImage_to_XImage (Lisp_Object device, int width, int height, bl = *ip++ >> (8 - bbits); conv.val = (rd << rshift) | (gr << gshift) | (bl << bshift); -#if WORDS_BIGENDIAN +#ifdef WORDS_BIGENDIAN if (outimg->byte_order == MSBFirst) for (q = 4-byte_cnt; q < 4; q++) *dp++ = conv.cp[q]; else @@ -394,11 +395,14 @@ x_finalize_image_instance (Lisp_Image_Instance *p) if (!p->data) return; - if (DEVICE_LIVE_P (XDEVICE (p->device))) + if (DEVICE_LIVE_P (XDEVICE (IMAGE_INSTANCE_DEVICE (p)))) { - Display *dpy = DEVICE_X_DISPLAY (XDEVICE (p->device)); - - if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET) + Display *dpy = DEVICE_X_DISPLAY + (XDEVICE (IMAGE_INSTANCE_DEVICE (p))); + if (0) + ; +#ifdef HAVE_WIDGETS + else if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET) { if (IMAGE_INSTANCE_SUBWINDOW_ID (p)) { @@ -408,10 +412,15 @@ x_finalize_image_instance (Lisp_Image_Instance *p) #endif lw_destroy_widget (IMAGE_INSTANCE_X_WIDGET_ID (p)); lw_destroy_widget (IMAGE_INSTANCE_X_CLIPWIDGET (p)); + + /* We can release the callbacks again. */ + ungcpro_popup_callbacks (IMAGE_INSTANCE_X_WIDGET_LWID (p)); + IMAGE_INSTANCE_X_WIDGET_ID (p) = 0; IMAGE_INSTANCE_X_CLIPWIDGET (p) = 0; } } +#endif else if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW) { if (IMAGE_INSTANCE_SUBWINDOW_ID (p)) @@ -2189,8 +2198,11 @@ x_update_widget (Lisp_Image_Instance *p) need to update most other things after the items have changed.*/ if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)) { + Lisp_Object image_instance; + + XSETIMAGE_INSTANCE (image_instance, p); wv = gui_items_to_widget_values - (IMAGE_INSTANCE_WIDGET_ITEMS (p)); + (image_instance, IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (p)); wv->change = STRUCTURAL_CHANGE; /* now modify the widget */ lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (p), @@ -2201,14 +2213,17 @@ x_update_widget (Lisp_Image_Instance *p) /* Now do non structural updates. */ wv = lw_get_all_values (IMAGE_INSTANCE_X_WIDGET_LWID (p)); + if (!wv) + return; + /* Possibly update the colors and font */ - if (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p) + if (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p) || - XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (p))->faces_changed + XFRAME (IMAGE_INSTANCE_FRAME (p))->faces_changed || IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)) { - update_widget_face (wv, p, IMAGE_INSTANCE_SUBWINDOW_FRAME (p)); + update_widget_face (wv, p, IMAGE_INSTANCE_FRAME (p)); } /* Possibly update the text. */ @@ -2225,7 +2240,9 @@ x_update_widget (Lisp_Image_Instance *p) /* Possibly update the size. */ if (IMAGE_INSTANCE_SIZE_CHANGED (p) || - IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)) + IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p) + || + IMAGE_INSTANCE_TEXT_CHANGED (p)) { assert (IMAGE_INSTANCE_X_WIDGET_ID (p) && IMAGE_INSTANCE_X_CLIPWIDGET (p)) ; @@ -2259,15 +2276,15 @@ x_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, /* This function can GC */ Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); - Lisp_Object frame = FW_FRAME (domain); + Lisp_Object frame = DOMAIN_FRAME (domain); struct frame* f = XFRAME (frame); Display *dpy; Screen *xs; Window pw, win; XSetWindowAttributes xswa; Mask valueMask = 0; - unsigned int w = IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii), - h = IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii); + unsigned int w = IMAGE_INSTANCE_WIDTH (ii), + h = IMAGE_INSTANCE_HEIGHT (ii); if (!DEVICE_X_P (XDEVICE (device))) signal_simple_error ("Not an X device", device); @@ -2412,7 +2429,7 @@ x_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), pixel; struct device* d = XDEVICE (device); - Lisp_Object frame = FW_FRAME (domain); + Lisp_Object frame = DOMAIN_FRAME (domain); struct frame* f = XFRAME (frame); char* nm=0; Widget wid; @@ -2470,12 +2487,12 @@ x_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, anymore...*/ pixel = FACE_FOREGROUND (IMAGE_INSTANCE_WIDGET_FACE (ii), - IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); + IMAGE_INSTANCE_FRAME (ii)); fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); pixel = FACE_BACKGROUND (IMAGE_INSTANCE_WIDGET_FACE (ii), - IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); + IMAGE_INSTANCE_FRAME (ii)); bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); lw_add_widget_value_arg (wv, XtNbackground, bcolor.pixel); @@ -2494,16 +2511,6 @@ x_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void*)wid; IMAGE_INSTANCE_X_WIDGET_LWID (ii) = id; -#if 0 - /* Resize the widget here so that the values do not get copied by - lwlib. */ - ac = 0; - XtSetArg (al [ac], XtNwidth, - (Dimension)IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii)); ac++; - XtSetArg (al [ac], XtNheight, - (Dimension)IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); ac++; - XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, ac); -#endif /* because the EmacsManager is the widgets parent we have to offset the redisplay of the widget by the amount the text widget is inside the manager. */ @@ -2515,6 +2522,9 @@ x_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, XtSetMappedWhenManaged (wid, TRUE); free_widget_value_tree (wv); + /* A kludgy but simple way to make sure the callback for a widget + doesn't get deleted. */ + gcpro_popup_callbacks (id); } /* get properties of a control */ @@ -2531,6 +2541,18 @@ x_widget_property (Lisp_Object image_instance, Lisp_Object prop) return Qunbound; } +/* Instantiate a layout control for putting other widgets in. */ +static void +x_native_layout_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, + Lisp_Object pointer_fg, Lisp_Object pointer_bg, + int dest_mask, Lisp_Object domain) +{ + Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + + x_widget_instantiate (image_instance, instantiator, pointer_fg, + pointer_bg, dest_mask, domain, "layout", 0); +} + /* Instantiate a button widget. Unfortunately instantiated widgets are particular to a frame since they need to have a parent. It's not like images where you just select the image into the context you @@ -2545,9 +2567,7 @@ x_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image); - widget_value* wv = xmalloc_widget_value (); - - button_item_to_widget_value (gui, wv, 1, 1); + widget_value* wv = gui_items_to_widget_values (image_instance, gui); if (!NILP (glyph)) { @@ -2574,6 +2594,30 @@ x_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, } } +/* Update a button's clicked state. + + #### This is overkill, but it works. Right now this causes all + button instances to flash for some reason buried deep in lwlib. In + theory this should be the Right Thing to do since lwlib should only + merge in changed values - and if nothing has changed then nothing + should get done. This may be because of the args stuff, + i.e. although the arg contents may be the same the args look + different and so are re-applied to the widget. */ +static void +x_button_update (Lisp_Object image_instance) +{ + /* This function can GC if IN_REDISPLAY is false. */ + Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); + widget_value* wv = + gui_items_to_widget_values (image_instance, + IMAGE_INSTANCE_WIDGET_ITEMS (p)); + + /* now modify the widget */ + lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (p), + wv, True); + free_widget_value_tree (wv); +} + /* get properties of a button */ static Lisp_Object x_button_property (Lisp_Object image_instance, Lisp_Object prop) @@ -2600,9 +2644,7 @@ x_progress_gauge_instantiate (Lisp_Object image_instance, Lisp_Object instantiat { Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); - widget_value* wv = xmalloc_widget_value (); - - button_item_to_widget_value (gui, wv, 1, 1); + widget_value* wv = gui_items_to_widget_values (image_instance, gui); x_widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, dest_mask, domain, "progress", wv); @@ -2614,12 +2656,14 @@ x_progress_gauge_update (Lisp_Object image_instance) { Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - if (IMAGE_INSTANCE_WIDGET_PERCENT_CHANGED (ii)) + if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)) { Arg al [1]; - /* #### I'm not convinced we should store this in the plist. */ - Lisp_Object val = Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), - Q_percent, Qnil); + Lisp_Object val; +#ifdef ERROR_CHECK_GLYPHS + assert (GUI_ITEMP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))); +#endif + val = XGUI_ITEM (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))->value; XtSetArg (al[0], XtNvalue, XINT (val)); XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, 1); } @@ -2633,9 +2677,7 @@ x_edit_field_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, { Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); - widget_value* wv = xmalloc_widget_value (); - - button_item_to_widget_value (gui, wv, 1, 1); + widget_value* wv = gui_items_to_widget_values (image_instance, gui); x_widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, dest_mask, domain, "text-field", wv); @@ -2655,7 +2697,8 @@ x_combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, dest_mask, domain); - wv = gui_items_to_widget_values (IMAGE_INSTANCE_WIDGET_ITEMS (ii)); + wv = gui_items_to_widget_values (image_instance, + IMAGE_INSTANCE_WIDGET_ITEMS (ii)); x_widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, dest_mask, domain, "combo-box", wv); @@ -2669,10 +2712,11 @@ x_tab_control_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, { Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); widget_value * wv = - gui_items_to_widget_values (IMAGE_INSTANCE_WIDGET_ITEMS (ii)); + gui_items_to_widget_values (image_instance, + IMAGE_INSTANCE_WIDGET_ITEMS (ii)); update_tab_widget_face (wv, ii, - IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); + IMAGE_INSTANCE_FRAME (ii)); x_widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, dest_mask, domain, "tab-control", wv); @@ -2680,20 +2724,25 @@ x_tab_control_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, /* set the properties of a tab control */ static void -x_tab_control_update (Lisp_Object image_instance) +x_tab_control_update (Lisp_Object image_instance) { Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); /* Possibly update the face. */ - if (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii) + if (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii) || - XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii))->faces_changed + XFRAME (IMAGE_INSTANCE_FRAME (ii))->faces_changed || IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)) { widget_value* wv = lw_get_all_values (IMAGE_INSTANCE_X_WIDGET_LWID (ii)); + + /* #### I don't know why this can occur. */ + if (!wv) + return; + update_tab_widget_face (wv, ii, - IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); + IMAGE_INSTANCE_FRAME (ii)); lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (ii), wv, True); } @@ -2707,9 +2756,7 @@ x_label_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, { Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); - widget_value* wv = xmalloc_widget_value (); - - button_item_to_widget_value (gui, wv, 1, 1); + widget_value* wv = gui_items_to_widget_values (image_instance, gui); x_widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, dest_mask, domain, "button", wv); @@ -2752,7 +2799,9 @@ image_instantiator_format_create_glyphs_x (void) { IIFORMAT_VALID_CONSOLE (x, nothing); IIFORMAT_VALID_CONSOLE (x, string); +#ifdef HAVE_WIDGETS IIFORMAT_VALID_CONSOLE (x, layout); +#endif IIFORMAT_VALID_CONSOLE (x, formatted_string); IIFORMAT_VALID_CONSOLE (x, inherit); #ifdef HAVE_XPM @@ -2777,11 +2826,15 @@ image_instantiator_format_create_glyphs_x (void) INITIALIZE_DEVICE_IIFORMAT (x, subwindow); IIFORMAT_HAS_DEVMETHOD (x, subwindow, instantiate); #ifdef HAVE_WIDGETS + /* layout widget */ + INITIALIZE_DEVICE_IIFORMAT (x, native_layout); + IIFORMAT_HAS_DEVMETHOD (x, native_layout, instantiate); /* button widget */ INITIALIZE_DEVICE_IIFORMAT (x, button); IIFORMAT_HAS_DEVMETHOD (x, button, property); IIFORMAT_HAS_DEVMETHOD (x, button, instantiate); - + IIFORMAT_HAS_DEVMETHOD (x, button, update); + /* general widget methods. */ INITIALIZE_DEVICE_IIFORMAT (x, widget); IIFORMAT_HAS_DEVMETHOD (x, widget, property); /* progress gauge */