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