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