1 /* Implements elisp-programmable dialog boxes -- MS Windows interface.
2 Copyright (C) 1998 Kirill M. Katsnelson <kkm@kis.ru>
3 Copyright (C) 2000 Ben Wing.
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. */
25 Initially written by kkm, May 1998
32 #include "console-msw.h"
40 Lisp_Object Qdialog_box_error;
42 static Lisp_Object Q_initial_directory;
43 static Lisp_Object Q_initial_filename;
44 static Lisp_Object Q_filter_list;
45 static Lisp_Object Q_title;
46 static Lisp_Object Q_allow_multi_select;
47 static Lisp_Object Q_create_prompt_on_nonexistent;
48 static Lisp_Object Q_overwrite_prompt;
49 static Lisp_Object Q_file_must_exist;
50 static Lisp_Object Q_no_network_button;
51 static Lisp_Object Q_no_read_only_return;
53 /* List containing all dialog data structures of currently popped up
55 static Lisp_Object Vdialog_data_list;
57 /* List of popup frames wanting keyboard traversal handled */
58 static Lisp_Object Vpopup_frame_list;
60 Lisp_Object Vdefault_file_dialog_filter_alist;
62 /* DLUs per character metrics */
63 #define X_DLU_PER_CHAR 4
64 #define Y_DLU_PER_CHAR 8
69 All buttons have height of 15 DLU. The minimum width for a button is 32 DLU,
70 but it can be expanded to accommodate its text, so the width is calculated as
71 8 DLU per button plus 4 DLU per character.
72 max (32, 6 * text_length). The factor of six is rather empirical, but it
73 works better than 8 which comes from the definition of a DLU. Buttons are
74 spaced with 6 DLU gap. Minimum distance from the button to the left or right
75 dialog edges is 6 DLU, and the distance between the dialog bottom edge and
79 #define X_MIN_BUTTON 32
80 #define X_BUTTON_MARGIN 8
82 #define X_BUTTON_SPACING 6
83 #define X_BUTTON_FROM_EDGE 6
84 #define Y_BUTTON_FROM_EDGE 7
89 Text distance from left and right edges is the same as for buttons, and the
90 top margin is 11 DLU. The static control has height of 2 DLU per control
91 plus 8 DLU per each line of text. Distance between the bottom edge of the
92 control and the button row is 15 DLU. Minimum width of the static control
93 is 100 DLU, thus giving minimum dialog weight of 112 DLU. Maximum width is
94 300 DLU, and, if the text is wider than that, the text is wrapped on the
95 next line. Each character in the text is considered 4 DLU wide.
98 #define X_MIN_TEXT 100
99 #define X_AVE_TEXT 200
100 #define X_MAX_TEXT 300
101 #define X_TEXT_FROM_EDGE X_BUTTON_FROM_EDGE
102 #define Y_TEXT_FROM_EDGE 11
103 #define Y_TEXT_MARGIN 2
104 #define Y_TEXT_FROM_BUTTON 15
106 #define X_MIN_TEXT_CHAR (X_MIN_TEXT / X_DLU_PER_CHAR)
107 #define X_AVE_TEXT_CHAR (X_AVE_TEXT / X_DLU_PER_CHAR)
108 #define X_MAX_TEXT_CHAR (X_MAX_TEXT / X_DLU_PER_CHAR)
113 First we calculate the minimum width of the button row, excluding "from
114 edge" distances. Note that the static control text can be narrower than
115 X_AVE_TEXT only if both text and button row are narrower than that (so,
116 even if text *can* be wrapped into 2 rows narrower than ave width, it is not
117 done). Let WBR denote the width of the button row.
119 Next, the width of the static field is determined.
120 First, if all lines of text fit into max (WBR, X_MAX_TEXT), the width of the
121 control is the same as the width of the longest line.
122 Second, if all lines of text are narrower than X_MIN_TEXT, then width of
123 the control is set to X_MIN_TEXT.
124 Otherwise, width is set to max(WBR, X_AVE_TEXT). In this case, line wrapping will
127 If width of the text control is larger than that of the button row, then the
128 latter is centered across the dialog, by giving it extra edge
129 margins. Otherwise, minimal margins are given to the button row.
132 #define ID_ITEM_BIAS 32
135 mswindows_register_popup_frame (Lisp_Object frame)
137 Vpopup_frame_list = Fcons (frame, Vpopup_frame_list);
141 mswindows_unregister_popup_frame (Lisp_Object frame)
143 Vpopup_frame_list = delq_no_quit (frame, Vpopup_frame_list);
146 /* Dispatch message to any dialog boxes. Return non-zero if dispatched. */
148 mswindows_is_dialog_msg (MSG *msg)
150 LIST_LOOP_2 (data, Vdialog_data_list)
152 if (IsDialogMessage (XMSWINDOWS_DIALOG_ID (data)->hwnd, msg))
157 LIST_LOOP_2 (popup, Vpopup_frame_list)
159 HWND hwnd = FRAME_MSWINDOWS_HANDLE (XFRAME (popup));
160 if (IsDialogMessage (hwnd, msg))
168 mark_mswindows_dialog_id (Lisp_Object obj)
170 struct mswindows_dialog_id *data = XMSWINDOWS_DIALOG_ID (obj);
171 mark_object (data->frame);
172 return data->callbacks;
175 DEFINE_LRECORD_IMPLEMENTATION ("mswindows-dialog-id", mswindows_dialog_id,
176 mark_mswindows_dialog_id, 0, 0, 0, 0, 0,
177 struct mswindows_dialog_id);
179 /* Dialog procedure */
181 dialog_proc (HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param)
186 SetWindowLong (hwnd, DWL_USER, l_param);
192 VOID_TO_LISP (data, GetWindowLong (hwnd, DWL_USER));
193 Vdialog_data_list = delq_no_quit (data, Vdialog_data_list);
199 Lisp_Object fn, arg, data;
200 struct mswindows_dialog_id *did;
202 VOID_TO_LISP (data, GetWindowLong (hwnd, DWL_USER));
203 did = XMSWINDOWS_DIALOG_ID (data);
204 if (w_param != IDCANCEL) /* user pressed escape */
206 assert (w_param >= ID_ITEM_BIAS
208 < XVECTOR_LENGTH (did->callbacks) + ID_ITEM_BIAS);
210 get_gui_callback (XVECTOR_DATA (did->callbacks)
211 [w_param - ID_ITEM_BIAS],
213 mswindows_enqueue_misc_user_event (did->frame, fn, arg);
216 mswindows_enqueue_misc_user_event (did->frame, Qrun_hooks,
217 Qmenu_no_selection_hook);
218 /* #### need to error-protect! will do so when i merge in
220 va_run_hook_with_args (Qdelete_dialog_box_hook, 1, data);
222 DestroyWindow (hwnd);
232 /* Helper function which converts the supplied string STRING into Unicode and
233 pushes it at the end of DYNARR */
235 push_lisp_string_as_unicode (unsigned_char_dynarr* dynarr, Lisp_Object string)
237 Extbyte *mbcs_string;
238 Charcount length = XSTRING_CHAR_LENGTH (string);
241 TO_EXTERNAL_FORMAT (LISP_STRING, string,
242 C_STRING_ALLOCA, mbcs_string,
244 uni_string = alloca_array (WCHAR, length + 1);
245 length = MultiByteToWideChar (CP_ACP, 0, mbcs_string, -1,
246 uni_string, sizeof(WCHAR) * (length + 1));
247 Dynarr_add_many (dynarr, uni_string, sizeof(WCHAR) * length);
250 /* Helper function which converts the supplied string STRING into Unicode and
251 pushes it at the end of DYNARR */
253 push_bufbyte_string_as_unicode (unsigned_char_dynarr* dynarr, Bufbyte *string,
256 Extbyte *mbcs_string;
257 Charcount length = bytecount_to_charcount (string, len);
260 TO_EXTERNAL_FORMAT (C_STRING, string,
261 C_STRING_ALLOCA, mbcs_string,
263 uni_string = alloca_array (WCHAR, length + 1);
264 length = MultiByteToWideChar (CP_ACP, 0, mbcs_string, -1,
265 uni_string, sizeof(WCHAR) * (length + 1));
266 Dynarr_add_many (dynarr, uni_string, sizeof(WCHAR) * length);
269 /* Given button TEXT, return button width in DLU */
271 button_width (Lisp_Object text)
273 unsigned int width = X_DLU_PER_CHAR * XSTRING_CHAR_LENGTH (text);
274 return max (X_MIN_BUTTON, width);
277 /* Unwind protection routine frees a dynarr opaqued into arg */
279 free_dynarr_opaque_ptr (Lisp_Object arg)
281 Dynarr_free (get_opaque_ptr (arg));
286 #define ALIGN_TEMPLATE \
288 unsigned int slippage = Dynarr_length (template) & 3; \
290 Dynarr_add_many (template, &zeroes, slippage); \
297 } common_dialog_errors[] =
299 { CDERR_DIALOGFAILURE, "CDERR_DIALOGFAILURE" },
300 { CDERR_FINDRESFAILURE, "CDERR_FINDRESFAILURE" },
301 { CDERR_INITIALIZATION, "CDERR_INITIALIZATION" },
302 { CDERR_LOADRESFAILURE, "CDERR_LOADRESFAILURE" },
303 { CDERR_LOADSTRFAILURE, "CDERR_LOADSTRFAILURE" },
304 { CDERR_LOCKRESFAILURE, "CDERR_LOCKRESFAILURE" },
305 { CDERR_MEMALLOCFAILURE, "CDERR_MEMALLOCFAILURE" },
306 { CDERR_MEMLOCKFAILURE, "CDERR_MEMLOCKFAILURE" },
307 { CDERR_NOHINSTANCE, "CDERR_NOHINSTANCE" },
308 { CDERR_NOHOOK, "CDERR_NOHOOK" },
309 { CDERR_NOTEMPLATE, "CDERR_NOTEMPLATE" },
310 { CDERR_REGISTERMSGFAIL, "CDERR_REGISTERMSGFAIL" },
311 { CDERR_STRUCTSIZE, "CDERR_STRUCTSIZE" },
312 { PDERR_CREATEICFAILURE, "PDERR_CREATEICFAILURE" },
313 { PDERR_DEFAULTDIFFERENT, "PDERR_DEFAULTDIFFERENT" },
314 { PDERR_DNDMMISMATCH, "PDERR_DNDMMISMATCH" },
315 { PDERR_GETDEVMODEFAIL, "PDERR_GETDEVMODEFAIL" },
316 { PDERR_INITFAILURE, "PDERR_INITFAILURE" },
317 { PDERR_LOADDRVFAILURE, "PDERR_LOADDRVFAILURE" },
318 { PDERR_NODEFAULTPRN, "PDERR_NODEFAULTPRN" },
319 { PDERR_NODEVICES, "PDERR_NODEVICES" },
320 { PDERR_PARSEFAILURE, "PDERR_PARSEFAILURE" },
321 { PDERR_PRINTERNOTFOUND, "PDERR_PRINTERNOTFOUND" },
322 { PDERR_RETDEFFAILURE, "PDERR_RETDEFFAILURE" },
323 { PDERR_SETUPFAILURE, "PDERR_SETUPFAILURE" },
324 { CFERR_MAXLESSTHANMIN, "CFERR_MAXLESSTHANMIN" },
325 { CFERR_NOFONTS, "CFERR_NOFONTS" },
326 { FNERR_BUFFERTOOSMALL, "FNERR_BUFFERTOOSMALL" },
327 { FNERR_INVALIDFILENAME, "FNERR_INVALIDFILENAME" },
328 { FNERR_SUBCLASSFAILURE, "FNERR_SUBCLASSFAILURE" },
329 { FRERR_BUFFERLENGTHZERO, "FRERR_BUFFERLENGTHZERO" },
333 handle_file_dialog_box (struct frame *f, Lisp_Object keys)
339 ofn.lStructSize = sizeof (ofn);
340 ofn.hwndOwner = FRAME_MSWINDOWS_HANDLE (f);
341 ofn.lpstrFile = fnbuf;
342 ofn.nMaxFile = sizeof (fnbuf) / XETCHAR_SIZE;
343 xetcscpy (fnbuf, XETEXT (""));
345 LOCAL_FILE_FORMAT_TO_TSTR (Fexpand_file_name (build_string (""), Qnil),
346 ofn.lpstrInitialDir);
349 EXTERNAL_PROPERTY_LIST_LOOP_3 (key, value, keys)
351 if (EQ (key, Q_initial_filename))
355 CHECK_STRING (value);
356 LOCAL_FILE_FORMAT_TO_TSTR (value, fnout);
357 xetcscpy (fnbuf, fnout);
359 else if (EQ (key, Q_title))
361 CHECK_STRING (value);
362 LISP_STRING_TO_EXTERNAL (value, ofn.lpstrTitle, Qmswindows_tstr);
364 else if (EQ (key, Q_initial_directory))
365 LOCAL_FILE_FORMAT_TO_TSTR (Fexpand_file_name (value, Qnil),
366 ofn.lpstrInitialDir);
367 else if (EQ (key, Q_file_must_exist))
370 ofn.Flags |= OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
372 ofn.Flags &= ~(OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST);
375 syntax_error ("Unrecognized file-dialog keyword", key);
379 if (!GetOpenFileName (&ofn))
381 DWORD err = CommDlgExtendedError ();
391 for (i = 0; i < countof (common_dialog_errors); i++)
393 if (common_dialog_errors[i].errmess == err)
394 signal_type_error (Qdialog_box_error,
395 "Creating file-dialog-box",
397 (common_dialog_errors[i].errname));
400 signal_type_error (Qdialog_box_error,
401 "Unknown common dialog box error???",
406 return tstr_to_local_file_format (ofn.lpstrFile);
410 handle_question_dialog_box (struct frame *f, Lisp_Object keys)
412 Lisp_Object_dynarr *dialog_items = Dynarr_new (Lisp_Object);
413 unsigned_char_dynarr *template = Dynarr_new (unsigned_char);
414 unsigned int button_row_width = 0;
415 unsigned int text_width, text_height;
416 Lisp_Object question = Qnil, title = Qnil;
418 int unbind_count = specpdl_depth ();
419 record_unwind_protect (free_dynarr_opaque_ptr,
420 make_opaque_ptr (dialog_items));
421 record_unwind_protect (free_dynarr_opaque_ptr,
422 make_opaque_ptr (template));
424 /* A big NO NEED to GCPRO gui_items stored in the array: they are just
425 pointers into KEYS list, which is GC-protected by the caller */
428 EXTERNAL_PROPERTY_LIST_LOOP_3 (key, value, keys)
430 if (EQ (key, Q_question))
432 CHECK_STRING (value);
435 else if (EQ (key, Q_title))
437 CHECK_STRING (value);
440 else if (EQ (key, Q_buttons))
442 Lisp_Object item_cons;
444 /* Parse each item in the dialog into gui_item structs,
445 and stuff a dynarr of these. Calculate button row width
447 EXTERNAL_LIST_LOOP (item_cons, value)
449 if (!NILP (XCAR (item_cons)))
452 gui_parse_item_keywords (XCAR (item_cons));
453 Dynarr_add (dialog_items, gitem);
454 button_row_width += button_width (XGUI_ITEM (gitem)->name)
459 button_row_width -= X_BUTTON_MARGIN;
462 syntax_error ("Unrecognized question-dialog keyword", key);
466 if (Dynarr_length (dialog_items) == 0)
467 syntax_error ("Dialog descriptor provides no buttons", keys);
470 syntax_error ("Dialog descriptor provides no question", keys);
472 /* Determine the final width layout */
474 Bufbyte *p = XSTRING_DATA (question);
475 Charcount string_max = 0, this_length = 0;
478 Emchar ch = charptr_emchar (p);
481 if (ch == (Emchar)'\n' || ch == (Emchar)'\0')
483 string_max = max (this_length, string_max);
489 if (ch == (Emchar)'\0')
493 if (string_max * X_DLU_PER_CHAR > max (X_MAX_TEXT, button_row_width))
494 text_width = X_AVE_TEXT;
495 else if (string_max * X_DLU_PER_CHAR < X_MIN_TEXT)
496 text_width = X_MIN_TEXT;
498 text_width = string_max * X_DLU_PER_CHAR;
499 text_width = max (text_width, button_row_width);
502 /* Now calculate the height for the text control */
504 Bufbyte *p = XSTRING_DATA (question);
505 Charcount break_at = text_width / X_DLU_PER_CHAR;
506 Charcount char_pos = 0;
510 while ((ch = charptr_emchar (p)) != (Emchar) '\0')
513 char_pos += ch != (Emchar) '\n';
514 if (ch == (Emchar) '\n' || char_pos == break_at)
520 text_height = Y_TEXT_MARGIN + Y_DLU_PER_CHAR * num_lines;
523 /* Ok, now we are ready to stuff the dialog template and lay out controls */
526 DLGITEMTEMPLATE item_tem;
528 const unsigned int zeroes = 0;
529 const unsigned int ones = 0xFFFFFFFF;
530 const WORD static_class_id = 0x0082;
531 const WORD button_class_id = 0x0080;
533 /* Create and stuff in DLGTEMPLATE header */
534 dlg_tem.style = (DS_CENTER | DS_MODALFRAME | DS_SETFONT
535 | WS_CAPTION | WS_POPUP | WS_VISIBLE);
536 dlg_tem.dwExtendedStyle = 0;
537 dlg_tem.cdit = Dynarr_length (dialog_items) + 1;
540 dlg_tem.cx = text_width + 2 * X_TEXT_FROM_EDGE;
541 dlg_tem.cy = (Y_TEXT_FROM_EDGE + text_height + Y_TEXT_FROM_BUTTON
542 + Y_BUTTON + Y_BUTTON_FROM_EDGE);
543 Dynarr_add_many (template, &dlg_tem, sizeof (dlg_tem));
545 /* We want no menu and standard class */
546 Dynarr_add_many (template, &zeroes, 4);
548 /* And the third is the dialog title. "XEmacs" unless one is supplied.
549 Note that the string must be in Unicode. */
551 Dynarr_add_many (template, L"XEmacs", 14);
553 push_lisp_string_as_unicode (template, title);
555 /* We want standard dialog font */
556 Dynarr_add_many (template, L"\x08MS Shell Dlg", 28);
558 /* Next add text control. */
559 item_tem.style = WS_CHILD | WS_VISIBLE | SS_LEFT | SS_NOPREFIX;
560 item_tem.dwExtendedStyle = 0;
561 item_tem.x = X_TEXT_FROM_EDGE;
562 item_tem.y = Y_TEXT_FROM_EDGE;
563 item_tem.cx = text_width;
564 item_tem.cy = text_height;
565 item_tem.id = 0xFFFF;
568 Dynarr_add_many (template, &item_tem, sizeof (item_tem));
570 /* Right after class id follows */
571 Dynarr_add_many (template, &ones, 2);
572 Dynarr_add_many (template, &static_class_id, sizeof (static_class_id));
574 /* Next thing to add is control text, as Unicode string */
575 push_lisp_string_as_unicode (template, question);
577 /* Specify 0 length creation data */
578 Dynarr_add_many (template, &zeroes, 2);
580 /* Now it's the button time */
581 item_tem.y = Y_TEXT_FROM_EDGE + text_height + Y_TEXT_FROM_BUTTON;
582 item_tem.x = X_BUTTON_FROM_EDGE + (button_row_width < text_width
583 ? (text_width - button_row_width) / 2
585 item_tem.cy = Y_BUTTON;
586 item_tem.dwExtendedStyle = 0;
588 for (i = 0; i < Dynarr_length (dialog_items); ++i)
590 Lisp_Object* gui_item = Dynarr_atp (dialog_items, i);
591 Lisp_Gui_Item *pgui_item = XGUI_ITEM (*gui_item);
593 item_tem.style = (WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON
594 | (gui_item_active_p (*gui_item) ? 0 : WS_DISABLED));
595 item_tem.cx = button_width (pgui_item->name);
596 /* Item ids are indices into dialog_items plus offset, to avoid having
597 items by reserved ids (IDOK, IDCANCEL) */
598 item_tem.id = i + ID_ITEM_BIAS;
601 Dynarr_add_many (template, &item_tem, sizeof (item_tem));
603 /* Right after 0xFFFF and class id atom follows */
604 Dynarr_add_many (template, &ones, 2);
605 Dynarr_add_many (template, &button_class_id, sizeof (button_class_id));
607 /* Next thing to add is control text, as Unicode string */
609 Lisp_Object ctext = pgui_item->name;
611 Bufbyte *trans = (Bufbyte *) alloca (2 * XSTRING_LENGTH (ctext) + 3);
614 memcpy (trans, XSTRING_DATA (ctext), XSTRING_LENGTH (ctext) + 1);
616 mswindows_translate_menu_or_dialog_item (trans,
617 XSTRING_LENGTH (ctext),
618 2 * XSTRING_LENGTH (ctext) + 3,
621 push_bufbyte_string_as_unicode (template, trans, translen);
624 /* Specify 0 length creation data. */
625 Dynarr_add_many (template, &zeroes, 2);
627 item_tem.x += item_tem.cx + X_BUTTON_SPACING;
631 /* Now the Windows dialog structure is ready. We need to prepare a
632 data structure for the new dialog, which will contain callbacks
633 and the frame for these callbacks. This structure has to be
634 GC-protected and thus it is put into a statically protected
637 Lisp_Object dialog_data;
639 struct mswindows_dialog_id *did =
640 alloc_lcrecord_type (struct mswindows_dialog_id,
641 &lrecord_mswindows_dialog_id);
643 XSETMSWINDOWS_DIALOG_ID (dialog_data, did);
645 did->frame = wrap_frame (f);
646 did->callbacks = make_vector (Dynarr_length (dialog_items), Qunbound);
647 for (i = 0; i < Dynarr_length (dialog_items); i++)
648 XVECTOR_DATA (did->callbacks) [i] =
649 XGUI_ITEM (*Dynarr_atp (dialog_items, i))->callback;
651 /* Woof! Everything is ready. Pop pop pop in now! */
653 CreateDialogIndirectParam (NULL,
654 (LPDLGTEMPLATE) Dynarr_atp (template, 0),
655 FRAME_MSWINDOWS_HANDLE (f), dialog_proc,
656 (LPARAM) LISP_TO_VOID (dialog_data));
658 /* Something went wrong creating the dialog */
659 signal_type_error (Qdialog_box_error, "Creating dialog", keys);
661 Vdialog_data_list = Fcons (dialog_data, Vdialog_data_list);
663 /* Cease protection and free dynarrays */
664 unbind_to (unbind_count, Qnil);
670 mswindows_make_dialog_box_internal (struct frame* f, Lisp_Object type,
673 if (EQ (type, Qfile))
674 return handle_file_dialog_box (f, keys);
675 else if (EQ (type, Qquestion))
676 return handle_question_dialog_box (f, keys);
677 else if (EQ (type, Qprint))
678 return mswindows_handle_print_dialog_box (f, keys);
679 else if (EQ (type, Qpage_setup))
680 return mswindows_handle_page_setup_dialog_box (f, keys);
681 else if (EQ (type, Qprint_setup))
682 return mswindows_handle_print_setup_dialog_box (f, keys);
684 signal_type_error (Qunimplemented, "Dialog box type", type);
689 console_type_create_dialog_mswindows (void)
691 CONSOLE_HAS_METHOD (mswindows, make_dialog_box_internal);
695 syms_of_dialog_mswindows (void)
697 INIT_LRECORD_IMPLEMENTATION (mswindows_dialog_id);
699 DEFKEYWORD (Q_initial_directory);
700 DEFKEYWORD (Q_initial_filename);
701 DEFKEYWORD (Q_filter_list);
702 DEFKEYWORD (Q_title);
703 DEFKEYWORD (Q_allow_multi_select);
704 DEFKEYWORD (Q_create_prompt_on_nonexistent);
705 DEFKEYWORD (Q_overwrite_prompt);
706 DEFKEYWORD (Q_file_must_exist);
707 DEFKEYWORD (Q_no_network_button);
708 DEFKEYWORD (Q_no_read_only_return);
711 DEFERROR_STANDARD (Qdialog_box_error, Qinvalid_operation);
715 vars_of_dialog_mswindows (void)
717 Vpopup_frame_list = Qnil;
718 staticpro (&Vpopup_frame_list);
720 Vdialog_data_list = Qnil;
721 staticpro (&Vdialog_data_list);
723 DEFVAR_LISP ("default-file-dialog-filter-alist",
724 &Vdefault_file_dialog_filter_alist /*
726 Vdefault_file_dialog_filter_alist =
727 list5 (Fcons (build_string ("Text Files"), build_string ("*.txt")),
728 Fcons (build_string ("C Files"), build_string ("*.c;*.h")),
729 Fcons (build_string ("Elisp Files"), build_string ("*.el")),
730 Fcons (build_string ("HTML Files"), build_string ("*.html;*.html")),
731 Fcons (build_string ("All Files"), build_string ("*.*")));