comparison src/toolbar-x.c @ 215:1f0dabaa0855 r20-4b6

Import from CVS: tag r20-4b6
author cvs
date Mon, 13 Aug 2007 10:07:35 +0200
parents 3d6bfa290dbd
children 0e522484dd2a
comparison
equal deleted inserted replaced
214:c5d88c05e1e9 215:1f0dabaa0855
39 #include "toolbar.h" 39 #include "toolbar.h"
40 #include "window.h" 40 #include "window.h"
41 41
42 static void 42 static void
43 x_draw_blank_toolbar_button (struct frame *f, int x, int y, int width, 43 x_draw_blank_toolbar_button (struct frame *f, int x, int y, int width,
44 int height, int threed) 44 int height, int threed, int border_width,
45 int vertical)
45 { 46 {
46 struct device *d = XDEVICE (f->device); 47 struct device *d = XDEVICE (f->device);
47 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f); 48 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f);
48 int shadow_thickness = ef->emacs_frame.toolbar_shadow_thickness; 49 int shadow_thickness = ef->emacs_frame.toolbar_shadow_thickness;
50 int sx = x, sy = y, swidth = width, sheight = height;
49 51
50 Display *dpy = DEVICE_X_DISPLAY (d); 52 Display *dpy = DEVICE_X_DISPLAY (d);
51 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); 53 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
52 GC top_shadow_gc, bottom_shadow_gc, background_gc; 54 GC top_shadow_gc, bottom_shadow_gc, background_gc;
53 55
62 { 64 {
63 top_shadow_gc = background_gc; 65 top_shadow_gc = background_gc;
64 bottom_shadow_gc = background_gc; 66 bottom_shadow_gc = background_gc;
65 } 67 }
66 68
69 if (vertical)
70 {
71 sx += border_width;
72 swidth -= 2 * border_width;
73 }
74 else
75 {
76 sy += border_width;
77 sheight -= 2 * border_width;
78 }
79
67 /* Draw the outline. */ 80 /* Draw the outline. */
68 x_output_shadows (f, x, y, width, height, top_shadow_gc, 81 x_output_shadows (f, sx, sy, swidth, sheight, top_shadow_gc,
69 bottom_shadow_gc, background_gc, shadow_thickness); 82 bottom_shadow_gc, background_gc, shadow_thickness);
70 83
71 /* Blank the middle. */ 84 /* Blank the middle. */
72 XFillRectangle (dpy, x_win, background_gc, x + shadow_thickness, 85 XFillRectangle (dpy, x_win, background_gc, sx + shadow_thickness,
73 y + shadow_thickness, width - shadow_thickness * 2, 86 sy + shadow_thickness, swidth - shadow_thickness * 2,
74 height - shadow_thickness * 2); 87 sheight - shadow_thickness * 2);
88
89 /* Do the border */
90 XFillRectangle (dpy, x_win, background_gc, x, y,
91 (vertical ? border_width : width),
92 (vertical ? height : border_width));
93 XFillRectangle (dpy, x_win, background_gc,
94 (vertical ? sx + swidth : x),
95 (vertical ? y : sy + sheight),
96 (vertical ? border_width : width),
97 (vertical ? height : border_width));
75 } 98 }
76 99
77 static void 100 static void
78 x_output_toolbar_button (struct frame *f, Lisp_Object button) 101 x_output_toolbar_button (struct frame *f, Lisp_Object button)
79 { 102 {
80 struct device *d = XDEVICE (f->device); 103 struct device *d = XDEVICE (f->device);
81 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f); 104 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f);
82 int shadow_thickness = ef->emacs_frame.toolbar_shadow_thickness; 105 int shadow_thickness = ef->emacs_frame.toolbar_shadow_thickness;
106 int x_adj, y_adj, width_adj, height_adj;
83 107
84 Display *dpy = DEVICE_X_DISPLAY (d); 108 Display *dpy = DEVICE_X_DISPLAY (d);
85 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); 109 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
86 GC top_shadow_gc, bottom_shadow_gc, background_gc; 110 GC top_shadow_gc, bottom_shadow_gc, background_gc;
87 Lisp_Object instance, frame, window, glyph; 111 Lisp_Object instance, frame, window, glyph;
88 struct toolbar_button *tb = XTOOLBAR_BUTTON (button); 112 struct toolbar_button *tb = XTOOLBAR_BUTTON (button);
89 struct Lisp_Image_Instance *p; 113 struct Lisp_Image_Instance *p;
90 struct window *w; 114 struct window *w;
115 int vertical = tb->vertical;
116 int border_width = tb->border_width;
117
118 if (vertical)
119 {
120 x_adj = border_width;
121 width_adj = - 2 * border_width;
122 y_adj = 0;
123 height_adj = 0;
124 }
125 else
126 {
127 x_adj = 0;
128 width_adj = 0;
129 y_adj = border_width;
130 height_adj = - 2 * border_width;
131 }
91 132
92 XSETFRAME (frame, f); 133 XSETFRAME (frame, f);
93 window = FRAME_LAST_NONMINIBUF_WINDOW (f); 134 window = FRAME_LAST_NONMINIBUF_WINDOW (f);
94 w = XWINDOW (window); 135 w = XWINDOW (window);
95 136
114 bottom_shadow_gc = FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f); 155 bottom_shadow_gc = FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f);
115 } 156 }
116 background_gc = FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f); 157 background_gc = FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f);
117 158
118 /* Draw the outline. */ 159 /* Draw the outline. */
119 x_output_shadows (f, tb->x, tb->y, tb->width, tb->height, top_shadow_gc, 160 x_output_shadows (f, tb->x + x_adj, tb->y + y_adj,
161 tb->width + width_adj, tb->height + height_adj,
162 top_shadow_gc,
120 bottom_shadow_gc, background_gc, shadow_thickness); 163 bottom_shadow_gc, background_gc, shadow_thickness);
121 164
122 /* Clear the pixmap area. */ 165 /* Clear the pixmap area. */
123 XFillRectangle (dpy, x_win, background_gc, tb->x + shadow_thickness, 166 XFillRectangle (dpy, x_win, background_gc, tb->x + x_adj + shadow_thickness,
124 tb->y + shadow_thickness, tb->width - shadow_thickness * 2, 167 tb->y + y_adj + shadow_thickness,
125 tb->height - shadow_thickness * 2); 168 tb->width + width_adj - shadow_thickness * 2,
169 tb->height + height_adj - shadow_thickness * 2);
170
171 /* Do the border. */
172 XFillRectangle (dpy, x_win, background_gc, tb->x, tb->y,
173 (vertical ? border_width : tb->width),
174 (vertical ? tb->height : border_width));
175
176 XFillRectangle (dpy, x_win, background_gc,
177 (vertical ? tb->x + tb->width - border_width : tb->x),
178 (vertical ? tb->y : tb->y + tb->height - border_width),
179 (vertical ? border_width : tb->width),
180 (vertical ? tb->height : border_width));
126 181
127 background_gc = FRAME_X_TOOLBAR_PIXMAP_BACKGROUND_GC (f); 182 background_gc = FRAME_X_TOOLBAR_PIXMAP_BACKGROUND_GC (f);
128 183
129 /* #### It is currently possible for users to trash us by directly 184 /* #### It is currently possible for users to trash us by directly
130 changing the toolbar glyphs. Avoid crashing in that case. */ 185 changing the toolbar glyphs. Avoid crashing in that case. */
133 else 188 else
134 instance = Qnil; 189 instance = Qnil;
135 190
136 if (IMAGE_INSTANCEP (instance)) 191 if (IMAGE_INSTANCEP (instance))
137 { 192 {
138 int width = tb->width - shadow_thickness * 2; 193 int width = tb->width + width_adj - shadow_thickness * 2;
139 int height = tb->height - shadow_thickness * 2; 194 int height = tb->height + height_adj - shadow_thickness * 2;
140 int x_offset = shadow_thickness; 195 int x_offset = x_adj + shadow_thickness;
141 int y_offset = shadow_thickness; 196 int y_offset = y_adj + shadow_thickness;
142 197
143 p = XIMAGE_INSTANCE (instance); 198 p = XIMAGE_INSTANCE (instance);
144 199
145 if (IMAGE_INSTANCE_PIXMAP_TYPE_P (p)) 200 if (IMAGE_INSTANCE_PIXMAP_TYPE_P (p))
146 { 201 {
297 { \ 352 { \
298 tb->x = x; \ 353 tb->x = x; \
299 tb->y = y; \ 354 tb->y = y; \
300 tb->width = width; \ 355 tb->width = width; \
301 tb->height = height; \ 356 tb->height = height; \
357 tb->border_width = border_width; \
358 tb->vertical = vert; \
302 \ 359 \
303 if (tb->blank || NILP (tb->up_glyph)) \ 360 if (tb->blank || NILP (tb->up_glyph)) \
304 { \ 361 { \
305 int threed = (EQ (Qt, tb->up_glyph) ? 1 : 0); \ 362 int threed = (EQ (Qt, tb->up_glyph) ? 1 : 0); \
306 x_draw_blank_toolbar_button (f, x, y, width, \ 363 x_draw_blank_toolbar_button (f, x, y, width, \
307 height, threed); \ 364 height, threed, \
365 border_width, vert); \
308 } \ 366 } \
309 else \ 367 else \
310 x_output_toolbar_button (f, button); \ 368 x_output_toolbar_button (f, button); \
311 } \ 369 } \
312 } \ 370 } \
348 x_output_toolbar (struct frame *f, enum toolbar_pos pos) 406 x_output_toolbar (struct frame *f, enum toolbar_pos pos)
349 { 407 {
350 struct device *d = XDEVICE (f->device); 408 struct device *d = XDEVICE (f->device);
351 int x, y, bar_width, bar_height, vert; 409 int x, y, bar_width, bar_height, vert;
352 int max_pixpos, right_size, right_start, blank_size; 410 int max_pixpos, right_size, right_start, blank_size;
411 int border_width = FRAME_REAL_TOOLBAR_BORDER_WIDTH (f, pos);
353 Lisp_Object button, window; 412 Lisp_Object button, window;
413 Display *dpy = DEVICE_X_DISPLAY (d);
414 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
415 GC background_gc = FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f);
354 416
355 get_toolbar_coords (f, pos, &x, &y, &bar_width, &bar_height, &vert, 1); 417 get_toolbar_coords (f, pos, &x, &y, &bar_width, &bar_height, &vert, 1);
356 window = FRAME_LAST_NONMINIBUF_WINDOW (f); 418 window = FRAME_LAST_NONMINIBUF_WINDOW (f);
357 419
420 /* Do the border */
421 XFillRectangle (dpy, x_win, background_gc, x, y,
422 (vert ? bar_width : border_width),
423 (vert ? border_width : bar_height));
424 XFillRectangle (dpy, x_win, background_gc,
425 (vert ? x : x + bar_width - border_width),
426 (vert ? y + bar_height - border_width : y),
427 (vert ? bar_width : border_width),
428 (vert ? border_width : bar_height));
429
358 if (vert) 430 if (vert)
359 max_pixpos = y + bar_height; 431 {
432 max_pixpos = y + bar_height - border_width;
433 y += border_width;
434 }
360 else 435 else
361 max_pixpos = x + bar_width; 436 {
437 max_pixpos = x + bar_width - border_width;
438 x += border_width;
439 }
362 440
363 button = FRAME_TOOLBAR_DATA (f, pos)->toolbar_buttons; 441 button = FRAME_TOOLBAR_DATA (f, pos)->toolbar_buttons;
364 right_size = 0; 442 right_size = 0;
365 443
366 /* First loop over all of the buttons to determine how much room we 444 /* First loop over all of the buttons to determine how much room we
404 { 482 {
405 width = blank_size; 483 width = blank_size;
406 height = bar_height; 484 height = bar_height;
407 } 485 }
408 486
409 x_draw_blank_toolbar_button (f, x, y, width, height, 1); 487 /*
488 * Use a 3D pushright separator only if there isn't a toolbar
489 * border. A flat separator meshes with the border and looks
490 * better.
491 */
492 x_draw_blank_toolbar_button (f, x, y, width, height, !border_width,
493 border_width, vert);
410 494
411 if (vert) 495 if (vert)
412 y += height; 496 y += height;
413 else 497 else
414 x += width; 498 x += width;
632 f->toolbar_size[pos] = make_int (newval); 716 f->toolbar_size[pos] = make_int (newval);
633 if (!EQ (old_visibility, Qzero)) 717 if (!EQ (old_visibility, Qzero))
634 f->toolbar_visible_p[pos] = new_visibility; 718 f->toolbar_visible_p[pos] = new_visibility;
635 719
636 if (change < 0) 720 if (change < 0)
637 x_clear_toolbar (f, pos, change); 721 {
722 x_clear_toolbar (f, pos, change);
723 mark_frame_toolbar_buttons_dirty (f, pos);
724 }
638 if (pos == LEFT_TOOLBAR || pos == RIGHT_TOOLBAR) 725 if (pos == LEFT_TOOLBAR || pos == RIGHT_TOOLBAR)
639 repl.width += change; 726 repl.width += change;
640 else 727 else
641 repl.height += change; 728 repl.height += change;
642 729
662 { 749 {
663 x_toolbar_size_changed_in_frame_1 (f, pos, oldval); 750 x_toolbar_size_changed_in_frame_1 (f, pos, oldval);
664 } 751 }
665 752
666 static void 753 static void
754 x_toolbar_border_width_changed_in_frame (struct frame *f, enum toolbar_pos pos,
755 Lisp_Object lispoldval)
756 {
757 XtWidgetGeometry req, repl;
758 int newval, oldval;
759
760 if (NILP (f->toolbar_visible_p[pos]) || ZEROP (f->toolbar_size[pos]))
761 {
762 return;
763 }
764 else if (!f->init_finished && !INTP (f->toolbar_border_width[pos]))
765 /* the size might not be set at all if we're in the process of
766 creating the frame. Otherwise it better be, and we'll crash
767 out if not. */
768 {
769 newval = 0;
770 }
771 else
772 {
773 Lisp_Object frame;
774
775 XSETFRAME (frame, f);
776 newval = XINT (Fspecifier_instance (Vtoolbar_border_width[pos],
777 frame, Qzero, Qnil));
778 }
779
780 if (INTP (lispoldval))
781 oldval = XINT (lispoldval);
782 else
783 oldval = 0;
784
785 if (oldval == newval)
786 return;
787
788 /* We want the text area to stay the same size. So, we query the
789 current size and then adjust it for the change in the toolbar
790 size. */
791
792 in_specifier_change_function++;
793 if (!in_resource_setting)
794 /* mirror the value in the frame resources, unless already done. */
795 {
796 Arg al [1];
797 XtSetArg (al [0],
798 pos == TOP_TOOLBAR ? XtNtopToolBarBorderWidth :
799 pos == BOTTOM_TOOLBAR ? XtNbottomToolBarBorderWidth :
800 pos == LEFT_TOOLBAR ? XtNleftToolBarBorderWidth :
801 XtNrightToolBarBorderWidth,
802 newval);
803 XtSetValues (FRAME_X_TEXT_WIDGET (f), al, 1);
804 }
805 if (XtIsRealized (FRAME_X_CONTAINER_WIDGET (f)))
806 {
807 int change = 2 * (newval - oldval);
808
809 req.request_mode = 0;
810
811 /*
812 * We want the current size, not the future size, so briefly
813 * reset the border width value so the query method returns
814 * the correct value.
815 */
816 f->toolbar_border_width[pos] = make_int (oldval);
817 XtQueryGeometry (FRAME_X_CONTAINER_WIDGET (f), &req, &repl);
818 f->toolbar_border_width[pos] = make_int (newval);
819
820 if (change < 0)
821 {
822 x_clear_toolbar (f, pos, change);
823 mark_frame_toolbar_buttons_dirty (f, pos);
824 }
825 if (pos == LEFT_TOOLBAR || pos == RIGHT_TOOLBAR)
826 repl.width += change;
827 else
828 repl.height += change;
829
830 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f);
831 EmacsManagerChangeSize (FRAME_X_CONTAINER_WIDGET (f), repl.width,
832 repl.height);
833 }
834 in_specifier_change_function--;
835 }
836
837 static void
667 x_initialize_frame_toolbar_gcs (struct frame *f) 838 x_initialize_frame_toolbar_gcs (struct frame *f)
668 { 839 {
669 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f); 840 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f);
670 XGCValues gcv; 841 XGCValues gcv;
671 unsigned long flags = (GCForeground | GCBackground | GCGraphicsExposures); 842 unsigned long flags = (GCForeground | GCBackground | GCGraphicsExposures);
843
844 /*
845 * If the user specified the global background resource, use it.
846 * Otherwise use the backgroundToolBarColor resource.
847 */
848 if (ef->emacs_frame.background_pixel != -1)
849 ef->emacs_frame.background_toolbar_pixel =
850 ef->emacs_frame.background_pixel;
672 851
673 gcv.foreground = ef->emacs_frame.background_toolbar_pixel; 852 gcv.foreground = ef->emacs_frame.background_toolbar_pixel;
674 gcv.background = ef->core.background_pixel; 853 gcv.background = ef->core.background_pixel;
675 gcv.graphics_exposures = False; 854 gcv.graphics_exposures = False;
676 FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f) = 855 FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f) =
789 CONSOLE_HAS_METHOD (x, free_frame_toolbars); 968 CONSOLE_HAS_METHOD (x, free_frame_toolbars);
790 CONSOLE_HAS_METHOD (x, output_toolbar_button); 969 CONSOLE_HAS_METHOD (x, output_toolbar_button);
791 CONSOLE_HAS_METHOD (x, redraw_exposed_toolbars); 970 CONSOLE_HAS_METHOD (x, redraw_exposed_toolbars);
792 CONSOLE_HAS_METHOD (x, redraw_frame_toolbars); 971 CONSOLE_HAS_METHOD (x, redraw_frame_toolbars);
793 CONSOLE_HAS_METHOD (x, toolbar_size_changed_in_frame); 972 CONSOLE_HAS_METHOD (x, toolbar_size_changed_in_frame);
973 CONSOLE_HAS_METHOD (x, toolbar_border_width_changed_in_frame);
794 CONSOLE_HAS_METHOD (x, toolbar_visible_p_changed_in_frame); 974 CONSOLE_HAS_METHOD (x, toolbar_visible_p_changed_in_frame);
795 } 975 }