Mercurial > hg > xemacs-beta
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 } |