Mercurial > hg > xemacs-beta
annotate src/device-msw.c @ 4981:4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
-------------------- ChangeLog entries follow: --------------------
modules/ChangeLog addition:
2010-02-05 Ben Wing <ben@xemacs.org>
* postgresql/postgresql.c:
* postgresql/postgresql.c (CHECK_LIVE_CONNECTION):
* postgresql/postgresql.c (Fpq_connectdb):
* postgresql/postgresql.c (Fpq_connect_start):
* postgresql/postgresql.c (Fpq_lo_import):
* postgresql/postgresql.c (Fpq_lo_export):
* ldap/eldap.c (Fldap_open):
* ldap/eldap.c (Fldap_search_basic):
* ldap/eldap.c (Fldap_add):
* ldap/eldap.c (Fldap_modify):
* ldap/eldap.c (Fldap_delete):
* canna/canna_api.c (Fcanna_initialize):
* canna/canna_api.c (Fcanna_store_yomi):
* canna/canna_api.c (Fcanna_parse):
* canna/canna_api.c (Fcanna_henkan_begin):
EXTERNAL_TO_C_STRING returns its argument instead of storing it
in a parameter, and is renamed to EXTERNAL_TO_ITEXT. Similar
things happen to related macros. See entry in src/ChangeLog.
More Mule-izing of postgresql.c. Extract out common code
between `pq-connectdb' and `pq-connect-start'. Fix places
that signal an error string using a formatted string to instead
follow the standard and have a fixed reason followed by the
particular error message stored as one of the frobs.
src/ChangeLog addition:
2010-02-05 Ben Wing <ben@xemacs.org>
* console-msw.c (write_string_to_mswindows_debugging_output):
* console-msw.c (Fmswindows_message_box):
* console-x.c (x_perhaps_init_unseen_key_defaults):
* console.c:
* database.c (dbm_get):
* database.c (dbm_put):
* database.c (dbm_remove):
* database.c (berkdb_get):
* database.c (berkdb_put):
* database.c (berkdb_remove):
* database.c (Fopen_database):
* device-gtk.c (gtk_init_device):
* device-msw.c (msprinter_init_device_internal):
* device-msw.c (msprinter_default_printer):
* device-msw.c (msprinter_init_device):
* device-msw.c (sync_printer_with_devmode):
* device-msw.c (Fmsprinter_select_settings):
* device-x.c (sanity_check_geometry_resource):
* device-x.c (Dynarr_add_validified_lisp_string):
* device-x.c (x_init_device):
* device-x.c (Fx_put_resource):
* device-x.c (Fx_valid_keysym_name_p):
* device-x.c (Fx_set_font_path):
* dialog-msw.c (push_lisp_string_as_unicode):
* dialog-msw.c (handle_directory_dialog_box):
* dialog-msw.c (handle_file_dialog_box):
* dialog-x.c (dbox_descriptor_to_widget_value):
* editfns.c (Fformat_time_string):
* editfns.c (Fencode_time):
* editfns.c (Fset_time_zone_rule):
* emacs.c (make_argc_argv):
* emacs.c (Fdump_emacs):
* emodules.c (emodules_load):
* eval.c:
* eval.c (maybe_signal_error_1):
* event-msw.c (Fdde_alloc_advise_item):
* event-msw.c (mswindows_dde_callback):
* event-msw.c (mswindows_wnd_proc):
* fileio.c (report_error_with_errno):
* fileio.c (Fsysnetunam):
* fileio.c (Fdo_auto_save):
* font-mgr.c (extract_fcapi_string):
* font-mgr.c (Ffc_config_app_font_add_file):
* font-mgr.c (Ffc_config_app_font_add_dir):
* font-mgr.c (Ffc_config_filename):
* frame-gtk.c (gtk_set_frame_text_value):
* frame-gtk.c (gtk_create_widgets):
* frame-msw.c (mswindows_init_frame_1):
* frame-msw.c (mswindows_set_title_from_ibyte):
* frame-msw.c (msprinter_init_frame_3):
* frame-x.c (x_set_frame_text_value):
* frame-x.c (x_set_frame_properties):
* frame-x.c (start_drag_internal_1):
* frame-x.c (x_cde_transfer_callback):
* frame-x.c (x_create_widgets):
* glyphs-eimage.c (my_jpeg_output_message):
* glyphs-eimage.c (jpeg_instantiate):
* glyphs-eimage.c (gif_instantiate):
* glyphs-eimage.c (png_instantiate):
* glyphs-eimage.c (tiff_instantiate):
* glyphs-gtk.c (xbm_instantiate_1):
* glyphs-gtk.c (gtk_xbm_instantiate):
* glyphs-gtk.c (gtk_xpm_instantiate):
* glyphs-gtk.c (gtk_xface_instantiate):
* glyphs-gtk.c (cursor_font_instantiate):
* glyphs-gtk.c (gtk_redisplay_widget):
* glyphs-gtk.c (gtk_widget_instantiate_1):
* glyphs-gtk.c (gtk_add_tab_item):
* glyphs-msw.c (mswindows_xpm_instantiate):
* glyphs-msw.c (bmp_instantiate):
* glyphs-msw.c (mswindows_resource_instantiate):
* glyphs-msw.c (xbm_instantiate_1):
* glyphs-msw.c (mswindows_xbm_instantiate):
* glyphs-msw.c (mswindows_xface_instantiate):
* glyphs-msw.c (mswindows_redisplay_widget):
* glyphs-msw.c (mswindows_widget_instantiate):
* glyphs-msw.c (add_tree_item):
* glyphs-msw.c (add_tab_item):
* glyphs-msw.c (mswindows_combo_box_instantiate):
* glyphs-msw.c (mswindows_widget_query_string_geometry):
* glyphs-x.c (x_locate_pixmap_file):
* glyphs-x.c (xbm_instantiate_1):
* glyphs-x.c (x_xbm_instantiate):
* glyphs-x.c (extract_xpm_color_names):
* glyphs-x.c (x_xpm_instantiate):
* glyphs-x.c (x_xface_instantiate):
* glyphs-x.c (autodetect_instantiate):
* glyphs-x.c (safe_XLoadFont):
* glyphs-x.c (cursor_font_instantiate):
* glyphs-x.c (x_redisplay_widget):
* glyphs-x.c (Fchange_subwindow_property):
* glyphs-x.c (x_widget_instantiate):
* glyphs-x.c (x_tab_control_redisplay):
* glyphs.c (pixmap_to_lisp_data):
* gui-x.c (menu_separator_style_and_to_external):
* gui-x.c (add_accel_and_to_external):
* gui-x.c (button_item_to_widget_value):
* hpplay.c (player_error_internal):
* hpplay.c (play_sound_file):
* hpplay.c (play_sound_data):
* intl.c (Fset_current_locale):
* lisp.h:
* menubar-gtk.c (gtk_xemacs_set_accel_keys):
* menubar-msw.c (populate_menu_add_item):
* menubar-msw.c (populate_or_checksum_helper):
* menubar-x.c (menu_item_descriptor_to_widget_value_1):
* nt.c (init_user_info):
* nt.c (get_long_basename):
* nt.c (nt_get_resource):
* nt.c (init_mswindows_environment):
* nt.c (get_cached_volume_information):
* nt.c (mswindows_readdir):
* nt.c (read_unc_volume):
* nt.c (mswindows_stat):
* nt.c (mswindows_getdcwd):
* nt.c (mswindows_executable_type):
* nt.c (Fmswindows_short_file_name):
* ntplay.c (nt_play_sound_file):
* objects-gtk.c:
* objects-gtk.c (gtk_valid_color_name_p):
* objects-gtk.c (gtk_initialize_font_instance):
* objects-gtk.c (gtk_font_list):
* objects-msw.c (font_enum_callback_2):
* objects-msw.c (parse_font_spec):
* objects-x.c (x_parse_nearest_color):
* objects-x.c (x_valid_color_name_p):
* objects-x.c (x_initialize_font_instance):
* objects-x.c (x_font_instance_truename):
* objects-x.c (x_font_list):
* objects-xlike-inc.c (XFUN):
* objects-xlike-inc.c (xft_find_charset_font):
* process-nt.c (mswindows_report_winsock_error):
* process-nt.c (nt_create_process):
* process-nt.c (get_internet_address):
* process-nt.c (nt_open_network_stream):
* process-unix.c:
* process-unix.c (allocate_pty):
* process-unix.c (get_internet_address):
* process-unix.c (unix_canonicalize_host_name):
* process-unix.c (unix_open_network_stream):
* realpath.c:
* select-common.h (lisp_data_to_selection_data):
* select-gtk.c (symbol_to_gtk_atom):
* select-gtk.c (atom_to_symbol):
* select-msw.c (symbol_to_ms_cf):
* select-msw.c (mswindows_register_selection_data_type):
* select-x.c (symbol_to_x_atom):
* select-x.c (x_atom_to_symbol):
* select-x.c (hack_motif_clipboard_selection):
* select-x.c (Fx_store_cutbuffer_internal):
* sound.c (Fplay_sound_file):
* sound.c (Fplay_sound):
* sound.h (sound_perror):
* sysdep.c:
* sysdep.c (qxe_allocating_getcwd):
* sysdep.c (qxe_execve):
* sysdep.c (copy_in_passwd):
* sysdep.c (qxe_getpwnam):
* sysdep.c (qxe_ctime):
* sysdll.c (dll_open):
* sysdll.c (dll_function):
* sysdll.c (dll_variable):
* sysdll.c (search_linked_libs):
* sysdll.c (dll_error):
* sysfile.h:
* sysfile.h (PATHNAME_CONVERT_OUT_TSTR):
* sysfile.h (PATHNAME_CONVERT_OUT_UTF_8):
* sysfile.h (PATHNAME_CONVERT_OUT):
* sysfile.h (LISP_PATHNAME_CONVERT_OUT):
* syswindows.h (ITEXT_TO_TSTR):
* syswindows.h (LOCAL_FILE_FORMAT_TO_TSTR):
* syswindows.h (TSTR_TO_LOCAL_FILE_FORMAT):
* syswindows.h (LOCAL_FILE_FORMAT_TO_INTERNAL_MSWIN):
* syswindows.h (LISP_LOCAL_FILE_FORMAT_MAYBE_URL_TO_TSTR):
* text.h:
* text.h (eicpy_ext_len):
* text.h (enum new_dfc_src_type):
* text.h (EXTERNAL_TO_ITEXT):
* text.h (GET_STRERROR):
* tooltalk.c (check_status):
* tooltalk.c (Fadd_tooltalk_message_arg):
* tooltalk.c (Fadd_tooltalk_pattern_attribute):
* tooltalk.c (Fadd_tooltalk_pattern_arg):
* win32.c (tstr_to_local_file_format):
* win32.c (mswindows_lisp_error_1):
* win32.c (mswindows_report_process_error):
* win32.c (Fmswindows_shell_execute):
* win32.c (mswindows_read_link_1):
Changes involving external/internal format conversion,
mostly code cleanup and renaming.
1. Eliminate the previous macros like LISP_STRING_TO_EXTERNAL
that stored its result in a parameter. The new version of
LISP_STRING_TO_EXTERNAL returns its result through the
return value, same as the previous NEW_LISP_STRING_TO_EXTERNAL.
Use the new-style macros throughout the code.
2. Rename C_STRING_TO_EXTERNAL and friends to ITEXT_TO_EXTERNAL,
in keeping with overall naming rationalization involving
Itext and related types.
Macros involved in previous two:
EXTERNAL_TO_C_STRING -> EXTERNAL_TO_ITEXT
EXTERNAL_TO_C_STRING_MALLOC -> EXTERNAL_TO_ITEXT_MALLOC
SIZED_EXTERNAL_TO_C_STRING -> SIZED_EXTERNAL_TO_ITEXT
SIZED_EXTERNAL_TO_C_STRING_MALLOC -> SIZED_EXTERNAL_TO_ITEXT_MALLOC
C_STRING_TO_EXTERNAL -> ITEXT_TO_EXTERNAL
C_STRING_TO_EXTERNAL_MALLOC -> ITEXT_TO_EXTERNAL_MALLOC
LISP_STRING_TO_EXTERNAL
LISP_STRING_TO_EXTERNAL_MALLOC
LISP_STRING_TO_TSTR
C_STRING_TO_TSTR -> ITEXT_TO_TSTR
TSTR_TO_C_STRING -> TSTR_TO_ITEXT
The following four still return their values through parameters,
since they have more than one value to return:
C_STRING_TO_SIZED_EXTERNAL -> ITEXT_TO_SIZED_EXTERNAL
LISP_STRING_TO_SIZED_EXTERNAL
C_STRING_TO_SIZED_EXTERNAL_MALLOC -> ITEXT_TO_SIZED_EXTERNAL_MALLOC
LISP_STRING_TO_SIZED_EXTERNAL_MALLOC
Sometimes additional casts had to be inserted, since the old
macros played strange games and completely defeated the type system
of the store params.
3. Rewrite many places where direct calls to TO_EXTERNAL_FORMAT
occurred with calls to one of the convenience macros listed above,
or to make_extstring().
4. Eliminate SIZED_C_STRING macros (they were hardly used, anyway)
and use a direct call to TO_EXTERNAL_FORMAT or TO_INTERNAL_FORMAT.
4. Use LISP_PATHNAME_CONVERT_OUT in many places instead of something
like LISP_STRING_TO_EXTERNAL(..., Qfile_name).
5. Eliminate some temporary variables that are no longer necessary
now that we return a value rather than storing it into a variable.
6. Some Mule-izing in database.c.
7. Error functions:
-- A bit of code cleanup in maybe_signal_error_1.
-- Eliminate report_file_type_error; it's just an alias for
signal_error_2 with params in a different order.
-- Fix some places in the hostname-handling code that directly
inserted externally-retrieved error strings into the
supposed ASCII "reason" param instead of doing the right thing
and sticking text descriptive of what was going on in "reason"
and putting the external message in a frob.
8. Use Ascbyte instead of CIbyte in process-unix.c and maybe one
or two other places.
9. Some code cleanup in copy_in_passwd() in sysdep.c.
10. Fix a real bug due to accidental variable shadowing in
tstr_to_local_file_format() in win32.c.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Fri, 05 Feb 2010 11:02:24 -0600 |
parents | e813cf16c015 |
children | 3c3c1d139863 |
rev | line source |
---|---|
428 | 1 /* device functions for mswindows. |
2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. | |
3 Copyright (C) 1994, 1995 Free Software Foundation, Inc. | |
771 | 4 Copyright (C) 2000, 2001, 2002 Ben Wing. |
428 | 5 |
6 This file is part of XEmacs. | |
7 | |
8 XEmacs is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
10 Free Software Foundation; either version 2, or (at your option) any | |
11 later version. | |
12 | |
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with XEmacs; see the file COPYING. If not, write to | |
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
21 Boston, MA 02111-1307, USA. */ | |
22 | |
23 /* Synched up with: Not in FSF. */ | |
24 | |
771 | 25 /* This file Mule-ized 8-11-2000. */ |
26 | |
428 | 27 /* Authorship: |
28 | |
29 Original authors: Jamie Zawinski and the FSF | |
30 Rewritten by Ben Wing and Chuck Thompson. | |
31 Rewritten for mswindows by Jonathan Harris, November 1997 for 21.0. | |
510 | 32 Print support added by Kirill Katsnelson, July 2000. |
428 | 33 */ |
34 | |
771 | 35 #define NEED_MSWINDOWS_COMMCTRL |
36 #define NEED_MSWINDOWS_OBJBASE /* for CoInitialize */ | |
428 | 37 |
38 #include <config.h> | |
39 #include "lisp.h" | |
40 | |
872 | 41 #include "device-impl.h" |
800 | 42 #include "events.h" |
43 #include "faces.h" | |
44 #include "frame.h" | |
45 | |
872 | 46 #include "console-msw-impl.h" |
428 | 47 #include "console-stream.h" |
442 | 48 #include "objects-msw.h" |
800 | 49 |
428 | 50 #include "sysdep.h" |
51 | |
52 /* win32 DDE management library globals */ | |
53 #ifdef HAVE_DRAGNDROP | |
54 DWORD mswindows_dde_mlid; | |
657 | 55 int mswindows_dde_enable; |
428 | 56 HSZ mswindows_dde_service; |
57 HSZ mswindows_dde_topic_system; | |
903 | 58 HSZ mswindows_dde_topic_eval; |
59 HSZ mswindows_dde_item_result; | |
428 | 60 HSZ mswindows_dde_item_open; |
61 #endif | |
62 | |
4477
e34711681f30
Don't determine whether to call general device-type code at startup,
Aidan Kehoe <kehoea@parhasard.net>
parents:
4117
diff
changeset
|
63 Lisp_Object Qmake_device_early_mswindows_entry_point, |
e34711681f30
Don't determine whether to call general device-type code at startup,
Aidan Kehoe <kehoea@parhasard.net>
parents:
4117
diff
changeset
|
64 Qmake_device_late_mswindows_entry_point; |
442 | 65 Lisp_Object Qdevmodep; |
428 | 66 |
510 | 67 static Lisp_Object Q_allow_selection; |
68 static Lisp_Object Q_allow_pages; | |
69 static Lisp_Object Q_selected_page_button; | |
70 static Lisp_Object Qselected_page_button; | |
71 | |
1204 | 72 static const struct memory_description mswindows_device_data_description_1 [] = { |
73 { XD_LISP_OBJECT, offsetof (struct mswindows_device, fontlist) }, | |
74 { XD_END } | |
75 }; | |
76 | |
3092 | 77 #ifdef NEW_GC |
78 DEFINE_LRECORD_IMPLEMENTATION ("mswindows-device", mswindows_device, | |
79 1, /*dumpable-flag*/ | |
80 0, 0, 0, 0, 0, | |
81 mswindows_device_data_description_1, | |
82 Lisp_Mswindows_Device); | |
83 #else /* not NEW_GC */ | |
1204 | 84 extern const struct sized_memory_description mswindows_device_data_description; |
85 | |
86 const struct sized_memory_description mswindows_device_data_description = { | |
87 sizeof (struct mswindows_device), mswindows_device_data_description_1 | |
88 }; | |
3092 | 89 #endif /* not NEW_GC */ |
1204 | 90 |
1346 | 91 static const struct memory_description msprinter_device_data_description_1 [] = { |
92 { XD_LISP_OBJECT, offsetof (struct msprinter_device, name) }, | |
93 { XD_LISP_OBJECT, offsetof (struct msprinter_device, devmode) }, | |
94 { XD_LISP_OBJECT, offsetof (struct msprinter_device, fontlist) }, | |
95 { XD_END } | |
96 }; | |
97 | |
3092 | 98 #ifdef NEW_GC |
99 DEFINE_LRECORD_IMPLEMENTATION ("msprinter-device", msprinter_device, | |
100 1, /*dumpable-flag*/ | |
101 0, 0, 0, 0, 0, | |
102 msprinter_device_data_description_1, | |
103 Lisp_Msprinter_Device); | |
104 #else /* not NEW_GC */ | |
1346 | 105 extern const struct sized_memory_description msprinter_device_data_description; |
106 | |
107 const struct sized_memory_description msprinter_device_data_description = { | |
108 sizeof (struct msprinter_device), msprinter_device_data_description_1 | |
109 }; | |
3092 | 110 #endif /* not NEW_GC */ |
1346 | 111 |
771 | 112 static Lisp_Object allocate_devmode (DEVMODEW *src_devmode, int do_copy, |
113 Lisp_Object src_name, struct device *d); | |
428 | 114 |
115 /************************************************************************/ | |
116 /* helpers */ | |
117 /************************************************************************/ | |
118 | |
119 static Lisp_Object | |
440 | 120 build_syscolor_string (int idx) |
428 | 121 { |
442 | 122 return (idx < 0 ? Qnil : mswindows_color_to_string (GetSysColor (idx))); |
428 | 123 } |
124 | |
125 static Lisp_Object | |
126 build_syscolor_cons (int index1, int index2) | |
127 { | |
128 Lisp_Object color1, color2; | |
129 struct gcpro gcpro1; | |
130 GCPRO1 (color1); | |
131 color1 = build_syscolor_string (index1); | |
132 color2 = build_syscolor_string (index2); | |
133 RETURN_UNGCPRO (Fcons (color1, color2)); | |
134 } | |
135 | |
136 static Lisp_Object | |
137 build_sysmetrics_cons (int index1, int index2) | |
138 { | |
139 return Fcons (index1 < 0 ? Qnil : make_int (GetSystemMetrics (index1)), | |
140 index2 < 0 ? Qnil : make_int (GetSystemMetrics (index2))); | |
141 } | |
142 | |
440 | 143 static Lisp_Object |
144 build_devicecaps_cons (HDC hdc, int index1, int index2) | |
145 { | |
146 return Fcons (index1 < 0 ? Qnil : make_int (GetDeviceCaps (hdc, index1)), | |
147 index2 < 0 ? Qnil : make_int (GetDeviceCaps (hdc, index2))); | |
148 } | |
149 | |
428 | 150 |
151 /************************************************************************/ | |
440 | 152 /* display methods */ |
428 | 153 /************************************************************************/ |
154 | |
155 static void | |
2286 | 156 mswindows_init_device (struct device *d, Lisp_Object UNUSED (props)) |
428 | 157 { |
158 HDC hdc; | |
771 | 159 WNDCLASSEXW wc; |
428 | 160 |
4477
e34711681f30
Don't determine whether to call general device-type code at startup,
Aidan Kehoe <kehoea@parhasard.net>
parents:
4117
diff
changeset
|
161 call0 (Qmake_device_early_mswindows_entry_point); |
e34711681f30
Don't determine whether to call general device-type code at startup,
Aidan Kehoe <kehoea@parhasard.net>
parents:
4117
diff
changeset
|
162 |
428 | 163 DEVICE_CLASS (d) = Qcolor; |
164 DEVICE_INFD (d) = DEVICE_OUTFD (d) = -1; | |
165 init_baud_rate (d); | |
166 init_one_device (d); | |
167 | |
3092 | 168 #ifdef NEW_GC |
169 d->device_data = alloc_lrecord_type (struct mswindows_device, | |
170 &lrecord_mswindows_device); | |
171 #else /* not NEW_GC */ | |
428 | 172 d->device_data = xnew_and_zero (struct mswindows_device); |
3092 | 173 #endif /* not NEW_GC */ |
428 | 174 hdc = CreateCompatibleDC (NULL); |
771 | 175 assert (hdc != NULL); |
176 DEVICE_MSWINDOWS_HCDC (d) = hdc; | |
440 | 177 DEVICE_MSWINDOWS_FONTLIST (d) = mswindows_enumerate_fonts (hdc); |
442 | 178 DEVICE_MSWINDOWS_UPDATE_TICK (d) = GetTickCount (); |
428 | 179 |
180 /* Register the main window class */ | |
771 | 181 wc.cbSize = sizeof (wc); |
428 | 182 wc.style = CS_OWNDC; /* One DC per window */ |
183 wc.lpfnWndProc = (WNDPROC) mswindows_wnd_proc; | |
184 wc.cbClsExtra = 0; | |
185 wc.cbWndExtra = MSWINDOWS_WINDOW_EXTRA_BYTES; | |
186 /* This must match whatever is passed to CreateWIndowEx, NULL is ok | |
187 for this. */ | |
771 | 188 wc.hInstance = NULL; |
189 wc.hIcon = qxeLoadIcon (qxeGetModuleHandle (NULL), XETEXT (XEMACS_CLASS)); | |
190 wc.hCursor = qxeLoadCursor (NULL, IDC_ARROW); | |
428 | 191 /* Background brush is only used during sizing, when XEmacs cannot |
192 take over */ | |
771 | 193 wc.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE + 1); |
428 | 194 wc.lpszMenuName = NULL; |
195 | |
771 | 196 wc.lpszClassName = (XELPTSTR) XETEXT (XEMACS_CLASS); |
197 wc.hIconSm = (HICON) qxeLoadImage (qxeGetModuleHandle (NULL), | |
198 XETEXT (XEMACS_CLASS), | |
199 IMAGE_ICON, 16, 16, 0); | |
200 qxeRegisterClassEx (&wc); | |
428 | 201 |
202 #ifdef HAVE_WIDGETS | |
203 xzero (wc); | |
204 /* Register the main window class */ | |
771 | 205 wc.cbSize = sizeof (wc); |
428 | 206 wc.lpfnWndProc = (WNDPROC) mswindows_control_wnd_proc; |
771 | 207 wc.lpszClassName = (XELPTSTR) XETEXT (XEMACS_CONTROL_CLASS); |
428 | 208 wc.hInstance = NULL; |
771 | 209 qxeRegisterClassEx (&wc); |
428 | 210 #endif |
211 | |
440 | 212 #if defined (HAVE_TOOLBARS) || defined (HAVE_WIDGETS) |
428 | 213 InitCommonControls (); |
214 #endif | |
215 } | |
216 | |
657 | 217 #ifdef HAVE_DRAGNDROP |
428 | 218 static void |
771 | 219 mswindows_init_dde (void) |
428 | 220 { |
221 /* Initialize DDE management library and our related globals. We execute a | |
771 | 222 * dde Open ("file") by simulating a drop, so this depends on dnd support. */ |
442 | 223 |
428 | 224 mswindows_dde_mlid = 0; |
659 | 225 mswindows_dde_enable = 0; |
771 | 226 qxeDdeInitialize (&mswindows_dde_mlid, (PFNCALLBACK)mswindows_dde_callback, |
903 | 227 APPCMD_FILTERINITS|CBF_FAIL_SELFCONNECTIONS| |
228 CBF_FAIL_POKES|CBF_SKIP_ALLNOTIFICATIONS, | |
771 | 229 0); |
230 | |
231 mswindows_dde_service = | |
232 qxeDdeCreateStringHandle (mswindows_dde_mlid, | |
233 XETEXT (XEMACS_CLASS), | |
234 XEUNICODE_P ? CP_WINUNICODE : CP_WINANSI); | |
235 /* The following strings we Unicode-ize ourselves: | |
236 -- SZDDESYS_TOPIC is system-provided | |
903 | 237 -- MSWINDOWS_DDE_TOPIC_EVAL is defined by us |
238 -- MSWINDOWS_DDE_ITEM_RESULT is defined by us | |
771 | 239 -- MSWINDOWS_DDE_ITEM_OPEN is used in internal-format comparisons |
240 */ | |
241 mswindows_dde_topic_system = | |
242 qxeDdeCreateStringHandle (mswindows_dde_mlid, | |
243 XETEXT (SZDDESYS_TOPIC), | |
244 XEUNICODE_P ? CP_WINUNICODE : CP_WINANSI); | |
903 | 245 mswindows_dde_topic_eval = |
246 qxeDdeCreateStringHandle (mswindows_dde_mlid, | |
247 XETEXT (MSWINDOWS_DDE_TOPIC_EVAL), | |
248 XEUNICODE_P ? CP_WINUNICODE : CP_WINANSI); | |
249 mswindows_dde_item_result = | |
250 qxeDdeCreateStringHandle (mswindows_dde_mlid, | |
251 XETEXT (MSWINDOWS_DDE_ITEM_RESULT), | |
252 XEUNICODE_P ? CP_WINUNICODE : CP_WINANSI); | |
771 | 253 mswindows_dde_item_open = |
254 qxeDdeCreateStringHandle (mswindows_dde_mlid, | |
255 XETEXT (MSWINDOWS_DDE_ITEM_OPEN), | |
256 XEUNICODE_P ? CP_WINUNICODE : CP_WINANSI); | |
428 | 257 DdeNameService (mswindows_dde_mlid, mswindows_dde_service, 0L, DNS_REGISTER); |
657 | 258 } |
771 | 259 #endif /* HAVE_DRAGNDROP */ |
657 | 260 |
261 void | |
771 | 262 init_mswindows_dde_very_early (void) |
657 | 263 { |
771 | 264 #if !defined (NO_CYGWIN_COM_SUPPORT) |
265 /* Needed by SHBrowseForFolder, so do it always */ | |
266 CoInitialize (NULL); | |
267 #endif | |
268 | |
657 | 269 #ifdef HAVE_DRAGNDROP |
270 /* Initializing dde when the device is created is too late - the | |
271 client will give up waiting. Instead we initialize here and tell | |
272 the client we're too busy until the rest of initialization has | |
273 happened. */ | |
771 | 274 mswindows_init_dde (); |
657 | 275 #endif |
276 } | |
277 | |
278 static void | |
4477
e34711681f30
Don't determine whether to call general device-type code at startup,
Aidan Kehoe <kehoea@parhasard.net>
parents:
4117
diff
changeset
|
279 mswindows_finish_init_device (struct device *d, |
2286 | 280 Lisp_Object UNUSED (props)) |
657 | 281 { |
282 #ifdef HAVE_DRAGNDROP | |
283 /* Tell pending clients we are ready. */ | |
284 mswindows_dde_enable = 1; | |
428 | 285 #endif |
4477
e34711681f30
Don't determine whether to call general device-type code at startup,
Aidan Kehoe <kehoea@parhasard.net>
parents:
4117
diff
changeset
|
286 call1 (Qmake_device_late_mswindows_entry_point, wrap_device(d)); |
428 | 287 } |
288 | |
289 static void | |
290 mswindows_delete_device (struct device *d) | |
291 { | |
292 #ifdef HAVE_DRAGNDROP | |
442 | 293 DdeNameService (mswindows_dde_mlid, 0L, 0L, DNS_UNREGISTER); |
903 | 294 DdeFreeStringHandle (mswindows_dde_mlid, mswindows_dde_item_result); |
442 | 295 DdeFreeStringHandle (mswindows_dde_mlid, mswindows_dde_item_open); |
296 DdeFreeStringHandle (mswindows_dde_mlid, mswindows_dde_topic_system); | |
903 | 297 DdeFreeStringHandle (mswindows_dde_mlid, mswindows_dde_topic_eval); |
442 | 298 DdeFreeStringHandle (mswindows_dde_mlid, mswindows_dde_service); |
428 | 299 DdeUninitialize (mswindows_dde_mlid); |
442 | 300 |
771 | 301 # if !defined (NO_CYGWIN_COM_SUPPORT) |
442 | 302 CoUninitialize (); |
303 # endif | |
428 | 304 #endif |
305 | |
771 | 306 DeleteDC (DEVICE_MSWINDOWS_HCDC (d)); |
4117 | 307 #ifndef NEW_GC |
1726 | 308 xfree (d->device_data, void *); |
3092 | 309 #endif /* not NEW_GC */ |
442 | 310 } |
311 | |
312 void | |
313 mswindows_get_workspace_coords (RECT *rc) | |
314 { | |
771 | 315 qxeSystemParametersInfo (SPI_GETWORKAREA, 0, rc, 0); |
428 | 316 } |
317 | |
440 | 318 static void |
319 mswindows_mark_device (struct device *d) | |
320 { | |
321 mark_object (DEVICE_MSWINDOWS_FONTLIST (d)); | |
322 } | |
323 | |
428 | 324 static Lisp_Object |
325 mswindows_device_system_metrics (struct device *d, | |
326 enum device_metrics m) | |
327 { | |
442 | 328 const HDC hdc = DEVICE_MSWINDOWS_HCDC(d); |
329 | |
428 | 330 switch (m) |
331 { | |
332 case DM_size_device: | |
442 | 333 return Fcons (make_int (GetDeviceCaps (hdc, HORZRES)), |
334 make_int (GetDeviceCaps (hdc, VERTRES))); | |
428 | 335 break; |
440 | 336 case DM_device_dpi: |
442 | 337 return Fcons (make_int (GetDeviceCaps (hdc, LOGPIXELSX)), |
338 make_int (GetDeviceCaps (hdc, LOGPIXELSY))); | |
440 | 339 break; |
428 | 340 case DM_size_device_mm: |
442 | 341 return Fcons (make_int (GetDeviceCaps (hdc, HORZSIZE)), |
342 make_int (GetDeviceCaps (hdc, VERTSIZE))); | |
428 | 343 break; |
344 case DM_num_bit_planes: | |
345 /* this is what X means by bitplanes therefore we ought to be | |
346 consistent. num planes is always 1 under mswindows and | |
347 therefore useless */ | |
442 | 348 return make_int (GetDeviceCaps (hdc, BITSPIXEL)); |
428 | 349 break; |
350 case DM_num_color_cells: | |
442 | 351 /* #### SIZEPALETTE only valid if RC_PALETTE bit set in RASTERCAPS, |
352 what should we return for a non-palette-based device? */ | |
353 return make_int (GetDeviceCaps (hdc, SIZEPALETTE)); | |
428 | 354 break; |
355 | |
356 /*** Colors ***/ | |
442 | 357 #define FROB(met, fore, back) \ |
428 | 358 case DM_##met: \ |
442 | 359 return build_syscolor_cons (fore, back); |
360 | |
361 FROB (color_default, COLOR_WINDOWTEXT, COLOR_WINDOW); | |
362 FROB (color_select, COLOR_HIGHLIGHTTEXT, COLOR_HIGHLIGHT); | |
363 FROB (color_balloon, COLOR_INFOTEXT, COLOR_INFOBK); | |
364 FROB (color_3d_face, COLOR_BTNTEXT, COLOR_BTNFACE); | |
365 FROB (color_3d_light, COLOR_3DHILIGHT, COLOR_3DLIGHT); | |
366 FROB (color_3d_dark, COLOR_3DDKSHADOW, COLOR_3DSHADOW); | |
367 FROB (color_menu, COLOR_MENUTEXT, COLOR_MENU); | |
368 FROB (color_menu_highlight, COLOR_HIGHLIGHTTEXT, COLOR_HIGHLIGHT); | |
369 FROB (color_menu_button, COLOR_MENUTEXT, COLOR_MENU); | |
370 FROB (color_menu_disabled, COLOR_GRAYTEXT, COLOR_MENU); | |
371 FROB (color_toolbar, COLOR_BTNTEXT, COLOR_BTNFACE); | |
372 FROB (color_scrollbar, COLOR_CAPTIONTEXT, COLOR_SCROLLBAR); | |
428 | 373 FROB (color_desktop, -1, COLOR_DESKTOP); |
374 FROB (color_workspace, -1, COLOR_APPWORKSPACE); | |
375 #undef FROB | |
376 | |
377 /*** Sizes ***/ | |
378 #define FROB(met, index1, index2) \ | |
379 case DM_##met: \ | |
380 return build_sysmetrics_cons (index1, index2); | |
381 | |
382 FROB (size_cursor, SM_CXCURSOR, SM_CYCURSOR); | |
383 FROB (size_scrollbar, SM_CXVSCROLL, SM_CYHSCROLL); | |
384 FROB (size_menu, -1, SM_CYMENU); | |
385 FROB (size_icon, SM_CXICON, SM_CYICON); | |
386 FROB (size_icon_small, SM_CXSMICON, SM_CYSMICON); | |
387 #undef FROB | |
388 | |
389 case DM_size_workspace: | |
390 { | |
391 RECT rc; | |
442 | 392 mswindows_get_workspace_coords (&rc); |
428 | 393 return Fcons (make_int (rc.right - rc.left), |
394 make_int (rc.bottom - rc.top)); | |
395 } | |
442 | 396 |
397 case DM_offset_workspace: | |
398 { | |
399 RECT rc; | |
400 mswindows_get_workspace_coords (&rc); | |
401 return Fcons (make_int (rc.left), make_int (rc.top)); | |
402 } | |
403 | |
428 | 404 /* |
405 case DM_size_toolbar: | |
406 case DM_size_toolbar_button: | |
407 case DM_size_toolbar_border: | |
408 */ | |
409 | |
410 /*** Features ***/ | |
411 #define FROB(met, index) \ | |
412 case DM_##met: \ | |
413 return make_int (GetSystemMetrics (index)); | |
414 | |
415 FROB (mouse_buttons, SM_CMOUSEBUTTONS); | |
416 FROB (swap_buttons, SM_SWAPBUTTON); | |
417 FROB (show_sounds, SM_SHOWSOUNDS); | |
418 FROB (slow_device, SM_SLOWMACHINE); | |
419 FROB (security, SM_SECURE); | |
420 #undef FROB | |
421 | |
422 } | |
423 | |
424 /* Do not know such property */ | |
425 return Qunbound; | |
426 } | |
427 | |
428 | |
429 /************************************************************************/ | |
442 | 430 /* printer helpers */ |
440 | 431 /************************************************************************/ |
432 | |
433 static void | |
434 signal_open_printer_error (struct device *d) | |
435 { | |
442 | 436 invalid_operation ("Failed to open printer", DEVICE_CONNECTION (d)); |
437 } | |
438 | |
439 | |
440 /* Helper function */ | |
441 static int | |
771 | 442 msprinter_init_device_internal (struct device *d, Lisp_Object printer_name) |
442 | 443 { |
771 | 444 Extbyte *printer_ext; |
445 HDC hdc; | |
442 | 446 |
771 | 447 DEVICE_MSPRINTER_NAME (d) = printer_name; |
448 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
449 printer_ext = LISP_STRING_TO_TSTR (printer_name); |
771 | 450 |
451 if (!qxeOpenPrinter (printer_ext, &DEVICE_MSPRINTER_HPRINTER (d), NULL)) | |
442 | 452 { |
453 DEVICE_MSPRINTER_HPRINTER (d) = NULL; | |
454 return 0; | |
455 } | |
456 | |
771 | 457 DEVICE_MSPRINTER_HDC (d) = qxeCreateDC (XETEXT ("WINSPOOL"), printer_ext, |
458 NULL, NULL); | |
442 | 459 if (DEVICE_MSPRINTER_HDC (d) == NULL) |
460 return 0; | |
461 | |
771 | 462 hdc = CreateCompatibleDC (DEVICE_MSPRINTER_HDC (d)); |
463 DEVICE_MSPRINTER_HCDC (d) = hdc; | |
464 DEVICE_MSPRINTER_FONTLIST (d) = mswindows_enumerate_fonts (hdc); | |
442 | 465 |
466 DEVICE_CLASS (d) = (GetDeviceCaps (DEVICE_MSPRINTER_HDC (d), BITSPIXEL) | |
467 * GetDeviceCaps (DEVICE_MSPRINTER_HDC (d), PLANES) | |
468 > 1) ? Qcolor : Qmono; | |
469 return 1; | |
440 | 470 } |
471 | |
472 static void | |
442 | 473 msprinter_delete_device_internal (struct device *d) |
474 { | |
475 if (DEVICE_MSPRINTER_HPRINTER (d)) | |
476 ClosePrinter (DEVICE_MSPRINTER_HPRINTER (d)); | |
477 if (DEVICE_MSPRINTER_HDC (d)) | |
478 DeleteDC (DEVICE_MSPRINTER_HDC (d)); | |
479 if (DEVICE_MSPRINTER_HCDC (d)) | |
480 DeleteDC (DEVICE_MSPRINTER_HCDC (d)); | |
481 | |
482 DEVICE_MSPRINTER_FONTLIST (d) = Qnil; | |
483 } | |
484 | |
485 static int | |
771 | 486 msprinter_reinit_device (struct device *d, Lisp_Object devname) |
442 | 487 { |
488 msprinter_delete_device_internal (d); | |
489 return msprinter_init_device_internal (d, devname); | |
490 } | |
491 | |
492 Lisp_Object | |
493 msprinter_default_printer (void) | |
494 { | |
495 Extbyte name[666]; | |
867 | 496 Ibyte *nameint; |
442 | 497 |
771 | 498 if (qxeGetProfileString (XETEXT ("windows"), XETEXT ("device"), NULL, name, |
499 sizeof (name) / XETCHAR_SIZE) <= 0) | |
442 | 500 return Qnil; |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
501 nameint = TSTR_TO_ITEXT (name); |
442 | 502 |
771 | 503 if (nameint[0] == '\0') |
442 | 504 return Qnil; |
505 | |
771 | 506 /* this is destructive, but that's ok because the string is either in |
851 | 507 name[] or ALLOCA ()ed */ |
771 | 508 qxestrtok (nameint, ","); |
509 | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
510 return build_istring (nameint); |
442 | 511 } |
512 | |
513 | |
514 /************************************************************************/ | |
515 /* printer methods */ | |
516 /************************************************************************/ | |
517 | |
518 static void | |
2286 | 519 msprinter_init_device (struct device *d, Lisp_Object UNUSED (props)) |
440 | 520 { |
771 | 521 DEVMODEW *pdm; |
647 | 522 LONG dm_size; |
771 | 523 Extbyte *printer_name; |
440 | 524 |
3092 | 525 #ifdef NEW_GC |
526 d->device_data = alloc_lrecord_type (struct msprinter_device, | |
527 &lrecord_msprinter_device); | |
528 #else /* not NEW_GC */ | |
440 | 529 d->device_data = xnew_and_zero (struct msprinter_device); |
3092 | 530 #endif /* not NEW_GC */ |
440 | 531 |
442 | 532 DEVICE_INFD (d) = DEVICE_OUTFD (d) = -1; |
771 | 533 DEVICE_MSPRINTER_DEVMODE (d) = Qnil; |
534 DEVICE_MSPRINTER_NAME (d) = Qnil; | |
440 | 535 |
2367 | 536 #if 0 /* #### deleted in new ikeyama ws */ |
771 | 537 /* We do not use printer font list as we do with the display |
538 device. Rather, we allow GDI to pick the closest match to the | |
440 | 539 display font. */ |
540 DEVICE_MSPRINTER_FONTLIST (d) = Qnil; | |
771 | 541 #endif /* 0 */ |
440 | 542 |
442 | 543 CHECK_STRING (DEVICE_CONNECTION (d)); |
544 | |
771 | 545 if (!msprinter_init_device_internal (d, DEVICE_CONNECTION (d))) |
442 | 546 signal_open_printer_error (d); |
547 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
548 printer_name = LISP_STRING_TO_TSTR (DEVICE_CONNECTION (d)); |
442 | 549 /* Determine DEVMODE size and store the default DEVMODE */ |
771 | 550 dm_size = qxeDocumentProperties (NULL, DEVICE_MSPRINTER_HPRINTER (d), |
551 printer_name, NULL, NULL, 0); | |
442 | 552 if (dm_size <= 0) |
553 signal_open_printer_error (d); | |
554 | |
771 | 555 pdm = (DEVMODEW *) xmalloc (dm_size); |
556 if (qxeDocumentProperties (NULL, DEVICE_MSPRINTER_HPRINTER(d), | |
557 printer_name, pdm, | |
558 NULL, DM_OUT_BUFFER) < 0) | |
552 | 559 signal_open_printer_error (d); |
442 | 560 |
561 assert (DEVMODE_SIZE (pdm) <= dm_size); | |
562 | |
771 | 563 DEVICE_MSPRINTER_DEVMODE (d) = |
564 allocate_devmode (pdm, 0, DEVICE_CONNECTION (d), d); | |
442 | 565 } |
566 | |
567 static void | |
568 msprinter_delete_device (struct device *d) | |
569 { | |
570 if (d->device_data) | |
571 { | |
572 msprinter_delete_device_internal (d); | |
573 | |
574 /* Disassociate the selected devmode with the device */ | |
575 if (!NILP (DEVICE_MSPRINTER_DEVMODE (d))) | |
576 { | |
577 XDEVMODE (DEVICE_MSPRINTER_DEVMODE (d))->device = Qnil; | |
578 DEVICE_MSPRINTER_DEVMODE (d) = Qnil; | |
579 } | |
580 | |
4117 | 581 #ifndef NEW_GC |
1726 | 582 xfree (d->device_data, void *); |
3092 | 583 #endif /* not NEW_GC */ |
442 | 584 } |
440 | 585 } |
586 | |
587 static Lisp_Object | |
588 msprinter_device_system_metrics (struct device *d, | |
589 enum device_metrics m) | |
590 { | |
591 switch (m) | |
592 { | |
593 /* Device sizes - pixel and mm */ | |
594 #define FROB(met, index1, index2) \ | |
595 case DM_##met: \ | |
596 return build_devicecaps_cons \ | |
771 | 597 (DEVICE_MSPRINTER_HDC (d), index1, index2); |
440 | 598 |
599 FROB (size_device, PHYSICALWIDTH, PHYSICALHEIGHT); | |
600 FROB (size_device_mm, HORZSIZE, VERTSIZE); | |
601 FROB (size_workspace, HORZRES, VERTRES); | |
602 FROB (offset_workspace, PHYSICALOFFSETX, PHYSICALOFFSETY); | |
603 FROB (device_dpi, LOGPIXELSX, LOGPIXELSY); | |
604 #undef FROB | |
605 | |
606 case DM_num_bit_planes: | |
607 /* this is what X means by bitplanes therefore we ought to be | |
608 consistent. num planes is always 1 under mswindows and | |
609 therefore useless */ | |
771 | 610 return make_int (GetDeviceCaps (DEVICE_MSPRINTER_HDC (d), BITSPIXEL)); |
440 | 611 |
442 | 612 case DM_num_color_cells: /* Printers are non-palette devices */ |
440 | 613 case DM_slow_device: /* Animation would be a really bad idea */ |
614 case DM_security: /* Not provided by windows */ | |
615 return Qzero; | |
616 } | |
617 | |
618 /* Do not know such property */ | |
619 return Qunbound; | |
620 } | |
621 | |
622 static void | |
623 msprinter_mark_device (struct device *d) | |
624 { | |
625 mark_object (DEVICE_MSPRINTER_FONTLIST (d)); | |
442 | 626 mark_object (DEVICE_MSPRINTER_DEVMODE (d)); |
771 | 627 mark_object (DEVICE_MSPRINTER_NAME (d)); |
440 | 628 } |
629 | |
630 | |
631 /************************************************************************/ | |
442 | 632 /* printer Lisp subroutines */ |
440 | 633 /************************************************************************/ |
634 | |
442 | 635 static void |
636 global_free_2_maybe (HGLOBAL hg1, HGLOBAL hg2) | |
637 { | |
638 if (hg1 != NULL) | |
639 GlobalFree (hg1); | |
640 if (hg2 != NULL) | |
641 GlobalFree (hg2); | |
642 } | |
643 | |
644 static HGLOBAL | |
645 devmode_to_hglobal (Lisp_Devmode *ldm) | |
646 { | |
647 HGLOBAL hg = GlobalAlloc (GHND, XDEVMODE_SIZE (ldm)); | |
648 memcpy (GlobalLock (hg), ldm->devmode, XDEVMODE_SIZE (ldm)); | |
649 GlobalUnlock (hg); | |
650 return hg; | |
651 } | |
652 | |
653 /* Returns 0 if the printer has been deleted due to a fatal I/O error, | |
654 1 otherwise. */ | |
655 static int | |
771 | 656 sync_printer_with_devmode (struct device* d, DEVMODEW* devmode_in, |
657 DEVMODEW* devmode_out, Lisp_Object devname) | |
440 | 658 { |
442 | 659 /* Change connection if the device changed */ |
771 | 660 if (!NILP (devname) |
4906
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
4846
diff
changeset
|
661 && lisp_strcasecmp_i18n (devname, DEVICE_MSPRINTER_NAME (d)) != 0) |
442 | 662 { |
771 | 663 Lisp_Object new_connection = devname; |
442 | 664 |
665 DEVICE_CONNECTION (d) = Qnil; | |
666 if (!NILP (Ffind_device (new_connection, Qmsprinter))) | |
667 { | |
668 /* We are in trouble - second msprinter for the same device. | |
669 Nothing wrong on the Windows side, just forge a unique | |
670 connection name. Use the memory address of d as a unique | |
671 suffix. */ | |
867 | 672 Ibyte new_connext[20]; |
771 | 673 |
674 qxesprintf (new_connext, ":%X", d->header.uid); | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
675 new_connection = concat2 (devname, build_istring (new_connext)); |
442 | 676 } |
677 DEVICE_CONNECTION (d) = new_connection; | |
678 | |
679 /* Reinitialize printer. The device can pop off in process */ | |
680 if (!msprinter_reinit_device (d, devname)) | |
681 { | |
682 /* Kaboom! */ | |
683 delete_device_internal (d, 1, 0, 1); | |
684 return 0; | |
685 } | |
686 } | |
771 | 687 { |
688 Extbyte *nameext; | |
442 | 689 |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
690 nameext = LISP_STRING_TO_TSTR (DEVICE_MSPRINTER_NAME (d)); |
771 | 691 |
692 /* Apply the new devmode to the printer */ | |
693 qxeDocumentProperties (NULL, DEVICE_MSPRINTER_HPRINTER (d), | |
694 nameext, devmode_out, devmode_in, | |
695 DM_IN_BUFFER | DM_OUT_BUFFER); | |
440 | 696 |
771 | 697 /* #### ResetDC fails sometimes, Bill only knows why. |
698 The solution below looks more like a workaround to me, | |
699 although it might be fine. --kkm */ | |
700 if (qxeResetDC (DEVICE_MSPRINTER_HDC (d), devmode_out) == NULL) | |
701 { | |
702 DeleteDC (DEVICE_MSPRINTER_HDC (d)); | |
703 DEVICE_MSPRINTER_HDC (d) = | |
704 qxeCreateDC (XETEXT ("WINSPOOL"), nameext, NULL, | |
705 devmode_out); | |
706 } | |
707 } | |
708 | |
442 | 709 return 1; |
710 } | |
711 | |
712 static void | |
713 handle_devmode_changes (Lisp_Devmode *ldm, HGLOBAL hDevNames, HGLOBAL hDevMode) | |
714 { | |
771 | 715 DEVNAMES *devnames = (DEVNAMES *) GlobalLock (hDevNames); |
716 Extbyte *new_name = | |
717 devnames ? | |
718 (Extbyte *) devnames + XETCHAR_SIZE * devnames->wDeviceOffset : NULL; | |
719 DEVMODEW *devmode = (DEVMODEW *) GlobalLock (hDevMode); | |
442 | 720 |
721 /* Size and name may have changed */ | |
771 | 722 ldm->devmode = (DEVMODEW *) xrealloc (ldm->devmode, DEVMODE_SIZE (devmode)); |
442 | 723 if (new_name) |
771 | 724 ldm->printer_name = build_tstr_string (new_name); |
440 | 725 |
442 | 726 if (!NILP (ldm->device)) |
727 { | |
728 /* Apply the new devmode to the printer and get a compete one back */ | |
729 struct device *d = XDEVICE (ldm->device); | |
771 | 730 if (!sync_printer_with_devmode (d, devmode, ldm->devmode, |
731 new_name ? ldm->printer_name : Qnil)) | |
442 | 732 { |
733 global_free_2_maybe (hDevNames, hDevMode); | |
771 | 734 signal_error |
735 (Qio_error, | |
736 "Printer device initialization I/O error, device deleted", | |
737 ldm->device); | |
442 | 738 } |
739 } | |
740 else | |
741 { | |
742 /* Just copy the devmode structure */ | |
743 memcpy (ldm->devmode, devmode, DEVMODE_SIZE (devmode)); | |
744 } | |
745 } | |
440 | 746 |
442 | 747 static void |
748 ensure_not_printing (struct device *d) | |
749 { | |
750 if (!NILP (DEVICE_FRAME_LIST (d))) | |
751 { | |
793 | 752 Lisp_Object device = wrap_device (d); |
753 | |
442 | 754 invalid_operation ("Cannot change settings while print job is active", |
755 device); | |
756 } | |
757 } | |
758 | |
759 static Lisp_Devmode * | |
760 decode_devmode (Lisp_Object dev) | |
761 { | |
762 if (DEVMODEP (dev)) | |
763 return XDEVMODE (dev); | |
764 else | |
765 { | |
766 ensure_not_printing (XDEVICE (dev)); | |
767 return XDEVMODE (DEVICE_MSPRINTER_DEVMODE (XDEVICE (dev))); | |
768 } | |
440 | 769 } |
770 | |
771 /* | |
442 | 772 * DEV can be either a printer or devmode |
440 | 773 */ |
442 | 774 static Lisp_Object |
510 | 775 print_dialog_worker (Lisp_Object dev, DWORD flags) |
442 | 776 { |
777 Lisp_Devmode *ldm = decode_devmode (dev); | |
771 | 778 PRINTDLGW pd; |
442 | 779 |
780 memset (&pd, 0, sizeof (pd)); | |
781 pd.lStructSize = sizeof (pd); | |
782 pd.hwndOwner = mswindows_get_selected_frame_hwnd (); | |
783 pd.hDevMode = devmode_to_hglobal (ldm); | |
510 | 784 pd.Flags = flags | PD_USEDEVMODECOPIESANDCOLLATE; |
442 | 785 pd.nMinPage = 0; |
786 pd.nMaxPage = 0xFFFF; | |
787 | |
771 | 788 if (!qxePrintDlg (&pd)) |
442 | 789 { |
790 global_free_2_maybe (pd.hDevNames, pd.hDevMode); | |
791 return Qnil; | |
792 } | |
793 | |
794 handle_devmode_changes (ldm, pd.hDevNames, pd.hDevMode); | |
795 | |
796 /* Finally, build the resulting plist */ | |
797 { | |
798 Lisp_Object result = Qnil; | |
799 struct gcpro gcpro1; | |
800 GCPRO1 (result); | |
801 | |
802 /* Do consing in reverse order. | |
803 Number of copies */ | |
510 | 804 result = Fcons (Qcopies, Fcons (make_int (pd.nCopies), result)); |
442 | 805 |
806 /* Page range */ | |
510 | 807 if (pd.Flags & PD_PAGENUMS) |
442 | 808 { |
809 result = Fcons (Qto_page, Fcons (make_int (pd.nToPage), result)); | |
810 result = Fcons (Qfrom_page, Fcons (make_int (pd.nFromPage), result)); | |
510 | 811 result = Fcons (Qselected_page_button, Fcons (Qpages, result)); |
442 | 812 } |
510 | 813 else if (pd.Flags & PD_SELECTION) |
814 result = Fcons (Qselected_page_button, Fcons (Qselection, result)); | |
815 else | |
816 result = Fcons (Qselected_page_button, Fcons (Qall, result)); | |
442 | 817 |
818 /* Device name */ | |
771 | 819 result = Fcons (Qname, Fcons (ldm->printer_name, result)); |
442 | 820 UNGCPRO; |
821 | |
822 global_free_2_maybe (pd.hDevNames, pd.hDevMode); | |
823 return result; | |
824 } | |
825 } | |
826 | |
827 Lisp_Object | |
2286 | 828 mswindows_handle_print_dialog_box (struct frame *UNUSED (f), Lisp_Object keys) |
442 | 829 { |
830 Lisp_Object device = Qunbound, settings = Qunbound; | |
510 | 831 DWORD flags = PD_NOSELECTION; |
442 | 832 |
833 { | |
834 EXTERNAL_PROPERTY_LIST_LOOP_3 (key, value, keys) | |
835 { | |
836 if (EQ (key, Q_device)) | |
837 { | |
838 device = wrap_device (decode_device (value)); | |
839 CHECK_MSPRINTER_DEVICE (device); | |
840 } | |
841 else if (EQ (key, Q_printer_settings)) | |
842 { | |
843 CHECK_DEVMODE (value); | |
844 settings = value; | |
845 } | |
510 | 846 else if (EQ (key, Q_allow_pages)) |
847 { | |
848 if (NILP (value)) | |
849 flags |= PD_NOPAGENUMS; | |
850 } | |
851 else if (EQ (key, Q_allow_selection)) | |
442 | 852 { |
510 | 853 if (!NILP (value)) |
854 flags &= ~PD_NOSELECTION; | |
442 | 855 } |
510 | 856 else if (EQ (key, Q_selected_page_button)) |
442 | 857 { |
510 | 858 if (EQ (value, Qselection)) |
859 flags |= PD_SELECTION; | |
860 else if (EQ (value, Qpages)) | |
861 flags |= PD_PAGENUMS; | |
862 else if (!EQ (value, Qall)) | |
563 | 863 invalid_constant ("for :selected-page-button", value); |
442 | 864 } |
865 else | |
563 | 866 invalid_constant ("Unrecognized print-dialog keyword", key); |
442 | 867 } |
868 } | |
869 | |
870 if ((UNBOUNDP (device) && UNBOUNDP (settings)) || | |
871 (!UNBOUNDP (device) && !UNBOUNDP (settings))) | |
563 | 872 sferror ("Exactly one of :device and :printer-settings must be given", |
442 | 873 keys); |
874 | |
510 | 875 return print_dialog_worker (!UNBOUNDP (device) ? device : settings, flags); |
442 | 876 } |
877 | |
506 | 878 int |
879 mswindows_get_default_margin (Lisp_Object prop) | |
880 { | |
881 if (EQ (prop, Qleft_margin)) return 1440; | |
882 if (EQ (prop, Qright_margin)) return 1440; | |
883 if (EQ (prop, Qtop_margin)) return 720; | |
884 if (EQ (prop, Qbottom_margin)) return 720; | |
2500 | 885 ABORT (); |
506 | 886 return 0; |
887 } | |
888 | |
442 | 889 static int |
798 | 890 plist_get_margin (Lisp_Object plist, Lisp_Object prop, int mm_p) |
442 | 891 { |
506 | 892 Lisp_Object val = |
893 Fplist_get (plist, prop, make_int (mswindows_get_default_margin (prop))); | |
442 | 894 if (!INTP (val)) |
895 invalid_argument ("Margin value must be an integer", val); | |
896 | |
798 | 897 return MulDiv (XINT (val), mm_p ? 254 : 100, 144); |
442 | 898 } |
899 | |
900 static Lisp_Object | |
901 plist_set_margin (Lisp_Object plist, Lisp_Object prop, int margin, int mm_p) | |
902 { | |
798 | 903 Lisp_Object val = make_int (MulDiv (margin, 144, mm_p ? 254 : 100)); |
442 | 904 return Fcons (prop, Fcons (val, plist)); |
905 } | |
906 | |
907 Lisp_Object | |
2286 | 908 mswindows_handle_page_setup_dialog_box (struct frame *UNUSED (f), |
909 Lisp_Object keys) | |
442 | 910 { |
911 Lisp_Object device = Qunbound, settings = Qunbound; | |
912 Lisp_Object plist = Qnil; | |
913 | |
914 { | |
915 EXTERNAL_PROPERTY_LIST_LOOP_3 (key, value, keys) | |
916 { | |
917 if (EQ (key, Q_device)) | |
918 { | |
919 device = wrap_device (decode_device (value)); | |
920 CHECK_MSPRINTER_DEVICE (device); | |
921 } | |
922 else if (EQ (key, Q_printer_settings)) | |
923 { | |
924 CHECK_DEVMODE (value); | |
925 settings = value; | |
926 } | |
927 else if (EQ (key, Q_properties)) | |
928 { | |
929 CHECK_LIST (value); | |
930 plist = value; | |
931 } | |
932 else | |
563 | 933 invalid_constant ("Unrecognized page-setup dialog keyword", key); |
442 | 934 } |
935 } | |
936 | |
937 if ((UNBOUNDP (device) && UNBOUNDP (settings)) || | |
938 (!UNBOUNDP (device) && !UNBOUNDP (settings))) | |
563 | 939 sferror ("Exactly one of :device and :printer-settings must be given", |
800 | 940 keys); |
442 | 941 |
942 if (UNBOUNDP (device)) | |
943 device = settings; | |
944 | |
945 { | |
946 Lisp_Devmode *ldm = decode_devmode (device); | |
771 | 947 PAGESETUPDLGW pd; |
853 | 948 Extbyte measure[2 * MAX_XETCHAR_SIZE]; |
850 | 949 int data; |
798 | 950 |
850 | 951 qxeGetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_IMEASURE, |
853 | 952 measure, sizeof (measure) / XETCHAR_SIZE); |
2421 | 953 data = qxetcscmp (measure, XETEXT ("0")); |
442 | 954 |
955 memset (&pd, 0, sizeof (pd)); | |
956 pd.lStructSize = sizeof (pd); | |
957 pd.hwndOwner = mswindows_get_selected_frame_hwnd (); | |
958 pd.Flags = PSD_MARGINS; | |
798 | 959 pd.rtMargin.left = plist_get_margin (plist, Qleft_margin, !data); |
960 pd.rtMargin.top = plist_get_margin (plist, Qtop_margin, !data); | |
961 pd.rtMargin.right = plist_get_margin (plist, Qright_margin, !data); | |
962 pd.rtMargin.bottom = plist_get_margin (plist, Qbottom_margin, !data); | |
442 | 963 pd.hDevMode = devmode_to_hglobal (ldm); |
964 | |
771 | 965 if (!qxePageSetupDlg (&pd)) |
442 | 966 { |
967 global_free_2_maybe (pd.hDevNames, pd.hDevMode); | |
968 return Qnil; | |
969 } | |
970 | |
971 if (pd.hDevMode) | |
972 handle_devmode_changes (ldm, pd.hDevNames, pd.hDevMode); | |
973 | |
974 /* Finally, build the resulting plist */ | |
975 { | |
976 Lisp_Object result = Qnil; | |
977 int mm_p = pd.Flags & PSD_INHUNDREDTHSOFMILLIMETERS; | |
978 result = plist_set_margin (result, Qbottom_margin, pd.rtMargin.bottom, | |
979 mm_p); | |
980 result = plist_set_margin (result, Qright_margin, pd.rtMargin.right, | |
981 mm_p); | |
982 result = plist_set_margin (result, Qtop_margin, pd.rtMargin.top, mm_p); | |
983 result = plist_set_margin (result, Qleft_margin, pd.rtMargin.left, mm_p); | |
984 return result; | |
985 } | |
986 } | |
987 } | |
988 | |
989 DEFUN ("msprinter-get-settings", Fmsprinter_get_settings, 1, 1, 0, /* | |
990 Return the settings object currently used by DEVICE. | |
991 The object returned is not a copy, but rather a pointer to the | |
992 original one. Use `msprinter-settings-copy' to create a copy of it. | |
993 */ | |
994 (device)) | |
995 { | |
996 struct device *d = decode_device (device); | |
793 | 997 device = wrap_device (d); |
442 | 998 CHECK_MSPRINTER_DEVICE (device); |
999 return DEVICE_MSPRINTER_DEVMODE (d); | |
1000 } | |
1001 | |
1002 DEFUN ("msprinter-select-settings", Fmsprinter_select_settings, 2, 2, 0, /* | |
1003 Select SETTINGS object into a DEVICE. | |
1004 The settings from the settings object are immediately applied to the | |
1005 printer, possibly changing even the target printer itself, and all | |
1006 future changes are applied synchronously to the printer device and the | |
1007 selected printer object, until a different settings object is selected | |
1008 into the same printer. | |
1009 | |
1010 A settings object can be selected to no more than one printer at a time. | |
1011 | |
1012 If the supplied settings object is not specialized, it is specialized | |
1013 for the printer immediately upon selection. The object can be | |
1014 despecialized after it is unselected by calling the function | |
1015 `msprinter-settings-despecialize'. | |
1016 | |
1017 Return value is the previously selected settings object. | |
1018 */ | |
1019 (device, settings)) | |
440 | 1020 { |
442 | 1021 Lisp_Devmode *ldm; |
1022 struct device *d = decode_device (device); | |
1023 | |
1024 struct gcpro gcpro1; | |
1025 GCPRO1 (settings); | |
1026 | |
793 | 1027 device = wrap_device (d); |
442 | 1028 CHECK_MSPRINTER_DEVICE (device); |
1029 CHECK_DEVMODE (settings); | |
1030 ldm = XDEVMODE (settings); | |
1031 | |
1032 if (!NILP (ldm->device)) | |
1033 invalid_operation ("The object is currently selected into a device", | |
1034 settings); | |
1035 | |
1036 /* If the object being selected is de-specialized, then its | |
1037 size is perhaps not enough to receive the new devmode. We can ask | |
1038 for printer's devmode size here, because despecialized settings | |
1039 cannot force switching to a different printer, as they supply no | |
1040 printer name at all. */ | |
771 | 1041 if (NILP (ldm->printer_name)) |
442 | 1042 { |
771 | 1043 Extbyte *nameext; |
1044 LONG dm_size; | |
1045 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
1046 nameext = LISP_STRING_TO_TSTR (DEVICE_MSPRINTER_NAME (d)); |
771 | 1047 dm_size = qxeDocumentProperties (NULL, DEVICE_MSPRINTER_HPRINTER (d), |
1048 nameext, NULL, NULL, 0); | |
442 | 1049 if (dm_size <= 0) |
563 | 1050 signal_error (Qio_error, |
1051 "Unable to specialize settings, printer error", | |
1052 device); | |
442 | 1053 |
1054 assert (XDEVMODE_SIZE (ldm) <= dm_size); | |
771 | 1055 ldm->devmode = (DEVMODEW *) xrealloc (ldm->devmode, dm_size); |
442 | 1056 } |
1057 | |
1058 /* If we bail out on signal here, no damage is done, except that | |
1059 the storage for the DEVMODE structure might be reallocated to | |
1060 hold a larger one - not a big deal */ | |
1061 if (!sync_printer_with_devmode (d, ldm->devmode, ldm->devmode, | |
1062 ldm->printer_name)) | |
563 | 1063 signal_error (Qio_error, |
1064 "Printer device initialization I/O error, device deleted", | |
771 | 1065 device); |
442 | 1066 |
771 | 1067 if (NILP (ldm->printer_name )) |
1068 ldm->printer_name = DEVICE_MSPRINTER_NAME (d); | |
442 | 1069 |
1070 { | |
1071 Lisp_Object old_mode = DEVICE_MSPRINTER_DEVMODE (d); | |
1072 ldm->device = device; | |
1073 XDEVMODE (old_mode)->device = Qnil; | |
1074 DEVICE_MSPRINTER_DEVMODE (d) = settings; | |
1075 UNGCPRO; | |
1076 return old_mode; | |
1077 } | |
1078 } | |
1079 | |
1080 DEFUN ("msprinter-apply-settings", Fmsprinter_apply_settings, 2, 2, 0, /* | |
3025 | 1081 Apply settings from a SETTINGS object to a `msprinter' DEVICE. |
442 | 1082 The settings from the settings object are immediately applied to the |
1083 printer, possibly changing even the target printer itself. The SETTING | |
1084 object is not modified, unlike `msprinter-select-settings', and the | |
1085 supplied object is not changed. The changes are immediately recorded | |
1086 into the settings object which is currently selected into the printer | |
1087 device. | |
1088 | |
1089 Return value is the currently selected settings object. | |
1090 */ | |
1091 (device, settings)) | |
1092 { | |
1093 Lisp_Devmode *ldm_current, *ldm_new; | |
1094 struct device *d = decode_device (device); | |
1095 | |
1096 struct gcpro gcpro1; | |
1097 GCPRO1 (settings); | |
1098 | |
793 | 1099 device = wrap_device (d); |
442 | 1100 CHECK_MSPRINTER_DEVICE (device); |
1101 CHECK_DEVMODE (settings); | |
1102 ldm_new = XDEVMODE (settings); | |
1103 ldm_current = XDEVMODE (DEVICE_MSPRINTER_DEVMODE (d)); | |
1104 | |
1105 /* If the supplied devmode is not specialized, then the current | |
1106 devmode size will always be sufficient, as the printer does | |
1107 not change. If it is specialized, we must reallocate the current | |
1108 devmode storage to match with the supplied one, as it has the right | |
1109 size for the new printer, if it is going to change. The correct | |
1110 way is to use the largest of the two though, to keep the old | |
1111 contents unchanged in case of preliminary exit. | |
1112 */ | |
771 | 1113 if (!NILP (ldm_new->printer_name)) |
442 | 1114 ldm_current->devmode = |
771 | 1115 (DEVMODEW*) xrealloc (ldm_current->devmode, |
442 | 1116 max (XDEVMODE_SIZE (ldm_new), |
1117 XDEVMODE_SIZE (ldm_current))); | |
1118 | |
1119 if (!sync_printer_with_devmode (d, ldm_new->devmode, | |
1120 ldm_current->devmode, | |
1121 ldm_new->printer_name)) | |
771 | 1122 signal_error |
1123 (Qio_error, | |
1124 "Printer device initialization I/O error, device deleted", device); | |
1125 | |
1126 if (!NILP (ldm_new->printer_name)) | |
1127 ldm_current->printer_name = ldm_new->printer_name; | |
442 | 1128 |
446 | 1129 UNGCPRO; |
442 | 1130 return DEVICE_MSPRINTER_DEVMODE (d); |
1131 } | |
1132 | |
1133 /************************************************************************/ | |
1134 /* devmode */ | |
1135 /************************************************************************/ | |
1136 | |
1204 | 1137 static const struct memory_description devmode_description[] = { |
934 | 1138 { XD_LISP_OBJECT, offsetof (struct Lisp_Devmode, printer_name) }, |
964 | 1139 { XD_LISP_OBJECT, offsetof (struct Lisp_Devmode, device) }, |
934 | 1140 { XD_END } |
1141 }; | |
1142 | |
771 | 1143 static Lisp_Object |
1144 mark_devmode (Lisp_Object obj) | |
1145 { | |
1146 Lisp_Devmode *data = XDEVMODE (obj); | |
1147 mark_object (data->printer_name); | |
1148 return data->device; | |
1149 } | |
1150 | |
442 | 1151 static void |
1152 print_devmode (Lisp_Object obj, Lisp_Object printcharfun, | |
2286 | 1153 int UNUSED (escapeflag)) |
442 | 1154 { |
1155 Lisp_Devmode *dm = XDEVMODE (obj); | |
1156 if (print_readably) | |
4846 | 1157 printing_unreadable_lcrecord (obj, 0); |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4846
diff
changeset
|
1158 write_ascstring (printcharfun, "#<msprinter-settings"); |
771 | 1159 if (!NILP (dm->printer_name)) |
800 | 1160 write_fmt_string_lisp (printcharfun, " for %S", 1, dm->printer_name); |
442 | 1161 if (!NILP (dm->device)) |
800 | 1162 write_fmt_string_lisp (printcharfun, " (currently on %s)", 1, dm->device); |
1163 write_fmt_string (printcharfun, " 0x%x>", dm->header.uid); | |
442 | 1164 } |
1165 | |
1166 static void | |
1167 finalize_devmode (void *header, int for_disksave) | |
1168 { | |
1169 Lisp_Devmode *dm = (Lisp_Devmode *) header; | |
1170 | |
1171 if (for_disksave) | |
1172 { | |
793 | 1173 Lisp_Object devmode = wrap_devmode (dm); |
1174 | |
442 | 1175 invalid_operation |
1176 ("Cannot dump XEmacs containing an msprinter-settings object", | |
1177 devmode); | |
1178 } | |
1179 | |
1180 assert (NILP (dm->device)); | |
1181 } | |
1182 | |
1183 static int | |
4906
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
4846
diff
changeset
|
1184 equal_devmode (Lisp_Object obj1, Lisp_Object obj2, int UNUSED (depth), |
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
4846
diff
changeset
|
1185 int UNUSED (foldcase)) |
442 | 1186 { |
1187 Lisp_Devmode *dm1 = XDEVMODE (obj1); | |
1188 Lisp_Devmode *dm2 = XDEVMODE (obj2); | |
440 | 1189 |
442 | 1190 if ((dm1->devmode != NULL) != (dm1->devmode != NULL)) |
1191 return 0; | |
1192 if (dm1->devmode == NULL) | |
1193 return 1; | |
1194 if (memcmp (dm1->devmode, dm2->devmode, XDEVMODE_SIZE (dm1)) != 0) | |
1195 return 0; | |
771 | 1196 if (NILP (dm1->printer_name) || NILP (dm2->printer_name)) |
442 | 1197 return 1; |
4906
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
4846
diff
changeset
|
1198 return lisp_strcasecmp_i18n (dm1->printer_name, dm2->printer_name) == 0; |
442 | 1199 } |
1200 | |
665 | 1201 static Hashcode |
442 | 1202 hash_devmode (Lisp_Object obj, int depth) |
1203 { | |
1204 Lisp_Devmode *dm = XDEVMODE (obj); | |
1205 | |
1206 return HASH3 (XDEVMODE_SIZE (dm), | |
1207 dm->devmode ? memory_hash (dm->devmode, XDEVMODE_SIZE (dm)) | |
1208 : 0, | |
771 | 1209 internal_hash (dm->printer_name, depth + 1)); |
442 | 1210 } |
1211 | |
934 | 1212 DEFINE_LRECORD_IMPLEMENTATION ("msprinter-settings", devmode, |
964 | 1213 0, /*dumpable-flag*/ |
934 | 1214 mark_devmode, print_devmode, finalize_devmode, |
1215 equal_devmode, hash_devmode, | |
1216 devmode_description, | |
1217 Lisp_Devmode); | |
1218 | |
442 | 1219 static Lisp_Object |
771 | 1220 allocate_devmode (DEVMODEW* src_devmode, int do_copy, |
1221 Lisp_Object src_name, struct device *d) | |
442 | 1222 { |
1223 Lisp_Devmode *dm; | |
1224 | |
3017 | 1225 dm = ALLOC_LCRECORD_TYPE (Lisp_Devmode, &lrecord_devmode); |
442 | 1226 |
1227 if (d) | |
793 | 1228 dm->device = wrap_device (d); |
442 | 1229 else |
1230 dm->device = Qnil; | |
1231 | |
771 | 1232 dm->printer_name = src_name; |
442 | 1233 |
1234 if (src_devmode != NULL && do_copy) | |
1235 { | |
771 | 1236 dm->devmode = (DEVMODEW*) xmalloc (DEVMODE_SIZE (src_devmode)); |
442 | 1237 memcpy (dm->devmode, src_devmode, DEVMODE_SIZE (src_devmode)); |
1238 } | |
1239 else | |
1240 { | |
1241 dm->devmode = src_devmode; | |
1242 } | |
1243 | |
793 | 1244 return wrap_devmode (dm); |
442 | 1245 } |
1246 | |
1247 DEFUN ("msprinter-settings-copy", Fmsprinter_settings_copy, 1, 1, 0, /* | |
1248 Create and returns an exact copy of a printer settings object. | |
1249 */ | |
1250 (settings)) | |
1251 { | |
1252 Lisp_Devmode *dm; | |
1253 | |
1254 CHECK_DEVMODE (settings); | |
1255 dm = XDEVMODE (settings); | |
1256 | |
1257 return allocate_devmode (dm->devmode, 1, dm->printer_name, NULL); | |
1258 } | |
1259 | |
1260 DEFUN ("msprinter-settings-despecialize", Fmsprinter_settings_despecialize, 1, 1, 0, /* | |
1261 Erase printer-specific settings from a printer settings object. | |
1262 */ | |
1263 (settings)) | |
1264 { | |
1265 Lisp_Devmode *ldm; | |
771 | 1266 DEVMODEW *dm; |
442 | 1267 |
1268 CHECK_DEVMODE (settings); | |
1269 ldm = XDEVMODE (settings); | |
1270 | |
1271 if (!NILP (ldm->device)) | |
1272 invalid_operation ("The object is currently selected into a device", | |
1273 settings); | |
1274 | |
1275 dm = ldm->devmode; | |
1276 | |
1277 /* #### TODO. Either remove references to device specific bins, | |
1278 paper sizes etc, or signal an error of they are present. */ | |
440 | 1279 |
442 | 1280 dm->dmDriverExtra = 0; |
1281 dm->dmDeviceName[0] = '\0'; | |
1282 | |
771 | 1283 ldm->printer_name = Qnil; |
442 | 1284 |
1285 return Qnil; | |
1286 } | |
1287 | |
1288 DEFUN ("mswindows-get-default-printer", Fmswindows_get_default_printer, 0, 0, 0, /* | |
1289 Return name of the default printer, as string, on nil if there is no default. | |
1290 */ | |
1291 ()) | |
1292 { | |
1293 return msprinter_default_printer (); | |
1294 } | |
1295 | |
1296 static void | |
1297 signal_enum_printer_error (void) | |
1298 { | |
1299 invalid_operation ("Error enumerating printers", make_int (GetLastError ())); | |
1300 } | |
1301 | |
1302 DEFUN ("mswindows-printer-list", Fmswindows_printer_list, 0, 0, 0, /* | |
1303 Return a list of string names of installed printers. | |
1304 If there is a default printer, it is returned as the first element of | |
1305 the list. If there is no default printer, the first element of the | |
1306 list will be nil. The rest of elements are guaranteed to have string | |
1307 values. Return value is nil if there are no printers installed. | |
1308 */ | |
1309 ()) | |
1310 { | |
1311 int have_nt, ok; | |
1312 BYTE *data_buf, dummy_byte; | |
665 | 1313 Bytecount enum_entry_size; |
442 | 1314 DWORD enum_flags, enum_level, bytes_needed, num_printers; |
1315 struct gcpro gcpro1, gcpro2; | |
1316 Lisp_Object result = Qnil, def_printer = Qnil; | |
1317 | |
1318 /* Determine OS flavor, to use the fastest enumeration method available */ | |
771 | 1319 have_nt = !mswindows_windows9x_p; |
442 | 1320 enum_flags = PRINTER_ENUM_LOCAL | (have_nt ? PRINTER_ENUM_CONNECTIONS : 0); |
1321 enum_level = have_nt ? 4 : 5; | |
771 | 1322 enum_entry_size = (have_nt ? sizeof (PRINTER_INFO_4) : |
1323 sizeof (PRINTER_INFO_5)); | |
442 | 1324 |
1325 /* Allocate memory for printer enum structure */ | |
771 | 1326 ok = qxeEnumPrinters (enum_flags, NULL, enum_level, &dummy_byte, 1, |
1327 &bytes_needed, &num_printers); | |
442 | 1328 if (ok) |
1329 /* No printers, if just 1 byte is enough */ | |
1330 return Qnil; | |
1331 | |
1332 if (GetLastError () != ERROR_INSUFFICIENT_BUFFER) | |
1333 signal_enum_printer_error (); | |
1334 | |
2367 | 1335 data_buf = alloca_array (BYTE, bytes_needed); |
771 | 1336 ok = qxeEnumPrinters (enum_flags, NULL, enum_level, data_buf, bytes_needed, |
1337 &bytes_needed, &num_printers); | |
442 | 1338 if (!ok) |
1339 signal_enum_printer_error (); | |
1340 | |
1341 if (num_printers == 0) | |
1342 /* Strange but... */ | |
1343 return Qnil; | |
1344 | |
1345 GCPRO2 (result, def_printer); | |
1346 | |
1347 while (num_printers--) | |
1348 { | |
771 | 1349 Extbyte *printer_name; |
442 | 1350 if (have_nt) |
1351 { | |
771 | 1352 PRINTER_INFO_4 *info = (PRINTER_INFO_4 *) data_buf; |
1353 printer_name = (Extbyte *) info->pPrinterName; | |
442 | 1354 } |
1355 else | |
1356 { | |
771 | 1357 PRINTER_INFO_5 *info = (PRINTER_INFO_5 *) data_buf; |
1358 printer_name = (Extbyte *) info->pPrinterName; | |
442 | 1359 } |
1360 data_buf += enum_entry_size; | |
1361 | |
771 | 1362 result = Fcons (build_tstr_string (printer_name), result); |
442 | 1363 } |
1364 | |
1365 def_printer = msprinter_default_printer (); | |
1366 result = Fdelete (def_printer, result); | |
1367 result = Fcons (def_printer, result); | |
1368 | |
1369 RETURN_UNGCPRO (result); | |
440 | 1370 } |
1371 | |
1372 | |
1373 /************************************************************************/ | |
428 | 1374 /* initialization */ |
1375 /************************************************************************/ | |
1376 | |
1377 void | |
1378 syms_of_device_mswindows (void) | |
1379 { | |
442 | 1380 INIT_LRECORD_IMPLEMENTATION (devmode); |
1381 | |
3092 | 1382 #ifdef NEW_GC |
1383 INIT_LRECORD_IMPLEMENTATION (mswindows_device); | |
1384 INIT_LRECORD_IMPLEMENTATION (msprinter_device); | |
1385 #endif /* NEW_GC */ | |
1386 | |
442 | 1387 DEFSUBR (Fmsprinter_get_settings); |
1388 DEFSUBR (Fmsprinter_select_settings); | |
1389 DEFSUBR (Fmsprinter_apply_settings); | |
1390 DEFSUBR (Fmsprinter_settings_copy); | |
1391 DEFSUBR (Fmsprinter_settings_despecialize); | |
1392 DEFSUBR (Fmswindows_get_default_printer); | |
1393 DEFSUBR (Fmswindows_printer_list); | |
1394 | |
510 | 1395 DEFKEYWORD (Q_allow_selection); |
1396 DEFKEYWORD (Q_allow_pages); | |
1397 DEFKEYWORD (Q_selected_page_button); | |
1398 DEFSYMBOL (Qselected_page_button); | |
1399 | |
4477
e34711681f30
Don't determine whether to call general device-type code at startup,
Aidan Kehoe <kehoea@parhasard.net>
parents:
4117
diff
changeset
|
1400 DEFSYMBOL (Qmake_device_early_mswindows_entry_point); |
e34711681f30
Don't determine whether to call general device-type code at startup,
Aidan Kehoe <kehoea@parhasard.net>
parents:
4117
diff
changeset
|
1401 DEFSYMBOL ( Qmake_device_late_mswindows_entry_point); |
428 | 1402 } |
1403 | |
1404 void | |
1405 console_type_create_device_mswindows (void) | |
1406 { | |
1407 CONSOLE_HAS_METHOD (mswindows, init_device); | |
1408 CONSOLE_HAS_METHOD (mswindows, finish_init_device); | |
440 | 1409 CONSOLE_HAS_METHOD (mswindows, mark_device); |
428 | 1410 CONSOLE_HAS_METHOD (mswindows, delete_device); |
1411 CONSOLE_HAS_METHOD (mswindows, device_system_metrics); | |
545 | 1412 CONSOLE_IMPLEMENTATION_FLAGS (mswindows, XDEVIMPF_PIXEL_GEOMETRY); |
440 | 1413 |
1414 CONSOLE_HAS_METHOD (msprinter, init_device); | |
1415 CONSOLE_HAS_METHOD (msprinter, mark_device); | |
1416 CONSOLE_HAS_METHOD (msprinter, delete_device); | |
1417 CONSOLE_HAS_METHOD (msprinter, device_system_metrics); | |
545 | 1418 CONSOLE_IMPLEMENTATION_FLAGS (msprinter, (XDEVIMPF_PIXEL_GEOMETRY |
1419 | XDEVIMPF_IS_A_PRINTER | |
1420 | XDEVIMPF_NO_AUTO_REDISPLAY | |
1421 | XDEVIMPF_DONT_PREEMPT_REDISPLAY | |
1422 | XDEVIMPF_FRAMELESS_OK)); | |
428 | 1423 } |
1424 | |
440 | 1425 |
428 | 1426 void |
1427 vars_of_device_mswindows (void) | |
1428 { | |
1429 } |