# HG changeset patch # User wmperry # Date 1009139302 0 # Node ID 02339d4ebed407ad61d505bfbcdc3c869cb1f08a # Parent c2c346111c9a9966a579fb8e9e5fd6e1622f0024 [xemacs-hg @ 2001-12-23 20:28:19 by wmperry] 2001-12-22 William M. Perry * glyphs-gtk.c (gtk_xpm_instantiate): Don't bother doing the xpm-color-symbols checks, they are impossible to implement with GTK's XPM implementation. :( 2001-12-13 William M. Perry * select-gtk.c (gtk_own_selection): Update to follow the new method signature. Ignore owned_p as it appears to only be used for motif hacks. * redisplay-gtk.c (gtk_output_string): Fixed some warnings about signed/unsigned comparison. (gtk_output_gdk_pixmap): Remove clipping code as per change by andy@xemacs.org to the X11 code. (gtk_output_pixmap): Make this follow the output_pixmap method conventions and expose it. (gtk_output_horizontal_line): Renamed from output_hline, and expose it in our method structure. (gtk_ring_bell): Don't ring the bell if volume <= 0 * toolbar-gtk.c (gtk_output_toolbar_button): (gtk_output_frame_toolbars): (gtk_redraw_exposed_toolbars): (gtk_redraw_frame_toolbars): These are now just aliases for the common_XXX() routines in toolbar-common.c * toolbar-common.c: New common toolbar implementation. This file uses only the redisplay_XXX() functions and device methods to draw the toolbar, and so should be portable across all windowing systems (other than tty, and even then I imagine text-based stuff would work if you had a way to select it). diff -r c2c346111c9a -r 02339d4ebed4 src/ChangeLog --- a/src/ChangeLog Sun Dec 23 01:11:00 2001 +0000 +++ b/src/ChangeLog Sun Dec 23 20:28:22 2001 +0000 @@ -1,3 +1,37 @@ +2001-12-22 William M. Perry + + * glyphs-gtk.c (gtk_xpm_instantiate): Don't bother doing the + xpm-color-symbols checks, they are impossible to implement with + GTK's XPM implementation. :( + +2001-12-13 William M. Perry + + * select-gtk.c (gtk_own_selection): Update to follow the new + method signature. Ignore owned_p as it appears to only be used + for motif hacks. + + * redisplay-gtk.c (gtk_output_string): Fixed some warnings about + signed/unsigned comparison. + (gtk_output_gdk_pixmap): Remove clipping code as per change by + andy@xemacs.org to the X11 code. + (gtk_output_pixmap): Make this follow the output_pixmap method + conventions and expose it. + (gtk_output_horizontal_line): Renamed from output_hline, and + expose it in our method structure. + (gtk_ring_bell): Don't ring the bell if volume <= 0 + + * toolbar-gtk.c (gtk_output_toolbar_button): + (gtk_output_frame_toolbars): + (gtk_redraw_exposed_toolbars): + (gtk_redraw_frame_toolbars): These are now just aliases for the + common_XXX() routines in toolbar-common.c + + * toolbar-common.c: New common toolbar implementation. This file + uses only the redisplay_XXX() functions and device methods to draw + the toolbar, and so should be portable across all windowing + systems (other than tty, and even then I imagine text-based stuff + would work if you had a way to select it). + 2001-12-11 Andy Piper * dialog-msw.c (dialog_popped_down): new function. unset popup_up_p. diff -r c2c346111c9a -r 02339d4ebed4 src/console-gtk.h --- a/src/console-gtk.h Sun Dec 23 01:11:00 2001 +0000 +++ b/src/console-gtk.h Sun Dec 23 20:28:22 2001 +0000 @@ -222,14 +222,10 @@ int start_pixpos, int width, face_index findex, int cursor, int cursor_start, int cursor_width, int cursor_height); -void gtk_output_gdk_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, - GdkColor *fg, GdkColor *bg, - GdkGC *override_gc); void gtk_output_shadows (struct frame *f, int x, int y, int width, int height, int shadow_thickness); +GdkGC *gtk_get_gc (struct device *d, Lisp_Object font, Lisp_Object fg, Lisp_Object bg, + Lisp_Object bg_pmap, Lisp_Object lwidth); int gtk_initialize_frame_menubar (struct frame *f); void gtk_init_modifier_mapping (struct device *d); diff -r c2c346111c9a -r 02339d4ebed4 src/glyphs-gtk.c --- a/src/glyphs-gtk.c Sun Dec 23 01:11:00 2001 +0000 +++ b/src/glyphs-gtk.c Sun Dec 23 20:28:22 2001 +0000 @@ -1,4 +1,4 @@ -/* X-specific Lisp objects. +/* GTK-specific Lisp objects. Copyright (C) 1993, 1994 Free Software Foundation, Inc. Copyright (C) 1995 Board of Trustees, University of Illinois. Copyright (C) 1995 Tinker Systems @@ -1083,6 +1083,7 @@ /********************************************************************** * XPM * **********************************************************************/ + static void write_lisp_string_to_temp_file (Lisp_Object string, char *filename_out) { @@ -1182,77 +1183,9 @@ report_file_error ("Writing temp file", build_string (filename_out)); } -struct color_symbol -{ - char* name; - GdkColor color; -}; - -static struct color_symbol* -extract_xpm_color_names (Lisp_Object device, - Lisp_Object domain, - Lisp_Object color_symbol_alist, - int* nsymbols) -{ - /* This function can GC */ - Lisp_Object rest; - Lisp_Object results = Qnil; - int i, j; - struct color_symbol *colortbl; - struct gcpro gcpro1, gcpro2; - - GCPRO2 (results, device); - - /* We built up results to be (("name" . #) ...) so that if an - error happens we don't lose any malloc()ed data, or more importantly, - leave any pixels allocated in the server. */ - i = 0; - LIST_LOOP (rest, color_symbol_alist) - { - Lisp_Object cons = XCAR (rest); - Lisp_Object name = XCAR (cons); - Lisp_Object value = XCDR (cons); - if (NILP (value)) - continue; - if (STRINGP (value)) - value = - Fmake_color_instance - (value, device, encode_error_behavior_flag (ERROR_ME_NOT)); - else - { - assert (COLOR_SPECIFIERP (value)); - value = Fspecifier_instance (value, domain, Qnil, Qnil); - } - - if (NILP (value)) - continue; - results = noseeum_cons (noseeum_cons (name, value), results); - i++; - } - UNGCPRO; /* no more evaluation */ - - *nsymbols=i; - if (i == 0) return 0; - - colortbl = xnew_array_and_zero (struct color_symbol, i); - - for (j=0; jsubmenu; - gpointer id = gtk_object_get_data (GTK_OBJECT (widget), XEMACS_MENU_GUIID_TAG); + GtkWidget *widget = NULL; + GtkWidget *menu = NULL; + gpointer id = NULL; + /* Do basic error checking first... */ + if (SYMBOLP (menu_desc)) + menu_desc = Fsymbol_value (menu_desc); + CHECK_CONS (menu_desc); + CHECK_STRING (XCAR (menu_desc)); + + /* Now lets get down to business... */ + widget = menu_descriptor_to_widget (menu_desc); + menu = GTK_MENU_ITEM (widget)->submenu; gtk_widget_set_name (widget, "XEmacsPopupMenu"); + id = gtk_object_get_data (GTK_OBJECT (widget), XEMACS_MENU_GUIID_TAG); __activate_menu (GTK_MENU_ITEM (widget), id); diff -r c2c346111c9a -r 02339d4ebed4 src/redisplay-gtk.c --- a/src/redisplay-gtk.c Sun Dec 23 01:11:00 2001 +0000 +++ b/src/redisplay-gtk.c Sun Dec 23 20:28:22 2001 +0000 @@ -1,4 +1,4 @@ -/* X output and frame manipulation routines. +/* GTK output and frame manipulation routines. Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. Copyright (C) 1994 Lucid, Inc. Copyright (C) 1995 Sun Microsystems, Inc. @@ -55,18 +55,22 @@ #define EOL_CURSOR_WIDTH 5 -static void gtk_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 gtk_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 bgpixmap); static void gtk_output_vertical_divider (struct window *w, int clear); static void gtk_output_blank (struct window *w, struct display_line *dl, struct rune *rb, int start_pixpos, int cursor_start, int cursor_width); -static void gtk_output_hline (struct window *w, struct display_line *dl, - struct rune *rb); +static void gtk_output_horizontal_line (struct window *w, + struct display_line *dl, + struct rune *rb); static void gtk_redraw_exposed_window (struct window *w, int x, int y, int width, int height); static void gtk_redraw_exposed_windows (Lisp_Object window, int x, int y, @@ -399,7 +403,7 @@ We borrow the shadow_thickness_changed flag for now. */ w->shadow_thickness_changed = 1; - gtk_output_hline (w, dl, rb); + gtk_output_horizontal_line (w, dl, rb); } elt++; @@ -449,10 +453,9 @@ case IMAGE_MONO_PIXMAP: case IMAGE_COLOR_PIXMAP: - gtk_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, &dbox, &dga, + findex,cursor_start, + cursor_width, cursor_height, 0); break; case IMAGE_POINTER: @@ -643,14 +646,14 @@ Starting Y position of cursor is the top of the text line. The cursor is drawn sometimes whether or not CURSOR is set. ??? ****************************************************************************/ -void -gdk_draw_text_image (GdkDrawable *drawable, - GdkFont *font, - GdkGC *gc, - gint x, - gint y, - const gchar *text, - gint text_length); +static +void gdk_draw_text_image (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const gchar *text, + gint text_length); void gtk_output_string (struct window *w, struct display_line *dl, @@ -1045,10 +1048,10 @@ gint width, gint height); -void +static void gtk_output_gdk_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, + int y, int xoffset, int yoffset, + int width, int height, GdkColor *fg, GdkColor *bg, GdkGC *override_gc) { struct device *d = XDEVICE (f->device); @@ -1057,7 +1060,6 @@ GdkGC *gc; GdkGCValues gcv; unsigned long pixmap_mask; - int need_clipping = (clip_x || clip_y); if (!override_gc) { @@ -1071,8 +1073,8 @@ { gcv.function = GDK_COPY; gcv.clip_mask = IMAGE_INSTANCE_GTK_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 |= (GDK_GC_FUNCTION | GDK_GC_CLIP_MASK | GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN); /* Can't set a clip rectangle below because we already have a mask. @@ -1080,8 +1082,9 @@ everything outside the clip region. Is it worth it? 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_GTK_GC_CACHE (d), &gcv, pixmap_mask); @@ -1092,47 +1095,32 @@ /* 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) - { - GdkRectangle clip_box; - - clip_box.x = clip_x; - clip_box.y = clip_y; - clip_box.width = clip_width; - clip_box.height = clip_height; - - gdk_gc_set_clip_rectangle (gc, &clip_box); - gdk_gc_set_clip_origin (gc, x, y); } if (IMAGE_INSTANCE_PIXMAP_DEPTH (p) > 0) { gdk_draw_pixmap (GDK_DRAWABLE (x_win), gc, IMAGE_INSTANCE_GTK_PIXMAP (p), - 0, pixmap_offset, x, y, width, height); + xoffset, yoffset, x, y, width, height); } else { our_draw_bitmap (GDK_DRAWABLE (x_win), gc, IMAGE_INSTANCE_GTK_PIXMAP (p), - 0, pixmap_offset, x, y, width, height); + xoffset, yoffset, x, y, width, height); } - - if (need_clipping) - { - gdk_gc_set_clip_rectangle (gc, NULL); - gdk_gc_set_clip_origin (gc, 0, 0); - } } static void -gtk_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) +gtk_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); @@ -1140,89 +1128,9 @@ Lisp_Object window; GdkWindow *x_win = GET_GTK_WIDGET_WINDOW (FRAME_GTK_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_GTK_MASK (p)) - { - int clear_x, clear_y, clear_width, clear_height; - - if (IMAGE_INSTANCE_GTK_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; @@ -1233,20 +1141,19 @@ tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); tmp_bcolor = COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (tmp_pixel)); - gtk_output_gdk_pixmap (f, p, xpos - xoffset, dl->ypos - dl->ascent, clip_x, - clip_y, clip_width, clip_height, - pwidth, pheight, pixmap_offset, - tmp_fcolor, tmp_bcolor, 0); + gtk_output_gdk_pixmap (f, p, db->xpos, db->ypos, + dga->xoffset, dga->yoffset, + dga->width, dga->height, + tmp_fcolor, tmp_bcolor, NULL); } /* 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))) { GdkGC *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 @@ -1254,11 +1161,11 @@ gc = gtk_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; gdk_draw_rectangle (GDK_DRAWABLE (x_win), gc, focus ? TRUE : FALSE, - cursor_start, y, cursor_width, + cursor_start, db->ypos, cursor_width, cursor_height); } } @@ -1426,12 +1333,14 @@ } /***************************************************************************** - gtk_output_hline + gtk_output_horizontal_line Output a horizontal line in the foreground of its face. ****************************************************************************/ static void -gtk_output_hline (struct window *w, struct display_line *dl, struct rune *rb) +gtk_output_horizontal_line (struct window *w, + struct display_line *dl, + struct rune *rb) { struct frame *f = XFRAME (w->frame); struct device *d = XDEVICE (f->device); @@ -1919,8 +1828,11 @@ static void gtk_ring_bell (struct device *d, int volume, int pitch, int duration) { - /* Gdk does not allow us to control the duration / pitch / volume */ - gdk_beep (); + /* Gdk does not allow us to control the duration / pitch / volume */ + if (volume > 0) + { + gdk_beep (); + } } @@ -1944,7 +1856,7 @@ CONSOLE_HAS_METHOD (gtk, ring_bell); CONSOLE_HAS_METHOD (gtk, bevel_area); CONSOLE_HAS_METHOD (gtk, output_string); - /* CONSOLE_HAS_METHOD (gtk, output_pixmap); */ + CONSOLE_HAS_METHOD (gtk, output_pixmap); } /* This makes me feel incredibly dirty... but there is no other way to @@ -1954,14 +1866,14 @@ #include -void -gdk_draw_text_image (GdkDrawable *drawable, - GdkFont *font, - GdkGC *gc, - gint x, - gint y, - const gchar *text, - gint text_length) +static +void gdk_draw_text_image (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const gchar *text, + gint text_length) { #if !USE_X_SPECIFIC_DRAW_ROUTINES int width = gdk_text_measure (font, text, text_length); diff -r c2c346111c9a -r 02339d4ebed4 src/toolbar-common.c --- a/src/toolbar-common.c Sun Dec 23 01:11:00 2001 +0000 +++ b/src/toolbar-common.c Sun Dec 23 20:28:22 2001 +0000 @@ -703,4 +703,3 @@ common_redraw_exposed_toolbars (f, 0, 0, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f)); } - diff -r c2c346111c9a -r 02339d4ebed4 src/toolbar-gtk.c --- a/src/toolbar-gtk.c Sun Dec 23 01:11:00 2001 +0000 +++ b/src/toolbar-gtk.c Sun Dec 23 20:28:22 2001 +0000 @@ -1,4 +1,4 @@ -/* toolbar implementation -- X interface. +/* toolbar implementation -- GTK interface. Copyright (C) 1995 Board of Trustees, University of Illinois. Copyright (C) 1995 Sun Microsystems, Inc. Copyright (C) 1995, 1996 Ben Wing. @@ -25,621 +25,18 @@ #include #include "lisp.h" - +#include "frame.h" +#include "toolbar-common.h" #include "console-gtk.h" -#include "glyphs-gtk.h" -#include "objects-gtk.h" -#include "gtk-xemacs.h" -#include "gccache-gtk.h" - -#include "faces.h" -#include "frame.h" -#include "toolbar.h" -#include "window.h" - -extern GdkGC *gtk_get_gc (struct device *d, Lisp_Object font, Lisp_Object fg, Lisp_Object bg, - Lisp_Object bg_pmap, Lisp_Object lwidth); - -static GdkGC *get_toolbar_gc (struct frame *f) -{ - Lisp_Object fg, bg; - Lisp_Object frame; - - XSETFRAME (frame, f); - - fg = Fspecifier_instance (Fget (Vtoolbar_face, Qforeground, Qnil), frame, Qnil, Qnil); - bg = Fspecifier_instance (Fget (Vtoolbar_face, Qbackground, Qnil), frame, Qnil, Qnil); - - /* Need to swap the foreground/background here or most themes look bug ugly */ - return (gtk_get_gc (XDEVICE (FRAME_DEVICE (f)), Qnil, bg, fg, Qnil, Qnil)); -} - -static void -gtk_draw_blank_toolbar_button (struct frame *f, int x, int y, int width, - int height, int threed, int border_width, - int vertical) -{ - GtkXEmacs *ef = GTK_XEMACS (FRAME_GTK_TEXT_WIDGET (f)); - int sx = x, sy = y, swidth = width, sheight = height; - GdkWindow *x_win = GTK_WIDGET (ef)->window; - GdkGC *background_gc = get_toolbar_gc (f); - - if (vertical) - { - sx += border_width; - swidth -= 2 * border_width; - } - else - { - sy += border_width; - sheight -= 2 * border_width; - } - - /* Blank the entire area. */ - gdk_draw_rectangle (x_win, background_gc, TRUE, sx, sy, swidth, sheight); - - /* Draw the outline. */ - if (threed) - gtk_output_shadows (f, sx, sy, swidth, sheight, 2); - - /* Do the border */ - gdk_draw_rectangle (x_win, background_gc, TRUE, x, y, - (vertical ? border_width : width), - (vertical ? height : border_width)); - gdk_draw_rectangle (x_win, background_gc, TRUE, - (vertical ? sx + swidth : x), - (vertical ? y : sy + sheight), - (vertical ? border_width : width), - (vertical ? height : border_width)); -} - -static void -gtk_output_toolbar_button (struct frame *f, Lisp_Object button) -{ - int shadow_thickness = 2; - int x_adj, y_adj, width_adj, height_adj; - GdkWindow *x_win = FRAME_GTK_TEXT_WIDGET (f)->window; - GdkGC *background_gc = get_toolbar_gc (f); - Lisp_Object instance, frame, window, glyph; - struct toolbar_button *tb = XTOOLBAR_BUTTON (button); - struct Lisp_Image_Instance *p; - struct window *w; - int vertical = tb->vertical; - int border_width = tb->border_width; - - if (vertical) - { - x_adj = border_width; - width_adj = - 2 * border_width; - y_adj = 0; - height_adj = 0; - } - else - { - x_adj = 0; - width_adj = 0; - y_adj = border_width; - height_adj = - 2 * border_width; - } - - XSETFRAME (frame, f); - window = FRAME_LAST_NONMINIBUF_WINDOW (f); - w = XWINDOW (window); - - glyph = get_toolbar_button_glyph (w, tb); - - if (tb->enabled) - { - if (tb->down) - { - shadow_thickness = -2; - } - else - { - shadow_thickness = 2; - } - } - else - { - shadow_thickness = 0; - } - - background_gc = get_toolbar_gc (f); - - /* Clear the entire area. */ - gdk_draw_rectangle (x_win, background_gc, TRUE, - tb->x + x_adj, - tb->y + y_adj, - tb->width + width_adj, - tb->height + height_adj); - - /* Draw the outline. */ - if (shadow_thickness) - gtk_output_shadows (f, tb->x + x_adj, tb->y + y_adj, - tb->width + width_adj, tb->height + height_adj, - shadow_thickness); - - /* Do the border. */ - gdk_draw_rectangle (x_win, background_gc, TRUE, tb->x, tb->y, - (vertical ? border_width : tb->width), - (vertical ? tb->height : border_width)); - - gdk_draw_rectangle (x_win, background_gc, TRUE, - (vertical ? tb->x + tb->width - border_width : tb->x), - (vertical ? tb->y : tb->y + tb->height - border_width), - (vertical ? border_width : tb->width), - (vertical ? tb->height : border_width)); - - background_gc = get_toolbar_gc (f); - - /* #### It is currently possible for users to trash us by directly - changing the toolbar glyphs. Avoid crashing in that case. */ - if (GLYPHP (glyph)) - instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1); - else - instance = Qnil; - - if (IMAGE_INSTANCEP (instance)) - { - int width = tb->width + width_adj - shadow_thickness * 2; - int height = tb->height + height_adj - shadow_thickness * 2; - int x_offset = x_adj + shadow_thickness; - int y_offset = y_adj + shadow_thickness; - - p = XIMAGE_INSTANCE (instance); - - if (IMAGE_INSTANCE_PIXMAP_TYPE_P (p)) - { - if (width > (int) IMAGE_INSTANCE_PIXMAP_WIDTH (p)) - { - x_offset += ((int) (width - IMAGE_INSTANCE_PIXMAP_WIDTH (p)) - / 2); - width = IMAGE_INSTANCE_PIXMAP_WIDTH (p); - } - if (height > (int) IMAGE_INSTANCE_PIXMAP_HEIGHT (p)) - { - y_offset += ((int) (height - IMAGE_INSTANCE_PIXMAP_HEIGHT (p)) - / 2); - height = IMAGE_INSTANCE_PIXMAP_HEIGHT (p); - } - - gtk_output_gdk_pixmap (f, XIMAGE_INSTANCE (instance), tb->x + x_offset, - tb->y + y_offset, 0, 0, 0, 0, width, height, - 0, 0, 0, background_gc); - } - else if (IMAGE_INSTANCE_TYPE (p) == IMAGE_TEXT) - { - /* #### We need to make the face used configurable. */ - struct face_cachel *cachel = - WINDOW_FACE_CACHEL (w, DEFAULT_INDEX); - struct display_line dl; - Lisp_Object string = IMAGE_INSTANCE_TEXT_STRING (p); - unsigned char charsets[NUM_LEADING_BYTES]; - Emchar_dynarr *buf; - struct font_metric_info fm; - - /* This could be true if we were called via the Expose event - handler. Mark the button as dirty and return - immediately. */ - if (f->window_face_cache_reset) - { - tb->dirty = 1; - MARK_TOOLBAR_CHANGED; - return; - } - buf = Dynarr_new (Emchar); - convert_intbyte_string_into_emchar_dynarr - (XSTRING_DATA (string), XSTRING_LENGTH (string), buf); - find_charsets_in_emchar_string (charsets, Dynarr_atp (buf, 0), - Dynarr_length (buf)); - ensure_face_cachel_complete (cachel, window, charsets); - face_cachel_charset_font_metric_info (cachel, charsets, &fm); - - dl.ascent = fm.ascent; - dl.descent = fm.descent; - dl.ypos = tb->y + y_offset + fm.ascent; - - if (fm.ascent + fm.descent <= height) - { - dl.ypos += (height - fm.ascent - fm.descent) / 2; - dl.clip = 0; - } - else - { - dl.clip = fm.ascent + fm.descent - height; - } - - gtk_output_string (w, &dl, buf, tb->x + x_offset, 0, 0, width, - DEFAULT_INDEX, 0, 0, 0, 0); - Dynarr_free (buf); - } - - /* We silently ignore the image if it isn't a pixmap or text. */ - } - - tb->dirty = 0; -} - -static int -gtk_get_button_size (struct frame *f, Lisp_Object window, - struct toolbar_button *tb, int vert, int pos) -{ - int shadow_thickness = 2; - int size; - - if (tb->blank) - { - if (!NILP (tb->down_glyph)) - size = XINT (tb->down_glyph); - else - size = DEFAULT_TOOLBAR_BLANK_SIZE; - } - else - { - struct window *w = XWINDOW (window); - Lisp_Object glyph = get_toolbar_button_glyph (w, tb); - - /* Unless, of course, the user has done something stupid like - change the glyph out from under us. Use a blank placeholder - in that case. */ - if (NILP (glyph)) - return XINT (f->toolbar_size[pos]); - - if (vert) - size = glyph_height (glyph, window); - else - size = glyph_width (glyph, window); - } - - if (!size) - { - /* If the glyph doesn't have a size we'll insert a blank - placeholder instead. */ - return XINT (f->toolbar_size[pos]); - } - - size += shadow_thickness * 2; - - return (size); -} -#define GTK_OUTPUT_BUTTONS_LOOP(left) \ - do { \ - while (!NILP (button)) \ - { \ - struct toolbar_button *tb = XTOOLBAR_BUTTON (button); \ - int size, height, width; \ - \ - if (left && tb->pushright) \ - break; \ - \ - size = gtk_get_button_size (f, window, tb, vert, pos); \ - \ - if (vert) \ - { \ - width = bar_width; \ - if (y + size > max_pixpos) \ - height = max_pixpos - y; \ - else \ - height = size; \ - } \ - else \ - { \ - if (x + size > max_pixpos) \ - width = max_pixpos - x; \ - else \ - width = size; \ - height = bar_height; \ - } \ - \ - if (tb->x != x \ - || tb->y != y \ - || tb->width != width \ - || tb->height != height \ - || tb->dirty) \ - { \ - if (width && height) \ - { \ - tb->x = x; \ - tb->y = y; \ - tb->width = width; \ - tb->height = height; \ - tb->border_width = border_width; \ - tb->vertical = vert; \ - \ - if (tb->blank || NILP (tb->up_glyph)) \ - { \ - int threed = (EQ (Qt, tb->up_glyph) ? 1 : 0); \ - gtk_draw_blank_toolbar_button (f, x, y, width, \ - height, threed, \ - border_width, vert); \ - } \ - else \ - gtk_output_toolbar_button (f, button); \ - } \ - } \ - \ - if (vert) \ - y += height; \ - else \ - x += width; \ - \ - if ((vert && y == max_pixpos) || (!vert && x == max_pixpos)) \ - button = Qnil; \ - else \ - button = tb->next; \ - } \ - } while (0) - -#define SET_TOOLBAR_WAS_VISIBLE_FLAG(frame, pos, flag) \ - do { \ - switch (pos) \ - { \ - case TOP_TOOLBAR: \ - (frame)->top_toolbar_was_visible = flag; \ - break; \ - case BOTTOM_TOOLBAR: \ - (frame)->bottom_toolbar_was_visible = flag; \ - break; \ - case LEFT_TOOLBAR: \ - (frame)->left_toolbar_was_visible = flag; \ - break; \ - case RIGHT_TOOLBAR: \ - (frame)->right_toolbar_was_visible = flag; \ - break; \ - default: \ - abort (); \ - } \ - } while (0) - -static void -gtk_output_toolbar (struct frame *f, enum toolbar_pos pos) -{ - int x, y, bar_width, bar_height, vert; - int max_pixpos, right_size, right_start, blank_size; - int border_width = FRAME_REAL_TOOLBAR_BORDER_WIDTH (f, pos); - Lisp_Object button, window; - GdkWindow *x_win = FRAME_GTK_TEXT_WIDGET (f)->window; - GdkGC *background_gc = get_toolbar_gc (f); - - get_toolbar_coords (f, pos, &x, &y, &bar_width, &bar_height, &vert, 1); - window = FRAME_LAST_NONMINIBUF_WINDOW (f); - - /* Do the border */ - gdk_draw_rectangle (x_win, background_gc, TRUE, x, y, - (vert ? bar_width : border_width), - (vert ? border_width : bar_height)); - gdk_draw_rectangle (x_win, background_gc, TRUE, - (vert ? x : x + bar_width - border_width), - (vert ? y + bar_height - border_width : y), - (vert ? bar_width : border_width), - (vert ? border_width : bar_height)); - - if (vert) - { - max_pixpos = y + bar_height - border_width; - y += border_width; - } - else - { - max_pixpos = x + bar_width - border_width; - x += border_width; - } - - button = FRAME_TOOLBAR_BUTTONS (f, pos); - right_size = 0; - - /* First loop over all of the buttons to determine how much room we - need for left hand and right hand buttons. This loop will also - make sure that all instances are instantiated so when we actually - output them they will come up immediately. */ - while (!NILP (button)) - { - struct toolbar_button *tb = XTOOLBAR_BUTTON (button); - int size = gtk_get_button_size (f, window, tb, vert, pos); - - if (tb->pushright) - right_size += size; - - button = tb->next; - } - - button = FRAME_TOOLBAR_BUTTONS (f, pos); - - /* Loop over the left buttons, updating and outputting them. */ - GTK_OUTPUT_BUTTONS_LOOP (1); - - /* Now determine where the right buttons start. */ - right_start = max_pixpos - right_size; - if (right_start < (vert ? y : x)) - right_start = (vert ? y : x); - - /* Output the blank which goes from the end of the left buttons to - the start of the right. */ - blank_size = right_start - (vert ? y : x); - if (blank_size) - { - int height, width; - - if (vert) - { - width = bar_width; - height = blank_size; - } - else - { - width = blank_size; - height = bar_height; - } - - /* - * Use a 3D pushright separator only if there isn't a toolbar - * border. A flat separator meshes with the border and looks - * better. - */ - gtk_draw_blank_toolbar_button (f, x, y, width, height, !border_width, - border_width, vert); - - if (vert) - y += height; - else - x += width; - } - - /* Loop over the right buttons, updating and outputting them. */ - GTK_OUTPUT_BUTTONS_LOOP (0); - - if (!vert) - { - Lisp_Object frame; - - XSETFRAME (frame, f); - redisplay_clear_region (frame, - DEFAULT_INDEX, FRAME_PIXWIDTH (f) - 1, y, 1, - bar_height); - } - - SET_TOOLBAR_WAS_VISIBLE_FLAG (f, pos, 1); - - gdk_flush (); -} - -static void -gtk_clear_toolbar (struct frame *f, enum toolbar_pos pos, int thickness_change) -{ - Lisp_Object frame; - int x, y, width, height, vert; - - get_toolbar_coords (f, pos, &x, &y, &width, &height, &vert, 1); - XSETFRAME (frame, f); - - /* The thickness_change parameter is used by the toolbar resize routines - to clear any excess toolbar if the size shrinks. */ - if (thickness_change < 0) - { - if (pos == LEFT_TOOLBAR || pos == RIGHT_TOOLBAR) - { - x = x + width + thickness_change; - width = -thickness_change; - } - else - { - y = y + height + thickness_change; - height = -thickness_change; - } - } - - SET_TOOLBAR_WAS_VISIBLE_FLAG (f, pos, 0); - - redisplay_clear_region (frame, DEFAULT_INDEX, x, y, width, height); - gdk_flush (); -} - -static void -gtk_output_frame_toolbars (struct frame *f) -{ - assert (FRAME_GTK_P (f)); - - if (FRAME_REAL_TOP_TOOLBAR_VISIBLE (f)) - gtk_output_toolbar (f, TOP_TOOLBAR); - else if (f->top_toolbar_was_visible) - gtk_clear_toolbar (f, TOP_TOOLBAR, 0); - - if (FRAME_REAL_BOTTOM_TOOLBAR_VISIBLE (f)) - gtk_output_toolbar (f, BOTTOM_TOOLBAR); - else if (f->bottom_toolbar_was_visible) - gtk_clear_toolbar (f, BOTTOM_TOOLBAR, 0); - - if (FRAME_REAL_LEFT_TOOLBAR_VISIBLE (f)) - gtk_output_toolbar (f, LEFT_TOOLBAR); - else if (f->left_toolbar_was_visible) - gtk_clear_toolbar (f, LEFT_TOOLBAR, 0); - - if (FRAME_REAL_RIGHT_TOOLBAR_VISIBLE (f)) - gtk_output_toolbar (f, RIGHT_TOOLBAR); - else if (f->right_toolbar_was_visible) - gtk_clear_toolbar (f, RIGHT_TOOLBAR, 0); -} - -static void -gtk_redraw_exposed_toolbar (struct frame *f, enum toolbar_pos pos, int x, int y, - int width, int height) -{ - int bar_x, bar_y, bar_width, bar_height, vert; - Lisp_Object button = FRAME_TOOLBAR_BUTTONS (f, pos); - - get_toolbar_coords (f, pos, &bar_x, &bar_y, &bar_width, &bar_height, - &vert, 1); - - if (((y + height) < bar_y) || (y > (bar_y + bar_height))) - return; - if (((x + width) < bar_x) || (x > (bar_x + bar_width))) - return; - - while (!NILP (button)) - { - struct toolbar_button *tb = XTOOLBAR_BUTTON (button); - - if (vert) - { - if (((tb->y + tb->height) > y) && (tb->y < (y + height))) - tb->dirty = 1; - - /* If this is true we have gone past the exposed region. */ - if (tb->y > (y + height)) - break; - } - else - { - if (((tb->x + tb->width) > x) && (tb->x < (x + width))) - tb->dirty = 1; - - /* If this is true we have gone past the exposed region. */ - if (tb->x > (x + width)) - break; - } - - button = tb->next; - } - - /* Even if none of the buttons is in the area, the blank region at - the very least must be because the first thing we did is verify - that some portion of the toolbar is in the exposed region. */ - gtk_output_toolbar (f, pos); -} - -static void -gtk_redraw_exposed_toolbars (struct frame *f, int x, int y, int width, - int height) -{ - assert (FRAME_GTK_P (f)); - - if (FRAME_REAL_TOP_TOOLBAR_VISIBLE (f)) - gtk_redraw_exposed_toolbar (f, TOP_TOOLBAR, x, y, width, height); - - if (FRAME_REAL_BOTTOM_TOOLBAR_VISIBLE (f)) - gtk_redraw_exposed_toolbar (f, BOTTOM_TOOLBAR, x, y, width, height); - - if (FRAME_REAL_LEFT_TOOLBAR_VISIBLE (f)) - gtk_redraw_exposed_toolbar (f, LEFT_TOOLBAR, x, y, width, height); - - if (FRAME_REAL_RIGHT_TOOLBAR_VISIBLE (f)) - gtk_redraw_exposed_toolbar (f, RIGHT_TOOLBAR, x, y, width, height); -} - -static void -gtk_redraw_frame_toolbars (struct frame *f) -{ - /* There are certain startup paths that lead to update_EmacsFrame in - faces.c being called before a new frame is fully initialized. In - particular before we have actually mapped it. That routine can - call this one. So, we need to make sure that the frame is - actually ready before we try and draw all over it. */ - - if (GTK_WIDGET_REALIZED (FRAME_GTK_TEXT_WIDGET (f))) - gtk_redraw_exposed_toolbars (f, 0, 0, FRAME_PIXWIDTH (f), - FRAME_PIXHEIGHT (f)); -} +/* We should really create a 'common' console type and fill it with +** all the shared code. We would then just use +** CONSOLE_INHERITS_METHOD(x,common,blah) +*/ +#define gtk_output_frame_toolbars common_output_frame_toolbars +#define gtk_output_toolbar_button common_output_toolbar_button +#define gtk_redraw_exposed_toolbars common_redraw_exposed_toolbars +#define gtk_redraw_frame_toolbars common_redraw_frame_toolbars static void