(U+6215): Apply new conventions for glyph granularity.
[chise/xemacs-chise.git.1] / src / device-msw.c
index da2727c..62536b7 100644 (file)
@@ -26,6 +26,7 @@ Boston, MA 02111-1307, USA.  */
    Original authors: Jamie Zawinski and the FSF
    Rewritten by Ben Wing and Chuck Thompson.
    Rewritten for mswindows by Jonathan Harris, November 1997 for 21.0.
+   Print support added by Kirill Katsnelson, July 2000.
 */
 
 
@@ -49,6 +50,7 @@ Boston, MA 02111-1307, USA.  */
 /* win32 DDE management library globals */
 #ifdef HAVE_DRAGNDROP
 DWORD mswindows_dde_mlid;
+int mswindows_dde_enable;
 HSZ mswindows_dde_service;
 HSZ mswindows_dde_topic_system;
 HSZ mswindows_dde_item_open;
@@ -66,6 +68,11 @@ Lisp_Object Vmswindows_get_true_file_attributes;
 Lisp_Object Qinit_pre_mswindows_win, Qinit_post_mswindows_win;
 Lisp_Object Qdevmodep;
 
+static Lisp_Object Q_allow_selection;
+static Lisp_Object Q_allow_pages;
+static Lisp_Object Q_selected_page_button;
+static Lisp_Object Qselected_page_button;
+
 static Lisp_Object allocate_devmode (DEVMODE* src_devmode, int do_copy,
                                     char* src_name, struct device *d);
 
@@ -173,17 +180,18 @@ mswindows_init_device (struct device *d, Lisp_Object props)
 #endif
 }
 
+#ifdef HAVE_DRAGNDROP
 static void
-mswindows_finish_init_device (struct device *d, Lisp_Object props)
+mswindows_init_dde ()
 {
   /* Initialize DDE management library and our related globals. We execute a
    * dde Open("file") by simulating a drop, so this depends on dnd support. */
-#ifdef HAVE_DRAGNDROP
 # if !(defined(CYGWIN) || defined(MINGW))
   CoInitialize (NULL);
 # endif
 
   mswindows_dde_mlid = 0;
+  mswindows_dde_enable = 0;
   DdeInitialize (&mswindows_dde_mlid, (PFNCALLBACK)mswindows_dde_callback,
                 APPCMD_FILTERINITS|CBF_FAIL_SELFCONNECTIONS|CBF_FAIL_ADVISES|
                 CBF_FAIL_POKES|CBF_FAIL_REQUESTS|CBF_SKIP_ALLNOTIFICATIONS,
@@ -196,6 +204,27 @@ mswindows_finish_init_device (struct device *d, Lisp_Object props)
   mswindows_dde_item_open = DdeCreateStringHandle (mswindows_dde_mlid,
                                                   TEXT(MSWINDOWS_DDE_ITEM_OPEN), 0);
   DdeNameService (mswindows_dde_mlid, mswindows_dde_service, 0L, DNS_REGISTER);
+}
+#endif
+
+void 
+init_mswindows_very_early()
+{
+#ifdef HAVE_DRAGNDROP
+  /* Initializing dde when the device is created is too late - the
+     client will give up waiting.  Instead we initialize here and tell
+     the client we're too busy until the rest of initialization has
+     happened. */
+  mswindows_init_dde();
+#endif
+}
+
+static void
+mswindows_finish_init_device (struct device *d, Lisp_Object props)
+{
+#ifdef HAVE_DRAGNDROP
+  /* Tell pending clients we are ready. */
+  mswindows_dde_enable = 1;
 #endif
 }
 
@@ -334,12 +363,6 @@ mswindows_device_system_metrics (struct device *d,
   return Qunbound;
 }
 
-static unsigned int
-mswindows_device_implementation_flags (void)
-{
-  return XDEVIMPF_PIXEL_GEOMETRY;
-}
-
 \f
 /************************************************************************/
 /*                          printer helpers                             */
@@ -527,14 +550,6 @@ msprinter_mark_device (struct device *d)
   mark_object (DEVICE_MSPRINTER_DEVMODE (d));
 }
 
-static unsigned int
-msprinter_device_implementation_flags (void)
-{
-  return (  XDEVIMPF_PIXEL_GEOMETRY
-         | XDEVIMPF_IS_A_PRINTER
-         | XDEVIMPF_NO_AUTO_REDISPLAY
-         | XDEVIMPF_FRAMELESS_OK );
-}
 \f
 /************************************************************************/
 /*                      printer Lisp subroutines                        */
@@ -674,11 +689,9 @@ decode_devmode (Lisp_Object dev)
 
 /*
  * DEV can be either a printer or devmode
- * PRINT_P is non-zero for the Print dialog, zero for the
- *         Page Setup dialog
  */
 static Lisp_Object
