Index: lisp/cus-edit.el =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/lisp/cus-edit.el,v retrieving revision 1.8.2.8 diff -u -r1.8.2.8 cus-edit.el --- lisp/cus-edit.el 1999/11/27 05:27:25 1.8.2.8 +++ lisp/cus-edit.el 1999/12/21 16:49:05 @@ -1033,7 +1033,6 @@ (widget-insert "\nOperate on everything in this buffer:\n ") (widget-create 'push-button :tag "Set" - :tag-glyph '("set-up" "set-down") :help-echo "\ Make your editing in this buffer take effect for this session" :action (lambda (widget &optional event) @@ -1041,7 +1040,6 @@ (widget-insert " ") (widget-create 'push-button :tag "Save" - :tag-glyph '("save-up" "save-down") :help-echo "\ Make your editing in this buffer take effect for future Emacs sessions" :action (lambda (widget &optional event) @@ -1077,7 +1075,6 @@ (widget-insert " ") (widget-create 'push-button :tag "Done" - :tag-glyph '("done-up" "done-down") :help-echo "Remove the buffer" :action (lambda (widget &optional event) (Custom-buffer-done))) Index: lwlib/lwlib-Xaw.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/lwlib/lwlib-Xaw.c,v retrieving revision 1.9.2.4 diff -u -r1.9.2.4 lwlib-Xaw.c --- lwlib/lwlib-Xaw.c 1999/08/30 13:37:06 1.9.2.4 +++ lwlib/lwlib-Xaw.c 1999/12/21 16:49:11 @@ -126,8 +126,8 @@ xaw_update_one_widget (widget_instance *instance, Widget widget, widget_value *val, Boolean deep_p) { - if (val->nargs) - XtSetValues (widget, val->args, val->nargs); + if (val->args && val->args->nargs) + XtSetValues (widget, val->args->args, val->args->nargs); if (0) ; @@ -146,7 +146,7 @@ } #endif /* LWLIB_DIALOGS_ATHENA */ #ifdef LWLIB_WIDGETS_ATHENA - else if (XtClass (widget) == labelWidgetClass) + else if (XtIsSubclass (widget, labelWidgetClass)) { Arg al [1]; XtSetArg (al [0], XtNlabel, val->value); Index: lwlib/lwlib.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/lwlib/lwlib.c,v retrieving revision 1.13.2.5 diff -u -r1.13.2.5 lwlib.c --- lwlib/lwlib.c 1999/09/03 04:40:21 1.13.2.5 +++ lwlib/lwlib.c 1999/12/21 16:49:15 @@ -40,7 +40,10 @@ #endif #ifdef NEED_MOTIF #include "lwlib-Xm.h" +#ifdef LWLIB_WIDGETS_MOTIF +#include #endif +#endif #ifdef NEED_ATHENA #include "lwlib-Xaw.h" #endif @@ -67,8 +70,8 @@ /* Forward declarations */ -static void -instantiate_widget_instance (widget_instance *instance); +static void instantiate_widget_instance (widget_instance *instance); +static void free_widget_value_args (widget_value* wv); /* utility functions for widget_instance and widget_info */ @@ -152,15 +155,10 @@ { free_widget_value_tree (wv->contents); wv->contents = (widget_value *) 0xDEADBEEF; - } - if (wv->args && wv->nargs) - { - if (wv->free_args) - free (wv->args); - wv->args = (ArgList) 0xDEADBEEF; - wv->nargs = 0; - wv->free_args = 0; } + + free_widget_value_args (wv); + if (wv->next) { free_widget_value_tree (wv->next); @@ -237,6 +235,41 @@ #endif /* NEED_SCROLLBARS */ +#ifdef HAVE_WIDGETS +/* + * Return true if old->args was not equivalent + * to new->args. + */ +static Boolean +merge_widget_value_args (widget_value *old, widget_value *new) +{ + Boolean changed = False; + + if (new->args && !old->args) + { + lw_copy_widget_value_args (new, old); + changed = True; + } + /* Generally we don't want to lose values that are already in the + widget. */ + else if (!new->args && old->args) + { + lw_copy_widget_value_args (old, new); + changed = True; + } + else if (new->args && old->args) + { + /* #### Do something more sensible here than just copying the + new values (like actually merging the values). */ + free_widget_value_args (old); + lw_copy_widget_value_args (new, old); + changed = True; + } + + return changed; +} +#endif /* HAVE_WIDGETS */ + /* Make a complete copy of a widget_value tree. Store CHANGE into the widget_value tree's `change' field. */ @@ -269,13 +302,8 @@ copy->next = copy_widget_value_tree (val->next, change); copy->toolkit_data = NULL; copy->free_toolkit_data = False; - if (val->nargs) - { - copy->args = (ArgList)malloc (sizeof (Arg) * val->nargs); - memcpy (copy->args, val->args, sizeof(Arg) * val->nargs); - copy->nargs = val->nargs; - copy->free_args = True; - } + + lw_copy_widget_value_args (val, copy); #ifdef NEED_SCROLLBARS copy_scrollbar_values (val, copy); #endif @@ -590,6 +618,14 @@ change = max (change, INVISIBLE_CHANGE); val1->call_data = val2->call_data; } +#ifdef HAVE_WIDGETS + if (merge_widget_value_args (val1, val2)) + { + EXPLAIN (val1->name, change, VISIBLE_CHANGE, "widget change", 0, 0); + change = max (change, VISIBLE_CHANGE); + } +#endif + #ifdef NEED_SCROLLBARS if (merge_scrollbar_values (val1, val2)) { @@ -1317,13 +1353,72 @@ void lw_add_value_args_to_args (widget_value* wv, ArgList addto, int* offset) { int i; - if (wv->nargs && wv->args) + if (wv->args && wv->args->nargs) { - for (i = 0; inargs; i++) + for (i = 0; iargs->nargs; i++) { - addto[i + *offset] = wv->args[i]; + addto[i + *offset] = wv->args->args[i]; } - *offset += wv->nargs; + *offset += wv->args->nargs; + } +} + +void lw_add_widget_value_arg (widget_value* wv, String name, XtArgVal value) +{ + if (!wv->args) + { + wv->args = (widget_args *) malloc (sizeof (widget_args)); + memset (wv->args, 0, sizeof (widget_args)); + wv->args->ref_count = 1; + wv->args->nargs = 0; + wv->args->args = (ArgList) malloc (sizeof (Arg) * 10); + memset (wv->args->args, 0, sizeof (Arg) * 10); + } + + if (wv->args->nargs > 10) + return; + + XtSetArg (wv->args->args [wv->args->nargs], name, value); wv->args->nargs++; +} + +static void free_widget_value_args (widget_value* wv) +{ + if (wv->args) + { + if (--wv->args->ref_count <= 0) + { + /* #### Free font values here. */ +#ifdef LWLIB_WIDGETS_MOTIF + int i; + for (i = 0; i < wv->args->nargs; i++) + { + if (!strcmp (wv->args->args[i].name, XmNfontList)) + XmFontListFree ((XmFontList)wv->args->args[i].value); + } +#endif + free (wv->args->args); + free (wv->args); + wv->args = (widget_args*)0xDEADBEEF; + } + } +} + +void lw_copy_widget_value_args (widget_value* val, widget_value* copy) +{ + if (!val->args) + { + val->args = (widget_args *) malloc (sizeof (widget_args)); + memset (val->args, 0, sizeof (widget_args)); + val->args->ref_count = 2; + val->args->nargs = 0; + val->args->args = (ArgList) malloc (sizeof (Arg) * 10); + memset (val->args->args, 0, sizeof (Arg) * 10); + copy->args = val->args; + } + else + { + copy->args = val->args; + copy->args->ref_count++; } } Index: lwlib/lwlib.h =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/lwlib/lwlib.h,v retrieving revision 1.4.2.4 diff -u -r1.4.2.4 lwlib.h --- lwlib/lwlib.h 1999/08/24 08:41:28 1.4.2.4 +++ lwlib/lwlib.h 1999/12/21 16:49:18 @@ -106,6 +106,17 @@ int scrollbar_x, scrollbar_y; } scrollbar_values; +typedef struct _widget_args +{ + /* some things are only possible at creation time. args are applied + to widgets at creation time. */ + ArgList args; + int nargs; + /* Copying args is impossible so we make the caller give us heap allocated + args and free them when on-one wants them any more. */ + int ref_count; +} widget_args; + typedef struct _widget_value { /* This slot is only partially utilized right now. */ @@ -147,15 +158,12 @@ /* data defining a scrollbar; only valid if type == "scrollbar" */ scrollbar_values *scrollbar_data; + /* A reference counted arg structure. */ + struct _widget_args *args; /* we resource the widget_value structures; this points to the next one on the free list if this one has been deallocated. */ struct _widget_value *free_list; - /* some things are only possible at creation time. args are applied - to widgets at creation time. */ - ArgList args; - int nargs; - Boolean free_args; } widget_value; @@ -211,6 +219,8 @@ void lw_pop_up_all_widgets (LWLIB_ID id); void lw_pop_down_all_widgets (LWLIB_ID id); void lw_add_value_args_to_args (widget_value* wv, ArgList addto, int* offset); +void lw_add_widget_value_arg (widget_value* wv, String name, XtArgVal value); +void lw_copy_widget_value_args (widget_value* copy, widget_value* val); widget_value *malloc_widget_value (void); void free_widget_value (widget_value *); Index: lwlib/xlwtabs.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/lwlib/Attic/xlwtabs.c,v retrieving revision 1.1.2.20 diff -u -r1.1.2.20 xlwtabs.c --- lwlib/xlwtabs.c 1999/12/14 14:09:19 1.1.2.20 +++ lwlib/xlwtabs.c 1999/12/21 16:49:27 @@ -18,7 +18,7 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /* Synched up with: Tabs.c 1.25 */ + /* Synched up with: Tabs.c 1.27 */ /* * Tabs.c - Index Tabs composite widget @@ -51,8 +51,8 @@ * the frame. */ -/* TODO: min child height = tab height - * +/* + * TODO: min child height = tab height */ #include @@ -189,6 +189,7 @@ static void TabsDestroy(); static void TabsRealize(); static Boolean TabsSetValues(); +static Boolean TabsAcceptFocus(); static XtGeometryResult TabsQueryGeometry(); static XtGeometryResult TabsGeometryManager(); static void TabsChangeManaged(); @@ -237,6 +238,7 @@ static void TabsResize( Widget w) ; static void TabsExpose( Widget w, XEvent *event, Region region) ; static Boolean TabsSetValues(Widget, Widget, Widget, ArgList, Cardinal *) ; +static Boolean TabsAcceptFocus(Widget, Time *); static Boolean TabsConstraintSetValues(Widget, Widget, Widget, ArgList, Cardinal *) ; static XtGeometryResult TabsQueryGeometry(Widget, @@ -263,7 +265,7 @@ static int TabLayout( TabsWidget, int wid, int hgt, Dimension *r_hgt, Bool query_only) ; static void GetPreferredSizes(TabsWidget) ; -static void MaxChild(TabsWidget) ; +static void MaxChild(TabsWidget, Widget except, Dimension, Dimension) ; static void TabsShuffleRows( TabsWidget tw) ; static int PreferredSize( TabsWidget, Dimension *reply_width, Dimension *reply_height, @@ -325,9 +327,9 @@ /* num_resources */ XtNumber(resources), /* xrm_class */ NULLQUARK, /* compress_motion */ TRUE, - /* compress_exposure */ TRUE, + /* compress_exposure */ XtExposeCompressMaximal|XtExposeNoRegion, /* compress_enterleave*/ TRUE, - /* visible_interest */ FALSE, + /* visible_interest */ TRUE, /* destroy */ TabsDestroy, /* resize */ TabsResize, /* expose */ TabsExpose, @@ -335,7 +337,7 @@ /* set_values_hook */ NULL, /* set_values_almost */ XtInheritSetValuesAlmost, /* get_values_hook */ NULL, - /* accept_focus */ NULL, + /* accept_focus */ TabsAcceptFocus, /* version */ XtVersion, /* callback_private */ NULL, /* tm_table */ defaultTranslations, @@ -460,7 +462,7 @@ newTw->tabs.grey50 = None ; newTw->tabs.needs_layout = False ; - + newTw->tabs.hilight = NULL ; #ifdef NEED_MOTIF @@ -480,7 +482,6 @@ { TabsConstraints tab = (TabsConstraints) new->core.constraints ; tab->tabs.greyAlloc = False ; /* defer allocation of pixel */ - tab->tabs.queried = False ; /* defer size query */ getBitmapInfo((TabsWidget)XtParent(new), tab) ; TabWidth(new) ; @@ -539,6 +540,8 @@ * to the bottom row. */ + tw->tabs.needs_layout = False ; + if( num_children > 0 && tw->composite.children != NULL ) { /* Loop through the tabs and assign rows & x positions */ @@ -554,28 +557,27 @@ tw->tabs.child_width = cw = tw->core.width - 2 * SHADWID ; tw->tabs.child_height = ch = - tw->core.height - tw->tabs.tab_total - 2 * SHADWID ; + tw->core.height - tw->tabs.tab_total - 2 * SHADWID ; for(i=0, childP=tw->composite.children; - i < num_children; + i < num_children; ++i, ++childP) if( XtIsManaged(*childP) ) { tab = (TabsConstraints) (*childP)->core.constraints ; - bw = tab->tabs.bwid ; + bw = (*childP)->core.border_width ; XtConfigureWidget(*childP, SHADWID,tw->tabs.tab_total+SHADWID, cw-bw*2,ch-bw*2, bw) ; - } - if( XtIsRealized(w) ) - { - XClearWindow(XtDisplay((Widget)tw), XtWindow((Widget)tw)) ; - tw->tabs.needs_layout = False ; - XtClass(tw)->core_class.expose((Widget)tw,NULL,None) ; } + if( XtIsRealized(w) ) { + XClearWindow(XtDisplay((Widget)tw), XtWindow((Widget)tw)) ; + /* should not be necessary to explicitly repaint after a + * resize, but XEmacs folks tell me it is. + */ + XtClass(tw)->core_class.expose((Widget)tw,NULL,None) ; + } } - - tw->tabs.needs_layout = False ; } /* Resize */ @@ -731,6 +733,22 @@ } +static Boolean +TabsAcceptFocus(Widget w, Time *t) +{ + if( !w->core.being_destroyed && XtIsRealized(w) && + XtIsSensitive(w) && XtIsManaged(w) && w->core.visible ) + { + Widget p ; + for(p = XtParent(w); !XtIsShell(p); p = XtParent(p)) ; + XtSetKeyboardFocus(p,w) ; + return True ; + } + else + return False ; +} + + /* * Return preferred size. Happily accept anything >= our preferred size. @@ -752,11 +770,9 @@ (!(mode & CWHeight) || intended->height == w->core.height) ) return XtGeometryNo ; -#ifdef COMMENT if( (!(mode & CWWidth) || intended->width >= preferred->width) && (!(mode & CWHeight) || intended->height >= preferred->height) ) return XtGeometryYes; -#endif /* COMMENT */ return XtGeometryAlmost; } @@ -774,6 +790,7 @@ Dimension s = SHADWID ; TabsConstraints tab = (TabsConstraints)w->core.constraints; XtGeometryResult result ; + Dimension rw, rh ; /* Position request always denied */ @@ -795,19 +812,21 @@ req->border_width == w->core.border_width ) return XtGeometryNo ; - /* updated cached preferred size of the child */ - tab->tabs.bwid = req->border_width ; - tab->tabs.wid = req->width + req->border_width * 2 ; - tab->tabs.hgt = req->height + req->border_width * 2 ; - MaxChild(tw) ; + rw = req->width + 2 * req->border_width ; + rh = req->height + 2 * req->border_width ; + /* find out how big the children want to be now */ + MaxChild(tw, w, rw, rh) ; + /* Size changes must see if the new size can be accommodated. * The Tabs widget keeps all of its children the same * size. A request to shrink will be accepted only if the * new size is still big enough for all other children. A * request to shrink that is not big enough for all children - * returns an "almost" response with the new proposed size. + * returns an "almost" response with the new proposed size + * or a "no" response if unable to shrink at all. + * * A request to grow will be accepted only if the Tabs parent can * grow to accommodate. * @@ -819,24 +838,19 @@ if (req->request_mode & (CWWidth | CWHeight | CWBorderWidth)) { - Dimension rw,rh ; /* child's requested width, height */ Dimension cw,ch ; /* children's preferred size */ Dimension aw,ah ; /* available size we can give child */ Dimension th ; /* space used by tabs */ Dimension wid,hgt ; /* Tabs widget size */ - rw = cw = tab->tabs.wid ; - rh = ch = tab->tabs.hgt ; + cw = tw->tabs.max_cw ; + ch = tw->tabs.max_ch ; - /* find out what the resulting preferred size would be */ + /* find out what *my* resulting preferred size would be */ -#ifdef COMMENT - MaxChild(tw, &cw, &ch) ; -#endif /* COMMENT */ - PreferredSize2(tw, - cw=tw->tabs.max_cw, ch=tw->tabs.max_ch, &wid, &hgt) ; + PreferredSize2(tw, cw, ch, &wid, &hgt) ; - /* Ask to be resized to accommodate. */ + /* Would my size change? If so, ask to be resized. */ if( wid != tw->core.width || hgt != tw->core.height ) { @@ -856,7 +870,7 @@ result = XtMakeGeometryRequest((Widget)tw, &myrequest, &myreply) ; - /* !$@# Box widget changes the core size even if QueryOnly + /* !$@# Athena Box widget changes the core size even if QueryOnly * is set. I'm convinced this is a bug. At any rate, to work * around the bug, we need to restore the core size after every * query geometry request. This is only partly effective, @@ -874,6 +888,7 @@ switch( result ) { case XtGeometryYes: case XtGeometryDone: + tw->tabs.needs_layout = True ; break ; case XtGeometryNo: @@ -884,6 +899,8 @@ case XtGeometryAlmost: wid = myreply.width ; hgt = myreply.height ; + tw->tabs.needs_layout = True ; + break ; } } @@ -995,9 +1012,6 @@ if( tw->tabs.topWidget != NULL ) XtVaSetValues(tw->tabs.topWidget, XmNtraversalOn, True, 0) ; #endif - - - } @@ -1224,15 +1238,15 @@ if( !XtIsSubclass(w->core.parent, tabsWidgetClass) ) { - char line[1024] ; - sprintf(line, "XawTabsSetTop: widget \"%s\" is not the child of a tabs widget.", XtName(w)) ; + char line[256] ; + sprintf(line, "XawTabsSetTop: widget \"%.64s\" is not the child of a tabs widget.", XtName(w)) ; XtAppWarning(XtWidgetToApplicationContext(w), line) ; return ; } if( callCallbacks ) XtCallCallbackList(w, tw->tabs.popdownCallbacks, - (XtPointer)tw->tabs.topWidget) ; + (XtPointer)tw->tabs.topWidget) ; if( !XtIsRealized(w) ) { tw->tabs.topWidget = w ; @@ -1437,11 +1451,11 @@ { if( tab->tabs.lbm_depth == 1 ) XCopyPlane(dpy, tab->tabs.left_bitmap, win,gc, - 0,0, tab->tabs.lbm_width, tab->tabs.lbm_height, + 0,0, tab->tabs.lbm_width, tab->tabs.lbm_height, x+tab->tabs.lbm_x, y+tab->tabs.lbm_y, 1L) ; else XCopyArea(dpy, tab->tabs.left_bitmap, win,gc, - 0,0, tab->tabs.lbm_width, tab->tabs.lbm_height, + 0,0, tab->tabs.lbm_width, tab->tabs.lbm_height, x+tab->tabs.lbm_x, y+tab->tabs.lbm_y) ; } @@ -1600,8 +1614,27 @@ /* GEOMETRY UTILITIES */ + /* Overview: + * + * MaxChild(): ask all children (except possibly one) their + * preferred sizes, set max_cw, max_ch accordingly. + * + * GetPreferredSizes(): ask all children their preferred sizes, + * set max_cw, max_ch accordingly. + * + * PreferredSize(): given max_cw, max_ch, return tabs widget + * preferred size. Iterate with other widths in order to get + * a reasonable aspect ratio. + * + * PreferredSize2(): Given child dimensions, return Tabs + * widget dimensions. + * + * PreferredSize3(): Same, except given child dimensions plus + * shadow. + */ - /* Compute the size of one child's tab. Positions will be computed + + /* Compute the width of one child's tab. Positions will be computed * elsewhere. * * height: font height + vertical_space*2 + shadowWid*2 @@ -1634,7 +1667,7 @@ { tab->tabs.width += XTextWidth( font, lbl, (int)strlen(lbl) ) + iw ; tab->tabs.l_y = (tw->tabs.tab_height + - tw->tabs.font->max_bounds.ascent - + tw->tabs.font->max_bounds.ascent - tw->tabs.font->max_bounds.descent)/2 ; } } @@ -1731,59 +1764,34 @@ /* Find max preferred child size. Returned sizes include child - * border widths. We only ever ask a child its preferred - * size once. After that, the preferred size is updated only - * if the child makes a geometry request. + * border widths. */ static void GetPreferredSizes(TabsWidget tw) { - int i ; - Widget *childP = tw->composite.children ; - XtWidgetGeometry preferred ; - TabsConstraints tab ; - Dimension cw = 0, ch = 0 ; - - for(i=tw->tabs.displayChildren; --i >= 0; ++childP) - if( XtIsManaged(*childP) ) - { - tab = (TabsConstraints) (*childP)->core.constraints ; - if( !tab->tabs.queried ) { - (void) XtQueryGeometry(*childP, NULL, &preferred) ; - tab->tabs.bwid = preferred.border_width ; - tab->tabs.wid = preferred.width + preferred.border_width * 2 ; - tab->tabs.hgt = preferred.height + preferred.border_width * 2 ; - tab->tabs.queried = True ; - } - cw = Max(cw, tab->tabs.wid ) ; - ch = Max(ch, tab->tabs.hgt ) ; - } - tw->tabs.max_cw = cw ; - tw->tabs.max_ch = ch ; + MaxChild(tw, NULL, 0,0) ; } /* Find max preferred child size. Returned sizes include child - * border widths. */ + * border widths. If except is non-null, don't ask that one. + */ static void -MaxChild(TabsWidget tw) +MaxChild(TabsWidget tw, Widget except, Dimension cw, Dimension ch) { - Dimension cw,ch ; /* child width, height */ - int i ; - Widget *childP = tw->composite.children ; - TabsConstraints tab ; - - cw = ch = 0 ; + int i ; + Widget *childP = tw->composite.children ; + XtWidgetGeometry preferred ; for(i=tw->composite.num_children; --i >=0; ++childP) - if( XtIsManaged(*childP) ) + if( XtIsManaged(*childP) && *childP != except ) { - tab = (TabsConstraints) (*childP)->core.constraints ; - cw = Max(cw, tab->tabs.wid ) ; - ch = Max(ch, tab->tabs.hgt ) ; + (void) XtQueryGeometry(*childP, NULL, &preferred) ; + cw = Max(cw, preferred.width + preferred.border_width * 2 ) ; + ch = Max(ch, preferred.height + preferred.border_width * 2 ) ; } tw->tabs.max_cw = cw ; @@ -1845,10 +1853,12 @@ } - /* find preferred size. Ask children, find size of largest, + /* Find preferred size. Ask children, find size of largest, * add room for tabs & return. This can get a little involved, * as we don't want to have too many rows of tabs; we may widen * the widget to reduce # of rows. + * + * This function requires that max_cw, max_ch already be set. */ static int @@ -1864,12 +1874,6 @@ Dimension rwid,rhgt ; int nrow ; - - /* find max desired child height */ -#ifdef COMMENT - MaxChild(tw, &cw, &ch) ; -#endif /* COMMENT */ - wid = cw = tw->tabs.max_cw ; hgt = ch = tw->tabs.max_ch ; @@ -1883,6 +1887,7 @@ if( nrow > 2 && rhgt > rwid ) { Dimension w0, w1 ; + int maxloop = 20 ; /* step 1: start doubling size until it's too big */ do { @@ -1895,7 +1900,7 @@ /* step 2: use Newton's method to find ideal size. Stop within * 8 pixels. */ - while( w1 > w0 + 8 ) + while( --maxloop > 0 && w1 > w0 + 8 ) { wid = (w0+w1)/2 ; nrow = PreferredSize2(tw, wid,hgt, &rwid,&rhgt) ; @@ -2013,7 +2018,7 @@ if( tab->tabs.left_bitmap == None || !XGetGeometry(XtDisplay(tw), tab->tabs.left_bitmap, &root, &x, &y, - &tab->tabs.lbm_width, &tab->tabs.lbm_height, + &tab->tabs.lbm_width, &tab->tabs.lbm_height, &bw, &tab->tabs.lbm_depth) ) tab->tabs.lbm_width = tab->tabs.lbm_height = 0 ; } Index: lwlib/xlwtabsP.h =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/lwlib/Attic/xlwtabsP.h,v retrieving revision 1.1.2.4 diff -u -r1.1.2.4 xlwtabsP.h --- lwlib/xlwtabsP.h 1999/10/21 14:29:47 1.1.2.4 +++ lwlib/xlwtabsP.h 1999/12/21 16:49:28 @@ -18,7 +18,7 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* Synched up with: TabsP.h 1.7 */ +/* Synched up with: TabsP.h 1.8 */ /* * TabsP.h - Private definitions for Index Tabs widget @@ -132,9 +132,6 @@ Dimension width ; /* tab width */ Position x,y ; /* tab base position */ short row ; /* tab row */ - Dimension wid,hgt ; /* desired size */ - Dimension bwid ; /* desired border width */ - Boolean queried ; /* we've asked child it's pref. size */ Position l_x, l_y ; /* label position */ Position lbm_x, lbm_y ; /* bitmap position */ unsigned int lbm_width, lbm_height, lbm_depth ; Index: src/Makefile.in.in =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/Makefile.in.in,v retrieving revision 1.81.2.15 diff -u -r1.81.2.15 Makefile.in.in --- src/Makefile.in.in 1999/11/27 20:57:39 1.81.2.15 +++ src/Makefile.in.in 1999/12/21 16:49:32 @@ -320,6 +320,7 @@ temacs_loadup = $(DUMPENV) ./temacs -batch -l ${srcdir}/../lisp/loadup.el dump_temacs = ${temacs_loadup} dump run_temacs = ${temacs_loadup} run-temacs +debug_temacs = $(DUMPENV) gdb temacs release: temacs ${libsrc}DOC $(mo_file) ${other_files} #ifdef CANNOT_DUMP @@ -491,6 +492,9 @@ suppress rui; \ runargs -batch -l ${srcdir}/../lisp/loadup.el run-temacs -q; \ run' rtcmacs + +debug-temacs: temacs + -${debug_temacs} ## Purify, Quantify, PureCoverage are software quality products from ## Rational, formerly Pure Atria, formerly Pure Software. Index: src/config.h.in =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/config.h.in,v retrieving revision 1.49.2.15 diff -u -r1.49.2.15 config.h.in --- src/config.h.in 1999/11/28 18:15:46 1.49.2.15 +++ src/config.h.in 1999/12/21 16:49:39 @@ -499,6 +499,16 @@ #define CONST const +/* Allow the source to use standard types. Include these before the + s&m files so that they can use them. */ +#undef ssize_t +#undef size_t +#undef pid_t +#undef mode_t +#undef off_t +#undef uid_t +#undef gid_t + /* If defined, use unions instead of ints. A few systems (DEC Alpha) seem to require this, probably because something with the int definitions isn't right with 64-bit systems. */ @@ -549,15 +559,6 @@ #define SIGTYPE RETSIGTYPE #define SIGRETURN return #endif - -/* Allow the source to use standard types */ -#undef ssize_t -#undef size_t -#undef pid_t -#undef mode_t -#undef off_t -#undef uid_t -#undef gid_t /* Define DYNODUMP if it is necessary to properly dump on this system. Currently this is only Solaris 2.x, for x < 6. */ Index: src/event-msw.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/event-msw.c,v retrieving revision 1.38.2.23 diff -u -r1.38.2.23 event-msw.c --- src/event-msw.c 1999/11/29 16:09:16 1.38.2.23 +++ src/event-msw.c 1999/12/21 16:50:44 @@ -73,7 +73,7 @@ #include #include -#if defined (__CYGWIN32__) && !defined (CYGWIN_VERSION_DLL_MAJOR) +#if defined (__CYGWIN32__) && (CYGWIN_VERSION_DLL_MAJOR < 20) typedef NMHDR *LPNMHDR; #endif Index: src/glyphs-widget.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/Attic/glyphs-widget.c,v retrieving revision 1.1.2.16 diff -u -r1.1.2.16 glyphs-widget.c --- src/glyphs-widget.c 1999/10/10 12:40:09 1.1.2.16 +++ src/glyphs-widget.c 1999/12/21 16:50:48 @@ -599,7 +599,49 @@ return inst; } -/* Instantiate a layout widget. */ +/* Instantiate a layout widget. Sizing commentary: we have a number of + problems that we would like to address. Some consider some of these + more important than others. Currently size information is + determined at instantiation time and is then fixed forever + after. Generally this is not what we want. Users want size to be + "big enough" to accommodate whatever they are trying to show and + this is dependent on text length, lines, font metrics etc. Of + course these attributes can change dynamically and so the size + should changed dynamically also. Only in a few limited cases should + the size be fixed and remain fixed. Of course this actually means + that we don't really want to specifiy the size *at all* for most + widgets - we want it to be discovered dynamically. Thus we can + envisage the following scenarios: + + 1. A button is sized to accommodate its text, the text changes and the + button should change size also. + + 2. A button is given an explicit size. Its size should never change. + + 3. Layout is put inside an area. The size of the area changes, the + layout should change with it. + + 4. A button grows to accommodate additional text. The whitespace + around it should be modified to cope with the new layout + requirements. + + 5. A button grows. The area surrounding it should grow also if + possible. + + What metrics are important? + 1. Actual width and height. + + 2. Whether the width and height are what the widget actually wants, or + whether it can grow or shrink. + + Text glyphs are particularly troublesome since their metrics depend + on the context in which they are being viewed. For instance they + can appear differently depending on the window face, frame face or + glyph face. All other glyphs are essentially fixed in + appearance. Perhaps the problem is that text glyphs are cached on a + device basis like most other glyphs. Instead they should be cached + per-window and then the instance would be fixed and we wouldn't + have to mess around with font metrics and the rest. */ static void layout_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, Lisp_Object pointer_fg, Lisp_Object pointer_bg, @@ -795,19 +837,34 @@ image_instantiator_format_create_glyphs_widget (void) { #define VALID_GUI_KEYWORDS(type) \ - IIFORMAT_VALID_KEYWORD (type, Q_active, check_valid_anything); \ - IIFORMAT_VALID_KEYWORD (type, Q_suffix, check_valid_anything); \ + IIFORMAT_VALID_NONCOPY_KEYWORD (type, Q_active, check_valid_anything); \ + IIFORMAT_VALID_KEYWORD (type, Q_suffix, check_valid_anything); \ IIFORMAT_VALID_KEYWORD (type, Q_keys, check_valid_string); \ IIFORMAT_VALID_KEYWORD (type, Q_style, check_valid_symbol); \ - IIFORMAT_VALID_KEYWORD (type, Q_selected, check_valid_anything); \ + IIFORMAT_VALID_NONCOPY_KEYWORD (type, Q_selected, check_valid_anything); \ IIFORMAT_VALID_KEYWORD (type, Q_filter, check_valid_anything); \ IIFORMAT_VALID_KEYWORD (type, Q_config, check_valid_symbol); \ IIFORMAT_VALID_KEYWORD (type, Q_included, check_valid_anything); \ IIFORMAT_VALID_KEYWORD (type, Q_key_sequence, check_valid_string); \ - IIFORMAT_VALID_KEYWORD (type, Q_accelerator, check_valid_string); \ + IIFORMAT_VALID_KEYWORD (type, Q_accelerator, check_valid_string); \ IIFORMAT_VALID_KEYWORD (type, Q_label, check_valid_anything); \ - IIFORMAT_VALID_KEYWORD (type, Q_callback, check_valid_callback); \ - IIFORMAT_VALID_KEYWORD (type, Q_descriptor, check_valid_string_or_vector) + IIFORMAT_VALID_NONCOPY_KEYWORD (type, Q_callback, check_valid_callback); \ + IIFORMAT_VALID_NONCOPY_KEYWORD (type, Q_descriptor, check_valid_string_or_vector) #define VALID_WIDGET_KEYWORDS(type) \ IIFORMAT_VALID_KEYWORD (type, Q_width, check_valid_int); \ Index: src/glyphs-x.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs-x.c,v retrieving revision 1.49.2.39 diff -u -r1.49.2.39 glyphs-x.c --- src/glyphs-x.c 1999/12/05 11:16:31 1.49.2.39 +++ src/glyphs-x.c 1999/12/21 16:51:07 @@ -148,7 +148,11 @@ #ifdef HAVE_WIDGETS static void -update_widget_face (struct Lisp_Image_Instance* ii, Lisp_Object domain); +update_widget_face (widget_value* wv, + struct Lisp_Image_Instance* ii, Lisp_Object domain); +static void +update_tab_widget_face (widget_value* wv, + struct Lisp_Image_Instance* ii, Lisp_Object domain); #endif #include "bitmaps.h" @@ -2163,30 +2167,16 @@ /* This seems ugly, but I'm not sure what else to do. */ if (EQ (IMAGE_INSTANCE_WIDGET_TYPE (p), Qtab_control)) { - widget_value* cur = 0; - /* Give each child label the correct foreground color. */ - Lisp_Object pixel = FACE_FOREGROUND - (IMAGE_INSTANCE_WIDGET_FACE (p), - IMAGE_INSTANCE_SUBWINDOW_FRAME (p)); - XColor fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); - XtSetArg (al [0], XtNtabForeground, fcolor.pixel); - - for (cur = wv->contents; cur; cur = cur->next) - { - if (cur->value) - { - cur->nargs = 1; - cur->args = al; - } - } + update_tab_widget_face (wv, p, + IMAGE_INSTANCE_SUBWINDOW_FRAME (p)); } - + /* update the colors and font */ + update_widget_face (wv, p, IMAGE_INSTANCE_SUBWINDOW_FRAME (p)); + /* now modify the widget */ lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (p), wv, True); free_widget_value_tree (wv); - /* update the colors and font */ - update_widget_face (p, IMAGE_INSTANCE_SUBWINDOW_FRAME (p)); /* We have to do this otherwise Motif will unceremoniously resize us when the label gets set. */ XtSetArg (al [0], XtNwidth, IMAGE_INSTANCE_WIDGET_WIDTH (p)); @@ -2314,45 +2304,59 @@ /************************************************************************/ static void -update_widget_face (struct Lisp_Image_Instance* ii, Lisp_Object domain) +update_widget_face (widget_value* wv, struct Lisp_Image_Instance *ii, + Lisp_Object domain) { - Arg al[3]; #ifdef LWLIB_WIDGETS_MOTIF XmFontList fontList; #endif - + Lisp_Object pixel = FACE_FOREGROUND (IMAGE_INSTANCE_WIDGET_FACE (ii), - IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); + domain); XColor fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); - XColor bcolor; - - pixel = FACE_BACKGROUND - (IMAGE_INSTANCE_WIDGET_FACE (ii), - IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); - bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); - - XtSetArg (al [0], XtNbackground, bcolor.pixel); - XtSetArg (al [1], XtNforeground, fcolor.pixel); + lw_add_widget_value_arg (wv, XtNforeground, fcolor.pixel); #ifdef LWLIB_WIDGETS_MOTIF fontList = XmFontListCreate (FONT_INSTANCE_X_FONT (XFONT_INSTANCE (widget_face_font_info - (domain, IMAGE_INSTANCE_WIDGET_FACE (ii), + (domain, + IMAGE_INSTANCE_WIDGET_FACE (ii), 0, 0))), XmSTRING_DEFAULT_CHARSET); - XtSetArg (al [2], XmNfontList, fontList ); -#else - XtSetArg (al [2], XtNfont, (void*)FONT_INSTANCE_X_FONT - (XFONT_INSTANCE (widget_face_font_info - (domain, - IMAGE_INSTANCE_WIDGET_FACE (ii), - 0, 0)))); -#endif - XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, 3); -#ifdef LWLIB_WIDGETS_MOTIF - XmFontListFree (fontList); + lw_add_widget_value_arg (wv, XmNfontList, (XtArgVal)fontList); #endif + lw_add_widget_value_arg + (wv, XtNfont, (XtArgVal)FONT_INSTANCE_X_FONT + (XFONT_INSTANCE (widget_face_font_info + (domain, + IMAGE_INSTANCE_WIDGET_FACE (ii), + 0, 0)))); +} + +static void +update_tab_widget_face (widget_value* wv, struct Lisp_Image_Instance *ii, + Lisp_Object domain) +{ + if (wv->contents) + { + widget_value* val = wv->contents, *cur; + + /* Give each child label the correct foreground color. */ + Lisp_Object pixel = FACE_FOREGROUND + (IMAGE_INSTANCE_WIDGET_FACE (ii), + domain); + XColor fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); + lw_add_widget_value_arg (val, XtNtabForeground, fcolor.pixel); + + for (cur = val->next; cur; cur = cur->next) + { + if (cur->value) + { + lw_copy_widget_value_args (val, cur); + } + } + } } static void @@ -2393,15 +2397,13 @@ required. */ clip_wv = xmalloc_widget_value (); - XtSetArg (al [ac], XtNresize, False); ac++; - XtSetArg (al [ac], XtNwidth, - (Dimension)IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii)); ac++; - XtSetArg (al [ac], XtNheight, - (Dimension)IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); ac++; - + lw_add_widget_value_arg (clip_wv, XtNresize, False); + lw_add_widget_value_arg (clip_wv, XtNwidth, + (Dimension)IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii)); + lw_add_widget_value_arg (clip_wv, XtNheight, + (Dimension)IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); clip_wv->enabled = True; - clip_wv->nargs = ac; - clip_wv->args = al; + clip_wv->name = xstrdup ("clip-window"); clip_wv->value = xstrdup ("clip-window"); @@ -2414,9 +2416,7 @@ /* copy any args we were given */ ac = 0; - - if (wv->nargs) - lw_add_value_args_to_args (wv, al, &ac); + lw_add_value_args_to_args (wv, al, &ac); /* Fixup the colors. We have to do this *before* the widget gets created so that Motif will fix up the shadow colors @@ -2432,17 +2432,16 @@ IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); - XtSetArg (al [ac], XtNbackground, bcolor.pixel); ac++; - XtSetArg (al [ac], XtNforeground, fcolor.pixel); ac++; + lw_add_widget_value_arg (wv, XtNbackground, bcolor.pixel); + lw_add_widget_value_arg (wv, XtNforeground, fcolor.pixel); /* we cannot allow widgets to resize themselves */ - XtSetArg (al [ac], XtNresize, False); ac++; - XtSetArg (al [ac], XtNwidth, - (Dimension)IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii)); ac++; - XtSetArg (al [ac], XtNheight, - (Dimension)IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); ac++; - - wv->nargs = ac; - wv->args = al; + lw_add_widget_value_arg (wv, XtNresize, False); + lw_add_widget_value_arg (wv, XtNwidth, + (Dimension)IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii)); + lw_add_widget_value_arg (wv, XtNheight, + (Dimension)IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); + /* update the font. */ + update_widget_face (wv, ii, domain); wid = lw_create_widget (type, wv->name, id, wv, IMAGE_INSTANCE_X_CLIPWIDGET (ii), False, 0, popup_selection_callback, 0); @@ -2450,9 +2449,6 @@ IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void*)wid; IMAGE_INSTANCE_X_WIDGET_LWID (ii) = id; - /* update the font. */ - update_widget_face (ii, domain); - /* Resize the widget here so that the values do not get copied by lwlib. */ ac = 0; @@ -2493,7 +2489,9 @@ /* Modify the face properties of the widget */ if (EQ (prop, Q_face)) { - update_widget_face (ii, IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); +#if 0 + update_widget_face (wv, ii, IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); +#endif return Qt; } return Qunbound; @@ -2650,30 +2648,12 @@ int dest_mask, Lisp_Object domain) { struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - Arg al [1]; - XColor fcolor; - Lisp_Object pixel; - widget_value* cur; - widget_value * wv = gui_items_to_widget_values (IMAGE_INSTANCE_WIDGET_ITEMS (ii)); - /* Give each child label the correct foreground color. */ - pixel = FACE_FOREGROUND - (IMAGE_INSTANCE_WIDGET_FACE (ii), - IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); - fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); - XtSetArg (al [0], XtNtabForeground, fcolor.pixel); + update_tab_widget_face (wv, ii, + IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); - for (cur = wv->contents; cur; cur = cur->next) - { - if (cur->value) - { - cur->nargs = 1; - cur->args = al; - } - } - x_widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, dest_mask, domain, "tab-control", wv); } @@ -2687,11 +2667,7 @@ if (EQ (prop, Q_items)) { - widget_value * wv = 0, *cur; - Arg al [1]; - XColor fcolor; - Lisp_Object pixel; - + widget_value * wv = 0; check_valid_item_list_1 (val); IMAGE_INSTANCE_WIDGET_ITEMS (ii) = @@ -2699,22 +2675,9 @@ parse_gui_item_tree_children (val)); wv = gui_items_to_widget_values (IMAGE_INSTANCE_WIDGET_ITEMS (ii)); - - /* Give each child label the correct foreground color. */ - pixel = FACE_FOREGROUND - (IMAGE_INSTANCE_WIDGET_FACE (ii), - IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); - fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); - XtSetArg (al [0], XtNtabForeground, fcolor.pixel); - for (cur = wv->contents; cur; cur = cur->next) - { - if (cur->value) - { - cur->nargs = 1; - cur->args = al; - } - } + update_tab_widget_face (wv, ii, + IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (ii), wv, True); Index: src/glyphs.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs.c,v retrieving revision 1.23.2.36 diff -u -r1.23.2.36 glyphs.c --- src/glyphs.c 1999/12/07 07:03:50 1.23.2.36 +++ src/glyphs.c 1999/12/21 16:51:35 @@ -1724,14 +1724,14 @@ Lisp_Object pointer_fg, Lisp_Object pointer_bg, int dest_mask, Lisp_Object domain) { - Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); + Lisp_Object string = find_keyword_in_vector (instantiator, Q_data); struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - assert (!NILP (data)); + assert (!NILP (string)); if (dest_mask & IMAGE_TEXT_MASK) { IMAGE_INSTANCE_TYPE (ii) = IMAGE_TEXT; - IMAGE_INSTANCE_TEXT_STRING (ii) = data; + IMAGE_INSTANCE_TEXT_STRING (ii) = string; } else incompatible_image_types (instantiator, dest_mask, IMAGE_TEXT_MASK); @@ -2536,10 +2536,12 @@ round it. */ if (UNBOUNDP (instance) && - dest_mask & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK)) + dest_mask & (IMAGE_SUBWINDOW_MASK + | IMAGE_WIDGET_MASK + | IMAGE_TEXT_MASK)) { if (!WINDOWP (domain)) - signal_simple_error ("Can't instantiate subwindow outside a window", + signal_simple_error ("Can't instantiate text or subwindow outside a window", instantiator); instance = Fgethash (instantiator, XWINDOW (domain)->subwindow_instance_cache, @@ -2733,6 +2735,76 @@ return retlist; } +/* Copy an image instantiator. We can't use Fcopy_tree since widgets + may contain circular references which would send Fcopy_tree into + infloop death. */ +static Lisp_Object +image_copy_vector_instantiator (Lisp_Object instantiator) +{ + int i; + struct image_instantiator_methods *meths; + Lisp_Object *elt; + int instantiator_len; + + CHECK_VECTOR (instantiator); + + instantiator = Fcopy_sequence (instantiator); + elt = XVECTOR_DATA (instantiator); + instantiator_len = XVECTOR_LENGTH (instantiator); + + meths = decode_image_instantiator_format (elt[0], ERROR_ME); + + for (i = 1; i < instantiator_len; i += 2) + { + int j; + Lisp_Object keyword = elt[i]; + Lisp_Object value = elt[i+1]; + + /* Find the keyword entry. */ + for (j = 0; j < Dynarr_length (meths->keywords); j++) + { + if (EQ (keyword, Dynarr_at (meths->keywords, j).keyword)) + break; + } + + /* Only copy keyword values that should be copied. */ + if (Dynarr_at (meths->keywords, j).copy_p + && + (CONSP (value) || VECTORP (value))) + { + elt [i+1] = Fcopy_tree (value, Qt); + } + } + + return instantiator; +} + +static Lisp_Object +image_copy_instantiator (Lisp_Object arg) +{ + if (CONSP (arg)) + { + Lisp_Object rest; + rest = arg = Fcopy_sequence (arg); + while (CONSP (rest)) + { + Lisp_Object elt = XCAR (rest); + if (CONSP (elt)) + XCAR (rest) = Fcopy_tree (elt, Qt); + else if (VECTORP (elt)) + XCAR (rest) = image_copy_vector_instantiator (elt); + if (VECTORP (XCDR (rest))) /* hack for (a b . [c d]) */ + XCDR (rest) = Fcopy_tree (XCDR (rest), Qt); + rest = XCDR (rest); + } + } + else if (VECTORP (arg)) + { + arg = image_copy_vector_instantiator (arg); + } + return arg; +} + DEFUN ("image-specifier-p", Fimage_specifier_p, 1, 1, 0, /* Return non-nil if OBJECT is an image specifier. @@ -4473,6 +4545,7 @@ SPECIFIER_HAS_METHOD (image, validate); SPECIFIER_HAS_METHOD (image, after_change); SPECIFIER_HAS_METHOD (image, going_to_add); + SPECIFIER_HAS_METHOD (image, copy_instantiator); } void Index: src/glyphs.h =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs.h,v retrieving revision 1.18.2.22 diff -u -r1.18.2.22 glyphs.h --- src/glyphs.h 1999/10/24 03:48:41 1.18.2.22 +++ src/glyphs.h 1999/12/21 16:51:40 @@ -74,6 +74,7 @@ Lisp_Object keyword; void (*validate) (Lisp_Object data); int multiple_p; + int copy_p; }; typedef struct @@ -130,6 +131,13 @@ Lisp_Object (*set_property_method) (Lisp_Object image_instance, Lisp_Object property, Lisp_Object val); + + /* Find out the geometry of this image instance. */ + void (*query_geometry_method) (Lisp_Object image_instance, + int* width, int* height, int disp); + + /* Layout the instances children. */ + void (*layout_children_method) (Lisp_Object image_instance); }; /***** Calling an image-instantiator method *****/ @@ -202,29 +210,31 @@ /* Declare that KEYW is a valid keyword for image-instantiator format FORMAT. VALIDATE_FUN if a function that returns whether the data is valid. The keyword may not appear more than once. */ -#define IIFORMAT_VALID_KEYWORD(format, keyw, validate_fun) \ - do { \ +#define IIFORMAT_VALID_GENERIC_KEYWORD(format, keyw, validate_fun, copy, multi) \ + do { \ struct ii_keyword_entry entry; \ - \ - entry.keyword = keyw; \ + \ + entry.keyword = keyw; \ entry.validate = validate_fun; \ - entry.multiple_p = 0; \ + entry.multiple_p = multi; \ + entry.copy_p = copy; \ Dynarr_add (format##_image_instantiator_methods->keywords, \ entry); \ } while (0) +#define IIFORMAT_VALID_KEYWORD(format, keyw, validate_fun) \ +IIFORMAT_VALID_GENERIC_KEYWORD(format, keyw, validate_fun, 1, 0) + /* Same as IIFORMAT_VALID_KEYWORD except that the keyword may appear multiple times. */ -#define IIFORMAT_VALID_MULTI_KEYWORD(format, keyword, validate_fun) \ - do { \ - struct ii_keyword_entry entry; \ - \ - entry.keyword = keyword; \ - entry.validate = validate_fun; \ - entry.multiple_p = 1; \ - Dynarr_add (format##_image_instantiator_methods->keywords, \ - entry); \ - } while (0) +#define IIFORMAT_VALID_MULTI_KEYWORD(format, keyw, validate_fun) \ +IIFORMAT_VALID_GENERIC_KEYWORD(format, keyw, validate_fun, 1, 1) + +/* Same as IIFORMAT_VALID_KEYWORD execpt that the argument is not + copied by the specifier functions. This is necessary for things + like callbacks etc. */ +#define IIFORMAT_VALID_NONCOPY_KEYWORD(format, keyw, validate_fun) \ +IIFORMAT_VALID_GENERIC_KEYWORD(format, keyw, validate_fun, 0, 0) /* Declare that image-instantiator format FORMAT is supported on CONSOLE type. */ @@ -362,6 +372,14 @@ IMAGE_LAYOUT }; +enum image_instance_geometry +{ + IMAGE_GEOMETRY, + IMAGE_DESIRED_GEOMETRY, + IMAGE_MIN_GEOMETRY, + IMAGE_MAX_GEOMETRY +}; + #define IMAGE_NOTHING_MASK (1 << 0) #define IMAGE_TEXT_MASK (1 << 1) #define IMAGE_MONO_PIXMAP_MASK (1 << 2) @@ -446,18 +464,20 @@ Lisp_Object device; Lisp_Object name; enum image_instance_type type; - int x_offset, y_offset; /* for layout purposes */ + unsigned int x_offset, y_offset; /* for layout purposes */ + unsigned int width, height; unsigned int dirty : 1; union { struct { + unsigned int descent; Lisp_Object string; } text; struct { - int width, height, depth; - int slice, maxslice, timeout; + unsigned int depth; + unsigned int slice, maxslice, timeout; Lisp_Object hotspot_x, hotspot_y; /* integer or Qnil */ Lisp_Object filename; /* string or Qnil */ Lisp_Object mask_filename; /* string or Qnil */ @@ -471,7 +491,6 @@ struct { Lisp_Object frame; - unsigned int width, height; void* subwindow; /* specific devices can use this as necessary */ unsigned int being_displayed : 1; /* used to detect when needs to be unmapped */ union @@ -501,15 +520,24 @@ #define IMAGE_INSTANCE_TYPE(i) ((i)->type) #define IMAGE_INSTANCE_XOFFSET(i) ((i)->x_offset) #define IMAGE_INSTANCE_YOFFSET(i) ((i)->y_offset) +#define IMAGE_INSTANCE_WIDTH(i) ((i)->width) +#define IMAGE_INSTANCE_HEIGHT(i) ((i)->height) #define IMAGE_INSTANCE_PIXMAP_TYPE_P(i) \ ((IMAGE_INSTANCE_TYPE (i) == IMAGE_MONO_PIXMAP) \ || (IMAGE_INSTANCE_TYPE (i) == IMAGE_COLOR_PIXMAP)) #define IMAGE_INSTANCE_DIRTYP(i) ((i)->dirty) #define IMAGE_INSTANCE_TEXT_STRING(i) ((i)->u.text.string) - -#define IMAGE_INSTANCE_PIXMAP_WIDTH(i) ((i)->u.pixmap.width) -#define IMAGE_INSTANCE_PIXMAP_HEIGHT(i) ((i)->u.pixmap.height) +#define IMAGE_INSTANCE_TEXT_WIDTH(i) \ + IMAGE_INSTANCE_WIDTH(i) +#define IMAGE_INSTANCE_TEXT_HEIGHT(i) \ + IMAGE_INSTANCE_HEIGHT(i) +#define IMAGE_INSTANCE_TEXT_DESCENT(i) ((i)->u.text.descent) + +#define IMAGE_INSTANCE_PIXMAP_WIDTH(i) \ + IMAGE_INSTANCE_WIDTH(i) +#define IMAGE_INSTANCE_PIXMAP_HEIGHT(i) \ + IMAGE_INSTANCE_HEIGHT(i) #define IMAGE_INSTANCE_PIXMAP_DEPTH(i) ((i)->u.pixmap.depth) #define IMAGE_INSTANCE_PIXMAP_FILENAME(i) ((i)->u.pixmap.filename) #define IMAGE_INSTANCE_PIXMAP_MASK_FILENAME(i) ((i)->u.pixmap.mask_filename) @@ -523,17 +551,19 @@ #define IMAGE_INSTANCE_PIXMAP_MAXSLICE(i) ((i)->u.pixmap.maxslice) #define IMAGE_INSTANCE_PIXMAP_TIMEOUT(i) ((i)->u.pixmap.timeout) -#define IMAGE_INSTANCE_SUBWINDOW_WIDTH(i) ((i)->u.subwindow.width) -#define IMAGE_INSTANCE_SUBWINDOW_HEIGHT(i) ((i)->u.subwindow.height) +#define IMAGE_INSTANCE_SUBWINDOW_WIDTH(i) \ + IMAGE_INSTANCE_WIDTH(i) +#define IMAGE_INSTANCE_SUBWINDOW_HEIGHT(i) \ + IMAGE_INSTANCE_HEIGHT(i) #define IMAGE_INSTANCE_SUBWINDOW_ID(i) ((i)->u.subwindow.subwindow) #define IMAGE_INSTANCE_SUBWINDOW_FRAME(i) ((i)->u.subwindow.frame) #define IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP(i) \ ((i)->u.subwindow.being_displayed) #define IMAGE_INSTANCE_WIDGET_WIDTH(i) \ - IMAGE_INSTANCE_SUBWINDOW_WIDTH(i) + IMAGE_INSTANCE_WIDTH(i) #define IMAGE_INSTANCE_WIDGET_HEIGHT(i) \ - IMAGE_INSTANCE_SUBWINDOW_HEIGHT(i) + IMAGE_INSTANCE_HEIGHT(i) #define IMAGE_INSTANCE_WIDGET_TYPE(i) ((i)->u.subwindow.s.widget.type) #define IMAGE_INSTANCE_WIDGET_PROPS(i) ((i)->u.subwindow.s.widget.props) #define IMAGE_INSTANCE_WIDGET_FACE(i) ((i)->u.subwindow.s.widget.face) Index: src/redisplay.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/redisplay.c,v retrieving revision 1.55.2.26 diff -u -r1.55.2.26 redisplay.c --- src/redisplay.c 1999/12/04 20:03:39 1.55.2.26 +++ src/redisplay.c 1999/12/21 16:52:44 @@ -6311,6 +6311,7 @@ process.*/ if (!Dynarr_length (f->subwindow_cachels) || f->subwindows_changed + || f->faces_changed || f->frame_changed) { reset_subwindow_cachels (f); Index: src/specifier.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/specifier.c,v retrieving revision 1.15.2.11 diff -u -r1.15.2.11 specifier.c --- src/specifier.c 1999/10/24 03:48:49 1.15.2.11 +++ src/specifier.c 1999/12/21 16:53:11 @@ -1648,10 +1648,16 @@ LIST_LOOP (rest, inst_list) { Lisp_Object tag_set = XCAR (XCAR (rest)); - Lisp_Object instantiator = Fcopy_tree (XCDR (XCAR (rest)), Qt); Lisp_Object sub_inst_list = Qnil; + Lisp_Object instantiator; struct gcpro ngcpro1, ngcpro2; + if (HAS_SPECMETH_P (sp, copy_instantiator)) + instantiator = SPECMETH (sp, copy_instantiator, + (XCDR (XCAR (rest)))); + else + instantiator = Fcopy_tree (XCDR (XCAR (rest)), Qt); + NGCPRO2 (instantiator, sub_inst_list); /* call the will-add method; it may GC */ sub_inst_list = HAS_SPECMETH_P (sp, going_to_add) ? @@ -2539,7 +2545,7 @@ goto do_fallback; } -retry: + retry: /* First see if we can generate one from the window specifiers. */ if (!NILP (window)) CHECK_INSTANCE_ENTRY (window, matchspec, LOCALE_WINDOW); @@ -2558,7 +2564,7 @@ /* Last and least try the global specifiers. */ CHECK_INSTANCE_ENTRY (Qglobal, matchspec, LOCALE_GLOBAL); -do_fallback: + do_fallback: /* We're out of specifiers and we still haven't generated an instance. At least try the fallback ... If this fails, then we just return Qunbound. */ Index: src/specifier.h =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/specifier.h,v retrieving revision 1.6.2.5 diff -u -r1.6.2.5 specifier.h --- src/specifier.h 1999/10/24 03:48:50 1.6.2.5 +++ src/specifier.h 1999/12/21 16:53:12 @@ -124,6 +124,13 @@ valid. */ void (*validate_method) (Lisp_Object instantiator); + + /* Copy method: Given an instantiator, copy the bits that we need to + for this specifier type. + + If this function is not present, then Fcopy_tree is used. */ + Lisp_Object (*copy_instantiator_method) (Lisp_Object instantiator); + /* Validate-matchspec method: Given a matchspec, verify that it's valid for this specifier type. If not, signal an error.