Mercurial > hg > xemacs-beta
annotate src/glyphs-msw.c @ 4976:16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
-------------------- ChangeLog entries follow: --------------------
src/ChangeLog addition:
2010-02-04 Ben Wing <ben@xemacs.org>
* alloc.c (release_breathing_space):
* alloc.c (resize_string):
* alloc.c (sweep_lcrecords_1):
* alloc.c (SWEEP_FIXED_TYPE_BLOCK_1):
* alloc.c (ADDITIONAL_FREE_compiled_function):
* alloc.c (compact_string_chars):
* alloc.c (ADDITIONAL_FREE_string):
* alloc.c (sweep_strings):
* alloca.c (xemacs_c_alloca):
* alsaplay.c (alsa_play_sound_file):
* buffer.c (init_initial_directory):
* buffer.h:
* buffer.h (BUFFER_FREE):
* console-stream.c (stream_delete_console):
* console-tty.c (free_tty_console_struct):
* data.c (Fnumber_to_string):
* device-gtk.c (gtk_init_device):
* device-gtk.c (free_gtk_device_struct):
* device-gtk.c (gtk_delete_device):
* device-msw.c (mswindows_delete_device):
* device-msw.c (msprinter_delete_device):
* device-tty.c (free_tty_device_struct):
* device-tty.c (tty_delete_device):
* device-x.c (x_init_device):
* device-x.c (free_x_device_struct):
* device-x.c (x_delete_device):
* dialog-msw.c (handle_directory_dialog_box):
* dialog-x.c (dbox_descriptor_to_widget_value):
* dired-msw.c (Fmswindows_insert_directory):
* dired.c (free_user_cache):
* dired.c (user_name_completion_unwind):
* doc.c (unparesseuxify_doc_string):
* doc.c (Fsubstitute_command_keys):
* doprnt.c (emacs_doprnt_1):
* dumper.c (pdump_load_finish):
* dumper.c (pdump_file_free):
* dumper.c (pdump_file_unmap):
* dynarr.c:
* dynarr.c (Dynarr_free):
* editfns.c (uncache_home_directory):
* editfns.c (Fset_time_zone_rule):
* elhash.c:
* elhash.c (pdump_reorganize_hash_table):
* elhash.c (maphash_unwind):
* emacs.c (make_arg_list_1):
* emacs.c (free_argc_argv):
* emacs.c (sort_args):
* emacs.c (Frunning_temacs_p):
* emodules.c (attempt_module_delete):
* eval.c (free_pointer):
* event-Xt.c (unselect_filedesc):
* event-Xt.c (emacs_Xt_select_process):
* event-gtk.c (unselect_filedesc):
* event-gtk.c (dragndrop_data_received):
* event-msw.c (winsock_closer):
* event-msw.c (mswindows_dde_callback):
* event-msw.c (mswindows_wnd_proc):
* event-stream.c (finalize_command_builder):
* event-stream.c (free_command_builder):
* extents.c (free_gap_array):
* extents.c (free_extent_list):
* extents.c (free_soe):
* extents.c (extent_fragment_delete):
* extents.c (extent_priority_sort_function):
* file-coding.c (make_coding_system_1):
* file-coding.c (coding_finalizer):
* file-coding.c (set_coding_stream_coding_system):
* file-coding.c (chain_finalize_coding_stream_1):
* file-coding.c (chain_finalize):
* file-coding.c (free_detection_state):
* file-coding.c (coding_category_symbol_to_id):
* fileio.c:
* fileio.c (Ffile_name_directory):
* fileio.c (if):
* fileio.c (Ffile_symlink_p):
* filelock.c (FREE_LOCK_INFO):
* filelock.c (current_lock_owner):
* font-mgr.c (Ffc_name_unparse):
* font-mgr.c (Ffc_pattern_duplicate):
* frame-gtk.c (gtk_delete_frame):
* frame-msw.c (mswindows_delete_frame):
* frame-msw.c (msprinter_delete_frame):
* frame-x.c (x_cde_destroy_callback):
* frame-x.c (Fcde_start_drag_internal):
* frame-x.c (x_cde_transfer_callback):
* frame-x.c (x_delete_frame):
* frame.c (update_frame_title):
* frame.c (Fset_frame_pointer):
* gc.c (register_for_finalization):
* gccache-gtk.c (free_gc_cache):
* gccache-gtk.c (gc_cache_lookup):
* gccache-x.c (free_gc_cache):
* gccache-x.c (gc_cache_lookup):
* glyphs-eimage.c:
* glyphs-eimage.c (jpeg_instantiate_unwind):
* glyphs-eimage.c (gif_instantiate_unwind):
* glyphs-eimage.c (png_instantiate_unwind):
* glyphs-eimage.c (png_instantiate):
* glyphs-eimage.c (tiff_instantiate_unwind):
* glyphs-gtk.c (convert_EImage_to_GDKImage):
* glyphs-gtk.c (gtk_finalize_image_instance):
* glyphs-gtk.c (gtk_init_image_instance_from_eimage):
* glyphs-gtk.c (gtk_xpm_instantiate):
* glyphs-msw.c (convert_EImage_to_DIBitmap):
* glyphs-msw.c (mswindows_init_image_instance_from_eimage):
* glyphs-msw.c (mswindows_initialize_image_instance_mask):
* glyphs-msw.c (xpm_to_eimage):
* glyphs-msw.c (mswindows_xpm_instantiate):
* glyphs-msw.c (xbm_create_bitmap_from_data):
* glyphs-msw.c (mswindows_finalize_image_instance):
* glyphs-x.c (convert_EImage_to_XImage):
* glyphs-x.c (x_finalize_image_instance):
* glyphs-x.c (x_init_image_instance_from_eimage):
* glyphs-x.c (x_xpm_instantiate):
* gui-x.c (free_popup_widget_value_tree):
* hash.c (free_hash_table):
* hash.c (grow_hash_table):
* hash.c (pregrow_hash_table_if_necessary):
* imgproc.c (build_EImage_quantable):
* insdel.c (uninit_buffer_text):
* intl-win32.c (convert_multibyte_to_internal_malloc):
* intl.c:
* intl.c (Fset_current_locale):
* keymap.c:
* keymap.c (where_is_recursive_mapper):
* keymap.c (where_is_internal):
* lisp.h:
* lisp.h (xfree):
* lstream.c (Lstream_close):
* lstream.c (resizing_buffer_closer):
* mule-coding.c:
* mule-coding.c (iso2022_finalize_detection_state):
* nt.c:
* nt.c (mswindows_get_long_filename):
* nt.c (nt_get_resource):
* nt.c (init_mswindows_environment):
* nt.c (get_cached_volume_information):
* nt.c (mswindows_opendir):
* nt.c (mswindows_closedir):
* nt.c (mswindows_readdir):
* nt.c (mswindows_stat):
* nt.c (mswindows_getdcwd):
* nt.c (Fmswindows_long_file_name):
* ntplay.c (nt_play_sound_file):
* ntplay.c (play_sound_data_1):
* number-gmp.c (gmp_free):
* number-gmp.c (init_number_gmp):
* number-mp.c (bignum_to_string):
* number-mp.c (BIGNUM_TO_TYPE):
* number.c (bignum_print):
* number.c (bignum_convfree):
* number.c (ratio_print):
* number.c (bigfloat_print):
* number.c (bigfloat_finalize):
* objects-gtk.c (gtk_finalize_color_instance):
* objects-gtk.c (gtk_finalize_font_instance):
* objects-msw.c (mswindows_finalize_color_instance):
* objects-msw.c (mswindows_finalize_font_instance):
* objects-tty.c (tty_finalize_color_instance):
* objects-tty.c (tty_finalize_font_instance):
* objects-tty.c (tty_font_list):
* objects-x.c (x_finalize_color_instance):
* objects-x.c (x_finalize_font_instance):
* process.c:
* process.c (finalize_process):
* realpath.c:
* redisplay.c (add_propagation_runes):
* regex.c:
* regex.c (xfree):
* regex.c (REGEX_FREE_STACK):
* regex.c (FREE_STACK_RETURN):
* regex.c (regex_compile):
* regex.c (regexec):
* regex.c (regfree):
* scrollbar-gtk.c (gtk_free_scrollbar_instance):
* scrollbar-gtk.c (gtk_release_scrollbar_instance):
* scrollbar-msw.c (mswindows_free_scrollbar_instance):
* scrollbar-msw.c (unshow_that_mofo):
* scrollbar-x.c (x_free_scrollbar_instance):
* scrollbar-x.c (x_release_scrollbar_instance):
* select-gtk.c (emacs_gtk_selection_handle):
* select-msw.c (mswindows_own_selection):
* select-x.c:
* select-x.c (x_handle_selection_request):
* select-x.c (unexpect_property_change):
* select-x.c (x_handle_property_notify):
* select-x.c (receive_incremental_selection):
* select-x.c (x_get_window_property_as_lisp_data):
* select-x.c (Fx_get_cutbuffer_internal):
* specifier.c (finalize_specifier):
* syntax.c (uninit_buffer_syntax_cache):
* sysdep.c (qxe_allocating_getcwd):
* sysdep.c (qxe_lstat):
* sysdep.c (copy_in_passwd):
* sysdep.c (qxe_ctime):
* sysdep.c (closedir):
* sysdep.c (DIRSIZ):
* termcap.c (tgetent):
* termcap.c (tprint):
* tests.c (Ftest_data_format_conversion):
* text.c (new_dfc_convert_copy_data):
* text.h (eifree):
* text.h (eito_alloca):
* text.h (eito_external):
* toolbar-msw.c (mswindows_output_toolbar):
* ui-gtk.c (CONVERT_RETVAL):
* ui-gtk.c (__allocate_object_storage):
* unicode.c (free_from_unicode_table):
* unicode.c (free_to_unicode_table):
* unicode.c (free_charset_unicode_tables):
* win32.c (mswindows_read_link_1):
Rename: xfree(VAL, TYPE)->xfree(VAL)
Command used:
gr 'xfree *\((.*),.*\);' 'xfree (\1);' *.[ch]
Followed by grepping for 'xfree.*,' and fixing anything left.
Rationale: Having to specify the TYPE argument is annoying and
error-prone. It was originally put in to work around warnings
due to strict aliasing but years and years ago I rewrote it
in a way that doesn't use the TYPE argument at all and no one
has complained since then. (And anyway, XEmacs is far from
ever being in compliance with strict aliasing and would require
far-reaching changes to get that way.)
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Thu, 04 Feb 2010 07:28:14 -0600 |
parents | 19a72041c5ed |
children | 3c3c1d139863 |
rev | line source |
---|---|
428 | 1 /* mswindows-specific glyph objects. |
438 | 2 Copyright (C) 1998, 1999, 2000 Andy Piper. |
2959 | 3 Copyright (C) 2001, 2002, 2003, 2004, 2005 Ben Wing. |
434 | 4 |
428 | 5 This file is part of XEmacs. |
6 | |
7 XEmacs is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
9 Free Software Foundation; either version 2, or (at your option) any | |
10 later version. | |
11 | |
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with XEmacs; see the file COPYING. If not, write to | |
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
20 Boston, MA 02111-1307, USA. */ | |
21 | |
22 /* Synched up with: Not in FSF. */ | |
23 | |
771 | 24 /* This file apparently Mule-ized, 8-7-2000, but could stand review. */ |
25 | |
442 | 26 /* written by Andy Piper <andy@xemacs.org> plagiarising bits from |
428 | 27 glyphs-x.c */ |
28 | |
771 | 29 #define NEED_MSWINDOWS_COMMCTRL |
30 | |
428 | 31 #include <config.h> |
32 #include "lisp.h" | |
800 | 33 |
872 | 34 #include "device-impl.h" |
800 | 35 #include "elhash.h" |
36 #include "faces.h" | |
37 #include "file-coding.h" | |
872 | 38 #include "frame-impl.h" |
800 | 39 #include "gui.h" |
40 #include "imgproc.h" | |
41 #include "insdel.h" | |
428 | 42 #include "lstream.h" |
800 | 43 #include "opaque.h" |
44 #include "sysdep.h" | |
45 #include "sysfile.h" | |
46 #include "window.h" | |
428 | 47 |
872 | 48 #include "console-msw-impl.h" |
428 | 49 #include "glyphs-msw.h" |
872 | 50 #include "objects-msw-impl.h" |
428 | 51 |
52 #define WIDGET_GLYPH_SLOT 0 | |
53 | |
54 DECLARE_IMAGE_INSTANTIATOR_FORMAT (nothing); | |
55 DECLARE_IMAGE_INSTANTIATOR_FORMAT (string); | |
56 DECLARE_IMAGE_INSTANTIATOR_FORMAT (formatted_string); | |
57 DECLARE_IMAGE_INSTANTIATOR_FORMAT (inherit); | |
58 #ifdef HAVE_JPEG | |
59 DECLARE_IMAGE_INSTANTIATOR_FORMAT (jpeg); | |
60 #endif | |
61 #ifdef HAVE_TIFF | |
62 DECLARE_IMAGE_INSTANTIATOR_FORMAT (tiff); | |
434 | 63 #endif |
428 | 64 #ifdef HAVE_PNG |
65 DECLARE_IMAGE_INSTANTIATOR_FORMAT (png); | |
434 | 66 #endif |
428 | 67 #ifdef HAVE_GIF |
68 DECLARE_IMAGE_INSTANTIATOR_FORMAT (gif); | |
434 | 69 #endif |
428 | 70 #ifdef HAVE_XPM |
71 DEFINE_DEVICE_IIFORMAT (mswindows, xpm); | |
442 | 72 DEFINE_DEVICE_IIFORMAT (msprinter, xpm); |
428 | 73 #endif |
74 DEFINE_DEVICE_IIFORMAT (mswindows, xbm); | |
442 | 75 DEFINE_DEVICE_IIFORMAT (msprinter, xbm); |
428 | 76 #ifdef HAVE_XFACE |
77 DEFINE_DEVICE_IIFORMAT (mswindows, xface); | |
442 | 78 DEFINE_DEVICE_IIFORMAT (msprinter, xface); |
428 | 79 #endif |
442 | 80 DECLARE_IMAGE_INSTANTIATOR_FORMAT (layout); |
81 DEFINE_DEVICE_IIFORMAT (mswindows, native_layout); | |
428 | 82 DEFINE_DEVICE_IIFORMAT (mswindows, button); |
83 DEFINE_DEVICE_IIFORMAT (mswindows, edit_field); | |
84 DEFINE_DEVICE_IIFORMAT (mswindows, subwindow); | |
85 DEFINE_DEVICE_IIFORMAT (mswindows, widget); | |
86 DEFINE_DEVICE_IIFORMAT (mswindows, label); | |
87 DEFINE_DEVICE_IIFORMAT (mswindows, scrollbar); | |
88 DEFINE_DEVICE_IIFORMAT (mswindows, combo_box); | |
89 DEFINE_DEVICE_IIFORMAT (mswindows, progress_gauge); | |
90 DEFINE_DEVICE_IIFORMAT (mswindows, tree_view); | |
91 DEFINE_DEVICE_IIFORMAT (mswindows, tab_control); | |
92 | |
93 DEFINE_IMAGE_INSTANTIATOR_FORMAT (bmp); | |
94 Lisp_Object Qbmp; | |
95 Lisp_Object Vmswindows_bitmap_file_path; | |
96 static COLORREF transparent_color = RGB (1,1,1); | |
97 | |
98 DEFINE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource); | |
99 Lisp_Object Qmswindows_resource; | |
100 | |
101 static void | |
440 | 102 mswindows_initialize_dibitmap_image_instance (Lisp_Image_Instance *ii, |
428 | 103 int slices, |
104 enum image_instance_type type); | |
105 static void | |
771 | 106 mswindows_initialize_image_instance_mask (Lisp_Image_Instance *image, |
442 | 107 HDC hcdc); |
108 | |
109 /* | |
110 * Given device D, retrieve compatible device context. D can be either | |
111 * mswindows or an msprinter device. | |
112 */ | |
113 inline static HDC | |
114 get_device_compdc (struct device *d) | |
115 { | |
116 if (DEVICE_MSWINDOWS_P (d)) | |
117 return DEVICE_MSWINDOWS_HCDC (d); | |
118 else | |
119 return DEVICE_MSPRINTER_HCDC (d); | |
120 } | |
121 | |
122 /* | |
123 * Initialize image instance pixel sizes in II. For a display bitmap, | |
124 * these will be same as real bitmap sizes. For a printer bitmap, | |
125 * these will be scaled up so that the bitmap is proportionally enlarged | |
126 * when output to printer. Redisplay code takes care of scaling, to | |
127 * conserve memory we do not really scale bitmaps. Set the watermark | |
128 * only here. | |
129 * #### Add support for unscalable bitmaps. | |
130 */ | |
131 static void init_image_instance_geometry (Lisp_Image_Instance *ii) | |
132 { | |
133 struct device *d = DOMAIN_XDEVICE (ii->domain); | |
134 | |
135 if (/* #### Scaleable && */ DEVICE_MSPRINTER_P (d)) | |
136 { | |
137 HDC printer_dc = DEVICE_MSPRINTER_HCDC (d); | |
138 HDC display_dc = CreateCompatibleDC (NULL); | |
139 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = | |
140 MulDiv (IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii), | |
141 GetDeviceCaps (printer_dc, LOGPIXELSX), | |
142 GetDeviceCaps (display_dc, LOGPIXELSX)); | |
143 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = | |
144 MulDiv (IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii), | |
145 GetDeviceCaps (printer_dc, LOGPIXELSY), | |
146 GetDeviceCaps (display_dc, LOGPIXELSY)); | |
147 } | |
148 else | |
149 { | |
150 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = | |
151 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii); | |
152 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = | |
153 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii); | |
154 } | |
155 } | |
428 | 156 |
157 #define BPLINE(width) ((int)(~3UL & (unsigned long)((width) +3))) | |
158 | |
159 /************************************************************************/ | |
160 /* convert from a series of RGB triples to a BITMAPINFO formated for the*/ | |
161 /* proper display */ | |
162 /************************************************************************/ | |
771 | 163 static BITMAPINFO *convert_EImage_to_DIBitmap (Lisp_Object device, |
428 | 164 int width, int height, |
2367 | 165 Binbyte *pic, |
428 | 166 int *bit_count, |
2367 | 167 Binbyte **bmp_data) |
428 | 168 { |
169 struct device *d = XDEVICE (device); | |
771 | 170 int i, j; |
171 RGBQUAD *colortbl; | |
172 int ncolors; | |
173 BITMAPINFO *bmp_info; | |
2367 | 174 Binbyte *ip, *dp; |
428 | 175 |
442 | 176 if (GetDeviceCaps (get_device_compdc (d), BITSPIXEL) > 0) |
428 | 177 { |
178 int bpline = BPLINE(width * 3); | |
179 /* FIXME: we can do this because 24bpp implies no color table, once | |
180 * we start palettizing this is no longer true. The X versions of | |
181 * this function quantises to 256 colors or bit masks down to a | |
182 * long. Windows can actually handle rgb triples in the raw so I | |
183 * don't see much point trying to optimize down to the best | |
184 * structure - unless it has memory / color allocation implications | |
185 * .... */ | |
771 | 186 bmp_info = xnew_and_zero (BITMAPINFO); |
434 | 187 |
428 | 188 if (!bmp_info) |
189 { | |
190 return NULL; | |
191 } | |
192 | |
771 | 193 bmp_info->bmiHeader.biBitCount = 24; /* just RGB triples for now */ |
194 bmp_info->bmiHeader.biCompression = BI_RGB; /* just RGB triples | |
195 for now */ | |
196 bmp_info->bmiHeader.biSizeImage = width * height * 3; | |
428 | 197 |
198 /* bitmap data needs to be in blue, green, red triples - in that | |
199 order, eimage is in RGB format so we need to convert */ | |
2367 | 200 *bmp_data = xnew_array_and_zero (Binbyte, bpline * height); |
428 | 201 *bit_count = bpline * height; |
202 | |
203 if (!bmp_data) | |
204 { | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
205 xfree (bmp_info); |
428 | 206 return NULL; |
207 } | |
208 | |
209 ip = pic; | |
210 for (i = height-1; i >= 0; i--) { | |
211 dp = (*bmp_data) + (i * bpline); | |
212 for (j = 0; j < width; j++) { | |
771 | 213 dp[2] = *ip++; |
214 dp[1] = *ip++; | |
215 *dp = *ip++; | |
428 | 216 dp += 3; |
217 } | |
218 } | |
219 } | |
220 else /* scale to 256 colors */ | |
221 { | |
222 int rd,gr,bl; | |
223 quant_table *qtable; | |
224 int bpline = BPLINE (width * 3); | |
225 /* Quantize the image and get a histogram while we're at it. | |
226 Do this first to save memory */ | |
227 qtable = build_EImage_quantable(pic, width, height, 256); | |
228 if (qtable == NULL) return NULL; | |
229 | |
230 /* use our quantize table to allocate the colors */ | |
231 ncolors = qtable->num_active_colors; | |
771 | 232 bmp_info = (BITMAPINFO *)xmalloc_and_zero (sizeof(BITMAPINFOHEADER) + |
428 | 233 sizeof(RGBQUAD) * ncolors); |
234 if (!bmp_info) | |
235 { | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
236 xfree (qtable); |
428 | 237 return NULL; |
238 } | |
239 | |
2367 | 240 colortbl = (RGBQUAD *) (((Binbyte *) bmp_info) + |
771 | 241 sizeof (BITMAPINFOHEADER)); |
242 | |
243 bmp_info->bmiHeader.biBitCount = 8; | |
244 bmp_info->bmiHeader.biCompression = BI_RGB; | |
245 bmp_info->bmiHeader.biSizeImage = bpline * height; | |
246 bmp_info->bmiHeader.biClrUsed = ncolors; | |
247 bmp_info->bmiHeader.biClrImportant = ncolors; | |
434 | 248 |
2367 | 249 *bmp_data = xnew_array_and_zero (Binbyte, bpline * height); |
428 | 250 *bit_count = bpline * height; |
251 | |
252 if (!*bmp_data) | |
253 { | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
254 xfree (qtable); |
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
255 xfree (bmp_info); |
428 | 256 return NULL; |
257 } | |
434 | 258 |
428 | 259 /* build up an RGBQUAD colortable */ |
442 | 260 for (i = 0; i < qtable->num_active_colors; i++) |
261 { | |
262 colortbl[i].rgbRed = (BYTE) qtable->rm[i]; | |
263 colortbl[i].rgbGreen = (BYTE) qtable->gm[i]; | |
264 colortbl[i].rgbBlue = (BYTE) qtable->bm[i]; | |
265 colortbl[i].rgbReserved = 0; | |
266 } | |
428 | 267 |
268 /* now build up the data. picture has to be upside-down and | |
269 back-to-front for msw bitmaps */ | |
270 ip = pic; | |
442 | 271 for (i = height-1; i >= 0; i--) |
272 { | |
273 dp = (*bmp_data) + (i * bpline); | |
274 for (j = 0; j < width; j++) | |
275 { | |
276 rd = *ip++; | |
277 gr = *ip++; | |
278 bl = *ip++; | |
279 *dp++ = QUANT_GET_COLOR (qtable,rd,gr,bl); | |
280 } | |
428 | 281 } |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
282 xfree (qtable); |
434 | 283 } |
428 | 284 /* fix up the standard stuff */ |
771 | 285 bmp_info->bmiHeader.biWidth = width; |
286 bmp_info->bmiHeader.biHeight = height; | |
287 bmp_info->bmiHeader.biPlanes = 1; | |
288 bmp_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |
289 bmp_info->bmiHeader.biXPelsPerMeter = 0; /* unless you know better */ | |
290 bmp_info->bmiHeader.biYPelsPerMeter = 0; | |
428 | 291 |
292 return bmp_info; | |
293 } | |
294 | |
295 /* Given a pixmap filename, look through all of the "standard" places | |
296 where the file might be located. Return a full pathname if found; | |
297 otherwise, return Qnil. */ | |
298 | |
299 static Lisp_Object | |
300 mswindows_locate_pixmap_file (Lisp_Object name) | |
301 { | |
302 /* This function can GC if IN_REDISPLAY is false */ | |
303 Lisp_Object found; | |
304 | |
305 /* Check non-absolute pathnames with a directory component relative to | |
306 the search path; that's the way Xt does it. */ | |
826 | 307 if (IS_DIRECTORY_SEP(string_byte (name, 0)) || |
308 (string_byte (name, 0) == '.' && | |
309 (IS_DIRECTORY_SEP(string_byte (name, 1)) || | |
310 (string_byte (name, 1) == '.' && | |
311 (IS_DIRECTORY_SEP(string_byte (name, 2))))))) | |
428 | 312 { |
313 if (!NILP (Ffile_readable_p (name))) | |
440 | 314 return Fexpand_file_name (name, Qnil); |
428 | 315 else |
316 return Qnil; | |
317 } | |
318 | |
319 if (locate_file (Vmswindows_bitmap_file_path, name, Qnil, &found, R_OK) < 0) | |
320 { | |
321 Lisp_Object temp = list1 (Vdata_directory); | |
322 struct gcpro gcpro1; | |
323 | |
324 GCPRO1 (temp); | |
325 locate_file (temp, name, Qnil, &found, R_OK); | |
326 UNGCPRO; | |
327 } | |
434 | 328 |
428 | 329 return found; |
330 } | |
331 | |
332 | |
333 /* Initialize an image instance from a bitmap | |
334 | |
335 DEST_MASK specifies the mask of allowed image types. | |
336 | |
337 If this fails, signal an error. INSTANTIATOR is only used | |
338 in the error message. */ | |
339 | |
340 static void | |
440 | 341 init_image_instance_from_dibitmap (Lisp_Image_Instance *ii, |
428 | 342 BITMAPINFO *bmp_info, |
343 int dest_mask, | |
344 void *bmp_data, | |
345 int bmp_bits, | |
346 int slices, | |
434 | 347 Lisp_Object instantiator, |
428 | 348 int x_hot, int y_hot, |
349 int create_mask) | |
350 { | |
442 | 351 struct device *d = XDEVICE (IMAGE_INSTANCE_DEVICE (ii)); |
771 | 352 void *bmp_buf = 0; |
442 | 353 enum image_instance_type type; |
428 | 354 HBITMAP bitmap; |
355 HDC hdc; | |
356 | |
357 if (dest_mask & IMAGE_COLOR_PIXMAP_MASK) | |
358 type = IMAGE_COLOR_PIXMAP; | |
359 else if (dest_mask & IMAGE_POINTER_MASK) | |
360 type = IMAGE_POINTER; | |
434 | 361 else |
428 | 362 incompatible_image_types (instantiator, dest_mask, |
363 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK); | |
442 | 364 |
365 hdc = get_device_compdc (d); | |
366 bitmap = CreateDIBSection (hdc, | |
367 bmp_info, | |
368 DIB_RGB_COLORS, | |
369 &bmp_buf, | |
370 0, 0); | |
428 | 371 |
372 if (!bitmap || !bmp_buf) | |
563 | 373 signal_image_error ("Unable to create bitmap", instantiator); |
428 | 374 |
375 /* copy in the actual bitmap */ | |
376 memcpy (bmp_buf, bmp_data, bmp_bits); | |
377 | |
378 mswindows_initialize_dibitmap_image_instance (ii, slices, type); | |
379 | |
380 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = | |
381 find_keyword_in_vector (instantiator, Q_file); | |
382 | |
383 /* Fixup a set of bitmaps. */ | |
384 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = bitmap; | |
385 | |
386 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL; | |
442 | 387 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii) = |
388 bmp_info->bmiHeader.biWidth; | |
389 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii) = | |
390 bmp_info->bmiHeader.biHeight; | |
391 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = bmp_info->bmiHeader.biBitCount; | |
793 | 392 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = make_int (x_hot); |
393 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = make_int (y_hot); | |
442 | 394 init_image_instance_geometry (ii); |
428 | 395 |
396 if (create_mask) | |
397 { | |
442 | 398 mswindows_initialize_image_instance_mask (ii, hdc); |
428 | 399 } |
434 | 400 |
428 | 401 if (type == IMAGE_POINTER) |
402 { | |
403 mswindows_initialize_image_instance_icon(ii, TRUE); | |
404 } | |
405 } | |
406 | |
407 static void | |
440 | 408 image_instance_add_dibitmap (Lisp_Image_Instance *ii, |
428 | 409 BITMAPINFO *bmp_info, |
410 void *bmp_data, | |
411 int bmp_bits, | |
412 int slice, | |
413 Lisp_Object instantiator) | |
414 { | |
442 | 415 struct device *d = XDEVICE (IMAGE_INSTANCE_DEVICE (ii)); |
771 | 416 void *bmp_buf = 0; |
442 | 417 |
418 HBITMAP bitmap = CreateDIBSection (get_device_compdc (d), | |
428 | 419 bmp_info, |
420 DIB_RGB_COLORS, | |
434 | 421 &bmp_buf, |
428 | 422 0,0); |
434 | 423 |
428 | 424 if (!bitmap || !bmp_buf) |
563 | 425 signal_image_error ("Unable to create bitmap", instantiator); |
428 | 426 |
427 /* copy in the actual bitmap */ | |
428 memcpy (bmp_buf, bmp_data, bmp_bits); | |
429 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (ii, slice) = bitmap; | |
430 } | |
431 | |
432 static void | |
440 | 433 mswindows_init_image_instance_from_eimage (Lisp_Image_Instance *ii, |
428 | 434 int width, int height, |
435 int slices, | |
2367 | 436 Binbyte *eimage, |
428 | 437 int dest_mask, |
438 Lisp_Object instantiator, | |
2959 | 439 Lisp_Object UNUSED (pointer_fg), |
440 Lisp_Object UNUSED (pointer_bg), | |
428 | 441 Lisp_Object domain) |
442 { | |
443 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); | |
771 | 444 BITMAPINFO * bmp_info; |
2367 | 445 Binbyte * bmp_data; |
428 | 446 int bmp_bits; |
447 COLORREF bkcolor; | |
448 int slice; | |
434 | 449 |
442 | 450 CHECK_MSGDI_DEVICE (device); |
428 | 451 |
452 /* this is a hack but MaskBlt and TransparentBlt are not supported | |
453 on most windows variants */ | |
434 | 454 bkcolor = COLOR_INSTANCE_MSWINDOWS_COLOR |
428 | 455 (XCOLOR_INSTANCE (FACE_BACKGROUND (Vdefault_face, domain))); |
456 | |
457 for (slice = 0; slice < slices; slice++) | |
458 { | |
459 /* build a bitmap from the eimage */ | |
771 | 460 if (!(bmp_info = convert_EImage_to_DIBitmap (device, width, height, |
428 | 461 eimage + (width * height * 3 * slice), |
462 &bmp_bits, &bmp_data))) | |
463 { | |
563 | 464 signal_image_error ("EImage to DIBitmap conversion failed", |
465 instantiator); | |
428 | 466 } |
467 | |
468 /* Now create the pixmap and set up the image instance */ | |
469 if (slice == 0) | |
470 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask, | |
471 bmp_data, bmp_bits, slices, instantiator, | |
472 0, 0, 0); | |
473 else | |
474 image_instance_add_dibitmap (ii, bmp_info, bmp_data, bmp_bits, slice, | |
475 instantiator); | |
434 | 476 |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
477 xfree (bmp_info); |
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
478 xfree (bmp_data); |
428 | 479 } |
480 } | |
481 | |
442 | 482 inline static void |
2367 | 483 set_mono_pixel (Binbyte *bits, |
442 | 484 int bpline, int height, |
485 int x, int y, int white) | |
434 | 486 { |
438 | 487 int i; |
2367 | 488 Binbyte bitnum; |
428 | 489 /* Find the byte on which this scanline begins */ |
438 | 490 i = (height - y - 1) * bpline; |
428 | 491 /* Find the byte containing this pixel */ |
438 | 492 i += (x >> 3); |
428 | 493 /* Which bit is it? */ |
2367 | 494 bitnum = (Binbyte) (7 - (x & 7)); |
442 | 495 if (white) /* Turn it on */ |
496 bits[i] |= (1 << bitnum); | |
497 else /* Turn it off */ | |
498 bits[i] &= ~(1 << bitnum); | |
434 | 499 } |
428 | 500 |
501 static void | |
771 | 502 mswindows_initialize_image_instance_mask (Lisp_Image_Instance *image, |
442 | 503 HDC hcdc) |
428 | 504 { |
505 HBITMAP mask; | |
506 HGDIOBJ old = NULL; | |
2367 | 507 Binbyte *dibits, *and_bits; |
442 | 508 BITMAPINFO *bmp_info = |
771 | 509 (BITMAPINFO *) xmalloc_and_zero (sizeof (BITMAPINFO) + sizeof (RGBQUAD)); |
428 | 510 int i, j; |
442 | 511 int height = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (image); |
512 | |
513 int maskbpline = BPLINE ((IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image) + 7) / 8); | |
514 int bpline = BPLINE (IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image) * 3); | |
428 | 515 |
516 if (!bmp_info) | |
517 return; | |
518 | |
771 | 519 bmp_info->bmiHeader.biWidth = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image); |
428 | 520 bmp_info->bmiHeader.biHeight = height; |
442 | 521 bmp_info->bmiHeader.biPlanes = 1; |
771 | 522 bmp_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); |
442 | 523 bmp_info->bmiHeader.biBitCount = 1; |
524 bmp_info->bmiHeader.biCompression = BI_RGB; | |
434 | 525 bmp_info->bmiHeader.biClrUsed = 2; |
526 bmp_info->bmiHeader.biClrImportant = 2; | |
527 bmp_info->bmiHeader.biSizeImage = height * maskbpline; | |
428 | 528 bmp_info->bmiColors[0].rgbRed = 0; |
529 bmp_info->bmiColors[0].rgbGreen = 0; | |
530 bmp_info->bmiColors[0].rgbBlue = 0; | |
531 bmp_info->bmiColors[0].rgbReserved = 0; | |
532 bmp_info->bmiColors[1].rgbRed = 255; | |
533 bmp_info->bmiColors[1].rgbGreen = 255; | |
534 bmp_info->bmiColors[1].rgbBlue = 255; | |
535 bmp_info->bmiColors[0].rgbReserved = 0; | |
434 | 536 |
537 if (!(mask = CreateDIBSection (hcdc, | |
428 | 538 bmp_info, |
539 DIB_RGB_COLORS, | |
2367 | 540 /* The intermediate cast fools gcc into |
541 not outputting strict-aliasing | |
542 complaints */ | |
543 (void **) (void *) &and_bits, | |
428 | 544 0,0))) |
545 { | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
546 xfree (bmp_info); |
428 | 547 return; |
548 } | |
549 | |
550 old = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (image)); | |
551 /* build up an in-memory set of bits to mess with */ | |
552 xzero (*bmp_info); | |
553 | |
442 | 554 bmp_info->bmiHeader.biWidth = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image); |
428 | 555 bmp_info->bmiHeader.biHeight = -height; |
442 | 556 bmp_info->bmiHeader.biPlanes = 1; |
557 bmp_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |
558 bmp_info->bmiHeader.biBitCount = 24; | |
559 bmp_info->bmiHeader.biCompression = BI_RGB; | |
434 | 560 bmp_info->bmiHeader.biClrUsed = 0; |
561 bmp_info->bmiHeader.biClrImportant = 0; | |
428 | 562 bmp_info->bmiHeader.biSizeImage = height * bpline; |
563 | |
2367 | 564 dibits = xnew_array_and_zero (Binbyte, bpline * height); |
428 | 565 if (GetDIBits (hcdc, |
566 IMAGE_INSTANCE_MSWINDOWS_BITMAP (image), | |
567 0, | |
568 height, | |
569 dibits, | |
570 bmp_info, | |
571 DIB_RGB_COLORS) <= 0) | |
572 { | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
573 xfree (bmp_info); |
428 | 574 return; |
575 } | |
576 | |
577 /* now set the colored bits in the mask and transparent ones to | |
578 black in the original */ | |
442 | 579 for (i = 0; i < IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (image); i++) |
434 | 580 { |
771 | 581 for (j = 0; j < height; j++) |
434 | 582 { |
2367 | 583 Binbyte *idx = &dibits[j * bpline + i * 3]; |
428 | 584 |
442 | 585 if (RGB (idx[2], idx[1], idx[0]) == transparent_color) |
434 | 586 { |
428 | 587 idx[0] = idx[1] = idx[2] = 0; |
442 | 588 set_mono_pixel (and_bits, maskbpline, height, i, j, TRUE); |
428 | 589 } |
434 | 590 else |
591 { | |
442 | 592 set_mono_pixel (and_bits, maskbpline, height, i, j, FALSE); |
428 | 593 } |
594 } | |
595 } | |
596 | |
597 SetDIBits (hcdc, | |
598 IMAGE_INSTANCE_MSWINDOWS_BITMAP (image), | |
599 0, | |
600 height, | |
601 dibits, | |
602 bmp_info, | |
603 DIB_RGB_COLORS); | |
604 | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
605 xfree (bmp_info); |
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
606 xfree (dibits); |
434 | 607 |
428 | 608 SelectObject(hcdc, old); |
609 | |
610 IMAGE_INSTANCE_MSWINDOWS_MASK (image) = mask; | |
611 } | |
612 | |
613 void | |
771 | 614 mswindows_initialize_image_instance_icon (Lisp_Image_Instance *image, |
428 | 615 int cursor) |
616 { | |
617 ICONINFO x_icon; | |
618 | |
619 /* we rely on windows to do any resizing necessary */ | |
771 | 620 x_icon.fIcon = cursor ? FALSE : TRUE; |
621 x_icon.xHotspot = XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (image)); | |
622 x_icon.yHotspot = XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (image)); | |
623 x_icon.hbmMask = IMAGE_INSTANCE_MSWINDOWS_MASK (image); | |
624 x_icon.hbmColor = IMAGE_INSTANCE_MSWINDOWS_BITMAP (image); | |
434 | 625 |
428 | 626 IMAGE_INSTANCE_MSWINDOWS_ICON (image)= |
627 CreateIconIndirect (&x_icon); | |
628 } | |
629 | |
442 | 630 static HBITMAP |
631 create_resized_bitmap (HBITMAP curbmp, struct frame *f, | |
632 int curx, int cury, | |
633 int newx, int newy) | |
428 | 634 { |
635 HBITMAP newbmp; | |
636 HGDIOBJ old1, old2; | |
442 | 637 |
638 HDC hcdc = get_device_compdc (XDEVICE (FRAME_DEVICE (f))); | |
434 | 639 HDC hdcDst = CreateCompatibleDC (hcdc); |
640 | |
442 | 641 old1 = SelectObject (hcdc, curbmp); |
434 | 642 |
428 | 643 newbmp = CreateCompatibleBitmap (hcdc, newx, newy); |
644 | |
645 old2 = SelectObject (hdcDst, newbmp); | |
434 | 646 |
428 | 647 if (!StretchBlt (hdcDst, 0, 0, newx, newy, |
434 | 648 hcdc, 0, 0, |
442 | 649 curx, |
650 cury, | |
428 | 651 SRCCOPY)) |
652 { | |
653 DeleteObject (newbmp); | |
654 DeleteDC (hdcDst); | |
655 return 0; | |
656 } | |
657 | |
658 SelectObject (hdcDst, old2); | |
659 SelectObject (hcdc, old1); | |
660 DeleteDC (hdcDst); | |
661 | |
662 return newbmp; | |
663 } | |
664 | |
665 HBITMAP | |
771 | 666 mswindows_create_resized_bitmap (Lisp_Image_Instance *ii, |
667 struct frame *f, | |
442 | 668 int newx, int newy) |
669 { | |
670 return create_resized_bitmap (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii), | |
671 f, | |
672 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii), | |
673 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii), | |
674 newx, newy); | |
675 } | |
676 | |
677 HBITMAP | |
771 | 678 mswindows_create_resized_mask (Lisp_Image_Instance *ii, |
679 struct frame *f, | |
428 | 680 int newx, int newy) |
681 { | |
442 | 682 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii) == NULL) |
683 return NULL; | |
684 | |
685 return create_resized_bitmap (IMAGE_INSTANCE_MSWINDOWS_MASK (ii), | |
686 f, | |
687 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii), | |
688 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii), | |
689 newx, newy); | |
428 | 690 } |
691 | |
442 | 692 #if 0 /* Currently unused */ |
693 /* #### Warning: This function is not correct anymore with | |
694 resizable printer bitmaps. If you uncomment it, clean it. --kkm */ | |
428 | 695 int |
771 | 696 mswindows_resize_dibitmap_instance (Lisp_Image_Instance *ii, |
697 struct frame *f, | |
428 | 698 int newx, int newy) |
699 { | |
700 HBITMAP newbmp = mswindows_create_resized_bitmap (ii, f, newx, newy); | |
701 HBITMAP newmask = mswindows_create_resized_mask (ii, f, newx, newy); | |
702 | |
703 if (!newbmp) | |
704 return FALSE; | |
434 | 705 |
428 | 706 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii)) |
707 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii)); | |
708 if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii)) | |
709 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (ii)); | |
710 | |
711 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = newbmp; | |
712 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = newmask; | |
713 IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = newx; | |
714 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = newy; | |
715 | |
716 return TRUE; | |
717 } | |
442 | 718 #endif |
428 | 719 |
720 /********************************************************************** | |
721 * XPM * | |
722 **********************************************************************/ | |
723 | |
724 #ifdef HAVE_XPM | |
725 | |
726 struct color_symbol | |
727 { | |
867 | 728 Ibyte * name; |
428 | 729 COLORREF color; |
730 }; | |
731 | |
771 | 732 static struct color_symbol * |
428 | 733 extract_xpm_color_names (Lisp_Object device, |
734 Lisp_Object domain, | |
735 Lisp_Object color_symbol_alist, | |
771 | 736 int *nsymbols) |
428 | 737 { |
738 /* This function can GC */ | |
739 Lisp_Object rest; | |
740 Lisp_Object results = Qnil; | |
741 int i, j; | |
742 struct color_symbol *colortbl; | |
743 struct gcpro gcpro1, gcpro2; | |
744 | |
745 GCPRO2 (results, device); | |
746 | |
747 /* We built up results to be (("name" . #<color>) ...) so that if an | |
748 error happens we don't lose any malloc()ed data, or more importantly, | |
749 leave any pixels allocated in the server. */ | |
750 i = 0; | |
751 LIST_LOOP (rest, color_symbol_alist) | |
752 { | |
753 Lisp_Object cons = XCAR (rest); | |
754 Lisp_Object name = XCAR (cons); | |
755 Lisp_Object value = XCDR (cons); | |
756 if (NILP (value)) | |
757 continue; | |
758 if (STRINGP (value)) | |
759 value = | |
760 Fmake_color_instance | |
793 | 761 (value, device, encode_error_behavior_flag (ERROR_ME_DEBUG_WARN)); |
428 | 762 else |
763 { | |
764 assert (COLOR_SPECIFIERP (value)); | |
765 value = Fspecifier_instance (value, domain, Qnil, Qnil); | |
766 } | |
767 if (NILP (value)) | |
768 continue; | |
769 results = noseeum_cons (noseeum_cons (name, value), results); | |
770 i++; | |
771 } | |
772 UNGCPRO; /* no more evaluation */ | |
773 | |
771 | 774 *nsymbols = i; |
428 | 775 if (i == 0) return 0; |
776 | |
777 colortbl = xnew_array_and_zero (struct color_symbol, i); | |
778 | |
771 | 779 for (j = 0; j < i; j++) |
428 | 780 { |
781 Lisp_Object cons = XCAR (results); | |
434 | 782 colortbl[j].color = |
428 | 783 COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (XCDR (cons))); |
784 | |
771 | 785 /* mustn't lose this when we return */ |
786 colortbl[j].name = qxestrdup (XSTRING_DATA (XCAR (cons))); | |
853 | 787 free_cons (cons); |
428 | 788 cons = results; |
789 results = XCDR (results); | |
853 | 790 free_cons (cons); |
428 | 791 } |
792 return colortbl; | |
793 } | |
794 | |
442 | 795 static int xpm_to_eimage (Lisp_Object image, const Extbyte *buffer, |
2367 | 796 Binbyte **data, |
771 | 797 int *width, int *height, |
798 int *x_hot, int *y_hot, | |
799 int *transp, | |
800 struct color_symbol *color_symbols, | |
428 | 801 int nsymbols) |
802 { | |
803 XpmImage xpmimage; | |
804 XpmInfo xpminfo; | |
805 int result, i, j, transp_idx, maskbpline; | |
2367 | 806 Binbyte *dptr; |
771 | 807 unsigned int *sptr; |
428 | 808 COLORREF color; /* the american spelling virus hits again .. */ |
771 | 809 COLORREF *colortbl; |
428 | 810 |
811 xzero (xpmimage); | |
812 xzero (xpminfo); | |
771 | 813 xpminfo.valuemask = XpmHotspot; |
814 *transp = FALSE; | |
815 | |
816 result = XpmCreateXpmImageFromBuffer ((char *)buffer, | |
428 | 817 &xpmimage, |
818 &xpminfo); | |
819 switch (result) | |
820 { | |
821 case XpmSuccess: | |
822 break; | |
823 case XpmFileInvalid: | |
824 { | |
563 | 825 signal_image_error ("Invalid XPM data", image); |
428 | 826 } |
827 case XpmNoMemory: | |
828 { | |
563 | 829 signal_double_image_error ("Parsing pixmap data", |
830 "out of memory", image); | |
428 | 831 } |
832 default: | |
833 { | |
563 | 834 signal_double_image_error_2 ("Parsing pixmap data", |
835 "unknown error", | |
836 make_int (result), image); | |
428 | 837 } |
838 } | |
434 | 839 |
428 | 840 *width = xpmimage.width; |
841 *height = xpmimage.height; | |
434 | 842 maskbpline = BPLINE ((~7UL & (unsigned long)(*width + 7)) / 8); |
843 | |
2367 | 844 *data = xnew_array_and_zero (Binbyte, *width * *height * 3); |
428 | 845 |
846 if (!*data) | |
847 { | |
848 XpmFreeXpmImage (&xpmimage); | |
849 XpmFreeXpmInfo (&xpminfo); | |
850 return 0; | |
851 } | |
852 | |
853 /* build a color table to speed things up */ | |
854 colortbl = xnew_array_and_zero (COLORREF, xpmimage.ncolors); | |
855 if (!colortbl) | |
856 { | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
857 xfree (*data); |
428 | 858 XpmFreeXpmImage (&xpmimage); |
859 XpmFreeXpmInfo (&xpminfo); | |
860 return 0; | |
861 } | |
862 | |
771 | 863 for (i = 0; i < (int) xpmimage.ncolors; i++) |
428 | 864 { |
865 /* goto alert!!!! */ | |
866 /* pick up symbolic colors in preference */ | |
867 if (xpmimage.colorTable[i].symbolic) | |
868 { | |
771 | 869 if (!strcasecmp (xpmimage.colorTable[i].symbolic, "BgColor") |
428 | 870 || |
771 | 871 !strcasecmp (xpmimage.colorTable[i].symbolic, "None")) |
428 | 872 { |
771 | 873 *transp = TRUE; |
874 colortbl[i] = transparent_color; | |
875 transp_idx = i; | |
428 | 876 goto label_found_color; |
877 } | |
878 else if (color_symbols) | |
879 { | |
771 | 880 for (j = 0; j < nsymbols; j++) |
428 | 881 { |
2367 | 882 if (!qxestrcmp_ascii (color_symbols[j].name, |
771 | 883 xpmimage.colorTable[i].symbolic)) |
428 | 884 { |
771 | 885 colortbl[i] = color_symbols[j].color; |
428 | 886 goto label_found_color; |
887 } | |
888 } | |
889 } | |
890 else if (xpmimage.colorTable[i].c_color == 0) | |
891 { | |
892 goto label_no_color; | |
893 } | |
894 } | |
895 /* pick up transparencies */ | |
771 | 896 if (!strcasecmp (xpmimage.colorTable[i].c_color, "None")) |
428 | 897 { |
771 | 898 *transp = TRUE; |
899 colortbl[i] = transparent_color; | |
900 transp_idx = i; | |
428 | 901 goto label_found_color; |
902 } | |
903 /* finally pick up a normal color spec */ | |
904 if (xpmimage.colorTable[i].c_color) | |
905 { | |
906 colortbl[i]= | |
867 | 907 mswindows_string_to_color ((Ibyte *) |
771 | 908 xpmimage.colorTable[i].c_color); |
428 | 909 goto label_found_color; |
910 } | |
434 | 911 |
428 | 912 label_no_color: |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
913 xfree (*data); |
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
914 xfree (colortbl); |
428 | 915 XpmFreeXpmImage (&xpmimage); |
916 XpmFreeXpmInfo (&xpminfo); | |
917 return 0; | |
434 | 918 |
428 | 919 label_found_color:; |
920 } | |
921 | |
922 /* convert the image */ | |
771 | 923 sptr = xpmimage.data; |
924 dptr= *data; | |
428 | 925 for (i = 0; i< *width * *height; i++) |
926 { | |
927 color = colortbl[*sptr++]; | |
928 | |
929 /* split out the 0x02bbggrr colorref into an rgb triple */ | |
930 *dptr++=GetRValue (color); /* red */ | |
931 *dptr++=GetGValue (color); /* green */ | |
932 *dptr++=GetBValue (color); /* blue */ | |
933 } | |
934 | |
771 | 935 *x_hot = xpminfo.x_hotspot; |
936 *y_hot = xpminfo.y_hotspot; | |
428 | 937 |
938 XpmFreeXpmImage (&xpmimage); | |
939 XpmFreeXpmInfo (&xpminfo); | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
940 xfree (colortbl); |
428 | 941 return TRUE; |
942 } | |
943 | |
944 static void | |
945 mswindows_xpm_instantiate (Lisp_Object image_instance, | |
946 Lisp_Object instantiator, | |
2286 | 947 Lisp_Object UNUSED (pointer_fg), |
948 Lisp_Object UNUSED (pointer_bg), | |
428 | 949 int dest_mask, Lisp_Object domain) |
950 { | |
440 | 951 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 952 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); |
442 | 953 const Extbyte *bytes; |
665 | 954 Bytecount len; |
2367 | 955 Binbyte *eimage; |
428 | 956 int width, height, x_hot, y_hot; |
957 BITMAPINFO* bmp_info; | |
2367 | 958 Binbyte* bmp_data; |
428 | 959 int bmp_bits; |
771 | 960 int nsymbols = 0, transp; |
961 struct color_symbol* color_symbols = NULL; | |
434 | 962 |
428 | 963 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); |
964 Lisp_Object color_symbol_alist = find_keyword_in_vector (instantiator, | |
965 Q_color_symbols); | |
966 | |
442 | 967 CHECK_MSGDI_DEVICE (device); |
428 | 968 |
969 assert (!NILP (data)); | |
970 | |
440 | 971 TO_EXTERNAL_FORMAT (LISP_STRING, data, |
972 ALLOCA, (bytes, len), | |
973 Qbinary); | |
428 | 974 |
975 /* in case we have color symbols */ | |
976 color_symbols = extract_xpm_color_names (device, domain, | |
977 color_symbol_alist, &nsymbols); | |
978 | |
979 /* convert to an eimage to make processing easier */ | |
980 if (!xpm_to_eimage (image_instance, bytes, &eimage, &width, &height, | |
981 &x_hot, &y_hot, &transp, color_symbols, nsymbols)) | |
982 { | |
563 | 983 signal_image_error ("XPM to EImage conversion failed", |
984 image_instance); | |
428 | 985 } |
434 | 986 |
428 | 987 if (color_symbols) |
988 { | |
989 while (nsymbols--) | |
990 { | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
991 xfree (color_symbols[nsymbols].name); |
428 | 992 } |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
993 xfree (color_symbols); |
428 | 994 } |
434 | 995 |
428 | 996 /* build a bitmap from the eimage */ |
771 | 997 if (!(bmp_info = convert_EImage_to_DIBitmap (device, width, height, eimage, |
428 | 998 &bmp_bits, &bmp_data))) |
999 { | |
563 | 1000 signal_image_error ("XPM to EImage conversion failed", |
1001 image_instance); | |
428 | 1002 } |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
1003 xfree (eimage); |
428 | 1004 |
1005 /* Now create the pixmap and set up the image instance */ | |
1006 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask, | |
1007 bmp_data, bmp_bits, 1, instantiator, | |
1008 x_hot, y_hot, transp); | |
1009 | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
1010 xfree (bmp_info); |
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
1011 xfree (bmp_data); |
428 | 1012 } |
1013 #endif /* HAVE_XPM */ | |
1014 | |
1015 /********************************************************************** | |
1016 * BMP * | |
1017 **********************************************************************/ | |
1018 | |
1019 static void | |
1020 bmp_validate (Lisp_Object instantiator) | |
1021 { | |
1022 file_or_data_must_be_present (instantiator); | |
1023 } | |
1024 | |
1025 static Lisp_Object | |
442 | 1026 bmp_normalize (Lisp_Object inst, Lisp_Object console_type, |
2286 | 1027 Lisp_Object UNUSED (dest_mask)) |
428 | 1028 { |
1029 return simple_image_type_normalize (inst, console_type, Qbmp); | |
1030 } | |
1031 | |
1032 static int | |
1033 bmp_possible_dest_types (void) | |
1034 { | |
1035 return IMAGE_COLOR_PIXMAP_MASK; | |
1036 } | |
1037 | |
1038 static void | |
1039 bmp_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
2286 | 1040 Lisp_Object UNUSED (pointer_fg), |
1041 Lisp_Object UNUSED (pointer_bg), | |
1042 int dest_mask, Lisp_Object UNUSED (domain)) | |
428 | 1043 { |
440 | 1044 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 1045 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); |
442 | 1046 const Extbyte *bytes; |
665 | 1047 Bytecount len; |
771 | 1048 BITMAPFILEHEADER * bmp_file_header; |
1049 BITMAPINFO * bmp_info; | |
1050 void * bmp_data; | |
428 | 1051 int bmp_bits; |
1052 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
1053 | |
442 | 1054 CHECK_MSGDI_DEVICE (device); |
428 | 1055 |
1056 assert (!NILP (data)); | |
1057 | |
440 | 1058 TO_EXTERNAL_FORMAT (LISP_STRING, data, |
1059 ALLOCA, (bytes, len), | |
1060 Qbinary); | |
434 | 1061 |
428 | 1062 /* Then slurp the image into memory, decoding along the way. |
1063 The result is the image in a simple one-byte-per-pixel | |
1064 format. */ | |
434 | 1065 |
771 | 1066 bmp_file_header = (BITMAPFILEHEADER *)bytes; |
1067 bmp_info = (BITMAPINFO *)(bytes + sizeof(BITMAPFILEHEADER)); | |
1068 bmp_data = (Extbyte *)bytes + bmp_file_header->bfOffBits; | |
428 | 1069 bmp_bits = bmp_file_header->bfSize - bmp_file_header->bfOffBits; |
1070 | |
1071 /* Now create the pixmap and set up the image instance */ | |
1072 init_image_instance_from_dibitmap (ii, bmp_info, dest_mask, | |
1073 bmp_data, bmp_bits, 1, instantiator, | |
1074 0, 0, 0); | |
1075 } | |
1076 | |
1077 | |
1078 /********************************************************************** | |
1079 * RESOURCES * | |
1080 **********************************************************************/ | |
1081 | |
1082 static void | |
1083 mswindows_resource_validate (Lisp_Object instantiator) | |
1084 { | |
563 | 1085 shared_resource_validate (instantiator); |
428 | 1086 } |
1087 | |
1088 static Lisp_Object | |
442 | 1089 mswindows_resource_normalize (Lisp_Object inst, Lisp_Object console_type, |
1090 Lisp_Object dest_mask) | |
428 | 1091 { |
563 | 1092 return shared_resource_normalize (inst, console_type, dest_mask, |
1093 Qmswindows_resource); | |
428 | 1094 } |
1095 | |
1096 static int | |
1097 mswindows_resource_possible_dest_types (void) | |
1098 { | |
1099 return IMAGE_POINTER_MASK | IMAGE_COLOR_PIXMAP_MASK; | |
1100 } | |
1101 | |
434 | 1102 typedef struct |
428 | 1103 { |
4932 | 1104 const Ascbyte *name; |
428 | 1105 int resource_id; |
1106 } resource_t; | |
1107 | |
442 | 1108 static const resource_t bitmap_table[] = |
428 | 1109 { |
1110 /* bitmaps */ | |
1111 { "close", OBM_CLOSE }, | |
1112 { "uparrow", OBM_UPARROW }, | |
1113 { "dnarrow", OBM_DNARROW }, | |
1114 { "rgarrow", OBM_RGARROW }, | |
1115 { "lfarrow", OBM_LFARROW }, | |
1116 { "reduce", OBM_REDUCE }, | |
1117 { "zoom", OBM_ZOOM }, | |
1118 { "restore", OBM_RESTORE }, | |
1119 { "reduced", OBM_REDUCED }, | |
1120 { "zoomd", OBM_ZOOMD }, | |
1121 { "restored", OBM_RESTORED }, | |
1122 { "uparrowd", OBM_UPARROWD }, | |
1123 { "dnarrowd", OBM_DNARROWD }, | |
1124 { "rgarrowd", OBM_RGARROWD }, | |
1125 { "lfarrowd", OBM_LFARROWD }, | |
1126 { "mnarrow", OBM_MNARROW }, | |
1127 { "combo", OBM_COMBO }, | |
1128 { "uparrowi", OBM_UPARROWI }, | |
1129 { "dnarrowi", OBM_DNARROWI }, | |
1130 { "rgarrowi", OBM_RGARROWI }, | |
1131 { "lfarrowi", OBM_LFARROWI }, | |
1132 { "size", OBM_SIZE }, | |
1133 { "btsize", OBM_BTSIZE }, | |
1134 { "check", OBM_CHECK }, | |
1135 { "checkboxes", OBM_CHECKBOXES }, | |
1136 { "btncorners" , OBM_BTNCORNERS }, | |
1137 {0} | |
1138 }; | |
1139 | |
442 | 1140 static const resource_t cursor_table[] = |
428 | 1141 { |
1142 /* cursors */ | |
1143 { "normal", OCR_NORMAL }, | |
1144 { "ibeam", OCR_IBEAM }, | |
1145 { "wait", OCR_WAIT }, | |
1146 { "cross", OCR_CROSS }, | |
1147 { "up", OCR_UP }, | |
1148 /* { "icon", OCR_ICON }, */ | |
1149 { "sizenwse", OCR_SIZENWSE }, | |
1150 { "sizenesw", OCR_SIZENESW }, | |
1151 { "sizewe", OCR_SIZEWE }, | |
1152 { "sizens", OCR_SIZENS }, | |
1153 { "sizeall", OCR_SIZEALL }, | |
1154 /* { "icour", OCR_ICOCUR }, */ | |
1155 { "no", OCR_NO }, | |
1156 { 0 } | |
1157 }; | |
1158 | |
442 | 1159 static const resource_t icon_table[] = |
428 | 1160 { |
1161 /* icons */ | |
1162 { "sample", OIC_SAMPLE }, | |
1163 { "hand", OIC_HAND }, | |
1164 { "ques", OIC_QUES }, | |
1165 { "bang", OIC_BANG }, | |
1166 { "note", OIC_NOTE }, | |
1167 { "winlogo", OIC_WINLOGO }, | |
1168 {0} | |
1169 }; | |
1170 | |
771 | 1171 static int |
1172 resource_name_to_resource (Lisp_Object name, int type) | |
428 | 1173 { |
771 | 1174 const resource_t *res = (type == IMAGE_CURSOR ? cursor_table |
434 | 1175 : type == IMAGE_ICON ? icon_table |
428 | 1176 : bitmap_table); |
1177 | |
1178 if (INTP (name)) | |
771 | 1179 return XINT (name); |
1180 else if (!STRINGP (name)) | |
1181 invalid_argument ("invalid resource identifier", name); | |
1182 | |
1183 do | |
428 | 1184 { |
867 | 1185 if (!qxestrcasecmp_i18n ((Ibyte *) res->name, XSTRING_DATA (name))) |
771 | 1186 return res->resource_id; |
428 | 1187 } |
771 | 1188 while ((++res)->name); |
428 | 1189 return 0; |
1190 } | |
1191 | |
1192 static int | |
1193 resource_symbol_to_type (Lisp_Object data) | |
1194 { | |
1195 if (EQ (data, Qcursor)) | |
1196 return IMAGE_CURSOR; | |
1197 else if (EQ (data, Qicon)) | |
1198 return IMAGE_ICON; | |
1199 else if (EQ (data, Qbitmap)) | |
1200 return IMAGE_BITMAP; | |
1201 else | |
1202 return 0; | |
1203 } | |
1204 | |
1205 static void | |
502 | 1206 mswindows_resource_instantiate (Lisp_Object image_instance, |
1207 Lisp_Object instantiator, | |
2286 | 1208 Lisp_Object UNUSED (pointer_fg), |
1209 Lisp_Object UNUSED (pointer_bg), | |
1210 int dest_mask, Lisp_Object UNUSED (domain)) | |
428 | 1211 { |
440 | 1212 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
647 | 1213 int type = 0; |
428 | 1214 HANDLE himage = NULL; |
771 | 1215 Extbyte *resid = 0; |
428 | 1216 HINSTANCE hinst = NULL; |
1217 ICONINFO iconinfo; | |
442 | 1218 enum image_instance_type iitype; |
428 | 1219 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); |
1220 | |
1221 Lisp_Object file = find_keyword_in_vector (instantiator, Q_file); | |
434 | 1222 Lisp_Object resource_type = find_keyword_in_vector (instantiator, |
428 | 1223 Q_resource_type); |
434 | 1224 Lisp_Object resource_id = find_keyword_in_vector (instantiator, |
428 | 1225 Q_resource_id); |
1226 | |
1227 xzero (iconinfo); | |
1228 | |
442 | 1229 CHECK_MSGDI_DEVICE (device); |
428 | 1230 |
1231 type = resource_symbol_to_type (resource_type); | |
1232 | |
1233 if (dest_mask & IMAGE_POINTER_MASK && type == IMAGE_CURSOR) | |
1234 iitype = IMAGE_POINTER; | |
1235 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK) | |
1236 iitype = IMAGE_COLOR_PIXMAP; | |
434 | 1237 else |
428 | 1238 incompatible_image_types (instantiator, dest_mask, |
1239 IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK); | |
1240 | |
1241 /* mess with the keyword info we were provided with */ | |
1242 if (!NILP (file)) | |
1243 { | |
771 | 1244 Extbyte *fname; |
1245 | |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
2959
diff
changeset
|
1246 LISP_LOCAL_FILE_FORMAT_TO_TSTR (file, fname); |
434 | 1247 |
428 | 1248 if (NILP (resource_id)) |
771 | 1249 resid = fname; |
428 | 1250 else |
1251 { | |
771 | 1252 hinst = qxeLoadLibraryEx (fname, NULL, LOAD_LIBRARY_AS_DATAFILE); |
428 | 1253 resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id, |
771 | 1254 type)); |
434 | 1255 |
428 | 1256 if (!resid) |
771 | 1257 LISP_STRING_TO_TSTR (resource_id, resid); |
428 | 1258 } |
1259 } | |
1260 else if (!(resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id, | |
771 | 1261 type)))) |
563 | 1262 invalid_argument ("Invalid resource identifier", resource_id); |
434 | 1263 |
428 | 1264 /* load the image */ |
771 | 1265 if (!(himage = qxeLoadImage (hinst, resid, type, 0, 0, |
1266 LR_CREATEDIBSECTION | LR_DEFAULTSIZE | | |
1267 LR_SHARED | | |
1268 (!NILP (file) ? LR_LOADFROMFILE : 0)))) | |
1269 signal_image_error ("Cannot load image", instantiator); | |
428 | 1270 |
1271 if (hinst) | |
1272 FreeLibrary (hinst); | |
1273 | |
1274 mswindows_initialize_dibitmap_image_instance (ii, 1, iitype); | |
1275 | |
1276 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = file; | |
442 | 1277 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii) = |
428 | 1278 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CXCURSOR : SM_CXICON); |
442 | 1279 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii) = |
428 | 1280 GetSystemMetrics (type == IMAGE_CURSOR ? SM_CYCURSOR : SM_CYICON); |
1281 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1; | |
442 | 1282 init_image_instance_geometry (ii); |
428 | 1283 |
1284 /* hey, we've got an icon type thing so we can reverse engineer the | |
1285 bitmap and mask */ | |
1286 if (type != IMAGE_BITMAP) | |
1287 { | |
442 | 1288 GetIconInfo ((HICON)himage, &iconinfo); |
428 | 1289 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = iconinfo.hbmColor; |
1290 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = iconinfo.hbmMask; | |
793 | 1291 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = make_int (iconinfo.xHotspot); |
1292 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = make_int (iconinfo.yHotspot); | |
442 | 1293 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = (HICON) himage; |
428 | 1294 } |
1295 else | |
1296 { | |
1297 IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = NULL; | |
442 | 1298 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = (HBITMAP) himage; |
428 | 1299 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL; |
793 | 1300 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = make_int (0); |
1301 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = make_int (0); | |
428 | 1302 } |
1303 } | |
1304 | |
1305 static void | |
1306 check_valid_resource_symbol (Lisp_Object data) | |
1307 { | |
1308 CHECK_SYMBOL (data); | |
1309 if (!resource_symbol_to_type (data)) | |
563 | 1310 invalid_constant ("invalid resource type", data); |
428 | 1311 } |
1312 | |
1313 static void | |
1314 check_valid_resource_id (Lisp_Object data) | |
1315 { | |
1316 if (!resource_name_to_resource (data, IMAGE_CURSOR) | |
1317 && | |
1318 !resource_name_to_resource (data, IMAGE_ICON) | |
1319 && | |
1320 !resource_name_to_resource (data, IMAGE_BITMAP)) | |
563 | 1321 invalid_constant ("invalid resource identifier", data); |
428 | 1322 } |
1323 | |
771 | 1324 |
428 | 1325 /********************************************************************** |
1326 * XBM * | |
1327 **********************************************************************/ | |
771 | 1328 |
428 | 1329 /* this table flips four bits around. */ |
1330 static int flip_table[] = | |
1331 { | |
1332 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 | |
1333 }; | |
1334 | |
1335 /* the bitmap data comes in the following format: Widths are padded to | |
1336 a multiple of 8. Scan lines are stored in increasing byte order | |
1337 from left to right, little-endian within a byte. 0 = white, 1 = | |
1338 black. It must be converted to the following format: Widths are | |
1339 padded to a multiple of 16. Scan lines are stored in increasing | |
1340 byte order from left to right, big-endian within a byte. 0 = | |
1341 black, 1 = white. */ | |
438 | 1342 static HBITMAP |
2367 | 1343 xbm_create_bitmap_from_data (HDC hdc, const Binbyte *data, |
647 | 1344 int width, int height, |
428 | 1345 int mask, COLORREF fg, COLORREF bg) |
1346 { | |
1347 int old_width = (width + 7)/8; | |
771 | 1348 int new_width = BPLINE (2 * ((width + 15)/16)); |
2367 | 1349 const Binbyte *offset; |
428 | 1350 void *bmp_buf = 0; |
2367 | 1351 Binbyte *new_data, *new_offset; |
428 | 1352 int i, j; |
442 | 1353 BITMAPINFO *bmp_info = |
771 | 1354 (BITMAPINFO *) xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD)); |
428 | 1355 HBITMAP bitmap; |
1356 | |
1357 if (!bmp_info) | |
1358 return NULL; | |
434 | 1359 |
2367 | 1360 new_data = xnew_array_and_zero (Binbyte, height * new_width); |
434 | 1361 |
428 | 1362 if (!new_data) |
1363 { | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
1364 xfree (bmp_info); |
428 | 1365 return NULL; |
1366 } | |
434 | 1367 |
771 | 1368 for (i = 0; i < height; i++) |
428 | 1369 { |
771 | 1370 offset = data + i * old_width; |
1371 new_offset = new_data + i * new_width; | |
1372 | |
1373 for (j = 0; j < old_width; j++) | |
428 | 1374 { |
771 | 1375 int bite = offset[j]; |
2367 | 1376 new_offset[j] = ~ (Binbyte) |
771 | 1377 ((flip_table[bite & 0xf] << 4) + flip_table[bite >> 4]); |
428 | 1378 } |
1379 } | |
1380 | |
1381 /* if we want a mask invert the bits */ | |
1382 if (!mask) | |
1383 { | |
1384 new_offset = &new_data[height * new_width]; | |
1385 while (new_offset-- != new_data) | |
1386 { | |
1387 *new_offset ^= 0xff; | |
1388 } | |
1389 } | |
1390 | |
771 | 1391 bmp_info->bmiHeader.biWidth = width; |
428 | 1392 bmp_info->bmiHeader.biHeight=-(LONG)height; |
771 | 1393 bmp_info->bmiHeader.biPlanes = 1; |
1394 bmp_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |
1395 bmp_info->bmiHeader.biBitCount = 1; | |
1396 bmp_info->bmiHeader.biCompression = BI_RGB; | |
434 | 1397 bmp_info->bmiHeader.biClrUsed = 2; |
1398 bmp_info->bmiHeader.biClrImportant = 2; | |
1399 bmp_info->bmiHeader.biSizeImage = height * new_width; | |
428 | 1400 bmp_info->bmiColors[0].rgbRed = GetRValue (fg); |
1401 bmp_info->bmiColors[0].rgbGreen = GetGValue (fg); | |
1402 bmp_info->bmiColors[0].rgbBlue = GetBValue (fg); | |
1403 bmp_info->bmiColors[0].rgbReserved = 0; | |
1404 bmp_info->bmiColors[1].rgbRed = GetRValue (bg); | |
1405 bmp_info->bmiColors[1].rgbGreen = GetGValue (bg); | |
1406 bmp_info->bmiColors[1].rgbBlue = GetBValue (bg); | |
1407 bmp_info->bmiColors[1].rgbReserved = 0; | |
434 | 1408 |
1409 bitmap = CreateDIBSection (hdc, | |
428 | 1410 bmp_info, |
1411 DIB_RGB_COLORS, | |
434 | 1412 &bmp_buf, |
428 | 1413 0,0); |
1414 | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
1415 xfree (bmp_info); |
434 | 1416 |
428 | 1417 if (!bitmap || !bmp_buf) |
1418 { | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
1419 xfree (new_data); |
428 | 1420 return NULL; |
1421 } | |
434 | 1422 |
428 | 1423 /* copy in the actual bitmap */ |
1424 memcpy (bmp_buf, new_data, height * new_width); | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
1425 xfree (new_data); |
428 | 1426 |
1427 return bitmap; | |
1428 } | |
1429 | |
1430 /* Given inline data for a mono pixmap, initialize the given | |
1431 image instance accordingly. */ | |
1432 | |
1433 static void | |
440 | 1434 init_image_instance_from_xbm_inline (Lisp_Image_Instance *ii, |
428 | 1435 int width, int height, |
2367 | 1436 const Binbyte *bits, |
428 | 1437 Lisp_Object instantiator, |
1438 Lisp_Object pointer_fg, | |
1439 Lisp_Object pointer_bg, | |
1440 int dest_mask, | |
1441 HBITMAP mask, | |
2286 | 1442 Lisp_Object UNUSED (mask_filename)) |
428 | 1443 { |
1444 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); | |
1445 Lisp_Object foreground = find_keyword_in_vector (instantiator, Q_foreground); | |
1446 Lisp_Object background = find_keyword_in_vector (instantiator, Q_background); | |
1447 enum image_instance_type type; | |
1448 COLORREF black = PALETTERGB (0,0,0); | |
1449 COLORREF white = PALETTERGB (255,255,255); | |
442 | 1450 HDC hdc; |
1451 | |
1452 CHECK_MSGDI_DEVICE (device); | |
1453 | |
1454 hdc = get_device_compdc (XDEVICE (device)); | |
428 | 1455 |
1456 if ((dest_mask & IMAGE_MONO_PIXMAP_MASK) && | |
1457 (dest_mask & IMAGE_COLOR_PIXMAP_MASK)) | |
1458 { | |
1459 if (!NILP (foreground) || !NILP (background)) | |
1460 type = IMAGE_COLOR_PIXMAP; | |
1461 else | |
1462 type = IMAGE_MONO_PIXMAP; | |
1463 } | |
1464 else if (dest_mask & IMAGE_MONO_PIXMAP_MASK) | |
1465 type = IMAGE_MONO_PIXMAP; | |
1466 else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK) | |
1467 type = IMAGE_COLOR_PIXMAP; | |
1468 else if (dest_mask & IMAGE_POINTER_MASK) | |
1469 type = IMAGE_POINTER; | |
1470 else | |
1471 incompatible_image_types (instantiator, dest_mask, | |
1472 IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK | |
1473 | IMAGE_POINTER_MASK); | |
1474 | |
1475 mswindows_initialize_dibitmap_image_instance (ii, 1, type); | |
434 | 1476 |
428 | 1477 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = |
1478 find_keyword_in_vector (instantiator, Q_file); | |
442 | 1479 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (ii) = width; |
1480 IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_HEIGHT (ii) = height; | |
428 | 1481 IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 1; |
793 | 1482 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = make_int (0); |
1483 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = make_int (0); | |
442 | 1484 init_image_instance_geometry (ii); |
1485 | |
428 | 1486 IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = mask ? mask : |
593 | 1487 xbm_create_bitmap_from_data (hdc, bits, width, height, TRUE, black, white); |
428 | 1488 |
1489 switch (type) | |
1490 { | |
1491 case IMAGE_MONO_PIXMAP: | |
434 | 1492 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = |
593 | 1493 xbm_create_bitmap_from_data (hdc, bits, width, height, |
428 | 1494 FALSE, black, black); |
1495 break; | |
1496 | |
1497 case IMAGE_COLOR_PIXMAP: | |
1498 { | |
1499 COLORREF fg = black; | |
1500 COLORREF bg = white; | |
1501 | |
1502 if (!NILP (foreground) && !COLOR_INSTANCEP (foreground)) | |
1503 foreground = | |
1504 Fmake_color_instance (foreground, device, | |
1505 encode_error_behavior_flag (ERROR_ME)); | |
1506 | |
1507 if (COLOR_INSTANCEP (foreground)) | |
1508 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground)); | |
1509 | |
1510 if (!NILP (background) && !COLOR_INSTANCEP (background)) | |
1511 background = | |
1512 Fmake_color_instance (background, device, | |
1513 encode_error_behavior_flag (ERROR_ME)); | |
1514 | |
1515 if (COLOR_INSTANCEP (background)) | |
1516 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background)); | |
1517 | |
1518 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground; | |
1519 IMAGE_INSTANCE_PIXMAP_BG (ii) = background; | |
1520 | |
434 | 1521 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = |
593 | 1522 xbm_create_bitmap_from_data (hdc, bits, width, height, |
428 | 1523 FALSE, fg, black); |
1524 } | |
1525 break; | |
1526 | |
1527 case IMAGE_POINTER: | |
1528 { | |
1529 COLORREF fg = black; | |
1530 COLORREF bg = white; | |
1531 | |
1532 if (NILP (foreground)) | |
1533 foreground = pointer_fg; | |
1534 if (NILP (background)) | |
1535 background = pointer_bg; | |
1536 | |
434 | 1537 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = |
428 | 1538 find_keyword_in_vector (instantiator, Q_hotspot_x); |
434 | 1539 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = |
428 | 1540 find_keyword_in_vector (instantiator, Q_hotspot_y); |
1541 IMAGE_INSTANCE_PIXMAP_FG (ii) = foreground; | |
1542 IMAGE_INSTANCE_PIXMAP_BG (ii) = background; | |
1543 if (COLOR_INSTANCEP (foreground)) | |
1544 fg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (foreground)); | |
1545 if (COLOR_INSTANCEP (background)) | |
1546 bg = COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (background)); | |
1547 | |
434 | 1548 IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = |
593 | 1549 xbm_create_bitmap_from_data (hdc, bits, width, height, |
428 | 1550 TRUE, fg, black); |
1551 mswindows_initialize_image_instance_icon (ii, TRUE); | |
1552 } | |
1553 break; | |
1554 | |
1555 default: | |
2500 | 1556 ABORT (); |
428 | 1557 } |
1558 } | |
1559 | |
1560 static void | |
1561 xbm_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator, | |
1562 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
1563 int dest_mask, int width, int height, | |
2367 | 1564 const Binbyte *bits) |
428 | 1565 { |
1566 Lisp_Object mask_data = find_keyword_in_vector (instantiator, Q_mask_data); | |
1567 Lisp_Object mask_file = find_keyword_in_vector (instantiator, Q_mask_file); | |
440 | 1568 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
442 | 1569 HDC hdc = get_device_compdc (XDEVICE (IMAGE_INSTANCE_DEVICE (ii))); |
428 | 1570 HBITMAP mask = 0; |
1571 | |
1572 if (!NILP (mask_data)) | |
1573 { | |
2367 | 1574 Binbyte *ext_data; |
440 | 1575 |
1576 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (XCDR (XCDR (mask_data))), | |
1577 C_STRING_ALLOCA, ext_data, | |
1578 Qbinary); | |
1579 mask = xbm_create_bitmap_from_data (hdc, | |
593 | 1580 ext_data, |
440 | 1581 XINT (XCAR (mask_data)), |
1582 XINT (XCAR (XCDR (mask_data))), | |
1583 FALSE, | |
1584 PALETTERGB (0,0,0), | |
1585 PALETTERGB (255,255,255)); | |
428 | 1586 } |
1587 | |
1588 init_image_instance_from_xbm_inline (ii, width, height, bits, | |
1589 instantiator, pointer_fg, pointer_bg, | |
1590 dest_mask, mask, mask_file); | |
1591 } | |
1592 | |
1593 /* Instantiate method for XBM's. */ | |
1594 | |
1595 static void | |
434 | 1596 mswindows_xbm_instantiate (Lisp_Object image_instance, |
428 | 1597 Lisp_Object instantiator, |
1598 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | |
2286 | 1599 int dest_mask, Lisp_Object UNUSED (domain)) |
428 | 1600 { |
1601 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
2367 | 1602 const Binbyte *ext_data; |
428 | 1603 |
1604 assert (!NILP (data)); | |
1605 | |
440 | 1606 TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (XCDR (XCDR (data))), |
1607 C_STRING_ALLOCA, ext_data, | |
1608 Qbinary); | |
428 | 1609 |
1610 xbm_instantiate_1 (image_instance, instantiator, pointer_fg, | |
1611 pointer_bg, dest_mask, XINT (XCAR (data)), | |
440 | 1612 XINT (XCAR (XCDR (data))), ext_data); |
428 | 1613 } |
1614 | |
1615 #ifdef HAVE_XFACE | |
1616 /********************************************************************** | |
1617 * X-Face * | |
1618 **********************************************************************/ | |
1619 #if defined(EXTERN) | |
1620 /* This is about to get redefined! */ | |
1621 #undef EXTERN | |
1622 #endif | |
1623 /* We have to define SYSV32 so that compface.h includes string.h | |
1624 instead of strings.h. */ | |
1625 #define SYSV32 | |
1743 | 1626 BEGIN_C_DECLS |
2500 | 1627 #ifndef __STDC__ /* Needed to avoid prototype warnings */ |
1628 #define __STDC__ | |
1629 #endif | |
428 | 1630 #include <compface.h> |
1743 | 1631 END_C_DECLS |
1632 | |
428 | 1633 /* JMP_BUF cannot be used here because if it doesn't get defined |
1634 to jmp_buf we end up with a conflicting type error with the | |
1635 definition in compface.h */ | |
1636 extern jmp_buf comp_env; | |
1637 #undef SYSV32 | |
1638 | |
1639 static void | |
502 | 1640 mswindows_xface_instantiate (Lisp_Object image_instance, |
1641 Lisp_Object instantiator, | |
428 | 1642 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
2286 | 1643 int dest_mask, Lisp_Object UNUSED (domain)) |
428 | 1644 { |
1645 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
1646 int i, stattis; | |
2367 | 1647 Binbyte *p, *bits, *bp; |
867 | 1648 const CIbyte * volatile emsg = 0; |
2367 | 1649 const Binbyte * volatile dstring; |
428 | 1650 |
1651 assert (!NILP (data)); | |
1652 | |
440 | 1653 TO_EXTERNAL_FORMAT (LISP_STRING, data, |
1654 C_STRING_ALLOCA, dstring, | |
1655 Qbinary); | |
428 | 1656 |
2367 | 1657 if ((p = (Binbyte *) strchr ((char *) dstring, ':'))) |
428 | 1658 { |
1659 dstring = p + 1; | |
1660 } | |
1661 | |
1662 /* Must use setjmp not SETJMP because we used jmp_buf above not JMP_BUF */ | |
1663 if (!(stattis = setjmp (comp_env))) | |
1664 { | |
1665 UnCompAll ((char *) dstring); | |
1666 UnGenFace (); | |
1667 } | |
1668 | |
1669 switch (stattis) | |
1670 { | |
1671 case -2: | |
1672 emsg = "uncompface: internal error"; | |
1673 break; | |
1674 case -1: | |
1675 emsg = "uncompface: insufficient or invalid data"; | |
1676 break; | |
1677 case 1: | |
1678 emsg = "uncompface: excess data ignored"; | |
1679 break; | |
1680 } | |
1681 | |
1682 if (emsg) | |
563 | 1683 signal_image_error_2 (emsg, data, Qimage); |
428 | 1684 |
2367 | 1685 bp = bits = alloca_binbytes (PIXELS / 8); |
428 | 1686 |
1687 /* the compface library exports char F[], which uses a single byte per | |
1688 pixel to represent a 48x48 bitmap. Yuck. */ | |
2367 | 1689 for (i = 0, p = (Binbyte *) F; i < (PIXELS / 8); ++i) |
428 | 1690 { |
1691 int n, b; | |
1692 /* reverse the bit order of each byte... */ | |
1693 for (b = n = 0; b < 8; ++b) | |
1694 { | |
1695 n |= ((*p++) << b); | |
1696 } | |
2367 | 1697 *bp++ = (Binbyte) n; |
428 | 1698 } |
1699 | |
1700 xbm_instantiate_1 (image_instance, instantiator, pointer_fg, | |
1701 pointer_bg, dest_mask, 48, 48, bits); | |
1702 } | |
1703 #endif /* HAVE_XFACE */ | |
1704 | |
1705 | |
1706 /************************************************************************/ | |
1707 /* image instance methods */ | |
1708 /************************************************************************/ | |
1709 | |
1710 static void | |
440 | 1711 mswindows_print_image_instance (Lisp_Image_Instance *p, |
428 | 1712 Lisp_Object printcharfun, |
2286 | 1713 int UNUSED (escapeflag)) |
428 | 1714 { |
1715 switch (IMAGE_INSTANCE_TYPE (p)) | |
1716 { | |
1717 case IMAGE_MONO_PIXMAP: | |
1718 case IMAGE_COLOR_PIXMAP: | |
1719 case IMAGE_POINTER: | |
800 | 1720 write_fmt_string (printcharfun, " (0x%lx", |
1721 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p)); | |
428 | 1722 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p)) |
1723 { | |
800 | 1724 write_fmt_string (printcharfun, "/0x%lx", |
1725 (unsigned long) IMAGE_INSTANCE_MSWINDOWS_MASK (p)); | |
428 | 1726 } |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
1727 write_ascstring (printcharfun, ")"); |
428 | 1728 break; |
1729 | |
1730 default: | |
1731 break; | |
1732 } | |
1733 } | |
1734 | |
1735 #ifdef DEBUG_WIDGETS | |
1736 extern int debug_widget_instances; | |
1737 #endif | |
1738 | |
1739 static void | |
611 | 1740 finalize_destroy_window (void *win) |
1741 { | |
1742 DestroyWindow ((HWND) win); | |
1743 } | |
1744 | |
1745 static void | |
440 | 1746 mswindows_finalize_image_instance (Lisp_Image_Instance *p) |
428 | 1747 { |
442 | 1748 if (!p->data) |
1749 return; | |
1750 | |
1751 if (DEVICE_LIVE_P (XDEVICE (IMAGE_INSTANCE_DEVICE (p)))) | |
428 | 1752 { |
442 | 1753 if (image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (p)) |
1754 & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK)) | |
428 | 1755 { |
1756 #ifdef DEBUG_WIDGETS | |
1757 debug_widget_instances--; | |
1758 stderr_out ("widget destroyed, %d left\n", debug_widget_instances); | |
1759 #endif | |
1760 if (IMAGE_INSTANCE_SUBWINDOW_ID (p)) | |
1761 { | |
611 | 1762 /* DestroyWindow is not safe here, as it will send messages |
1763 to our window proc. */ | |
1764 register_post_gc_action | |
1765 (finalize_destroy_window, | |
1766 (void *) (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p))); | |
1767 register_post_gc_action | |
1768 (finalize_destroy_window, | |
1769 (void *) (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p))); | |
428 | 1770 IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0; |
1771 } | |
1772 } | |
1773 else if (p->data) | |
1774 { | |
1775 int i; | |
1776 if (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p)) | |
1777 disable_glyph_animated_timeout (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p)); | |
1778 | |
1779 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p)) | |
1780 { | |
1781 for (i = 0; i < IMAGE_INSTANCE_PIXMAP_MAXSLICE (p); i++) | |
1782 { | |
1783 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i)) | |
1784 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i)); | |
1785 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i) = 0; | |
1786 } | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
1787 xfree (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p)); |
428 | 1788 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p) = 0; |
1789 } | |
1790 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p)) | |
1791 DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (p)); | |
1792 IMAGE_INSTANCE_MSWINDOWS_MASK (p) = 0; | |
1793 if (IMAGE_INSTANCE_MSWINDOWS_ICON (p)) | |
1794 DestroyIcon (IMAGE_INSTANCE_MSWINDOWS_ICON (p)); | |
1795 IMAGE_INSTANCE_MSWINDOWS_ICON (p) = 0; | |
1796 } | |
1797 } | |
1798 | |
1799 if (p->data) | |
1800 { | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
1801 xfree (p->data); |
428 | 1802 p->data = 0; |
1803 } | |
1804 } | |
1805 | |
1806 /************************************************************************/ | |
771 | 1807 /* subwindow and widget support */ |
428 | 1808 /************************************************************************/ |
1809 | |
771 | 1810 static Lisp_Object |
2333 | 1811 charset_of_text (Lisp_Object USED_IF_MULE (text)) |
771 | 1812 { |
1813 #ifdef MULE | |
867 | 1814 Ibyte *p; |
771 | 1815 |
1816 if (NILP (text)) | |
1817 return Vcharset_ascii; | |
1818 for (p = XSTRING_DATA (text); *p;) | |
1819 { | |
867 | 1820 Ichar c = itext_ichar (p); |
1821 if (!EQ (ichar_charset (c), Vcharset_ascii)) | |
1822 return ichar_charset (c); | |
1823 INC_IBYTEPTR (p); | |
771 | 1824 } |
1825 #endif /* MULE */ | |
1826 | |
1827 return Vcharset_ascii; | |
1828 } | |
1829 | |
1830 | |
440 | 1831 static HFONT |
771 | 1832 mswindows_widget_hfont (Lisp_Object face, |
1833 Lisp_Object domain, | |
1834 Lisp_Object text) | |
440 | 1835 { |
1836 int under = FACE_UNDERLINE_P (face, domain); | |
1837 int strike = FACE_STRIKETHRU_P (face, domain); | |
771 | 1838 Lisp_Object font; |
1839 struct face_cachel frame_cachel; | |
1840 struct face_cachel *cachel; | |
1841 Lisp_Object charset; | |
1842 | |
1843 reset_face_cachel (&frame_cachel); | |
1844 update_face_cachel_data (&frame_cachel, domain, face); | |
1845 cachel = &frame_cachel; | |
1846 /* !!#### This is a big hack. We return the first non-ASCII charset in | |
1847 the string, on the assumption that we can display ASCII characters in | |
1848 all fonts. We really need to draw the text of the widget ourselves; | |
1849 or perhaps there are fonts supporting lots of character sets? */ | |
1850 charset = charset_of_text (text); | |
1851 | |
1852 font = FACE_CACHEL_FONT (cachel, charset); | |
1853 | |
1854 if (!FONT_INSTANCEP (font)) | |
1855 font = ensure_face_cachel_contains_charset (cachel, domain, charset); | |
1856 | |
1857 if (EQ (font, Vthe_null_font_instance)) | |
1858 font = FACE_CACHEL_FONT (cachel, Vcharset_ascii); | |
440 | 1859 |
1860 return mswindows_get_hfont (XFONT_INSTANCE (font), under, strike); | |
1861 } | |
1862 | |
872 | 1863 #ifdef DEFER_WINDOW_POS |
1864 | |
442 | 1865 static HDWP |
1866 begin_defer_window_pos (struct frame *f) | |
1867 { | |
1868 if (FRAME_MSWINDOWS_DATA (f)->hdwp == 0) | |
1869 FRAME_MSWINDOWS_DATA (f)->hdwp = BeginDeferWindowPos (10); | |
1870 return FRAME_MSWINDOWS_DATA (f)->hdwp; | |
1871 } | |
1872 | |
872 | 1873 #endif |
1874 | |
428 | 1875 /* unmap the image if it is a widget. This is used by redisplay via |
1876 redisplay_unmap_subwindows */ | |
1877 static void | |
440 | 1878 mswindows_unmap_subwindow (Lisp_Image_Instance *p) |
428 | 1879 { |
1880 if (IMAGE_INSTANCE_SUBWINDOW_ID (p)) | |
1881 { | |
442 | 1882 #ifdef DEFER_WINDOW_POS |
1883 struct frame *f = XFRAME (IMAGE_INSTANCE_FRAME (p)); | |
1884 HDWP hdwp = begin_defer_window_pos (f); | |
1885 HDWP new_hdwp; | |
1886 new_hdwp = DeferWindowPos (hdwp, IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p), | |
1887 NULL, | |
1888 0, 0, 0, 0, | |
1889 SWP_HIDEWINDOW | SWP_NOACTIVATE | | |
1890 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | |
1891 /* Setting this flag causes the call to | |
1892 DeferWindowPos to fail with | |
1893 "Invalid parameter". I don't understand | |
1894 why we bother to try and set this | |
1895 anyway. -- ben */ | |
1896 /* | SWP_NOSENDCHANGING */ | |
1897 ); | |
1898 if (!new_hdwp) | |
1899 mswindows_output_last_error ("unmapping"); | |
1900 else | |
1901 hdwp = new_hdwp; | |
1902 FRAME_MSWINDOWS_DATA (f)->hdwp = hdwp; | |
1903 #else | |
434 | 1904 SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p), |
1905 NULL, | |
428 | 1906 0, 0, 0, 0, |
442 | 1907 SWP_HIDEWINDOW | SWP_NOACTIVATE | |
1908 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER ); | |
1909 #endif | |
440 | 1910 if (GetFocus() == WIDGET_INSTANCE_MSWINDOWS_HANDLE (p)) |
1911 SetFocus (GetParent (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p))); | |
428 | 1912 } |
1913 } | |
1914 | |
1915 /* map the subwindow. This is used by redisplay via | |
1916 redisplay_output_subwindow */ | |
1917 static void | |
440 | 1918 mswindows_map_subwindow (Lisp_Image_Instance *p, int x, int y, |
771 | 1919 struct display_glyph_area *dga) |
428 | 1920 { |
442 | 1921 #ifdef DEFER_WINDOW_POS |
1922 struct frame *f = XFRAME (IMAGE_INSTANCE_FRAME (p)); | |
1923 HDWP hdwp = begin_defer_window_pos (f); | |
1924 HDWP new_hdwp; | |
1925 #endif | |
428 | 1926 /* move the window before mapping it ... */ |
1927 SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p), | |
434 | 1928 NULL, |
428 | 1929 x, y, dga->width, dga->height, |
434 | 1930 SWP_NOZORDER |
428 | 1931 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING); |
1932 /* ... adjust the child ... */ | |
1933 SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), | |
434 | 1934 NULL, |
428 | 1935 -dga->xoffset, -dga->yoffset, 0, 0, |
1936 SWP_NOZORDER | SWP_NOSIZE | |
1937 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING); | |
1938 /* ... now map it - we are not allowed to move it at the same time. */ | |
442 | 1939 if (!IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (p)) |
1940 { | |
1941 #ifdef DEFER_WINDOW_POS | |
1942 new_hdwp = DeferWindowPos | |
1943 (hdwp, | |
1944 IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p), | |
1945 NULL, 0, 0, 0, 0, | |
1946 SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | |
1947 | SWP_SHOWWINDOW | |
1948 /* | SWP_NOCOPYBITS */ | |
1949 /* Setting this flag causes the call to | |
1950 DeferWindowPos to fail with | |
1951 "Invalid parameter". I don't understand | |
1952 why we bother to try and set this | |
1953 anyway. -- ben */ | |
1954 /* | SWP_NOSENDCHANGING */ | |
1955 | SWP_NOACTIVATE); | |
1956 if (!new_hdwp) | |
1957 mswindows_output_last_error ("mapping"); | |
1958 else | |
1959 hdwp = new_hdwp; | |
1960 FRAME_MSWINDOWS_DATA (f)->hdwp = hdwp; | |
1961 #else | |
1962 SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p), | |
1963 NULL, | |
1964 0, 0, 0, 0, | |
1965 SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | |
1966 | SWP_SHOWWINDOW | SWP_NOCOPYBITS | SWP_NOACTIVATE); | |
863 | 1967 |
1968 /* Doing this once does not seem to be enough, for instance when | |
1969 mapping the search dialog this gets called four times. If we | |
1970 only set on the first time through then the subwindow never | |
1971 gets focus as intended. However, doing this everytime doesn't | |
1972 seem so bad, after all we only need to redo this after the | |
1973 focus changes - and if that happens resetting the initial | |
1974 focus doesn't seem so bad. */ | |
1975 if (IMAGE_INSTANCE_WANTS_INITIAL_FOCUS (p)) | |
1976 SetFocus (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p)); | |
442 | 1977 #endif |
1978 } | |
428 | 1979 } |
1980 | |
1981 /* resize the subwindow instance */ | |
434 | 1982 static void |
771 | 1983 mswindows_resize_subwindow (Lisp_Image_Instance *ii, int w, int h) |
428 | 1984 { |
1985 /* Set the size of the control .... */ | |
442 | 1986 if (!SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii), |
1987 NULL, | |
1988 0, 0, w, h, | |
1989 SWP_NOZORDER | SWP_NOMOVE | |
1990 | SWP_NOCOPYBITS | SWP_NOSENDCHANGING)) | |
1991 mswindows_output_last_error ("resizing"); | |
1992 } | |
1993 | |
1994 /* Simply resize the window here. */ | |
1995 static void | |
1996 mswindows_redisplay_subwindow (Lisp_Image_Instance *p) | |
1997 { | |
1998 mswindows_resize_subwindow (p, | |
1999 IMAGE_INSTANCE_WIDTH (p), | |
2000 IMAGE_INSTANCE_HEIGHT (p)); | |
428 | 2001 } |
2002 | |
2003 /* when you click on a widget you may activate another widget this | |
2004 needs to be checked and all appropriate widgets updated */ | |
2005 static void | |
442 | 2006 mswindows_redisplay_widget (Lisp_Image_Instance *p) |
428 | 2007 { |
442 | 2008 /* Possibly update the face font and colors. */ |
2009 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (p)) | |
2010 && (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p) | |
2011 || XFRAME (IMAGE_INSTANCE_FRAME (p))->faces_changed | |
2012 || IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p))) | |
428 | 2013 { |
2014 /* set the widget font from the widget face */ | |
771 | 2015 qxeSendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), |
2016 WM_SETFONT, | |
2017 (WPARAM) mswindows_widget_hfont | |
2018 (IMAGE_INSTANCE_WIDGET_FACE (p), | |
2019 IMAGE_INSTANCE_FRAME (p), | |
2020 IMAGE_INSTANCE_WIDGET_TEXT (p)), | |
2021 MAKELPARAM (TRUE, 0)); | |
428 | 2022 } |
442 | 2023 /* Possibly update the dimensions. */ |
2024 if (IMAGE_INSTANCE_SIZE_CHANGED (p)) | |
2025 { | |
2026 mswindows_resize_subwindow (p, | |
2027 IMAGE_INSTANCE_WIDTH (p), | |
2028 IMAGE_INSTANCE_HEIGHT (p)); | |
2029 } | |
2030 /* Possibly update the text in the widget. */ | |
2031 if (IMAGE_INSTANCE_TEXT_CHANGED (p) | |
2032 && !NILP (IMAGE_INSTANCE_WIDGET_TEXT (p))) | |
2033 { | |
771 | 2034 Extbyte *lparam = 0; |
2035 LISP_STRING_TO_TSTR (IMAGE_INSTANCE_WIDGET_TEXT (p), lparam); | |
2036 qxeSendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), | |
2037 WM_SETTEXT, 0, (LPARAM) lparam); | |
442 | 2038 } |
454 | 2039 /* Set active state. */ |
2040 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)) | |
2041 { | |
2042 Lisp_Object item = IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (p); | |
771 | 2043 LONG style = qxeGetWindowLong |
454 | 2044 (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), |
2045 GWL_STYLE); | |
2046 | |
2047 if (CONSP (item)) | |
2048 item = XCAR (item); | |
2049 | |
1913 | 2050 if (gui_item_active_p (item)) |
771 | 2051 qxeSetWindowLong (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), |
2052 GWL_STYLE, style & ~WS_DISABLED); | |
454 | 2053 else |
771 | 2054 qxeSetWindowLong (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), |
2055 GWL_STYLE, style | WS_DISABLED); | |
454 | 2056 } |
428 | 2057 } |
2058 | |
771 | 2059 #ifdef HAVE_WIDGETS |
2060 | |
863 | 2061 /* Account for some of the limitations with widget images. */ |
2062 static int | |
2063 mswindows_widget_border_width (void) | |
2064 { | |
2065 return DEFAULT_WIDGET_BORDER_WIDTH; | |
2066 } | |
2067 | |
442 | 2068 /* register widgets into our hashtable so that we can cope with the |
428 | 2069 callbacks. The hashtable is weak so deregistration is handled |
2070 automatically */ | |
2071 static int | |
442 | 2072 mswindows_register_gui_item (Lisp_Object image_instance, |
2073 Lisp_Object gui, Lisp_Object domain) | |
428 | 2074 { |
442 | 2075 Lisp_Object frame = DOMAIN_FRAME (domain); |
771 | 2076 struct frame *f = XFRAME (frame); |
442 | 2077 int id = gui_item_id_hash (FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f), |
428 | 2078 gui, |
2079 WIDGET_GLYPH_SLOT); | |
442 | 2080 Fputhash (make_int (id), image_instance, |
2081 FRAME_MSWINDOWS_WIDGET_HASH_TABLE1 (f)); | |
2082 Fputhash (make_int (id), XGUI_ITEM (gui)->callback, | |
2083 FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f)); | |
2084 Fputhash (make_int (id), XGUI_ITEM (gui)->callback_ex, | |
2085 FRAME_MSWINDOWS_WIDGET_HASH_TABLE3 (f)); | |
428 | 2086 return id; |
2087 } | |
2088 | |
2089 static int | |
2090 mswindows_register_widget_instance (Lisp_Object instance, Lisp_Object domain) | |
2091 { | |
442 | 2092 return mswindows_register_gui_item (instance, |
2093 XIMAGE_INSTANCE_WIDGET_ITEM (instance), | |
428 | 2094 domain); |
2095 } | |
2096 | |
2097 static void | |
502 | 2098 mswindows_subwindow_instantiate (Lisp_Object image_instance, |
2286 | 2099 Lisp_Object UNUSED (instantiator), |
2100 Lisp_Object UNUSED (pointer_fg), | |
2101 Lisp_Object UNUSED (pointer_bg), | |
2102 int UNUSED (dest_mask), Lisp_Object domain) | |
428 | 2103 { |
440 | 2104 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2105 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); |
442 | 2106 Lisp_Object frame = DOMAIN_FRAME (domain); |
428 | 2107 HWND wnd; |
2108 | |
442 | 2109 CHECK_MSWINDOWS_DEVICE (device); |
428 | 2110 |
2111 /* have to set the type this late in case there is no device | |
2112 instantiation for a widget */ | |
2113 IMAGE_INSTANCE_TYPE (ii) = IMAGE_SUBWINDOW; | |
2114 /* Allocate space for the clip window */ | |
2115 ii->data = xnew_and_zero (struct mswindows_subwindow_data); | |
2116 | |
2117 if ((IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii) | |
771 | 2118 = qxeCreateWindowEx ( |
2119 0, /* EX flags */ | |
2120 XETEXT (XEMACS_CONTROL_CLASS), | |
2121 0, /* text */ | |
2122 WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD, | |
2123 0, /* starting x position */ | |
2124 0, /* starting y position */ | |
2125 IMAGE_INSTANCE_WIDGET_WIDTH (ii), | |
2126 IMAGE_INSTANCE_WIDGET_HEIGHT (ii), | |
2127 /* parent window */ | |
2128 FRAME_MSWINDOWS_HANDLE (XFRAME (frame)), | |
2129 NULL, /* No menu */ | |
2130 NULL, /* must be null for this class */ | |
2131 NULL)) == NULL) | |
563 | 2132 gui_error ("window creation failed with code", |
2133 make_int (GetLastError())); | |
428 | 2134 |
771 | 2135 wnd = qxeCreateWindow (XETEXT ("STATIC"), XETEXT (""), |
2136 WS_CHILD, | |
2137 0, /* starting x position */ | |
2138 0, /* starting y position */ | |
2139 IMAGE_INSTANCE_WIDGET_WIDTH (ii), | |
2140 IMAGE_INSTANCE_WIDGET_HEIGHT (ii), | |
2141 IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii), | |
2142 0, | |
2143 (HINSTANCE) | |
2144 qxeGetWindowLong | |
2145 (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)), | |
2146 GWL_HINSTANCE), | |
2147 NULL); | |
2148 | |
2149 qxeSetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance)); | |
428 | 2150 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd; |
2151 } | |
2152 | |
771 | 2153 #endif /* HAVE_WIDGETS */ |
2154 | |
428 | 2155 static int |
440 | 2156 mswindows_image_instance_equal (Lisp_Image_Instance *p1, |
2286 | 2157 Lisp_Image_Instance *p2, int UNUSED (depth)) |
428 | 2158 { |
2159 switch (IMAGE_INSTANCE_TYPE (p1)) | |
2160 { | |
2161 case IMAGE_MONO_PIXMAP: | |
2162 case IMAGE_COLOR_PIXMAP: | |
2163 case IMAGE_POINTER: | |
434 | 2164 if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p1) |
428 | 2165 != IMAGE_INSTANCE_MSWINDOWS_BITMAP (p2)) |
2166 return 0; | |
2167 break; | |
434 | 2168 |
428 | 2169 default: |
2170 break; | |
2171 } | |
2172 | |
2173 return 1; | |
2174 } | |
2175 | |
665 | 2176 static Hashcode |
2286 | 2177 mswindows_image_instance_hash (Lisp_Image_Instance *p, int UNUSED (depth)) |
428 | 2178 { |
2179 switch (IMAGE_INSTANCE_TYPE (p)) | |
2180 { | |
2181 case IMAGE_MONO_PIXMAP: | |
2182 case IMAGE_COLOR_PIXMAP: | |
2183 case IMAGE_POINTER: | |
665 | 2184 return (Hashcode) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p); |
434 | 2185 |
428 | 2186 default: |
2187 return 0; | |
2188 } | |
2189 } | |
2190 | |
2191 /* Set all the slots in an image instance structure to reasonable | |
2192 default values. This is used somewhere within an instantiate | |
2193 method. It is assumed that the device slot within the image | |
2194 instance is already set -- this is the case when instantiate | |
2195 methods are called. */ | |
2196 | |
2197 static void | |
440 | 2198 mswindows_initialize_dibitmap_image_instance (Lisp_Image_Instance *ii, |
428 | 2199 int slices, |
2200 enum image_instance_type type) | |
2201 { | |
2202 ii->data = xnew_and_zero (struct mswindows_image_instance_data); | |
2203 IMAGE_INSTANCE_TYPE (ii) = type; | |
2204 IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil; | |
2205 IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (ii) = Qnil; | |
2206 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii) = Qnil; | |
2207 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = Qnil; | |
2208 IMAGE_INSTANCE_PIXMAP_FG (ii) = Qnil; | |
2209 IMAGE_INSTANCE_PIXMAP_BG (ii) = Qnil; | |
2210 IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii) = slices; | |
434 | 2211 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (ii) = |
428 | 2212 xnew_array_and_zero (HBITMAP, slices); |
2213 } | |
2214 | |
2215 | |
2216 #ifdef HAVE_WIDGETS | |
2217 | |
2218 /************************************************************************/ | |
771 | 2219 /* widgets */ |
428 | 2220 /************************************************************************/ |
2221 static void | |
502 | 2222 mswindows_widget_instantiate (Lisp_Object image_instance, |
2286 | 2223 Lisp_Object UNUSED (instantiator), |
2224 Lisp_Object UNUSED (pointer_fg), | |
2225 Lisp_Object UNUSED (pointer_bg), | |
2226 int UNUSED (dest_mask), Lisp_Object domain, | |
1204 | 2227 const CIbyte *class_, int flags, int exflags) |
428 | 2228 { |
2229 /* this function can call lisp */ | |
440 | 2230 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2231 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), style; |
442 | 2232 Lisp_Object frame = DOMAIN_FRAME (domain); |
771 | 2233 Extbyte *nm = 0; |
2234 Extbyte *classext; | |
428 | 2235 HWND wnd; |
2236 int id = 0xffff; | |
2237 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); | |
771 | 2238 Lisp_Gui_Item *pgui = XGUI_ITEM (gui); |
428 | 2239 |
442 | 2240 CHECK_MSWINDOWS_DEVICE (device); |
428 | 2241 |
1913 | 2242 if (!gui_item_active_p (gui)) |
428 | 2243 flags |= WS_DISABLED; |
2244 | |
2245 style = pgui->style; | |
2246 | |
442 | 2247 if (!NILP (pgui->callback) || !NILP (pgui->callback_ex)) |
428 | 2248 { |
2249 id = mswindows_register_widget_instance (image_instance, domain); | |
2250 } | |
438 | 2251 |
428 | 2252 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii))) |
771 | 2253 LISP_STRING_TO_TSTR (IMAGE_INSTANCE_WIDGET_TEXT (ii), nm); |
428 | 2254 |
2255 /* allocate space for the clip window and then allocate the clip window */ | |
2256 ii->data = xnew_and_zero (struct mswindows_subwindow_data); | |
2257 | |
2258 if ((IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii) | |
771 | 2259 = qxeCreateWindowEx (WS_EX_CONTROLPARENT, /* EX flags */ |
2260 XETEXT (XEMACS_CONTROL_CLASS), | |
2261 0, /* text */ | |
2262 WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD, | |
428 | 2263 0, /* starting x position */ |
2264 0, /* starting y position */ | |
2265 IMAGE_INSTANCE_WIDGET_WIDTH (ii), | |
2266 IMAGE_INSTANCE_WIDGET_HEIGHT (ii), | |
2267 /* parent window */ | |
771 | 2268 DOMAIN_MSWINDOWS_HANDLE (domain), |
428 | 2269 (HMENU)id, /* No menu */ |
771 | 2270 NULL, /* must be null for this class */ |
428 | 2271 NULL)) == NULL) |
563 | 2272 gui_error ("window creation failed with code", |
2273 make_int (GetLastError())); | |
428 | 2274 |
1204 | 2275 C_STRING_TO_TSTR (class_, classext); |
771 | 2276 |
2277 if ((wnd = qxeCreateWindowEx (exflags /* | WS_EX_NOPARENTNOTIFY*/, | |
2278 classext, | |
2279 nm, | |
2280 flags | WS_CHILD | WS_VISIBLE, | |
2281 0, /* starting x position */ | |
2282 0, /* starting y position */ | |
2283 IMAGE_INSTANCE_WIDGET_WIDTH (ii), | |
2284 IMAGE_INSTANCE_WIDGET_HEIGHT (ii), | |
2285 /* parent window */ | |
2286 IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii), | |
2287 (HMENU)id, /* No menu */ | |
2288 (HINSTANCE) | |
2289 qxeGetWindowLong | |
2290 (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)), | |
2291 GWL_HINSTANCE), | |
2292 NULL)) == NULL) | |
2293 gui_error ("window creation failed with code", | |
2294 make_int (GetLastError())); | |
2295 | |
428 | 2296 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd; |
771 | 2297 qxeSetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance)); |
428 | 2298 /* set the widget font from the widget face */ |
442 | 2299 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii))) |
771 | 2300 qxeSendMessage (wnd, WM_SETFONT, |
2301 (WPARAM) mswindows_widget_hfont | |
2302 (IMAGE_INSTANCE_WIDGET_FACE (ii), domain, | |
2303 IMAGE_INSTANCE_WIDGET_TEXT (ii)), | |
2304 MAKELPARAM (TRUE, 0)); | |
442 | 2305 } |
2306 | |
2307 /* Instantiate a native layout widget. */ | |
2308 static void | |
2309 mswindows_native_layout_instantiate (Lisp_Object image_instance, | |
2310 Lisp_Object instantiator, | |
502 | 2311 Lisp_Object pointer_fg, |
2312 Lisp_Object pointer_bg, | |
442 | 2313 int dest_mask, Lisp_Object domain) |
2314 { | |
2315 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
2316 | |
2317 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg, | |
2318 pointer_bg, dest_mask, domain, "STATIC", | |
2319 /* Approximation to styles available with | |
2320 an XEmacs layout. */ | |
2321 (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (ii), | |
2322 Qetched_in) || | |
2323 EQ (IMAGE_INSTANCE_LAYOUT_BORDER (ii), | |
2324 Qetched_out) || | |
2325 GLYPHP (IMAGE_INSTANCE_LAYOUT_BORDER (ii)) | |
2326 ? SS_ETCHEDFRAME : SS_SUNKEN) | DS_CONTROL, | |
2327 0); | |
428 | 2328 } |
2329 | |
2330 /* Instantiate a button widget. Unfortunately instantiated widgets are | |
2331 particular to a frame since they need to have a parent. It's not | |
2332 like images where you just select the image into the context you | |
438 | 2333 want to display it in and BitBlt it. So image instances can have a |
428 | 2334 many-to-one relationship with things you see, whereas widgets can |
2335 only be one-to-one (i.e. per frame) */ | |
2336 static void | |
502 | 2337 mswindows_button_instantiate (Lisp_Object image_instance, |
2338 Lisp_Object instantiator, | |
428 | 2339 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
2340 int dest_mask, Lisp_Object domain) | |
2341 { | |
442 | 2342 /* This function can call lisp */ |
440 | 2343 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2344 HWND wnd; |
444 | 2345 int flags = WS_TABSTOP | BS_NOTIFY; |
2346 /* BS_NOTIFY #### is needed to get exotic feedback only. Since we | |
2347 seem to want nothing beyond BN_CLICK, the style is perhaps not | |
2348 necessary -- kkm */ | |
428 | 2349 Lisp_Object style; |
2350 Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii); | |
771 | 2351 Lisp_Gui_Item *pgui = XGUI_ITEM (gui); |
428 | 2352 Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image); |
2353 | |
2354 if (!NILP (glyph)) | |
2355 { | |
2356 if (!IMAGE_INSTANCEP (glyph)) | |
2357 glyph = glyph_image_instance (glyph, domain, ERROR_ME, 1); | |
2358 | |
2359 if (IMAGE_INSTANCEP (glyph)) | |
434 | 2360 flags |= XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ? |
428 | 2361 BS_BITMAP : BS_ICON; |
2362 } | |
2363 | |
2364 style = pgui->style; | |
2365 | |
438 | 2366 /* #### consider using the default face for radio and toggle |
2367 buttons. */ | |
428 | 2368 if (EQ (style, Qradio)) |
2369 { | |
2370 flags |= BS_RADIOBUTTON; | |
2371 } | |
2372 else if (EQ (style, Qtoggle)) | |
2373 { | |
2374 flags |= BS_AUTOCHECKBOX; | |
2375 } | |
2376 else | |
438 | 2377 { |
2378 flags |= BS_DEFPUSHBUTTON; | |
2379 } | |
428 | 2380 |
2381 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg, | |
771 | 2382 pointer_bg, dest_mask, domain, |
2383 "BUTTON", flags, 0); | |
428 | 2384 |
2385 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); | |
2386 /* set the checked state */ | |
1913 | 2387 if (gui_item_selected_p (gui)) |
771 | 2388 qxeSendMessage (wnd, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); |
428 | 2389 else |
771 | 2390 qxeSendMessage (wnd, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0); |
428 | 2391 /* add the image if one was given */ |
440 | 2392 if (!NILP (glyph) && IMAGE_INSTANCEP (glyph) |
2393 && | |
2394 IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (glyph))) | |
428 | 2395 { |
771 | 2396 qxeSendMessage (wnd, BM_SETIMAGE, |
2397 (WPARAM) (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ? | |
2398 IMAGE_BITMAP : IMAGE_ICON), | |
2399 (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ? | |
2400 (LPARAM) XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) : | |
2401 (LPARAM) XIMAGE_INSTANCE_MSWINDOWS_ICON (glyph))); | |
428 | 2402 } |
2403 } | |
2404 | |
442 | 2405 /* Update the state of a button. */ |
2406 static void | |
2407 mswindows_button_redisplay (Lisp_Object image_instance) | |
2408 { | |
2409 /* This function can GC if IN_REDISPLAY is false. */ | |
2410 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
2411 | |
2412 /* buttons checked or otherwise */ | |
1913 | 2413 if (gui_item_selected_p (IMAGE_INSTANCE_WIDGET_ITEM (ii))) |
771 | 2414 qxeSendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii), |
2415 BM_SETCHECK, (WPARAM)BST_CHECKED, 0); | |
442 | 2416 else |
771 | 2417 qxeSendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii), |
2418 BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0); | |
442 | 2419 } |
2420 | |
428 | 2421 /* instantiate an edit control */ |
2422 static void | |
502 | 2423 mswindows_edit_field_instantiate (Lisp_Object image_instance, |
2424 Lisp_Object instantiator, | |
2425 Lisp_Object pointer_fg, | |
2426 Lisp_Object pointer_bg, | |
2427 int dest_mask, Lisp_Object domain) | |
428 | 2428 { |
2429 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg, | |
434 | 2430 pointer_bg, dest_mask, domain, "EDIT", |
428 | 2431 ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP |
438 | 2432 | WS_BORDER, WS_EX_CLIENTEDGE); |
428 | 2433 } |
2434 | |
2435 /* instantiate a progress gauge */ | |
2436 static void | |
502 | 2437 mswindows_progress_gauge_instantiate (Lisp_Object image_instance, |
2438 Lisp_Object instantiator, | |
2439 Lisp_Object pointer_fg, | |
2440 Lisp_Object pointer_bg, | |
2441 int dest_mask, Lisp_Object domain) | |
428 | 2442 { |
2443 HWND wnd; | |
440 | 2444 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
442 | 2445 Lisp_Object val; |
428 | 2446 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg, |
434 | 2447 pointer_bg, dest_mask, domain, PROGRESS_CLASS, |
438 | 2448 WS_BORDER | PBS_SMOOTH, WS_EX_CLIENTEDGE); |
428 | 2449 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); |
2450 /* set the colors */ | |
502 | 2451 #if 0 /* #### fix this */ |
771 | 2452 qxeSendMessage (wnd, PBM_SETBKCOLOR, 0, |
2453 (LPARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR | |
2454 (XCOLOR_INSTANCE | |
2455 (FACE_BACKGROUND | |
2456 (XIMAGE_INSTANCE_WIDGET_FACE (ii), | |
2457 XIMAGE_INSTANCE_FRAME (ii)))))); | |
2458 qxeSendMessage (wnd, PBM_SETBARCOLOR, 0, | |
2459 (LPARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR | |
2460 (XCOLOR_INSTANCE | |
2461 (FACE_FOREGROUND | |
2462 (XIMAGE_INSTANCE_WIDGET_FACE (ii), | |
2463 XIMAGE_INSTANCE_FRAME (ii)))))); | |
428 | 2464 #endif |
442 | 2465 val = XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEMS (ii))->value; |
2466 CHECK_INT (val); | |
771 | 2467 qxeSendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii), |
2468 PBM_SETPOS, (WPARAM)XINT (val), 0); | |
428 | 2469 } |
2470 | |
2471 /* instantiate a tree view widget */ | |
2472 static HTREEITEM add_tree_item (Lisp_Object image_instance, | |
2473 HWND wnd, HTREEITEM parent, Lisp_Object item, | |
2474 int children, Lisp_Object domain) | |
2475 { | |
2476 HTREEITEM ret; | |
771 | 2477 TV_INSERTSTRUCTW tvitem; |
428 | 2478 |
2479 tvitem.hParent = parent; | |
2480 tvitem.hInsertAfter = TVI_LAST; | |
2481 tvitem.item.mask = TVIF_TEXT | TVIF_CHILDREN; | |
2482 tvitem.item.cChildren = children; | |
771 | 2483 |
428 | 2484 if (GUI_ITEMP (item)) |
2485 { | |
771 | 2486 tvitem.item.lParam = |
2487 mswindows_register_gui_item (image_instance, item, domain); | |
428 | 2488 tvitem.item.mask |= TVIF_PARAM; |
771 | 2489 LISP_STRING_TO_TSTR (XGUI_ITEM (item)->name, tvitem.item.pszText); |
428 | 2490 } |
2491 else | |
771 | 2492 LISP_STRING_TO_TSTR (item, tvitem.item.pszText); |
2493 | |
2421 | 2494 tvitem.item.cchTextMax = qxetcslen ((Extbyte *) tvitem.item.pszText); |
771 | 2495 |
2496 if ((ret = (HTREEITEM) qxeSendMessage (wnd, TVM_INSERTITEM, | |
2497 0, (LPARAM) &tvitem)) == 0) | |
563 | 2498 gui_error ("error adding tree view entry", item); |
428 | 2499 |
2500 return ret; | |
2501 } | |
2502 | |
2503 static void add_tree_item_list (Lisp_Object image_instance, | |
2504 HWND wnd, HTREEITEM parent, Lisp_Object list, | |
2505 Lisp_Object domain) | |
2506 { | |
2507 Lisp_Object rest; | |
2508 | |
2509 /* get the first item */ | |
2510 parent = add_tree_item (image_instance, wnd, parent, XCAR (list), TRUE, domain); | |
2511 /* recursively add items to the tree view */ | |
2512 LIST_LOOP (rest, XCDR (list)) | |
2513 { | |
2514 if (LISTP (XCAR (rest))) | |
2515 add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain); | |
2516 else | |
2517 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain); | |
2518 } | |
2519 } | |
2520 | |
2521 static void | |
502 | 2522 mswindows_tree_view_instantiate (Lisp_Object image_instance, |
2523 Lisp_Object instantiator, | |
2524 Lisp_Object pointer_fg, | |
2525 Lisp_Object pointer_bg, | |
2526 int dest_mask, Lisp_Object domain) | |
428 | 2527 { |
2528 Lisp_Object rest; | |
2529 HWND wnd; | |
2530 HTREEITEM parent; | |
440 | 2531 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2532 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg, |
434 | 2533 pointer_bg, dest_mask, domain, WC_TREEVIEW, |
428 | 2534 WS_TABSTOP | WS_BORDER | PBS_SMOOTH |
2535 | TVS_HASLINES | TVS_HASBUTTONS, | |
438 | 2536 WS_EX_CLIENTEDGE); |
428 | 2537 |
2538 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); | |
434 | 2539 |
428 | 2540 /* define a root */ |
434 | 2541 parent = add_tree_item (image_instance, wnd, NULL, |
2542 XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)), | |
428 | 2543 TRUE, domain); |
434 | 2544 |
428 | 2545 /* recursively add items to the tree view */ |
2546 /* add items to the tab */ | |
2547 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))) | |
2548 { | |
2549 if (LISTP (XCAR (rest))) | |
2550 add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain); | |
2551 else | |
2552 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain); | |
2553 } | |
2554 } | |
2555 | |
442 | 2556 /* Set the properties of a tree view. */ |
2557 static void | |
2558 mswindows_tree_view_redisplay (Lisp_Object image_instance) | |
2559 { | |
2560 /* This function can GC if IN_REDISPLAY is false. */ | |
2561 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | |
2562 | |
2563 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)) | |
2564 { | |
2565 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); | |
2566 Lisp_Object rest; | |
2567 HTREEITEM parent; | |
2568 /* Delete previous items. */ | |
771 | 2569 qxeSendMessage (wnd, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT); |
442 | 2570 /* define a root */ |
2571 parent = add_tree_item (image_instance, wnd, NULL, | |
2572 XCAR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)), | |
2573 TRUE, IMAGE_INSTANCE_DOMAIN (ii)); | |
2574 | |
2575 /* recursively add items to the tree view */ | |
2576 /* add items to the tab */ | |
2577 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))) | |
2578 { | |
2579 if (LISTP (XCAR (rest))) | |
2580 add_tree_item_list (image_instance, wnd, parent, XCAR (rest), | |
2581 IMAGE_INSTANCE_DOMAIN (ii)); | |
2582 else | |
2583 add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, | |
2584 IMAGE_INSTANCE_DOMAIN (ii)); | |
2585 } | |
2586 } | |
2587 } | |
2588 | |
428 | 2589 /* instantiate a tab control */ |
442 | 2590 static int |
2591 add_tab_item (Lisp_Object image_instance, | |
2592 HWND wnd, Lisp_Object item, | |
2593 Lisp_Object domain, int i) | |
428 | 2594 { |
771 | 2595 TC_ITEMW tcitem; |
442 | 2596 int ret = 0; |
428 | 2597 |
771 | 2598 tcitem.mask = TCIF_TEXT; |
434 | 2599 |
428 | 2600 if (GUI_ITEMP (item)) |
2601 { | |
771 | 2602 tcitem.lParam = |
2603 mswindows_register_gui_item (image_instance, item, domain); | |
2604 tcitem.mask |= TCIF_PARAM; | |
2605 LISP_STRING_TO_TSTR (XGUI_ITEM (item)->name, tcitem.pszText); | |
428 | 2606 } |
2607 else | |
2608 { | |
2609 CHECK_STRING (item); | |
771 | 2610 LISP_STRING_TO_TSTR (item, tcitem.pszText); |
428 | 2611 } |
2612 | |
2421 | 2613 tcitem.cchTextMax = qxetcslen ((Extbyte *) tcitem.pszText); |
771 | 2614 |
2615 if ((ret = qxeSendMessage (wnd, TCM_INSERTITEM, i, (LPARAM) &tcitem)) < 0) | |
563 | 2616 gui_error ("error adding tab entry", item); |
428 | 2617 |
2618 return ret; | |
2619 } | |
2620 | |
2621 static void | |
502 | 2622 mswindows_tab_control_instantiate (Lisp_Object image_instance, |
2623 Lisp_Object instantiator, | |
2624 Lisp_Object pointer_fg, | |
2625 Lisp_Object pointer_bg, | |
2626 int dest_mask, Lisp_Object domain) | |
428 | 2627 { |
442 | 2628 /* This function can call lisp */ |
428 | 2629 Lisp_Object rest; |
2630 HWND wnd; | |
442 | 2631 int i = 0, selected = 0; |
440 | 2632 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
438 | 2633 Lisp_Object orient = find_keyword_in_vector (instantiator, Q_orientation); |
2634 unsigned int flags = WS_TABSTOP; | |
2635 | |
2636 if (EQ (orient, Qleft) || EQ (orient, Qright)) | |
2637 { | |
2638 flags |= TCS_VERTICAL | TCS_MULTILINE; | |
2639 } | |
2640 if (EQ (orient, Qright) || EQ (orient, Qbottom)) | |
2641 { | |
2642 flags |= TCS_BOTTOM; | |
2643 } | |
2644 | |
428 | 2645 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg, |
434 | 2646 pointer_bg, dest_mask, domain, WC_TABCONTROL, |
428 | 2647 /* borders don't suit tabs so well */ |
438 | 2648 flags, 0); |
428 | 2649 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); |
2650 /* add items to the tab */ | |
2651 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))) | |
2652 { | |
442 | 2653 int idx = add_tab_item (image_instance, wnd, XCAR (rest), domain, i); |
2654 assert (idx == i); | |
1913 | 2655 if (gui_item_selected_p (XCAR (rest))) |
442 | 2656 selected = i; |
438 | 2657 i++; |
428 | 2658 } |
771 | 2659 qxeSendMessage (wnd, TCM_SETCURSEL, selected, 0); |
428 | 2660 } |
2661 | |
442 | 2662 /* Set the properties of a tab control. */ |
2663 static void | |
2664 mswindows_tab_control_redisplay (Lisp_Object image_instance) | |
428 | 2665 { |
442 | 2666 /* This function can GC if IN_REDISPLAY is false. */ |
440 | 2667 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
442 | 2668 #ifdef DEBUG_WIDGET_OUTPUT |
1318 | 2669 stderr_out ("tab control %p redisplayed\n", |
2670 IMAGE_INSTANCE_SUBWINDOW_ID (ii)); | |
442 | 2671 #endif |
2672 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) | |
2673 || | |
2674 IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (ii)) | |
428 | 2675 { |
2676 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); | |
454 | 2677 int i = 0, selected_idx = 0; |
428 | 2678 Lisp_Object rest; |
442 | 2679 |
2680 assert (!NILP (IMAGE_INSTANCE_WIDGET_ITEMS (ii))); | |
2681 | |
2682 /* If only the order has changed then simply select the first | |
2683 one. This stops horrendous rebuilding of the tabs each time | |
2684 you click on one. */ | |
2685 if (tab_control_order_only_changed (image_instance)) | |
428 | 2686 { |
442 | 2687 Lisp_Object selected = |
2688 gui_item_list_find_selected | |
2689 (NILP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)) ? | |
2690 XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)) : | |
2691 XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))); | |
2692 | |
2693 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))) | |
2694 { | |
1913 | 2695 if (gui_item_equal_sans_selected (XCAR (rest), selected, 0)) |
442 | 2696 { |
1318 | 2697 Lisp_Object old_selected = |
2698 gui_item_list_find_selected | |
442 | 2699 (XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))); |
2700 | |
2701 /* Pick up the new selected item. */ | |
2702 XGUI_ITEM (old_selected)->selected = | |
2703 XGUI_ITEM (XCAR (rest))->selected; | |
2704 XGUI_ITEM (XCAR (rest))->selected = | |
2705 XGUI_ITEM (selected)->selected; | |
2706 /* We're not actually changing the items. */ | |
2707 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0; | |
2708 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil; | |
2709 | |
771 | 2710 qxeSendMessage (wnd, TCM_SETCURSEL, i, 0); |
442 | 2711 #ifdef DEBUG_WIDGET_OUTPUT |
2712 stderr_out ("tab control %p selected item %d\n", | |
1318 | 2713 IMAGE_INSTANCE_SUBWINDOW_ID (ii), i); |
442 | 2714 #endif |
2715 break; | |
2716 } | |
2717 i++; | |
2718 } | |
428 | 2719 } |
442 | 2720 else |
2721 { | |
2722 /* delete the pre-existing items */ | |
771 | 2723 qxeSendMessage (wnd, TCM_DELETEALLITEMS, 0, 0); |
442 | 2724 |
2725 /* add items to the tab */ | |
2726 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))) | |
2727 { | |
2728 add_tab_item (image_instance, wnd, XCAR (rest), | |
2729 IMAGE_INSTANCE_FRAME (ii), i); | |
1913 | 2730 if (gui_item_selected_p (XCAR (rest))) |
454 | 2731 selected_idx = i; |
442 | 2732 i++; |
2733 } | |
771 | 2734 qxeSendMessage (wnd, TCM_SETCURSEL, selected_idx, 0); |
442 | 2735 } |
428 | 2736 } |
2737 } | |
2738 | |
2739 /* instantiate a static control possible for putting other things in */ | |
2740 static void | |
502 | 2741 mswindows_label_instantiate (Lisp_Object image_instance, |
2742 Lisp_Object instantiator, | |
428 | 2743 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
2744 int dest_mask, Lisp_Object domain) | |
2745 { | |
2746 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg, | |
771 | 2747 pointer_bg, dest_mask, domain, |
2748 "STATIC", 0, WS_EX_STATICEDGE); | |
428 | 2749 } |
2750 | |
2751 /* instantiate a scrollbar control */ | |
2752 static void | |
502 | 2753 mswindows_scrollbar_instantiate (Lisp_Object image_instance, |
2754 Lisp_Object instantiator, | |
2755 Lisp_Object pointer_fg, | |
2756 Lisp_Object pointer_bg, | |
428 | 2757 int dest_mask, Lisp_Object domain) |
2758 { | |
2759 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg, | |
771 | 2760 pointer_bg, dest_mask, domain, |
2761 "SCROLLBAR", WS_TABSTOP, WS_EX_CLIENTEDGE); | |
428 | 2762 } |
2763 | |
2764 /* instantiate a combo control */ | |
2765 static void | |
502 | 2766 mswindows_combo_box_instantiate (Lisp_Object image_instance, |
2767 Lisp_Object instantiator, | |
2768 Lisp_Object pointer_fg, | |
2769 Lisp_Object pointer_bg, | |
2770 int dest_mask, Lisp_Object domain) | |
428 | 2771 { |
440 | 2772 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
442 | 2773 HWND wnd; |
428 | 2774 Lisp_Object rest; |
442 | 2775 Lisp_Object items = find_keyword_in_vector (instantiator, Q_items); |
438 | 2776 int len, height; |
428 | 2777 |
2778 /* Maybe ought to generalise this more but it may be very windows | |
2779 specific. In windows the window height of a combo box is the | |
2780 height when the combo box is open. Thus we need to set the height | |
2781 before creating the window and then reset it to a single line | |
2782 after the window is created so that redisplay does the right | |
2783 thing. */ | |
438 | 2784 widget_instantiate (image_instance, instantiator, pointer_fg, |
2785 pointer_bg, dest_mask, domain); | |
2786 | |
2787 /* We now have everything right apart from the height. */ | |
2788 default_face_font_info (domain, 0, 0, &height, 0, 0); | |
442 | 2789 GET_LIST_LENGTH (items, len); |
438 | 2790 |
863 | 2791 height = (height + DEFAULT_WIDGET_BORDER_WIDTH * 2 ) * len; |
438 | 2792 IMAGE_INSTANCE_HEIGHT (ii) = height; |
440 | 2793 |
438 | 2794 /* Now create the widget. */ |
428 | 2795 mswindows_widget_instantiate (image_instance, instantiator, pointer_fg, |
771 | 2796 pointer_bg, dest_mask, domain, |
2797 "COMBOBOX", | |
428 | 2798 WS_BORDER | WS_TABSTOP | CBS_DROPDOWN |
434 | 2799 | CBS_AUTOHSCROLL |
428 | 2800 | CBS_HASSTRINGS | WS_VSCROLL, |
438 | 2801 WS_EX_CLIENTEDGE); |
2802 /* Reset the height. layout will probably do this safely, but better make sure. */ | |
440 | 2803 image_instance_layout (image_instance, |
438 | 2804 IMAGE_UNSPECIFIED_GEOMETRY, |
2805 IMAGE_UNSPECIFIED_GEOMETRY, | |
442 | 2806 IMAGE_UNCHANGED_GEOMETRY, |
2807 IMAGE_UNCHANGED_GEOMETRY, | |
438 | 2808 domain); |
2809 | |
428 | 2810 wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); |
2811 /* add items to the combo box */ | |
771 | 2812 qxeSendMessage (wnd, CB_RESETCONTENT, 0, 0); |
442 | 2813 LIST_LOOP (rest, items) |
428 | 2814 { |
771 | 2815 Extbyte *lparam; |
2816 LISP_STRING_TO_TSTR (XCAR (rest), lparam); | |
2817 if (qxeSendMessage (wnd, CB_ADDSTRING, 0, (LPARAM)lparam) == CB_ERR) | |
563 | 2818 gui_error ("error adding combo entries", instantiator); |
428 | 2819 } |
2820 } | |
2821 | |
2822 /* get properties of a control */ | |
2823 static Lisp_Object | |
2824 mswindows_widget_property (Lisp_Object image_instance, Lisp_Object prop) | |
2825 { | |
440 | 2826 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
442 | 2827 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); |
428 | 2828 /* get the text from a control */ |
2829 if (EQ (prop, Q_text)) | |
2830 { | |
771 | 2831 Charcount tchar_len = qxeSendMessage (wnd, WM_GETTEXTLENGTH, 0, 0); |
2367 | 2832 Extbyte *buf = alloca_extbytes (XETCHAR_SIZE * (tchar_len + 1)); |
771 | 2833 |
2834 qxeSendMessage (wnd, WM_GETTEXT, (WPARAM)tchar_len + 1, (LPARAM) buf); | |
2835 return build_tstr_string (buf); | |
428 | 2836 } |
2837 return Qunbound; | |
2838 } | |
2839 | |
2840 /* get properties of a button */ | |
2841 static Lisp_Object | |
2842 mswindows_button_property (Lisp_Object image_instance, Lisp_Object prop) | |
2843 { | |
440 | 2844 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
442 | 2845 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); |
428 | 2846 /* check the state of a button */ |
2847 if (EQ (prop, Q_selected)) | |
2848 { | |
771 | 2849 if (qxeSendMessage (wnd, BM_GETSTATE, 0, 0) & BST_CHECKED) |
428 | 2850 return Qt; |
2851 else | |
2852 return Qnil; | |
2853 } | |
2854 return Qunbound; | |
2855 } | |
2856 | |
2857 /* get properties of a combo box */ | |
2858 static Lisp_Object | |
2859 mswindows_combo_box_property (Lisp_Object image_instance, Lisp_Object prop) | |
2860 { | |
440 | 2861 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
442 | 2862 HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii); |
428 | 2863 /* get the text from a control */ |
2864 if (EQ (prop, Q_text)) | |
2865 { | |
771 | 2866 long item = qxeSendMessage (wnd, CB_GETCURSEL, 0, 0); |
2867 Charcount tchar_len = qxeSendMessage (wnd, CB_GETLBTEXTLEN, | |
2868 (WPARAM)item, 0); | |
2367 | 2869 Extbyte *buf = alloca_extbytes (XETCHAR_SIZE * (tchar_len + 1)); |
771 | 2870 qxeSendMessage (wnd, CB_GETLBTEXT, (WPARAM)item, (LPARAM) buf); |
2871 return build_tstr_string (buf); | |
428 | 2872 } |
2873 return Qunbound; | |
2874 } | |
2875 | |
442 | 2876 /* set the properties of a progress gauge */ |
2877 static void | |
2878 mswindows_progress_gauge_redisplay (Lisp_Object image_instance) | |
428 | 2879 { |
440 | 2880 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 2881 |
442 | 2882 if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)) |
428 | 2883 { |
442 | 2884 Lisp_Object val; |
2885 val = XGUI_ITEM (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))->value; | |
2886 #ifdef DEBUG_WIDGET_OUTPUT | |
2887 stderr_out ("progress gauge displayed value on %p updated to %ld\n", | |
2888 WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii), | |
2889 XINT(val)); | |
2890 #endif | |
428 | 2891 CHECK_INT (val); |
771 | 2892 qxeSendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii), |
2893 PBM_SETPOS, (WPARAM)XINT (val), 0); | |
428 | 2894 } |
2895 } | |
2896 | |
2897 LRESULT WINAPI | |
438 | 2898 mswindows_control_wnd_proc (HWND hwnd, UINT msg, |
428 | 2899 WPARAM wParam, LPARAM lParam) |
2900 { | |
438 | 2901 switch (msg) |
428 | 2902 { |
2903 case WM_NOTIFY: | |
2904 case WM_COMMAND: | |
2905 case WM_CTLCOLORBTN: | |
2906 case WM_CTLCOLORLISTBOX: | |
2907 case WM_CTLCOLOREDIT: | |
2908 case WM_CTLCOLORSTATIC: | |
2909 case WM_CTLCOLORSCROLLBAR: | |
2910 | |
438 | 2911 return mswindows_wnd_proc (GetParent (hwnd), msg, wParam, lParam); |
428 | 2912 default: |
771 | 2913 return qxeDefWindowProc (hwnd, msg, wParam, lParam); |
2914 } | |
2915 } | |
2916 | |
2917 static void | |
2918 mswindows_widget_query_string_geometry (Lisp_Object string, Lisp_Object face, | |
2919 int *width, int *height, | |
2920 Lisp_Object domain) | |
2921 { | |
2922 if (height) | |
2923 query_string_geometry (string, face, 0, height, 0, domain); | |
2924 | |
2925 if (width) | |
2926 { | |
2927 HDC hdc = FRAME_MSWINDOWS_DC (DOMAIN_XFRAME (domain)); | |
2928 Extbyte *str; | |
2929 Bytecount len; | |
2930 SIZE size; | |
2931 | |
2932 SelectObject (hdc, mswindows_widget_hfont (face, domain, string)); | |
2933 TO_EXTERNAL_FORMAT (LISP_STRING, string, ALLOCA, (str, len), | |
2934 Qmswindows_tstr); | |
2935 qxeGetTextExtentPoint32 (hdc, str, len / XETCHAR_SIZE, &size); | |
2936 *width = size.cx; | |
428 | 2937 } |
2938 } | |
2939 | |
2940 #endif /* HAVE_WIDGETS */ | |
2941 | |
2942 | |
2943 /************************************************************************/ | |
2944 /* initialization */ | |
2945 /************************************************************************/ | |
2946 | |
2947 void | |
2948 syms_of_glyphs_mswindows (void) | |
2949 { | |
2950 } | |
2951 | |
2952 void | |
2953 console_type_create_glyphs_mswindows (void) | |
2954 { | |
442 | 2955 /* image methods - display */ |
428 | 2956 CONSOLE_HAS_METHOD (mswindows, print_image_instance); |
2957 CONSOLE_HAS_METHOD (mswindows, finalize_image_instance); | |
2958 CONSOLE_HAS_METHOD (mswindows, unmap_subwindow); | |
2959 CONSOLE_HAS_METHOD (mswindows, map_subwindow); | |
442 | 2960 CONSOLE_HAS_METHOD (mswindows, redisplay_subwindow); |
2961 CONSOLE_HAS_METHOD (mswindows, resize_subwindow); | |
2962 CONSOLE_HAS_METHOD (mswindows, redisplay_widget); | |
428 | 2963 CONSOLE_HAS_METHOD (mswindows, image_instance_equal); |
2964 CONSOLE_HAS_METHOD (mswindows, image_instance_hash); | |
2965 CONSOLE_HAS_METHOD (mswindows, init_image_instance_from_eimage); | |
2966 CONSOLE_HAS_METHOD (mswindows, locate_pixmap_file); | |
771 | 2967 #ifdef HAVE_WIDGETS |
2968 CONSOLE_HAS_METHOD (mswindows, widget_query_string_geometry); | |
863 | 2969 CONSOLE_HAS_METHOD (mswindows, widget_border_width); |
771 | 2970 #endif |
442 | 2971 |
2972 /* image methods - printer */ | |
2973 CONSOLE_INHERITS_METHOD (msprinter, mswindows, print_image_instance); | |
2974 CONSOLE_INHERITS_METHOD (msprinter, mswindows, finalize_image_instance); | |
2975 CONSOLE_INHERITS_METHOD (msprinter, mswindows, image_instance_equal); | |
2976 CONSOLE_INHERITS_METHOD (msprinter, mswindows, image_instance_hash); | |
771 | 2977 CONSOLE_INHERITS_METHOD (msprinter, mswindows, |
2978 init_image_instance_from_eimage); | |
442 | 2979 CONSOLE_INHERITS_METHOD (msprinter, mswindows, locate_pixmap_file); |
428 | 2980 } |
2981 | |
2982 void | |
2983 image_instantiator_format_create_glyphs_mswindows (void) | |
2984 { | |
442 | 2985 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, nothing); |
2986 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, string); | |
2987 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, formatted_string); | |
2988 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, inherit); | |
428 | 2989 /* image-instantiator types */ |
442 | 2990 INITIALIZE_DEVICE_IIFORMAT (mswindows, xbm); |
2991 INITIALIZE_DEVICE_IIFORMAT (msprinter, xbm); | |
2992 IIFORMAT_HAS_DEVMETHOD (mswindows, xbm, instantiate); | |
2993 IIFORMAT_INHERITS_DEVMETHOD (msprinter, mswindows, xbm, instantiate); | |
428 | 2994 #ifdef HAVE_XPM |
2995 INITIALIZE_DEVICE_IIFORMAT (mswindows, xpm); | |
442 | 2996 INITIALIZE_DEVICE_IIFORMAT (msprinter, xpm); |
428 | 2997 IIFORMAT_HAS_DEVMETHOD (mswindows, xpm, instantiate); |
442 | 2998 IIFORMAT_INHERITS_DEVMETHOD (msprinter, mswindows, xpm, instantiate); |
428 | 2999 #endif |
3000 #ifdef HAVE_XFACE | |
3001 INITIALIZE_DEVICE_IIFORMAT (mswindows, xface); | |
442 | 3002 INITIALIZE_DEVICE_IIFORMAT (msprinter, xface); |
428 | 3003 IIFORMAT_HAS_DEVMETHOD (mswindows, xface, instantiate); |
442 | 3004 IIFORMAT_INHERITS_DEVMETHOD (msprinter, mswindows, xface, instantiate); |
428 | 3005 #endif |
3006 #ifdef HAVE_JPEG | |
442 | 3007 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, jpeg); |
428 | 3008 #endif |
3009 #ifdef HAVE_TIFF | |
442 | 3010 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, tiff); |
434 | 3011 #endif |
428 | 3012 #ifdef HAVE_PNG |
442 | 3013 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, png); |
434 | 3014 #endif |
428 | 3015 #ifdef HAVE_GIF |
442 | 3016 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, gif); |
434 | 3017 #endif |
428 | 3018 #ifdef HAVE_WIDGETS |
442 | 3019 INITIALIZE_DEVICE_IIFORMAT (mswindows, widget); |
3020 IIFORMAT_HAS_DEVMETHOD (mswindows, widget, property); | |
3021 /* layout widget */ | |
3022 IIFORMAT_VALID_CONSOLE (mswindows, layout); | |
3023 INITIALIZE_DEVICE_IIFORMAT (mswindows, native_layout); | |
3024 IIFORMAT_HAS_DEVMETHOD (mswindows, native_layout, instantiate); | |
428 | 3025 /* button widget */ |
3026 INITIALIZE_DEVICE_IIFORMAT (mswindows, button); | |
3027 IIFORMAT_HAS_DEVMETHOD (mswindows, button, property); | |
3028 IIFORMAT_HAS_DEVMETHOD (mswindows, button, instantiate); | |
442 | 3029 IIFORMAT_HAS_DEVMETHOD (mswindows, button, redisplay); |
3030 /* edit-field widget */ | |
428 | 3031 INITIALIZE_DEVICE_IIFORMAT (mswindows, edit_field); |
3032 IIFORMAT_HAS_DEVMETHOD (mswindows, edit_field, instantiate); | |
442 | 3033 /* subwindow */ |
428 | 3034 INITIALIZE_DEVICE_IIFORMAT (mswindows, subwindow); |
3035 IIFORMAT_HAS_DEVMETHOD (mswindows, subwindow, instantiate); | |
3036 /* label */ | |
3037 INITIALIZE_DEVICE_IIFORMAT (mswindows, label); | |
3038 IIFORMAT_HAS_DEVMETHOD (mswindows, label, instantiate); | |
3039 /* combo box */ | |
3040 INITIALIZE_DEVICE_IIFORMAT (mswindows, combo_box); | |
3041 IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, property); | |
3042 IIFORMAT_HAS_DEVMETHOD (mswindows, combo_box, instantiate); | |
3043 /* scrollbar */ | |
3044 INITIALIZE_DEVICE_IIFORMAT (mswindows, scrollbar); | |
3045 IIFORMAT_HAS_DEVMETHOD (mswindows, scrollbar, instantiate); | |
3046 /* progress gauge */ | |
3047 INITIALIZE_DEVICE_IIFORMAT (mswindows, progress_gauge); | |
442 | 3048 IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, redisplay); |
428 | 3049 IIFORMAT_HAS_DEVMETHOD (mswindows, progress_gauge, instantiate); |
3050 /* tree view widget */ | |
3051 INITIALIZE_DEVICE_IIFORMAT (mswindows, tree_view); | |
3052 IIFORMAT_HAS_DEVMETHOD (mswindows, tree_view, instantiate); | |
442 | 3053 IIFORMAT_HAS_DEVMETHOD (mswindows, tree_view, redisplay); |
428 | 3054 /* tab control widget */ |
3055 INITIALIZE_DEVICE_IIFORMAT (mswindows, tab_control); | |
3056 IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, instantiate); | |
442 | 3057 IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, redisplay); |
428 | 3058 #endif |
3059 /* windows bitmap format */ | |
3060 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (bmp, "bmp"); | |
3061 IIFORMAT_HAS_METHOD (bmp, validate); | |
3062 IIFORMAT_HAS_METHOD (bmp, normalize); | |
3063 IIFORMAT_HAS_METHOD (bmp, possible_dest_types); | |
3064 IIFORMAT_HAS_METHOD (bmp, instantiate); | |
3065 | |
3066 IIFORMAT_VALID_KEYWORD (bmp, Q_data, check_valid_string); | |
3067 IIFORMAT_VALID_KEYWORD (bmp, Q_file, check_valid_string); | |
442 | 3068 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, bmp); |
428 | 3069 |
3070 /* mswindows resources */ | |
3071 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (mswindows_resource, | |
3072 "mswindows-resource"); | |
3073 | |
3074 IIFORMAT_HAS_METHOD (mswindows_resource, validate); | |
3075 IIFORMAT_HAS_METHOD (mswindows_resource, normalize); | |
3076 IIFORMAT_HAS_METHOD (mswindows_resource, possible_dest_types); | |
3077 IIFORMAT_HAS_METHOD (mswindows_resource, instantiate); | |
3078 | |
434 | 3079 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_type, |
428 | 3080 check_valid_resource_symbol); |
3081 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_resource_id, check_valid_resource_id); | |
3082 IIFORMAT_VALID_KEYWORD (mswindows_resource, Q_file, check_valid_string); | |
442 | 3083 IIFORMAT_VALID_CONSOLE2 (mswindows, msprinter, mswindows_resource); |
428 | 3084 } |
3085 | |
3086 void | |
3087 vars_of_glyphs_mswindows (void) | |
3088 { | |
3089 DEFVAR_LISP ("mswindows-bitmap-file-path", &Vmswindows_bitmap_file_path /* | |
3090 A list of the directories in which mswindows bitmap files may be found. | |
3091 This is used by the `make-image-instance' function. | |
3092 */ ); | |
3093 Vmswindows_bitmap_file_path = Qnil; | |
3094 } | |
3095 | |
3096 void | |
3097 complex_vars_of_glyphs_mswindows (void) | |
3098 { | |
3099 } |