Index: lisp/gutter-items.el =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/lisp/Attic/gutter-items.el,v retrieving revision 1.1.2.13 diff -u -r1.1.2.13 gutter-items.el --- lisp/gutter-items.el 1999/08/17 11:33:33 1.1.2.13 +++ lisp/gutter-items.el 1999/08/23 16:34:12 @@ -228,6 +228,8 @@ (defun update-tab-in-gutter (&optional frame-or-buffer) "Update the tab control in the gutter area." + (unless gutter-buffers-tab + (add-tab-to-gutter)) (when (valid-image-instantiator-format-p 'tab-control) (let ((inst (glyph-image-instance gutter-buffers-tab @@ -254,7 +256,6 @@ (resize-subwindow inst (gutter-pixel-width) nil) ))) -(add-tab-to-gutter) (add-hook 'kill-buffer-hook 'remove-buffer-from-gutter-tab) (add-hook 'create-frame-hook 'update-tab-in-gutter) (add-hook 'record-buffer-hook 'update-tab-in-gutter) Index: lwlib/lwlib-Xaw.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/lwlib/lwlib-Xaw.c,v retrieving revision 1.9.2.1 diff -u -r1.9.2.1 lwlib-Xaw.c --- lwlib/lwlib-Xaw.c 1999/07/30 09:13:53 1.9.2.1 +++ lwlib/lwlib-Xaw.c 1999/08/23 16:34:17 @@ -747,6 +747,12 @@ return button; } +static Widget +xaw_create_label_field (widget_instance *instance) +{ + return xaw_create_label (instance->parent, instance->info->val); +} + Widget xaw_create_label (Widget parent, widget_value* val) { @@ -838,6 +844,7 @@ #endif #ifdef LWLIB_WIDGETS_ATHENA {"button", xaw_create_button }, + { "label", xaw_create_label_field }, #ifndef NEED_MOTIF {"text-field", xaw_create_text_field }, #endif Index: lwlib/lwlib-Xm.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/lwlib/lwlib-Xm.c,v retrieving revision 1.11.2.7 diff -u -r1.11.2.7 lwlib-Xm.c --- lwlib/lwlib-Xm.c 1999/08/16 11:18:50 1.11.2.7 +++ lwlib/lwlib-Xm.c 1999/08/23 16:34:19 @@ -1689,6 +1689,12 @@ return text; } +static Widget +xm_create_label_field (widget_instance *instance) +{ + return xm_create_label (instance->parent, instance->info->val); +} + Widget xm_create_label (Widget parent, widget_value* val) { @@ -1765,6 +1771,7 @@ {"button", xm_create_button}, {"progress", xm_create_progress}, {"text-field", xm_create_text_field}, + {"label", xm_create_label_field}, #if XmVERSION > 1 {"combo-box", xm_create_combo_box}, #endif Index: lwlib/lwlib.h =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/lwlib/lwlib.h,v retrieving revision 1.4.2.3 diff -u -r1.4.2.3 lwlib.h --- lwlib/lwlib.h 1999/08/16 11:18:50 1.4.2.3 +++ lwlib/lwlib.h 1999/08/23 16:34:20 @@ -181,6 +181,10 @@ /* do this for the other toolkits too */ #endif /* LWLIB_MENUBARS_LUCID */ +#if defined (LWLIB_TABS_LUCID) +#include "xlwtabs.h" +#endif + void lw_register_widget (CONST char* type, CONST char* name, LWLIB_ID id, widget_value* val, lw_callback pre_activate_cb, lw_callback selection_cb, Index: lwlib/xlwtabs.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/lwlib/Attic/xlwtabs.c,v retrieving revision 1.1.2.2 diff -u -r1.1.2.2 xlwtabs.c --- lwlib/xlwtabs.c 1999/08/04 13:55:22 1.1.2.2 +++ lwlib/xlwtabs.c 1999/08/23 16:34:33 @@ -640,13 +640,16 @@ * Tabs widget might. */ - if( tw->tabs.needs_layout ) { - XClearWindow(XtDisplay((Widget)tw), XtWindow((Widget)tw)) ; - XtClass(tw)->core_class.expose((Widget)tw,NULL,None) ; - } - - else if( tab->tabs.foreground != ctab->tabs.foreground ) - DrawTab(tw, new, True) ; + if( XtIsRealized((Widget)tw) ) + { + if( tw->tabs.needs_layout ) { + XClearWindow(XtDisplay((Widget)tw), XtWindow((Widget)tw)) ; + XtClass(tw)->core_class.expose((Widget)tw,NULL,None) ; + } + + else if( tab->tabs.foreground != ctab->tabs.foreground ) + DrawTab(tw, new, True) ; + } return False ; } Index: src/console.h =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/console.h,v retrieving revision 1.22.2.8 diff -u -r1.22.2.8 console.h --- src/console.h 1999/07/16 19:05:37 1.22.2.8 +++ src/console.h 1999/08/23 16:34:35 @@ -155,8 +155,15 @@ int duration); void (*frame_redraw_cursor_method) (struct frame *f); void (*set_final_cursor_coords_method) (struct frame *, int, int); - void (*bevel_area_method) (struct window *, face_index, int, int, int, int, int); - + void (*bevel_area_method) (struct window *, face_index, int, int, int, int, int, + int, enum edge_style); + void (*output_pixmap_method) (struct window *w, Lisp_Object image_instance, + struct display_box *db, struct display_glyph_area *dga, + face_index findex, int cursor_start, int cursor_width, + int cursor_height, int offset_bitmap); + void (*output_string_method) (struct window *w, struct display_line *dl, + Emchar_dynarr *buf, int xpos, int xoffset, int clip_start, + int width, face_index findex); /* color methods */ int (*initialize_color_instance_method) (struct Lisp_Color_Instance *, Lisp_Object name, Index: src/event-Xt.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/event-Xt.c,v retrieving revision 1.41.2.11 diff -u -r1.41.2.11 event-Xt.c --- src/event-Xt.c 1999/07/30 09:14:01 1.41.2.11 +++ src/event-Xt.c 1999/08/23 16:34:42 @@ -1570,7 +1570,10 @@ case Expose: if (!check_for_ignored_expose (f, event->xexpose.x, event->xexpose.y, - event->xexpose.width, event->xexpose.height)) + event->xexpose.width, event->xexpose.height) + && + !find_matching_subwindow (f, event->xexpose.x, event->xexpose.y, + event->xexpose.width, event->xexpose.height)) x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y, event->xexpose.width, event->xexpose.height); break; Index: src/general.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/general.c,v retrieving revision 1.13.2.3 diff -u -r1.13.2.3 general.c --- src/general.c 1999/07/16 19:05:40 1.13.2.3 +++ src/general.c 1999/08/23 16:34:46 @@ -52,6 +52,7 @@ Lisp_Object Qbuffer; Lisp_Object Qbutton; Lisp_Object Qcase; +Lisp_Object Qcenter; Lisp_Object Qcategory; Lisp_Object Qchannel; Lisp_Object Qchar; @@ -92,6 +93,7 @@ Lisp_Object Qgutter; Lisp_Object Qheight; Lisp_Object Qhighlight; +Lisp_Object Qhorizontal; Lisp_Object Qicon; Lisp_Object Qid; Lisp_Object Qimage; @@ -105,6 +107,7 @@ Lisp_Object Qkeymap; Lisp_Object Qkrbv41; Lisp_Object Qkrbv42; +Lisp_Object Qlayout; Lisp_Object Qleft; Lisp_Object Qlist; Lisp_Object Qmagic; @@ -176,6 +179,7 @@ Lisp_Object Qunimplemented; Lisp_Object Qvalue_assoc; Lisp_Object Qvector; +Lisp_Object Qvertical; Lisp_Object Qwarning; Lisp_Object Qwhite; Lisp_Object Qwidth; @@ -210,6 +214,7 @@ defsymbol (&Qbutton, "button"); defsymbol (&Qcase, "case"); defsymbol (&Qcategory, "category"); + defsymbol (&Qcenter, "center"); defsymbol (&Qchannel, "channel"); defsymbol (&Qchar, "char"); defsymbol (&Qcharacter, "character"); @@ -249,6 +254,7 @@ defsymbol (&Qgutter, "gutter"); defsymbol (&Qheight, "height"); defsymbol (&Qhighlight, "highlight"); + defsymbol (&Qhorizontal, "horizontal"); defsymbol (&Qicon, "icon"); defsymbol (&Qid, "id"); defsymbol (&Qimage, "image"); @@ -262,6 +268,7 @@ defsymbol (&Qkeymap, "keymap"); defsymbol (&Qkrbv41, "krbv41"); defsymbol (&Qkrbv42, "krbv42"); + defsymbol (&Qlayout, "layout"); defsymbol (&Qleft, "left"); defsymbol (&Qlist, "list"); defsymbol (&Qmagic, "magic"); @@ -333,6 +340,7 @@ defsymbol (&Qunimplemented, "unimplemented"); defsymbol (&Qvalue_assoc, "value-assoc"); defsymbol (&Qvector, "vector"); + defsymbol (&Qvertical, "vertical"); defsymbol (&Qwarning, "warning"); defsymbol (&Qwhite, "white"); defsymbol (&Qwidth, "width"); Index: src/glyphs-msw.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs-msw.c,v retrieving revision 1.21.2.21 diff -u -r1.21.2.21 glyphs-msw.c --- src/glyphs-msw.c 1999/08/08 13:50:09 1.21.2.21 +++ src/glyphs-msw.c 1999/08/23 16:34:53 @@ -57,6 +57,7 @@ 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 @@ -2786,6 +2787,7 @@ { IIFORMAT_VALID_CONSOLE (mswindows, nothing); IIFORMAT_VALID_CONSOLE (mswindows, string); + IIFORMAT_VALID_CONSOLE (mswindows, layout); IIFORMAT_VALID_CONSOLE (mswindows, formatted_string); IIFORMAT_VALID_CONSOLE (mswindows, inherit); /* image-instantiator types */ Index: src/glyphs-msw.h =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs-msw.h,v retrieving revision 1.7.2.1 diff -u -r1.7.2.1 glyphs-msw.h --- src/glyphs-msw.h 1998/12/18 05:42:08 1.7.2.1 +++ src/glyphs-msw.h 1999/08/23 16:35:13 @@ -35,7 +35,6 @@ struct mswindows_image_instance_data { HBITMAP bitmap; - HBITMAP mask; HICON icon; }; @@ -45,7 +44,7 @@ #define IMAGE_INSTANCE_MSWINDOWS_BITMAP(i) \ (MSWINDOWS_IMAGE_INSTANCE_DATA (i)->bitmap) #define IMAGE_INSTANCE_MSWINDOWS_MASK(i) \ - (MSWINDOWS_IMAGE_INSTANCE_DATA (i)->mask) + (HBITMAP)(IMAGE_INSTANCE_PIXMAP_MASK (i)) #define IMAGE_INSTANCE_MSWINDOWS_ICON(i) \ (MSWINDOWS_IMAGE_INSTANCE_DATA (i)->icon) Index: src/glyphs-widget.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/Attic/glyphs-widget.c,v retrieving revision 1.1.2.9 diff -u -r1.1.2.9 glyphs-widget.c --- src/glyphs-widget.c 1999/08/08 13:50:09 1.1.2.9 +++ src/glyphs-widget.c 1999/08/23 16:35:13 @@ -57,9 +57,12 @@ Lisp_Object Qtree_view; DEFINE_IMAGE_INSTANTIATOR_FORMAT (tab_control); Lisp_Object Qtab_control; +DEFINE_IMAGE_INSTANTIATOR_FORMAT (layout); +Lisp_Object Qlayout; Lisp_Object Q_descriptor, Q_height, Q_width, Q_properties, Q_items; -Lisp_Object Q_image, Q_text, Q_percent; +Lisp_Object Q_image, Q_text, Q_percent, Q_orientation, Q_justify, Q_border; +Lisp_Object Qetched_in, Qetched_out, Qbevel_in, Qbevel_out; #define WIDGET_BORDER_HEIGHT 4 #define WIDGET_BORDER_WIDTH 4 @@ -125,6 +128,30 @@ } static void +check_valid_orientation (Lisp_Object data) +{ + if (!EQ (data, Qhorizontal) + && + !EQ (data, Qvertical)) + signal_simple_error ("unknown orientation for layout", data); +} + +static void +check_valid_justification (Lisp_Object data) +{ + if (!EQ (data, Qleft) && !EQ (data, Qright) && !EQ (data, Qcenter)) + signal_simple_error ("unknown justification for layout", data); +} + +static void +check_valid_border (Lisp_Object data) +{ + if (!EQ (data, Qt) && !EQ (data, Qetched_in) && !EQ (data, Qetched_out) + && !EQ (data, Qbevel_in) && !EQ (data, Qbevel_out)) + signal_simple_error ("unknown border style for layout", data); +} + +static void check_valid_anything (Lisp_Object data) { } @@ -183,6 +210,18 @@ check_valid_item_list_1 (items); } +static void +check_valid_glyph_or_image_list (Lisp_Object data) +{ + Lisp_Object rest; + + CHECK_LIST (data); + EXTERNAL_LIST_LOOP (rest, data) + { + check_valid_glyph_or_image (XCAR (rest)); + } +} + /* wire widget property invocations to specific widgets ... The problem we are solving here is that when instantiators get converted to instances they lose some type information (they just become @@ -503,6 +542,198 @@ } +/***************************************************************************** + * widget layout * + *****************************************************************************/ +static int +layout_possible_dest_types (void) +{ + return IMAGE_LAYOUT_MASK; +} + +/* we need to convert things like glyphs to images, eval expressions + etc.*/ +static Lisp_Object +layout_normalize (Lisp_Object inst, Lisp_Object console_type) +{ + /* This function can call lisp */ + Lisp_Object items = find_keyword_in_vector (inst, Q_items); + + /* we need to eval glyph if its an expression, we do this for the + same reasons we normalize file to data. */ + if (!NILP (items)) + { + Lisp_Object rest; + LIST_LOOP (rest, items) + { + Lisp_Object glyph = XCAR (rest); + struct gcpro gcpro1; + + /* if we have a symbol get at the actual data */ + if (SYMBOLP (glyph)) + glyph = XSYMBOL (glyph)->value; + GCPRO1 (glyph); + + if (CONSP (glyph)) + glyph = Feval (glyph); + /* substitute the new glyph */ + Fsetcar (rest, glyph); + + UNGCPRO; + } + } + return inst; +} + +/* Instantiate a layout widget. */ +static void +layout_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, + Lisp_Object pointer_fg, Lisp_Object pointer_bg, + int dest_mask, Lisp_Object domain) +{ + struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + Lisp_Object rest, device = IMAGE_INSTANCE_DEVICE (ii); + Lisp_Object frame = FW_FRAME (domain); + Lisp_Object items = find_keyword_in_vector (instantiator, Q_items); + Lisp_Object width = find_keyword_in_vector (instantiator, Q_pixel_width); + Lisp_Object height = find_keyword_in_vector (instantiator, Q_pixel_height); + Lisp_Object orient = find_keyword_in_vector (instantiator, Q_orientation); + Lisp_Object justify = find_keyword_in_vector (instantiator, Q_justify); + Lisp_Object border = find_keyword_in_vector (instantiator, Q_border); + Lisp_Object children = Qnil; + int pw = 0, ph = 0, x, y, maxph = 0, maxpw = 0, nitems = 0, + horiz_spacing, vert_spacing; + + if (NILP (frame)) + signal_simple_error ("No selected frame", device); + + if (!(dest_mask & IMAGE_LAYOUT_MASK)) + incompatible_image_types (instantiator, dest_mask, IMAGE_LAYOUT_MASK); + + if (NILP (orient)) + orient = Qvertical; + + if (EQ (border, Qt)) + border = Qetched_in; + + ii->data = 0; + IMAGE_INSTANCE_TYPE (ii) = IMAGE_LAYOUT; + IMAGE_INSTANCE_SUBWINDOW_ID (ii) = 0; + IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; + IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = frame; + IMAGE_INSTANCE_LAYOUT_BORDER (ii) = border; + /* normalize size information */ + if (!NILP (width)) + pw = XINT (width); + if (!NILP (height)) + ph = XINT (height); + + /* flip through the items to work out how much stuff we have to display */ + LIST_LOOP (rest, items) + { + Lisp_Object glyph = XCAR (rest); + int gheight = glyph_height (glyph, Qnil, DEFAULT_INDEX, domain); + int gwidth = glyph_width (glyph, Qnil, DEFAULT_INDEX, domain); + nitems ++; + if (EQ (orient, Qhorizontal)) + { + maxph = max (maxph, gheight); + maxpw += gwidth; + } + else if (EQ (orient, Qvertical)) + { + maxpw = max (maxpw, gwidth); + maxph += gheight; + } + } + + /* work out spacing between items and bounds of the layout */ + if (!pw) + { + /* No user provided width so we just do default spacing. */ + horiz_spacing = WIDGET_BORDER_WIDTH * 2; + if (EQ (orient, Qhorizontal)) + pw = maxpw + (nitems + 1) * horiz_spacing; + else + pw = maxpw + 2 * horiz_spacing; + } + else if (pw < maxpw) + /* The user wants a smaller space than the largest item, so we + just provide default spacing and will let the output routines + clip.. */ + horiz_spacing = WIDGET_BORDER_WIDTH * 2; + else if (EQ (orient, Qhorizontal)) + /* We have a larger area to display in so distribute the space + evenly. */ + horiz_spacing = (pw - maxpw) / (nitems + 1); + else + horiz_spacing = (pw - maxpw) / 2; + + if (!ph) + { + vert_spacing = WIDGET_BORDER_HEIGHT * 2; + if (EQ (orient, Qvertical)) + ph = maxph + (nitems + 1) * vert_spacing; + else + ph = maxph + 2 * vert_spacing; + } + else if (ph < maxph) + vert_spacing = WIDGET_BORDER_HEIGHT * 2; + else if (EQ (orient, Qvertical)) + vert_spacing = (ph - maxph) / (nitems + 1); + else + vert_spacing = (ph - maxph) / 2; + + y = vert_spacing; + x = horiz_spacing; + + /* Now flip through putting items where we want them, paying + attention to justification. */ + LIST_LOOP (rest, items) + { + /* make sure the image is instantiated */ + Lisp_Object glyph = XCAR (rest); + Lisp_Object ii = glyph_image_instance (glyph, domain, ERROR_ME, 1); + int gwidth = glyph_width (glyph, Qnil, DEFAULT_INDEX, domain); + int gheight = glyph_height (glyph, Qnil, DEFAULT_INDEX, domain); + + children = Fcons (ii, children); + + if (EQ (orient, Qhorizontal)) + { + if (EQ (justify, Qright)) + y = ph - (gheight + vert_spacing); + else if (EQ (justify, Qcenter)) + y = (ph - gheight) / 2; + } + else if (EQ (orient, Qvertical)) + { + if (EQ (justify, Qright)) + x = pw - (gwidth + horiz_spacing); + else if (EQ (justify, Qcenter)) + x = (pw - gwidth) / 2; + } + + XIMAGE_INSTANCE_XOFFSET (ii) = x; + XIMAGE_INSTANCE_YOFFSET (ii) = y; + + if (EQ (orient, Qhorizontal)) + { + x += (gwidth + horiz_spacing); + } + else if (EQ (orient, Qvertical)) + { + y += (gheight + vert_spacing); + } + } + + IMAGE_INSTANCE_LAYOUT_CHILDREN (ii) = children; + assert (pw && ph); + IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = pw; + IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = ph; +} + + /************************************************************************/ /* initialization */ /************************************************************************/ @@ -518,6 +749,14 @@ defkeyword (&Q_image, ":image"); defkeyword (&Q_percent, ":percent"); defkeyword (&Q_text, ":text"); + defkeyword (&Q_orientation, ":orientation"); + defkeyword (&Q_justify, ":justify"); + defkeyword (&Q_border, ":border"); + + defsymbol (&Qetched_in, "etched-in"); + defsymbol (&Qetched_out, "etched-out"); + defsymbol (&Qbevel_in, "bevel-in"); + defsymbol (&Qbevel_out, "bevel-out"); } void @@ -623,6 +862,18 @@ IIFORMAT_HAS_SHARED_METHOD (label, instantiate, static); VALID_WIDGET_KEYWORDS (label); IIFORMAT_VALID_KEYWORD (label, Q_descriptor, check_valid_string); + + /* layout */ + INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (layout, "layout"); + IIFORMAT_HAS_METHOD (layout, possible_dest_types); + IIFORMAT_HAS_METHOD (layout, instantiate); + IIFORMAT_HAS_METHOD (layout, normalize); + IIFORMAT_VALID_KEYWORD (layout, Q_pixel_width, check_valid_int); + IIFORMAT_VALID_KEYWORD (layout, Q_pixel_height, check_valid_int); + IIFORMAT_VALID_KEYWORD (layout, Q_orientation, check_valid_orientation); + IIFORMAT_VALID_KEYWORD (layout, Q_justify, check_valid_justification); + IIFORMAT_VALID_KEYWORD (layout, Q_border, check_valid_border); + IIFORMAT_VALID_KEYWORD (layout, Q_items, check_valid_glyph_or_image_list); #if 0 /* group */ Index: src/glyphs-x.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs-x.c,v retrieving revision 1.49.2.19 diff -u -r1.49.2.19 glyphs-x.c --- src/glyphs-x.c 1999/08/16 11:18:53 1.49.2.19 +++ src/glyphs-x.c 1999/08/23 16:36:02 @@ -95,6 +95,7 @@ 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 @@ -132,6 +133,7 @@ DEFINE_DEVICE_IIFORMAT (x, combo_box); #endif DEFINE_DEVICE_IIFORMAT (x, tab_control); +DEFINE_DEVICE_IIFORMAT (x, label); #endif static void cursor_font_instantiate (Lisp_Object image_instance, @@ -2286,6 +2288,25 @@ lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (ii), wv, False); return Qt; } + /* Modify the colors of the widget */ + if (EQ (prop, Q_face)) + { + Arg al [2]; + XColor fcolor, bcolor; + Lisp_Object pixel = FACE_FOREGROUND + (IMAGE_INSTANCE_WIDGET_FACE (ii), + IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); + fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); + pixel = FACE_BACKGROUND + (IMAGE_INSTANCE_WIDGET_FACE (ii), + IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); + bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); + + XtSetArg (al [0], XtNforeground, fcolor.pixel); + XtSetArg (al [1], XtNbackground, bcolor.pixel); + XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, 2); + return Qt; + } return Qunbound; } @@ -2443,9 +2464,22 @@ widget_value * wv = gui_items_to_widget_values (IMAGE_INSTANCE_WIDGET_ITEMS (ii)); - + x_widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, dest_mask, domain, "tab-control", wv); +#if 0 + { + Arg al [1]; + XColor fcolor; + Lisp_Object 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); + XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, 1); + } +#endif } /* set the properties of a tab control */ @@ -2471,8 +2505,40 @@ free_widget_value_tree (wv); return Qt; } + /* Modify the foreground property of the tab widget */ +#if 0 + if (EQ (prop, Q_face)) + { + Arg al [1]; + XColor fcolor; + Lisp_Object 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); + XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, 1); + return Qt; + } +#endif return Qunbound; } + +/* instantiate a static control possible for putting other things in */ +static void +x_label_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, + Lisp_Object pointer_fg, Lisp_Object pointer_bg, + int dest_mask, Lisp_Object domain) +{ + struct 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); + + x_widget_instantiate (image_instance, instantiator, pointer_fg, + pointer_bg, dest_mask, domain, "button", wv); +} #endif /* HAVE_WIDGETS */ @@ -2511,6 +2577,7 @@ { IIFORMAT_VALID_CONSOLE (x, nothing); IIFORMAT_VALID_CONSOLE (x, string); + IIFORMAT_VALID_CONSOLE (x, layout); IIFORMAT_VALID_CONSOLE (x, formatted_string); IIFORMAT_VALID_CONSOLE (x, inherit); #ifdef HAVE_XPM @@ -2560,6 +2627,9 @@ INITIALIZE_DEVICE_IIFORMAT (x, tab_control); IIFORMAT_HAS_DEVMETHOD (x, tab_control, instantiate); IIFORMAT_HAS_DEVMETHOD (x, tab_control, set_property); + /* label */ + INITIALIZE_DEVICE_IIFORMAT (x, label); + IIFORMAT_HAS_DEVMETHOD (x, label, instantiate); #endif INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (cursor_font, "cursor-font"); IIFORMAT_VALID_CONSOLE (x, cursor_font); Index: src/glyphs-x.h =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs-x.h,v retrieving revision 1.4.2.3 diff -u -r1.4.2.3 glyphs-x.h --- src/glyphs-x.h 1999/06/25 14:16:47 1.4.2.3 +++ src/glyphs-x.h 1999/08/23 16:36:02 @@ -40,7 +40,6 @@ struct x_image_instance_data { Pixmap pixmap; - Pixmap mask; Cursor cursor; /* If depth>0, then that means that other colors were allocated when @@ -57,7 +56,8 @@ #define X_IMAGE_INSTANCE_DATA(i) ((struct x_image_instance_data *) (i)->data) #define IMAGE_INSTANCE_X_PIXMAP(i) (X_IMAGE_INSTANCE_DATA (i)->pixmap) -#define IMAGE_INSTANCE_X_MASK(i) (X_IMAGE_INSTANCE_DATA (i)->mask) +#define IMAGE_INSTANCE_X_MASK(i) \ + (Pixmap)(IMAGE_INSTANCE_PIXMAP_MASK (i)) #define IMAGE_INSTANCE_X_CURSOR(i) (X_IMAGE_INSTANCE_DATA (i)->cursor) #define IMAGE_INSTANCE_X_COLORMAP(i) (X_IMAGE_INSTANCE_DATA (i)->colormap) #define IMAGE_INSTANCE_X_PIXELS(i) (X_IMAGE_INSTANCE_DATA (i)->pixels) Index: src/glyphs.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs.c,v retrieving revision 1.23.2.20 diff -u -r1.23.2.20 glyphs.c --- src/glyphs.c 1999/08/14 20:32:25 1.23.2.20 +++ src/glyphs.c 1999/08/23 16:36:09 @@ -57,6 +57,7 @@ Lisp_Object Qcolor_pixmap_image_instance_p; Lisp_Object Qpointer_image_instance_p; Lisp_Object Qsubwindow_image_instance_p; +Lisp_Object Qlayout_image_instance_p; Lisp_Object Qwidget_image_instance_p; Lisp_Object Qconst_glyph_variable; Lisp_Object Qmono_pixmap, Qcolor_pixmap, Qsubwindow; @@ -125,7 +126,7 @@ Lisp_Object locale); static void register_ignored_expose (struct frame* f, int x, int y, int width, int height); /* Unfortunately windows and X are different. In windows BeginPaint() - will prevent WM_PAINT messages being generate so it is unnecessary + will prevent WM_PAINT messages being generated so it is unnecessary to register exposures as they will not occur. Under X they will always occur. */ int hold_ignored_expose_registration; @@ -642,6 +643,12 @@ markobj (IMAGE_INSTANCE_SUBWINDOW_FRAME (i)); break; + case IMAGE_LAYOUT: + markobj (IMAGE_INSTANCE_LAYOUT_CHILDREN (i)); + markobj (IMAGE_INSTANCE_LAYOUT_BORDER (i)); + markobj (IMAGE_INSTANCE_SUBWINDOW_FRAME (i)); + break; + default: break; } @@ -763,6 +770,7 @@ print_internal (IMAGE_INSTANCE_WIDGET_TEXT (ii), printcharfun, 0); case IMAGE_SUBWINDOW: + case IMAGE_LAYOUT: sprintf (buf, " %dx%d", IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii), IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); write_c_string (buf, printcharfun); @@ -882,6 +890,16 @@ depth + 1) )) return 0; + case IMAGE_LAYOUT: + if (IMAGE_INSTANCE_TYPE (i1) == IMAGE_LAYOUT + && + !(EQ (IMAGE_INSTANCE_LAYOUT_BORDER (i1), + IMAGE_INSTANCE_LAYOUT_BORDER (i2)) + && + internal_equal (IMAGE_INSTANCE_LAYOUT_CHILDREN (i1), + IMAGE_INSTANCE_LAYOUT_CHILDREN (i2), + depth + 1))) + return 0; case IMAGE_SUBWINDOW: if (!(IMAGE_INSTANCE_SUBWINDOW_WIDTH (i1) == IMAGE_INSTANCE_SUBWINDOW_WIDTH (i2) && @@ -931,6 +949,12 @@ internal_hash (IMAGE_INSTANCE_WIDGET_TYPE (i), depth + 1), internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1), internal_hash (IMAGE_INSTANCE_WIDGET_ITEMS (i), depth + 1)); + case IMAGE_LAYOUT: + if (IMAGE_INSTANCE_TYPE (i) == IMAGE_LAYOUT) + hash = HASH3 (hash, + internal_hash (IMAGE_INSTANCE_LAYOUT_BORDER (i), depth + 1), + internal_hash (IMAGE_INSTANCE_LAYOUT_CHILDREN (i), + depth + 1)); case IMAGE_SUBWINDOW: hash = HASH4 (hash, IMAGE_INSTANCE_SUBWINDOW_WIDTH (i), IMAGE_INSTANCE_SUBWINDOW_HEIGHT (i), @@ -962,6 +986,8 @@ lp->device = device; lp->type = IMAGE_NOTHING; lp->name = Qnil; + lp->x_offset = 0; + lp->y_offset = 0; XSETIMAGE_INSTANCE (val, lp); return val; } @@ -979,6 +1005,7 @@ if (EQ (type, Qpointer)) return IMAGE_POINTER; if (EQ (type, Qsubwindow)) return IMAGE_SUBWINDOW; if (EQ (type, Qwidget)) return IMAGE_WIDGET; + if (EQ (type, Qlayout)) return IMAGE_LAYOUT; maybe_signal_simple_error ("Invalid image-instance type", type, Qimage, errb); @@ -998,6 +1025,7 @@ case IMAGE_POINTER: return Qpointer; case IMAGE_SUBWINDOW: return Qsubwindow; case IMAGE_WIDGET: return Qwidget; + case IMAGE_LAYOUT: return Qlayout; default: abort (); } @@ -1410,6 +1438,7 @@ case IMAGE_SUBWINDOW: case IMAGE_WIDGET: + case IMAGE_LAYOUT: return make_int (XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (image_instance)); default: @@ -1433,6 +1462,7 @@ case IMAGE_SUBWINDOW: case IMAGE_WIDGET: + case IMAGE_LAYOUT: return make_int (XIMAGE_INSTANCE_SUBWINDOW_WIDTH (image_instance)); default: @@ -3016,7 +3046,8 @@ XIMAGE_SPECIFIER_ALLOWED (g->image) = IMAGE_NOTHING_MASK | IMAGE_TEXT_MASK | IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK - | IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK; + | IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK + | IMAGE_LAYOUT_MASK; break; case GLYPH_POINTER: XIMAGE_SPECIFIER_ALLOWED (g->image) = @@ -3168,14 +3199,12 @@ glyph_width (Lisp_Object glyph, Lisp_Object frame_face, face_index window_findex, Lisp_Object window) { - Lisp_Object instance; + Lisp_Object instance = glyph; Lisp_Object frame = XWINDOW (window)->frame; /* #### We somehow need to distinguish between the user causing this error condition and a bug causing it. */ - if (!GLYPHP (glyph)) - return 0; - else + if (GLYPHP (glyph)) instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1); if (!IMAGE_INSTANCEP (instance)) @@ -3213,6 +3242,7 @@ case IMAGE_SUBWINDOW: case IMAGE_WIDGET: + case IMAGE_LAYOUT: return XIMAGE_INSTANCE_SUBWINDOW_WIDTH (instance); default: @@ -3255,12 +3285,10 @@ face_index window_findex, Lisp_Object window, int function) { - Lisp_Object instance; + Lisp_Object instance = glyph; Lisp_Object frame = XWINDOW (window)->frame; - if (!GLYPHP (glyph)) - return 0; - else + if (GLYPHP (glyph)) instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1); if (!IMAGE_INSTANCEP (instance)) @@ -3317,6 +3345,7 @@ case IMAGE_SUBWINDOW: case IMAGE_WIDGET: + case IMAGE_LAYOUT: /* #### Ugh ugh ugh -- temporary crap */ if (function == RETURN_ASCENT || function == RETURN_HEIGHT) return XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (instance); @@ -3819,6 +3848,35 @@ } } +/**************************************************************************** + find_matching_subwindow + + See if there is a subwindow that completely encloses the requested + area. + ****************************************************************************/ +int find_matching_subwindow (struct frame* f, int x, int y, int width, int height) +{ + int elt; + + for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) + { + struct subwindow_cachel *cachel = + Dynarr_atp (f->subwindow_cachels, elt); + + if (cachel->being_displayed + && + cachel->x <= x && cachel->y <= y + && + cachel->x + cachel->width >= x + && + cachel->y + cachel->height >= y) + { + return 1; + } + } + return 0; +} + /***************************************************************************** * subwindow functions * @@ -3942,7 +4000,6 @@ ii->data = 0; IMAGE_INSTANCE_SUBWINDOW_ID (ii) = 0; - IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = Qnil; IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = frame; @@ -4114,6 +4171,7 @@ abort (); } } + /***************************************************************************** * initialization * @@ -4162,6 +4220,7 @@ defsymbol (&Qpointer_image_instance_p, "pointer-image-instance-p"); defsymbol (&Qwidget_image_instance_p, "widget-image-instance-p"); defsymbol (&Qsubwindow_image_instance_p, "subwindow-image-instance-p"); + defsymbol (&Qlayout_image_instance_p, "layout-image-instance-p"); DEFSUBR (Fmake_image_instance); DEFSUBR (Fimage_instance_p); Index: src/glyphs.h =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs.h,v retrieving revision 1.18.2.15 diff -u -r1.18.2.15 glyphs.h --- src/glyphs.h 1999/08/08 13:50:10 1.18.2.15 +++ src/glyphs.h 1999/08/23 16:36:12 @@ -56,8 +56,11 @@ inherit mono-pixmap autodetect mono-pixmap, color-pixmap, pointer, text button widget - edit widget - combo widget + edit-field widget + combo -box widget + progress-gauge widget + tab-control widget + tree-view widget scrollbar widget static widget */ @@ -350,7 +353,8 @@ IMAGE_COLOR_PIXMAP, IMAGE_POINTER, IMAGE_SUBWINDOW, - IMAGE_WIDGET + IMAGE_WIDGET, + IMAGE_LAYOUT }; #define IMAGE_NOTHING_MASK (1 << 0) @@ -360,6 +364,7 @@ #define IMAGE_POINTER_MASK (1 << 4) #define IMAGE_SUBWINDOW_MASK (1 << 5) #define IMAGE_WIDGET_MASK (1 << 6) +#define IMAGE_LAYOUT_MASK (1 << 7) #define IMAGE_INSTANCE_TYPE_P(ii, type) \ (IMAGE_INSTANCEP (ii) && XIMAGE_INSTANCE_TYPE (ii) == type) @@ -378,15 +383,17 @@ IMAGE_INSTANCE_TYPE_P (ii, IMAGE_SUBWINDOW) #define WIDGET_IMAGE_INSTANCEP(ii) \ IMAGE_INSTANCE_TYPE_P (ii, IMAGE_WIDGET) +#define LAYOUT_IMAGE_INSTANCEP(ii) \ + IMAGE_INSTANCE_TYPE_P (ii, IMAGE_LAYOUT) -#define CHECK_NOTHING_IMAGE_INSTANCE(x) do { \ - CHECK_IMAGE_INSTANCE (x); \ +#define CHECK_NOTHING_IMAGE_INSTANCE(x) do { \ + CHECK_IMAGE_INSTANCE (x); \ if (!NOTHING_IMAGE_INSTANCEP (x)) \ x = wrong_type_argument (Qnothing_image_instance_p, (x)); \ } while (0) -#define CHECK_TEXT_IMAGE_INSTANCE(x) do { \ - CHECK_IMAGE_INSTANCE (x); \ +#define CHECK_TEXT_IMAGE_INSTANCE(x) do { \ + CHECK_IMAGE_INSTANCE (x); \ if (!TEXT_IMAGE_INSTANCEP (x)) \ x = wrong_type_argument (Qtext_image_instance_p, (x)); \ } while (0) @@ -397,37 +404,44 @@ x = wrong_type_argument (Qmono_pixmap_image_instance_p, (x)); \ } while (0) -#define CHECK_COLOR_PIXMAP_IMAGE_INSTANCE(x) do { \ - CHECK_IMAGE_INSTANCE (x); \ +#define CHECK_COLOR_PIXMAP_IMAGE_INSTANCE(x) do { \ + CHECK_IMAGE_INSTANCE (x); \ if (!COLOR_PIXMAP_IMAGE_INSTANCEP (x)) \ x = wrong_type_argument (Qcolor_pixmap_image_instance_p, (x)); \ } while (0) -#define CHECK_POINTER_IMAGE_INSTANCE(x) do { \ - CHECK_IMAGE_INSTANCE (x); \ +#define CHECK_POINTER_IMAGE_INSTANCE(x) do { \ + CHECK_IMAGE_INSTANCE (x); \ if (!POINTER_IMAGE_INSTANCEP (x)) \ x = wrong_type_argument (Qpointer_image_instance_p, (x)); \ } while (0) -#define CHECK_SUBWINDOW_IMAGE_INSTANCE(x) do { \ +#define CHECK_SUBWINDOW_IMAGE_INSTANCE(x) do { \ CHECK_IMAGE_INSTANCE (x); \ if (!SUBWINDOW_IMAGE_INSTANCEP (x) \ && !WIDGET_IMAGE_INSTANCEP (x)) \ x = wrong_type_argument (Qsubwindow_image_instance_p, (x)); \ } while (0) -#define CHECK_WIDGET_IMAGE_INSTANCE(x) do { \ - CHECK_IMAGE_INSTANCE (x); \ +#define CHECK_WIDGET_IMAGE_INSTANCE(x) do { \ + CHECK_IMAGE_INSTANCE (x); \ if (!WIDGET_IMAGE_INSTANCEP (x)) \ x = wrong_type_argument (Qwidget_image_instance_p, (x)); \ } while (0) +#define CHECK_LAYOUT_IMAGE_INSTANCE(x) do { \ + CHECK_IMAGE_INSTANCE (x); \ + if (!LAYOUT_IMAGE_INSTANCEP (x)) \ + x = wrong_type_argument (Qlayout_image_instance_p, (x)); \ +} while (0) + struct Lisp_Image_Instance { struct lcrecord_header header; Lisp_Object device; Lisp_Object name; enum image_instance_type type; + int x_offset, y_offset; /* for layout purposes */ union { struct @@ -445,6 +459,7 @@ or a pointer */ Lisp_Object auxdata; /* list or Qnil: any additional data to be seen from lisp */ + void* mask; /* mask that can be seen from all windowing systems */ } pixmap; /* used for pointers as well */ struct { @@ -452,13 +467,21 @@ unsigned int width, height; void* subwindow; /* specific devices can use this as necessary */ int being_displayed; /* used to detect when needs to be unmapped */ - struct + union { - Lisp_Object face; /* foreground and background colors */ - Lisp_Object type; - Lisp_Object props; /* properties */ - Lisp_Object gui_item; /* a list of gui_items */ - } widget; /* widgets are subwindows */ + struct + { + Lisp_Object face; /* foreground and background colors */ + Lisp_Object type; + Lisp_Object props; /* properties */ + Lisp_Object gui_item; /* a list of gui_items */ + } widget; /* widgets are subwindows */ + struct + { + Lisp_Object children; /* managed children */ + Lisp_Object border; /* orientation */ + } layout; + } s; } subwindow; } u; @@ -469,6 +492,8 @@ #define IMAGE_INSTANCE_DEVICE(i) ((i)->device) #define IMAGE_INSTANCE_NAME(i) ((i)->name) #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_PIXMAP_TYPE_P(i) \ ((IMAGE_INSTANCE_TYPE (i) == IMAGE_MONO_PIXMAP) \ || (IMAGE_INSTANCE_TYPE (i) == IMAGE_COLOR_PIXMAP)) @@ -485,6 +510,7 @@ #define IMAGE_INSTANCE_PIXMAP_FG(i) ((i)->u.pixmap.fg) #define IMAGE_INSTANCE_PIXMAP_BG(i) ((i)->u.pixmap.bg) #define IMAGE_INSTANCE_PIXMAP_AUXDATA(i) ((i)->u.pixmap.auxdata) +#define IMAGE_INSTANCE_PIXMAP_MASK(i) ((i)->u.pixmap.mask) #define IMAGE_INSTANCE_SUBWINDOW_WIDTH(i) ((i)->u.subwindow.width) #define IMAGE_INSTANCE_SUBWINDOW_HEIGHT(i) ((i)->u.subwindow.height) @@ -497,22 +523,29 @@ IMAGE_INSTANCE_SUBWINDOW_WIDTH(i) #define IMAGE_INSTANCE_WIDGET_HEIGHT(i) \ IMAGE_INSTANCE_SUBWINDOW_HEIGHT(i) -#define IMAGE_INSTANCE_WIDGET_TYPE(i) ((i)->u.subwindow.widget.type) -#define IMAGE_INSTANCE_WIDGET_PROPS(i) ((i)->u.subwindow.widget.props) -#define IMAGE_INSTANCE_WIDGET_FACE(i) ((i)->u.subwindow.widget.face) -#define IMAGE_INSTANCE_WIDGET_ITEMS(i) ((i)->u.subwindow.widget.gui_item) +#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) +#define IMAGE_INSTANCE_WIDGET_ITEMS(i) ((i)->u.subwindow.s.widget.gui_item) #define IMAGE_INSTANCE_WIDGET_ITEM(i) \ (CONSP (IMAGE_INSTANCE_WIDGET_ITEMS (i)) ? \ XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (i)) : \ IMAGE_INSTANCE_WIDGET_ITEMS (i)) #define IMAGE_INSTANCE_WIDGET_TEXT(i) XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEM (i))->name +#define IMAGE_INSTANCE_LAYOUT_CHILDREN(i) ((i)->u.subwindow.s.layout.children) +#define IMAGE_INSTANCE_LAYOUT_BORDER(i) ((i)->u.subwindow.s.layout.border) + #define XIMAGE_INSTANCE_DEVICE(i) \ IMAGE_INSTANCE_DEVICE (XIMAGE_INSTANCE (i)) #define XIMAGE_INSTANCE_NAME(i) \ IMAGE_INSTANCE_NAME (XIMAGE_INSTANCE (i)) #define XIMAGE_INSTANCE_TYPE(i) \ IMAGE_INSTANCE_TYPE (XIMAGE_INSTANCE (i)) +#define XIMAGE_INSTANCE_XOFFSET(i) \ + IMAGE_INSTANCE_XOFFSET (XIMAGE_INSTANCE (i)) +#define XIMAGE_INSTANCE_YOFFSET(i) \ + IMAGE_INSTANCE_YOFFSET (XIMAGE_INSTANCE (i)) #define XIMAGE_INSTANCE_TEXT_STRING(i) \ IMAGE_INSTANCE_TEXT_STRING (XIMAGE_INSTANCE (i)) @@ -535,6 +568,8 @@ IMAGE_INSTANCE_PIXMAP_FG (XIMAGE_INSTANCE (i)) #define XIMAGE_INSTANCE_PIXMAP_BG(i) \ IMAGE_INSTANCE_PIXMAP_BG (XIMAGE_INSTANCE (i)) +#define XIMAGE_INSTANCE_PIXMAP_MASK(i) \ + IMAGE_INSTANCE_PIXMAP_MASK (XIMAGE_INSTANCE (i)) #define XIMAGE_INSTANCE_WIDGET_WIDTH(i) \ IMAGE_INSTANCE_WIDGET_WIDTH (XIMAGE_INSTANCE (i)) @@ -553,6 +588,11 @@ #define XIMAGE_INSTANCE_WIDGET_TEXT(i) \ IMAGE_INSTANCE_WIDGET_TEXT (XIMAGE_INSTANCE (i)) +#define XIMAGE_INSTANCE_LAYOUT_CHILDREN(i) \ + IMAGE_INSTANCE_LAYOUT_CHILDREN (XIMAGE_INSTANCE (i)) +#define XIMAGE_INSTANCE_LAYOUT_BORDER(i) \ + IMAGE_INSTANCE_LAYOUT_BORDER (XIMAGE_INSTANCE (i)) + #define XIMAGE_INSTANCE_SUBWINDOW_WIDTH(i) \ IMAGE_INSTANCE_SUBWINDOW_WIDTH (XIMAGE_INSTANCE (i)) #define XIMAGE_INSTANCE_SUBWINDOW_HEIGHT(i) \ @@ -647,14 +687,15 @@ #define XGLYPH_BASELINE(g) GLYPH_BASELINE (XGLYPH (g)) #define XGLYPH_FACE(g) GLYPH_FACE (XGLYPH (g)) -extern Lisp_Object Qxpm, Qxface; +extern Lisp_Object Qxpm, Qxface, Qetched_in, Qetched_out, Qbevel_in, Qbevel_out; extern Lisp_Object Q_data, Q_file, Q_color_symbols, Qconst_glyph_variable; extern Lisp_Object Qxbm, Qedit_field, Qgroup, Qlabel, Qcombo_box, Qscrollbar; -extern Lisp_Object Qtree_view, Qtab_control, Qprogress_gauge; +extern Lisp_Object Qtree_view, Qtab_control, Qprogress_gauge, Q_border; extern Lisp_Object Q_mask_file, Q_mask_data, Q_hotspot_x, Q_hotspot_y; extern Lisp_Object Q_foreground, Q_background, Q_face, Q_descriptor, Q_group; extern Lisp_Object Q_width, Q_height, Q_pixel_width, Q_pixel_height, Q_text; extern Lisp_Object Q_items, Q_properties, Q_image, Q_percent, Qimage_conversion_error; +extern Lisp_Object Q_orientation; extern Lisp_Object Vcontinuation_glyph, Vcontrol_arrow_glyph, Vhscroll_glyph; extern Lisp_Object Vinvisible_text_glyph, Voctal_escape_glyph, Vtruncation_glyph; extern Lisp_Object Vxemacs_logo; @@ -775,6 +816,7 @@ void unmap_subwindow (Lisp_Object subwindow); void map_subwindow (Lisp_Object subwindow, int x, int y); void update_frame_subwindows (struct frame *f); +int find_matching_subwindow (struct frame* f, int x, int y, int width, int height); struct expose_ignore { Index: src/gutter.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/Attic/gutter.c,v retrieving revision 1.1.2.7 diff -u -r1.1.2.7 gutter.c --- src/gutter.c 1999/08/17 15:11:40 1.1.2.7 +++ src/gutter.c 1999/08/23 16:36:14 @@ -266,7 +266,8 @@ if (border_width != 0) { MAYBE_DEVMETH (d, bevel_area, - (w, findex, x, y, width, height, border_width)); + (w, findex, x, y, width, height, border_width, + EDGE_ALL, EDGE_BEVEL_OUT)); } } Index: src/lisp.h =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/lisp.h,v retrieving revision 1.38.2.18 diff -u -r1.38.2.18 lisp.h --- src/lisp.h 1999/07/05 07:28:25 1.38.2.18 +++ src/lisp.h 1999/08/23 16:36:25 @@ -340,6 +340,8 @@ struct Lisp_Gui_Item; typedef struct Lisp_Gui_Item Lisp_Gui_Item; struct display_line; +struct display_glyph_area; +struct display_box; struct redisplay_info; struct window_mirror; struct scrollbar_instance; @@ -467,6 +469,14 @@ }; #endif +enum edge_style +{ + EDGE_ETCHED_IN, + EDGE_ETCHED_OUT, + EDGE_BEVEL_IN, + EDGE_BEVEL_OUT +}; + #ifndef ERROR_CHECK_TYPECHECK typedef enum error_behavior @@ -2811,7 +2821,7 @@ extern Lisp_Object Qcategory_designator_p, Qcategory_table_value_p, Qccl, Qcdr; extern Lisp_Object Qchannel, Qchar, Qchar_or_string_p, Qcharacter, Qcharacterp; extern Lisp_Object Qchars, Qcharset_g0, Qcharset_g1, Qcharset_g2, Qcharset_g3; -extern Lisp_Object Qcircular_list, Qcircular_property_list; +extern Lisp_Object Qcenter, Qcircular_list, Qcircular_property_list; extern Lisp_Object Qcoding_system_error, Qcoding_system_p; extern Lisp_Object Qcolor, Qcolor_pixmap_image_instance_p; extern Lisp_Object Qcolumns, Qcommand, Qcommandp, Qcompletion_ignore_case; @@ -2829,14 +2839,14 @@ extern Lisp_Object Qfont, Qforce_g0_on_output, Qforce_g1_on_output; extern Lisp_Object Qforce_g2_on_output, Qforce_g3_on_output, Qforeground; extern Lisp_Object Qformat, Qframe, Qframe_live_p, Qfunction, Qgap_overhead; -extern Lisp_Object Qgeneric, Qgeometry, Qglobal, Qheight, Qhighlight, Qicon; +extern Lisp_Object Qgeneric, Qgeometry, Qglobal, Qheight, Qhighlight, Qhorizontal, Qicon; extern Lisp_Object Qicon_glyph_p, Qid, Qidentity, Qimage, Qinfo, Qinherit; extern Lisp_Object Qinhibit_quit, Qinhibit_read_only; extern Lisp_Object Qinput_charset_conversion, Qinteger; extern Lisp_Object Qinteger_char_or_marker_p, Qinteger_or_char_p; extern Lisp_Object Qinteger_or_marker_p, Qintegerp, Qinteractive, Qinternal; extern Lisp_Object Qinvalid_function, Qinvalid_read_syntax, Qio_error; -extern Lisp_Object Qiso2022, Qkey, Qkey_assoc, Qkeymap, Qlambda, Qleft, Qlf; +extern Lisp_Object Qiso2022, Qkey, Qkey_assoc, Qkeymap, Qlambda, Qlayout, Qleft, Qlf; extern Lisp_Object Qlist, Qlistp, Qload, Qlock_shift, Qmacro, Qmagic; extern Lisp_Object Qmalformed_list, Qmalformed_property_list; extern Lisp_Object Qmalloc_overhead, Qmark, Qmarkers; @@ -2868,7 +2878,7 @@ extern Lisp_Object Qunbound, Qundecided, Qundefined, Qunderflow_error; extern Lisp_Object Qunderline, Qunimplemented, Quser_files_and_directories; extern Lisp_Object Qvalue_assoc, Qvalues; -extern Lisp_Object Qvariable_documentation, Qvariable_domain, Qvector; +extern Lisp_Object Qvariable_documentation, Qvariable_domain, Qvector, Qvertical; extern Lisp_Object Qvoid_function, Qvoid_variable, Qwarning, Qwidth, Qwidget, Qwindow; extern Lisp_Object Qwindow_live_p, Qwindow_system, Qwrong_number_of_arguments; extern Lisp_Object Qwrong_type_argument, Qx, Qy, Qyes_or_no_p; Index: src/redisplay-msw.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/redisplay-msw.c,v retrieving revision 1.28.2.5 diff -u -r1.28.2.5 redisplay-msw.c --- src/redisplay-msw.c 1999/07/16 19:05:41 1.28.2.5 +++ src/redisplay-msw.c 1999/08/23 16:36:29 @@ -64,18 +64,8 @@ int y, int width, int height); static void mswindows_output_dibitmap (struct frame *f, struct Lisp_Image_Instance *p, - int x, int y, - int clip_x, int clip_y, - int clip_width, int clip_height, - int width, int height, - int pixmap_offset, - int offset_bitmap); -static void mswindows_output_pixmap (struct window *w, struct display_line *dl, - Lisp_Object image_instance, int xpos, - int xoffset, int start_pixpos, int width, - face_index findex, int cursor_start, - int cursor_width, int cursor_height, - int offset_bitmap); + struct display_box* db, + struct display_glyph_area* dga); void bevel_modeline (struct window *w, struct display_line *dl); typedef struct textual_run @@ -319,13 +309,16 @@ if (!NILP(bg_pmap)) { + struct display_box db; + struct display_glyph_area dga; + redisplay_calculate_display_boxes (dl, rb->xpos, + /*rb->object.dglyph.xoffset*/ 0, + start_pixpos, rb->width, + &db, &dga); /* blank the background in the appropriate color */ mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, cachel->foreground, cachel->background, Qnil); - - mswindows_output_pixmap (w, dl, bg_pmap, - rb->xpos, 0 /*rb->object.dglyph.xoffset*/, - start_pixpos, rb->width, rb->findex, + redisplay_output_pixmap (w, bg_pmap, &db, &dga, rb->findex, 0, 0, 0, TRUE); } else @@ -518,13 +511,14 @@ if (!NILP(bg_pmap)) { + struct display_box db; + struct display_glyph_area dga; + redisplay_calculate_display_boxes (dl, xpos + xoffset, 0, + clip_start, width, &db, &dga); /* blank the background in the appropriate color */ mswindows_update_dc (hdc, Qnil, cachel->foreground, cachel->background, Qnil); - - mswindows_output_pixmap (w, dl, bg_pmap, - xpos, xoffset, - clip_start, width, findex, + redisplay_output_pixmap (w, bg_pmap, &db, &dga, findex, 0, 0, 0, TRUE); /* output pixmap calls this so we have to recall to get correct references */ @@ -581,31 +575,12 @@ static void mswindows_output_dibitmap (struct frame *f, struct Lisp_Image_Instance *p, - int x, int y, - int clip_x, int clip_y, - int clip_width, int clip_height, - int width, int height, int pixmap_offset, - int offset_bitmap) + struct display_box* db, + struct display_glyph_area* dga) { HDC hdc = FRAME_MSWINDOWS_DC (f); HGDIOBJ old=NULL; COLORREF bgcolor = GetBkColor (hdc); - int need_clipping = (clip_x || clip_y); - int yoffset=0; - int xoffset=0; - - /* do we need to offset the pixmap vertically? this is necessary - for background pixmaps. */ - if (offset_bitmap) - { - yoffset = y % IMAGE_INSTANCE_PIXMAP_HEIGHT (p); - xoffset = x % IMAGE_INSTANCE_PIXMAP_WIDTH (p); - /* the width is handled by mswindows_output_pixmap_region */ - } - - if (need_clipping) - { - } /* first blt the mask */ if (IMAGE_INSTANCE_MSWINDOWS_MASK (p)) @@ -622,10 +597,10 @@ SetDIBColorTable (FRAME_MSWINDOWS_CDC (f), 1, 1, &col); BitBlt (hdc, - x,y, - width, height, + db->xpos, db->ypos, + dga->width, dga->height, FRAME_MSWINDOWS_CDC (f), - xoffset,yoffset, + dga->xoffset, dga->yoffset, SRCCOPY); SelectObject (FRAME_MSWINDOWS_CDC (f), old); @@ -636,79 +611,79 @@ IMAGE_INSTANCE_MSWINDOWS_BITMAP (p)); BitBlt (hdc, - x,y, - width, height, + db->xpos, db->ypos, + dga->width, dga->height, FRAME_MSWINDOWS_CDC (f), - xoffset, yoffset, + dga->xoffset, dga->yoffset, IMAGE_INSTANCE_MSWINDOWS_MASK (p) ? SRCINVERT : SRCCOPY); SelectObject (FRAME_MSWINDOWS_CDC (f),old); - - if (need_clipping) - { - } } -/* - * X gc's have this nice property that setting the bg pixmap will +/* X gc's have this nice property that setting the bg pixmap will * output it offset relative to the window. Windows doesn't have this - * feature so we have to emulate this by outputting multiple pixmaps - */ + * feature so we have to emulate this by outputting multiple pixmaps. + * This is only used for background pixmaps. Normal pixmaps are + * outputted once and are scrollable */ static void mswindows_output_dibitmap_region (struct frame *f, struct Lisp_Image_Instance *p, - int x, int y, - int clip_x, int clip_y, - int clip_width, int clip_height, - int width, int height, int pixmap_offset, - int offset_bitmap) + struct display_box *db, + struct display_glyph_area *dga) { - int pwidth = min (width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)); - int pheight = min (height, IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); + struct display_box xdb = { db->xpos, db->ypos, db->width, db->height }; + struct display_glyph_area xdga + = { 0, 0, IMAGE_INSTANCE_PIXMAP_WIDTH (p), + IMAGE_INSTANCE_PIXMAP_HEIGHT (p) }; int pxoffset = 0, pyoffset = 0; + if (dga) + { + xdga.width = dga->width; + xdga.height = dga->height; + } + else if (!redisplay_normalize_glyph_area (&xdb, &xdga)) + return; + /* when doing a bg pixmap do a partial pixmap first so that we blt whole pixmaps thereafter */ + xdga.height = min (xdga.height, IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - + db->ypos % IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); - if (offset_bitmap) + while (xdga.height > 0) { - pheight = min (pheight, IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - - y % IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); - } - - while (pheight > 0) - { - if (offset_bitmap) - { - pwidth = min (min (width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)), + xdga.width = min (min (db->width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)), IMAGE_INSTANCE_PIXMAP_WIDTH (p) - - x % IMAGE_INSTANCE_PIXMAP_WIDTH (p)); - pxoffset = 0; - } - while (pwidth > 0) + db->xpos % IMAGE_INSTANCE_PIXMAP_WIDTH (p)); + pxoffset = 0; + while (xdga.width > 0) { - mswindows_output_dibitmap (f, p, - x + pxoffset, y + pyoffset, - clip_x, clip_y, - clip_width, clip_height, - pwidth, pheight, pixmap_offset, - offset_bitmap); - pxoffset += pwidth; - pwidth = min ((width-pxoffset), - IMAGE_INSTANCE_PIXMAP_WIDTH (p)); + xdb.xpos = db->xpos + pxoffset; + xdb.ypos = db->ypos + pyoffset; + /* do we need to offset the pixmap vertically? this is necessary + for background pixmaps. */ + xdga.yoffset = xdb.ypos % IMAGE_INSTANCE_PIXMAP_HEIGHT (p); + xdga.xoffset = xdb.xpos % IMAGE_INSTANCE_PIXMAP_WIDTH (p); + /* the width is handled by mswindows_output_pixmap_region */ + mswindows_output_dibitmap (f, p, &xdb, &xdga); + pxoffset += xdga.width; + xdga.width = min ((db->width - pxoffset), + IMAGE_INSTANCE_PIXMAP_WIDTH (p)); } - pyoffset += pheight; - pheight = min ((height-pyoffset), - IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); + pyoffset += xdga.height; + xdga.height = min ((db->height - pyoffset), + IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); } } +/* Output a pixmap at the desired location. + DB normalized display_box. + DGA normalized display_glyph_area. */ static void -mswindows_output_pixmap (struct window *w, struct display_line *dl, - Lisp_Object image_instance, int xpos, int xoffset, - int start_pixpos, int width, face_index findex, - int cursor_start, int cursor_width, int cursor_height, - int offset_bitmap) +mswindows_output_pixmap (struct window *w, Lisp_Object image_instance, + struct display_box *db, struct display_glyph_area *dga, + face_index findex, int cursor_start, int cursor_width, + int cursor_height, int bg_pixmap) { struct frame *f = XFRAME (w->frame); HDC hdc = FRAME_MSWINDOWS_DC (f); @@ -716,100 +691,18 @@ struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); Lisp_Object window; - int lheight = DISPLAY_LINE_HEIGHT (dl); - int pheight = ((int) IMAGE_INSTANCE_PIXMAP_HEIGHT (p) > lheight ? lheight : - IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); - int clip_x, clip_y, clip_width, clip_height; - - /* The pixmap_offset is used to center the pixmap on lines which are - shorter than it is. This results in odd effects when scrolling - pixmaps off of the bottom. Let's try not using it. */ -#if 0 - int pixmap_offset = (int) (IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - lheight) / 2; -#else - int pixmap_offset = 0; -#endif - XSETWINDOW (window, w); - if ((start_pixpos >= 0 && start_pixpos > xpos) || xoffset) - { - if (start_pixpos > xpos && start_pixpos > xpos + width) - return; - - clip_x = xoffset; - clip_width = width; - if (start_pixpos > xpos) - { - clip_x += (start_pixpos - xpos); - clip_width -= (start_pixpos - xpos); - } - } - else - { - clip_x = 0; - clip_width = 0; - } - - /* Place markers for possible future functionality (clipping the top - half instead of the bottom half; think pixel scrolling). */ - clip_y = 0; - clip_height = pheight; - - /* Clear the area the pixmap is going into. The pixmap itself will - always take care of the full width. We don't want to clear where - it is going to go in order to avoid flicker. So, all we have to - take care of is any area above or below the pixmap. */ - /* #### We take a shortcut for now. We know that since we have - pixmap_offset hardwired to 0 that the pixmap is against the top - edge so all we have to worry about is below it. */ - /* #### Unless the pixmap has a mask in which case we have to clear - the whole damn thing since we can't yet clear just the area not - included in the mask. */ - if (((int) (dl->ypos - dl->ascent + pheight) < - (int) (dl->ypos + dl->descent - dl->clip)) - || IMAGE_INSTANCE_MSWINDOWS_MASK (p)) - { - int clear_x, clear_y, clear_width, clear_height; - - if (IMAGE_INSTANCE_MSWINDOWS_MASK (p)) - { - clear_y = dl->ypos - dl->ascent; - clear_height = lheight; - } - else - { - clear_y = dl->ypos - dl->ascent + pheight; - clear_height = lheight - pheight; - } - - if (start_pixpos >= 0 && start_pixpos > xpos) - { - clear_x = start_pixpos; - clear_width = xpos + width - start_pixpos; - } - else - { - clear_x = xpos; - clear_width = width; - } - - if (!offset_bitmap) /* i.e. not a bg pixmap */ - redisplay_clear_region (window, findex, clear_x, clear_y, - clear_width, clear_height); - } - /* Output the pixmap. Have to do this as many times as is required to fill the given area */ mswindows_update_dc (hdc, Qnil, WINDOW_FACE_CACHEL_FOREGROUND (w, findex), WINDOW_FACE_CACHEL_BACKGROUND (w, findex), Qnil); - mswindows_output_dibitmap_region (f, p, xpos - xoffset, - dl->ypos - dl->ascent, - clip_x, clip_y, clip_width, clip_height, - width + xoffset, pheight, pixmap_offset, - offset_bitmap); + if (bg_pixmap) + mswindows_output_dibitmap_region (f, p, db, dga); + else + mswindows_output_dibitmap (f, p, db, dga); } #ifdef HAVE_SCROLLBARS @@ -986,29 +879,47 @@ ****************************************************************************/ static void mswindows_bevel_area (struct window *w, face_index findex, int x, int y, - int width, int height, int shadow_thickness) + int width, int height, int thickness, + int edges, enum edge_style style) { struct frame *f = XFRAME (w->frame); UINT edge; + UINT border = 0; - if (shadow_thickness < -1) - edge = EDGE_SUNKEN; - else if (shadow_thickness < 0) - edge = BDR_SUNKENINNER; - else if (shadow_thickness == 1) - edge = BDR_RAISEDINNER; - else - edge = EDGE_RAISED; + if (style == EDGE_ETCHED_IN) + edge = EDGE_ETCHED; + else if (style == EDGE_ETCHED_OUT) + edge = EDGE_BUMP; + else if (style == EDGE_BEVEL_IN) + { + if (thickness == 1) + edge = BDR_SUNKENINNER; + else + edge = EDGE_SUNKEN; + } + else /* EDGE_BEVEL_OUT */ + { + if (thickness == 1) + edge = BDR_RAISEDINNER; + else + edge = EDGE_RAISED; + } - if (shadow_thickness < 0) - shadow_thickness = -shadow_thickness; + if (edges & EDGE_TOP) + border |= BF_TOP; + if (edges & EDGE_LEFT) + border |= BF_LEFT; + if (edges & EDGE_BOTTOM) + border |= BF_BOTTOM; + if (edges & EDGE_RIGHT) + border |= BF_RIGHT; { RECT rect = { x, y, x + width, y + height }; Lisp_Object color = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, color, Qnil); - DrawEdge (FRAME_MSWINDOWS_DC (f), &rect, edge, BF_RECT); + DrawEdge (FRAME_MSWINDOWS_DC (f), &rect, edge, border); } } @@ -1214,6 +1125,11 @@ else if (rb->type == RUNE_DGLYPH) { Lisp_Object instance; + struct display_box db; + struct display_glyph_area dga; + redisplay_calculate_display_boxes (dl, rb->xpos, rb->object.dglyph.xoffset, + start_pixpos, rb->width, + &db, &dga); XSETWINDOW (window, w); instance = glyph_image_instance (rb->object.dglyph.glyph, @@ -1245,10 +1161,9 @@ case IMAGE_MONO_PIXMAP: case IMAGE_COLOR_PIXMAP: - mswindows_output_pixmap (w, dl, instance, xpos, - rb->object.dglyph.xoffset, start_pixpos, - rb->width, findex, cursor_start, - cursor_width, cursor_height, 0); + redisplay_output_pixmap (w, instance, &db, &dga, findex, + cursor_start, cursor_width, + cursor_height, 0); if (rb->cursor_type == CURSOR_ON) mswindows_output_cursor (w, dl, xpos, cursor_width, findex, 0, 1); @@ -1259,15 +1174,23 @@ case IMAGE_SUBWINDOW: case IMAGE_WIDGET: - redisplay_output_subwindow (w, dl, instance, xpos, - rb->object.dglyph.xoffset, start_pixpos, - rb->width, findex, cursor_start, - cursor_width, cursor_height); + redisplay_output_subwindow (w, instance, &db, &dga, findex, + cursor_start, cursor_width, + cursor_height); if (rb->cursor_type == CURSOR_ON) mswindows_output_cursor (w, dl, xpos, cursor_width, findex, 0, 1); break; + case IMAGE_LAYOUT: + redisplay_output_layout (w, instance, &db, &dga, findex, + cursor_start, cursor_width, + cursor_height); + if (rb->cursor_type == CURSOR_ON) + mswindows_output_cursor (w, dl, xpos, cursor_width, + findex, 0, 1); + break; + case IMAGE_NOTHING: /* nothing is as nothing does */ break; @@ -1400,12 +1323,11 @@ if (!NILP (background_pixmap)) { + struct display_box db = { x, y, width, height }; mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, fcolor, bcolor, background_pixmap); - mswindows_output_dibitmap_region - ( f, XIMAGE_INSTANCE (background_pixmap), - x, y, 0, 0, 0, 0, width, height, 0, TRUE); + ( f, XIMAGE_INSTANCE (background_pixmap), &db, 0); } else { @@ -1449,4 +1371,6 @@ CONSOLE_HAS_METHOD (mswindows, flash); CONSOLE_HAS_METHOD (mswindows, ring_bell); CONSOLE_HAS_METHOD (mswindows, bevel_area); + CONSOLE_HAS_METHOD (mswindows, output_string); + CONSOLE_HAS_METHOD (mswindows, output_pixmap); } Index: src/redisplay-output.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/redisplay-output.c,v retrieving revision 1.11.2.11 diff -u -r1.11.2.11 redisplay-output.c --- src/redisplay-output.c 1999/08/18 14:32:53 1.11.2.11 +++ src/redisplay-output.c 1999/08/23 16:36:36 @@ -2,6 +2,7 @@ Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. Copyright (C) 1995, 1996 Ben Wing. Copyright (C) 1996 Chuck Thompson. + Copyright (C) 1999 Andy Piper.. This file is part of XEmacs. @@ -26,6 +27,9 @@ /* Author: Chuck Thompson */ +/* Heavily hacked for modularity, gutter and subwindow support by Andy + Piper. */ + #include #include "lisp.h" @@ -45,6 +49,11 @@ int block, int start, int end, int start_pixpos, int cursor_start, int cursor_width, int cursor_height); +static void redisplay_normalize_display_box (struct display_box* dest, + struct display_glyph_area* src); +static int redisplay_display_boxes_in_window_p (struct window* w, + struct display_box* db, + struct display_glyph_area* dga); /***************************************************************************** sync_rune_structs @@ -1091,23 +1100,28 @@ /**************************************************************************** redisplay_output_subwindow - output a subwindow. This code borrows heavily from the pixmap stuff, although is much simpler not needing to account for partial pixmaps, backgrounds etc. ****************************************************************************/ void -redisplay_output_subwindow (struct window *w, struct display_line *dl, - Lisp_Object image_instance, int xpos, int xoffset, - int start_pixpos, int width, face_index findex, - int cursor_start, int cursor_width, int cursor_height) +redisplay_output_subwindow (struct window *w, + Lisp_Object image_instance, + struct display_box* db, struct display_glyph_area* dga, + face_index findex, int cursor_start, int cursor_width, + int cursor_height) { struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); Lisp_Object window; struct frame* f = XFRAME (WINDOW_FRAME (w)); - int lheight = DISPLAY_LINE_HEIGHT (dl); - int pheight = ((int) IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p) > lheight ? lheight : - IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p)); + struct display_glyph_area sdga; + + dga->height = IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p); + dga->width = IMAGE_INSTANCE_SUBWINDOW_WIDTH (p); + + /* This makes the glyph area fit into the display area. */ + if (!redisplay_normalize_glyph_area (db, dga)) + return; XSETWINDOW (window, w); @@ -1117,62 +1131,248 @@ have to take care of is any area above or below the subwindow. Of course this is rubbish if the subwindow has transparent areas (for instance with frames). */ - /* #### We take a shortcut for now. We know that since we have - subwindow_offset hardwired to 0 that the subwindow is against the top - edge so all we have to worry about is below it. */ - if ((DISPLAY_LINE_YPOS (dl) + pheight) < - DISPLAY_LINE_HEIGHT (dl)) - { - int clear_x, clear_width; + redisplay_clear_clipped_region (window, findex, + db, dga, 1); - int clear_y = DISPLAY_LINE_YPOS (dl) + pheight; - int clear_height = lheight - pheight; + /* This shrinks the display box to exactly enclose the glyph + area. */ + redisplay_normalize_display_box (db, dga); - if (start_pixpos >= 0 && start_pixpos > xpos) - { - clear_x = start_pixpos; - clear_width = xpos + width - start_pixpos; - } - else - { - clear_x = xpos; - clear_width = width; - } - - redisplay_clear_region (window, findex, clear_x, clear_y, - clear_width, clear_height); - } /* unmap all subwindows we are mapping over - except ourselves because we will get moved anyway. unmapping ourselves cause unacceptable flicker. */ - redisplay_unmap_subwindows_except_us (f, xpos - xoffset, - dl->ypos - dl->ascent, width, - lheight, image_instance); - /* if we can't view the whole window we can't view any of it */ - if (IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p) > lheight - || - (IMAGE_INSTANCE_SUBWINDOW_WIDTH (p) > width -#if 0 /* I think this cause problems under X */ - && - /* If we are only clipping because of the right border we will - allow the whole window to be displayed since the window will - get clipped natively */ - width + xpos - xoffset < FRAME_RIGHT_BORDER_START (f) - && - /* Ditto the left border. */ - xpos - xoffset > FRAME_LEFT_BORDER_END (f) -#endif - )) + redisplay_unmap_subwindows_except_us (f, db->xpos, db->ypos, + db->width, db->height, + image_instance); + /* if we can't view the whole window we can't view any of it. We + have to be careful here since we may be being asked to display + part of a subwindow, the rest of which is on-screen as well. We + need to allow this case and map the entire subwindow. We also + need to be careful since the subwindow could be outside the + window in the gutter or modeline - we also need to allow these + cases.*/ + sdga.xoffset = -dga->xoffset; + sdga.yoffset = -dga->yoffset; + sdga.height = IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p); + sdga.width = IMAGE_INSTANCE_SUBWINDOW_WIDTH (p); + + if (redisplay_display_boxes_in_window_p (w, db, &sdga) < 0) { - redisplay_clear_region (window, findex, xpos - xoffset, dl->ypos - dl->ascent, - width, lheight); + redisplay_clear_region (window, findex, db->xpos, db->ypos, + dga->width, dga->height); unmap_subwindow (image_instance); } else - map_subwindow (image_instance, xpos - xoffset, dl->ypos - dl->ascent); + map_subwindow (image_instance, db->xpos - dga->xoffset, + db->ypos - dga->yoffset); +} + +/**************************************************************************** + redisplay_output_layout + + Output a widget hierarchy. + ****************************************************************************/ +void +redisplay_output_layout (struct window *w, + Lisp_Object image_instance, + struct display_box* db, struct display_glyph_area* dga, + face_index findex, int cursor_start, int cursor_width, + int cursor_height) +{ + struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); + Lisp_Object window, rest; + Emchar_dynarr *buf = Dynarr_new (Emchar); + struct device *d = XDEVICE (XFRAME (w->frame)->device); + int layout_height, layout_width; + + XSETWINDOW (window, w); + + layout_height = glyph_height (image_instance, Qnil, findex, window); + layout_width = glyph_width (image_instance, Qnil, findex, window); + + dga->height = layout_height; + dga->width = layout_width; + + /* This makes the glyph area fit into the display area. */ + if (!redisplay_normalize_glyph_area (db, dga)) + return; + + /* First clear the area we are drawing into. This is the easiest + thing to do since we have many gaps that we have to make sure are + filled in. */ + redisplay_clear_clipped_region (window, findex, db, dga, 1); + + /* Output a border if required */ + if (!NILP (IMAGE_INSTANCE_LAYOUT_BORDER (p))) + { + int edges = 0; + enum edge_style style; + + if (dga->xoffset >= 0) + edges |= EDGE_LEFT; + if (dga->width - dga->xoffset == layout_width) + edges |= EDGE_RIGHT; + if (dga->yoffset >= 0) + edges |= EDGE_TOP; + if (dga->height - dga->yoffset == layout_height) + edges |= EDGE_BOTTOM; + + if (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (p), Qetched_in)) + style = EDGE_ETCHED_IN; + else if (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (p), Qetched_out)) + style = EDGE_ETCHED_OUT; + else if (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (p), Qbevel_in)) + style = EDGE_BEVEL_IN; + else + style = EDGE_BEVEL_OUT; + + MAYBE_DEVMETH (d, bevel_area, + (w, findex, db->xpos, db->ypos, + db->width, db->height, + 2, edges, style)); + } + + /* This shrinks the display box to exactly enclose the glyph + area. */ + redisplay_normalize_display_box (db, dga); + + Dynarr_reset (buf); + /* Flip through the widgets in the layout displaying as necessary */ + LIST_LOOP (rest, IMAGE_INSTANCE_LAYOUT_CHILDREN (p)) + { + struct display_box cdb = { db->xpos, db->ypos, db->width, db->height }; + + Lisp_Object child = XCAR (rest); + + /* First determine if the image is visible at all */ + if (IMAGE_INSTANCEP (child)) + { + /* The enclosing layout offsets are +ve at this point */ + struct display_glyph_area cdga + = { XIMAGE_INSTANCE_XOFFSET (child) - dga->xoffset, + XIMAGE_INSTANCE_YOFFSET (child) - dga->yoffset, + glyph_width (child, Qnil, findex, window), + glyph_height (child, Qnil, findex, window) }; + + /* Although normalization is done by the output routines + we have to do it here so that they don't try and + clear all of db. This is true below also. */ + if (redisplay_normalize_glyph_area (&cdb, &cdga)) + { + redisplay_normalize_display_box (&cdb, &cdga); + /* We have to invert the offset here as normalization + will have made them positive which the output + routines will treat as a truely +ve offset. */ + cdga.xoffset = -cdga.xoffset; + cdga.yoffset = -cdga.yoffset; + + switch (XIMAGE_INSTANCE_TYPE (child)) + { + case IMAGE_TEXT: +#if 0 + { + /* #### This is way losing. See the comment in + add_glyph_rune(). */ + Lisp_Object string = + XIMAGE_INSTANCE_TEXT_STRING (instance); + convert_bufbyte_string_into_emchar_dynarr + (XSTRING_DATA (string), XSTRING_LENGTH (string), buf); + + MAYBE_DEVMETH (d, output_string, (w, dl, buf, xpos, + rb->object.dglyph.xoffset, + start_pixpos, -1, findex, + 0, + cursor_start, cursor_width, + cursor_height)); + Dynarr_reset (buf); + } +#endif + break; + + case IMAGE_MONO_PIXMAP: + case IMAGE_COLOR_PIXMAP: + redisplay_output_pixmap (w, child, &cdb, &cdga, findex, + 0, 0, 0, 0); + break; + + case IMAGE_WIDGET: + case IMAGE_SUBWINDOW: + redisplay_output_subwindow (w, child, &cdb, &cdga, findex, + 0, 0, 0); + break; + + case IMAGE_LAYOUT: + redisplay_output_layout (w, child, &cdb, &cdga, findex, + 0, 0, 0); + break; + + case IMAGE_NOTHING: + /* nothing is as nothing does */ + break; + + case IMAGE_POINTER: + default: + abort (); + } + } + } + } + Dynarr_free (buf); } /**************************************************************************** + redisplay_output_pixmap + + + output a pixmap. + ****************************************************************************/ +void +redisplay_output_pixmap (struct window *w, + Lisp_Object image_instance, + struct display_box* db, struct display_glyph_area* dga, + face_index findex, int cursor_start, int cursor_width, + int cursor_height, int offset_bitmap) +{ + struct frame *f = XFRAME (w->frame); + struct device *d = XDEVICE (f->device); + struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); + Lisp_Object window; + XSETWINDOW (window, w); + + dga->height = IMAGE_INSTANCE_PIXMAP_HEIGHT (p); + dga->width = IMAGE_INSTANCE_PIXMAP_WIDTH (p); + + /* This makes the glyph area fit into the display area. */ + if (!redisplay_normalize_glyph_area (db, dga)) + return; + + /* Clear the area the pixmap is going into. The pixmap itself will + always take care of the full width. We don't want to clear where + it is going to go in order to avoid flicker. So, all we have to + take care of is any area above or below the pixmap. If the pixmap + has a mask in which case we have to clear the whole damn thing + since we can't yet clear just the area not included in the + mask. */ + if (!offset_bitmap) + { + redisplay_clear_clipped_region (window, findex, + db, dga, + (int)IMAGE_INSTANCE_PIXMAP_MASK (p)); + + /* This shrinks the display box to exactly enclose the glyph + area. */ + redisplay_normalize_display_box (db, dga); + } + assert (db->xpos >= 0 && db->ypos >= 0); + + MAYBE_DEVMETH (d, output_pixmap, (w, image_instance, + db, dga, + findex, cursor_start, + cursor_width, cursor_height, + offset_bitmap)); +} + +/**************************************************************************** redisplay_clear_region Clear the area in the box defined by the given parameters using the @@ -1274,7 +1474,225 @@ (locale, d, f, findex, x, y, width, height, fcolor, bcolor, background_pixmap)); } +/**************************************************************************** + redisplay_clear_clipped_region + + Clear the area in the dest display_box not covered by the src + display_glyph_area using the given face. This is a common occurance + for images shorter than the display line. Clipping can be played + around with by altering these. glyphsrc should be normalized. + ****************************************************************************/ +void +redisplay_clear_clipped_region (Lisp_Object window, face_index findex, + struct display_box* dest, struct display_glyph_area* glyphsrc, + int fullheight_p) +{ + /* assume dest->xpos >= 0 */ + int clear_x; +#if 0 + /* This works because xoffset can be -ve as well as +ve */ + if (dest->xpos + glyphsrc->xoffset + glyphsrc->width > dest->xpos + dest->width) + { + if (glyphsrc->xoffset > 0) + clear_width = dest->width - glyphsrc->xoffset; + else + clear_width = dest->width; + } + else + clear_width = glyphsrc->width; +#endif + + if (glyphsrc->xoffset > 0) + { + clear_x = dest->xpos + glyphsrc->xoffset; + } + else + { + clear_x = dest->xpos; + } + + /* If we need the whole height cleared then just do it. */ + if (fullheight_p) + { + redisplay_clear_region (window, findex, clear_x, dest->ypos, + glyphsrc->width, dest->height); + } + else + { + /* first the top box */ + if (glyphsrc->yoffset > 0) + { + redisplay_clear_region (window, findex, clear_x, dest->ypos, + glyphsrc->width, glyphsrc->yoffset); + + } + /* Then the bottom box */ + if (glyphsrc->yoffset + glyphsrc->height < dest->height) + { + redisplay_clear_region (window, findex, clear_x, + dest->ypos + glyphsrc->yoffset + glyphsrc->height, + glyphsrc->width, + dest->height - (glyphsrc->yoffset + glyphsrc->height)); + + } + } +} + /***************************************************************************** + redisplay_normalize_glyph_area + redisplay_normalize_display_box + + Calculate the visible box for displaying src in dest. + ****************************************************************************/ +int +redisplay_normalize_glyph_area (struct display_box* dest, + struct display_glyph_area* glyphsrc) +{ + if (dest->xpos + glyphsrc->xoffset > dest->xpos + dest->width + || + dest->ypos + glyphsrc->yoffset > dest->ypos + dest->height) + { + /* It's all clipped out */ + return 0; + } + + /* Horizontal offsets. This works because xoffset can be -ve as well as +ve */ + if (dest->xpos + glyphsrc->xoffset + glyphsrc->width > dest->xpos + dest->width) + { + if (glyphsrc->xoffset > 0) + glyphsrc->width = dest->width - glyphsrc->xoffset; + else + glyphsrc->width = dest->width; + } + + if (glyphsrc->xoffset < 0) + glyphsrc->width += glyphsrc->xoffset; + + /* Vertical offsets. This works because yoffset can be -ve as well as +ve */ + if (dest->ypos + glyphsrc->yoffset + glyphsrc->height > dest->ypos + dest->height) + { + if (glyphsrc->yoffset > 0) + glyphsrc->height = dest->height - glyphsrc->yoffset; + else + glyphsrc->height = dest->height; + } + + if (glyphsrc->yoffset < 0) + glyphsrc->height += glyphsrc->yoffset; + + return 1; +} + +static void +redisplay_normalize_display_box (struct display_box* dest, + struct display_glyph_area* glyphsrc) +{ + /* Adjust the destination area. At the end of this the destination + area will exactly enclose the glyph area. The only remaining + adjustment will be offsets into the glyph area. */ + + /* Horizontal adjustment. */ + if (glyphsrc->xoffset > 0) + { + dest->xpos += glyphsrc->xoffset; + dest->width -= glyphsrc->xoffset; + glyphsrc->xoffset = 0; + } + else + glyphsrc->xoffset = -glyphsrc->xoffset; + + if (glyphsrc->width < dest->width) + dest->width = glyphsrc->width; + + /* Vertical adjustment. */ + if (glyphsrc->yoffset > 0) + { + dest->ypos += glyphsrc->yoffset; + dest->height -= glyphsrc->yoffset; + glyphsrc->yoffset = 0; + } + else + glyphsrc->yoffset = -glyphsrc->yoffset; + + if (glyphsrc->height < dest->height) + dest->height = glyphsrc->height; +} + +/***************************************************************************** + redisplay_display_boxes_in_window_p + + Determine whether the require display_glyph_area is completely inside + the window. 0 means the display_box is not in the window. 1 means the + display_box and the display_glyph_area are in the window. -1 means + the display_box is in the window but the display_glyph_area is not. + ****************************************************************************/ +static int +redisplay_display_boxes_in_window_p (struct window* w, + struct display_box* db, + struct display_glyph_area* dga) +{ + int left = WINDOW_TEXT_LEFT (w); + int right = WINDOW_TEXT_RIGHT (w); + int top = WINDOW_TEXT_TOP (w); + int bottom = WINDOW_TEXT_BOTTOM (w); + + if (db->xpos < left || db->ypos < top + || db->xpos + db->width > right + || db->ypos + db->height > bottom) + /* We are not displaying in a window at all */ + return 0; + + if (db->xpos + dga->xoffset >= left + && + db->ypos + dga->yoffset >= top + && + db->xpos + dga->xoffset + dga->width <= right + && + db->ypos + dga->yoffset + dga->height <= bottom) + return 1; + + return -1; +} + +/***************************************************************************** + redisplay_calculate_display_boxes + + Convert from rune/display_line co-ordinates to display_box + co-ordinates. + ****************************************************************************/ +int +redisplay_calculate_display_boxes (struct display_line *dl, int xpos, + int xoffset, int start_pixpos, int width, + struct display_box* dest, + struct display_glyph_area* src) +{ + dest->xpos = xpos; + dest->ypos = DISPLAY_LINE_YPOS (dl); + dest->width = width; + dest->height = DISPLAY_LINE_HEIGHT (dl); + + src->xoffset = -xoffset; + src->yoffset = 0; + src->width = 0; + src->height = 0; + + if (start_pixpos >=0 && start_pixpos > xpos) + { + /* Oops, we're asking for a start outside of the displayable + area. */ + if (start_pixpos > xpos + width) + return 0; + dest->xpos = start_pixpos; + dest->width -= (start_pixpos - xpos); + /* Offsets are -ve when we want to clip pixels off the displayed + glyph. */ + src->xoffset -= (start_pixpos - xpos); + } + + return 1; +} + +/***************************************************************************** redisplay_clear_top_of_window If window is topmost, clear the internal border above it. @@ -1729,6 +2147,7 @@ struct device *d = XDEVICE (f->device); int x, y, width, height; int shadow_thickness = MODELINE_SHADOW_THICKNESS (w); + enum edge_style style; x = WINDOW_MODELINE_LEFT (w); width = WINDOW_MODELINE_RIGHT (w) - x; @@ -1736,8 +2155,15 @@ height = dl->ascent + dl->descent + 2 * shadow_thickness; if (XINT (w->modeline_shadow_thickness) < 0) - shadow_thickness = - shadow_thickness; + { + style = EDGE_BEVEL_IN; + } + else + { + style = EDGE_BEVEL_OUT; + } MAYBE_DEVMETH (d, bevel_area, - (w, MODELINE_INDEX, x, y, width, height, shadow_thickness)); + (w, MODELINE_INDEX, x, y, width, height, shadow_thickness, + EDGE_ALL, style)); } Index: src/redisplay-tty.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/redisplay-tty.c,v retrieving revision 1.15.2.2 diff -u -r1.15.2.2 redisplay-tty.c --- src/redisplay-tty.c 1998/12/18 05:42:13 1.15.2.2 +++ src/redisplay-tty.c 1999/08/23 16:36:45 @@ -392,6 +392,7 @@ case IMAGE_COLOR_PIXMAP: case IMAGE_SUBWINDOW: case IMAGE_WIDGET: + case IMAGE_LAYOUT: /* just do nothing here */ break; Index: src/redisplay-x.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/redisplay-x.c,v retrieving revision 1.23.2.8 diff -u -r1.23.2.8 redisplay-x.c --- src/redisplay-x.c 1999/07/22 06:19:57 1.23.2.8 +++ src/redisplay-x.c 1999/08/23 16:37:04 @@ -59,12 +59,6 @@ #define EOL_CURSOR_WIDTH 5 -static void x_output_pixmap (struct window *w, struct display_line *dl, - Lisp_Object image_instance, int xpos, - int xoffset, - int start_pixpos, int width, face_index findex, - int cursor_start, int cursor_width, - int cursor_height); static void x_output_vertical_divider (struct window *w, int clear); static void x_output_blank (struct window *w, struct display_line *dl, struct rune *rb, int start_pixpos, @@ -445,6 +439,11 @@ else if (rb->type == RUNE_DGLYPH) { Lisp_Object instance; + struct display_box db; + struct display_glyph_area dga; + redisplay_calculate_display_boxes (dl, rb->xpos, rb->object.dglyph.xoffset, + start_pixpos, rb->width, + &db, &dga); XSETWINDOW (window, w); instance = glyph_image_instance (rb->object.dglyph.glyph, @@ -475,26 +474,29 @@ case IMAGE_MONO_PIXMAP: case IMAGE_COLOR_PIXMAP: - x_output_pixmap (w, dl, instance, xpos, - rb->object.dglyph.xoffset, start_pixpos, - rb->width, findex, cursor_start, - cursor_width, cursor_height); + redisplay_output_pixmap (w, instance, &db, &dga, findex, + cursor_start, cursor_width, + cursor_height, 0); break; - case IMAGE_POINTER: - abort (); - case IMAGE_WIDGET: case IMAGE_SUBWINDOW: - redisplay_output_subwindow (w, dl, instance, xpos, - rb->object.dglyph.xoffset, start_pixpos, - rb->width, findex, cursor_start, - cursor_width, cursor_height); + redisplay_output_subwindow (w, instance, &db, &dga, findex, + cursor_start, cursor_width, + cursor_height); + break; + + case IMAGE_LAYOUT: + redisplay_output_layout (w, instance, &db, &dga, findex, + cursor_start, cursor_width, + cursor_height); + break; case IMAGE_NOTHING: /* nothing is as nothing does */ break; + case IMAGE_POINTER: default: abort (); } @@ -531,7 +533,7 @@ static void x_bevel_area (struct window *w, face_index findex, int x, int y, int width, int height, - int shadow_thickness) + int shadow_thickness, int edges, enum edge_style style) { struct frame *f = XFRAME (w->frame); struct device *d = XDEVICE (f->device); @@ -549,6 +551,7 @@ int flip_gcs = 0; unsigned long mask; + assert (shadow_thickness >=0); memset (&gcv, ~0, sizeof (XGCValues)); tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); @@ -618,24 +621,33 @@ gcv.foreground = background_pixel; background_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, mask); - /* possibly revert the GC's in case the shadow thickness is < 0. - This will give a depressed look to the divider */ - if (shadow_thickness < 0) + /* possibly revert the GC's This will give a depressed look to the + divider */ + if (style == EDGE_ETCHED_IN || style == EDGE_BEVEL_IN) { GC temp; temp = top_shadow_gc; top_shadow_gc = bottom_shadow_gc; bottom_shadow_gc = temp; - - /* better avoid a Bad Address XLib error ;-) */ - shadow_thickness = - shadow_thickness; } + if (style == EDGE_ETCHED_IN || style == EDGE_ETCHED_OUT) + shadow_thickness /= 2; + /* Draw the shadows around the divider line */ x_output_shadows (f, x, y, width, height, top_shadow_gc, bottom_shadow_gc, - background_gc, shadow_thickness); + background_gc, shadow_thickness, edges); + + if (style == EDGE_ETCHED_IN || style == EDGE_ETCHED_OUT) + { + /* Draw the shadows around the divider line */ + x_output_shadows (f, x + shadow_thickness, y + shadow_thickness, + width - 2*shadow_thickness, height - 2*shadow_thickness, + bottom_shadow_gc, top_shadow_gc, + background_gc, shadow_thickness, edges); + } } /***************************************************************************** @@ -1153,9 +1165,9 @@ void x_output_x_pixmap (struct frame *f, struct Lisp_Image_Instance *p, int x, - int y, int clip_x, int clip_y, int clip_width, - int clip_height, int width, int height, int pixmap_offset, - unsigned long fg, unsigned long bg, GC override_gc) + int y, int xoffset, int yoffset, + int width, int height, unsigned long fg, unsigned long bg, + GC override_gc) { struct device *d = XDEVICE (f->device); Display *dpy = DEVICE_X_DISPLAY (d); @@ -1164,7 +1176,6 @@ GC gc; XGCValues gcv; unsigned long pixmap_mask; - int need_clipping = (clip_x || clip_y); if (!override_gc) { @@ -1178,17 +1189,16 @@ { gcv.function = GXcopy; gcv.clip_mask = IMAGE_INSTANCE_X_MASK (p); - gcv.clip_x_origin = x; - gcv.clip_y_origin = y - pixmap_offset; + gcv.clip_x_origin = x - xoffset; + gcv.clip_y_origin = y - yoffset; pixmap_mask |= (GCFunction | GCClipMask | GCClipXOrigin | GCClipYOrigin); - /* Can't set a clip rectangle below because we already have a mask. - We could conceivably create a new clipmask by zeroing out - everything outside the clip region. Is it worth it? + /* Can't set a clip rectangle because we already have a mask. Is it possible to get an equivalent effect by changing the args to XCopyArea below rather than messing with a clip box? - - dkindred@cs.cmu.edu */ - need_clipping = 0; + - dkindred@cs.cmu.edu + Yes. We don't clip at all now - andy@xemacs.org + */ } gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, pixmap_mask); @@ -1199,147 +1209,38 @@ /* override_gc might have a mask already--we don't want to nuke it. Maybe we can insist that override_gc have no mask, or use one of the suggestions above. */ - need_clipping = 0; } - if (need_clipping) - { - XRectangle clip_box[1]; - - clip_box[0].x = clip_x; - clip_box[0].y = clip_y; - clip_box[0].width = clip_width; - clip_box[0].height = clip_height; - - XSetClipRectangles (dpy, gc, x, y, clip_box, 1, Unsorted); - } - /* depth of 0 means it's a bitmap, not a pixmap, and we should use XCopyPlane (1 = current foreground color, 0 = background) instead of XCopyArea, which means that the bits in the pixmap are actual pixel values, instead of symbolic of fg/bg. */ if (IMAGE_INSTANCE_PIXMAP_DEPTH (p) > 0) { - XCopyArea (dpy, IMAGE_INSTANCE_X_PIXMAP (p), x_win, gc, 0, - pixmap_offset, width, + XCopyArea (dpy, IMAGE_INSTANCE_X_PIXMAP (p), x_win, gc, xoffset, + yoffset, width, height, x, y); } else { - XCopyPlane (dpy, IMAGE_INSTANCE_X_PIXMAP (p), x_win, gc, 0, - (pixmap_offset < 0 - ? 0 - : pixmap_offset), - width, height, x, - (pixmap_offset < 0 - ? y - pixmap_offset - : y), - 1L); + XCopyPlane (dpy, IMAGE_INSTANCE_X_PIXMAP (p), x_win, gc, + xoffset, yoffset, width, height, x, y, 1L); } - - if (need_clipping) - { - XSetClipMask (dpy, gc, None); - XSetClipOrigin (dpy, gc, 0, 0); - } } static void -x_output_pixmap (struct window *w, struct display_line *dl, - Lisp_Object image_instance, int xpos, int xoffset, - int start_pixpos, int width, face_index findex, - int cursor_start, int cursor_width, int cursor_height) +x_output_pixmap (struct window *w, Lisp_Object image_instance, + struct display_box *db, struct display_glyph_area *dga, + face_index findex, int cursor_start, int cursor_width, + int cursor_height, int bg_pixmap) { struct frame *f = XFRAME (w->frame); struct device *d = XDEVICE (f->device); struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); - Lisp_Object window; Display *dpy = DEVICE_X_DISPLAY (d); Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); - int lheight = dl->ascent + dl->descent - dl->clip; - int pheight = ((int) IMAGE_INSTANCE_PIXMAP_HEIGHT (p) > lheight ? lheight : - IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); - int pwidth = min (width + xoffset, (int) IMAGE_INSTANCE_PIXMAP_WIDTH (p)); - int clip_x, clip_y, clip_width, clip_height; - - /* The pixmap_offset is used to center the pixmap on lines which are - shorter than it is. This results in odd effects when scrolling - pixmaps off of the bottom. Let's try not using it. */ -#if 0 - int pixmap_offset = (int) (IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - lheight) / 2; -#else - int pixmap_offset = 0; -#endif - - XSETWINDOW (window, w); - - if ((start_pixpos >= 0 && start_pixpos > xpos) || xoffset) - { - if (start_pixpos > xpos && start_pixpos > xpos + width) - return; - - clip_x = xoffset; - clip_width = width; - if (start_pixpos > xpos) - { - clip_x += (start_pixpos - xpos); - clip_width -= (start_pixpos - xpos); - } - } - else - { - clip_x = 0; - clip_width = 0; - } - - /* Place markers for possible future functionality (clipping the top - half instead of the bottom half; think pixel scrolling). */ - clip_y = 0; - clip_height = pheight; - - /* Clear the area the pixmap is going into. The pixmap itself will - always take care of the full width. We don't want to clear where - it is going to go in order to avoid flicker. So, all we have to - take care of is any area above or below the pixmap. */ - /* #### We take a shortcut for now. We know that since we have - pixmap_offset hardwired to 0 that the pixmap is against the top - edge so all we have to worry about is below it. */ - /* #### Unless the pixmap has a mask in which case we have to clear - the whole damn thing since we can't yet clear just the area not - included in the mask. */ - if (((int) (dl->ypos - dl->ascent + pheight) < - (int) (dl->ypos + dl->descent - dl->clip)) - || IMAGE_INSTANCE_X_MASK (p)) - { - int clear_x, clear_y, clear_width, clear_height; - - if (IMAGE_INSTANCE_X_MASK (p)) - { - clear_y = dl->ypos - dl->ascent; - clear_height = lheight; - } - else - { - clear_y = dl->ypos - dl->ascent + pheight; - clear_height = lheight - pheight; - } - - if (start_pixpos >= 0 && start_pixpos > xpos) - { - clear_x = start_pixpos; - clear_width = xpos + width - start_pixpos; - } - else - { - clear_x = xpos; - clear_width = width; - } - - redisplay_clear_region (window, findex, clear_x, clear_y, - clear_width, clear_height); - } - + /* Output the pixmap. */ { Lisp_Object tmp_pixel; @@ -1350,20 +1251,19 @@ tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); tmp_bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); - x_output_x_pixmap (f, p, xpos - xoffset, dl->ypos - dl->ascent, clip_x, - clip_y, clip_width, clip_height, - pwidth, pheight, pixmap_offset, + x_output_x_pixmap (f, p, db->xpos, db->ypos, + dga->xoffset, dga->yoffset, + dga->width, dga->height, tmp_fcolor.pixel, tmp_bcolor.pixel, 0); } /* Draw a cursor over top of the pixmap. */ - if (cursor_width && cursor_height && (cursor_start >= xpos) + if (cursor_width && cursor_height && (cursor_start >= db->xpos) && !NILP (w->text_cursor_visible_p) - && (cursor_start < xpos + pwidth)) + && (cursor_start < db->xpos + dga->width)) { GC gc; int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); - int y = dl->ypos - dl->ascent; struct face_cachel *cursor_cachel = WINDOW_FACE_CACHEL (w, get_builtin_face_cache_index @@ -1371,17 +1271,17 @@ gc = x_get_gc (d, Qnil, cursor_cachel->background, Qnil, Qnil, Qnil); - if (cursor_width > xpos + pwidth - cursor_start) - cursor_width = xpos + pwidth - cursor_start; + if (cursor_width > db->xpos + dga->width - cursor_start) + cursor_width = db->xpos + dga->width - cursor_start; if (focus) { - XFillRectangle (dpy, x_win, gc, cursor_start, y, cursor_width, + XFillRectangle (dpy, x_win, gc, cursor_start, db->ypos, cursor_width, cursor_height); } else { - XDrawRectangle (dpy, x_win, gc, cursor_start, y, cursor_width, + XDrawRectangle (dpy, x_win, gc, cursor_start, db->ypos, cursor_width, cursor_height); } } @@ -1404,6 +1304,7 @@ XColor tmp_color; XGCValues gcv; GC background_gc; + enum edge_style style; unsigned long mask; int x, y1, y2, width, shadow_thickness, spacing, line_width; @@ -1439,10 +1340,19 @@ x + spacing + shadow_thickness, y1, line_width, y2 - y1); + if (shadow_thickness < 0) + { + style = EDGE_BEVEL_IN; + } + else + { + style = EDGE_BEVEL_OUT; + } + /* Draw the shadows around the divider line */ x_bevel_area (w, div_face, x + spacing, y1, width - 2 * spacing, y2 - y1, - shadow_thickness); + shadow_thickness, EDGE_ALL, style); } /***************************************************************************** @@ -1609,7 +1519,7 @@ void x_output_shadows (struct frame *f, int x, int y, int width, int height, GC top_shadow_gc, GC bottom_shadow_gc, GC background_gc, - int shadow_thickness) + int shadow_thickness, int edges) { struct device *d = XDEVICE (f->device); @@ -1631,28 +1541,41 @@ for (elt = 0; elt < shadow_thickness; elt++) { int seg1 = elt; - int seg2 = elt + shadow_thickness; - - top_shadow[seg1].x1 = x; - top_shadow[seg1].x2 = x + width - elt - 1; - top_shadow[seg1].y1 = top_shadow[seg1].y2 = y + elt; - - top_shadow[seg2].x1 = top_shadow[seg2].x2 = x + elt; - top_shadow[seg2].y1 = y + shadow_thickness; - top_shadow[seg2].y2 = y + height - elt - 1; + int seg2 = (edges & EDGE_TOP) ? elt + shadow_thickness : elt; + int bot_seg2 = (edges & EDGE_BOTTOM) ? elt + shadow_thickness : elt; - bottom_shadow[seg1].x1 = x + elt + 1; - bottom_shadow[seg1].x2 = x + width - 1; - bottom_shadow[seg1].y1 = bottom_shadow[seg1].y2 = y + height - elt - 1; - - bottom_shadow[seg2].x1 = bottom_shadow[seg2].x2 = x + width - elt - 1; - bottom_shadow[seg2].y1 = y + elt + 1; - bottom_shadow[seg2].y2 = y + height - shadow_thickness; + if (edges & EDGE_TOP) + { + top_shadow[seg1].x1 = x; + top_shadow[seg1].x2 = x + width - elt - 1; + top_shadow[seg1].y1 = top_shadow[seg1].y2 = y + elt; + } + if (edges & EDGE_LEFT) + { + top_shadow[seg2].x1 = top_shadow[seg2].x2 = x + elt; + top_shadow[seg2].y1 = y + shadow_thickness; + top_shadow[seg2].y2 = y + height - elt - 1; + } + if (edges & EDGE_BOTTOM) + { + bottom_shadow[seg1].x1 = x + elt + 1; + bottom_shadow[seg1].x2 = x + width - 1; + bottom_shadow[seg1].y1 = bottom_shadow[seg1].y2 = y + height - elt - 1; + } + if (edges & EDGE_RIGHT) + { + bottom_shadow[bot_seg2].x1 = bottom_shadow[bot_seg2].x2 = x + width - elt - 1; + bottom_shadow[bot_seg2].y1 = y + elt + 1; + bottom_shadow[bot_seg2].y2 = y + height - shadow_thickness; + } } - XDrawSegments (dpy, x_win, top_shadow_gc, top_shadow, shadow_thickness * 2); + XDrawSegments (dpy, x_win, top_shadow_gc, top_shadow, + ((edges & EDGE_TOP) ? shadow_thickness : 0) + + ((edges & EDGE_LEFT) ? shadow_thickness : 0)); XDrawSegments (dpy, x_win, bottom_shadow_gc, bottom_shadow, - shadow_thickness * 2); + ((edges & EDGE_BOTTOM) ? shadow_thickness : 0) + + ((edges & EDGE_RIGHT) ? shadow_thickness : 0)); } /***************************************************************************** @@ -2153,4 +2076,6 @@ CONSOLE_HAS_METHOD (x, flash); CONSOLE_HAS_METHOD (x, ring_bell); CONSOLE_HAS_METHOD (x, bevel_area); + CONSOLE_HAS_METHOD (x, output_string); + CONSOLE_HAS_METHOD (x, output_pixmap); } Index: src/redisplay.h =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/redisplay.h,v retrieving revision 1.7.2.5 diff -u -r1.7.2.5 redisplay.h --- src/redisplay.h 1999/08/16 11:18:55 1.7.2.5 +++ src/redisplay.h 1999/08/23 16:37:07 @@ -310,6 +310,34 @@ Dynarr_declare (display_line); } display_line_dynarr; +/* The following two structures are used to represent an area to +displayed and where to display it. Using these two structures all +combinations of clipping and position can be accomodated. */ + +/* This represents an area to be displayed into. */ +typedef struct display_box display_box; +struct display_box +{ + int xpos; /* absolute horizontal position of area */ + int ypos; /* absolute horizontal position of area */ + int width, height; +}; + +/* This represents the area from a glyph to be displayed. */ +typedef struct display_glyph_area display_glyph_area; +struct display_glyph_area +{ + int xoffset; /* horizontal offset of the glyph, +ve means + display the glyph with x offset by xoffset, + -ve means display starting xoffset into the + glyph. */ + int yoffset; /* vertical offset of the glyph, +ve means + display the glyph with y offset by yoffset, + -ve means display starting xoffset into the + glyph. */ + int width, height; /* width and height of glyph to display. */ +}; + /* It could be argued that the following two structs belong in extents.h, but they're only used by redisplay and it simplifies the header files to put them here. */ @@ -345,6 +373,12 @@ unsigned int invisible_ellipses_already_displayed:1; }; +#define EDGE_TOP 1 +#define EDGE_LEFT 2 +#define EDGE_BOTTOM 4 +#define EDGE_RIGHT 8 +#define EDGE_ALL (EDGE_TOP | EDGE_LEFT | EDGE_BOTTOM | EDGE_RIGHT) + /*************************************************************************/ /* change flags */ @@ -600,12 +634,32 @@ int get_next_display_block (layout_bounds bounds, display_block_dynarr *dba, int start_pos, int *next_start); -void redisplay_output_subwindow (struct window *w, struct display_line *dl, - Lisp_Object image_instance, int xpos, - int xoffset, int start_pixpos, int width, - face_index findex, int cursor_start, - int cursor_width, int cursor_height); +void redisplay_output_layout (struct window *w, + Lisp_Object image_instance, + struct display_box* db, struct display_glyph_area* dga, + face_index findex, int cursor_start, int cursor_width, + int cursor_height); +void redisplay_output_subwindow (struct window *w, + Lisp_Object image_instance, + struct display_box* db, struct display_glyph_area* dga, + face_index findex, int cursor_start, int cursor_width, + int cursor_height); void redisplay_unmap_subwindows_maybe (struct frame* f, int x, int y, int width, int height); +void redisplay_output_pixmap (struct window *w, + Lisp_Object image_instance, + struct display_box* db, struct display_glyph_area* dga, + face_index findex, int cursor_start, int cursor_width, + int cursor_height, int offset_bitmap); +int redisplay_calculate_display_boxes (struct display_line *dl, int xpos, + int xoffset, int start_pixpos, int width, + struct display_box* dest, + struct display_glyph_area* src); +void redisplay_clear_clipped_region (Lisp_Object locale, face_index findex, + struct display_box* dest, + struct display_glyph_area* glyphsrc, + int fullheight_p); +int redisplay_normalize_glyph_area (struct display_box* dest, + struct display_glyph_area* glyphsrc); void redisplay_clear_to_window_end (struct window *w, int ypos1, int ypos2); void redisplay_clear_region (Lisp_Object window, face_index findex, int x, int y, int width, int height); Index: src/toolbar-x.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/toolbar-x.c,v retrieving revision 1.12.2.2 diff -u -r1.12.2.2 toolbar-x.c --- src/toolbar-x.c 1998/12/18 05:42:15 1.12.2.2 +++ src/toolbar-x.c 1999/08/23 16:37:08 @@ -77,7 +77,8 @@ /* Draw the outline. */ x_output_shadows (f, sx, sy, swidth, sheight, top_shadow_gc, - bottom_shadow_gc, background_gc, shadow_thickness); + bottom_shadow_gc, background_gc, shadow_thickness, + EDGE_ALL); /* Blank the middle. */ XFillRectangle (dpy, x_win, background_gc, sx + shadow_thickness, @@ -158,7 +159,8 @@ x_output_shadows (f, tb->x + x_adj, tb->y + y_adj, tb->width + width_adj, tb->height + height_adj, top_shadow_gc, - bottom_shadow_gc, background_gc, shadow_thickness); + bottom_shadow_gc, background_gc, shadow_thickness, + EDGE_ALL); /* Clear the pixmap area. */ XFillRectangle (dpy, x_win, background_gc, tb->x + x_adj + shadow_thickness, @@ -211,8 +213,8 @@ } x_output_x_pixmap (f, XIMAGE_INSTANCE (instance), tb->x + x_offset, - tb->y + y_offset, 0, 0, 0, 0, width, height, - 0, 0, 0, background_gc); + tb->y + y_offset, 0, 0, width, height, + 0, 0, background_gc); } else if (IMAGE_INSTANCE_TYPE (p) == IMAGE_TEXT) { Index: tests/glyph-test.el =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/tests/Attic/glyph-test.el,v retrieving revision 1.1.2.12 diff -u -r1.1.2.12 glyph-test.el --- tests/glyph-test.el 1999/08/08 13:50:14 1.1.2.12 +++ tests/glyph-test.el 1999/08/23 16:37:08 @@ -12,13 +12,17 @@ (setq ok-select nil) (set-extent-begin-glyph (make-extent (point) (point)) - (make-glyph [button :descriptor ["ok " (setq ok-select t) - :style radio :selected ok-select]])) + (setq radio-button1 + (make-glyph + [button :descriptor ["ok " (setq ok-select t) + :style radio :selected ok-select]]))) ;; button in a group (set-extent-begin-glyph (make-extent (point) (point)) - (make-glyph [button :descriptor ["ok" (setq ok-select nil) :style radio - :selected (not ok-select)]])) + (setq radio-button2 + (make-glyph + [button :descriptor ["ok" (setq ok-select nil) :style radio + :selected (not ok-select)]]))) ;; toggle button (set-extent-begin-glyph (make-extent (point) (point)) @@ -28,19 +32,20 @@ :selected (not ok-select)]]))) (set-extent-begin-glyph (make-extent (point) (point)) - (make-glyph [button :descriptor ["ok" :style toggle - :callback - (setq ok-select (not ok-select)) - :selected ok-select]])) + (setq toggle-button + (make-glyph [button :descriptor ["ok" :style toggle + :callback + (setq ok-select (not ok-select)) + :selected ok-select]]))) ;; normal pushbutton (set-extent-begin-glyph (make-extent (point) (point)) - (setq pbutton (make-glyph - [button :width 10 :height 2 - :face modeline-mousable - :descriptor "ok" :callback foo - :selected t]))) + (setq push-button + (make-glyph [button :width 10 :height 2 + :face modeline-mousable + :descriptor "ok" :callback foo + :selected t]))) ;; tree view (set-extent-begin-glyph (make-extent (point) (point)) @@ -105,20 +110,20 @@ ;; edit box (set-extent-begin-glyph (make-extent (point) (point)) - (setq hedit (make-glyph [edit-field :pixel-width 50 :pixel-height 30 - :face bold-italic - :descriptor ["Hello"]]))) + (setq edit-field (make-glyph [edit-field :pixel-width 50 :pixel-height 30 + :face bold-italic + :descriptor ["Hello"]]))) ;; combo box (set-extent-begin-glyph (make-extent (point) (point)) - (setq hcombo (make-glyph - [combo-box :width 10 :descriptor ["Hello"] - :properties (:items ("One" "Two" "Three"))]))) + (setq combo-box (make-glyph + [combo-box :width 10 :descriptor ["Hello"] + :properties (:items ("One" "Two" "Three"))]))) -;; line +;; label (set-extent-begin-glyph (make-extent (point) (point)) - (make-glyph [label :pixel-width 150 :descriptor "Hello"])) + (setq label (make-glyph [label :pixel-width 150 :descriptor "Hello"]))) ;; scrollbar ;(set-extent-begin-glyph @@ -129,3 +134,17 @@ (setq sw (make-glyph [subwindow :pixel-width 50 :pixel-height 70])) (set-extent-begin-glyph (make-extent (point) (point)) sw) +;; layout +(setq layout (make-extent (point)(point))) +(set-extent-face layout 'gui-element) +(set-extent-begin-glyph + layout + (make-glyph + [layout :pixel-width 200 :pixel-height 200 + :orientation vertical + :justify left + :border etched-in + :items ((make-glyph [layout :orientation horizontal + :items (radio-button1 radio-button2)]) + edit-field toggle-button label)])) +