comparison src/device-msw.c @ 771:943eaba38521

[xemacs-hg @ 2002-03-13 08:51:24 by ben] The big ben-mule-21-5 check-in! Various files were added and deleted. See CHANGES-ben-mule. There are still some test suite failures. No crashes, though. Many of the failures have to do with problems in the test suite itself rather than in the actual code. I'll be addressing these in the next day or so -- none of the test suite failures are at all critical. Meanwhile I'll be trying to address the biggest issues -- i.e. build or run failures, which will almost certainly happen on various platforms. All comments should be sent to ben@xemacs.org -- use a Cc: if necessary when sending to mailing lists. There will be pre- and post- tags, something like pre-ben-mule-21-5-merge-in, and post-ben-mule-21-5-merge-in.
author ben
date Wed, 13 Mar 2002 08:54:06 +0000
parents fdefd0186b75
children e38acbeb1cae
comparison
equal deleted inserted replaced
770:336a418893b5 771:943eaba38521
1 /* device functions for mswindows. 1 /* device functions for mswindows.
2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. 2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
3 Copyright (C) 1994, 1995 Free Software Foundation, Inc. 3 Copyright (C) 1994, 1995 Free Software Foundation, Inc.
4 Copyright (C) 2000, 2001, 2002 Ben Wing.
4 5
5 This file is part of XEmacs. 6 This file is part of XEmacs.
6 7
7 XEmacs is free software; you can redistribute it and/or modify it 8 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the 9 under the terms of the GNU General Public License as published by the
18 along with XEmacs; see the file COPYING. If not, write to 19 along with XEmacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */ 21 Boston, MA 02111-1307, USA. */
21 22
22 /* Synched up with: Not in FSF. */ 23 /* Synched up with: Not in FSF. */
24
25 /* This file Mule-ized 8-11-2000. */
23 26
24 /* Authorship: 27 /* Authorship:
25 28
26 Original authors: Jamie Zawinski and the FSF 29 Original authors: Jamie Zawinski and the FSF
27 Rewritten by Ben Wing and Chuck Thompson. 30 Rewritten by Ben Wing and Chuck Thompson.
28 Rewritten for mswindows by Jonathan Harris, November 1997 for 21.0. 31 Rewritten for mswindows by Jonathan Harris, November 1997 for 21.0.
29 Print support added by Kirill Katsnelson, July 2000. 32 Print support added by Kirill Katsnelson, July 2000.
30 */ 33 */
31 34
35 #define NEED_MSWINDOWS_COMMCTRL
36 #define NEED_MSWINDOWS_OBJBASE /* for CoInitialize */
32 37
33 #include <config.h> 38 #include <config.h>
34 #include "lisp.h" 39 #include "lisp.h"
35 40
36 #include "console-msw.h" 41 #include "console-msw.h"
38 #include "objects-msw.h" 43 #include "objects-msw.h"
39 #include "events.h" 44 #include "events.h"
40 #include "faces.h" 45 #include "faces.h"
41 #include "frame.h" 46 #include "frame.h"
42 #include "sysdep.h" 47 #include "sysdep.h"
43
44 #include <commdlg.h>
45
46 #if !(defined (CYGWIN) || defined(MINGW))
47 #include <objbase.h> /* For CoInitialize */
48 #endif
49 48
50 /* win32 DDE management library globals */ 49 /* win32 DDE management library globals */
51 #ifdef HAVE_DRAGNDROP 50 #ifdef HAVE_DRAGNDROP
52 DWORD mswindows_dde_mlid; 51 DWORD mswindows_dde_mlid;
53 int mswindows_dde_enable; 52 int mswindows_dde_enable;
54 HSZ mswindows_dde_service; 53 HSZ mswindows_dde_service;
55 HSZ mswindows_dde_topic_system; 54 HSZ mswindows_dde_topic_system;
56 HSZ mswindows_dde_item_open; 55 HSZ mswindows_dde_item_open;
57 #endif 56 #endif
58 57
59 /* Control conversion of upper case file names to lower case.
60 nil means no, t means yes. */
61 Lisp_Object Vmswindows_downcase_file_names;
62
63 /* Control whether xemacs_stat() attempts to determine file type and link count
64 exactly, at the expense of slower operation. Since true hard links
65 are supported on NTFS volumes, this is only relevant on NT. */
66 Lisp_Object Vmswindows_get_true_file_attributes;
67
68 Lisp_Object Qinit_pre_mswindows_win, Qinit_post_mswindows_win; 58 Lisp_Object Qinit_pre_mswindows_win, Qinit_post_mswindows_win;
69 Lisp_Object Qdevmodep; 59 Lisp_Object Qdevmodep;
70 60
71 static Lisp_Object Q_allow_selection; 61 static Lisp_Object Q_allow_selection;
72 static Lisp_Object Q_allow_pages; 62 static Lisp_Object Q_allow_pages;
73 static Lisp_Object Q_selected_page_button; 63 static Lisp_Object Q_selected_page_button;
74 static Lisp_Object Qselected_page_button; 64 static Lisp_Object Qselected_page_button;
75 65
76 static Lisp_Object allocate_devmode (DEVMODE* src_devmode, int do_copy, 66 static Lisp_Object allocate_devmode (DEVMODEW *src_devmode, int do_copy,
77 char* src_name, struct device *d); 67 Lisp_Object src_name, struct device *d);
78 68
79 /************************************************************************/ 69 /************************************************************************/
80 /* helpers */ 70 /* helpers */
81 /************************************************************************/ 71 /************************************************************************/
82 72
117 /************************************************************************/ 107 /************************************************************************/
118 108
119 static void 109 static void
120 mswindows_init_device (struct device *d, Lisp_Object props) 110 mswindows_init_device (struct device *d, Lisp_Object props)
121 { 111 {
122 WNDCLASSEX wc;
123 HDC hdc; 112 HDC hdc;
113 WNDCLASSEXW wc;
124 114
125 DEVICE_CLASS (d) = Qcolor; 115 DEVICE_CLASS (d) = Qcolor;
126 DEVICE_INFD (d) = DEVICE_OUTFD (d) = -1; 116 DEVICE_INFD (d) = DEVICE_OUTFD (d) = -1;
127 init_baud_rate (d); 117 init_baud_rate (d);
128 init_one_device (d); 118 init_one_device (d);
129 119
130 d->device_data = xnew_and_zero (struct mswindows_device); 120 d->device_data = xnew_and_zero (struct mswindows_device);
131 hdc = CreateCompatibleDC (NULL); 121 hdc = CreateCompatibleDC (NULL);
132 assert (hdc!=NULL); 122 assert (hdc != NULL);
133 DEVICE_MSWINDOWS_HCDC(d) = hdc; 123 DEVICE_MSWINDOWS_HCDC (d) = hdc;
134 DEVICE_MSWINDOWS_FONTLIST (d) = mswindows_enumerate_fonts (hdc); 124 DEVICE_MSWINDOWS_FONTLIST (d) = mswindows_enumerate_fonts (hdc);
135 DEVICE_MSWINDOWS_UPDATE_TICK (d) = GetTickCount (); 125 DEVICE_MSWINDOWS_UPDATE_TICK (d) = GetTickCount ();
136 126
137 /* Register the main window class */ 127 /* Register the main window class */
138 wc.cbSize = sizeof (WNDCLASSEX); 128 wc.cbSize = sizeof (wc);
139 wc.style = CS_OWNDC; /* One DC per window */ 129 wc.style = CS_OWNDC; /* One DC per window */
140 wc.lpfnWndProc = (WNDPROC) mswindows_wnd_proc; 130 wc.lpfnWndProc = (WNDPROC) mswindows_wnd_proc;
141 wc.cbClsExtra = 0; 131 wc.cbClsExtra = 0;
142 wc.cbWndExtra = MSWINDOWS_WINDOW_EXTRA_BYTES; 132 wc.cbWndExtra = MSWINDOWS_WINDOW_EXTRA_BYTES;
143 /* This must match whatever is passed to CreateWIndowEx, NULL is ok 133 /* This must match whatever is passed to CreateWIndowEx, NULL is ok
144 for this. */ 134 for this. */
145 wc.hInstance = NULL; 135 wc.hInstance = NULL;
146 wc.hIcon = LoadIcon (GetModuleHandle(NULL), XEMACS_CLASS); 136 wc.hIcon = qxeLoadIcon (qxeGetModuleHandle (NULL), XETEXT (XEMACS_CLASS));
147 wc.hCursor = LoadCursor (NULL, IDC_ARROW); 137 wc.hCursor = qxeLoadCursor (NULL, IDC_ARROW);
148 /* Background brush is only used during sizing, when XEmacs cannot 138 /* Background brush is only used during sizing, when XEmacs cannot
149 take over */ 139 take over */
150 wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1); 140 wc.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE + 1);
151 wc.lpszMenuName = NULL; 141 wc.lpszMenuName = NULL;
152 142
153 wc.lpszClassName = XEMACS_CLASS; 143 wc.lpszClassName = (XELPTSTR) XETEXT (XEMACS_CLASS);
154 if (xLoadImageA) /* not in NT 3.5 */ 144 wc.hIconSm = (HICON) qxeLoadImage (qxeGetModuleHandle (NULL),
155 wc.hIconSm = (HICON) xLoadImageA (GetModuleHandle (NULL), XEMACS_CLASS, 145 XETEXT (XEMACS_CLASS),
156 IMAGE_ICON, 16, 16, 0); 146 IMAGE_ICON, 16, 16, 0);
157 else 147 qxeRegisterClassEx (&wc);
158 wc.hIconSm = 0;
159
160 if (xRegisterClassExA) /* not in NT 3.5 */
161 xRegisterClassExA (&wc);
162 else
163 RegisterClassA ((WNDCLASS *) &wc.style);
164 148
165 #ifdef HAVE_WIDGETS 149 #ifdef HAVE_WIDGETS
166 xzero (wc); 150 xzero (wc);
167 /* Register the main window class */ 151 /* Register the main window class */
168 wc.cbSize = sizeof (WNDCLASSEX); 152 wc.cbSize = sizeof (wc);
169 wc.lpfnWndProc = (WNDPROC) mswindows_control_wnd_proc; 153 wc.lpfnWndProc = (WNDPROC) mswindows_control_wnd_proc;
170 wc.lpszClassName = XEMACS_CONTROL_CLASS; 154 wc.lpszClassName = (XELPTSTR) XETEXT (XEMACS_CONTROL_CLASS);
171 wc.hInstance = NULL; 155 wc.hInstance = NULL;
172 if (xRegisterClassExA) /* not in NT 3.5 */ 156 qxeRegisterClassEx (&wc);
173 xRegisterClassExA (&wc);
174 else
175 RegisterClassA ((WNDCLASS *) &wc.style);
176 #endif 157 #endif
177 158
178 #if defined (HAVE_TOOLBARS) || defined (HAVE_WIDGETS) 159 #if defined (HAVE_TOOLBARS) || defined (HAVE_WIDGETS)
179 InitCommonControls (); 160 InitCommonControls ();
180 #endif 161 #endif
181 } 162 }
182 163
183 #ifdef HAVE_DRAGNDROP 164 #ifdef HAVE_DRAGNDROP
184 static void 165 static void
185 mswindows_init_dde () 166 mswindows_init_dde (void)
186 { 167 {
187 /* Initialize DDE management library and our related globals. We execute a 168 /* Initialize DDE management library and our related globals. We execute a
188 * dde Open("file") by simulating a drop, so this depends on dnd support. */ 169 * dde Open ("file") by simulating a drop, so this depends on dnd support. */
189 # if !(defined(CYGWIN) || defined(MINGW))
190 CoInitialize (NULL);
191 # endif
192 170
193 mswindows_dde_mlid = 0; 171 mswindows_dde_mlid = 0;
194 mswindows_dde_enable = 0; 172 mswindows_dde_enable = 0;
195 DdeInitialize (&mswindows_dde_mlid, (PFNCALLBACK)mswindows_dde_callback, 173 qxeDdeInitialize (&mswindows_dde_mlid, (PFNCALLBACK)mswindows_dde_callback,
196 APPCMD_FILTERINITS|CBF_FAIL_SELFCONNECTIONS|CBF_FAIL_ADVISES| 174 APPCMD_FILTERINITS|CBF_FAIL_SELFCONNECTIONS|CBF_FAIL_ADVISES|
197 CBF_FAIL_POKES|CBF_FAIL_REQUESTS|CBF_SKIP_ALLNOTIFICATIONS, 175 CBF_FAIL_POKES|CBF_FAIL_REQUESTS|CBF_SKIP_ALLNOTIFICATIONS,
198 0); 176 0);
199 177
200 mswindows_dde_service = DdeCreateStringHandle (mswindows_dde_mlid, 178 mswindows_dde_service =
201 XEMACS_CLASS, 0); 179 qxeDdeCreateStringHandle (mswindows_dde_mlid,
202 mswindows_dde_topic_system = DdeCreateStringHandle (mswindows_dde_mlid, 180 XETEXT (XEMACS_CLASS),
203 SZDDESYS_TOPIC, 0); 181 XEUNICODE_P ? CP_WINUNICODE : CP_WINANSI);
204 mswindows_dde_item_open = DdeCreateStringHandle (mswindows_dde_mlid, 182 /* The following strings we Unicode-ize ourselves:
205 TEXT(MSWINDOWS_DDE_ITEM_OPEN), 0); 183 -- SZDDESYS_TOPIC is system-provided
184 -- MSWINDOWS_DDE_ITEM_OPEN is used in internal-format comparisons
185 */
186 mswindows_dde_topic_system =
187 qxeDdeCreateStringHandle (mswindows_dde_mlid,
188 XETEXT (SZDDESYS_TOPIC),
189 XEUNICODE_P ? CP_WINUNICODE : CP_WINANSI);
190 mswindows_dde_item_open =
191 qxeDdeCreateStringHandle (mswindows_dde_mlid,
192 XETEXT (MSWINDOWS_DDE_ITEM_OPEN),
193 XEUNICODE_P ? CP_WINUNICODE : CP_WINANSI);
206 DdeNameService (mswindows_dde_mlid, mswindows_dde_service, 0L, DNS_REGISTER); 194 DdeNameService (mswindows_dde_mlid, mswindows_dde_service, 0L, DNS_REGISTER);
207 } 195 }
196 #endif /* HAVE_DRAGNDROP */
197
198 void
199 init_mswindows_dde_very_early (void)
200 {
201 #if !defined (NO_CYGWIN_COM_SUPPORT)
202 /* Needed by SHBrowseForFolder, so do it always */
203 CoInitialize (NULL);
208 #endif 204 #endif
209 205
210 void
211 init_mswindows_very_early()
212 {
213 #ifdef HAVE_DRAGNDROP 206 #ifdef HAVE_DRAGNDROP
214 /* Initializing dde when the device is created is too late - the 207 /* Initializing dde when the device is created is too late - the
215 client will give up waiting. Instead we initialize here and tell 208 client will give up waiting. Instead we initialize here and tell
216 the client we're too busy until the rest of initialization has 209 the client we're too busy until the rest of initialization has
217 happened. */ 210 happened. */
218 mswindows_init_dde(); 211 mswindows_init_dde ();
219 #endif 212 #endif
220 } 213 }
221 214
222 static void 215 static void
223 mswindows_finish_init_device (struct device *d, Lisp_Object props) 216 mswindows_finish_init_device (struct device *d, Lisp_Object props)
236 DdeFreeStringHandle (mswindows_dde_mlid, mswindows_dde_item_open); 229 DdeFreeStringHandle (mswindows_dde_mlid, mswindows_dde_item_open);
237 DdeFreeStringHandle (mswindows_dde_mlid, mswindows_dde_topic_system); 230 DdeFreeStringHandle (mswindows_dde_mlid, mswindows_dde_topic_system);
238 DdeFreeStringHandle (mswindows_dde_mlid, mswindows_dde_service); 231 DdeFreeStringHandle (mswindows_dde_mlid, mswindows_dde_service);
239 DdeUninitialize (mswindows_dde_mlid); 232 DdeUninitialize (mswindows_dde_mlid);
240 233
241 # if !(defined(CYGWIN) || defined(MINGW)) 234 # if !defined (NO_CYGWIN_COM_SUPPORT)
242 CoUninitialize (); 235 CoUninitialize ();
243 # endif 236 # endif
244 #endif 237 #endif
245 238
246 DeleteDC (DEVICE_MSWINDOWS_HCDC(d)); 239 DeleteDC (DEVICE_MSWINDOWS_HCDC (d));
247 xfree (d->device_data); 240 xfree (d->device_data);
248 } 241 }
249 242
250 void 243 void
251 mswindows_get_workspace_coords (RECT *rc) 244 mswindows_get_workspace_coords (RECT *rc)
252 { 245 {
253 SystemParametersInfo (SPI_GETWORKAREA, 0, rc, 0); 246 qxeSystemParametersInfo (SPI_GETWORKAREA, 0, rc, 0);
254 } 247 }
255 248
256 static void 249 static void
257 mswindows_mark_device (struct device *d) 250 mswindows_mark_device (struct device *d)
258 { 251 {
375 } 368 }
376 369
377 370
378 /* Helper function */ 371 /* Helper function */
379 static int 372 static int
380 msprinter_init_device_internal (struct device *d, char* printer_name) 373 msprinter_init_device_internal (struct device *d, Lisp_Object printer_name)
381 { 374 {
382 DEVICE_MSPRINTER_NAME(d) = xstrdup (printer_name); 375 Extbyte *printer_ext;
383 376 HDC hdc;
384 if (!OpenPrinter (printer_name, &DEVICE_MSPRINTER_HPRINTER (d), NULL)) 377
378 DEVICE_MSPRINTER_NAME (d) = printer_name;
379
380 LISP_STRING_TO_TSTR (printer_name, printer_ext);
381
382 if (!qxeOpenPrinter (printer_ext, &DEVICE_MSPRINTER_HPRINTER (d), NULL))
385 { 383 {
386 DEVICE_MSPRINTER_HPRINTER (d) = NULL; 384 DEVICE_MSPRINTER_HPRINTER (d) = NULL;
387 return 0; 385 return 0;
388 } 386 }
389 387
390 DEVICE_MSPRINTER_HDC (d) = CreateDC ("WINSPOOL", printer_name, 388 DEVICE_MSPRINTER_HDC (d) = qxeCreateDC (XETEXT ("WINSPOOL"), printer_ext,
391 NULL, NULL); 389 NULL, NULL);
392 if (DEVICE_MSPRINTER_HDC (d) == NULL) 390 if (DEVICE_MSPRINTER_HDC (d) == NULL)
393 return 0; 391 return 0;
394 392
395 DEVICE_MSPRINTER_HCDC(d) = 393 hdc = CreateCompatibleDC (DEVICE_MSPRINTER_HDC (d));
396 CreateCompatibleDC (DEVICE_MSPRINTER_HDC (d)); 394 DEVICE_MSPRINTER_HCDC (d) = hdc;
395 DEVICE_MSPRINTER_FONTLIST (d) = mswindows_enumerate_fonts (hdc);
397 396
398 DEVICE_CLASS (d) = (GetDeviceCaps (DEVICE_MSPRINTER_HDC (d), BITSPIXEL) 397 DEVICE_CLASS (d) = (GetDeviceCaps (DEVICE_MSPRINTER_HDC (d), BITSPIXEL)
399 * GetDeviceCaps (DEVICE_MSPRINTER_HDC (d), PLANES) 398 * GetDeviceCaps (DEVICE_MSPRINTER_HDC (d), PLANES)
400 > 1) ? Qcolor : Qmono; 399 > 1) ? Qcolor : Qmono;
401 return 1; 400 return 1;
408 ClosePrinter (DEVICE_MSPRINTER_HPRINTER (d)); 407 ClosePrinter (DEVICE_MSPRINTER_HPRINTER (d));
409 if (DEVICE_MSPRINTER_HDC (d)) 408 if (DEVICE_MSPRINTER_HDC (d))
410 DeleteDC (DEVICE_MSPRINTER_HDC (d)); 409 DeleteDC (DEVICE_MSPRINTER_HDC (d));
411 if (DEVICE_MSPRINTER_HCDC (d)) 410 if (DEVICE_MSPRINTER_HCDC (d))
412 DeleteDC (DEVICE_MSPRINTER_HCDC (d)); 411 DeleteDC (DEVICE_MSPRINTER_HCDC (d));
413 if (DEVICE_MSPRINTER_NAME (d))
414 xfree (DEVICE_MSPRINTER_NAME (d));
415 412
416 DEVICE_MSPRINTER_FONTLIST (d) = Qnil; 413 DEVICE_MSPRINTER_FONTLIST (d) = Qnil;
417 } 414 }
418 415
419 static int 416 static int
420 msprinter_reinit_device (struct device *d, char* devname) 417 msprinter_reinit_device (struct device *d, Lisp_Object devname)
421 { 418 {
422 msprinter_delete_device_internal (d); 419 msprinter_delete_device_internal (d);
423 return msprinter_init_device_internal (d, devname); 420 return msprinter_init_device_internal (d, devname);
424 } 421 }
425 422
427 msprinter_default_printer (void) 424 msprinter_default_printer (void)
428 { 425 {
429 Extbyte name[666]; 426 Extbyte name[666];
430 Intbyte *nameint; 427 Intbyte *nameint;
431 428
432 if (GetProfileString (XETEXT ("windows"), XETEXT ("device"), NULL, name, 429 if (qxeGetProfileString (XETEXT ("windows"), XETEXT ("device"), NULL, name,
433 sizeof (name) / XETCHAR_SIZE) <= 0) 430 sizeof (name) / XETCHAR_SIZE) <= 0)
434 return Qnil; 431 return Qnil;
435 EXTERNAL_TO_C_STRING (name, nameint, Qmswindows_tstr); 432 TSTR_TO_C_STRING (name, nameint);
436 433
437 if (name[0] == '\0') 434 if (nameint[0] == '\0')
438 return Qnil; 435 return Qnil;
439 strtok (name, ","); 436
440 437 /* this is destructive, but that's ok because the string is either in
441 return build_string (name); 438 name[] or alloca()ed */
439 qxestrtok (nameint, ",");
440
441 return build_intstring (nameint);
442 } 442 }
443 443
444 444
445 /************************************************************************/ 445 /************************************************************************/
446 /* printer methods */ 446 /* printer methods */
447 /************************************************************************/ 447 /************************************************************************/
448 448
449 static void 449 static void
450 msprinter_init_device (struct device *d, Lisp_Object props) 450 msprinter_init_device (struct device *d, Lisp_Object props)
451 { 451 {
452 char* printer_name; 452 DEVMODEW *pdm;
453 DEVMODE *pdm;
454 LONG dm_size; 453 LONG dm_size;
454 Extbyte *printer_name;
455 455
456 d->device_data = xnew_and_zero (struct msprinter_device); 456 d->device_data = xnew_and_zero (struct msprinter_device);
457 457
458 DEVICE_INFD (d) = DEVICE_OUTFD (d) = -1; 458 DEVICE_INFD (d) = DEVICE_OUTFD (d) = -1;
459 DEVICE_MSPRINTER_DEVMODE(d) = Qnil; 459 DEVICE_MSPRINTER_DEVMODE (d) = Qnil;
460 460 DEVICE_MSPRINTER_NAME (d) = Qnil;
461 /* We do not use printer fon list as we do with the display 461
462 device. Rather, we allow GDI to pick the closest match to the 462 #if 0 /* @@#### deleted in new ikeyama ws */
463 /* We do not use printer font list as we do with the display
464 device. Rather, we allow GDI to pick the closest match to the
463 display font. */ 465 display font. */
464 DEVICE_MSPRINTER_FONTLIST (d) = Qnil; 466 DEVICE_MSPRINTER_FONTLIST (d) = Qnil;
467 #endif /* 0 */
465 468
466 CHECK_STRING (DEVICE_CONNECTION (d)); 469 CHECK_STRING (DEVICE_CONNECTION (d));
467 470
468 TO_EXTERNAL_FORMAT (LISP_STRING, DEVICE_CONNECTION (d), 471 if (!msprinter_init_device_internal (d, DEVICE_CONNECTION (d)))
469 C_STRING_ALLOCA, printer_name,
470 Qmswindows_tstr);
471
472 if (!msprinter_init_device_internal (d, printer_name))
473 signal_open_printer_error (d); 472 signal_open_printer_error (d);
474 473
474 LISP_STRING_TO_TSTR (DEVICE_CONNECTION (d), printer_name);
475 /* Determine DEVMODE size and store the default DEVMODE */ 475 /* Determine DEVMODE size and store the default DEVMODE */
476 dm_size = DocumentProperties (NULL, DEVICE_MSPRINTER_HPRINTER (d), 476 dm_size = qxeDocumentProperties (NULL, DEVICE_MSPRINTER_HPRINTER (d),
477 printer_name, NULL, NULL, 0); 477 printer_name, NULL, NULL, 0);
478 if (dm_size <= 0) 478 if (dm_size <= 0)
479 signal_open_printer_error (d); 479 signal_open_printer_error (d);
480 480
481 pdm = (DEVMODE*) xmalloc (dm_size); 481 pdm = (DEVMODEW *) xmalloc (dm_size);
482 if (DocumentProperties (NULL, DEVICE_MSPRINTER_HPRINTER(d), 482 if (qxeDocumentProperties (NULL, DEVICE_MSPRINTER_HPRINTER(d),
483 printer_name, pdm, 483 printer_name, pdm,
484 NULL, DM_OUT_BUFFER) < 0) 484 NULL, DM_OUT_BUFFER) < 0)
485 signal_open_printer_error (d); 485 signal_open_printer_error (d);
486 486
487 assert (DEVMODE_SIZE (pdm) <= dm_size); 487 assert (DEVMODE_SIZE (pdm) <= dm_size);
488 488
489 DEVICE_MSPRINTER_DEVMODE(d) = 489 DEVICE_MSPRINTER_DEVMODE (d) =
490 allocate_devmode (pdm, 0, printer_name, d); 490 allocate_devmode (pdm, 0, DEVICE_CONNECTION (d), d);
491
492 } 491 }
493 492
494 static void 493 static void
495 msprinter_delete_device (struct device *d) 494 msprinter_delete_device (struct device *d)
496 { 495 {
517 { 516 {
518 /* Device sizes - pixel and mm */ 517 /* Device sizes - pixel and mm */
519 #define FROB(met, index1, index2) \ 518 #define FROB(met, index1, index2) \
520 case DM_##met: \ 519 case DM_##met: \
521 return build_devicecaps_cons \ 520 return build_devicecaps_cons \
522 (DEVICE_MSPRINTER_HDC(d), index1, index2); 521 (DEVICE_MSPRINTER_HDC (d), index1, index2);
523 522
524 FROB (size_device, PHYSICALWIDTH, PHYSICALHEIGHT); 523 FROB (size_device, PHYSICALWIDTH, PHYSICALHEIGHT);
525 FROB (size_device_mm, HORZSIZE, VERTSIZE); 524 FROB (size_device_mm, HORZSIZE, VERTSIZE);
526 FROB (size_workspace, HORZRES, VERTRES); 525 FROB (size_workspace, HORZRES, VERTRES);
527 FROB (offset_workspace, PHYSICALOFFSETX, PHYSICALOFFSETY); 526 FROB (offset_workspace, PHYSICALOFFSETX, PHYSICALOFFSETY);
530 529
531 case DM_num_bit_planes: 530 case DM_num_bit_planes:
532 /* this is what X means by bitplanes therefore we ought to be 531 /* this is what X means by bitplanes therefore we ought to be
533 consistent. num planes is always 1 under mswindows and 532 consistent. num planes is always 1 under mswindows and
534 therefore useless */ 533 therefore useless */
535 return make_int (GetDeviceCaps (DEVICE_MSPRINTER_HDC(d), BITSPIXEL)); 534 return make_int (GetDeviceCaps (DEVICE_MSPRINTER_HDC (d), BITSPIXEL));
536 535
537 case DM_num_color_cells: /* Printers are non-palette devices */ 536 case DM_num_color_cells: /* Printers are non-palette devices */
538 case DM_slow_device: /* Animation would be a really bad idea */ 537 case DM_slow_device: /* Animation would be a really bad idea */
539 case DM_security: /* Not provided by windows */ 538 case DM_security: /* Not provided by windows */
540 return Qzero; 539 return Qzero;
547 static void 546 static void
548 msprinter_mark_device (struct device *d) 547 msprinter_mark_device (struct device *d)
549 { 548 {
550 mark_object (DEVICE_MSPRINTER_FONTLIST (d)); 549 mark_object (DEVICE_MSPRINTER_FONTLIST (d));
551 mark_object (DEVICE_MSPRINTER_DEVMODE (d)); 550 mark_object (DEVICE_MSPRINTER_DEVMODE (d));
551 mark_object (DEVICE_MSPRINTER_NAME (d));
552 } 552 }
553 553
554 554
555 /************************************************************************/ 555 /************************************************************************/
556 /* printer Lisp subroutines */ 556 /* printer Lisp subroutines */
575 } 575 }
576 576
577 /* Returns 0 if the printer has been deleted due to a fatal I/O error, 577 /* Returns 0 if the printer has been deleted due to a fatal I/O error,
578 1 otherwise. */ 578 1 otherwise. */
579 static int 579 static int
580 sync_printer_with_devmode (struct device* d, DEVMODE* devmode_in, 580 sync_printer_with_devmode (struct device* d, DEVMODEW* devmode_in,
581 DEVMODE* devmode_out, char* devname) 581 DEVMODEW* devmode_out, Lisp_Object devname)
582 { 582 {
583 /* Change connection if the device changed */ 583 /* Change connection if the device changed */
584 if (devname != NULL 584 if (!NILP (devname)
585 && stricmp (devname, DEVICE_MSPRINTER_NAME(d)) != 0) 585 && lisp_strcasecmp (devname, DEVICE_MSPRINTER_NAME (d)) != 0)
586 { 586 {
587 Lisp_Object new_connection = build_ext_string (devname, Qmswindows_tstr); 587 Lisp_Object new_connection = devname;
588 struct gcpro gcpro1; 588
589
590 GCPRO1 (new_connection);
591 DEVICE_CONNECTION (d) = Qnil; 589 DEVICE_CONNECTION (d) = Qnil;
592 if (!NILP (Ffind_device (new_connection, Qmsprinter))) 590 if (!NILP (Ffind_device (new_connection, Qmsprinter)))
593 { 591 {
594 /* We are in trouble - second msprinter for the same device. 592 /* We are in trouble - second msprinter for the same device.
595 Nothing wrong on the Windows side, just forge a unique 593 Nothing wrong on the Windows side, just forge a unique
596 connection name. Use the memory address of d as a unique 594 connection name. Use the memory address of d as a unique
597 suffix. */ 595 suffix. */
598 Extbyte *new_connext = (Extbyte *) alloca (strlen (devname + 11)); 596 Intbyte new_connext[20];
599 sprintf (new_connext, "%s:%X", devname, d->header.uid); 597
600 new_connection = build_ext_string (devname, Qmswindows_tstr); 598 qxesprintf (new_connext, ":%X", d->header.uid);
599 new_connection = concat2 (devname, build_intstring (new_connext));
601 } 600 }
602 DEVICE_CONNECTION (d) = new_connection; 601 DEVICE_CONNECTION (d) = new_connection;
603 UNGCPRO;
604 602
605 /* Reinitialize printer. The device can pop off in process */ 603 /* Reinitialize printer. The device can pop off in process */
606 if (!msprinter_reinit_device (d, devname)) 604 if (!msprinter_reinit_device (d, devname))
607 { 605 {
608 /* Kaboom! */ 606 /* Kaboom! */
609 delete_device_internal (d, 1, 0, 1); 607 delete_device_internal (d, 1, 0, 1);
610 return 0; 608 return 0;
611 } 609 }
612 } 610 }
613 611 {
614 /* Apply the new devmode to the printer */ 612 Extbyte *nameext;
615 DocumentProperties (NULL, 613
616 DEVICE_MSPRINTER_HPRINTER(d), 614 LISP_STRING_TO_TSTR (DEVICE_MSPRINTER_NAME (d), nameext);
617 DEVICE_MSPRINTER_NAME(d), 615
618 devmode_out, devmode_in, 616 /* Apply the new devmode to the printer */
619 DM_IN_BUFFER | DM_OUT_BUFFER); 617 qxeDocumentProperties (NULL, DEVICE_MSPRINTER_HPRINTER (d),
620 618 nameext, devmode_out, devmode_in,
621 /* #### ResetDC fails sometimes, Bill only knows why. 619 DM_IN_BUFFER | DM_OUT_BUFFER);
622 The solution below looks more like a workaround to me, 620
623 although it might be fine. --kkm */ 621 /* #### ResetDC fails sometimes, Bill only knows why.
624 if (ResetDC (DEVICE_MSPRINTER_HDC (d), devmode_out) == NULL) 622 The solution below looks more like a workaround to me,
625 { 623 although it might be fine. --kkm */
626 DeleteDC (DEVICE_MSPRINTER_HDC (d)); 624 if (qxeResetDC (DEVICE_MSPRINTER_HDC (d), devmode_out) == NULL)
627 DEVICE_MSPRINTER_HDC (d) = 625 {
628 CreateDC ("WINSPOOL", DEVICE_MSPRINTER_NAME(d), NULL, devmode_out); 626 DeleteDC (DEVICE_MSPRINTER_HDC (d));
629 } 627 DEVICE_MSPRINTER_HDC (d) =
630 628 qxeCreateDC (XETEXT ("WINSPOOL"), nameext, NULL,
629 devmode_out);
630 }
631 }
632
631 return 1; 633 return 1;
632 } 634 }
633 635
634 static void 636 static void
635 handle_devmode_changes (Lisp_Devmode *ldm, HGLOBAL hDevNames, HGLOBAL hDevMode) 637 handle_devmode_changes (Lisp_Devmode *ldm, HGLOBAL hDevNames, HGLOBAL hDevMode)
636 { 638 {
637 DEVNAMES* devnames = (DEVNAMES*) GlobalLock (hDevNames); 639 DEVNAMES *devnames = (DEVNAMES *) GlobalLock (hDevNames);
638 char *new_name = devnames ? (char*)devnames + devnames->wDeviceOffset : NULL; 640 Extbyte *new_name =
639 DEVMODE* devmode = (DEVMODE*) GlobalLock (hDevMode); 641 devnames ?
642 (Extbyte *) devnames + XETCHAR_SIZE * devnames->wDeviceOffset : NULL;
643 DEVMODEW *devmode = (DEVMODEW *) GlobalLock (hDevMode);
640 644
641 /* Size and name may have changed */ 645 /* Size and name may have changed */
642 ldm->devmode = (DEVMODE *) xrealloc (ldm->devmode, DEVMODE_SIZE (devmode)); 646 ldm->devmode = (DEVMODEW *) xrealloc (ldm->devmode, DEVMODE_SIZE (devmode));
643 if (new_name) 647 if (new_name)
644 { 648 ldm->printer_name = build_tstr_string (new_name);
645 if (ldm->printer_name)
646 xfree (ldm->printer_name);
647 ldm->printer_name = xstrdup (new_name);
648 }
649 649
650 if (!NILP (ldm->device)) 650 if (!NILP (ldm->device))
651 { 651 {
652 /* Apply the new devmode to the printer and get a compete one back */ 652 /* Apply the new devmode to the printer and get a compete one back */
653 struct device *d = XDEVICE (ldm->device); 653 struct device *d = XDEVICE (ldm->device);
654 if (!sync_printer_with_devmode (d, devmode, ldm->devmode, new_name)) 654 if (!sync_printer_with_devmode (d, devmode, ldm->devmode,
655 new_name ? ldm->printer_name : Qnil))
655 { 656 {
656 global_free_2_maybe (hDevNames, hDevMode); 657 global_free_2_maybe (hDevNames, hDevMode);
657 signal_error (Qio_error, "Printer device initialization I/O error, device deleted", Qunbound); 658 signal_error
659 (Qio_error,
660 "Printer device initialization I/O error, device deleted",
661 ldm->device);
658 } 662 }
659 } 663 }
660 else 664 else
661 { 665 {
662 /* Just copy the devmode structure */ 666 /* Just copy the devmode structure */
693 */ 697 */
694 static Lisp_Object 698 static Lisp_Object
695 print_dialog_worker (Lisp_Object dev, DWORD flags) 699 print_dialog_worker (Lisp_Object dev, DWORD flags)
696 { 700 {
697 Lisp_Devmode *ldm = decode_devmode (dev); 701 Lisp_Devmode *ldm = decode_devmode (dev);
698 PRINTDLG pd; 702 PRINTDLGW pd;
699 703
700 memset (&pd, 0, sizeof (pd)); 704 memset (&pd, 0, sizeof (pd));
701 pd.lStructSize = sizeof (pd); 705 pd.lStructSize = sizeof (pd);
702 pd.hwndOwner = mswindows_get_selected_frame_hwnd (); 706 pd.hwndOwner = mswindows_get_selected_frame_hwnd ();
703 pd.hDevMode = devmode_to_hglobal (ldm); 707 pd.hDevMode = devmode_to_hglobal (ldm);
704 pd.Flags = flags | PD_USEDEVMODECOPIESANDCOLLATE; 708 pd.Flags = flags | PD_USEDEVMODECOPIESANDCOLLATE;
705 pd.nMinPage = 0; 709 pd.nMinPage = 0;
706 pd.nMaxPage = 0xFFFF; 710 pd.nMaxPage = 0xFFFF;
707 711
708 if (!PrintDlg (&pd)) 712 if (!qxePrintDlg (&pd))
709 { 713 {
710 global_free_2_maybe (pd.hDevNames, pd.hDevMode); 714 global_free_2_maybe (pd.hDevNames, pd.hDevMode);
711 return Qnil; 715 return Qnil;
712 } 716 }
713 717
734 result = Fcons (Qselected_page_button, Fcons (Qselection, result)); 738 result = Fcons (Qselected_page_button, Fcons (Qselection, result));
735 else 739 else
736 result = Fcons (Qselected_page_button, Fcons (Qall, result)); 740 result = Fcons (Qselected_page_button, Fcons (Qall, result));
737 741
738 /* Device name */ 742 /* Device name */
739 result = Fcons (Qname, Fcons (build_ext_string (ldm->printer_name, 743 result = Fcons (Qname, Fcons (ldm->printer_name, result));
740 Qmswindows_tstr),
741 result));
742 UNGCPRO; 744 UNGCPRO;
743 745
744 global_free_2_maybe (pd.hDevNames, pd.hDevMode); 746 global_free_2_maybe (pd.hDevNames, pd.hDevMode);
745 return result; 747 return result;
746 } 748 }
863 if (UNBOUNDP (device)) 865 if (UNBOUNDP (device))
864 device = settings; 866 device = settings;
865 867
866 { 868 {
867 Lisp_Devmode *ldm = decode_devmode (device); 869 Lisp_Devmode *ldm = decode_devmode (device);
868 PAGESETUPDLG pd; 870 PAGESETUPDLGW pd;
869 871
870 memset (&pd, 0, sizeof (pd)); 872 memset (&pd, 0, sizeof (pd));
871 pd.lStructSize = sizeof (pd); 873 pd.lStructSize = sizeof (pd);
872 pd.hwndOwner = mswindows_get_selected_frame_hwnd (); 874 pd.hwndOwner = mswindows_get_selected_frame_hwnd ();
873 pd.Flags = PSD_MARGINS; 875 pd.Flags = PSD_MARGINS;
875 pd.rtMargin.top = plist_get_margin (plist, Qtop_margin); 877 pd.rtMargin.top = plist_get_margin (plist, Qtop_margin);
876 pd.rtMargin.right = plist_get_margin (plist, Qright_margin); 878 pd.rtMargin.right = plist_get_margin (plist, Qright_margin);
877 pd.rtMargin.bottom = plist_get_margin (plist, Qbottom_margin); 879 pd.rtMargin.bottom = plist_get_margin (plist, Qbottom_margin);
878 pd.hDevMode = devmode_to_hglobal (ldm); 880 pd.hDevMode = devmode_to_hglobal (ldm);
879 881
880 if (!PageSetupDlg (&pd)) 882 if (!qxePageSetupDlg (&pd))
881 { 883 {
882 global_free_2_maybe (pd.hDevNames, pd.hDevMode); 884 global_free_2_maybe (pd.hDevNames, pd.hDevMode);
883 return Qnil; 885 return Qnil;
884 } 886 }
885 887
951 /* If the object being selected is de-specialized, then its 953 /* If the object being selected is de-specialized, then its
952 size is perhaps not enough to receive the new devmode. We can ask 954 size is perhaps not enough to receive the new devmode. We can ask
953 for printer's devmode size here, because despecialized settings 955 for printer's devmode size here, because despecialized settings
954 cannot force switching to a different printer, as they supply no 956 cannot force switching to a different printer, as they supply no
955 printer name at all. */ 957 printer name at all. */
956 if (ldm->printer_name == NULL) 958 if (NILP (ldm->printer_name))
957 { 959 {
958 LONG dm_size = 960 Extbyte *nameext;
959 DocumentProperties (NULL, DEVICE_MSPRINTER_HPRINTER(d), 961 LONG dm_size;
960 DEVICE_MSPRINTER_NAME(d), NULL, NULL, 0); 962
963 LISP_STRING_TO_TSTR (DEVICE_MSPRINTER_NAME (d), nameext);
964 dm_size = qxeDocumentProperties (NULL, DEVICE_MSPRINTER_HPRINTER (d),
965 nameext, NULL, NULL, 0);
961 if (dm_size <= 0) 966 if (dm_size <= 0)
962 signal_error (Qio_error, 967 signal_error (Qio_error,
963 "Unable to specialize settings, printer error", 968 "Unable to specialize settings, printer error",
964 device); 969 device);
965 970
966 assert (XDEVMODE_SIZE (ldm) <= dm_size); 971 assert (XDEVMODE_SIZE (ldm) <= dm_size);
967 ldm->devmode = (DEVMODE *) xrealloc (ldm->devmode, dm_size); 972 ldm->devmode = (DEVMODEW *) xrealloc (ldm->devmode, dm_size);
968 } 973 }
969 974
970 /* If we bail out on signal here, no damage is done, except that 975 /* If we bail out on signal here, no damage is done, except that
971 the storage for the DEVMODE structure might be reallocated to 976 the storage for the DEVMODE structure might be reallocated to
972 hold a larger one - not a big deal */ 977 hold a larger one - not a big deal */
973 if (!sync_printer_with_devmode (d, ldm->devmode, ldm->devmode, 978 if (!sync_printer_with_devmode (d, ldm->devmode, ldm->devmode,
974 ldm->printer_name)) 979 ldm->printer_name))
975 signal_error (Qio_error, 980 signal_error (Qio_error,
976 "Printer device initialization I/O error, device deleted", 981 "Printer device initialization I/O error, device deleted",
977 Qunbound); 982 device);
978 983
979 if (ldm->printer_name == NULL) 984 if (NILP (ldm->printer_name ))
980 ldm->printer_name = xstrdup (DEVICE_MSPRINTER_NAME(d)); 985 ldm->printer_name = DEVICE_MSPRINTER_NAME (d);
981 986
982 { 987 {
983 Lisp_Object old_mode = DEVICE_MSPRINTER_DEVMODE (d); 988 Lisp_Object old_mode = DEVICE_MSPRINTER_DEVMODE (d);
984 ldm->device = device; 989 ldm->device = device;
985 XDEVMODE (old_mode)->device = Qnil; 990 XDEVMODE (old_mode)->device = Qnil;
1020 devmode storage to match with the supplied one, as it has the right 1025 devmode storage to match with the supplied one, as it has the right
1021 size for the new printer, if it is going to change. The correct 1026 size for the new printer, if it is going to change. The correct
1022 way is to use the largest of the two though, to keep the old 1027 way is to use the largest of the two though, to keep the old
1023 contents unchanged in case of preliminary exit. 1028 contents unchanged in case of preliminary exit.
1024 */ 1029 */
1025 if (ldm_new->printer_name) 1030 if (!NILP (ldm_new->printer_name))
1026 ldm_current->devmode = 1031 ldm_current->devmode =
1027 (DEVMODE*) xrealloc (ldm_current->devmode, 1032 (DEVMODEW*) xrealloc (ldm_current->devmode,
1028 max (XDEVMODE_SIZE (ldm_new), 1033 max (XDEVMODE_SIZE (ldm_new),
1029 XDEVMODE_SIZE (ldm_current))); 1034 XDEVMODE_SIZE (ldm_current)));
1030 1035
1031 if (!sync_printer_with_devmode (d, ldm_new->devmode, 1036 if (!sync_printer_with_devmode (d, ldm_new->devmode,
1032 ldm_current->devmode, 1037 ldm_current->devmode,
1033 ldm_new->printer_name)) 1038 ldm_new->printer_name))
1034 signal_error (Qio_error, 1039 signal_error
1035 "Printer device initialization I/O error, device deleted", 1040 (Qio_error,
1036 Qunbound); 1041 "Printer device initialization I/O error, device deleted", device);
1037 1042
1038 if (ldm_new->printer_name != NULL) 1043 if (!NILP (ldm_new->printer_name))
1039 { 1044 ldm_current->printer_name = ldm_new->printer_name;
1040 xfree (ldm_current->printer_name);
1041 ldm_current->printer_name = xstrdup (ldm_new->printer_name);
1042 }
1043 1045
1044 UNGCPRO; 1046 UNGCPRO;
1045 return DEVICE_MSPRINTER_DEVMODE (d); 1047 return DEVICE_MSPRINTER_DEVMODE (d);
1046 } 1048 }
1047 1049
1048 /************************************************************************/ 1050 /************************************************************************/
1049 /* devmode */ 1051 /* devmode */
1050 /************************************************************************/ 1052 /************************************************************************/
1051 1053
1054 static Lisp_Object
1055 mark_devmode (Lisp_Object obj)
1056 {
1057 Lisp_Devmode *data = XDEVMODE (obj);
1058 mark_object (data->printer_name);
1059 return data->device;
1060 }
1061
1052 static void 1062 static void
1053 print_devmode (Lisp_Object obj, Lisp_Object printcharfun, 1063 print_devmode (Lisp_Object obj, Lisp_Object printcharfun,
1054 int escapeflag) 1064 int escapeflag)
1055 { 1065 {
1056 char buf[100]; 1066 CIntbyte buf[100];
1057 Lisp_Devmode *dm = XDEVMODE (obj); 1067 Lisp_Devmode *dm = XDEVMODE (obj);
1058 if (print_readably) 1068 if (print_readably)
1059 printing_unreadable_object ("#<msprinter-settings 0x%x>", 1069 printing_unreadable_object ("#<msprinter-settings 0x%x>",
1060 dm->header.uid); 1070 dm->header.uid);
1061 write_c_string ("#<msprinter-settings", printcharfun); 1071 write_c_string ("#<msprinter-settings", printcharfun);
1062 if (dm->printer_name) 1072 if (!NILP (dm->printer_name))
1063 { 1073 {
1064 write_c_string (" for \"", printcharfun); 1074 write_c_string (" for ", printcharfun);
1065 write_c_string (dm->printer_name, printcharfun); 1075 print_internal (dm->printer_name, printcharfun, 1);
1066 write_c_string ("\"", printcharfun);
1067 } 1076 }
1068 if (!NILP (dm->device)) 1077 if (!NILP (dm->device))
1069 { 1078 {
1070 write_c_string (" (currently on ", printcharfun); 1079 write_c_string (" (currently on ", printcharfun);
1071 print_internal (dm->device, printcharfun, 0); 1080 print_internal (dm->device, printcharfun, 0);
1088 ("Cannot dump XEmacs containing an msprinter-settings object", 1097 ("Cannot dump XEmacs containing an msprinter-settings object",
1089 devmode); 1098 devmode);
1090 } 1099 }
1091 1100
1092 assert (NILP (dm->device)); 1101 assert (NILP (dm->device));
1093
1094 if (dm->printer_name)
1095 xfree (dm->printer_name);
1096 } 1102 }
1097 1103
1098 static int 1104 static int
1099 equal_devmode (Lisp_Object obj1, Lisp_Object obj2, int depth) 1105 equal_devmode (Lisp_Object obj1, Lisp_Object obj2, int depth)
1100 { 1106 {
1105 return 0; 1111 return 0;
1106 if (dm1->devmode == NULL) 1112 if (dm1->devmode == NULL)
1107 return 1; 1113 return 1;
1108 if (memcmp (dm1->devmode, dm2->devmode, XDEVMODE_SIZE (dm1)) != 0) 1114 if (memcmp (dm1->devmode, dm2->devmode, XDEVMODE_SIZE (dm1)) != 0)
1109 return 0; 1115 return 0;
1110 if (dm1->printer_name == NULL || dm2->printer_name == NULL) 1116 if (NILP (dm1->printer_name) || NILP (dm2->printer_name))
1111 return 1; 1117 return 1;
1112 return stricmp (dm1->printer_name, dm2->printer_name) == 0; 1118 return lisp_strcasecmp (dm1->printer_name, dm2->printer_name) == 0;
1113 } 1119 }
1114 1120
1115 static Hashcode 1121 static Hashcode
1116 hash_devmode (Lisp_Object obj, int depth) 1122 hash_devmode (Lisp_Object obj, int depth)
1117 { 1123 {
1118 Lisp_Devmode *dm = XDEVMODE (obj); 1124 Lisp_Devmode *dm = XDEVMODE (obj);
1119 1125
1120 return HASH3 (XDEVMODE_SIZE (dm), 1126 return HASH3 (XDEVMODE_SIZE (dm),
1121 dm->devmode ? memory_hash (dm->devmode, XDEVMODE_SIZE (dm)) 1127 dm->devmode ? memory_hash (dm->devmode, XDEVMODE_SIZE (dm))
1122 : 0, 1128 : 0,
1123 dm->printer_name ? string_hash (dm->printer_name) : 0); 1129 internal_hash (dm->printer_name, depth + 1));
1124 } 1130 }
1125 1131
1126 DEFINE_LRECORD_IMPLEMENTATION ("msprinter-settings", devmode, 1132 DEFINE_LRECORD_IMPLEMENTATION ("msprinter-settings", devmode,
1127 0/*mark*/, print_devmode, finalize_devmode, 1133 mark_devmode, print_devmode, finalize_devmode,
1128 equal_devmode, hash_devmode, 0/*description*/, 1134 equal_devmode, hash_devmode, 0/*description*/,
1129 Lisp_Devmode); 1135 Lisp_Devmode);
1130 static Lisp_Object 1136 static Lisp_Object
1131 allocate_devmode (DEVMODE* src_devmode, int do_copy, 1137 allocate_devmode (DEVMODEW* src_devmode, int do_copy,
1132 char* src_name, struct device *d) 1138 Lisp_Object src_name, struct device *d)
1133 { 1139 {
1134 Lisp_Devmode *dm; 1140 Lisp_Devmode *dm;
1135 Lisp_Object ob; 1141 Lisp_Object ob;
1136 1142
1137 dm = alloc_lcrecord_type (Lisp_Devmode, &lrecord_devmode); 1143 dm = alloc_lcrecord_type (Lisp_Devmode, &lrecord_devmode);
1139 if (d) 1145 if (d)
1140 XSETDEVICE (dm->device, d); 1146 XSETDEVICE (dm->device, d);
1141 else 1147 else
1142 dm->device = Qnil; 1148 dm->device = Qnil;
1143 1149
1144 dm->printer_name = src_name ? xstrdup (src_name) : NULL; 1150 dm->printer_name = src_name;
1145 1151
1146 if (src_devmode != NULL && do_copy) 1152 if (src_devmode != NULL && do_copy)
1147 { 1153 {
1148 dm->devmode = (DEVMODE*) xmalloc (DEVMODE_SIZE (src_devmode)); 1154 dm->devmode = (DEVMODEW*) xmalloc (DEVMODE_SIZE (src_devmode));
1149 memcpy (dm->devmode, src_devmode, DEVMODE_SIZE (src_devmode)); 1155 memcpy (dm->devmode, src_devmode, DEVMODE_SIZE (src_devmode));
1150 } 1156 }
1151 else 1157 else
1152 { 1158 {
1153 dm->devmode = src_devmode; 1159 dm->devmode = src_devmode;
1174 Erase printer-specific settings from a printer settings object. 1180 Erase printer-specific settings from a printer settings object.
1175 */ 1181 */
1176 (settings)) 1182 (settings))
1177 { 1183 {
1178 Lisp_Devmode *ldm; 1184 Lisp_Devmode *ldm;
1179 DEVMODE *dm; 1185 DEVMODEW *dm;
1180 1186
1181 CHECK_DEVMODE (settings); 1187 CHECK_DEVMODE (settings);
1182 ldm = XDEVMODE (settings); 1188 ldm = XDEVMODE (settings);
1183 1189
1184 if (!NILP (ldm->device)) 1190 if (!NILP (ldm->device))
1191 paper sizes etc, or signal an error of they are present. */ 1197 paper sizes etc, or signal an error of they are present. */
1192 1198
1193 dm->dmDriverExtra = 0; 1199 dm->dmDriverExtra = 0;
1194 dm->dmDeviceName[0] = '\0'; 1200 dm->dmDeviceName[0] = '\0';
1195 1201
1196 if (ldm->printer_name) 1202 ldm->printer_name = Qnil;
1197 xfree (ldm->printer_name);
1198 1203
1199 return Qnil; 1204 return Qnil;
1200 } 1205 }
1201 1206
1202 DEFUN ("mswindows-get-default-printer", Fmswindows_get_default_printer, 0, 0, 0, /* 1207 DEFUN ("mswindows-get-default-printer", Fmswindows_get_default_printer, 0, 0, 0, /*
1228 DWORD enum_flags, enum_level, bytes_needed, num_printers; 1233 DWORD enum_flags, enum_level, bytes_needed, num_printers;
1229 struct gcpro gcpro1, gcpro2; 1234 struct gcpro gcpro1, gcpro2;
1230 Lisp_Object result = Qnil, def_printer = Qnil; 1235 Lisp_Object result = Qnil, def_printer = Qnil;
1231 1236
1232 /* Determine OS flavor, to use the fastest enumeration method available */ 1237 /* Determine OS flavor, to use the fastest enumeration method available */
1233 have_nt = !mswindows_windows9x_p (); 1238 have_nt = !mswindows_windows9x_p;
1234 enum_flags = PRINTER_ENUM_LOCAL | (have_nt ? PRINTER_ENUM_CONNECTIONS : 0); 1239 enum_flags = PRINTER_ENUM_LOCAL | (have_nt ? PRINTER_ENUM_CONNECTIONS : 0);
1235 enum_level = have_nt ? 4 : 5; 1240 enum_level = have_nt ? 4 : 5;
1236 enum_entry_size = have_nt ? sizeof (PRINTER_INFO_4) : sizeof (PRINTER_INFO_5); 1241 enum_entry_size = (have_nt ? sizeof (PRINTER_INFO_4) :
1242 sizeof (PRINTER_INFO_5));
1237 1243
1238 /* Allocate memory for printer enum structure */ 1244 /* Allocate memory for printer enum structure */
1239 ok = EnumPrinters (enum_flags, NULL, enum_level, &dummy_byte, 1, 1245 ok = qxeEnumPrinters (enum_flags, NULL, enum_level, &dummy_byte, 1,
1240 &bytes_needed, &num_printers); 1246 &bytes_needed, &num_printers);
1241 if (ok) 1247 if (ok)
1242 /* No printers, if just 1 byte is enough */ 1248 /* No printers, if just 1 byte is enough */
1243 return Qnil; 1249 return Qnil;
1244 1250
1245 if (GetLastError () != ERROR_INSUFFICIENT_BUFFER) 1251 if (GetLastError () != ERROR_INSUFFICIENT_BUFFER)
1246 signal_enum_printer_error (); 1252 signal_enum_printer_error ();
1247 1253
1248 data_buf = (BYTE *) alloca (bytes_needed); 1254 data_buf = (BYTE *) alloca (bytes_needed);
1249 ok = EnumPrinters (enum_flags, NULL, enum_level, data_buf, bytes_needed, 1255 ok = qxeEnumPrinters (enum_flags, NULL, enum_level, data_buf, bytes_needed,
1250 &bytes_needed, &num_printers); 1256 &bytes_needed, &num_printers);
1251 if (!ok) 1257 if (!ok)
1252 signal_enum_printer_error (); 1258 signal_enum_printer_error ();
1253 1259
1254 if (num_printers == 0) 1260 if (num_printers == 0)
1255 /* Strange but... */ 1261 /* Strange but... */
1257 1263
1258 GCPRO2 (result, def_printer); 1264 GCPRO2 (result, def_printer);
1259 1265
1260 while (num_printers--) 1266 while (num_printers--)
1261 { 1267 {
1262 LPCTSTR printer_name; 1268 Extbyte *printer_name;
1263 if (have_nt) 1269 if (have_nt)
1264 { 1270 {
1265 PRINTER_INFO_4 *info = (PRINTER_INFO_4*) data_buf; 1271 PRINTER_INFO_4 *info = (PRINTER_INFO_4 *) data_buf;
1266 printer_name = info->pPrinterName; 1272 printer_name = (Extbyte *) info->pPrinterName;
1267 } 1273 }
1268 else 1274 else
1269 { 1275 {
1270 PRINTER_INFO_5 *info = (PRINTER_INFO_5*) data_buf; 1276 PRINTER_INFO_5 *info = (PRINTER_INFO_5 *) data_buf;
1271 printer_name = info->pPrinterName; 1277 printer_name = (Extbyte *) info->pPrinterName;
1272 } 1278 }
1273 data_buf += enum_entry_size; 1279 data_buf += enum_entry_size;
1274 1280
1275 result = Fcons (build_ext_string (printer_name, Qmswindows_tstr), 1281 result = Fcons (build_tstr_string (printer_name), result);
1276 result);
1277 } 1282 }
1278 1283
1279 def_printer = msprinter_default_printer (); 1284 def_printer = msprinter_default_printer ();
1280 result = Fdelete (def_printer, result); 1285 result = Fdelete (def_printer, result);
1281 result = Fcons (def_printer, result); 1286 result = Fcons (def_printer, result);
1333 1338
1334 1339
1335 void 1340 void
1336 vars_of_device_mswindows (void) 1341 vars_of_device_mswindows (void)
1337 { 1342 {
1338 DEFVAR_LISP ("mswindows-downcase-file-names", &Vmswindows_downcase_file_names /* 1343 }
1339 Non-nil means convert all-upper case file names to lower case.
1340 This applies when performing completions and file name expansion.
1341 */ );
1342 Vmswindows_downcase_file_names = Qnil;
1343
1344 DEFVAR_LISP ("mswindows-get-true-file-attributes", &Vmswindows_get_true_file_attributes /*
1345 Non-nil means determine accurate link count in file-attributes.
1346 This option slows down file-attributes noticeably, so is disabled by
1347 default. Note that it is only useful for files on NTFS volumes,
1348 where hard links are supported.
1349 */ );
1350 Vmswindows_get_true_file_attributes = Qnil;
1351 }