Mercurial > hg > xemacs-beta
annotate src/gtk-xemacs.c @ 5811:b527c25f36ce
Do not insert timestamps into .elcs files for reproducibility. See
<CAHCOHQnEpzvbiu6cQMwc+3yYMxadgNUt=b+=Z1HBc91CMHTMDw@mail.gmail.com> in
xemacs-patches.
author | Jerry James <james@xemacs.org> |
---|---|
date | Mon, 29 Sep 2014 10:44:50 -0600 |
parents | 56144c8593a8 |
children |
rev | line source |
---|---|
462 | 1 /* gtk-xemacs.c |
2 ** | |
3 ** Description: A widget to encapsulate a XEmacs 'text widget' | |
4 ** | |
5 ** Created by: William M. Perry | |
6 ** Copyright (c) 2000 William M. Perry <wmperry@gnu.org> | |
5043 | 7 ** Copyright (C) 2010 Ben Wing. |
462 | 8 ** |
4709
db7068430402
Add explicit GPL v2 or later notices to Bill Perry's code, where such notices
Jerry James <james@xemacs.org>
parents:
3087
diff
changeset
|
9 ** This file is part of XEmacs. |
db7068430402
Add explicit GPL v2 or later notices to Bill Perry's code, where such notices
Jerry James <james@xemacs.org>
parents:
3087
diff
changeset
|
10 ** |
5405
2aa9cd456ae7
Move src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
5231
diff
changeset
|
11 ** XEmacs is free software: you can redistribute it and/or modify it |
4709
db7068430402
Add explicit GPL v2 or later notices to Bill Perry's code, where such notices
Jerry James <james@xemacs.org>
parents:
3087
diff
changeset
|
12 ** under the terms of the GNU General Public License as published by the |
5405
2aa9cd456ae7
Move src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
5231
diff
changeset
|
13 ** Free Software Foundation, either version 3 of the License, or (at your |
2aa9cd456ae7
Move src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
5231
diff
changeset
|
14 ** option) any later version. |
2aa9cd456ae7
Move src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
5231
diff
changeset
|
15 ** |
4709
db7068430402
Add explicit GPL v2 or later notices to Bill Perry's code, where such notices
Jerry James <james@xemacs.org>
parents:
3087
diff
changeset
|
16 ** XEmacs is distributed in the hope that it will be useful, but WITHOUT |
db7068430402
Add explicit GPL v2 or later notices to Bill Perry's code, where such notices
Jerry James <james@xemacs.org>
parents:
3087
diff
changeset
|
17 ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
db7068430402
Add explicit GPL v2 or later notices to Bill Perry's code, where such notices
Jerry James <james@xemacs.org>
parents:
3087
diff
changeset
|
18 ** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
db7068430402
Add explicit GPL v2 or later notices to Bill Perry's code, where such notices
Jerry James <james@xemacs.org>
parents:
3087
diff
changeset
|
19 ** for more details. |
5405
2aa9cd456ae7
Move src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
5231
diff
changeset
|
20 ** |
4709
db7068430402
Add explicit GPL v2 or later notices to Bill Perry's code, where such notices
Jerry James <james@xemacs.org>
parents:
3087
diff
changeset
|
21 ** You should have received a copy of the GNU General Public License |
5405
2aa9cd456ae7
Move src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
5231
diff
changeset
|
22 ** along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */ |
462 | 23 |
24 #include <config.h> | |
25 | |
26 #include "lisp.h" | |
4908
b3ce27ca7647
various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents:
4709
diff
changeset
|
27 |
809 | 28 #include "device.h" |
4908
b3ce27ca7647
various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents:
4709
diff
changeset
|
29 #include "faces.h" |
809 | 30 #include "glyphs.h" |
462 | 31 #include "window.h" |
4908
b3ce27ca7647
various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents:
4709
diff
changeset
|
32 |
876 | 33 #include "frame-impl.h" |
34 #include "console-gtk-impl.h" | |
35 #include "device-impl.h" | |
4908
b3ce27ca7647
various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents:
4709
diff
changeset
|
36 #include "gtk-xemacs.h" |
5176
8b2f75cecb89
rename objects* (.c, .h and .el files) to fontcolor*
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
37 #include "fontcolor-gtk.h" |
462 | 38 |
39 extern Lisp_Object Vmodeline_face; | |
40 extern Lisp_Object Vscrollbar_on_left_p; | |
41 | |
42 EXFUN (Fmake_image_instance, 4); | |
43 | |
44 static void gtk_xemacs_class_init (GtkXEmacsClass *klass); | |
45 static void gtk_xemacs_init (GtkXEmacs *xemacs); | |
46 static void gtk_xemacs_size_allocate (GtkWidget *widget, GtkAllocation *allocaction); | |
47 static void gtk_xemacs_draw (GtkWidget *widget, GdkRectangle *area); | |
48 static void gtk_xemacs_paint (GtkWidget *widget, GdkRectangle *area); | |
49 static void gtk_xemacs_size_request (GtkWidget *widget, GtkRequisition *requisition); | |
50 static void gtk_xemacs_realize (GtkWidget *widget); | |
51 static void gtk_xemacs_style_set (GtkWidget *widget, GtkStyle *previous_style); | |
52 static gint gtk_xemacs_expose (GtkWidget *widget, GdkEventExpose *event); | |
53 | |
54 guint | |
55 gtk_xemacs_get_type (void) | |
56 { | |
57 static guint xemacs_type = 0; | |
58 | |
59 if (!xemacs_type) | |
60 { | |
61 static const GtkTypeInfo xemacs_info = | |
62 { | |
63 "GtkXEmacs", | |
64 sizeof (GtkXEmacs), | |
65 sizeof (GtkXEmacsClass), | |
66 (GtkClassInitFunc) gtk_xemacs_class_init, | |
67 (GtkObjectInitFunc) gtk_xemacs_init, | |
68 /* reserved_1 */ NULL, | |
69 /* reserved_2 */ NULL, | |
70 (GtkClassInitFunc) NULL, | |
71 }; | |
72 | |
73 xemacs_type = gtk_type_unique (gtk_fixed_get_type (), &xemacs_info); | |
74 } | |
75 | |
76 return xemacs_type; | |
77 } | |
78 | |
79 static GtkWidgetClass *parent_class; | |
80 | |
81 static void | |
1204 | 82 gtk_xemacs_class_init (GtkXEmacsClass *class_) |
462 | 83 { |
84 GtkWidgetClass *widget_class; | |
85 | |
1204 | 86 widget_class = (GtkWidgetClass*) class_; |
462 | 87 parent_class = (GtkWidgetClass *) gtk_type_class (gtk_fixed_get_type ()); |
88 | |
89 widget_class->size_allocate = gtk_xemacs_size_allocate; | |
90 widget_class->size_request = gtk_xemacs_size_request; | |
91 widget_class->draw = gtk_xemacs_draw; | |
92 widget_class->expose_event = gtk_xemacs_expose; | |
93 widget_class->realize = gtk_xemacs_realize; | |
94 widget_class->button_press_event = emacs_gtk_button_event_handler; | |
95 widget_class->button_release_event = emacs_gtk_button_event_handler; | |
96 widget_class->key_press_event = emacs_gtk_key_event_handler; | |
97 widget_class->key_release_event = emacs_gtk_key_event_handler; | |
98 widget_class->motion_notify_event = emacs_gtk_motion_event_handler; | |
99 widget_class->style_set = gtk_xemacs_style_set; | |
100 } | |
101 | |
102 static void | |
103 gtk_xemacs_init (GtkXEmacs *xemacs) | |
104 { | |
105 GTK_WIDGET_SET_FLAGS (xemacs, GTK_CAN_FOCUS); | |
106 } | |
107 | |
108 GtkWidget* | |
109 gtk_xemacs_new (struct frame *f) | |
110 { | |
111 GtkXEmacs *xemacs; | |
112 | |
2054 | 113 xemacs = (GtkXEmacs*) gtk_type_new (gtk_xemacs_get_type ()); |
462 | 114 xemacs->f = f; |
115 | |
116 return GTK_WIDGET (xemacs); | |
117 } | |
118 | |
119 static void | |
120 __nuke_background_items (GtkWidget *widget) | |
121 { | |
122 /* This bit of voodoo is here to get around the annoying flicker | |
123 when GDK tries to futz with our background pixmap as well as | |
124 XEmacs doing it | |
125 | |
126 We do NOT set the background of this widget window, that way | |
127 there is NO flickering, etc. The downside is the XEmacs frame | |
128 appears as 'seethru' when XEmacs is too busy to redraw the | |
129 frame. | |
130 | |
131 Well, wait, we do... otherwise there sre weird 'seethru' areas | |
5384
3889ef128488
Fix misspelled words, and some grammar, across the entire source tree.
Jerry James <james@xemacs.org>
parents:
5231
diff
changeset
|
132 even when XEmacs does a full redisplay. Most noticeable in some |
462 | 133 areas of the modeline, or in the right-hand-side of the window |
134 between the scrollbar ad n the edge of the window. | |
135 */ | |
136 if (widget->window) | |
137 { | |
138 gdk_window_set_back_pixmap (widget->window, NULL, 0); | |
139 gdk_window_set_back_pixmap (widget->parent->window, NULL, 0); | |
140 gdk_window_set_background (widget->parent->window, | |
141 &widget->style->bg[GTK_STATE_NORMAL]); | |
142 gdk_window_set_background (widget->window, | |
143 &widget->style->bg[GTK_STATE_NORMAL]); | |
144 } | |
145 } | |
146 | |
147 extern Lisp_Object xemacs_gtk_convert_color(GdkColor *c, GtkWidget *w); | |
148 | |
5176
8b2f75cecb89
rename objects* (.c, .h and .el files) to fontcolor*
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
149 /* From fontcolor-gtk.c */ |
462 | 150 extern Lisp_Object __get_gtk_font_truename (GdkFont *gdk_font, int expandp); |
151 | |
152 #define convert_font(f) __get_gtk_font_truename (f, 0) | |
153 | |
778 | 154 #ifdef SMASH_FACE_FALLBACKS |
462 | 155 static void |
156 smash_face_fallbacks (struct frame *f, GtkStyle *style) | |
157 { | |
158 #define FROB(face,prop,slot) do { \ | |
159 Lisp_Object fallback = Qnil; \ | |
160 Lisp_Object specifier = Fget (face, prop, Qnil); \ | |
161 struct Lisp_Specifier *sp = NULL; \ | |
162 if (NILP (specifier)) continue; \ | |
163 sp = XSPECIFIER (specifier); \ | |
164 fallback = sp->fallback; \ | |
165 if (EQ (Fcar (Fcar (Fcar (fallback))), Qgtk)) \ | |
166 fallback = XCDR (fallback); \ | |
167 if (! NILP (slot)) \ | |
168 fallback = acons (list1 (Qgtk), \ | |
169 slot, \ | |
170 fallback); \ | |
171 set_specifier_fallback (specifier, fallback); \ | |
172 } while (0); | |
173 #define FROB_FACE(face,fg_slot,bg_slot) \ | |
174 do { \ | |
175 FROB (face, Qforeground, xemacs_gtk_convert_color (&style->fg_slot[GTK_STATE_NORMAL], FRAME_GTK_SHELL_WIDGET (f))); \ | |
176 FROB (face, Qbackground, xemacs_gtk_convert_color (&style->bg_slot[GTK_STATE_NORMAL], FRAME_GTK_SHELL_WIDGET (f))); \ | |
177 if (style->rc_style && style->rc_style->bg_pixmap_name[GTK_STATE_NORMAL]) \ | |
178 { \ | |
179 FROB (Vdefault_face, Qbackground_pixmap, \ | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4709
diff
changeset
|
180 Fmake_image_instance (build_cistring (style->rc_style->bg_pixmap_name[GTK_STATE_NORMAL]), \ |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
181 f->device, Qnil, make_fixnum (5))); \ |
462 | 182 } \ |
183 else \ | |
184 { \ | |
185 FROB (Vdefault_face, Qbackground_pixmap, Qnil); \ | |
186 } \ | |
187 } while (0) | |
188 | |
189 FROB (Vdefault_face, Qfont, convert_font (style->font)); | |
190 FROB_FACE (Vdefault_face, fg, bg); | |
191 FROB_FACE (Vgui_element_face, text, mid); | |
192 | |
193 #undef FROB | |
194 #undef FROB_FACE | |
195 } | |
778 | 196 #endif /* SMASH_FACE_FALLBACKS */ |
462 | 197 |
198 #ifdef HAVE_SCROLLBARS | |
199 static void | |
200 smash_scrollbar_specifiers (struct frame *f, GtkStyle *style) | |
201 { | |
202 Lisp_Object frame; | |
203 int slider_size = 0; | |
204 int hsize, vsize; | |
205 GtkRangeClass *klass; | |
206 | |
793 | 207 frame = wrap_frame (f); |
462 | 208 |
209 klass = (GtkRangeClass *) gtk_type_class (GTK_TYPE_SCROLLBAR); | |
210 slider_size = klass->slider_width; | |
211 hsize = slider_size + (style->klass->ythickness * 2); | |
212 vsize = slider_size + (style->klass->xthickness * 2); | |
213 | |
214 style = gtk_style_attach (style, | |
215 GTK_WIDGET (DEVICE_GTK_APP_SHELL (XDEVICE (FRAME_DEVICE (f))))->window); | |
216 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
217 Fadd_spec_to_specifier (Vscrollbar_width, make_fixnum (vsize), frame, Qnil, Qnil); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
218 Fadd_spec_to_specifier (Vscrollbar_height, make_fixnum (hsize), frame, Qnil, Qnil); |
462 | 219 } |
220 #endif /* HAVE_SCROLLBARS */ | |
221 | |
744 | 222 #ifdef HAVE_TOOLBARS |
223 extern Lisp_Object Vtoolbar_shadow_thickness; | |
224 | |
225 static void | |
226 smash_toolbar_specifiers(struct frame *f, GtkStyle *style) | |
227 { | |
228 Lisp_Object frame; | |
229 GtkStyleClass *klass = (GtkStyleClass *) style->klass; | |
230 | |
793 | 231 frame = wrap_frame (f); |
744 | 232 |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
233 Fadd_spec_to_specifier (Vtoolbar_shadow_thickness, make_fixnum (klass->xthickness), |
744 | 234 Qnil, list2 (Qgtk, Qdefault), Qprepend); |
235 } | |
236 #endif /* HAVE_TOOLBARS */ | |
237 | |
462 | 238 static void |
239 gtk_xemacs_realize (GtkWidget *widget) | |
240 { | |
241 parent_class->realize (widget); | |
242 gtk_xemacs_style_set (widget, gtk_widget_get_style (widget)); | |
243 } | |
244 | |
245 static void | |
246 gtk_xemacs_style_set (GtkWidget *widget, GtkStyle *previous_style) | |
247 { | |
248 GtkStyle *new_style = gtk_widget_get_style (widget); | |
249 GtkXEmacs *x = GTK_XEMACS (widget); | |
250 | |
251 parent_class->style_set (widget, previous_style); | |
252 | |
253 if (x->f) | |
254 { | |
255 __nuke_background_items (widget); | |
778 | 256 #ifdef SMASH_FACE_FALLBACKS |
462 | 257 smash_face_fallbacks (x->f, new_style); |
258 #endif | |
744 | 259 #ifdef HAVE_SCROLLBARS |
462 | 260 smash_scrollbar_specifiers (x->f, new_style); |
744 | 261 #endif |
262 #ifdef HAVE_TOOLBARS | |
263 smash_toolbar_specifiers (x->f, new_style); | |
264 #endif | |
462 | 265 } |
266 } | |
267 | |
268 static void | |
269 gtk_xemacs_size_request (GtkWidget *widget, GtkRequisition *requisition) | |
270 { | |
271 GtkXEmacs *x = GTK_XEMACS (widget); | |
272 struct frame *f = GTK_XEMACS_FRAME (x); | |
273 int width, height; | |
274 | |
275 if (f) | |
276 { | |
5043 | 277 frame_unit_to_pixel_size (f, FRAME_WIDTH (f), FRAME_HEIGHT (f), |
462 | 278 &width, &height); |
279 requisition->width = width; | |
280 requisition->height = height; | |
281 } | |
282 else | |
283 { | |
284 parent_class->size_request (widget, requisition); | |
285 } | |
286 } | |
287 | |
2168 | 288 /* Assign a size and position to the child widgets. This differs from the |
289 super class method in that for all widgets except the scrollbars the size | |
290 and position are not caclulated here. This is because these widgets have | |
291 this function performed for them by the redisplay code (see | |
292 gtk_map_subwindow()). If the superclass method is called then the widgets | |
293 can change size and position as the two pieces of code move the widgets at | |
294 random. | |
295 */ | |
462 | 296 static void |
297 gtk_xemacs_size_allocate (GtkWidget *widget, GtkAllocation *allocation) | |
298 { | |
299 GtkXEmacs *x = GTK_XEMACS (widget); | |
2168 | 300 GtkFixed *fixed = GTK_FIXED (widget); |
462 | 301 struct frame *f = GTK_XEMACS_FRAME (x); |
302 int columns, rows; | |
2168 | 303 GList *children; |
304 guint16 border_width; | |
462 | 305 |
2168 | 306 widget->allocation = *allocation; |
307 if (GTK_WIDGET_REALIZED (widget)) | |
308 gdk_window_move_resize (widget->window, | |
309 allocation->x, | |
310 allocation->y, | |
311 allocation->width, | |
312 allocation->height); | |
313 | |
314 border_width = GTK_CONTAINER (fixed)->border_width; | |
315 | |
316 children = fixed->children; | |
317 while (children) | |
318 { | |
2336 | 319 GtkFixedChild* child = (GtkFixedChild*) children->data; |
2168 | 320 children = children->next; |
321 | |
322 /* | |
323 Scrollbars are the only widget that is managed by GTK. See | |
324 comments in gtk_create_scrollbar_instance(). | |
325 */ | |
326 if (GTK_WIDGET_VISIBLE (child->widget) && | |
327 gtk_type_is_a(GTK_OBJECT_TYPE(child->widget), GTK_TYPE_SCROLLBAR)) | |
328 { | |
329 GtkAllocation child_allocation; | |
330 GtkRequisition child_requisition; | |
331 | |
332 gtk_widget_get_child_requisition (child->widget, &child_requisition); | |
333 child_allocation.x = child->x + border_width; | |
334 child_allocation.y = child->y + border_width; | |
335 child_allocation.width = child_requisition.width; | |
336 child_allocation.height = child_requisition.height; | |
337 gtk_widget_size_allocate (child->widget, &child_allocation); | |
338 } | |
339 } | |
462 | 340 |
341 if (f) | |
342 { | |
343 f->pixwidth = allocation->width; | |
344 f->pixheight = allocation->height; | |
345 | |
5043 | 346 pixel_to_frame_unit_size (f, |
462 | 347 allocation->width, |
348 allocation->height, &columns, &rows); | |
349 | |
5043 | 350 change_frame_size (f, columns, rows, 1); |
462 | 351 } |
352 } | |
353 | |
354 static void | |
355 gtk_xemacs_paint (GtkWidget *widget, GdkRectangle *area) | |
356 { | |
357 GtkXEmacs *x = GTK_XEMACS (widget); | |
358 struct frame *f = GTK_XEMACS_FRAME (x); | |
2195 | 359 |
360 if (GTK_WIDGET_DRAWABLE (widget)) | |
361 redisplay_redraw_exposed_area (f, area->x, area->y, area->width, | |
362 area->height); | |
462 | 363 } |
364 | |
365 static void | |
366 gtk_xemacs_draw (GtkWidget *widget, GdkRectangle *area) | |
367 { | |
368 GtkFixed *fixed = GTK_FIXED (widget); | |
369 GtkFixedChild *child; | |
370 GdkRectangle child_area; | |
371 GList *children; | |
372 | |
373 /* I need to manually iterate over the children instead of just | |
374 chaining to parent_class->draw() because it calls | |
375 gtk_fixed_paint() directly, which clears the background window, | |
376 which causes A LOT of flashing. */ | |
377 | |
2195 | 378 if (GTK_WIDGET_DRAWABLE (widget)) |
379 { | |
380 gtk_xemacs_paint (widget, area); | |
462 | 381 |
2195 | 382 children = fixed->children; |
462 | 383 |
2195 | 384 while (children) |
385 { | |
386 child = (GtkFixedChild*) children->data; | |
387 children = children->next; | |
388 /* #### This is what causes the scrollbar flickering! | |
389 Evidently the scrollbars pretty much take care of drawing | |
390 themselves in most cases. Then we come along and tell them | |
391 to redraw again! | |
462 | 392 |
2195 | 393 But if we just leave it out, then they do not get drawn |
394 correctly the first time! | |
462 | 395 |
2195 | 396 Scrollbar flickering has been greatly helped by the |
397 optimizations in scrollbar-gtk.c / | |
398 gtk_update_scrollbar_instance_status (), so this is not that | |
399 big a deal anymore. | |
400 */ | |
401 if (gtk_widget_intersect (child->widget, area, &child_area)) | |
402 { | |
403 gtk_widget_draw (child->widget, &child_area); | |
404 } | |
405 } | |
406 } | |
462 | 407 } |
408 | |
409 static gint | |
410 gtk_xemacs_expose (GtkWidget *widget, GdkEventExpose *event) | |
411 { | |
412 GtkXEmacs *x = GTK_XEMACS (widget); | |
413 struct frame *f = GTK_XEMACS_FRAME (x); | |
414 GdkRectangle *a = &event->area; | |
415 | |
2195 | 416 if (GTK_WIDGET_DRAWABLE (widget)) |
417 { | |
418 /* This takes care of drawing the scrollbars, etc */ | |
419 parent_class->expose_event (widget, event); | |
462 | 420 |
2195 | 421 /* Now draw the actual frame data */ |
422 if (!check_for_ignored_expose (f, a->x, a->y, a->width, a->height) && | |
423 !find_matching_subwindow (f, a->x, a->y, a->width, a->height)) | |
424 redisplay_redraw_exposed_area (f, a->x, a->y, a->width, a->height); | |
425 return (TRUE); | |
426 } | |
3087 | 427 |
428 return FALSE; | |
462 | 429 } |
430 | |
431 Lisp_Object | |
2286 | 432 xemacs_gtk_convert_color(GdkColor *c, GtkWidget *UNUSED (w)) |
462 | 433 { |
434 char color_buf[255]; | |
435 | |
436 sprintf (color_buf, "#%04x%04x%04x", c->red, c->green, c->blue); | |
437 | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4709
diff
changeset
|
438 return (build_cistring (color_buf)); |
462 | 439 } |