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"
37 #include "objects-msw.h"
43 #if (defined (__CYGWIN32__) || defined(__MINGW32__)) && \
44 CYGWIN_VERSION_DLL_MAJOR < 21
45 extern BOOL WINAPI DdeFreeStringHandle(DWORD,HSZ);
50 #if !(defined (__CYGWIN32__) || defined(__MINGW32__))
51 # include <objbase.h> /* For CoInitialize */
54 /* win32 DDE management library globals */
56 DWORD mswindows_dde_mlid;
57 HSZ mswindows_dde_service;
58 HSZ mswindows_dde_topic_system;
59 HSZ mswindows_dde_item_open;
62 /* Control conversion of upper case file names to lower case.
63 nil means no, t means yes. */
64 Lisp_Object Vmswindows_downcase_file_names;
66 /* Control whether stat() attempts to determine file type and link count
67 exactly, at the expense of slower operation. Since true hard links
68 are supported on NTFS volumes, this is only relevant on NT. */
69 Lisp_Object Vmswindows_get_true_file_attributes;
71 Lisp_Object Qinit_pre_mswindows_win, Qinit_post_mswindows_win;
74 /************************************************************************/
76 /************************************************************************/
79 build_syscolor_string (int idx)
81 return (idx < 0 ? Qnil : mswindows_color_to_string (GetSysColor (idx)));
85 build_syscolor_cons (int index1, int index2)
87 Lisp_Object color1, color2;
90 color1 = build_syscolor_string (index1);
91 color2 = build_syscolor_string (index2);
92 RETURN_UNGCPRO (Fcons (color1, color2));
96 build_sysmetrics_cons (int index1, int index2)
98 return Fcons (index1 < 0 ? Qnil : make_int (GetSystemMetrics (index1)),
99 index2 < 0 ? Qnil : make_int (GetSystemMetrics (index2)));
103 build_devicecaps_cons (HDC hdc, int index1, int index2)
105 return Fcons (index1 < 0 ? Qnil : make_int (GetDeviceCaps (hdc, index1)),
106 index2 < 0 ? Qnil : make_int (GetDeviceCaps (hdc, index2)));
111 /************************************************************************/
112 /* display methods */
113 /************************************************************************/
116 mswindows_init_device (struct device *d, Lisp_Object props)
121 DEVICE_CLASS (d) = Qcolor;
122 DEVICE_INFD (d) = DEVICE_OUTFD (d) = -1;
126 d->device_data = xnew_and_zero (struct mswindows_device);
127 hdc = CreateCompatibleDC (NULL);
129 DEVICE_MSWINDOWS_LOGPIXELSX(d) = GetDeviceCaps(hdc, LOGPIXELSX);
130 DEVICE_MSWINDOWS_LOGPIXELSY(d) = GetDeviceCaps(hdc, LOGPIXELSY);
131 DEVICE_MSWINDOWS_PLANES(d) = GetDeviceCaps(hdc, PLANES);
132 /* #### SIZEPALETTE only valid if RC_PALETTE bit set in RASTERCAPS,
133 what should we return for a non-palette-based device? */
134 DEVICE_MSWINDOWS_CELLS(d) = GetDeviceCaps(hdc, SIZEPALETTE);
135 DEVICE_MSWINDOWS_HORZRES(d) = GetDeviceCaps(hdc, HORZRES);
136 DEVICE_MSWINDOWS_VERTRES(d) = GetDeviceCaps(hdc, VERTRES);
137 DEVICE_MSWINDOWS_HORZSIZE(d) = GetDeviceCaps(hdc, HORZSIZE);
138 DEVICE_MSWINDOWS_VERTSIZE(d) = GetDeviceCaps(hdc, VERTSIZE);
139 DEVICE_MSWINDOWS_BITSPIXEL(d) = GetDeviceCaps(hdc, BITSPIXEL);
140 DEVICE_MSWINDOWS_FONTLIST (d) = mswindows_enumerate_fonts (hdc);
142 DEVICE_MSWINDOWS_HCDC(d) = hdc;
144 /* Register the main window class */
145 wc.cbSize = sizeof (WNDCLASSEX);
146 wc.style = CS_OWNDC; /* One DC per window */
147 wc.lpfnWndProc = (WNDPROC) mswindows_wnd_proc;
149 wc.cbWndExtra = MSWINDOWS_WINDOW_EXTRA_BYTES;
150 /* This must match whatever is passed to CreateWIndowEx, NULL is ok
153 wc.hIcon = LoadIcon (GetModuleHandle(NULL), XEMACS_CLASS);
154 wc.hCursor = LoadCursor (NULL, IDC_ARROW);
155 /* Background brush is only used during sizing, when XEmacs cannot
157 wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);
158 wc.lpszMenuName = NULL;
160 wc.lpszClassName = XEMACS_CLASS;
161 wc.hIconSm = (HICON) LoadImage (GetModuleHandle (NULL), XEMACS_CLASS,
162 IMAGE_ICON, 16, 16, 0);
163 RegisterClassEx (&wc);
167 /* Register the main window class */
168 wc.cbSize = sizeof (WNDCLASSEX);
169 wc.lpfnWndProc = (WNDPROC) mswindows_control_wnd_proc;
170 wc.lpszClassName = XEMACS_CONTROL_CLASS;
172 RegisterClassEx (&wc);
175 #if defined (HAVE_TOOLBARS) || defined (HAVE_WIDGETS)
176 InitCommonControls ();
181 mswindows_finish_init_device (struct device *d, Lisp_Object props)
183 /* Initialize DDE management library and our related globals. We execute a
184 * dde Open("file") by simulating a drop, so this depends on dnd support. */
185 #ifdef HAVE_DRAGNDROP
186 # if !(defined(__CYGWIN32__) || defined(__MINGW32__))
190 mswindows_dde_mlid = 0;
191 DdeInitialize (&mswindows_dde_mlid, (PFNCALLBACK)mswindows_dde_callback,
192 APPCMD_FILTERINITS|CBF_FAIL_SELFCONNECTIONS|CBF_FAIL_ADVISES|
193 CBF_FAIL_POKES|CBF_FAIL_REQUESTS|CBF_SKIP_ALLNOTIFICATIONS,
196 mswindows_dde_service = DdeCreateStringHandle (mswindows_dde_mlid,
198 mswindows_dde_topic_system = DdeCreateStringHandle (mswindows_dde_mlid,
200 mswindows_dde_item_open = DdeCreateStringHandle (mswindows_dde_mlid,
201 TEXT(MSWINDOWS_DDE_ITEM_OPEN), 0);
202 DdeNameService (mswindows_dde_mlid, mswindows_dde_service, 0L, DNS_REGISTER);
207 mswindows_delete_device (struct device *d)
209 #ifdef HAVE_DRAGNDROP
210 DdeNameService (mswindows_dde_mlid, 0L, 0L, DNS_UNREGISTER);
211 DdeFreeStringHandle (mswindows_dde_mlid, mswindows_dde_item_open);
212 DdeFreeStringHandle (mswindows_dde_mlid, mswindows_dde_topic_system);
213 DdeFreeStringHandle (mswindows_dde_mlid, mswindows_dde_service);
214 DdeUninitialize (mswindows_dde_mlid);
216 # if !(defined(__CYGWIN32__) || defined(__MINGW32__))
221 DeleteDC (DEVICE_MSWINDOWS_HCDC(d));
222 free (d->device_data);
226 msw_get_workspace_coords (RECT *rc)
228 SystemParametersInfo (SPI_GETWORKAREA, 0, rc, 0);
232 mswindows_mark_device (struct device *d)
234 mark_object (DEVICE_MSWINDOWS_FONTLIST (d));
238 mswindows_device_system_metrics (struct device *d,
239 enum device_metrics m)
244 return Fcons (make_int (DEVICE_MSWINDOWS_HORZRES(d)),
245 make_int (DEVICE_MSWINDOWS_VERTRES(d)));
248 return Fcons (make_int (DEVICE_MSWINDOWS_LOGPIXELSX(d)),
249 make_int (DEVICE_MSWINDOWS_LOGPIXELSY(d)));
251 case DM_size_device_mm:
252 return Fcons (make_int (DEVICE_MSWINDOWS_HORZSIZE(d)),
253 make_int (DEVICE_MSWINDOWS_VERTSIZE(d)));
255 case DM_num_bit_planes:
256 /* this is what X means by bitplanes therefore we ought to be
257 consistent. num planes is always 1 under mswindows and
259 return make_int (DEVICE_MSWINDOWS_BITSPIXEL(d));
261 case DM_num_color_cells:
262 return make_int (DEVICE_MSWINDOWS_CELLS(d));
266 #define FROB(met, fore, back) \
268 return build_syscolor_cons (fore, back);
270 FROB (color_default, COLOR_WINDOWTEXT, COLOR_WINDOW);
271 FROB (color_select, COLOR_HIGHLIGHTTEXT, COLOR_HIGHLIGHT);
272 FROB (color_balloon, COLOR_INFOTEXT, COLOR_INFOBK);
273 FROB (color_3d_face, COLOR_BTNTEXT, COLOR_BTNFACE);
274 FROB (color_3d_light, COLOR_3DHILIGHT, COLOR_3DLIGHT);
275 FROB (color_3d_dark, COLOR_3DDKSHADOW, COLOR_3DSHADOW);
276 FROB (color_menu, COLOR_MENUTEXT, COLOR_MENU);
277 FROB (color_menu_highlight, COLOR_HIGHLIGHTTEXT, COLOR_HIGHLIGHT);
278 FROB (color_menu_button, COLOR_MENUTEXT, COLOR_MENU);
279 FROB (color_menu_disabled, COLOR_GRAYTEXT, COLOR_MENU);
280 FROB (color_toolbar, COLOR_BTNTEXT, COLOR_BTNFACE);
281 FROB (color_scrollbar, COLOR_CAPTIONTEXT, COLOR_SCROLLBAR);
282 FROB (color_desktop, -1, COLOR_DESKTOP);
283 FROB (color_workspace, -1, COLOR_APPWORKSPACE);
287 #define FROB(met, index1, index2) \
289 return build_sysmetrics_cons (index1, index2);
291 FROB (size_cursor, SM_CXCURSOR, SM_CYCURSOR);
292 FROB (size_scrollbar, SM_CXVSCROLL, SM_CYHSCROLL);
293 FROB (size_menu, -1, SM_CYMENU);
294 FROB (size_icon, SM_CXICON, SM_CYICON);
295 FROB (size_icon_small, SM_CXSMICON, SM_CYSMICON);
298 case DM_size_workspace:
301 msw_get_workspace_coords (&rc);
302 return Fcons (make_int (rc.right - rc.left),
303 make_int (rc.bottom - rc.top));
306 case DM_offset_workspace:
309 msw_get_workspace_coords (&rc);
310 return Fcons (make_int (rc.left), make_int (rc.top));
314 case DM_size_toolbar:
315 case DM_size_toolbar_button:
316 case DM_size_toolbar_border:
320 #define FROB(met, index) \
322 return make_int (GetSystemMetrics (index));
324 FROB (mouse_buttons, SM_CMOUSEBUTTONS);
325 FROB (swap_buttons, SM_SWAPBUTTON);
326 FROB (show_sounds, SM_SHOWSOUNDS);
327 FROB (slow_device, SM_SLOWMACHINE);
328 FROB (security, SM_SECURE);
333 /* Do not know such property */
338 mswindows_device_implementation_flags (void)
340 return XDEVIMPF_PIXEL_GEOMETRY;
344 /************************************************************************/
345 /* printer methods */
346 /************************************************************************/
349 signal_open_printer_error (struct device *d)
351 signal_simple_error ("Failed to open printer", DEVICE_CONNECTION (d));
355 msprinter_init_device (struct device *d, Lisp_Object props)
359 DEVICE_INFD (d) = DEVICE_OUTFD (d) = -1;
361 CHECK_STRING (DEVICE_CONNECTION (d));
363 TO_EXTERNAL_FORMAT (LISP_STRING, DEVICE_CONNECTION (d),
364 C_STRING_ALLOCA, printer_name,
367 d->device_data = xnew_and_zero (struct msprinter_device);
369 DEVICE_MSPRINTER_NAME(d) = xstrdup (printer_name);
371 if (!OpenPrinter (printer_name, &DEVICE_MSPRINTER_HPRINTER (d), NULL))
373 DEVICE_MSPRINTER_HPRINTER (d) = NULL;
374 signal_open_printer_error (d);
377 DEVICE_MSPRINTER_HDC (d) = CreateDC ("WINSPOOL", printer_name,
379 if (DEVICE_MSPRINTER_HDC (d) == NULL)
380 signal_open_printer_error (d);
382 DEVICE_MSPRINTER_HCDC(d) =
383 CreateCompatibleDC (DEVICE_MSPRINTER_HDC (d));
385 /* Determinie DEVMODE size and store the default DEVMODE */
386 DEVICE_MSPRINTER_DEVMODE_SIZE(d) =
387 DocumentProperties (NULL, DEVICE_MSPRINTER_HPRINTER(d),
388 printer_name, NULL, NULL, 0);
389 if (DEVICE_MSPRINTER_DEVMODE_SIZE(d) <= 0)
390 signal_open_printer_error (d);
392 DEVICE_MSPRINTER_DEVMODE(d) =
393 (DEVMODE*) xmalloc (DEVICE_MSPRINTER_DEVMODE_SIZE(d));
394 DocumentProperties (NULL, DEVICE_MSPRINTER_HPRINTER(d),
395 printer_name, DEVICE_MSPRINTER_DEVMODE(d),
396 NULL, DM_OUT_BUFFER);
398 /* We do not use printer fon list as we do with the display
399 device. Rather, we allow GDI to pick the closest match to the
401 DEVICE_MSPRINTER_FONTLIST (d) = Qnil;
403 DEVICE_CLASS (d) = (GetDeviceCaps (DEVICE_MSPRINTER_HDC (d), BITSPIXEL)
404 * GetDeviceCaps (DEVICE_MSPRINTER_HDC (d), PLANES)
405 > 1) ? Qcolor : Qmono;
409 msprinter_device_system_metrics (struct device *d,
410 enum device_metrics m)
414 /* Device sizes - pixel and mm */
415 #define FROB(met, index1, index2) \
417 return build_devicecaps_cons \
418 (DEVICE_MSPRINTER_HDC(d), index1, index2);
420 FROB (size_device, PHYSICALWIDTH, PHYSICALHEIGHT);
421 FROB (size_device_mm, HORZSIZE, VERTSIZE);
422 FROB (size_workspace, HORZRES, VERTRES);
423 FROB (offset_workspace, PHYSICALOFFSETX, PHYSICALOFFSETY);
424 FROB (device_dpi, LOGPIXELSX, LOGPIXELSY);
427 case DM_num_bit_planes:
428 /* this is what X means by bitplanes therefore we ought to be
429 consistent. num planes is always 1 under mswindows and
431 return make_int (GetDeviceCaps (DEVICE_MSPRINTER_HDC(d), BITSPIXEL));
433 case DM_num_color_cells: /* Prnters are non-palette devices */
434 case DM_slow_device: /* Animation would be a really bad idea */
435 case DM_security: /* Not provided by windows */
439 /* Do not know such property */
444 msprinter_delete_device (struct device *d)
448 if (DEVICE_MSPRINTER_HPRINTER (d))
449 ClosePrinter (DEVICE_MSPRINTER_HPRINTER (d));
450 if (DEVICE_MSPRINTER_HDC (d))
451 DeleteDC (DEVICE_MSPRINTER_HDC (d));
452 if (DEVICE_MSPRINTER_HCDC (d))
453 DeleteDC (DEVICE_MSPRINTER_HCDC (d));
454 if (DEVICE_MSPRINTER_NAME (d))
455 free (DEVICE_MSPRINTER_NAME (d));
456 if (DEVICE_MSPRINTER_DEVMODE (d))
457 free (DEVICE_MSPRINTER_DEVMODE (d));
458 if (DEVICE_MSPRINTER_DEVMODE_MIRROR (d))
459 free (DEVICE_MSPRINTER_DEVMODE_MIRROR (d));
461 free (d->device_data);
466 msprinter_mark_device (struct device *d)
468 mark_object (DEVICE_MSPRINTER_FONTLIST (d));
472 msprinter_device_implementation_flags (void)
474 return ( XDEVIMPF_PIXEL_GEOMETRY
475 | XDEVIMPF_IS_A_PRINTER
476 | XDEVIMPF_NO_AUTO_REDISPLAY
477 | XDEVIMPF_FRAMELESS_OK );
481 /************************************************************************/
482 /* printer external functions */
483 /************************************************************************/
486 * Return a copy of default DEVMODE. The copy returned is in
487 * a static buffer which will be overwritten by next call.
490 msprinter_get_devmode_copy (struct device *d)
492 assert (DEVICE_MSPRINTER_P (d));
494 if (DEVICE_MSPRINTER_DEVMODE_MIRROR(d) == NULL)
495 DEVICE_MSPRINTER_DEVMODE_MIRROR(d) =
496 (DEVMODE*) xmalloc (DEVICE_MSPRINTER_DEVMODE_SIZE(d));
498 memcpy (DEVICE_MSPRINTER_DEVMODE_MIRROR(d),
499 DEVICE_MSPRINTER_DEVMODE(d),
500 DEVICE_MSPRINTER_DEVMODE_SIZE(d));
502 return DEVICE_MSPRINTER_DEVMODE_MIRROR(d);
506 * Apply settings from the DEVMODE. The settings are considered
507 * incremental to the default DEVMODE, so that changes in the
508 * passed structure supercede parameters of the printer.
510 * The passed structure is overwritten by the fuction call;
511 * complete printer settings are returned.
514 msprinter_apply_devmode (struct device *d, DEVMODE *devmode)
516 assert (DEVICE_MSPRINTER_P (d));
518 DocumentProperties (NULL,
519 DEVICE_MSPRINTER_HPRINTER(d),
520 DEVICE_MSPRINTER_NAME(d),
522 DM_IN_BUFFER | DM_OUT_BUFFER);
524 /* #### ResetDC fails sometimes, Bill only know s why.
525 The solution below looks more like a workaround to me,
526 although it might be fine. --kkm */
527 if (ResetDC (DEVICE_MSPRINTER_HDC (d), devmode) == NULL)
529 DeleteDC (DEVICE_MSPRINTER_HDC (d));
530 DEVICE_MSPRINTER_HDC (d) =
531 CreateDC ("WINSPOOL", DEVICE_MSPRINTER_NAME(d), NULL, devmode);
536 /************************************************************************/
538 /************************************************************************/
541 syms_of_device_mswindows (void)
543 defsymbol (&Qinit_pre_mswindows_win, "init-pre-mswindows-win");
544 defsymbol (&Qinit_post_mswindows_win, "init-post-mswindows-win");
548 console_type_create_device_mswindows (void)
550 CONSOLE_HAS_METHOD (mswindows, init_device);
551 CONSOLE_HAS_METHOD (mswindows, finish_init_device);
552 CONSOLE_HAS_METHOD (mswindows, mark_device);
553 CONSOLE_HAS_METHOD (mswindows, delete_device);
554 CONSOLE_HAS_METHOD (mswindows, device_system_metrics);
555 CONSOLE_HAS_METHOD (mswindows, device_implementation_flags);
557 CONSOLE_HAS_METHOD (msprinter, init_device);
558 CONSOLE_HAS_METHOD (msprinter, mark_device);
559 CONSOLE_HAS_METHOD (msprinter, delete_device);
560 CONSOLE_HAS_METHOD (msprinter, device_system_metrics);
561 CONSOLE_HAS_METHOD (msprinter, device_implementation_flags);
566 vars_of_device_mswindows (void)
568 DEFVAR_LISP ("mswindows-downcase-file-names", &Vmswindows_downcase_file_names /*
569 Non-nil means convert all-upper case file names to lower case.
570 This applies when performing completions and file name expansion.
572 Vmswindows_downcase_file_names = Qnil;
574 DEFVAR_LISP ("mswindows-get-true-file-attributes", &Vmswindows_get_true_file_attributes /*
575 Non-nil means determine accurate link count in file-attributes.
576 This option slows down file-attributes noticeably, so is disabled by
577 default. Note that it is only useful for files on NTFS volumes,
578 where hard links are supported.
580 Vmswindows_get_true_file_attributes = Qnil;