Index: event-msw.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/event-msw.c,v retrieving revision 1.38.2.18 diff -u -r1.38.2.18 event-msw.c --- event-msw.c 1999/08/04 15:30:39 1.38.2.18 +++ event-msw.c 1999/08/08 13:36:51 @@ -1982,21 +1982,35 @@ case WM_PAINT: { - PAINTSTRUCT paintStruct; - int x, y, width, height; - - frame = XFRAME (mswindows_find_frame (hwnd)); + /* According to the docs we need to check GetUpdateRect() before + actually doing a WM_PAINT */ + if (GetUpdateRect (hwnd, NULL, FALSE)) + { + PAINTSTRUCT paintStruct; + int x, y, width, height; - BeginPaint (hwnd, &paintStruct); - x = paintStruct.rcPaint.left; - y = paintStruct.rcPaint.top; - width = paintStruct.rcPaint.right - paintStruct.rcPaint.left; - height = paintStruct.rcPaint.bottom - paintStruct.rcPaint.top; - - if (!check_for_ignored_expose (frame, x, y, width, height)) - mswindows_redraw_exposed_area (frame, x, y, width, height); + frame = XFRAME (mswindows_find_frame (hwnd)); + + BeginPaint (hwnd, &paintStruct); + x = paintStruct.rcPaint.left; + y = paintStruct.rcPaint.top; + width = paintStruct.rcPaint.right - paintStruct.rcPaint.left; + height = paintStruct.rcPaint.bottom - paintStruct.rcPaint.top; + /* Normally we want to ignore expose events when child + windows are unmapped, however once we are in the guts of + WM_PAINT we need to make sure that we don't register + unmaps then because they will not actually occur. */ + if (!check_for_ignored_expose (frame, x, y, width, height)) + { + hold_ignored_expose_registration = 1; + mswindows_redraw_exposed_area (frame, x, y, width, height); + hold_ignored_expose_registration = 0; + } - EndPaint (hwnd, &paintStruct); + EndPaint (hwnd, &paintStruct); + } + else + goto defproc; } break; Index: glyphs-msw.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs-msw.c,v retrieving revision 1.21.2.20 diff -u -r1.21.2.20 glyphs-msw.c --- glyphs-msw.c 1999/07/30 09:14:03 1.21.2.20 +++ glyphs-msw.c 1999/08/08 13:37:08 @@ -107,7 +107,6 @@ struct frame* f); COLORREF mswindows_string_to_color (CONST char *name); -void check_valid_item_list_1 (Lisp_Object items); #define BPLINE(width) ((int)(~3UL & (unsigned long)((width) +3))) @@ -2040,8 +2039,8 @@ SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), NULL, 0, 0, 0, 0, - SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE - | SWP_NOCOPYBITS | SWP_NOSENDCHANGING); + SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE + | SWP_NOSENDCHANGING); } } @@ -2050,12 +2049,19 @@ static void mswindows_map_subwindow (struct Lisp_Image_Instance *p, int x, int y) { - /* ShowWindow (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), SW_SHOW);*/ + /* move the window before mapping it ... */ SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), NULL, x, y, 0, 0, - SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOSIZE + SWP_NOZORDER | SWP_NOSIZE | SWP_NOCOPYBITS | SWP_NOSENDCHANGING); + /* ... now map it - we are not allowed to move it at the same time. */ + SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), + NULL, + 0, 0, 0, 0, + SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE + | SWP_SHOWWINDOW | SWP_NOCOPYBITS + | SWP_NOSENDCHANGING); } /* resize the subwindow instance */ @@ -2217,6 +2223,7 @@ int dest_mask, Lisp_Object domain, CONST char* class, int flags, int exflags) { + /* this function can call lisp */ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); #if 0 struct Lisp_Image_Instance *groupii = 0; @@ -2299,6 +2306,7 @@ Lisp_Object pointer_fg, Lisp_Object pointer_bg, int dest_mask, Lisp_Object domain) { + /* this function can call lisp */ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); HWND wnd; int flags = BS_NOTIFY; @@ -2618,6 +2626,10 @@ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); HANDLE wnd; Lisp_Object rest; + Lisp_Object data = Fplist_get (find_keyword_in_vector (instantiator, Q_properties), + Q_items, Qnil); + int len; + GET_LIST_LENGTH (data, len); /* Maybe ought to generalise this more but it may be very windows specific. In windows the window height of a combo box is the @@ -2625,6 +2637,9 @@ before creating the window and then reset it to a single line after the window is created so that redisplay does the right thing. */ + widget_instantiate_1 (image_instance, instantiator, pointer_fg, + pointer_bg, dest_mask, domain, len + 1, 0, 0); + mswindows_widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, dest_mask, domain, "COMBOBOX", WS_BORDER | WS_TABSTOP | CBS_DROPDOWN Index: glyphs-widget.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/Attic/glyphs-widget.c,v retrieving revision 1.1.2.8 diff -u -r1.1.2.8 glyphs-widget.c --- glyphs-widget.c 1999/07/30 09:14:03 1.1.2.8 +++ glyphs-widget.c 1999/08/08 13:37:16 @@ -331,7 +331,7 @@ want to display it in and BitBlt it. So image instances can have a many-to-one relationship with things you see, whereas widgets can only be one-to-one (i.e. per frame) */ -static void +void widget_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator, Lisp_Object pointer_fg, Lisp_Object pointer_bg, int dest_mask, Lisp_Object domain, int default_textheight, @@ -452,11 +452,11 @@ pointer_bg, dest_mask, domain, 1, 0, 0); } -/* combo-box generic instantiation - get the height right */ +/* tree-view generic instantiation - get the height right */ static void -combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, - Lisp_Object pointer_fg, Lisp_Object pointer_bg, - int dest_mask, Lisp_Object domain) +tree_view_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, + Lisp_Object pointer_fg, Lisp_Object pointer_bg, + int dest_mask, Lisp_Object domain) { Lisp_Object data = Fplist_get (find_keyword_in_vector (instantiator, Q_properties), Q_items, Qnil); @@ -572,7 +572,6 @@ INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (combo_box, "combo-box"); IIFORMAT_HAS_METHOD (combo_box, validate); IIFORMAT_HAS_SHARED_METHOD (combo_box, possible_dest_types, widget); - IIFORMAT_HAS_METHOD (combo_box, instantiate); VALID_GUI_KEYWORDS (combo_box); IIFORMAT_VALID_KEYWORD (combo_box, Q_width, check_valid_int); @@ -596,7 +595,7 @@ INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (progress_gauge, "progress-gauge"); IIFORMAT_HAS_SHARED_METHOD (progress_gauge, validate, widget); IIFORMAT_HAS_SHARED_METHOD (progress_gauge, possible_dest_types, widget); - IIFORMAT_HAS_SHARED_METHOD (progress_gauge, instantiate, combo_box); + IIFORMAT_HAS_SHARED_METHOD (progress_gauge, instantiate, widget); VALID_WIDGET_KEYWORDS (progress_gauge); VALID_GUI_KEYWORDS (progress_gauge); @@ -604,7 +603,7 @@ INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tree_view, "tree-view"); IIFORMAT_HAS_SHARED_METHOD (tree_view, validate, combo_box); IIFORMAT_HAS_SHARED_METHOD (tree_view, possible_dest_types, widget); - IIFORMAT_HAS_SHARED_METHOD (tree_view, instantiate, combo_box); + IIFORMAT_HAS_METHOD (tree_view, instantiate); VALID_WIDGET_KEYWORDS (tree_view); VALID_GUI_KEYWORDS (tree_view); IIFORMAT_VALID_KEYWORD (tree_view, Q_properties, check_valid_item_list); Index: glyphs-x.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs-x.c,v retrieving revision 1.49.2.17 diff -u -r1.49.2.17 glyphs-x.c --- glyphs-x.c 1999/08/04 15:16:14 1.49.2.17 +++ glyphs-x.c 1999/08/08 13:37:26 @@ -128,11 +128,12 @@ DEFINE_DEVICE_IIFORMAT (x, button); DEFINE_DEVICE_IIFORMAT (x, progress_gauge); DEFINE_DEVICE_IIFORMAT (x, edit_field); +#if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1 DEFINE_DEVICE_IIFORMAT (x, combo_box); +#endif DEFINE_DEVICE_IIFORMAT (x, tab_control); #endif -void check_valid_item_list_1 (Lisp_Object items); static void cursor_font_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, Lisp_Object pointer_fg, @@ -2412,6 +2413,7 @@ pointer_bg, dest_mask, domain, "text-field", wv); } +#if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1 /* instantiate a combo control */ static void x_combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, @@ -2419,27 +2421,18 @@ int dest_mask, Lisp_Object domain) { struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); - Lisp_Object rest; - Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); - widget_value* wv = xmalloc_widget_value (); + widget_value * wv = 0; + /* This is not done generically because of sizing problems under + mswindows. */ + widget_instantiate_1 (image_instance, instantiator, pointer_fg, + pointer_bg, dest_mask, domain, 1, 0, 0); - button_item_to_widget_value (gui, wv, 1, 1); + wv = gui_items_to_widget_values (IMAGE_INSTANCE_WIDGET_ITEMS (ii)); x_widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg, dest_mask, domain, "combo-box", wv); - /* add items to the combo box */ - LIST_LOOP (rest, Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), Q_items, Qnil)) - { -#if 0 - Extbyte* str; - XmString xmstr; - GET_C_STRING_OS_DATA_ALLOCA (XCAR (rest), str); - xmstr = XmStringCreate (str, XmSTRING_DEFAULT_CHARSET); - XmListAddItem (IMAGE_INSTANCE_X_WIDGET_ID (ii), xmstr, 0); - XmStringFree (xmstr); -#endif - } } +#endif static void x_tab_control_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, @@ -2557,10 +2550,11 @@ /* text field */ INITIALIZE_DEVICE_IIFORMAT (x, edit_field); IIFORMAT_HAS_DEVMETHOD (x, edit_field, instantiate); -#if 0 /* XmVERSION > 1*/ +#if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1 /* combo box */ INITIALIZE_DEVICE_IIFORMAT (x, combo_box); IIFORMAT_HAS_DEVMETHOD (x, combo_box, instantiate); + IIFORMAT_HAS_SHARED_DEVMETHOD (x, combo_box, set_property, tab_control); #endif /* tab control widget */ INITIALIZE_DEVICE_IIFORMAT (x, tab_control); Index: glyphs.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs.c,v retrieving revision 1.23.2.18 diff -u -r1.23.2.18 glyphs.c --- glyphs.c 1999/08/05 10:22:41 1.23.2.18 +++ glyphs.c 1999/08/08 13:38:35 @@ -124,6 +124,11 @@ Lisp_Object property, 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 + to register exposures as they will not occur. Under X they will + always occur. */ +int hold_ignored_expose_registration; EXFUN (Fimage_instance_type, 1); EXFUN (Fglyph_type, 1); @@ -1314,18 +1319,20 @@ !UNBOUNDP (ret = IIFORMAT_METH (meths, set_property, (image_instance, prop, val)))) { - return ret; + val = ret; } - /* ... then format specific methods ... */ - meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT); - if (meths && HAS_IIFORMAT_METH_P (meths, set_property) - && - !UNBOUNDP (ret = - IIFORMAT_METH (meths, set_property, (image_instance, prop, val)))) + else { - return ret; + /* ... then format specific methods ... */ + meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT); + if (meths && HAS_IIFORMAT_METH_P (meths, set_property) + && + !UNBOUNDP (ret = + IIFORMAT_METH (meths, set_property, (image_instance, prop, val)))) + { + val = ret; + } } - return val; } @@ -3755,6 +3762,10 @@ && ei->x + ei->width >= x + width && ei->y + ei->height >= y + height) { +#ifdef DEBUG_WIDGETS + stderr_out ("ignored %d+%d, %dx%d for exposure %d+%d, %dx%d\n", + x, y, width, height, ei->x, ei->y, ei->width, ei->height); +#endif if (!prev) f->subwindow_exposures = ei->next; else @@ -3774,28 +3785,31 @@ static void register_ignored_expose (struct frame* f, int x, int y, int width, int height) { - struct expose_ignore *ei; - - ei = Blocktype_alloc (the_expose_ignore_blocktype); - - ei->next = NULL; - ei->x = x; - ei->y = y; - ei->width = width; - ei->height = height; - - /* we have to add the exposure to the end of the list, since we - want to check the oldest events first. for speed we keep a record - of the end so that we can add right to it. */ - if (f->subwindow_exposures_tail) - { - f->subwindow_exposures_tail->next = ei; - } - if (!f->subwindow_exposures) + if (!hold_ignored_expose_registration) { - f->subwindow_exposures = ei; + struct expose_ignore *ei; + + ei = Blocktype_alloc (the_expose_ignore_blocktype); + + ei->next = NULL; + ei->x = x; + ei->y = y; + ei->width = width; + ei->height = height; + + /* we have to add the exposure to the end of the list, since we + want to check the oldest events first. for speed we keep a record + of the end so that we can add right to it. */ + if (f->subwindow_exposures_tail) + { + f->subwindow_exposures_tail->next = ei; + } + if (!f->subwindow_exposures) + { + f->subwindow_exposures = ei; + } + f->subwindow_exposures_tail = ei; } - f->subwindow_exposures_tail = ei; } @@ -3849,7 +3863,9 @@ || NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii))) return; - +#ifdef DEBUG_WIDGETS + stderr_out ("unmapping subwindow %d\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii)); +#endif f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); elt = get_subwindow_cachel_index (f, subwindow); cachel = Dynarr_atp (f->subwindow_cachels, elt); @@ -3879,6 +3895,9 @@ NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii))) return; +#ifdef DEBUG_WIDGETS + stderr_out ("mapping subwindow %d\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii)); +#endif f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)); IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 1; elt = get_subwindow_cachel_index (f, subwindow); @@ -4379,6 +4398,7 @@ #ifdef HAVE_XFACE Fprovide (Qxface); #endif + hold_ignored_expose_registration = 0; } void Index: glyphs.h =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs.h,v retrieving revision 1.18.2.14 diff -u -r1.18.2.14 glyphs.h --- glyphs.h 1999/07/30 09:14:04 1.18.2.14 +++ glyphs.h 1999/08/08 13:38:36 @@ -252,6 +252,8 @@ initialization routines */ #define IIFORMAT_HAS_DEVMETHOD(type, format, m) \ (type##_##format##_image_instantiator_methods->m##_method = type##_##format##_##m) +#define IIFORMAT_HAS_SHARED_DEVMETHOD(type, format, m, fromformat) \ + (type##_##format##_image_instantiator_methods->m##_method = type##_##fromformat##_##m) struct image_instantiator_methods * decode_device_ii_format (Lisp_Object device, Lisp_Object format, @@ -279,11 +281,16 @@ void check_valid_int (Lisp_Object data); void check_valid_face (Lisp_Object data); void check_valid_vector (Lisp_Object data); +void check_valid_item_list_1 (Lisp_Object items); void initialize_subwindow_image_instance (struct Lisp_Image_Instance*); void subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, Lisp_Object pointer_fg, Lisp_Object pointer_bg, int dest_mask, Lisp_Object domain); +void widget_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator, + Lisp_Object pointer_fg, Lisp_Object pointer_bg, + int dest_mask, Lisp_Object domain, int default_textheight, + int default_pixheight, int default_textwidth); DECLARE_DOESNT_RETURN (incompatible_image_types (Lisp_Object instantiator, int given_dest_mask, @@ -779,5 +786,6 @@ }; int check_for_ignored_expose (struct frame* f, int x, int y, int width, int height); +extern int hold_ignored_expose_registration; #endif /* _XEMACS_GLYPHS_H_ */ Index: gui-x.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/gui-x.c,v retrieving revision 1.14.2.8 diff -u -r1.14.2.8 gui-x.c --- gui-x.c 1999/08/04 15:16:15 1.14.2.8 +++ gui-x.c 1999/08/08 13:38:36 @@ -325,7 +325,19 @@ /* !!#### This function has not been Mule-ized */ /* This function cannot GC because gc_currently_forbidden is set when it's called */ - struct Lisp_Gui_Item* pgui = XGUI_ITEM (gui_item); + struct Lisp_Gui_Item* pgui = 0; + + /* degenerate case */ + if (STRINGP (gui_item)) + { + wv->type = TEXT_TYPE; + wv->name = (char *) XSTRING_DATA (gui_item); + return 1; + } + else if (!GUI_ITEMP (gui_item)) + signal_simple_error("need a string or a gui_item here", gui_item); + + pgui = XGUI_ITEM (gui_item); if (!NILP (pgui->filter)) signal_simple_error(":filter keyword not permitted on leaf nodes", gui_item); Index: gui.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/gui.c,v retrieving revision 1.10.2.11 diff -u -r1.10.2.11 gui.c --- gui.c 1999/08/05 10:22:41 1.10.2.11 +++ gui.c 1999/08/08 13:38:40 @@ -383,6 +383,7 @@ gui_item_display_flush_left (Lisp_Object gui_item, char* buf, Bytecount buf_len) { + /* This function can call lisp */ char *p = buf; Bytecount len; struct Lisp_Gui_Item* pgui_item = XGUI_ITEM (gui_item); Index: gutter.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/Attic/gutter.c,v retrieving revision 1.1.2.4 diff -u -r1.1.2.4 gutter.c --- gutter.c 1999/07/30 09:14:05 1.1.2.4 +++ gutter.c 1999/08/08 13:38:46 @@ -230,14 +230,13 @@ f->current_display_lines = Dynarr_new (display_line); if (!f->desired_display_lines) f->desired_display_lines = Dynarr_new (display_line); - + ddla = f->desired_display_lines; cdla = f->current_display_lines; XSETFRAME (frame, f); get_gutter_coords (f, pos, &x, &y, &width, &height); - /* clear out what we want to cover */ /* generate some display lines */ generate_displayable_area (w, WINDOW_GUTTER (w, pos), x + border_width, y + border_width, @@ -324,7 +323,7 @@ void update_frame_gutters (struct frame *f) { - if (f->gutter_changed || f->frame_changed || f->clear) + if (f->gutter_changed || f->frame_changed || f->clear || f->glyphs_changed) { int pos; /* and output */ Index: redisplay-output.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/redisplay-output.c,v retrieving revision 1.11.2.8 diff -u -r1.11.2.8 redisplay-output.c --- redisplay-output.c 1999/07/30 14:34:46 1.11.2.8 +++ redisplay-output.c 1999/08/08 13:38:56 @@ -658,7 +658,11 @@ region or if it was a block of a different type, then output the entire ddb. Otherwise, compare cdb and ddb and output only the changed region. */ - if (!force && cdb && ddb->type == cdb->type && b == old_b) + if (!force && cdb && ddb->type == cdb->type + /* If there was no buffer being display before the + compare anyway as we might be outputting a gutter. */ + && + (b == old_b || !old_b)) { must_sync |= compare_display_blocks (w, cdl, ddl, old_block, block, start_pixpos, @@ -1005,7 +1009,27 @@ { struct frame *f = XFRAME (w->frame); struct device *d = XDEVICE (f->device); + struct display_block *db = Dynarr_atp (dl->display_blocks, block); + rune_dynarr *rba = db->runes; + struct rune *rb; + int xpos, width; + rb = Dynarr_atp (rba, start); + if (!rb) + /* Nothing to do so don't do anything. */ + return; + + xpos = max (start_pixpos, rb->xpos); + + if (end < 0) + end = Dynarr_length (rba); + + rb = Dynarr_atp (rba, end - 1); + width = rb->xpos + rb->width - xpos; + /* make sure the area we are about to display is subwindow free. */ + redisplay_unmap_subwindows_maybe (f, xpos, DISPLAY_LINE_YPOS (dl), + width, DISPLAY_LINE_HEIGHT (dl)); + /* now actually output the block. */ DEVMETH (d, output_display_block, (w, dl, block, start, end, start_pixpos, cursor_start, cursor_width, Index: redisplay.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/redisplay.c,v retrieving revision 1.55.2.9 diff -u -r1.55.2.9 redisplay.c --- redisplay.c 1999/07/18 19:03:57 1.55.2.9 +++ redisplay.c 1999/08/08 13:39:45 @@ -6262,7 +6262,6 @@ being handled. */ update_frame_menubars (f); #endif /* HAVE_MENUBARS */ - update_frame_gutters (f); /* widgets are similar to menus in that they can call lisp to determine activation etc. Therefore update them before we get into redisplay. This is primarily for connected widgets such as @@ -6273,6 +6272,26 @@ update_frame_toolbars (f); #endif /* HAVE_TOOLBARS */ + /* If we clear the frame we have to force its contents to be redrawn. */ + if (f->clear) + f->frame_changed = 1; + + /* invalidate the subwindow cache. we are going to reuse the glyphs + flag here to cause subwindows to get instantiated. This is + because subwindows changed is less strict - dealing with things + like the clicked state of button. We have to do this before + redisplaying the gutters as subwindows get unmapped in the + process.*/ + if (!Dynarr_length (f->subwindow_cachels) + || f->glyphs_changed + || f->frame_changed) + reset_subwindow_cachels (f); + else + mark_subwindow_cachels_as_not_updated (f); + /* We can now update the gutters, safe in the knowledge that our + efforts won't get undone. */ + update_frame_gutters (f); + hold_frame_size_changes (); /* ----------------- BEGIN CRITICAL REDISPLAY SECTION ---------------- */ @@ -6299,26 +6318,11 @@ #### If a frame-size change does occur we should probably actually be preempting redisplay. */ - /* If we clear the frame we have to force its contents to be redrawn. */ - if (f->clear) - f->frame_changed = 1; - /* Erase the frame before outputting its contents. */ if (f->clear) { DEVMETH (d, clear_frame, (f)); } - - /* invalidate the subwindow cache. we are going to reuse the glyphs - flag here to cause subwindows to get instantiated. This is - because subwindows changed is less strict - dealing with things - like the clicked state of button. */ - if (!Dynarr_length (f->subwindow_cachels) - || f->glyphs_changed - || f->frame_changed) - reset_subwindow_cachels (f); - else - mark_subwindow_cachels_as_not_updated (f); /* Do the selected window first. */ redisplay_window (FRAME_SELECTED_WINDOW (f), 0); Index: toolbar-msw.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/toolbar-msw.c,v retrieving revision 1.13.2.3 diff -u -r1.13.2.3 toolbar-msw.c --- toolbar-msw.c 1999/05/15 04:51:07 1.13.2.3 +++ toolbar-msw.c 1999/08/08 13:39:51 @@ -59,6 +59,9 @@ #define MSWINDOWS_BLANK_SIZE 5 #define MSWINDOWS_MINIMUM_TOOLBAR_SIZE 8 +static void +mswindows_move_toolbar (struct frame *f, enum toolbar_pos pos); + #define SET_TOOLBAR_WAS_VISIBLE_FLAG(frame, pos, flag) \ do { \ switch (pos) \ @@ -460,6 +463,9 @@ /* now display the window */ ShowWindow (toolbarwnd, SW_SHOW); + /* no idea why this is necessary but initial display will not + happen otherwise. */ + mswindows_move_toolbar (f, pos); if (button_tbl) xfree (button_tbl); @@ -525,6 +531,13 @@ } static void +mswindows_redraw_frame_toolbars (struct frame *f) +{ + mswindows_redraw_exposed_toolbars (f, 0, 0, FRAME_PIXWIDTH (f), + FRAME_PIXHEIGHT (f)); +} + +static void mswindows_initialize_frame_toolbars (struct frame *f) { @@ -636,5 +649,6 @@ CONSOLE_HAS_METHOD (mswindows, initialize_frame_toolbars); CONSOLE_HAS_METHOD (mswindows, free_frame_toolbars); CONSOLE_HAS_METHOD (mswindows, redraw_exposed_toolbars); + CONSOLE_HAS_METHOD (mswindows, redraw_frame_toolbars); } Index: window.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/window.c,v retrieving revision 1.41.2.11 diff -u -r1.41.2.11 window.c --- window.c 1999/07/19 11:04:14 1.41.2.11 +++ window.c 1999/08/08 13:40:18 @@ -5466,6 +5466,77 @@ return unbind_to (speccount, val); } +DEFUN ("current-pixel-column", Fcurrent_pixel_column, 0, 2, 0, /* +Return the horizontal pixel position of POS in window. +Beginning of line is column 0. This is calculated using the redisplay +display tables. If WINDOW is nil, the current window is assumed. +If POS is nil, point is assumed. Note that POS must be visible for +a non-nil result to be returned. +*/ + (window, pos)) +{ + struct window* w = decode_window (window); + display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP); + + struct display_line *dl = 0; + struct display_block *db = 0; + struct rune* rb = 0; + int y = w->last_point_y[CURRENT_DISP]; + int x = w->last_point_x[CURRENT_DISP]; + + if (MINI_WINDOW_P (w)) + return Qnil; + + if (y<0 || x<0 || y >= Dynarr_length (dla) || !NILP (pos)) + { + int first_line, i; + Bufpos point; + + if (NILP (pos)) + pos = Fwindow_point (window); + + CHECK_INT (pos); + point = XINT (pos); + + if (Dynarr_length (dla) && Dynarr_atp (dla, 0)->modeline) + first_line = 1; + else + first_line = 0; + + for (i = first_line; i < Dynarr_length (dla); i++) + { + dl = Dynarr_atp (dla, i); + /* find the vertical location first */ + if (point >= dl->bufpos && point <= dl->end_bufpos) + { + db = get_display_block_from_line (dl, TEXT); + for (i = 0; i < Dynarr_length (db->runes); i++) + { + rb = Dynarr_atp (db->runes, i); + if (point <= rb->bufpos) + goto found_bufpos; + } + return Qnil; + } + } + return Qnil; + found_bufpos: + } + else + { + /* optimised case */ + dl = Dynarr_atp (dla, y); + db = get_display_block_from_line (dl, TEXT); + + if (x >= Dynarr_length (db->runes)) + return Qnil; + + rb = Dynarr_atp (db->runes, x); + } + + return make_int (rb->xpos - WINDOW_LEFT (w)); +} + #ifdef DEBUG_XEMACS /* This is short and simple in elisp, but... it was written to debug @@ -5613,6 +5684,7 @@ DEFSUBR (Fset_window_configuration); DEFSUBR (Fcurrent_window_configuration); DEFSUBR (Fsave_window_excursion); + DEFSUBR (Fcurrent_pixel_column); } void Index: gutter-items.el =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/lisp/Attic/gutter-items.el,v retrieving revision 1.1.2.7 diff -u -r1.1.2.7 gutter-items.el --- gutter-items.el 1999/08/05 10:22:37 1.1.2.7 +++ gutter-items.el 1999/08/08 13:41:01 @@ -70,7 +70,7 @@ shown. If this is nil, then all buffers will be shown. Setting this to a large number or nil will slow down tab responsiveness." :type '(choice (const :tag "Show all" nil) - (integer 10)) + (integer 6)) :group 'buffers-tab) (defcustom buffers-tab-switch-to-buffer-function 'buffers-tab-switch-to-buffer @@ -91,6 +91,15 @@ function) :group 'buffers-tab) +(defcustom buffers-tab-selection-function 'select-buffers-tab-buffers-by-mode + "*If non-nil, a function specifying the buffers to select from the buffers tab. +This is passed two buffers and should return non-nil if the second buffer should be +selected. The default value `select-buffers-tab-buffers-by-mode' groups +buffers by major mode." + :type '(choice (const :tag "None" nil) + function) + :group 'buffers-tab) + (defcustom buffers-tab-format-buffer-line-function 'format-buffers-menu-line "*The function to call to return a string to represent a buffer in the buffers tab. The function is passed a buffer and should return a string. @@ -102,7 +111,17 @@ (defun buffers-tab-switch-to-buffer (buffer) "For use as a value for `buffers-tab-switch-to-buffer-function'." - (switch-to-buffer buffer t)) + (unless (eq (window-buffer) buffer) + (if (> (length (windows-of-buffer buffer)) 0) + (select-window (car (windows-of-buffer buffer))) + (switch-to-buffer buffer t)))) + +(defun select-buffers-tab-buffers-by-mode (buf1 buf2) + "For use as a value of `buffers-tab-selection-function'. +This selects buffers by major mode." + (cond ((eq (symbol-value-in-buffer 'major-mode buf1) + (symbol-value-in-buffer 'major-mode buf2)) t) + (t nil))) (defsubst build-buffers-tab-internal (buffers) (let (line) @@ -114,14 +133,24 @@ (buffer-name buffer)))) buffers))) -(defun buffers-tab-items (&optional frame) +(defun buffers-tab-items (&optional in-deletion frame) "This is the tab filter for the top-level buffers \"Buffers\" tab. It dynamically creates a list of buffers to use as the contents of the tab. Only the most-recently-used few buffers will be listed on the tab, for efficiency reasons. You can control how many buffers will be shown by setting `buffers-tab-max-size'. You can control the text of the tab items by redefining the function `format-buffers-menu-line'." - (let ((buffers (delete-if buffers-tab-omit-function (buffer-list frame)))) + (let* ((buffers (delete-if buffers-tab-omit-function (buffer-list frame))) + (first-buf (car buffers))) + ;; if we're in deletion ignore the current buffer + (when in-deletion + (setq buffers (delq (current-buffer) buffers)) + (setq first-buf (car buffers))) + ;; group buffers by mode + (when buffers-tab-selection-function + (delete-if-not #'(lambda (buf) + (funcall buffers-tab-selection-function + first-buf buf)) buffers)) (and (integerp buffers-tab-max-size) (> buffers-tab-max-size 1) (> (length buffers) buffers-tab-max-size) @@ -137,7 +166,7 @@ (make-extent 0 0 gutter-string) (setq gutter-buffers-tab (make-glyph - (vector 'tab-control :descriptor "Buffers" + (vector 'tab-control :descriptor "Buffers" :face 'default :properties (list :items (buffers-tab-items)))))) ;; This looks better than a 3d border (mapcar '(lambda (x) @@ -155,24 +184,24 @@ (frame-selected-window frame-or-buffer))))) (set-image-instance-property inst :items (buffers-tab-items - (and (framep frame-or-buffer) frame-or-buffer))) + nil + (and (framep frame-or-buffer) + frame-or-buffer))) (resize-subwindow inst (gutter-pixel-width) nil)) )) (defun remove-buffer-from-gutter-tab () "Remove the current buffer from the tab control in the gutter area." (when (valid-image-instantiator-format-p 'tab-control) - (let ((buffers (cdr (buffers-tab-items)))) + (let ((inst (glyph-image-instance gutter-buffers-tab)) + (buffers (buffers-tab-items t))) (unless buffers (get-buffer-create "*scratch*") - (setq buffers (buffers-tab-items)) + (setq buffers (buffers-tab-items t)) (unless (equal "*scratch*" (aref (car buffers) 0)) (setq buffers (cdr buffers)))) - (set-image-instance-property (glyph-image-instance gutter-buffers-tab) - :items - buffers) - (resize-subwindow (glyph-image-instance gutter-buffers-tab) - (gutter-pixel-width) nil) + (set-image-instance-property inst :items buffers) + (resize-subwindow inst (gutter-pixel-width) nil) ))) (add-tab-to-gutter)