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