-print_dialog_worker (Lisp_Object dev, int print_p)
+print_dialog_worker (Lisp_Object dev, DWORD flags)
 {
   Lisp_Devmode *ldm = decode_devmode (dev);
   PRINTDLG pd;
@@ -687,8 +700,7 @@ print_dialog_worker (Lisp_Object dev, int print_p)
   pd.lStructSize = sizeof (pd);
   pd.hwndOwner = mswindows_get_selected_frame_hwnd ();
   pd.hDevMode = devmode_to_hglobal (ldm);
-  pd.Flags = (PD_NOSELECTION | PD_USEDEVMODECOPIESANDCOLLATE
-             | (print_p ? 0 : PD_PRINTSETUP));
+  pd.Flags = flags | PD_USEDEVMODECOPIESANDCOLLATE;
   pd.nMinPage = 0;
   pd.nMaxPage = 0xFFFF;
 
@@ -708,21 +720,24 @@ print_dialog_worker (Lisp_Object dev, int print_p)
 
     /* Do consing in reverse order.
        Number of copies */
-    if (print_p)
-      result = Fcons (Qcopies, Fcons (make_int (pd.nCopies), result));
+    result = Fcons (Qcopies, Fcons (make_int (pd.nCopies), result));
 
     /* Page range */
-    if (print_p && (pd.Flags & PD_PAGENUMS))
+    if (pd.Flags & PD_PAGENUMS)
       {
        result = Fcons (Qto_page, Fcons (make_int (pd.nToPage), result));
        result = Fcons (Qfrom_page, Fcons (make_int (pd.nFromPage), result));
+       result = Fcons (Qselected_page_button, Fcons (Qpages, result));
       }
+    else if (pd.Flags & PD_SELECTION)
+      result = Fcons (Qselected_page_button, Fcons (Qselection, result));
+    else
+      result = Fcons (Qselected_page_button, Fcons (Qall, result));
 
     /* Device name */
-    result = Fcons (Qname,
-                   Fcons (build_ext_string (ldm->printer_name,
-                                            Qmswindows_tstr),
-                          result));
+    result = Fcons (Qname, Fcons (build_ext_string (ldm->printer_name,
+                                                   Qmswindows_tstr),
+                                 result));
     UNGCPRO;
 
     global_free_2_maybe (pd.hDevNames, pd.hDevMode);
@@ -731,9 +746,10 @@ print_dialog_worker (Lisp_Object dev, int print_p)
 }
 
 Lisp_Object
