Mercurial > hg > xemacs-beta
annotate src/glyphs-gtk.c @ 5402:308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
author | Mats Lidell <matsl@xemacs.org> |
---|---|
date | Thu, 14 Oct 2010 17:15:20 +0200 |
parents | 71ee43b8a74d |
children | 56144c8593a8 |
rev | line source |
---|---|
714 | 1 /* GTK-specific Lisp objects. |
462 | 2 Copyright (C) 1993, 1994 Free Software Foundation, Inc. |
3 Copyright (C) 1995 Board of Trustees, University of Illinois. | |
4 Copyright (C) 1995 Tinker Systems | |
5050
6f2158fa75ed
Fix quick-build, use asserts() in place of ABORT()
Ben Wing <ben@xemacs.org>
parents:
4982
diff
changeset
|
5 Copyright (C) 1995, 1996, 2001, 2002, 2004, 2005, 2010 Ben Wing |
462 | 6 Copyright (C) 1995 Sun Microsystems |
7 | |
8 This file is part of XEmacs. | |
9 | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5191
diff
changeset
|
10 XEmacs is free software: you can redistribute it and/or modify it |
462 | 11 under the terms of the GNU General Public License as published by the |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5191
diff
changeset
|
12 Free Software Foundation, either version 3 of the License, or (at your |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5191
diff
changeset
|
13 option) any later version. |
462 | 14 |
15 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
18 for more details. | |
19 | |
20 You should have received a copy of the GNU General Public License | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5191
diff
changeset
|
21 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */ |
462 | 22 |
23 /* Synched up with: Not in FSF. */ | |
24 | |
25 /* Original author: Jamie Zawinski for 19.8 | |
26 font-truename stuff added by Jamie Zawinski for 19.10 | |
27 subwindow support added by Chuck Thompson | |
28 additional XPM support added by Chuck Thompson | |
29 initial X-Face support added by Stig | |
30 rewritten/restructured by Ben Wing for 19.12/19.13 | |
31 GIF/JPEG support added by Ben Wing for 19.14 | |
32 PNG support added by Bill Perry for 19.14 | |
33 Improved GIF/JPEG support added by Bill Perry for 19.14 | |
34 Cleanup/simplification of error handling by Ben Wing for 19.14 | |
35 Pointer/icon overhaul, more restructuring by Ben Wing for 19.14 | |
36 GIF support changed to external GIFlib 3.1 by Jareth Hein for 21.0 | |
37 Many changes for color work and optimizations by Jareth Hein for 21.0 | |
38 Switch of GIF/JPEG/PNG to new EImage intermediate code by Jareth Hein for 21.0 | |
39 TIFF code by Jareth Hein for 21.0 | |
40 GIF/JPEG/PNG/TIFF code moved to new glyph-eimage.c for 21.0 | |
41 Gtk version by William Perry for 21.1 | |
42 | |
43 TODO: | |
44 Support the GrayScale, StaticColor and StaticGray visual classes. | |
45 Convert images.el to C and stick it in here? | |
46 */ | |
47 | |
48 #include <config.h> | |
49 #include "lisp.h" | |
50 | |
51 #include "buffer.h" | |
872 | 52 #include "device-impl.h" |
53 #include "faces.h" | |
54 #include "file-coding.h" | |
55 #include "frame-impl.h" | |
56 #include "glyphs.h" | |
809 | 57 #include "gui.h" |
872 | 58 #include "imgproc.h" |
462 | 59 #include "insdel.h" |
872 | 60 #include "lstream.h" |
462 | 61 #include "opaque.h" |
872 | 62 #include "window.h" |
2168 | 63 #include "elhash.h" |
64 #include "events.h" | |
872 | 65 |
66 #include "console-gtk-impl.h" | |
67 #include "glyphs-gtk.h" | |
5176
8b2f75cecb89
rename objects* (.c, .h and .el files) to fontcolor*
Ben Wing <ben@xemacs.org>
parents:
5050
diff
changeset
|
68 #include "fontcolor-gtk-impl.h" |
872 | 69 #include "ui-gtk.h" |
462 | 70 |
71 #include "sysfile.h" | |
72 | |
73 #include <setjmp.h> | |
74 | |
2082 | 75 #if defined (HAVE_XPM) |
76 #include <X11/xpm.h> | |
77 #endif | |
78 | |
2168 | 79 /* Widget callback hash table callback slot. */ |
80 #define WIDGET_GLYPH_SLOT 0 | |
81 | |
462 | 82 DECLARE_IMAGE_INSTANTIATOR_FORMAT (nothing); |
83 DECLARE_IMAGE_INSTANTIATOR_FORMAT (string); | |
84 DECLARE_IMAGE_INSTANTIATOR_FORMAT (formatted_string); | |
85 DECLARE_IMAGE_INSTANTIATOR_FORMAT (inherit); | |
86 #ifdef HAVE_JPEG | |
87 DECLARE_IMAGE_INSTANTIATOR_FORMAT (jpeg); | |
88 #endif | |
89 #ifdef HAVE_TIFF | |
90 DECLARE_IMAGE_INSTANTIATOR_FORMAT (tiff); | |
91 #endif | |
92 #ifdef HAVE_PNG | |
93 DECLARE_IMAGE_INSTANTIATOR_FORMAT (png); | |
94 #endif | |
95 #ifdef HAVE_GIF | |
96 DECLARE_IMAGE_INSTANTIATOR_FORMAT (gif); | |
97 #endif | |
98 | |
99 #ifdef HAVE_XFACE | |
100 DEFINE_DEVICE_IIFORMAT (gtk, xface); | |
101 #endif | |
102 | |
103 #ifdef HAVE_XPM | |
104 DEFINE_DEVICE_IIFORMAT (gtk, xpm); | |
105 #endif | |
106 | |
107 DEFINE_DEVICE_IIFORMAT (gtk, xbm); | |
108 DEFINE_DEVICE_IIFORMAT (gtk, subwindow); | |
109 | |
110 DEFINE_IMAGE_INSTANTIATOR_FORMAT (cursor_font); | |
111 Lisp_Object Qcursor_font; | |
112 | |
113 DEFINE_IMAGE_INSTANTIATOR_FORMAT (font); | |
114 | |
115 DEFINE_IMAGE_INSTANTIATOR_FORMAT (autodetect); | |
116 | |
117 #ifdef HAVE_WIDGETS | |
118 DECLARE_IMAGE_INSTANTIATOR_FORMAT (layout); | |
119 DEFINE_DEVICE_IIFORMAT (gtk, widget); | |
120 DEFINE_DEVICE_IIFORMAT (gtk, native_layout); | |
121 DEFINE_DEVICE_IIFORMAT (gtk, button); | |
122 DEFINE_DEVICE_IIFORMAT (gtk, progress_gauge); | |
123 DEFINE_DEVICE_IIFORMAT (gtk, edit_field); | |
124 DEFINE_DEVICE_IIFORMAT (gtk, combo_box); | |
125 DEFINE_DEVICE_IIFORMAT (gtk, tab_control); | |
126 DEFINE_DEVICE_IIFORMAT (gtk, label); | |
127 #endif | |
128 | |
129 static void update_widget_face (GtkWidget *w, Lisp_Image_Instance *ii, | |
130 Lisp_Object domain); | |
131 static void cursor_font_instantiate (Lisp_Object image_instance, | |
132 Lisp_Object instantiator, | |
133 Lisp_Object pointer_fg, | |
134 Lisp_Object pointer_bg, | |
135 int dest_mask, | |
136 Lisp_Object domain); | |
137 | |
2054 | 138 static GdkCursorType cursor_name_to_index (const char *name); |
462 | 139 |
140 #ifndef BitmapSuccess | |
141 #define BitmapSuccess 0 | |
142 #define BitmapOpenFailed 1 | |
143 #define BitmapFileInvalid 2 | |
144 #define BitmapNoMemory 3 | |
145 #endif | |
146 | |
147 #include "bitmaps.h" | |
148 | |
149 DEFINE_IMAGE_INSTANTIATOR_FORMAT (gtk_resource); | |
150 Lisp_Object Qgtk_resource; | |
151 #ifdef HAVE_WIDGETS | |
152 Lisp_Object Qgtk_widget_instantiate_internal, Qgtk_widget_property_internal; | |
153 Lisp_Object Qgtk_widget_redisplay_internal, Qgtk_widget_set_style; | |
154 #endif | |
155 | |
156 | |
157 /************************************************************************/ | |
158 /* image instance methods */ | |
159 /************************************************************************/ | |
160 | |
161 /************************************************************************/ | |
162 /* convert from a series of RGB triples to an XImage formated for the */ | |
4252 | 163 /* proper display */ |
462 | 164 /************************************************************************/ |
165 static GdkImage * | |
166 convert_EImage_to_GDKImage (Lisp_Object device, int width, int height, | |
167 unsigned char *pic, unsigned long **pixtbl, | |
168 int *npixels) | |
169 { | |
170 GdkColormap *cmap; | |
171 GdkVisual *vis; | |
172 GdkImage *outimg; | |
173 int depth, byte_cnt, i, j; | |
174 int rd,gr,bl,q; | |
175 unsigned char *data, *ip, *dp = NULL; | |
176 quant_table *qtable = NULL; | |
177 union { | |
826 | 178 UINT_32_BIT val; |
462 | 179 char cp[4]; |
180 } conv; | |
181 | |
182 cmap = DEVICE_GTK_COLORMAP (XDEVICE(device)); | |
183 vis = DEVICE_GTK_VISUAL (XDEVICE(device)); | |
184 depth = DEVICE_GTK_DEPTH(XDEVICE(device)); | |
185 | |
186 if (vis->type == GDK_VISUAL_GRAYSCALE || vis->type == GDK_VISUAL_STATIC_COLOR || | |
187 vis->type == GDK_VISUAL_STATIC_GRAY) | |
188 { | |
189 /* #### Implement me!!! */ | |
190 return NULL; | |
191 } | |
192 | |
193 if (vis->type == GDK_VISUAL_PSEUDO_COLOR) | |
194 { | |
195 /* Quantize the image and get a histogram while we're at it. | |
196 Do this first to save memory */ | |
197 qtable = build_EImage_quantable(pic, width, height, 256); | |
198 if (qtable == NULL) return NULL; | |
199 } | |
200 | |
201 /* The first parameter (GdkWindow *) is allowed to be NULL if we | |
202 ** specify the depth */ | |
203 outimg = gdk_image_new (GDK_IMAGE_FASTEST, vis, width, height); | |
204 | |
205 if (!outimg) return NULL; | |
206 | |
207 byte_cnt = outimg->bpp; | |
208 | |
209 data = (unsigned char *) outimg->mem; | |
210 | |
211 if (!data) | |
212 { | |
213 gdk_image_destroy (outimg); | |
214 return NULL; | |
215 } | |
4252 | 216 |
462 | 217 if (vis->type == GDK_VISUAL_PSEUDO_COLOR) |
218 { | |
219 unsigned long pixarray[256]; | |
220 int pixcount, n; | |
221 /* use our quantize table to allocate the colors */ | |
222 pixcount = 32; | |
223 *pixtbl = xnew_array (unsigned long, pixcount); | |
224 *npixels = 0; | |
225 | |
226 /* ### should implement a sort by popularity to assure proper allocation */ | |
227 n = *npixels; | |
228 for (i = 0; i < qtable->num_active_colors; i++) | |
229 { | |
230 GdkColor color; | |
231 int res; | |
4252 | 232 |
462 | 233 color.red = qtable->rm[i] ? qtable->rm[i] << 8 : 0; |
234 color.green = qtable->gm[i] ? qtable->gm[i] << 8 : 0; | |
235 color.blue = qtable->bm[i] ? qtable->bm[i] << 8 : 0; | |
236 res = allocate_nearest_color (cmap, vis, &color); | |
237 if (res > 0 && res < 3) | |
238 { | |
239 DO_REALLOC(*pixtbl, pixcount, n+1, unsigned long); | |
240 (*pixtbl)[n] = color.pixel; | |
241 n++; | |
242 } | |
243 pixarray[i] = color.pixel; | |
244 } | |
245 *npixels = n; | |
246 ip = pic; | |
247 for (i = 0; i < height; i++) | |
248 { | |
249 dp = data + (i * outimg->bpl); | |
250 for (j = 0; j < width; j++) | |
251 { | |
252 rd = *ip++; | |
253 gr = *ip++; | |
254 bl = *ip++; | |
255 conv.val = pixarray[QUANT_GET_COLOR(qtable,rd,gr,bl)]; | |
256 #if WORDS_BIGENDIAN | |
257 if (outimg->byte_order == GDK_MSB_FIRST) | |
258 for (q = 4-byte_cnt; q < 4; q++) *dp++ = conv.cp[q]; | |
259 else | |
260 for (q = 3; q >= 4-byte_cnt; q--) *dp++ = conv.cp[q]; | |
261 #else | |
262 if (outimg->byte_order == GDK_MSB_FIRST) | |
263 for (q = byte_cnt-1; q >= 0; q--) *dp++ = conv.cp[q]; | |
264 else | |
265 for (q = 0; q < byte_cnt; q++) *dp++ = conv.cp[q]; | |
266 #endif | |
267 } | |
268 } | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
269 xfree (qtable); |
462 | 270 } else { |
271 unsigned long rshift,gshift,bshift,rbits,gbits,bbits,junk; | |
272 junk = vis->red_mask; | |
273 rshift = 0; | |
274 while ((junk & 0x1) == 0) | |
275 { | |
276 junk = junk >> 1; | |
277 rshift ++; | |
278 } | |
279 rbits = 0; | |
280 while (junk != 0) | |
281 { | |
282 junk = junk >> 1; | |
283 rbits++; | |
284 } | |
285 junk = vis->green_mask; | |
286 gshift = 0; | |
287 while ((junk & 0x1) == 0) | |
288 { | |
289 junk = junk >> 1; | |
290 gshift ++; | |
291 } | |
292 gbits = 0; | |
293 while (junk != 0) | |
294 { | |
295 junk = junk >> 1; | |
296 gbits++; | |
297 } | |
298 junk = vis->blue_mask; | |
299 bshift = 0; | |
300 while ((junk & 0x1) == 0) | |
301 { | |
302 junk = junk >> 1; | |
303 bshift ++; | |
304 } | |
305 bbits = 0; | |
306 while (junk != 0) | |
307 { | |
308 junk = junk >> 1; | |
309 bbits++; | |
310 } | |
311 ip = pic; | |
312 for (i = 0; i < height; i++) | |
313 { | |
314 dp = data + (i * outimg->bpl); | |
315 for (j = 0; j < width; j++) | |
316 { | |
317 if (rbits > 8) | |
318 rd = *ip++ << (rbits - 8); | |
319 else | |
320 rd = *ip++ >> (8 - rbits); | |
321 if (gbits > 8) | |
322 gr = *ip++ << (gbits - 8); | |
323 else | |
324 gr = *ip++ >> (8 - gbits); | |
325 if (bbits > 8) | |
326 bl = *ip++ << (bbits - 8); | |
327 else | |
328 bl = *ip++ >> (8 - bbits); | |
329 | |
330 conv.val = (rd << rshift) | (gr << gshift) | (bl << bshift); | |
331 #if WORDS_BIGENDIAN | |
332 if (outimg->byte_order == GDK_MSB_FIRST) | |
333 for (q = 4-byte_cnt; q < 4; q++) *dp++ = conv.cp[q]; | |
334 else | |
335 for (q = 3; q >= 4-byte_cnt; q--) *dp++ = conv.cp[q]; | |
336 #else | |
337 if (outimg->byte_order == GDK_MSB_FIRST) | |
338 for (q = byte_cnt-1; q >= 0; q--) *dp++ = conv.cp[q]; | |
339 else | |
340 for (q = 0; q < byte_cnt; q++) *dp++ = conv.cp[q]; | |
341 #endif | |
342 } | |
343 } | |
4252 | 344 } |
462 | 345 return outimg; |
346 } | |
347 | |
348 static void | |
349 gtk_print_image_instance (struct Lisp_Image_Instance *p, | |
350 Lisp_Object printcharfun, | |
2286 | 351 int UNUSED (escapeflag)) |
462 | 352 { |
353 switch (IMAGE_INSTANCE_TYPE (p)) | |
354 { | |
355 case IMAGE_MONO_PIXMAP: | |
356 case IMAGE_COLOR_PIXMAP: | |
357 case IMAGE_POINTER: | |
800 | 358 write_fmt_string (printcharfun, " (0x%lx", |
359 (unsigned long) IMAGE_INSTANCE_GTK_PIXMAP (p)); | |
462 | 360 if (IMAGE_INSTANCE_GTK_MASK (p)) |
800 | 361 write_fmt_string (printcharfun, "/0x%lx", |
362 (unsigned long) IMAGE_INSTANCE_GTK_MASK (p)); | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4700
diff
changeset
|
363 write_ascstring (printcharfun, ")"); |
462 | 364 break; |
2054 | 365 #ifdef HAVE_SUBWINDOWS |
462 | 366 case IMAGE_SUBWINDOW: |
367 /* #### implement me */ | |
368 #endif | |
369 default: | |
370 break; | |
371 } | |
372 } | |
373 | |
374 static void | |
375 gtk_finalize_image_instance (struct Lisp_Image_Instance *p) | |
376 { | |
377 if (!p->data) | |
378 return; | |
379 | |
380 if (DEVICE_LIVE_P (XDEVICE (p->device))) | |
381 { | |
382 if (0) | |
383 ; | |
384 #ifdef HAVE_WIDGETS | |
385 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET) | |
386 { | |
387 if (IMAGE_INSTANCE_SUBWINDOW_ID (p)) | |
388 { | |
2054 | 389 gtk_widget_destroy ((GtkWidget*) IMAGE_INSTANCE_SUBWINDOW_ID (p)); |
462 | 390 |
391 /* We can release the callbacks again. */ | |
392 /* #### FIXME! */ | |
393 /* ungcpro_popup_callbacks (...); */ | |
394 | |
395 /* IMAGE_INSTANCE_GTK_WIDGET_ID (p) = 0; */ | |
396 IMAGE_INSTANCE_GTK_CLIPWIDGET (p) = 0; | |
397 } | |
398 } | |
399 #endif | |
400 else if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW) | |
401 { | |
2500 | 402 ABORT(); |
462 | 403 } |
404 else | |
405 { | |
406 int i; | |
407 if (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p)) | |
408 disable_glyph_animated_timeout (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p)); | |
409 | |
410 if (IMAGE_INSTANCE_GTK_MASK (p) && | |
411 IMAGE_INSTANCE_GTK_MASK (p) != IMAGE_INSTANCE_GTK_PIXMAP (p)) | |
412 gdk_pixmap_unref (IMAGE_INSTANCE_GTK_MASK (p)); | |
413 IMAGE_INSTANCE_PIXMAP_MASK (p) = 0; | |
414 | |
415 if (IMAGE_INSTANCE_GTK_PIXMAP_SLICES (p)) | |
416 { | |
417 for (i = 0; i < IMAGE_INSTANCE_PIXMAP_MAXSLICE (p); i++) | |
418 if (IMAGE_INSTANCE_GTK_PIXMAP_SLICE (p,i)) | |
419 { | |
420 gdk_pixmap_unref (IMAGE_INSTANCE_GTK_PIXMAP_SLICE (p,i)); | |
421 IMAGE_INSTANCE_GTK_PIXMAP_SLICE (p, i) = 0; | |
422 } | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
423 xfree (IMAGE_INSTANCE_GTK_PIXMAP_SLICES (p)); |
462 | 424 IMAGE_INSTANCE_GTK_PIXMAP_SLICES (p) = 0; |
425 } | |
426 | |
427 if (IMAGE_INSTANCE_GTK_CURSOR (p)) | |
428 { | |
429 gdk_cursor_destroy (IMAGE_INSTANCE_GTK_CURSOR (p)); | |
430 IMAGE_INSTANCE_GTK_CURSOR (p) = 0; | |
431 } | |
432 } | |
433 | |
434 #if 0 | |
435 /* #### BILL!!! */ | |
436 if (IMAGE_INSTANCE_GTK_NPIXELS (p) != 0) | |
437 { | |
438 XFreeColors (dpy, | |
439 IMAGE_INSTANCE_GTK_COLORMAP (p), | |
440 IMAGE_INSTANCE_GTK_PIXELS (p), | |
441 IMAGE_INSTANCE_GTK_NPIXELS (p), 0); | |
442 IMAGE_INSTANCE_GTK_NPIXELS (p) = 0; | |
443 } | |
444 #endif | |
445 } | |
446 | |
447 if (IMAGE_INSTANCE_TYPE (p) != IMAGE_WIDGET | |
448 && IMAGE_INSTANCE_TYPE (p) != IMAGE_SUBWINDOW | |
449 && IMAGE_INSTANCE_GTK_PIXELS (p)) | |
450 { | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
451 xfree (IMAGE_INSTANCE_GTK_PIXELS (p)); |
462 | 452 IMAGE_INSTANCE_GTK_PIXELS (p) = 0; |
453 } | |
454 | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
455 xfree (p->data); |
462 | 456 p->data = 0; |
457 } | |
458 | |
459 static int | |
460 gtk_image_instance_equal (struct Lisp_Image_Instance *p1, | |
2286 | 461 struct Lisp_Image_Instance *p2, int UNUSED (depth)) |
462 | 462 { |
463 switch (IMAGE_INSTANCE_TYPE (p1)) | |
464 { | |
465 case IMAGE_MONO_PIXMAP: | |
466 case IMAGE_COLOR_PIXMAP: | |
467 case IMAGE_POINTER: | |
468 if (IMAGE_INSTANCE_GTK_COLORMAP (p1) != IMAGE_INSTANCE_GTK_COLORMAP (p2) || | |
469 IMAGE_INSTANCE_GTK_NPIXELS (p1) != IMAGE_INSTANCE_GTK_NPIXELS (p2)) | |
470 return 0; | |
2054 | 471 #ifdef HAVE_SUBWINDOWS |
462 | 472 case IMAGE_SUBWINDOW: |
473 /* #### implement me */ | |
474 #endif | |
475 break; | |
476 default: | |
477 break; | |
478 } | |
479 | |
480 return 1; | |
481 } | |
482 | |
2515 | 483 static Hashcode |
5191
71ee43b8a74d
Add #'equalp as a hash test by default; add #'define-hash-table-test, GNU API
Aidan Kehoe <kehoea@parhasard.net>
parents:
5176
diff
changeset
|
484 gtk_image_instance_hash (struct Lisp_Image_Instance *p, int UNUSED (depth), |
71ee43b8a74d
Add #'equalp as a hash test by default; add #'define-hash-table-test, GNU API
Aidan Kehoe <kehoea@parhasard.net>
parents:
5176
diff
changeset
|
485 Boolint UNUSED (equalp)) |
462 | 486 { |
487 switch (IMAGE_INSTANCE_TYPE (p)) | |
488 { | |
489 case IMAGE_MONO_PIXMAP: | |
490 case IMAGE_COLOR_PIXMAP: | |
491 case IMAGE_POINTER: | |
492 return IMAGE_INSTANCE_GTK_NPIXELS (p); | |
2054 | 493 #ifdef HAVE_SUBWINDOWS |
462 | 494 case IMAGE_SUBWINDOW: |
495 /* #### implement me */ | |
496 return 0; | |
497 #endif | |
498 default: | |
499 return 0; | |
500 } | |
501 } | |
502 | |
503 /* Set all the slots in an image instance structure to reasonable | |
504 default values. This is used somewhere within an instantiate | |
505 method. It is assumed that the device slot within the image | |
506 instance is already set -- this is the case when instantiate | |
507 methods are called. */ | |
508 | |
509 static void | |
510 gtk_initialize_pixmap_image_instance (struct Lisp_Image_Instance *ii, | |
511 int slices, | |
512 enum image_instance_type type) | |
513 { | |
514 ii->data = xnew_and_zero (struct gtk_image_instance_data); | |
515 IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii) = slices; | |
516 IMAGE_INSTANCE_GTK_PIXMAP_SLICES (ii) = | |
517 xnew_array_and_zero (GdkPixmap *, slices); | |
518 IMAGE_INSTANCE_TYPE (ii) = type; | |
519 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil; | |
520 IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (ii) = Qnil; | |
521 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = Qnil; | |
522 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = Qnil; | |
523 IMAGE_INSTANCE_PIXMAP_FG (ii) = Qnil; | |
524 IMAGE_INSTANCE_PIXMAP_BG (ii) = Qnil; | |
525 } | |
526 | |
527 | |
528 /************************************************************************/ | |
529 /* pixmap file functions */ | |
530 /************************************************************************/ | |
531 | |
532 /* Where bitmaps are; initialized from resource database */ | |
533 Lisp_Object Vgtk_bitmap_file_path; | |
534 | |
535 #ifndef BITMAPDIR | |
536 #define BITMAPDIR "/usr/include/X11/bitmaps" | |
537 #endif | |
538 | |
539 /* Given a pixmap filename, look through all of the "standard" places | |
540 where the file might be located. Return a full pathname if found; | |
541 otherwise, return Qnil. */ | |
542 | |
543 static Lisp_Object | |
544 gtk_locate_pixmap_file (Lisp_Object name) | |
545 { | |
546 /* This function can GC if IN_REDISPLAY is false */ | |
547 | |
548 /* Check non-absolute pathnames with a directory component relative to | |
549 the search path; that's the way Xt does it. */ | |
550 /* #### Unix-specific */ | |
826 | 551 if (string_byte (name, 0) == '/' || |
552 (string_byte (name, 0) == '.' && | |
553 (string_byte (name, 1) == '/' || | |
554 (string_byte (name, 1) == '.' && | |
555 (string_byte (name, 2) == '/'))))) | |
462 | 556 { |
557 if (!NILP (Ffile_readable_p (name))) | |
558 return name; | |
559 else | |
560 return Qnil; | |
561 } | |
562 | |
563 if (NILP (Vgtk_bitmap_file_path)) | |
564 { | |
565 Vgtk_bitmap_file_path = nconc2 (Vgtk_bitmap_file_path, | |
778 | 566 (split_external_path (BITMAPDIR))); |
462 | 567 } |
568 | |
569 { | |
570 Lisp_Object found; | |
571 if (locate_file (Vgtk_bitmap_file_path, name, Qnil, &found, R_OK) < 0) | |
572 { | |
573 Lisp_Object temp = list1 (Vdata_directory); | |
574 struct gcpro gcpro1; | |
575 | |
576 GCPRO1 (temp); | |
577 locate_file (temp, name, Qnil, &found, R_OK); | |
578 UNGCPRO; | |
579 } | |
580 | |
581 return found; | |
582 } | |
583 } | |
584 | |
585 static Lisp_Object | |
586 locate_pixmap_file (Lisp_Object name) | |
587 { | |
588 return gtk_locate_pixmap_file (name); | |
589 } | |
590 | |
591 | |
592 /************************************************************************/ | |
593 /* cursor functions */ | |
594 /************************************************************************/ | |
595 | |
596 /* Check that this server supports cursors of size WIDTH * HEIGHT. If | |
597 not, signal an error. INSTANTIATOR is only used in the error | |
598 message. */ | |
599 | |
600 static void | |
2286 | 601 check_pointer_sizes (unsigned int UNUSED (width), unsigned int UNUSED (height), |
602 Lisp_Object UNUSED (instantiator)) | |
462 | 603 { |
604 /* #### BILL!!! There is no way to call XQueryBestCursor from Gdk! */ | |
605 #if 0 | |
606 unsigned int best_width, best_height; | |
607 if (! XQueryBestCursor (DisplayOfScreen (xs), RootWindowOfScreen (xs), | |
608 width, height, &best_width, &best_height)) | |
609 /* this means that an X error of some sort occurred (we trap | |
610 these so they're not fatal). */ | |
563 | 611 gui_error ("XQueryBestCursor() failed?", instantiator); |
462 | 612 |
613 if (width > best_width || height > best_height) | |
563 | 614 signal_ferror_with_frob (Qgui_error, instantiator, |
615 "pointer too large (%dx%d): " | |
616 "server requires %dx%d or smaller", | |
617 width, height, best_width, best_height); | |
462 | 618 #endif |
619 } | |
620 | |
621 static void | |
622 generate_cursor_fg_bg (Lisp_Object device, Lisp_Object *foreground, | |
623 Lisp_Object *background, GdkColor *xfg, GdkColor *xbg) | |
624 { | |
625 if (!NILP (*foreground) && !COLOR_INSTANCEP (*foreground)) | |
626 *foreground = | |
627 Fmake_color_instance (*foreground, device, | |
628 encode_error_behavior_flag (ERROR_ME)); | |
629 if (COLOR_INSTANCEP (*foreground)) | |
630 *xfg = * COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (*foreground)); | |
631 else | |
632 { | |
633 xfg->pixel = 0; | |
634 xfg->red = xfg->green = xfg->blue = 0; | |
635 } | |
636 | |
637 if (!NILP (*background) && !COLOR_INSTANCEP (*background)) | |
638 *background = | |
639 Fmake_color_instance (*background, device, | |
640 encode_error_behavior_flag (ERROR_ME)); | |
641 if (COLOR_INSTANCEP (*background)) | |
642 *xbg = * COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (*background)); | |
643 else | |
644 { | |
645 xbg->pixel = 0; | |
646 xbg->red = xbg->green = xbg->blue = ~0; | |
647 } | |
648 } | |
649 | |
650 static void | |
2286 | 651 maybe_recolor_cursor (Lisp_Object UNUSED (image_instance), |
652 Lisp_Object UNUSED (foreground), | |
653 Lisp_Object UNUSED (background)) | |
462 | 654 { |
655 #if 0 | |
656 /* #### BILL!!! */ | |
657 Lisp_Object device = XIMAGE_INSTANCE_DEVICE (image_instance); | |
658 GdkColor xfg, xbg; | |
659 | |
660 generate_cursor_fg_bg (device, &foreground, &background, &xfg, &xbg); | |
661 if (!NILP (foreground) || !NILP (background)) | |
662 { | |
663 XRecolorCursor (DEVICE_X_DISPLAY (XDEVICE (device)), | |
664 XIMAGE_INSTANCE_GTK_CURSOR (image_instance), | |
665 &xfg, &xbg); | |
666 XIMAGE_INSTANCE_PIXMAP_FG (image_instance) = foreground; | |
667 XIMAGE_INSTANCE_PIXMAP_BG (image_instance) = background; | |
668 } | |
669 #else | |
670 /* stderr_out ("Don't know how to recolor cursors in Gtk!\n"); */ | |
671 #endif | |
672 } | |
673 | |
674 | |
675 /************************************************************************/ | |
676 /* color pixmap functions */ | |
677 /************************************************************************/ | |
678 | |
2959 | 679 /* Create a pointer from a color pixmap. */ |
680 | |
681 static void | |
682 image_instance_convert_to_pointer (Lisp_Image_Instance *ii, | |
683 Lisp_Object instantiator, | |
684 Lisp_Object pointer_fg, | |
685 Lisp_Object pointer_bg) | |
686 { | |
687 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); | |
3087 | 688 GdkPixmap *pixmap = IMAGE_INSTANCE_GTK_PIXMAP (ii); |
689 GdkPixmap *mask = (GdkPixmap *) IMAGE_INSTANCE_GTK_MASK (ii); | |
2959 | 690 GdkColor fg, bg; |
691 int xhot = 0, yhot = 0; | |
692 int w, h; | |
693 | |
694 if (INTP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii))) | |
695 xhot = XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii)); | |
696 if (INTP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii))) | |
697 yhot = XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii)); | |
698 w = IMAGE_INSTANCE_PIXMAP_WIDTH (ii); | |
699 h = IMAGE_INSTANCE_PIXMAP_HEIGHT (ii); | |
700 | |
701 check_pointer_sizes (w, h, instantiator); | |
702 | |
703 /* If the loaded pixmap has colors allocated (meaning it came from an | |
704 XPM file), then use those as the default colors for the cursor we | |
705 create. Otherwise, default to pointer_fg and pointer_bg. | |
706 */ | |
707 if (DEVICE_GTK_DEPTH (XDEVICE (device)) > 1) | |
708 { | |
709 warn_when_safe (Qunimplemented, Qnotice, | |
710 "GTK does not support XPM cursors...\n"); | |
711 IMAGE_INSTANCE_GTK_CURSOR (ii) = gdk_cursor_new (GDK_COFFEE_MUG); | |
712 } | |
713 else | |
714 { | |
715 generate_cursor_fg_bg (device, &pointer_fg, &pointer_bg, | |
716 &fg, &bg); | |
717 IMAGE_INSTANCE_PIXMAP_FG (ii) = pointer_fg; | |
718 IMAGE_INSTANCE_PIXMAP_BG (ii) = pointer_bg; | |
719 IMAGE_INSTANCE_GTK_CURSOR (ii) = | |
720 gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg, xhot, yhot); | |
721 } | |
722 } | |
723 | |
462 | 724 /* Initialize an image instance from an XImage. |
725 | |
726 DEST_MASK specifies the mask of allowed image types. | |
727 | |
728 PIXELS and NPIXELS specify an array of pixels that are used in | |
729 the image. These need to be kept around for the duration of the | |
730 image. When the image instance is freed, XFreeColors() will | |
731 automatically be called on all the pixels specified here; thus, | |
732 you should have allocated the pixels yourself using XAllocColor() | |
733 or the like. The array passed in is used directly without | |
734 being copied, so it should be heap data created with xmalloc(). | |
735 It will be freed using xfree() when the image instance is | |
736 destroyed. | |
737 | |
738 If this fails, signal an error. INSTANTIATOR is only used | |
739 in the error message. | |
740 | |
741 #### This should be able to handle conversion into `pointer'. | |
742 Use the same code as for `xpm'. */ | |
743 | |
744 static void | |
745 init_image_instance_from_gdk_image (struct Lisp_Image_Instance *ii, | |
746 GdkImage *gdk_image, | |
747 int dest_mask, | |
748 GdkColormap *cmap, | |
749 unsigned long *pixels, | |
750 int npixels, | |
751 int slices, | |
2959 | 752 Lisp_Object instantiator, |
753 Lisp_Object pointer_fg, | |
754 Lisp_Object pointer_bg) | |
462 | 755 { |
756 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); | |
757 GdkGC *gc; | |
758 GdkWindow *d; | |
759 GdkPixmap *pixmap; | |
2959 | 760 enum image_instance_type type; |
462 | 761 |
762 if (!DEVICE_GTK_P (XDEVICE (device))) | |
563 | 763 gui_error ("Not a Gtk device", device); |
462 | 764 |
765 d = GET_GTK_WIDGET_WINDOW (DEVICE_GTK_APP_SHELL (XDEVICE (device))); | |
766 | |
2959 | 767 if (dest_mask & IMAGE_COLOR_PIXMAP_MASK) |
768 type = IMAGE_COLOR_PIXMAP; | |
769 else if (dest_mask & IMAGE_POINTER_MASK) | |
770 type = IMAGE_POINTER; | |
771 else | |
462 | 772 incompatible_image_types (instantiator, dest_mask, |
2959 | 773 IMAGE_COLOR_PIXMAP_MASK |
774 | IMAGE_POINTER_MASK); | |
462 | 775 |
776 pixmap = gdk_pixmap_new (d, gdk_image->width, gdk_image->height, gdk_image->depth); | |
777 if (!pixmap) | |
563 | 778 gui_error ("Unable to create pixmap", instantiator); |
462 | 779 |
780 gc = gdk_gc_new (pixmap); | |
781 if (!gc) | |
782 { | |
783 gdk_pixmap_unref (pixmap); | |
563 | 784 gui_error ("Unable to create GC", instantiator); |
462 | 785 } |
786 | |
787 gdk_draw_image (GDK_DRAWABLE (pixmap), gc, gdk_image, | |
788 0, 0, 0, 0, gdk_image->width, gdk_image->height); | |
789 | |
790 gdk_gc_destroy (gc); | |
791 | |
792 gtk_initialize_pixmap_image_instance (ii, slices, IMAGE_COLOR_PIXMAP); | |
793 | |
794 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = | |
795 find_keyword_in_vector (instantiator, Q_file); | |
796 | |
797 IMAGE_INSTANCE_GTK_PIXMAP (ii) = pixmap; | |
4433
1bf48c59700e
Fix old use of rvalue on lhs to placate gcc >4.0.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4252
diff
changeset
|
798 IMAGE_INSTANCE_PIXMAP_MASK (ii) = 0; |
462 | 799 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = gdk_image->width; |
800 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = gdk_image->height; | |
801 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = gdk_image->depth; | |
802 IMAGE_INSTANCE_GTK_COLORMAP (ii) = cmap; | |
803 IMAGE_INSTANCE_GTK_PIXELS (ii) = pixels; | |
804 IMAGE_INSTANCE_GTK_NPIXELS (ii) = npixels; | |
2959 | 805 |
806 if (type == IMAGE_POINTER) | |
807 image_instance_convert_to_pointer (ii, instantiator, pointer_fg, | |
808 pointer_bg); | |
462 | 809 } |
810 | |
811 #if 0 | |
812 void init_image_instance_from_gdk_pixmap (struct Lisp_Image_Instance *ii, | |
813 struct device *device, | |
814 GdkPixmap *gdk_pixmap, | |
815 int dest_mask, | |
816 Lisp_Object instantiator) | |
817 { | |
818 GdkWindow *d; | |
819 gint width, height, depth; | |
820 | |
5050
6f2158fa75ed
Fix quick-build, use asserts() in place of ABORT()
Ben Wing <ben@xemacs.org>
parents:
4982
diff
changeset
|
821 assert (DEVICE_GTK_P (device)); |
462 | 822 |
823 IMAGE_INSTANCE_DEVICE (ii) = device; | |
824 IMAGE_INSTANCE_TYPE (ii) = IMAGE_COLOR_PIXMAP; | |
825 | |
826 d = GET_GTK_WIDGET_WINDOW (DEVICE_GTK_APP_SHELL (device)); | |
827 | |
828 if (!(dest_mask & IMAGE_COLOR_PIXMAP_MASK)) | |
829 incompatible_image_types (instantiator, dest_mask, | |
830 IMAGE_COLOR_PIXMAP_MASK); | |
831 | |
832 gtk_initialize_pixmap_image_instance (ii, IMAGE_COLOR_PIXMAP); | |
833 | |
834 gdk_window_get_geometry (gdk_pixmap, NULL, NULL, &width, &height, &depth); | |
835 | |
836 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil; | |
837 IMAGE_INSTANCE_GTK_PIXMAP (ii) = gdk_pixmap; | |
4629
a1dd514df5c6
Apply the 2008-03-05 change from Dominique Quatravaux in init_image_instance_from_gdk_pixmap as well even though the code is not enabled at the moment
"Ville Skyttä <scop@xemacs.org>"
parents:
4433
diff
changeset
|
838 IMAGE_INSTANCE_PIXMAP_MASK (ii) = 0; |
462 | 839 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = width; |
840 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = height; | |
841 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = depth; | |
842 IMAGE_INSTANCE_GTK_COLORMAP (ii) = gdk_window_get_colormap (gdk_pixmap); | |
843 IMAGE_INSTANCE_GTK_PIXELS (ii) = 0; | |
844 IMAGE_INSTANCE_GTK_NPIXELS (ii) = 0; | |
845 } | |
846 #endif | |
847 | |
848 static void | |
849 image_instance_add_gdk_image (Lisp_Image_Instance *ii, | |
850 GdkImage *gdk_image, | |
851 int slice, | |
852 Lisp_Object instantiator) | |
853 { | |
854 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); | |
855 GdkWindow *d; | |
856 GdkPixmap *pixmap; | |
857 GdkGC *gc; | |
858 | |
859 d = GET_GTK_WIDGET_WINDOW (DEVICE_GTK_APP_SHELL (XDEVICE (device))); | |
860 | |
861 pixmap = gdk_pixmap_new (d, gdk_image->width, gdk_image->height, gdk_image->depth); | |
862 | |
863 if (!pixmap) | |
563 | 864 gui_error ("Unable to create pixmap", instantiator); |
462 | 865 |
866 gc = gdk_gc_new (pixmap); | |
867 | |
868 if (!gc) | |
869 { | |
870 gdk_pixmap_unref (pixmap); | |
563 | 871 gui_error ("Unable to create GC", instantiator); |
462 | 872 } |
873 | |
874 gdk_draw_image (GDK_DRAWABLE (pixmap), gc, gdk_image, 0, 0, 0, 0, | |
875 gdk_image->width, gdk_image->height); | |
876 | |
877 gdk_gc_destroy (gc); | |
878 | |
879 IMAGE_INSTANCE_GTK_PIXMAP_SLICE (ii, slice) = pixmap; | |
880 } | |
881 | |
882 static void | |
883 gtk_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii, | |
884 int width, int height, | |
885 int slices, | |
4252 | 886 unsigned char *eimage, |
462 | 887 int dest_mask, |
888 Lisp_Object instantiator, | |
2959 | 889 Lisp_Object pointer_fg, |
890 Lisp_Object pointer_bg, | |
2286 | 891 Lisp_Object UNUSED (domain)) |
462 | 892 { |
893 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); | |
894 GdkColormap *cmap = DEVICE_GTK_COLORMAP (XDEVICE(device)); | |
895 unsigned long *pixtbl = NULL; | |
896 int npixels = 0; | |
897 int slice; | |
898 GdkImage* gdk_image; | |
899 | |
900 | |
901 for (slice = 0; slice < slices; slice++) | |
902 { | |
903 gdk_image = convert_EImage_to_GDKImage (device, width, height, eimage, | |
904 &pixtbl, &npixels); | |
905 if (!gdk_image) | |
906 { | |
1726 | 907 if (pixtbl) |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
908 xfree (pixtbl); |
462 | 909 signal_image_error("EImage to GdkImage conversion failed", instantiator); |
910 } | |
911 | |
912 if (slice == 0) | |
913 /* Now create the pixmap and set up the image instance */ | |
914 init_image_instance_from_gdk_image (ii, gdk_image, dest_mask, | |
915 cmap, pixtbl, npixels, slices, | |
2959 | 916 instantiator, pointer_fg, |
917 pointer_bg); | |
462 | 918 else |
919 image_instance_add_gdk_image (ii, gdk_image, slice, instantiator); | |
920 | |
921 if (gdk_image) | |
922 { | |
923 gdk_image_destroy (gdk_image); | |
924 } | |
925 gdk_image = 0; | |
926 } | |
927 } | |
928 | |
929 /* Given inline data for a mono pixmap, create and return the | |
930 corresponding X object. */ | |
931 | |
932 static GdkPixmap * | |
933 pixmap_from_xbm_inline (Lisp_Object device, int width, int height, | |
934 /* Note that data is in ext-format! */ | |
771 | 935 const Extbyte *bits) |
462 | 936 { |
937 return (gdk_bitmap_create_from_data (GET_GTK_WIDGET_WINDOW (DEVICE_GTK_APP_SHELL (XDEVICE (device))), | |
938 (char *) bits, width, height)); | |
939 } | |
940 | |
941 /* Given inline data for a mono pixmap, initialize the given | |
942 image instance accordingly. */ | |
943 | |
944 static void | |
945 init_image_instance_from_xbm_inline (struct Lisp_Image_Instance *ii, | |
946 int width, int height, | |
947 /* Note that data is in ext-format! */ | |
771 | 948 const char *bits, |
462 | 949 Lisp_Object instantiator, |
950 Lisp_Object pointer_fg, | |
951 Lisp_Object pointer_bg, | |
952 int dest_mask, | |
953 GdkPixmap *mask, | |
2286 | 954 Lisp_Object UNUSED (mask_filename)) |
462 | 955 { |
956 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); | |
957 Lisp_Object foreground = find_keyword_in_vector (instantiator, Q_foreground); | |
958 Lisp_Object background = find_keyword_in_vector (instantiator, Q_background); | |
959 GdkColor fg; | |
960 GdkColor bg; | |
961 enum image_instance_type type; | |
962 GdkWindow *draw = GET_GTK_WIDGET_WINDOW (DEVICE_GTK_APP_SHELL (XDEVICE (device))); | |
963 GdkColormap *cmap = DEVICE_GTK_COLORMAP (XDEVICE(device)); | |
964 GdkColor black; | |
965 GdkColor white; | |
966 | |
967 gdk_color_black(cmap, &black); | |
968 gdk_color_white(cmap, &white); | |
969 | |
970 if (!DEVICE_GTK_P (XDEVICE (device))) | |
563 | 971 gui_error ("Not a Gtk device", device); |
462 | 972 |
973 if ((dest_mask & IMAGE_MONO_PIXMAP_MASK) && | |
974 (dest_mask & IMAGE_COLOR_PIXMAP_MASK)) | |
975 { | |
976 if (!NILP (foreground) || !NILP (background)) | |
977 type = IMAGE_COLOR_PIXMAP; | |
978 else | |
979 type = IMAGE_MONO_PIXMAP; | |
980 } | |
981 else if (dest_mask & IMAGE_MONO_PIXMAP_MASK) | |
982 type = IMAGE_MONO_PIXMAP; | |
983 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK) | |
984 type = IMAGE_COLOR_PIXMAP; | |
985 else if (dest_mask & IMAGE_POINTER_MASK) | |
986 type = IMAGE_POINTER; | |
987 else | |
988 incompatible_image_types (instantiator, dest_mask, | |
989 IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK | |
990 | IMAGE_POINTER_MASK); | |
991 | |
992 gtk_initialize_pixmap_image_instance (ii, 1, type); | |
993 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = width; | |
994 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = height; | |
995 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = | |
996 find_keyword_in_vector (instantiator, Q_file); | |
997 | |
998 switch (type) | |
999 { | |
1000 case IMAGE_MONO_PIXMAP: | |
1001 { | |
1002 IMAGE_INSTANCE_GTK_PIXMAP (ii) = | |
1003 pixmap_from_xbm_inline (device, width, height, (Extbyte *) bits); | |
1004 } | |
1005 break; | |
1006 | |
1007 case IMAGE_COLOR_PIXMAP: | |
1008 { | |
1009 gint d = DEVICE_GTK_DEPTH (XDEVICE(device)); | |
1010 | |
1011 if (!NILP (foreground) && !COLOR_INSTANCEP (foreground)) | |
1012 foreground = | |
1013 Fmake_color_instance (foreground, device, | |
1014 encode_error_behavior_flag (ERROR_ME)); | |
1015 | |
1016 if (COLOR_INSTANCEP (foreground)) | |
1017 fg = * COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (foreground)); | |
1018 | |
1019 if (!NILP (background) && !COLOR_INSTANCEP (background)) | |
1020 background = | |
1021 Fmake_color_instance (background, device, | |
1022 encode_error_behavior_flag (ERROR_ME)); | |
1023 | |
1024 if (COLOR_INSTANCEP (background)) | |
1025 bg = * COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (background)); | |
1026 | |
1027 /* We used to duplicate the pixels using XAllocColor(), to protect | |
1028 against their getting freed. Just as easy to just store the | |
1029 color instances here and GC-protect them, so this doesn't | |
1030 happen. */ | |
1031 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground; | |
1032 IMAGE_INSTANCE_PIXMAP_BG (ii) = background; | |
1033 IMAGE_INSTANCE_GTK_PIXMAP (ii) = | |
1034 gdk_pixmap_create_from_data (draw, (char *) bits, width, height, d, &fg, &bg); | |
1035 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = d; | |
1036 } | |
1037 break; | |
1038 | |
1039 case IMAGE_POINTER: | |
1040 { | |
1041 GdkColor fg_color, bg_color; | |
1042 GdkPixmap *source; | |
1043 | |
1044 check_pointer_sizes (width, height, instantiator); | |
1045 | |
1046 source = gdk_pixmap_create_from_data (draw, (char *) bits, width, height, 1, &black, &white); | |
1047 | |
1048 if (NILP (foreground)) | |
1049 foreground = pointer_fg; | |
1050 if (NILP (background)) | |
1051 background = pointer_bg; | |
1052 generate_cursor_fg_bg (device, &foreground, &background, | |
1053 &fg_color, &bg_color); | |
1054 | |
1055 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground; | |
1056 IMAGE_INSTANCE_PIXMAP_BG (ii) = background; | |
1057 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = | |
1058 find_keyword_in_vector (instantiator, Q_hotspot_x); | |
1059 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = | |
1060 find_keyword_in_vector (instantiator, Q_hotspot_y); | |
1061 IMAGE_INSTANCE_GTK_CURSOR (ii) = | |
1062 gdk_cursor_new_from_pixmap (source, mask, &fg_color, &bg_color, | |
1063 !NILP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii)) ? | |
1064 XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii)) : 0, | |
1065 !NILP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii)) ? | |
1066 XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii)) : 0); | |
1067 } | |
1068 break; | |
1069 | |
1070 default: | |
2500 | 1071 ABORT (); |
462 | 1072 } |
1073 } | |
1074 | |
1075 static void | |
1076 xbm_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator, | |
1077 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
1078 int dest_mask, int width, int height, | |
1079 /* Note that data is in ext-format! */ | |
771 | 1080 const char *bits) |
462 | 1081 { |
1082 Lisp_Object mask_data = find_keyword_in_vector (instantiator, Q_mask_data); | |
1083 Lisp_Object mask_file = find_keyword_in_vector (instantiator, Q_mask_file); | |
1084 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
1085 GdkPixmap *mask = 0; | |
2054 | 1086 const Extbyte *gcc_may_you_rot_in_hell; |
462 | 1087 |
1088 if (!NILP (mask_data)) | |
1089 { | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
1090 gcc_may_you_rot_in_hell = |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
1091 LISP_STRING_TO_EXTERNAL (XCAR (XCDR (XCDR (mask_data))), |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
1092 Qfile_name); |
462 | 1093 mask = |
1094 pixmap_from_xbm_inline (IMAGE_INSTANCE_DEVICE (ii), | |
1095 XINT (XCAR (mask_data)), | |
1096 XINT (XCAR (XCDR (mask_data))), | |
1097 gcc_may_you_rot_in_hell); | |
1098 } | |
1099 | |
1100 init_image_instance_from_xbm_inline (ii, width, height, bits, | |
1101 instantiator, pointer_fg, pointer_bg, | |
1102 dest_mask, mask, mask_file); | |
1103 } | |
1104 | |
1105 /* Instantiate method for XBM's. */ | |
1106 | |
1107 static void | |
1108 gtk_xbm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
1109 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
2286 | 1110 int dest_mask, Lisp_Object UNUSED (domain)) |
462 | 1111 { |
1112 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
771 | 1113 const char *gcc_go_home; |
462 | 1114 |
1115 assert (!NILP (data)); | |
1116 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
1117 gcc_go_home = LISP_STRING_TO_EXTERNAL (XCAR (XCDR (XCDR (data))), Qbinary); |
462 | 1118 |
1119 xbm_instantiate_1 (image_instance, instantiator, pointer_fg, | |
1120 pointer_bg, dest_mask, XINT (XCAR (data)), | |
1121 XINT (XCAR (XCDR (data))), gcc_go_home); | |
1122 } | |
1123 | |
1124 | |
1125 #ifdef HAVE_XPM | |
1126 /********************************************************************** | |
1127 * XPM * | |
1128 **********************************************************************/ | |
1129 | |
739 | 1130 struct color_symbol |
1131 { | |
2054 | 1132 Ibyte* name; |
739 | 1133 GdkColor color; |
1134 }; | |
1135 | |
1136 static struct color_symbol* | |
1137 extract_xpm_color_names (Lisp_Object device, | |
1138 Lisp_Object domain, | |
1139 Lisp_Object color_symbol_alist, | |
1140 int* nsymbols) | |
1141 { | |
1142 /* This function can GC */ | |
1143 Lisp_Object rest; | |
1144 Lisp_Object results = Qnil; | |
1145 int i, j; | |
1146 struct color_symbol *colortbl; | |
1147 struct gcpro gcpro1, gcpro2; | |
1148 | |
1149 GCPRO2 (results, device); | |
1150 | |
1151 /* We built up results to be (("name" . #<color>) ...) so that if an | |
1152 error happens we don't lose any malloc()ed data, or more importantly, | |
1153 leave any pixels allocated in the server. */ | |
1154 i = 0; | |
1155 LIST_LOOP (rest, color_symbol_alist) | |
1156 { | |
1157 Lisp_Object cons = XCAR (rest); | |
1158 Lisp_Object name = XCAR (cons); | |
1159 Lisp_Object value = XCDR (cons); | |
1160 if (NILP (value)) | |
1161 continue; | |
1162 if (STRINGP (value)) | |
1163 value = | |
1164 Fmake_color_instance | |
793 | 1165 (value, device, encode_error_behavior_flag (ERROR_ME_DEBUG_WARN)); |
739 | 1166 else |
4252 | 1167 { |
1168 assert (COLOR_SPECIFIERP (value)); | |
1169 value = Fspecifier_instance (value, domain, Qnil, Qnil); | |
1170 } | |
739 | 1171 |
1172 if (NILP (value)) | |
4252 | 1173 continue; |
739 | 1174 results = noseeum_cons (noseeum_cons (name, value), results); |
1175 i++; | |
1176 } | |
1177 UNGCPRO; /* no more evaluation */ | |
1178 | |
1179 *nsymbols=i; | |
1180 if (i == 0) return 0; | |
1181 | |
1182 colortbl = xnew_array_and_zero (struct color_symbol, i); | |
1183 | |
1184 for (j=0; j<i; j++) | |
1185 { | |
1186 Lisp_Object cons = XCAR (results); | |
4252 | 1187 colortbl[j].color = |
739 | 1188 * COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (XCDR (cons))); |
1189 | |
2054 | 1190 colortbl[j].name = XSTRING_DATA (XCAR (cons)); |
1191 free_cons (cons); | |
739 | 1192 cons = results; |
1193 results = XCDR (results); | |
2054 | 1194 free_cons (cons); |
739 | 1195 } |
1196 return colortbl; | |
1197 } | |
1198 | |
462 | 1199 static void |
739 | 1200 gtk_xpm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, |
462 | 1201 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
1202 int dest_mask, Lisp_Object domain) | |
1203 { | |
1204 /* This function can GC */ | |
1205 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
1206 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); | |
1207 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
1208 GdkColormap *cmap; | |
1209 int depth; | |
1210 GdkVisual *visual; | |
1211 GdkPixmap *pixmap; | |
1212 GdkPixmap *mask = 0; | |
1213 GdkWindow *window = 0; | |
739 | 1214 int nsymbols = 0, i = 0; |
1215 struct color_symbol *color_symbols = NULL; | |
462 | 1216 Lisp_Object color_symbol_alist = find_keyword_in_vector (instantiator, |
1217 Q_color_symbols); | |
1218 enum image_instance_type type; | |
1219 int force_mono; | |
2054 | 1220 gint w, h; |
2082 | 1221 struct gcpro gcpro1, gcpro2, gcpro3; |
2367 | 1222 const Binbyte * volatile dstring; |
462 | 1223 |
1224 if (!DEVICE_GTK_P (XDEVICE (device))) | |
563 | 1225 gui_error ("Not a Gtk device", device); |
462 | 1226 |
1227 if (dest_mask & IMAGE_COLOR_PIXMAP_MASK) | |
1228 type = IMAGE_COLOR_PIXMAP; | |
1229 else if (dest_mask & IMAGE_MONO_PIXMAP_MASK) | |
1230 type = IMAGE_MONO_PIXMAP; | |
1231 else if (dest_mask & IMAGE_POINTER_MASK) | |
1232 type = IMAGE_POINTER; | |
1233 else | |
1234 incompatible_image_types (instantiator, dest_mask, | |
1235 IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK | |
1236 | IMAGE_POINTER_MASK); | |
1237 force_mono = (type != IMAGE_COLOR_PIXMAP); | |
1238 | |
2082 | 1239 GCPRO3 (device, data, color_symbol_alist); |
771 | 1240 |
462 | 1241 window = GET_GTK_WIDGET_WINDOW (DEVICE_GTK_APP_SHELL (XDEVICE (device))); |
1242 cmap = DEVICE_GTK_COLORMAP (XDEVICE (device)); | |
1243 depth = DEVICE_GTK_DEPTH (XDEVICE (device)); | |
1244 visual = DEVICE_GTK_VISUAL (XDEVICE (device)); | |
1245 | |
1246 gtk_initialize_pixmap_image_instance (ii, 1, type); | |
1247 | |
1248 assert (!NILP (data)); | |
1249 | |
2082 | 1250 /* Extract all the entries from xpm-color-symbols */ |
771 | 1251 color_symbols = extract_xpm_color_names (device, domain, color_symbol_alist, |
1252 &nsymbols); | |
2082 | 1253 assert (!NILP (data)); |
1254 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
1255 dstring = LISP_STRING_TO_EXTERNAL (data, Qbinary); |
2082 | 1256 |
1257 /* | |
1258 * GTK only uses the 'c' color entry of an XPM and doesn't use the symbolic | |
1259 * color names at all. This is unfortunate because the way to change the | |
1260 * colors from lisp is by adding the symbolic names, and the new colors, to | |
1261 * the variable xpm-color-symbols. | |
1262 * | |
1263 * To get around this decode the XPM, add a 'c' entry of the desired color | |
1264 * for each matching symbolic color, recode the XPM and pass it to GTK. The | |
1265 * decode and recode stages aren't too bad because this also performs the | |
1266 * external to internal format translation, which avoids contortions like | |
1267 * writing the XPM back to disk in order to get it processed. | |
1268 */ | |
771 | 1269 { |
2082 | 1270 XpmImage image; |
1271 XpmInfo info; | |
1272 char** data; | |
1273 | |
1274 XpmCreateXpmImageFromBuffer ((char*) dstring, &image, &info); | |
1275 | |
1276 for (i = 0; i < nsymbols; i++) | |
1277 { | |
1278 unsigned j; | |
1279 | |
1280 for (j = 0; j < image.ncolors; j++) | |
1281 { | |
1282 if (image.colorTable[j].symbolic != NULL && | |
2367 | 1283 !qxestrcasecmp_ascii(color_symbols[i].name, image.colorTable[j].symbolic)) |
2082 | 1284 { |
2367 | 1285 image.colorTable[j].c_color = xnew_ascbytes (16); |
2082 | 1286 |
1287 sprintf(image.colorTable[j].c_color, "#%.4x%.4x%.4x", | |
1288 color_symbols[i].color.red, color_symbols[i].color.green, | |
1289 color_symbols[i].color.blue); | |
1290 } | |
1291 } | |
1292 } | |
1293 | |
1294 XpmCreateDataFromXpmImage (&data, &image, &info); | |
1295 | |
1296 pixmap = gdk_pixmap_create_from_xpm_d (window, &mask, NULL, | |
1297 data); | |
771 | 1298 } |
462 | 1299 |
1726 | 1300 if (color_symbols) |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
1301 xfree (color_symbols); |
739 | 1302 |
462 | 1303 if (!pixmap) |
1304 signal_image_error ("Error reading pixmap", data); | |
1305 | |
1306 gdk_window_get_geometry (pixmap, NULL, NULL, &w, &h, &depth); | |
1307 | |
1308 IMAGE_INSTANCE_GTK_PIXMAP (ii) = pixmap; | |
3087 | 1309 IMAGE_INSTANCE_PIXMAP_MASK (ii) = mask; |
462 | 1310 IMAGE_INSTANCE_GTK_COLORMAP (ii) = cmap; |
1311 IMAGE_INSTANCE_GTK_PIXELS (ii) = 0; | |
1312 IMAGE_INSTANCE_GTK_NPIXELS (ii) = 0; | |
1313 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = w; | |
1314 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = h; | |
1315 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = | |
1316 find_keyword_in_vector (instantiator, Q_file); | |
1317 | |
1318 switch (type) | |
1319 { | |
1320 case IMAGE_MONO_PIXMAP: | |
1321 break; | |
1322 | |
1323 case IMAGE_COLOR_PIXMAP: | |
771 | 1324 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = depth; |
462 | 1325 break; |
1326 | |
1327 case IMAGE_POINTER: | |
4700
ef70ee47d287
Image instantiator pixmap hotspots are Lisp integers; make it so in GTK.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4629
diff
changeset
|
1328 /* #### Gtk does not give us access to the hotspots of a pixmap */ |
ef70ee47d287
Image instantiator pixmap hotspots are Lisp integers; make it so in GTK.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4629
diff
changeset
|
1329 |
ef70ee47d287
Image instantiator pixmap hotspots are Lisp integers; make it so in GTK.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4629
diff
changeset
|
1330 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = make_int(1); |
ef70ee47d287
Image instantiator pixmap hotspots are Lisp integers; make it so in GTK.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4629
diff
changeset
|
1331 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = make_int(1); |
3087 | 1332 |
4252 | 1333 |
2959 | 1334 image_instance_convert_to_pointer (ii, instantiator, pointer_fg, |
1335 pointer_bg); | |
462 | 1336 break; |
1337 | |
1338 default: | |
2500 | 1339 ABORT (); |
462 | 1340 } |
771 | 1341 |
1342 UNGCPRO; | |
462 | 1343 } |
1344 #endif /* HAVE_XPM */ | |
1345 | |
1346 | |
1347 #ifdef HAVE_XFACE | |
1348 | |
1349 /********************************************************************** | |
1350 * X-Face * | |
1351 **********************************************************************/ | |
1352 #if defined(EXTERN) | |
1353 /* This is about to get redefined! */ | |
1354 #undef EXTERN | |
1355 #endif | |
1356 /* We have to define SYSV32 so that compface.h includes string.h | |
1357 instead of strings.h. */ | |
1358 #define SYSV32 | |
1743 | 1359 BEGIN_C_DECLS |
462 | 1360 #include <compface.h> |
1743 | 1361 END_C_DECLS |
1362 | |
462 | 1363 /* JMP_BUF cannot be used here because if it doesn't get defined |
1364 to jmp_buf we end up with a conflicting type error with the | |
1365 definition in compface.h */ | |
1366 extern jmp_buf comp_env; | |
1367 #undef SYSV32 | |
1368 | |
1369 static void | |
1370 gtk_xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
2286 | 1371 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
1372 int dest_mask, Lisp_Object UNUSED (domain)) | |
462 | 1373 { |
1374 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
1375 int i, stattis; | |
1376 char *p, *bits, *bp; | |
771 | 1377 const char * volatile emsg = 0; |
1378 const char * volatile dstring; | |
462 | 1379 |
1380 assert (!NILP (data)); | |
1381 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
1382 dstring = LISP_STRING_TO_EXTERNAL (data, Qbinary); |
462 | 1383 |
1384 if ((p = strchr (dstring, ':'))) | |
1385 { | |
1386 dstring = p + 1; | |
1387 } | |
1388 | |
1389 /* Must use setjmp not SETJMP because we used jmp_buf above not JMP_BUF */ | |
1390 if (!(stattis = setjmp (comp_env))) | |
1391 { | |
1392 UnCompAll ((char *) dstring); | |
1393 UnGenFace (); | |
1394 } | |
1395 | |
1396 switch (stattis) | |
1397 { | |
1398 case -2: | |
1399 emsg = "uncompface: internal error"; | |
1400 break; | |
1401 case -1: | |
1402 emsg = "uncompface: insufficient or invalid data"; | |
1403 break; | |
1404 case 1: | |
1405 emsg = "uncompface: excess data ignored"; | |
1406 break; | |
1407 } | |
1408 | |
1409 if (emsg) | |
563 | 1410 gui_error_2 (emsg, data, Qimage); |
462 | 1411 |
851 | 1412 bp = bits = (char *) ALLOCA (PIXELS / 8); |
462 | 1413 |
1414 /* the compface library exports char F[], which uses a single byte per | |
1415 pixel to represent a 48x48 bitmap. Yuck. */ | |
1416 for (i = 0, p = F; i < (PIXELS / 8); ++i) | |
1417 { | |
1418 int n, b; | |
1419 /* reverse the bit order of each byte... */ | |
1420 for (b = n = 0; b < 8; ++b) | |
1421 { | |
1422 n |= ((*p++) << b); | |
1423 } | |
1424 *bp++ = (char) n; | |
1425 } | |
1426 | |
1427 xbm_instantiate_1 (image_instance, instantiator, pointer_fg, | |
1428 pointer_bg, dest_mask, 48, 48, bits); | |
1429 } | |
1430 | |
1431 #endif /* HAVE_XFACE */ | |
1432 | |
1433 /********************************************************************** | |
1434 * RESOURCES * | |
1435 **********************************************************************/ | |
1436 | |
1437 static void | |
1438 gtk_resource_validate (Lisp_Object instantiator) | |
1439 { | |
4252 | 1440 if ((NILP (find_keyword_in_vector (instantiator, Q_file)) |
462 | 1441 && |
4252 | 1442 NILP (find_keyword_in_vector (instantiator, Q_resource_id))) |
462 | 1443 || |
1444 NILP (find_keyword_in_vector (instantiator, Q_resource_type))) | |
563 | 1445 sferror ("Must supply :file, :resource-id and :resource-type", |
462 | 1446 instantiator); |
1447 } | |
1448 | |
1449 static Lisp_Object | |
563 | 1450 gtk_resource_normalize (Lisp_Object inst, Lisp_Object console_type, |
1451 Lisp_Object dest_mask) | |
462 | 1452 { |
563 | 1453 return shared_resource_normalize (inst, console_type, dest_mask, |
1454 Qgtk_resource); | |
462 | 1455 } |
1456 | |
1457 static int | |
1458 gtk_resource_possible_dest_types (void) | |
1459 { | |
1460 return IMAGE_POINTER_MASK | IMAGE_COLOR_PIXMAP_MASK; | |
1461 } | |
1462 | |
1463 extern guint symbol_to_enum (Lisp_Object, GtkType); | |
1464 | |
2272 | 1465 static guint resource_name_to_resource (Lisp_Object name, |
1466 enum image_instance_type type) | |
462 | 1467 { |
1468 if (type == IMAGE_POINTER) | |
1469 return (symbol_to_enum (name, GTK_TYPE_GDK_CURSOR_TYPE)); | |
1470 else | |
1471 return (0); | |
1472 } | |
1473 | |
2272 | 1474 static enum image_instance_type |
462 | 1475 resource_symbol_to_type (Lisp_Object data) |
1476 { | |
1477 if (EQ (data, Qcursor)) | |
1478 return IMAGE_POINTER; | |
1479 #if 0 | |
1480 else if (EQ (data, Qicon)) | |
1481 return IMAGE_ICON; | |
1482 else if (EQ (data, Qbitmap)) | |
1483 return IMAGE_BITMAP; | |
1484 #endif | |
1485 else | |
2054 | 1486 return IMAGE_UNKNOWN; |
462 | 1487 } |
1488 | |
1489 static void | |
1490 gtk_resource_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
2286 | 1491 Lisp_Object UNUSED (pointer_fg), |
1492 Lisp_Object UNUSED (pointer_bg), | |
1493 int UNUSED (dest_mask), Lisp_Object UNUSED (domain)) | |
462 | 1494 { |
1495 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
1496 GdkCursor *c = NULL; | |
2272 | 1497 enum image_instance_type type; |
462 | 1498 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); |
1499 Lisp_Object resource_type = find_keyword_in_vector (instantiator, Q_resource_type); | |
1500 Lisp_Object resource_id = find_keyword_in_vector (instantiator, Q_resource_id); | |
1501 | |
1502 if (!DEVICE_GTK_P (XDEVICE (device))) | |
563 | 1503 gui_error ("Not a GTK device", device); |
462 | 1504 |
1505 type = resource_symbol_to_type (resource_type); | |
1506 | |
595 | 1507 #if 0 |
1508 if (dest_mask & IMAGE_POINTER_MASK && type == IMAGE_POINTER_MASK) | |
1509 iitype = IMAGE_POINTER; | |
1510 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK) | |
1511 iitype = IMAGE_COLOR_PIXMAP; | |
4252 | 1512 else |
595 | 1513 incompatible_image_types (instantiator, dest_mask, |
4252 | 1514 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK); |
595 | 1515 #endif |
4252 | 1516 |
462 | 1517 /* mess with the keyword info we were provided with */ |
1518 gtk_initialize_pixmap_image_instance (ii, 1, type); | |
2054 | 1519 c = gdk_cursor_new ((GdkCursorType) resource_name_to_resource (resource_id, type)); |
462 | 1520 IMAGE_INSTANCE_GTK_CURSOR (ii) = c; |
1521 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = resource_id; | |
1522 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = 10; | |
1523 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = 10; | |
1524 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1; | |
1525 } | |
1526 | |
1527 static void | |
1528 check_valid_resource_symbol (Lisp_Object data) | |
1529 { | |
1530 CHECK_SYMBOL (data); | |
1531 if (!resource_symbol_to_type (data)) | |
563 | 1532 invalid_constant ("invalid resource type", data); |
462 | 1533 } |
1534 | |
1535 static void | |
1536 check_valid_resource_id (Lisp_Object data) | |
1537 { | |
1538 if (!resource_name_to_resource (data, IMAGE_POINTER) | |
1539 && | |
1540 !resource_name_to_resource (data, IMAGE_COLOR_PIXMAP) | |
1541 #if 0 | |
1542 && | |
1543 !resource_name_to_resource (data, IMAGE_BITMAP) | |
1544 #endif | |
1545 ) | |
563 | 1546 invalid_constant ("invalid resource identifier", data); |
462 | 1547 } |
1548 | |
1549 #if 0 | |
1550 void | |
1551 check_valid_string_or_int (Lisp_Object data) | |
1552 { | |
1553 if (!INTP (data)) | |
1554 CHECK_STRING (data); | |
1555 else | |
1556 CHECK_INT (data); | |
1557 } | |
1558 #endif | |
1559 | |
1560 | |
1561 /********************************************************************** | |
1562 * Autodetect * | |
1563 **********************************************************************/ | |
1564 | |
1565 static void | |
1566 autodetect_validate (Lisp_Object instantiator) | |
1567 { | |
1568 data_must_be_present (instantiator); | |
1569 } | |
1570 | |
1571 static Lisp_Object | |
1572 autodetect_normalize (Lisp_Object instantiator, | |
1573 Lisp_Object console_type, | |
2286 | 1574 Lisp_Object UNUSED (dest_mask)) |
462 | 1575 { |
1576 Lisp_Object file = find_keyword_in_vector (instantiator, Q_data); | |
1577 Lisp_Object filename = Qnil; | |
1578 Lisp_Object data = Qnil; | |
1579 struct gcpro gcpro1, gcpro2, gcpro3; | |
1580 Lisp_Object alist = Qnil; | |
1581 | |
1582 GCPRO3 (filename, data, alist); | |
1583 | |
1584 if (NILP (file)) /* no conversion necessary */ | |
1585 RETURN_UNGCPRO (instantiator); | |
1586 | |
1587 alist = tagged_vector_to_alist (instantiator); | |
1588 | |
1589 filename = locate_pixmap_file (file); | |
1590 if (!NILP (filename)) | |
1591 { | |
1592 int xhot, yhot; | |
1593 /* #### Apparently some versions of XpmReadFileToData, which is | |
1594 called by pixmap_to_lisp_data, don't return an error value | |
1595 if the given file is not a valid XPM file. Instead, they | |
1596 just seg fault. It is definitely caused by passing a | |
1597 bitmap. To try and avoid this we check for bitmaps first. */ | |
1598 | |
1599 data = bitmap_to_lisp_data (filename, &xhot, &yhot, 1); | |
1600 | |
1601 if (!EQ (data, Qt)) | |
1602 { | |
1603 alist = remassq_no_quit (Q_data, alist); | |
1604 alist = Fcons (Fcons (Q_file, filename), | |
1605 Fcons (Fcons (Q_data, data), alist)); | |
1606 if (xhot != -1) | |
1607 alist = Fcons (Fcons (Q_hotspot_x, make_int (xhot)), | |
1608 alist); | |
1609 if (yhot != -1) | |
1610 alist = Fcons (Fcons (Q_hotspot_y, make_int (yhot)), | |
1611 alist); | |
1612 | |
4252 | 1613 alist = xbm_mask_file_munging (alist, filename, Qt, console_type); |
462 | 1614 |
1615 { | |
1616 Lisp_Object result = alist_to_tagged_vector (Qxbm, alist); | |
1617 free_alist (alist); | |
1618 RETURN_UNGCPRO (result); | |
1619 } | |
1620 } | |
1621 | |
1622 #ifdef HAVE_XPM | |
1623 data = pixmap_to_lisp_data (filename, 1); | |
1624 | |
1625 if (!EQ (data, Qt)) | |
1626 { | |
1627 alist = remassq_no_quit (Q_data, alist); | |
1628 alist = Fcons (Fcons (Q_file, filename), | |
1629 Fcons (Fcons (Q_data, data), alist)); | |
1630 alist = Fcons (Fcons (Q_color_symbols, | |
1631 evaluate_xpm_color_symbols ()), | |
1632 alist); | |
1633 { | |
1634 Lisp_Object result = alist_to_tagged_vector (Qxpm, alist); | |
1635 free_alist (alist); | |
1636 RETURN_UNGCPRO (result); | |
1637 } | |
1638 } | |
1639 #endif | |
1640 } | |
1641 | |
1642 /* If we couldn't convert it, just put it back as it is. | |
1643 We might try to further frob it later as a cursor-font | |
1644 specification. (We can't do that now because we don't know | |
1645 what dest-types it's going to be instantiated into.) */ | |
1646 { | |
1647 Lisp_Object result = alist_to_tagged_vector (Qautodetect, alist); | |
1648 free_alist (alist); | |
1649 RETURN_UNGCPRO (result); | |
1650 } | |
1651 } | |
1652 | |
1653 static int | |
1654 autodetect_possible_dest_types (void) | |
1655 { | |
1656 return | |
1657 IMAGE_MONO_PIXMAP_MASK | | |
1658 IMAGE_COLOR_PIXMAP_MASK | | |
1659 IMAGE_POINTER_MASK | | |
1660 IMAGE_TEXT_MASK; | |
1661 } | |
1662 | |
1663 static void | |
1664 autodetect_instantiate (Lisp_Object image_instance, | |
1665 Lisp_Object instantiator, | |
1666 Lisp_Object pointer_fg, | |
1667 Lisp_Object pointer_bg, | |
1668 int dest_mask, Lisp_Object domain) | |
1669 { | |
1670 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
1671 struct gcpro gcpro1, gcpro2, gcpro3; | |
1672 Lisp_Object alist = Qnil; | |
1673 Lisp_Object result = Qnil; | |
1674 int is_cursor_font = 0; | |
1675 | |
1676 GCPRO3 (data, alist, result); | |
1677 | |
1678 alist = tagged_vector_to_alist (instantiator); | |
1679 if (dest_mask & IMAGE_POINTER_MASK) | |
1680 { | |
771 | 1681 const char *name_ext; |
462 | 1682 |
1683 TO_EXTERNAL_FORMAT (LISP_STRING, data, | |
1684 C_STRING_ALLOCA, name_ext, | |
1685 Qfile_name); | |
1686 | |
1687 if (cursor_name_to_index (name_ext) != -1) | |
4252 | 1688 { |
1689 result = alist_to_tagged_vector (Qcursor_font, alist); | |
1690 is_cursor_font = 1; | |
1691 } | |
462 | 1692 } |
1693 | |
1694 if (!is_cursor_font) | |
1695 result = alist_to_tagged_vector (Qstring, alist); | |
1696 free_alist (alist); | |
1697 | |
1698 if (is_cursor_font) | |
1699 cursor_font_instantiate (image_instance, result, pointer_fg, | |
1700 pointer_bg, dest_mask, domain); | |
1701 else | |
1702 string_instantiate (image_instance, result, pointer_fg, | |
1703 pointer_bg, dest_mask, domain); | |
1704 | |
1705 UNGCPRO; | |
1706 } | |
1707 | |
1708 | |
1709 /********************************************************************** | |
1710 * Font * | |
1711 **********************************************************************/ | |
1712 | |
1713 static void | |
1714 font_validate (Lisp_Object instantiator) | |
1715 { | |
1716 data_must_be_present (instantiator); | |
1717 } | |
1718 | |
1719 static int | |
1720 font_possible_dest_types (void) | |
1721 { | |
1722 return IMAGE_POINTER_MASK; | |
1723 } | |
1724 | |
1725 static void | |
1726 font_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
1727 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
2286 | 1728 int dest_mask, Lisp_Object UNUSED (domain)) |
462 | 1729 { |
1730 /* This function can GC */ | |
1731 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
1732 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
1733 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); | |
1734 GdkColor fg, bg; | |
1735 GdkFont *source, *mask; | |
2421 | 1736 char source_name[PATH_MAX_INTERNAL], mask_name[PATH_MAX_INTERNAL], dummy; |
462 | 1737 int source_char, mask_char; |
1738 int count; | |
1739 Lisp_Object foreground, background; | |
1740 | |
1741 if (!DEVICE_GTK_P (XDEVICE (device))) | |
563 | 1742 gui_error ("Not a Gtk device", device); |
462 | 1743 |
1744 if (!STRINGP (data) || | |
1745 strncmp ("FONT ", (char *) XSTRING_DATA (data), 5)) | |
563 | 1746 invalid_argument ("Invalid font-glyph instantiator", |
462 | 1747 instantiator); |
1748 | |
1749 if (!(dest_mask & IMAGE_POINTER_MASK)) | |
1750 incompatible_image_types (instantiator, dest_mask, IMAGE_POINTER_MASK); | |
1751 | |
1752 foreground = find_keyword_in_vector (instantiator, Q_foreground); | |
1753 if (NILP (foreground)) | |
1754 foreground = pointer_fg; | |
1755 background = find_keyword_in_vector (instantiator, Q_background); | |
1756 if (NILP (background)) | |
1757 background = pointer_bg; | |
1758 | |
1759 generate_cursor_fg_bg (device, &foreground, &background, &fg, &bg); | |
1760 | |
1761 count = sscanf ((char *) XSTRING_DATA (data), | |
1762 "FONT %s %d %s %d %c", | |
1763 source_name, &source_char, | |
1764 mask_name, &mask_char, &dummy); | |
1765 /* Allow "%s %d %d" as well... */ | |
1766 if (count == 3 && (1 == sscanf (mask_name, "%d %c", &mask_char, &dummy))) | |
1767 count = 4, mask_name[0] = 0; | |
1768 | |
1769 if (count != 2 && count != 4) | |
563 | 1770 syntax_error ("invalid cursor specification", data); |
462 | 1771 source = gdk_font_load (source_name); |
1772 if (! source) | |
563 | 1773 gui_error_2 ("couldn't load font", |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
1774 build_cistring (source_name), |
462 | 1775 data); |
1776 if (count == 2) | |
1777 mask = 0; | |
1778 else if (!mask_name[0]) | |
1779 mask = source; | |
1780 else | |
1781 { | |
1782 mask = gdk_font_load (mask_name); | |
1783 if (!mask) | |
1784 /* continuable */ | |
771 | 1785 Fsignal (Qgui_error, list3 (build_msg_string ("couldn't load font"), |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
1786 build_cistring (mask_name), data)); |
462 | 1787 } |
1788 if (!mask) | |
1789 mask_char = 0; | |
1790 | |
1791 /* #### call XQueryTextExtents() and check_pointer_sizes() here. */ | |
1792 | |
1793 gtk_initialize_pixmap_image_instance (ii, 1, IMAGE_POINTER); | |
1794 | |
1795 IMAGE_INSTANCE_GTK_CURSOR (ii) = NULL; | |
1796 | |
1797 #if 0 | |
1798 /* #### BILL!!! There is no way to call this function from Gdk */ | |
1799 XCreateGlyphCursor (dpy, source, mask, source_char, mask_char, | |
1800 &fg, &bg); | |
1801 #endif | |
1802 XIMAGE_INSTANCE_PIXMAP_FG (image_instance) = foreground; | |
1803 XIMAGE_INSTANCE_PIXMAP_BG (image_instance) = background; | |
1804 | |
1805 gdk_font_unref (source); | |
1806 if (mask && mask != source) gdk_font_unref (mask); | |
1807 } | |
1808 | |
1809 | |
1810 /********************************************************************** | |
1811 * Cursor-Font * | |
1812 **********************************************************************/ | |
1813 | |
1814 static void | |
1815 cursor_font_validate (Lisp_Object instantiator) | |
1816 { | |
1817 data_must_be_present (instantiator); | |
1818 } | |
1819 | |
1820 static int | |
1821 cursor_font_possible_dest_types (void) | |
1822 { | |
1823 return IMAGE_POINTER_MASK; | |
1824 } | |
1825 | |
1826 static char *__downcase (const char *name) | |
1827 { | |
1828 char *converted = strdup(name); | |
1829 char *work = converted; | |
1830 | |
1831 while (*work) | |
1832 { | |
1833 *work = tolower(*work); | |
1834 work++; | |
1835 } | |
1836 return(converted); | |
1837 } | |
1838 | |
1839 /* This is basically the equivalent of XmuCursorNameToIndex */ | |
2054 | 1840 static GdkCursorType |
462 | 1841 cursor_name_to_index (const char *name) |
1842 { | |
1843 int i; | |
1844 static char *the_gdk_cursors[GDK_NUM_GLYPHS]; | |
1845 | |
1846 if (!the_gdk_cursors[GDK_BASED_ARROW_UP]) | |
1847 { | |
1848 /* Need to initialize the array */ | |
1849 /* Supposedly since this array is static it should be | |
4252 | 1850 initialized to NULLs for us, but I'm very paranoid. */ |
462 | 1851 for (i = 0; i < GDK_NUM_GLYPHS; i++) |
1852 { | |
1853 the_gdk_cursors[i] = NULL; | |
1854 } | |
1855 | |
1856 #define FROB_CURSOR(x) the_gdk_cursors[GDK_##x] = __downcase(#x) | |
1857 FROB_CURSOR(ARROW); FROB_CURSOR(BASED_ARROW_DOWN); | |
1858 FROB_CURSOR(BASED_ARROW_UP); FROB_CURSOR(BOAT); | |
1859 FROB_CURSOR(BOGOSITY); FROB_CURSOR(BOTTOM_LEFT_CORNER); | |
1860 FROB_CURSOR(BOTTOM_RIGHT_CORNER); FROB_CURSOR(BOTTOM_SIDE); | |
1861 FROB_CURSOR(BOTTOM_TEE); FROB_CURSOR(BOX_SPIRAL); | |
1862 FROB_CURSOR(CENTER_PTR); FROB_CURSOR(CIRCLE); | |
1863 FROB_CURSOR(CLOCK); FROB_CURSOR(COFFEE_MUG); | |
1864 FROB_CURSOR(CROSS); FROB_CURSOR(CROSS_REVERSE); | |
1865 FROB_CURSOR(CROSSHAIR); FROB_CURSOR(DIAMOND_CROSS); | |
1866 FROB_CURSOR(DOT); FROB_CURSOR(DOTBOX); | |
1867 FROB_CURSOR(DOUBLE_ARROW); FROB_CURSOR(DRAFT_LARGE); | |
1868 FROB_CURSOR(DRAFT_SMALL); FROB_CURSOR(DRAPED_BOX); | |
1869 FROB_CURSOR(EXCHANGE); FROB_CURSOR(FLEUR); | |
1870 FROB_CURSOR(GOBBLER); FROB_CURSOR(GUMBY); | |
1871 FROB_CURSOR(HAND1); FROB_CURSOR(HAND2); | |
1872 FROB_CURSOR(HEART); FROB_CURSOR(ICON); | |
1873 FROB_CURSOR(IRON_CROSS); FROB_CURSOR(LEFT_PTR); | |
1874 FROB_CURSOR(LEFT_SIDE); FROB_CURSOR(LEFT_TEE); | |
1875 FROB_CURSOR(LEFTBUTTON); FROB_CURSOR(LL_ANGLE); | |
1876 FROB_CURSOR(LR_ANGLE); FROB_CURSOR(MAN); | |
1877 FROB_CURSOR(MIDDLEBUTTON); FROB_CURSOR(MOUSE); | |
1878 FROB_CURSOR(PENCIL); FROB_CURSOR(PIRATE); | |
1879 FROB_CURSOR(PLUS); FROB_CURSOR(QUESTION_ARROW); | |
1880 FROB_CURSOR(RIGHT_PTR); FROB_CURSOR(RIGHT_SIDE); | |
1881 FROB_CURSOR(RIGHT_TEE); FROB_CURSOR(RIGHTBUTTON); | |
1882 FROB_CURSOR(RTL_LOGO); FROB_CURSOR(SAILBOAT); | |
1883 FROB_CURSOR(SB_DOWN_ARROW); FROB_CURSOR(SB_H_DOUBLE_ARROW); | |
1884 FROB_CURSOR(SB_LEFT_ARROW); FROB_CURSOR(SB_RIGHT_ARROW); | |
1885 FROB_CURSOR(SB_UP_ARROW); FROB_CURSOR(SB_V_DOUBLE_ARROW); | |
1886 FROB_CURSOR(SHUTTLE); FROB_CURSOR(SIZING); | |
1887 FROB_CURSOR(SPIDER); FROB_CURSOR(SPRAYCAN); | |
1888 FROB_CURSOR(STAR); FROB_CURSOR(TARGET); | |
1889 FROB_CURSOR(TCROSS); FROB_CURSOR(TOP_LEFT_ARROW); | |
1890 FROB_CURSOR(TOP_LEFT_CORNER); FROB_CURSOR(TOP_RIGHT_CORNER); | |
1891 FROB_CURSOR(TOP_SIDE); FROB_CURSOR(TOP_TEE); | |
1892 FROB_CURSOR(TREK); FROB_CURSOR(UL_ANGLE); | |
1893 FROB_CURSOR(UMBRELLA); FROB_CURSOR(UR_ANGLE); | |
1894 FROB_CURSOR(WATCH); FROB_CURSOR(XTERM); | |
1895 FROB_CURSOR(X_CURSOR); | |
1896 #undef FROB_CURSOR | |
1897 } | |
1898 | |
1899 for (i = 0; i < GDK_NUM_GLYPHS; i++) | |
1900 { | |
1901 if (!the_gdk_cursors[i]) continue; | |
1902 if (!strcmp (the_gdk_cursors[i], name)) | |
1903 { | |
2054 | 1904 return (GdkCursorType) i; |
462 | 1905 } |
1906 } | |
2054 | 1907 return (GdkCursorType) -1; |
462 | 1908 } |
1909 | |
1910 static void | |
1911 cursor_font_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
1912 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
2286 | 1913 int dest_mask, Lisp_Object UNUSED (domain)) |
462 | 1914 { |
1915 /* This function can GC */ | |
1916 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
1917 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
1918 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); | |
2054 | 1919 GdkCursorType i; |
771 | 1920 const char *name_ext; |
462 | 1921 Lisp_Object foreground, background; |
1922 | |
1923 if (!DEVICE_GTK_P (XDEVICE (device))) | |
563 | 1924 gui_error ("Not a Gtk device", device); |
462 | 1925 |
1926 if (!(dest_mask & IMAGE_POINTER_MASK)) | |
1927 incompatible_image_types (instantiator, dest_mask, IMAGE_POINTER_MASK); | |
1928 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
1929 name_ext = LISP_STRING_TO_EXTERNAL (data, Qfile_name); |
462 | 1930 |
1931 if ((i = cursor_name_to_index (name_ext)) == -1) | |
563 | 1932 invalid_argument ("Unrecognized cursor-font name", data); |
462 | 1933 |
1934 gtk_initialize_pixmap_image_instance (ii, 1, IMAGE_POINTER); | |
1935 IMAGE_INSTANCE_GTK_CURSOR (ii) = gdk_cursor_new (i); | |
1936 foreground = find_keyword_in_vector (instantiator, Q_foreground); | |
1937 if (NILP (foreground)) | |
1938 foreground = pointer_fg; | |
1939 background = find_keyword_in_vector (instantiator, Q_background); | |
1940 if (NILP (background)) | |
1941 background = pointer_bg; | |
1942 maybe_recolor_cursor (image_instance, foreground, background); | |
1943 } | |
1944 | |
1945 static int | |
1946 gtk_colorize_image_instance (Lisp_Object image_instance, | |
1947 Lisp_Object foreground, Lisp_Object background); | |
1948 | |
1949 | |
1950 /************************************************************************/ | |
1951 /* subwindow and widget support */ | |
1952 /************************************************************************/ | |
1953 | |
1954 /* unmap the image if it is a widget. This is used by redisplay via | |
1955 redisplay_unmap_subwindows */ | |
1956 static void | |
1957 gtk_unmap_subwindow (Lisp_Image_Instance *p) | |
1958 { | |
1959 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW) | |
1960 { | |
1961 /* We don't support subwindows, but we do support widgets... */ | |
2500 | 1962 ABORT (); |
462 | 1963 } |
1964 else /* must be a widget */ | |
1965 { | |
1966 /* Since we are being unmapped we want the enclosing frame to | |
1967 get focus. The losing with simple scrolling but is the safest | |
1968 thing to do. */ | |
1969 if (IMAGE_INSTANCE_GTK_CLIPWIDGET (p)) | |
1970 gtk_widget_unmap (IMAGE_INSTANCE_GTK_CLIPWIDGET (p)); | |
1971 } | |
1972 } | |
1973 | |
1974 /* map the subwindow. This is used by redisplay via | |
1975 redisplay_output_subwindow */ | |
1976 static void | |
1977 gtk_map_subwindow (Lisp_Image_Instance *p, int x, int y, | |
691 | 1978 struct display_glyph_area* dga) |
462 | 1979 { |
1980 assert (dga->width > 0 && dga->height > 0); | |
1981 | |
1982 if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW) | |
1983 { | |
1984 /* No subwindow support... */ | |
2500 | 1985 ABORT (); |
462 | 1986 } |
1987 else /* must be a widget */ | |
1988 { | |
1989 struct frame *f = XFRAME (IMAGE_INSTANCE_FRAME (p)); | |
1990 GtkWidget *wid = IMAGE_INSTANCE_GTK_CLIPWIDGET (p); | |
1991 GtkAllocation a; | |
2168 | 1992 int moving; |
462 | 1993 |
1994 if (!wid) return; | |
1995 | |
1996 a.x = x + IMAGE_INSTANCE_GTK_WIDGET_XOFFSET (p); | |
1997 a.y = y + IMAGE_INSTANCE_GTK_WIDGET_YOFFSET (p); | |
1998 a.width = dga->width; | |
1999 a.height = dga->height; | |
2000 | |
2168 | 2001 /* Is the widget cganging position? */ |
2002 moving = (a.x != wid->allocation.x) || | |
2003 (a.y != wid->allocation.y); | |
2004 | |
462 | 2005 if ((a.width != wid->allocation.width) || |
2168 | 2006 (a.height != wid->allocation.height) || |
2007 moving) | |
462 | 2008 { |
2009 gtk_widget_size_allocate (IMAGE_INSTANCE_GTK_CLIPWIDGET (p), &a); | |
2010 } | |
2011 | |
2168 | 2012 if (moving) |
462 | 2013 { |
2014 guint32 old_flags = GTK_WIDGET_FLAGS (FRAME_GTK_TEXT_WIDGET (f)); | |
2015 | |
2168 | 2016 /* GtkFixed widget queues a resize when you add a widget. |
462 | 2017 ** But only if it is visible. |
2018 ** losers. | |
2019 */ | |
2020 GTK_WIDGET_FLAGS(FRAME_GTK_TEXT_WIDGET (f)) &= ~GTK_VISIBLE; | |
2168 | 2021 |
462 | 2022 if (IMAGE_INSTANCE_GTK_ALREADY_PUT(p)) |
2023 { | |
2024 gtk_fixed_move (GTK_FIXED (FRAME_GTK_TEXT_WIDGET (f)), | |
2025 wid, | |
2168 | 2026 a.x, a.y); |
462 | 2027 } |
2028 else | |
2029 { | |
2030 IMAGE_INSTANCE_GTK_ALREADY_PUT(p) = TRUE; | |
2031 gtk_fixed_put (GTK_FIXED (FRAME_GTK_TEXT_WIDGET (f)), | |
2032 wid, | |
2168 | 2033 a.x, a.y); |
462 | 2034 } |
2168 | 2035 |
462 | 2036 GTK_WIDGET_FLAGS(FRAME_GTK_TEXT_WIDGET (f)) = old_flags; |
2037 } | |
691 | 2038 else |
2039 { | |
2040 if (IMAGE_INSTANCE_GTK_ALREADY_PUT(p)) | |
2041 { | |
2042 /* Do nothing... */ | |
2043 } | |
2044 else | |
2045 { | |
2046 /* Must make sure we have put the image at least once! */ | |
2047 IMAGE_INSTANCE_GTK_ALREADY_PUT(p) = TRUE; | |
2048 gtk_fixed_put (GTK_FIXED (FRAME_GTK_TEXT_WIDGET (f)), | |
2049 wid, | |
2168 | 2050 a.x, a.y); |
691 | 2051 } |
2052 } | |
462 | 2053 |
2054 if (!IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (p)) | |
2055 { | |
2056 gtk_widget_map (wid); | |
2057 } | |
2058 | |
2059 gtk_widget_draw (wid, NULL); | |
2060 } | |
2061 } | |
2062 | |
2063 /* when you click on a widget you may activate another widget this | |
2064 needs to be checked and all appropriate widgets updated */ | |
2065 static void | |
2066 gtk_redisplay_subwindow (Lisp_Image_Instance *p) | |
2067 { | |
2068 /* Update the subwindow size if necessary. */ | |
2069 if (IMAGE_INSTANCE_SIZE_CHANGED (p)) | |
2070 { | |
2071 #if 0 | |
2072 XResizeWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p), | |
2073 IMAGE_INSTANCE_X_SUBWINDOW_ID (p), | |
2074 IMAGE_INSTANCE_WIDTH (p), | |
2075 IMAGE_INSTANCE_HEIGHT (p)); | |
2076 #endif | |
2077 } | |
2078 } | |
2079 | |
2080 /* Update all attributes that have changed. */ | |
2081 static void | |
2082 gtk_redisplay_widget (Lisp_Image_Instance *p) | |
2083 { | |
2084 /* This function can GC if IN_REDISPLAY is false. */ | |
2085 | |
2086 if (!IMAGE_INSTANCE_GTK_CLIPWIDGET (p)) | |
2087 return; | |
2088 | |
2089 #ifdef HAVE_WIDGETS | |
2090 /* First get the items if they have changed since this is a | |
2091 structural change. As such it will nuke all added values so we | |
2092 need to update most other things after the items have changed.*/ | |
2093 gtk_widget_show_all (IMAGE_INSTANCE_GTK_CLIPWIDGET (p)); | |
2094 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)) | |
2095 { | |
2096 /* Need to update GtkArgs that might have changed... */ | |
2097 /* #### FIXME!!! */ | |
2054 | 2098 /*Lisp_Object image_instance = wrap_image_instance (p); */ |
462 | 2099 } |
2100 else | |
2101 { | |
2102 /* #### FIXME!!! */ | |
2103 /* No items changed, so do nothing, right? */ | |
2104 } | |
2105 | |
2106 /* Possibly update the colors and font */ | |
2107 if (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p) | |
2108 || | |
2109 /* #### This is not sufficient because it will not cope with widgets | |
2110 that are not currently visible. Once redisplay has done the | |
2111 visible ones it will clear this flag so that when new ones | |
2112 become visible they will not be updated. */ | |
2113 XFRAME (IMAGE_INSTANCE_FRAME (p))->faces_changed | |
2114 || | |
2115 XFRAME (IMAGE_INSTANCE_FRAME (p))->frame_changed | |
2116 || | |
2117 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)) | |
2118 { | |
2119 /* #### Write this function BILL! */ | |
2120 update_widget_face (NULL, p, IMAGE_INSTANCE_FRAME (p)); | |
2121 } | |
2122 | |
2123 /* Possibly update the text. */ | |
2124 if (IMAGE_INSTANCE_TEXT_CHANGED (p)) | |
2125 { | |
2126 char* str; | |
2127 Lisp_Object val = IMAGE_INSTANCE_WIDGET_TEXT (p); | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
2128 str = LISP_STRING_TO_EXTERNAL (val, Qnative); |
462 | 2129 |
2130 /* #### Need to special case each type of GtkWidget here! */ | |
2131 } | |
2132 | |
2133 /* Possibly update the size. */ | |
2134 if (IMAGE_INSTANCE_SIZE_CHANGED (p) | |
2135 || | |
2136 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p) | |
2137 || | |
2138 IMAGE_INSTANCE_TEXT_CHANGED (p)) | |
2139 { | |
2168 | 2140 GtkRequisition r; |
2141 GtkAllocation a = IMAGE_INSTANCE_GTK_CLIPWIDGET (p)->allocation; | |
2142 | |
462 | 2143 assert (IMAGE_INSTANCE_GTK_WIDGET_ID (p) && |
2144 IMAGE_INSTANCE_GTK_CLIPWIDGET (p)) ; | |
2145 | |
2168 | 2146 a.width = r.width = IMAGE_INSTANCE_WIDTH (p); |
2147 a.height = r.height = IMAGE_INSTANCE_HEIGHT (p); | |
2148 | |
2149 /* Force the widget's preferred and actual size to what we say it shall | |
2150 be. */ | |
2151 gtk_widget_size_request (IMAGE_INSTANCE_GTK_CLIPWIDGET (p), &r); | |
2152 gtk_widget_size_allocate (IMAGE_INSTANCE_GTK_CLIPWIDGET (p), &a); | |
462 | 2153 } |
2154 | |
2155 /* Adjust offsets within the frame. */ | |
2156 if (XFRAME (IMAGE_INSTANCE_FRAME (p))->size_changed) | |
2157 { | |
2158 /* I don't think we need to do anything for Gtk here... */ | |
2159 } | |
2160 | |
2161 /* now modify the widget */ | |
2162 #endif | |
2163 } | |
2164 | |
2165 /* instantiate and gtk type subwindow */ | |
2166 static void | |
2286 | 2167 gtk_subwindow_instantiate (Lisp_Object image_instance, |
2168 Lisp_Object UNUSED (instantiator), | |
2169 Lisp_Object UNUSED (pointer_fg), | |
2170 Lisp_Object UNUSED (pointer_bg), | |
2171 int UNUSED (dest_mask), Lisp_Object UNUSED (domain)) | |
462 | 2172 { |
2173 /* This function can GC */ | |
2174 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
2175 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); | |
2176 | |
2177 if (!DEVICE_GTK_P (XDEVICE (device))) | |
563 | 2178 gui_error ("Not a GTK device", device); |
462 | 2179 |
2180 IMAGE_INSTANCE_TYPE (ii) = IMAGE_SUBWINDOW; | |
2181 | |
2182 ii->data = xnew_and_zero (struct gtk_subwindow_data); | |
2183 | |
2184 /* Create a window for clipping */ | |
2185 IMAGE_INSTANCE_GTK_CLIPWINDOW (ii) = NULL; | |
2186 | |
2187 /* Now put the subwindow inside the clip window. */ | |
2188 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void *) NULL; | |
2189 } | |
2190 | |
2191 #ifdef HAVE_WIDGETS | |
2192 | |
2193 /************************************************************************/ | |
2194 /* widgets */ | |
2195 /************************************************************************/ | |
2196 static void | |
2197 update_widget_face (GtkWidget *w, Lisp_Image_Instance *ii, | |
2198 Lisp_Object domain) | |
2199 { | |
2200 if (0) | |
2201 { | |
2202 GtkStyle *style = gtk_widget_get_style (w); | |
2203 Lisp_Object pixel = Qnil; | |
2204 GdkColor *fcolor, *bcolor; | |
2205 | |
2206 style = gtk_style_copy (style); | |
4252 | 2207 |
462 | 2208 /* Update the foreground. */ |
2209 pixel = FACE_FOREGROUND (IMAGE_INSTANCE_WIDGET_FACE (ii), domain); | |
2210 fcolor = COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (pixel)); | |
2211 | |
2212 /* Update the background. */ | |
2213 pixel = FACE_BACKGROUND (IMAGE_INSTANCE_WIDGET_FACE (ii), domain); | |
2214 bcolor = COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (pixel)); | |
2215 | |
2216 /* Update the font */ | |
2217 /* #### FIXME!!! Need to copy the widgets style, dick with it, and | |
2218 ** set the widgets style to the new style... | |
2219 */ | |
2220 gtk_widget_set_style (w, style); | |
2221 | |
2222 /* #### Megahack - but its just getting too complicated to do this | |
2223 in the right place. */ | |
2224 #if 0 | |
2225 if (EQ (IMAGE_INSTANCE_WIDGET_TYPE (ii), Qtab_control)) | |
2226 update_tab_widget_face (wv, ii, domain); | |
2227 #endif | |
2228 } | |
2229 } | |
2230 | |
2231 #if 0 | |
2232 static void | |
2233 update_tab_widget_face (GtkWidget *w, Lisp_Image_Instance *ii, | |
2234 Lisp_Object domain) | |
2235 { | |
2236 if (wv->contents) | |
2237 { | |
2238 widget_value* val = wv->contents, *cur; | |
2239 | |
2240 /* Give each child label the correct foreground color. */ | |
2241 Lisp_Object pixel = FACE_FOREGROUND | |
2242 (IMAGE_INSTANCE_WIDGET_FACE (ii), | |
2243 domain); | |
2244 XColor fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel)); | |
2245 lw_add_widget_value_arg (val, XtNtabForeground, fcolor.pixel); | |
2246 wv->change = VISIBLE_CHANGE; | |
2247 val->change = VISIBLE_CHANGE; | |
2248 | |
2249 for (cur = val->next; cur; cur = cur->next) | |
2250 { | |
2251 cur->change = VISIBLE_CHANGE; | |
2252 if (cur->value) | |
2253 { | |
2254 lw_copy_widget_value_args (val, cur); | |
2255 } | |
2256 } | |
2257 } | |
2258 } | |
2259 #endif | |
2260 | |
2261 static Lisp_Object | |
2262 gtk_widget_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator, | |
2263 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
2264 Lisp_Object domain) | |
2265 { | |
2266 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
2267 Lisp_Object widget = Qnil; | |
2268 char *nm = NULL; | |
2269 GtkWidget *w = NULL; | |
2270 struct gcpro gcpro1; | |
2271 | |
2272 IMAGE_INSTANCE_TYPE (ii) = IMAGE_WIDGET; | |
2273 | |
2274 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii))) | |
2275 { | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
2276 nm = LISP_STRING_TO_EXTERNAL (IMAGE_INSTANCE_WIDGET_TEXT (ii), Qnative); |
462 | 2277 } |
2278 | |
2279 ii->data = xnew_and_zero (struct gtk_subwindow_data); | |
2280 | |
2281 /* Create a clipping widget */ | |
2282 IMAGE_INSTANCE_GTK_CLIPWIDGET (ii) = NULL; | |
2283 IMAGE_INSTANCE_GTK_ALREADY_PUT(ii) = FALSE; | |
2284 | |
2285 /* Create the actual widget */ | |
2286 GCPRO1 (widget); | |
2287 widget = call5 (Qgtk_widget_instantiate_internal, | |
2288 image_instance, instantiator, | |
2289 pointer_fg, pointer_bg, | |
2290 domain); | |
2291 | |
2292 if (!NILP (widget)) | |
2293 { | |
2294 CHECK_GTK_OBJECT (widget); | |
2295 w = GTK_WIDGET (XGTK_OBJECT (widget)->object); | |
2296 } | |
2297 else | |
2298 { | |
2299 stderr_out ("Lisp-level creation of widget failed... falling back\n"); | |
2300 w = gtk_label_new ("Widget Creation Failed..."); | |
2301 } | |
2302 | |
2303 UNGCPRO; | |
2304 | |
2305 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void *) w; | |
2306 | |
2307 /* #### HACK!!!! We should make this do the right thing if we | |
2308 ** really need a clip widget! | |
2309 */ | |
2310 IMAGE_INSTANCE_GTK_CLIPWIDGET (ii) = w; | |
2311 | |
2168 | 2312 /* The current theme may produce a widget of a different size that what we |
2313 expect so force reconsideration of the widget's size. */ | |
2314 IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 1; | |
2315 | |
462 | 2316 return (Qt); |
2317 } | |
2318 | |
2319 static void | |
2320 gtk_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
2321 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
2286 | 2322 int UNUSED (dest_mask), Lisp_Object domain) |
462 | 2323 { |
2324 call_with_suspended_errors ((lisp_fn_t) gtk_widget_instantiate_1, | |
2325 Qnil, Qimage, | |
2326 ERROR_ME_WARN, 5, | |
2327 image_instance, instantiator, | |
2328 pointer_fg, | |
2329 pointer_bg, | |
2330 domain); | |
2331 } | |
2332 | |
2333 /* get properties of a control */ | |
2334 static Lisp_Object | |
2286 | 2335 gtk_widget_property (Lisp_Object UNUSED (image_instance), Lisp_Object prop) |
462 | 2336 { |
2337 /* Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); */ | |
2338 | |
2339 /* get the text from a control */ | |
2340 if (EQ (prop, Q_text)) | |
2341 { | |
2342 return Qnil; | |
2343 } | |
2344 return Qunbound; | |
2345 } | |
2346 | |
2347 #define FAKE_GTK_WIDGET_INSTANTIATOR(x) \ | |
2348 static void \ | |
2349 gtk_##x##_instantiate (Lisp_Object image_instance, \ | |
2350 Lisp_Object instantiator, \ | |
2351 Lisp_Object pointer_fg, \ | |
2352 Lisp_Object pointer_bg, \ | |
2353 int dest_mask, Lisp_Object domain) \ | |
2354 { \ | |
2355 gtk_widget_instantiate (image_instance, instantiator, pointer_fg, \ | |
2356 pointer_bg, dest_mask, domain); \ | |
2357 } | |
2358 | |
2359 FAKE_GTK_WIDGET_INSTANTIATOR(native_layout); | |
2360 FAKE_GTK_WIDGET_INSTANTIATOR(button); | |
2361 FAKE_GTK_WIDGET_INSTANTIATOR(progress_gauge); | |
2362 FAKE_GTK_WIDGET_INSTANTIATOR(edit_field); | |
2363 FAKE_GTK_WIDGET_INSTANTIATOR(combo_box); | |
2364 FAKE_GTK_WIDGET_INSTANTIATOR(label); | |
2168 | 2365 /* Note: tab_control has a custom instantiator (see below) */ |
2366 | |
2367 /* | |
2368 Ask the widget to return it's preferred size. This device method must | |
2369 defined for all widgets that also have format specific version of | |
2370 query_geometry defined in glyphs-widget.c. This is because those format | |
2371 specific versions return sizes that are appropriate for the X widgets. For | |
2372 GTK, the size of a widget can change at runtime due to the user changing | |
2373 their theme. | |
2374 | |
2375 This method can be called before the widget is instantiated. This is | |
2376 because instantiate_image_instantiator() is tying to be helpful to other | |
2377 toolkits and supply sane geometry values to them. This is not appropriate | |
2378 for GTK and can be ignored. | |
2379 | |
2380 This method can be used by all widgets. | |
2381 */ | |
2382 static void | |
2383 gtk_widget_query_geometry (Lisp_Object image_instance, | |
2384 int* width, int* height, | |
2286 | 2385 enum image_instance_geometry UNUSED (disp), |
2386 Lisp_Object UNUSED (domain)) | |
2168 | 2387 { |
2388 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); | |
2389 | |
2390 if (p->data != NULL) | |
2391 { | |
2392 GtkWidget *w = IMAGE_INSTANCE_GTK_CLIPWIDGET (p); | |
2393 GtkRequisition r; | |
2394 | |
2395 gtk_widget_size_request(w, &r); | |
2396 *height= r.height; | |
2397 *width = r.width; | |
2398 } | |
2399 } | |
2400 | |
2401 | |
2402 /* Button functions. */ | |
462 | 2403 |
2404 /* Update a button's clicked state. */ | |
2405 static void | |
2406 gtk_button_redisplay (Lisp_Object image_instance) | |
2407 { | |
2408 /* This function can GC if IN_REDISPLAY is false. */ | |
2409 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); | |
2410 GtkWidget *w = IMAGE_INSTANCE_GTK_CLIPWIDGET (p); | |
2411 | |
2412 if (GTK_WIDGET_TYPE (w) == gtk_button_get_type ()) | |
2413 { | |
2414 } | |
2415 else if (GTK_WIDGET_TYPE (w) == gtk_check_button_get_type ()) | |
2416 { | |
2417 } | |
2418 else if (GTK_WIDGET_TYPE (w) == gtk_radio_button_get_type ()) | |
2419 { | |
2420 } | |
2421 else | |
2422 { | |
2423 /* Unknown button type... */ | |
2500 | 2424 ABORT(); |
462 | 2425 } |
2426 } | |
2427 | |
2428 /* get properties of a button */ | |
2429 static Lisp_Object | |
2430 gtk_button_property (Lisp_Object image_instance, Lisp_Object prop) | |
2431 { | |
2432 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
2433 | |
2434 /* check the state of a button */ | |
2435 if (EQ (prop, Q_selected)) | |
2436 { | |
2437 if (GTK_WIDGET_HAS_FOCUS (IMAGE_INSTANCE_SUBWINDOW_ID (ii))) | |
2438 return Qt; | |
2439 else | |
2440 return Qnil; | |
2441 } | |
2442 return Qunbound; | |
2443 } | |
2444 | |
2168 | 2445 |
2446 /* Progress gauge functions. */ | |
2447 | |
462 | 2448 /* set the properties of a progress gauge */ |
2449 static void | |
2450 gtk_progress_gauge_redisplay (Lisp_Object image_instance) | |
2451 { | |
2452 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
2453 | |
2454 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)) | |
2455 { | |
2456 gfloat f; | |
2457 Lisp_Object val; | |
2458 | |
2459 val = XGUI_ITEM (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))->value; | |
2460 f = XFLOATINT (val); | |
2461 | |
2462 gtk_progress_set_value (GTK_PROGRESS (IMAGE_INSTANCE_SUBWINDOW_ID (ii)), | |
2463 f); | |
2464 } | |
2465 } | |
2466 | |
2168 | 2467 |
2468 /* Tab Control functions. */ | |
2469 | |
2470 /* | |
2471 Register a widget's callbacks with the frame's hashtable. The hashtable is | |
2472 weak so deregistration is handled automatically. Tab controls have per-tab | |
2473 callback list functions and the GTK callback architecture is not | |
2474 sufficiently flexible to deal with this. Instead, the functions are | |
2475 registered here and the id is passed through the callback loop. | |
2476 */ | |
2477 static int | |
2478 gtk_register_gui_item (Lisp_Object image_instance, Lisp_Object gui, | |
2479 Lisp_Object domain) | |
2480 { | |
2481 struct frame *f = XFRAME(DOMAIN_FRAME(domain)); | |
2482 int id = gui_item_id_hash(FRAME_GTK_WIDGET_CALLBACK_HASH_TABLE(f), | |
2483 gui, WIDGET_GLYPH_SLOT); | |
2484 | |
2485 Fputhash(make_int(id), image_instance, | |
2486 FRAME_GTK_WIDGET_INSTANCE_HASH_TABLE (f)); | |
2487 Fputhash(make_int(id), XGUI_ITEM (gui)->callback, | |
2488 FRAME_GTK_WIDGET_CALLBACK_HASH_TABLE (f)); | |
2489 Fputhash(make_int(id), XGUI_ITEM (gui)->callback_ex, | |
2490 FRAME_GTK_WIDGET_CALLBACK_EX_HASH_TABLE (f)); | |
2491 return id; | |
2492 } | |
2493 | |
2494 /* | |
2495 Append the given item as a tab to the notebook. Callbacks, etc are all | |
2496 setup. | |
2497 */ | |
2498 static void | |
2499 gtk_add_tab_item(Lisp_Object image_instance, | |
2500 GtkNotebook* nb, Lisp_Object item, | |
2286 | 2501 Lisp_Object domain, int UNUSED (i)) |
2168 | 2502 { |
2503 Lisp_Object name; | |
2504 int hash_id = 0; | |
2505 char *c_name = NULL; | |
2506 GtkWidget* box; | |
2507 | |
2508 if (GUI_ITEMP (item)) | |
2509 { | |
2510 Lisp_Gui_Item *pgui = XGUI_ITEM (item); | |
2511 | |
2512 if (!STRINGP (pgui->name)) | |
2513 pgui->name = eval_within_redisplay (pgui->name); | |
2514 | |
2515 if (!STRINGP (pgui->name)) { | |
2516 warn_when_safe (Qredisplay, Qwarning, | |
2517 "Name does not evaluate to string"); | |
2518 | |
2519 return; | |
2520 } | |
2521 | |
2522 hash_id = gtk_register_gui_item (image_instance, item, domain); | |
2523 name = pgui->name; | |
2524 } | |
2525 else | |
2526 { | |
2527 CHECK_STRING (item); | |
2528 name = item; | |
2529 } | |
2530 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
2531 c_name = LISP_STRING_TO_EXTERNAL (name, Qctext); |
2168 | 2532 |
2533 /* Dummy widget that the notbook wants to display when a tab is selected. */ | |
2534 box = gtk_vbox_new (FALSE, 3); | |
2535 | |
2536 /* | |
2537 Store the per-tab callback data id in the tab. The callback functions | |
2538 themselves could have been stored in the widget but this avoids having to | |
2539 worry about the garbage collector running between here and the callback | |
2540 function. | |
2541 */ | |
2542 gtk_object_set_data(GTK_OBJECT(box), GTK_DATA_TAB_HASHCODE_IDENTIFIER, | |
2543 (gpointer) hash_id); | |
2544 | |
2545 gtk_notebook_append_page (nb, box, gtk_label_new (c_name)); | |
2546 } | |
2547 | |
2548 /* Signal handler for the switch-page signal. */ | |
2549 static void gtk_tab_control_callback(GtkNotebook *notebook, | |
2550 GtkNotebookPage *page, | |
2286 | 2551 gint UNUSED (page_num), |
2552 gpointer UNUSED (user_data)) | |
2168 | 2553 { |
2554 /* | |
2555 This callback is called for every selection, not just user selection. | |
2556 We're only interested in user selection, which occurs outside of | |
2557 redisplay. | |
2558 */ | |
2559 | |
2560 if (!in_display) | |
2561 { | |
2562 Lisp_Object image_instance, callback, callback_ex; | |
2563 Lisp_Object frame, event; | |
2564 int update_subwindows_p = 0; | |
2565 struct frame *f = gtk_widget_to_frame(GTK_WIDGET(notebook)); | |
2566 int id; | |
2567 | |
2568 if (!f) | |
2569 return; | |
2570 frame = wrap_frame (f); | |
2571 | |
2572 id = (int) gtk_object_get_data(GTK_OBJECT(page->child), | |
2573 GTK_DATA_TAB_HASHCODE_IDENTIFIER); | |
2574 image_instance = Fgethash(make_int_verify(id), | |
2575 FRAME_GTK_WIDGET_INSTANCE_HASH_TABLE(f), Qnil); | |
2576 callback = Fgethash(make_int(id), | |
2577 FRAME_GTK_WIDGET_CALLBACK_HASH_TABLE(f), Qnil); | |
2578 callback_ex = Fgethash(make_int(id), | |
2579 FRAME_GTK_WIDGET_CALLBACK_EX_HASH_TABLE(f), Qnil); | |
2580 update_subwindows_p = 1; | |
2581 | |
2582 /* It is possible for a widget action to cause it to get out of | |
2583 sync with its instantiator. Thus it is necessary to signal | |
2584 this possibility. */ | |
2585 if (IMAGE_INSTANCEP (image_instance)) | |
2586 XIMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (image_instance) = 1; | |
4252 | 2587 |
2168 | 2588 if (!NILP (callback_ex) && !UNBOUNDP (callback_ex)) |
2589 { | |
2590 event = Fmake_event (Qnil, Qnil); | |
2591 | |
2592 XSET_EVENT_TYPE (event, misc_user_event); | |
2593 XSET_EVENT_CHANNEL (event, frame); | |
2594 XSET_EVENT_MISC_USER_FUNCTION (event, Qeval); | |
2595 XSET_EVENT_MISC_USER_OBJECT (event, list4 (Qfuncall, callback_ex, image_instance, event)); | |
2596 } | |
2597 else if (NILP (callback) || UNBOUNDP (callback)) | |
2598 event = Qnil; | |
2599 else | |
2600 { | |
2601 Lisp_Object fn, arg; | |
2602 | |
2603 event = Fmake_event (Qnil, Qnil); | |
2604 | |
2605 get_gui_callback (callback, &fn, &arg); | |
2606 XSET_EVENT_TYPE (event, misc_user_event); | |
2607 XSET_EVENT_CHANNEL (event, frame); | |
2608 XSET_EVENT_MISC_USER_FUNCTION (event, fn); | |
2609 XSET_EVENT_MISC_USER_OBJECT (event, arg); | |
2610 } | |
2611 | |
2612 if (!NILP (event)) | |
2613 enqueue_dispatch_event (event); | |
2614 | |
2615 /* The result of this evaluation could cause other instances to change so | |
2616 enqueue an update callback to check this. */ | |
2617 if (update_subwindows_p && !NILP (event)) | |
2618 enqueue_magic_eval_event (update_widget_instances, frame); | |
2619 } | |
2620 } | |
2621 | |
2622 /* Create a tab_control widget. The special handling of the individual tabs | |
2623 means that the normal instantiation code cannot be used. */ | |
2624 static void | |
2625 gtk_tab_control_instantiate (Lisp_Object image_instance, | |
2626 Lisp_Object instantiator, | |
2627 Lisp_Object pointer_fg, | |
2628 Lisp_Object pointer_bg, | |
2629 int dest_mask, Lisp_Object domain) | |
2630 { | |
2631 Lisp_Object rest; | |
2632 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
2633 int i = 0; | |
2634 int selected = 0; | |
2635 GtkNotebook *nb; | |
2636 | |
2637 /* The normal instantiation is still needed. */ | |
2638 gtk_widget_instantiate (image_instance, instantiator, pointer_fg, | |
2639 pointer_bg, dest_mask, domain); | |
2640 | |
2641 nb = GTK_NOTEBOOK (IMAGE_INSTANCE_GTK_CLIPWIDGET (ii)); | |
2642 | |
2643 /* Add items to the tab, find the current selection */ | |
2644 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))) | |
2645 { | |
2646 gtk_add_tab_item (image_instance, nb, XCAR (rest), domain, i); | |
2647 | |
2648 if (gui_item_selected_p (XCAR (rest))) | |
2649 selected = i; | |
2650 | |
2651 i++; | |
2652 } | |
2653 | |
2654 gtk_notebook_set_page(nb, selected); | |
2655 | |
2656 /* Call per-tab lisp callback when a tab is pressed. */ | |
2657 gtk_signal_connect (GTK_OBJECT (nb), "switch-page", | |
2658 GTK_SIGNAL_FUNC (gtk_tab_control_callback), NULL); | |
2659 } | |
2660 | |
462 | 2661 /* Set the properties of a tab control */ |
2662 static void | |
2663 gtk_tab_control_redisplay (Lisp_Object image_instance) | |
2664 { | |
2665 /* #### Convert this to GTK baby! */ | |
2666 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
2667 | |
2668 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) || | |
2669 IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (ii)) | |
2670 { | |
2671 /* If only the order has changed then simply select the first | |
2672 one of the pending set. This stops horrendous rebuilding - | |
2673 and hence flicker - of the tabs each time you click on | |
2674 one. */ | |
2675 if (tab_control_order_only_changed (image_instance)) | |
2676 { | |
2168 | 2677 int i = 0; |
462 | 2678 Lisp_Object rest, selected = |
2679 gui_item_list_find_selected | |
2680 (NILP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)) ? | |
2681 XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)) : | |
2682 XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))); | |
2683 | |
2684 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))) | |
2685 { | |
1913 | 2686 if (gui_item_equal_sans_selected (XCAR (rest), selected, 0)) |
462 | 2687 { |
2688 Lisp_Object old_selected =gui_item_list_find_selected | |
2689 (XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))); | |
2690 | |
2691 /* Pick up the new selected item. */ | |
2692 XGUI_ITEM (old_selected)->selected = | |
2693 XGUI_ITEM (XCAR (rest))->selected; | |
2694 XGUI_ITEM (XCAR (rest))->selected = | |
2695 XGUI_ITEM (selected)->selected; | |
2696 /* We're not actually changing the items anymore. */ | |
2697 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0; | |
2698 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil; | |
2168 | 2699 |
2700 gtk_notebook_set_page(GTK_NOTEBOOK (IMAGE_INSTANCE_GTK_CLIPWIDGET (ii)), | |
2701 i); | |
462 | 2702 break; |
2703 } | |
2168 | 2704 |
2705 i++; | |
462 | 2706 } |
2707 } | |
2708 else | |
2709 { | |
2710 /* More than just the order has changed... let's get busy! */ | |
2711 GtkNotebook *nb = GTK_NOTEBOOK (IMAGE_INSTANCE_GTK_CLIPWIDGET (ii)); | |
2712 guint num_pages = g_list_length (nb->children); | |
2713 Lisp_Object rest; | |
2168 | 2714 int i; |
2715 | |
2716 /* Why is there no API to remove everything from a notebook? */ | |
462 | 2717 if (num_pages >= 0) |
2718 { | |
2719 for (i = num_pages; i >= 0; --i) | |
2720 { | |
2721 gtk_notebook_remove_page (nb, i); | |
2722 } | |
2723 } | |
2724 | |
2168 | 2725 i = 0; |
2726 | |
2727 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))) | |
462 | 2728 { |
2168 | 2729 gtk_add_tab_item(image_instance, nb, XCAR(rest), |
2730 IMAGE_INSTANCE_FRAME(ii), i); | |
462 | 2731 } |
2732 | |
2733 /* Show all the new widgets we just added... */ | |
2734 gtk_widget_show_all (GTK_WIDGET (nb)); | |
2735 } | |
2736 } | |
2737 | |
2738 /* Possibly update the face. */ | |
2739 #if 0 | |
2740 if (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii) | |
2741 || | |
2742 XFRAME (IMAGE_INSTANCE_FRAME (ii))->faces_changed | |
2743 || | |
2744 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)) | |
2745 { | |
2746 update_tab_widget_face (wv, ii, | |
2747 IMAGE_INSTANCE_FRAME (ii)); | |
2748 } | |
2749 #endif | |
2750 } | |
2751 #endif /* HAVE_WIDGETS */ | |
2752 | |
2753 | |
2754 /************************************************************************/ | |
2755 /* initialization */ | |
2756 /************************************************************************/ | |
2757 void | |
2758 syms_of_glyphs_gtk (void) | |
2759 { | |
2760 #ifdef HAVE_WIDGETS | |
563 | 2761 DEFSYMBOL (Qgtk_widget_instantiate_internal); |
2762 DEFSYMBOL (Qgtk_widget_property_internal); | |
2763 DEFSYMBOL (Qgtk_widget_redisplay_internal); | |
2764 DEFSYMBOL (Qgtk_widget_set_style); | |
462 | 2765 #endif |
2766 } | |
2767 | |
2768 void | |
2769 console_type_create_glyphs_gtk (void) | |
2770 { | |
2771 /* image methods */ | |
2772 CONSOLE_HAS_METHOD (gtk, print_image_instance); | |
2773 CONSOLE_HAS_METHOD (gtk, finalize_image_instance); | |
2774 CONSOLE_HAS_METHOD (gtk, image_instance_equal); | |
2775 CONSOLE_HAS_METHOD (gtk, image_instance_hash); | |
2776 CONSOLE_HAS_METHOD (gtk, colorize_image_instance); | |
2777 CONSOLE_HAS_METHOD (gtk, init_image_instance_from_eimage); | |
2778 CONSOLE_HAS_METHOD (gtk, locate_pixmap_file); | |
2779 CONSOLE_HAS_METHOD (gtk, unmap_subwindow); | |
2780 CONSOLE_HAS_METHOD (gtk, map_subwindow); | |
2781 CONSOLE_HAS_METHOD (gtk, redisplay_widget); | |
2782 CONSOLE_HAS_METHOD (gtk, redisplay_subwindow); | |
2783 } | |
2784 | |
2785 void | |
2786 image_instantiator_format_create_glyphs_gtk (void) | |
2787 { | |
2788 IIFORMAT_VALID_CONSOLE (gtk, nothing); | |
2789 IIFORMAT_VALID_CONSOLE (gtk, string); | |
2790 #ifdef HAVE_WIDGETS | |
2791 IIFORMAT_VALID_CONSOLE (gtk, layout); | |
2792 #endif | |
2793 IIFORMAT_VALID_CONSOLE (gtk, formatted_string); | |
2794 IIFORMAT_VALID_CONSOLE (gtk, inherit); | |
2795 #ifdef HAVE_XPM | |
2796 INITIALIZE_DEVICE_IIFORMAT (gtk, xpm); | |
2797 IIFORMAT_HAS_DEVMETHOD (gtk, xpm, instantiate); | |
2798 #endif | |
2799 #ifdef HAVE_JPEG | |
2800 IIFORMAT_VALID_CONSOLE (gtk, jpeg); | |
2801 #endif | |
2802 #ifdef HAVE_TIFF | |
2803 IIFORMAT_VALID_CONSOLE (gtk, tiff); | |
2804 #endif | |
2805 #ifdef HAVE_PNG | |
2806 IIFORMAT_VALID_CONSOLE (gtk, png); | |
2807 #endif | |
2808 #ifdef HAVE_GIF | |
2809 IIFORMAT_VALID_CONSOLE (gtk, gif); | |
2810 #endif | |
2811 | |
2812 INITIALIZE_DEVICE_IIFORMAT (gtk, subwindow); | |
2813 IIFORMAT_HAS_DEVMETHOD (gtk, subwindow, instantiate); | |
2814 | |
2815 #ifdef HAVE_WIDGETS | |
2816 /* layout widget */ | |
2817 INITIALIZE_DEVICE_IIFORMAT (gtk, native_layout); | |
2818 IIFORMAT_HAS_DEVMETHOD (gtk, native_layout, instantiate); | |
2819 | |
2820 /* button widget */ | |
2821 INITIALIZE_DEVICE_IIFORMAT (gtk, button); | |
2822 IIFORMAT_HAS_DEVMETHOD (gtk, button, property); | |
2823 IIFORMAT_HAS_DEVMETHOD (gtk, button, instantiate); | |
2824 IIFORMAT_HAS_DEVMETHOD (gtk, button, redisplay); | |
2168 | 2825 IIFORMAT_HAS_SHARED_DEVMETHOD (gtk, button, query_geometry, widget); |
462 | 2826 /* general widget methods. */ |
2827 INITIALIZE_DEVICE_IIFORMAT (gtk, widget); | |
2828 IIFORMAT_HAS_DEVMETHOD (gtk, widget, property); | |
2168 | 2829 IIFORMAT_HAS_DEVMETHOD (gtk, widget, query_geometry); |
462 | 2830 |
2831 /* progress gauge */ | |
2832 INITIALIZE_DEVICE_IIFORMAT (gtk, progress_gauge); | |
2833 IIFORMAT_HAS_DEVMETHOD (gtk, progress_gauge, redisplay); | |
2834 IIFORMAT_HAS_DEVMETHOD (gtk, progress_gauge, instantiate); | |
2168 | 2835 IIFORMAT_HAS_SHARED_DEVMETHOD (gtk, progress_gauge, query_geometry, widget); |
462 | 2836 /* text field */ |
2837 INITIALIZE_DEVICE_IIFORMAT (gtk, edit_field); | |
2838 IIFORMAT_HAS_DEVMETHOD (gtk, edit_field, instantiate); | |
2839 INITIALIZE_DEVICE_IIFORMAT (gtk, combo_box); | |
2840 IIFORMAT_HAS_DEVMETHOD (gtk, combo_box, instantiate); | |
2841 IIFORMAT_HAS_SHARED_DEVMETHOD (gtk, combo_box, redisplay, tab_control); | |
2842 /* tab control widget */ | |
2843 INITIALIZE_DEVICE_IIFORMAT (gtk, tab_control); | |
2844 IIFORMAT_HAS_DEVMETHOD (gtk, tab_control, instantiate); | |
2845 IIFORMAT_HAS_DEVMETHOD (gtk, tab_control, redisplay); | |
2168 | 2846 IIFORMAT_HAS_SHARED_DEVMETHOD (gtk, tab_control, query_geometry, widget); |
462 | 2847 /* label */ |
2848 INITIALIZE_DEVICE_IIFORMAT (gtk, label); | |
2849 IIFORMAT_HAS_DEVMETHOD (gtk, label, instantiate); | |
2850 #endif | |
2851 | |
2852 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (cursor_font, "cursor-font"); | |
2853 IIFORMAT_VALID_CONSOLE (gtk, cursor_font); | |
2854 | |
2855 IIFORMAT_HAS_METHOD (cursor_font, validate); | |
2856 IIFORMAT_HAS_METHOD (cursor_font, possible_dest_types); | |
2857 IIFORMAT_HAS_METHOD (cursor_font, instantiate); | |
2858 | |
2859 IIFORMAT_VALID_KEYWORD (cursor_font, Q_data, check_valid_string); | |
2860 IIFORMAT_VALID_KEYWORD (cursor_font, Q_foreground, check_valid_string); | |
2861 IIFORMAT_VALID_KEYWORD (cursor_font, Q_background, check_valid_string); | |
2862 | |
2863 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (font, "font"); | |
2864 IIFORMAT_VALID_CONSOLE (gtk, font); | |
2865 | |
2866 IIFORMAT_HAS_METHOD (font, validate); | |
2867 IIFORMAT_HAS_METHOD (font, possible_dest_types); | |
2868 IIFORMAT_HAS_METHOD (font, instantiate); | |
2869 | |
2870 IIFORMAT_VALID_KEYWORD (font, Q_data, check_valid_string); | |
2871 IIFORMAT_VALID_KEYWORD (font, Q_foreground, check_valid_string); | |
2872 IIFORMAT_VALID_KEYWORD (font, Q_background, check_valid_string); | |
2873 | |
2874 #ifdef HAVE_XPM | |
2875 INITIALIZE_DEVICE_IIFORMAT (gtk, xpm); | |
2876 IIFORMAT_HAS_DEVMETHOD (gtk, xpm, instantiate); | |
2877 #endif | |
2878 | |
2879 #ifdef HAVE_XFACE | |
2880 INITIALIZE_DEVICE_IIFORMAT (gtk, xface); | |
2881 IIFORMAT_HAS_DEVMETHOD (gtk, xface, instantiate); | |
2882 #endif | |
2883 | |
2884 INITIALIZE_DEVICE_IIFORMAT (gtk, xbm); | |
2885 IIFORMAT_HAS_DEVMETHOD (gtk, xbm, instantiate); | |
2886 IIFORMAT_VALID_CONSOLE (gtk, xbm); | |
2887 | |
2888 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (gtk_resource, "gtk-resource"); | |
2889 IIFORMAT_VALID_CONSOLE (gtk, gtk_resource); | |
2890 | |
2891 IIFORMAT_HAS_METHOD (gtk_resource, validate); | |
2892 IIFORMAT_HAS_METHOD (gtk_resource, normalize); | |
2893 IIFORMAT_HAS_METHOD (gtk_resource, possible_dest_types); | |
2894 IIFORMAT_HAS_METHOD (gtk_resource, instantiate); | |
2895 | |
2896 IIFORMAT_VALID_KEYWORD (gtk_resource, Q_resource_type, check_valid_resource_symbol); | |
2897 IIFORMAT_VALID_KEYWORD (gtk_resource, Q_resource_id, check_valid_resource_id); | |
2898 IIFORMAT_VALID_KEYWORD (gtk_resource, Q_file, check_valid_string); | |
2899 | |
2900 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (autodetect, "autodetect"); | |
2901 IIFORMAT_VALID_CONSOLE (gtk, autodetect); | |
2902 | |
2903 IIFORMAT_HAS_METHOD (autodetect, validate); | |
2904 IIFORMAT_HAS_METHOD (autodetect, normalize); | |
2905 IIFORMAT_HAS_METHOD (autodetect, possible_dest_types); | |
2906 IIFORMAT_HAS_METHOD (autodetect, instantiate); | |
2907 | |
2908 IIFORMAT_VALID_KEYWORD (autodetect, Q_data, check_valid_string); | |
2909 } | |
2910 | |
2911 void | |
2912 vars_of_glyphs_gtk (void) | |
2913 { | |
2914 #ifdef HAVE_XFACE | |
2915 Fprovide (Qxface); | |
2916 #endif | |
2917 | |
2918 DEFVAR_LISP ("gtk-bitmap-file-path", &Vgtk_bitmap_file_path /* | |
2919 A list of the directories in which X bitmap files may be found. | |
2920 If nil, this is initialized from the "*bitmapFilePath" resource. | |
2921 This is used by the `make-image-instance' function (however, note that if | |
2922 the environment variable XBMLANGPATH is set, it is consulted first). | |
2923 */ ); | |
2924 Vgtk_bitmap_file_path = Qnil; | |
2925 } | |
2926 | |
2927 void | |
2928 complex_vars_of_glyphs_gtk (void) | |
2929 { | |
2930 #define BUILD_GLYPH_INST(variable, name) \ | |
2931 Fadd_spec_to_specifier \ | |
2932 (GLYPH_IMAGE (XGLYPH (variable)), \ | |
2933 vector3 (Qxbm, Q_data, \ | |
2934 list3 (make_int (name##_width), \ | |
2935 make_int (name##_height), \ | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
2936 make_extstring ((Extbyte*) name##_bits, \ |
462 | 2937 sizeof (name##_bits), \ |
2938 Qbinary))), \ | |
2939 Qglobal, Qgtk, Qnil) | |
2940 | |
2941 BUILD_GLYPH_INST (Vtruncation_glyph, truncator); | |
2942 BUILD_GLYPH_INST (Vcontinuation_glyph, continuer); | |
2943 BUILD_GLYPH_INST (Vxemacs_logo, xemacs); | |
2944 BUILD_GLYPH_INST (Vhscroll_glyph, hscroll); | |
2945 | |
2946 #undef BUILD_GLYPH_INST | |
2947 } | |
2948 | |
2949 /* X specific crap */ | |
4908
b3ce27ca7647
various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents:
4700
diff
changeset
|
2950 #include "sysgdkx.h" |
462 | 2951 /* #### Should remove all this X specific stuff when GTK/GDK matures a |
2952 bit more and provides an abstraction for it. */ | |
2953 static int | |
2954 gtk_colorize_image_instance (Lisp_Object image_instance, | |
2955 Lisp_Object foreground, Lisp_Object background) | |
2956 { | |
2957 struct Lisp_Image_Instance *p; | |
2958 | |
2959 p = XIMAGE_INSTANCE (image_instance); | |
2960 | |
2961 switch (IMAGE_INSTANCE_TYPE (p)) | |
2962 { | |
2963 case IMAGE_MONO_PIXMAP: | |
2964 IMAGE_INSTANCE_TYPE (p) = IMAGE_COLOR_PIXMAP; | |
2965 /* Make sure there aren't two pointers to the same mask, causing | |
2966 it to get freed twice. */ | |
4433
1bf48c59700e
Fix old use of rvalue on lhs to placate gcc >4.0.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4252
diff
changeset
|
2967 IMAGE_INSTANCE_PIXMAP_MASK (p) = 0; |
462 | 2968 break; |
2969 | |
2970 default: | |
2971 return 0; | |
2972 } | |
2973 | |
2974 { | |
2975 GdkWindow *draw = GET_GTK_WIDGET_WINDOW (DEVICE_GTK_APP_SHELL (XDEVICE (IMAGE_INSTANCE_DEVICE (p)))); | |
2976 GdkPixmap *new_pxmp = gdk_pixmap_new (draw, | |
2977 IMAGE_INSTANCE_PIXMAP_WIDTH (p), | |
2978 IMAGE_INSTANCE_PIXMAP_HEIGHT (p), | |
2979 DEVICE_GTK_DEPTH (XDEVICE (IMAGE_INSTANCE_DEVICE (p)))); | |
2980 GdkGCValues gcv; | |
2981 GdkGC *gc; | |
2982 | |
2983 gcv.foreground = * COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (foreground)); | |
2984 gcv.background = * COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (background)); | |
2054 | 2985 gc = gdk_gc_new_with_values (new_pxmp, &gcv, |
2986 (GdkGCValuesMask) (GDK_GC_BACKGROUND | GDK_GC_FOREGROUND)); | |
462 | 2987 |
2988 XCopyPlane (GDK_WINDOW_XDISPLAY (draw), | |
2989 GDK_WINDOW_XWINDOW (IMAGE_INSTANCE_GTK_PIXMAP (p)), | |
2990 GDK_WINDOW_XWINDOW (new_pxmp), | |
2991 GDK_GC_XGC (gc), 0, 0, | |
2992 IMAGE_INSTANCE_PIXMAP_WIDTH (p), | |
2993 IMAGE_INSTANCE_PIXMAP_HEIGHT (p), | |
2994 0, 0, 1); | |
2995 | |
2996 gdk_gc_destroy (gc); | |
2997 IMAGE_INSTANCE_GTK_PIXMAP (p) = new_pxmp; | |
2998 IMAGE_INSTANCE_PIXMAP_DEPTH (p) = DEVICE_GTK_DEPTH (XDEVICE (IMAGE_INSTANCE_DEVICE (p))); | |
2999 IMAGE_INSTANCE_PIXMAP_FG (p) = foreground; | |
3000 IMAGE_INSTANCE_PIXMAP_BG (p) = background; | |
3001 return 1; | |
3002 } | |
3003 } |