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