-mswindows_handle_print_setup_dialog_box (struct frame *f, Lisp_Object keys)
+mswindows_handle_print_dialog_box (struct frame *f, Lisp_Object keys)
 {
   Lisp_Object device = Qunbound, settings = Qunbound;
+  DWORD flags = PD_NOSELECTION;
 
   {
     EXTERNAL_PROPERTY_LIST_LOOP_3 (key, value, keys)
@@ -748,36 +764,25 @@ mswindows_handle_print_setup_dialog_box (struct frame *f, Lisp_Object keys)
            CHECK_DEVMODE (value);
            settings = value;
          }
-       else
-         syntax_error ("Unrecognized print-dialog keyword", key);
-      }
-  }
-
-  if ((UNBOUNDP (device) && UNBOUNDP (settings)) ||
-      (!UNBOUNDP (device) && !UNBOUNDP (settings)))
-    syntax_error ("Exactly one of :device and :printer-settings must be given",
-                 keys);
-
-  return print_dialog_worker (!UNBOUNDP (device) ? device : settings, 0);
-}
-
-Lisp_Object
-mswindows_handle_print_dialog_box (struct frame *f, Lisp_Object keys)
-{
-  Lisp_Object device = Qunbound, settings = Qunbound;
-
-  {
-    EXTERNAL_PROPERTY_LIST_LOOP_3 (key, value, keys)
-      {
-       if (EQ (key, Q_device))
+       else if (EQ (key, Q_allow_pages))
          {
-           device = wrap_device (decode_device (value));
-           CHECK_MSPRINTER_DEVICE (device);
+           if (NILP (value))
+             flags |= PD_NOPAGENUMS;
          }
-       else if (EQ (key, Q_printer_settings))
+       else if (EQ (key, Q_allow_selection))
          {
-           CHECK_DEVMODE (value);
-           settings = value;
+           if (!NILP (value))
+             flags &= ~PD_NOSELECTION;
+         }
+       else if (EQ (key, Q_selected_page_button))
+         {
+           if (EQ (value, Qselection))
+             flags |= PD_SELECTION;
+           else if (EQ (value, Qpages))
+             flags |= PD_PAGENUMS;
+           else if (!EQ (value, Qall))
+             invalid_argument ("Invalid value for :selected-page-button",
+                               value);
          }
        else
          syntax_error ("Unrecognized print-dialog keyword", key);
@@ -789,23 +794,35 @@ mswindows_handle_print_dialog_box (struct frame *f, Lisp_Object keys)
     syntax_error ("Exactly one of :device and :printer-settings must be given",
                  keys);
 
-  return print_dialog_worker (!UNBOUNDP (device) ? device : settings, 1);
+  return print_dialog_worker (!UNBOUNDP (device) ? device : settings, flags);
+}
+
+int
+mswindows_get_default_margin (Lisp_Object prop)
+{
+  if (EQ (prop, Qleft_margin)) return 1440;
+  if (EQ (prop, Qright_margin)) return 1440;
+  if (EQ (prop, Qtop_margin)) return 720;
+  if (EQ (prop, Qbottom_margin)) return 720;
+  ABORT ();
+  return 0;
 }
 
 static int
-plist_get_margin (Lisp_Object plist, Lisp_Object prop)
+plist_get_margin (Lisp_Object plist, Lisp_Object prop, int mm_p)
 {
-  Lisp_Object val = Fplist_get (plist, prop, make_int (1440));
+  Lisp_Object val =
+    Fplist_get (plist, prop, make_int (mswindows_get_default_margin (prop)));
   if (!INTP (val))
     invalid_argument ("Margin value must be an integer", val);
 
-  return MulDiv (XINT (val), 100, 144);
+  return MulDiv (XINT (val), mm_p ? 254 : 100, 144);
 }
 
 static Lisp_Object
 plist_set_margin (Lisp_Object plist, Lisp_Object prop, int margin, int mm_p)
 {
-  Lisp_Object val = make_int (MulDiv (margin, 144, mm_p ? 2450 : 100));
+  Lisp_Object val = make_int (MulDiv (margin, 144, mm_p ? 254 : 100));
   return Fcons (prop, Fcons (val, plist));
 }
 
@@ -849,15 +866,21 @@ mswindows_handle_page_setup_dialog_box (struct frame *f, Lisp_Object keys)
   {
     Lisp_Devmode *ldm = decode_devmode (device);
     PAGESETUPDLG pd;
+    TCHAR measure[2];
+    int data;
+    GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_IMEASURE,
+                  measure, sizeof(measure));
+    data = (strcmp (measure, "0"));
 
     memset (&pd, 0, sizeof (pd));
     pd.lStructSize = sizeof (pd);
     pd.hwndOwner = mswindows_get_selected_frame_hwnd ();
     pd.Flags = PSD_MARGINS;
-    pd.rtMargin.left   = plist_get_margin (plist, Qleft_margin);
-    pd.rtMargin.top    = plist_get_margin (plist, Qtop_margin);
-    pd.rtMargin.right  = plist_get_margin (plist, Qright_margin);
-    pd.rtMargin.bottom = plist_get_margin (plist, Qbottom_margin);
+    pd.rtMargin.left   = plist_get_margin (plist, Qleft_margin, !data);
+    pd.rtMargin.top    = plist_get_margin (plist, Qtop_margin, !data);
+    pd.rtMargin.right  = plist_get_margin (plist, Qright_margin, !data);
+    pd.rtMargin.bottom = plist_get_margin (plist, Qbottom_margin, !data);
     pd.hDevMode = devmode_to_hglobal (ldm);
 
     if (!PageSetupDlg (&pd))
@@ -1279,8 +1302,13 @@ syms_of_device_mswindows (void)
   DEFSUBR (Fmswindows_get_default_printer);
   DEFSUBR (Fmswindows_printer_list);
 
-  defsymbol (&Qinit_pre_mswindows_win, "init-pre-mswindows-win");
-  defsymbol (&Qinit_post_mswindows_win, "init-post-mswindows-win");
+  DEFKEYWORD (Q_allow_selection);
+  DEFKEYWORD (Q_allow_pages);
+  DEFKEYWORD (Q_selected_page_button);
+  DEFSYMBOL (Qselected_page_button);
+
+  DEFSYMBOL (Qinit_pre_mswindows_win);
+  DEFSYMBOL (Qinit_post_mswindows_win);
 }
 
 void
@@ -1291,13 +1319,17 @@ console_type_create_device_mswindows (void)
   CONSOLE_HAS_METHOD (mswindows, mark_device);
   CONSOLE_HAS_METHOD (mswindows, delete_device);
   CONSOLE_HAS_METHOD (mswindows, device_system_metrics);
-  CONSOLE_HAS_METHOD (mswindows, device_implementation_flags);
+  CONSOLE_IMPLEMENTATION_FLAGS (mswindows, XDEVIMPF_PIXEL_GEOMETRY);
 
   CONSOLE_HAS_METHOD (msprinter, init_device);
   CONSOLE_HAS_METHOD (msprinter, mark_device);
   CONSOLE_HAS_METHOD (msprinter, delete_device);
   CONSOLE_HAS_METHOD (msprinter, device_system_metrics);
-  CONSOLE_HAS_METHOD (msprinter, device_implementation_flags);
+  CONSOLE_IMPLEMENTATION_FLAGS (msprinter, (XDEVIMPF_PIXEL_GEOMETRY
+                                           | XDEVIMPF_IS_A_PRINTER
+                                           | XDEVIMPF_NO_AUTO_REDISPLAY
+                                           | XDEVIMPF_DONT_PREEMPT_REDISPLAY
+                                           | XDEVIMPF_FRAMELESS_OK));
 }