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.
5 This file is part of XEmacs.
7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* Synched up with: Not in FSF. */
26 Original authors: Jamie Zawinski and the FSF
27 Rewritten by Ben Wing and Chuck Thompson.
28 Rewritten for mswindows by Jonathan Harris, November 1997 for 21.0.
35 #include "console-msw.h"
36 #include "console-stream.h"
44 /* win32 DDE management library globals */
46 DWORD mswindows_dde_mlid;
47 HSZ mswindows_dde_service;
48 HSZ mswindows_dde_topic_system;
49 HSZ mswindows_dde_item_open;
52 /* Control conversion of upper case file names to lower case.
53 nil means no, t means yes. */
54 Lisp_Object Vmswindows_downcase_file_names;
56 /* Control whether stat() attempts to determine file type and link count
57 exactly, at the expense of slower operation. Since true hard links
58 are supported on NTFS volumes, this is only relevant on NT. */
59 Lisp_Object Vmswindows_get_true_file_attributes;
61 Lisp_Object Qinit_pre_mswindows_win, Qinit_post_mswindows_win;
64 /************************************************************************/
66 /************************************************************************/
69 build_syscolor_string (int idx)
77 clr = GetSysColor (idx);
78 sprintf (buf, "#%02X%02X%02X",
82 return build_string (buf);
86 build_syscolor_cons (int index1, int index2)
88 Lisp_Object color1, color2;
91 color1 = build_syscolor_string (index1);
92 color2 = build_syscolor_string (index2);
93 RETURN_UNGCPRO (Fcons (color1, color2));
97 build_sysmetrics_cons (int index1, int index2)
99 return Fcons (index1 < 0 ? Qnil : make_int (GetSystemMetrics (index1)),
100 index2 < 0 ? Qnil : make_int (GetSystemMetrics (index2)));
104 build_devicecaps_cons (HDC hdc, int index1, int index2)
106 return Fcons (index1 < 0 ? Qnil : make_int (GetDeviceCaps (hdc, index1)),
107 index2 < 0 ? Qnil : make_int (GetDeviceCaps (hdc, index2)));
112 /************************************************************************/
113 /* display methods */
114 /************************************************************************/
117 mswindows_init_device (struct device *d, Lisp_Object props)
122 DEVICE_CLASS (d) = Qcolor;
123 DEVICE_INFD (d) = DEVICE_OUTFD (d) = -1;
127 d->device_data = xnew_and_zero (struct mswindows_device);
128 hdc = CreateCompatibleDC (NULL);
130 DEVICE_MSWINDOWS_LOGPIXELSX(d) = GetDeviceCaps(hdc, LOGPIXELSX);
131 DEVICE_MSWINDOWS_LOGPIXELSY(d) = GetDeviceCaps(hdc, LOGPIXELSY);
132 DEVICE_MSWINDOWS_PLANES(d) = GetDeviceCaps(hdc, PLANES);
133 /* #### SIZEPALETTE only valid if RC_PALETTE bit set in RASTERCAPS,
134 what should we return for a non-palette-based device? */
135 DEVICE_MSWINDOWS_CELLS(d) = GetDeviceCaps(hdc, SIZEPALETTE);
136 DEVICE_MSWINDOWS_HORZRES(d) = GetDeviceCaps(hdc, HORZRES);
137 DEVICE_MSWINDOWS_VERTRES(d) = GetDeviceCaps(hdc, VERTRES);
138 DEVICE_MSWINDOWS_HORZSIZE(d) = GetDeviceCaps(hdc, HORZSIZE);
139 DEVICE_MSWINDOWS_VERTSIZE(d) = GetDeviceCaps(hdc, VERTSIZE);
140 DEVICE_MSWINDOWS_BITSPIXEL(d) = GetDeviceCaps(hdc, BITSPIXEL);
141 DEVICE_MSWINDOWS_FONTLIST (d) = mswindows_enumerate_fonts (hdc);
145 /* Register the main window class */
146 wc.cbSize = sizeof (WNDCLASSEX);
147 wc.style = CS_OWNDC; /* One DC per window */
148 wc.lpfnWndProc = (WNDPROC) mswindows_wnd_proc;
150 wc.cbWndExtra = MSWINDOWS_WINDOW_EXTRA_BYTES;
151 /* This must match whatever is passed to CreateWIndowEx, NULL is ok
154 wc.hIcon = LoadIcon (GetModuleHandle(NULL), XEMACS_CLASS);
155 wc.hCursor = LoadCursor (NULL, IDC_ARROW);
156 /* Background brush is only used during sizing, when XEmacs cannot
158 wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);
159 wc.lpszMenuName = NULL;
161 wc.lpszClassName = XEMACS_CLASS;
162 wc.hIconSm = LoadImage (GetModuleHandle (NULL), XEMACS_CLASS,
163 IMAGE_ICON, 16, 16, 0);
164 RegisterClassEx (&wc);
168 /* Register the main window class */
169 wc.cbSize = sizeof (WNDCLASSEX);
170 wc.lpfnWndProc = (WNDPROC) mswindows_control_wnd_proc;
171 wc.lpszClassName = XEMACS_CONTROL_CLASS;
173 RegisterClassEx (&wc);
176 #if defined (HAVE_TOOLBARS) || defined (HAVE_WIDGETS)
177 InitCommonControls ();
182 mswindows_finish_init_device (struct device *d, Lisp_Object props)
184 /* Initialize DDE management library and our related globals. We execute a
185 * dde Open("file") by simulating a drop, so this depends on dnd support. */
186 #ifdef HAVE_DRAGNDROP
187 mswindows_dde_mlid = 0;
188 DdeInitialize (&mswindows_dde_mlid, (PFNCALLBACK)mswindows_dde_callback,
189 APPCMD_FILTERINITS|CBF_FAIL_SELFCONNECTIONS|CBF_FAIL_ADVISES|
190 CBF_FAIL_POKES|CBF_FAIL_REQUESTS|CBF_SKIP_ALLNOTIFICATIONS, 0);
192 mswindows_dde_service = DdeCreateStringHandle (mswindows_dde_mlid, XEMACS_CLASS, 0);
193 mswindows_dde_topic_system = DdeCreateStringHandle (mswindows_dde_mlid, SZDDESYS_TOPIC, 0);
194 mswindows_dde_item_open = DdeCreateStringHandle (mswindows_dde_mlid,
195 TEXT(MSWINDOWS_DDE_ITEM_OPEN), 0);
196 DdeNameService (mswindows_dde_mlid, mswindows_dde_service, 0L, DNS_REGISTER);
201 mswindows_delete_device (struct device *d)
203 #ifdef HAVE_DRAGNDROP
204 DdeNameService (mswindows_dde_mlid, 0L, 0L, DNS_REGISTER);
205 DdeUninitialize (mswindows_dde_mlid);
208 free (d->device_data);
212 mswindows_mark_device (struct device *d)
214 mark_object (DEVICE_MSWINDOWS_FONTLIST (d));
218 mswindows_device_system_metrics (struct device *d,
219 enum device_metrics m)
224 return Fcons (make_int (DEVICE_MSWINDOWS_HORZRES(d)),
225 make_int (DEVICE_MSWINDOWS_VERTRES(d)));
228 return Fcons (make_int (DEVICE_MSWINDOWS_LOGPIXELSX(d)),
229 make_int (DEVICE_MSWINDOWS_LOGPIXELSY(d)));
231 case DM_size_device_mm:
232 return Fcons (make_int (DEVICE_MSWINDOWS_HORZSIZE(d)),
233 make_int (DEVICE_MSWINDOWS_VERTSIZE(d)));
235 case DM_num_bit_planes:
236 /* this is what X means by bitplanes therefore we ought to be
237 consistent. num planes is always 1 under mswindows and
239 return make_int (DEVICE_MSWINDOWS_BITSPIXEL(d));
241 case DM_num_color_cells:
242 return make_int (DEVICE_MSWINDOWS_CELLS(d));
246 #define FROB(met, index1, index2) \
248 return build_syscolor_cons (index1, index2);
250 FROB (color_default, COLOR_WINDOW, COLOR_WINDOWTEXT);
251 FROB (color_select, COLOR_HIGHLIGHT, COLOR_HIGHLIGHTTEXT);
252 FROB (color_balloon, COLOR_INFOBK, COLOR_INFOTEXT);
253 FROB (color_3d_face, COLOR_3DFACE, COLOR_BTNTEXT);
254 FROB (color_3d_light, COLOR_3DLIGHT, COLOR_3DHILIGHT);
255 FROB (color_3d_dark, COLOR_3DSHADOW, COLOR_3DDKSHADOW);
256 FROB (color_menu, COLOR_MENU, COLOR_MENUTEXT);
257 FROB (color_menu_highlight, COLOR_HIGHLIGHT, COLOR_HIGHLIGHTTEXT);
258 FROB (color_menu_button, COLOR_MENU, COLOR_MENUTEXT);
259 FROB (color_menu_disabled, COLOR_MENU, COLOR_GRAYTEXT);
260 FROB (color_toolbar, COLOR_BTNFACE, COLOR_BTNTEXT);
261 FROB (color_scrollbar, COLOR_SCROLLBAR, COLOR_CAPTIONTEXT);
262 FROB (color_desktop, -1, COLOR_DESKTOP);
263 FROB (color_workspace, -1, COLOR_APPWORKSPACE);
267 #define FROB(met, index1, index2) \
269 return build_sysmetrics_cons (index1, index2);
271 FROB (size_cursor, SM_CXCURSOR, SM_CYCURSOR);
272 FROB (size_scrollbar, SM_CXVSCROLL, SM_CYHSCROLL);
273 FROB (size_menu, -1, SM_CYMENU);
274 FROB (size_icon, SM_CXICON, SM_CYICON);
275 FROB (size_icon_small, SM_CXSMICON, SM_CYSMICON);
278 case DM_size_workspace:
281 SystemParametersInfo (SPI_GETWORKAREA, 0, &rc, 0);
282 return Fcons (make_int (rc.right - rc.left),
283 make_int (rc.bottom - rc.top));
286 case DM_size_toolbar:
287 case DM_size_toolbar_button:
288 case DM_size_toolbar_border:
292 #define FROB(met, index) \
294 return make_int (GetSystemMetrics (index));
296 FROB (mouse_buttons, SM_CMOUSEBUTTONS);
297 FROB (swap_buttons, SM_SWAPBUTTON);
298 FROB (show_sounds, SM_SHOWSOUNDS);
299 FROB (slow_device, SM_SLOWMACHINE);
300 FROB (security, SM_SECURE);
305 /* Do not know such property */
310 mswindows_device_implementation_flags (void)
312 return XDEVIMPF_PIXEL_GEOMETRY;
316 /************************************************************************/
317 /* printer methods */
318 /************************************************************************/
321 signal_open_printer_error (struct device *d)
323 signal_simple_error ("Failed to open printer", DEVICE_CONNECTION (d));
327 msprinter_init_device (struct device *d, Lisp_Object props)
331 DEVICE_INFD (d) = DEVICE_OUTFD (d) = -1;
333 CHECK_STRING (DEVICE_CONNECTION (d));
335 TO_EXTERNAL_FORMAT (LISP_STRING, DEVICE_CONNECTION (d),
336 C_STRING_ALLOCA, printer_name,
339 d->device_data = xnew_and_zero (struct msprinter_device);
341 DEVICE_MSPRINTER_NAME(d) = xstrdup (printer_name);
343 if (!OpenPrinter (printer_name, &DEVICE_MSPRINTER_HPRINTER (d), NULL))
345 DEVICE_MSPRINTER_HPRINTER (d) = NULL;
346 signal_open_printer_error (d);
349 DEVICE_MSPRINTER_HDC (d) = CreateDC ("WINSPOOL", printer_name,
351 if (DEVICE_MSPRINTER_HDC (d) == NULL)
352 signal_open_printer_error (d);
354 /* Determinie DEVMODE size and store the default DEVMODE */
355 DEVICE_MSPRINTER_DEVMODE_SIZE(d) =
356 DocumentProperties (NULL, DEVICE_MSPRINTER_HPRINTER(d),
357 printer_name, NULL, NULL, 0);
358 if (DEVICE_MSPRINTER_DEVMODE_SIZE(d) <= 0)
359 signal_open_printer_error (d);
361 DEVICE_MSPRINTER_DEVMODE(d) = xmalloc (DEVICE_MSPRINTER_DEVMODE_SIZE(d));
362 DocumentProperties (NULL, DEVICE_MSPRINTER_HPRINTER(d),
363 printer_name, DEVICE_MSPRINTER_DEVMODE(d),
364 NULL, DM_OUT_BUFFER);
366 /* We do not use printer fon list as we do with the display
367 device. Rather, we allow GDI to pick the closest match to the
369 DEVICE_MSPRINTER_FONTLIST (d) = Qnil;
371 DEVICE_CLASS (d) = (GetDeviceCaps (DEVICE_MSPRINTER_HDC (d), BITSPIXEL)
372 * GetDeviceCaps (DEVICE_MSPRINTER_HDC (d), PLANES)
373 > 1) ? Qcolor : Qmono;
377 msprinter_device_system_metrics (struct device *d,
378 enum device_metrics m)
382 /* Device sizes - pixel and mm */
383 #define FROB(met, index1, index2) \
385 return build_devicecaps_cons \
386 (DEVICE_MSPRINTER_HDC(d), index1, index2);
388 FROB (size_device, PHYSICALWIDTH, PHYSICALHEIGHT);
389 FROB (size_device_mm, HORZSIZE, VERTSIZE);
390 FROB (size_workspace, HORZRES, VERTRES);
391 FROB (offset_workspace, PHYSICALOFFSETX, PHYSICALOFFSETY);
392 FROB (device_dpi, LOGPIXELSX, LOGPIXELSY);
395 case DM_num_bit_planes:
396 /* this is what X means by bitplanes therefore we ought to be
397 consistent. num planes is always 1 under mswindows and
399 return make_int (GetDeviceCaps (DEVICE_MSPRINTER_HDC(d), BITSPIXEL));
401 case DM_num_color_cells: /* Prnters are non-palette devices */
402 case DM_slow_device: /* Animation would be a really bad idea */
403 case DM_security: /* Not provided by windows */
407 /* Do not know such property */
412 msprinter_delete_device (struct device *d)
416 if (DEVICE_MSPRINTER_HPRINTER (d))
417 ClosePrinter (DEVICE_MSPRINTER_HPRINTER (d));
418 if (DEVICE_MSPRINTER_HDC (d))
419 DeleteDC (DEVICE_MSPRINTER_HDC (d));
420 if (DEVICE_MSPRINTER_NAME (d))
421 free (DEVICE_MSPRINTER_NAME (d));
422 if (DEVICE_MSPRINTER_DEVMODE (d))
423 free (DEVICE_MSPRINTER_DEVMODE (d));
424 if (DEVICE_MSPRINTER_DEVMODE_MIRROR (d))
425 free (DEVICE_MSPRINTER_DEVMODE_MIRROR (d));
427 free (d->device_data);
432 msprinter_mark_device (struct device *d)
434 mark_object (DEVICE_MSPRINTER_FONTLIST (d));
438 msprinter_device_implementation_flags (void)
440 return ( XDEVIMPF_PIXEL_GEOMETRY
441 | XDEVIMPF_IS_A_PRINTER
442 | XDEVIMPF_NO_AUTO_REDISPLAY
443 | XDEVIMPF_FRAMELESS_OK );
447 /************************************************************************/
448 /* printer external functions */
449 /************************************************************************/
452 * Return a copy of default DEVMODE. The copy returned is in
453 * a static buffer which will be overwritten by next call.
456 msprinter_get_devmode_copy (struct device *d)
458 assert (DEVICE_MSPRINTER_P (d));
460 if (DEVICE_MSPRINTER_DEVMODE_MIRROR(d) == NULL)
461 DEVICE_MSPRINTER_DEVMODE_MIRROR(d) =
462 xmalloc (DEVICE_MSPRINTER_DEVMODE_SIZE(d));
464 memcpy (DEVICE_MSPRINTER_DEVMODE_MIRROR(d),
465 DEVICE_MSPRINTER_DEVMODE(d),
466 DEVICE_MSPRINTER_DEVMODE_SIZE(d));
468 return DEVICE_MSPRINTER_DEVMODE_MIRROR(d);
472 * Apply settings from the DEVMODE. The settings are considered
473 * incremental to the default DEVMODE, so that changes in the
474 * passed structure supercede parameters of the printer.
476 * The passed structure is overwritten by the fuction call;
477 * complete printer settings are returned.
480 msprinter_apply_devmode (struct device *d, DEVMODE *devmode)
482 assert (DEVICE_MSPRINTER_P (d));
484 DocumentProperties (NULL,
485 DEVICE_MSPRINTER_HPRINTER(d),
486 DEVICE_MSPRINTER_NAME(d),
488 DM_IN_BUFFER | DM_OUT_BUFFER);
490 ResetDC (DEVICE_MSPRINTER_HDC (d), devmode);
494 /************************************************************************/
496 /************************************************************************/
499 syms_of_device_mswindows (void)
501 defsymbol (&Qinit_pre_mswindows_win, "init-pre-mswindows-win");
502 defsymbol (&Qinit_post_mswindows_win, "init-post-mswindows-win");
506 console_type_create_device_mswindows (void)
508 CONSOLE_HAS_METHOD (mswindows, init_device);
509 CONSOLE_HAS_METHOD (mswindows, finish_init_device);
510 CONSOLE_HAS_METHOD (mswindows, mark_device);
511 CONSOLE_HAS_METHOD (mswindows, delete_device);
512 CONSOLE_HAS_METHOD (mswindows, device_system_metrics);
513 CONSOLE_HAS_METHOD (mswindows, device_implementation_flags);
515 CONSOLE_HAS_METHOD (msprinter, init_device);
516 CONSOLE_HAS_METHOD (msprinter, mark_device);
517 CONSOLE_HAS_METHOD (msprinter, delete_device);
518 CONSOLE_HAS_METHOD (msprinter, device_system_metrics);
519 CONSOLE_HAS_METHOD (msprinter, device_implementation_flags);
524 vars_of_device_mswindows (void)
526 DEFVAR_LISP ("mswindows-downcase-file-names", &Vmswindows_downcase_file_names /*
527 Non-nil means convert all-upper case file names to lower case.
528 This applies when performing completions and file name expansion.
530 Vmswindows_downcase_file_names = Qnil;
532 DEFVAR_LISP ("mswindows-get-true-file-attributes", &Vmswindows_get_true_file_attributes /*
533 Non-nil means determine accurate link count in file-attributes.
534 This option slows down file-attributes noticeably, so is disabled by
535 default. Note that it is only useful for files on NTFS volumes,
536 where hard links are supported.
538 Vmswindows_get_true_file_attributes = Qnil;