Revision: miles@gnu.org--gnu-2004/emacs--unicode--0--patch-71
[bpt/emacs.git] / src / w32fns.c
index a5f8c4b..df6228b 100644 (file)
@@ -261,6 +261,7 @@ typedef BOOL (WINAPI * TrackMouseEvent_Proc)
 
 TrackMouseEvent_Proc track_mouse_event_fn = NULL;
 ClipboardSequence_Proc clipboard_sequence_fn = NULL;
+extern AppendMenuW_Proc unicode_append_menu;
 
 /* W95 mousewheel handler */
 unsigned int msh_mousewheel = 0;
@@ -3458,7 +3459,13 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
               pMis->itemHeight = GetSystemMetrics (SM_CYMENUSIZE);
               if (title)
                 {
-                  GetTextExtentPoint32 (hdc, title, strlen (title), &size);
+                 if (unicode_append_menu)
+                   GetTextExtentPoint32W (hdc, (WCHAR *) title,
+                                          wcslen ((WCHAR *) title),
+                                          &size);
+                 else
+                   GetTextExtentPoint32 (hdc, title, strlen (title), &size);
+
                   pMis->itemWidth = size.cx;
                   if (pMis->itemHeight < size.cy)
                     pMis->itemHeight = size.cy;
@@ -3496,13 +3503,22 @@ w32_wnd_proc (hwnd, msg, wParam, lParam)
                   menu_font = CreateFontIndirect (&menu_logfont);
                   old_font = SelectObject (hdc, menu_font);
 
-                  /* Always draw title as if not selected.  */
-                  ExtTextOut (hdc,
-                              pDis->rcItem.left
-                              + GetSystemMetrics (SM_CXMENUCHECK),
-                              pDis->rcItem.top,
-                              ETO_OPAQUE, &pDis->rcItem,
-                              title, strlen (title), NULL);
+                 /* Always draw title as if not selected.  */
+                 if (unicode_append_menu)
+                   ExtTextOutW (hdc,
+                                pDis->rcItem.left
+                                + GetSystemMetrics (SM_CXMENUCHECK),
+                                pDis->rcItem.top,
+                                ETO_OPAQUE, &pDis->rcItem,
+                                (WCHAR *) title,
+                                wcslen ((WCHAR *) title), NULL);
+                 else
+                   ExtTextOut (hdc,
+                               pDis->rcItem.left
+                               + GetSystemMetrics (SM_CXMENUCHECK),
+                               pDis->rcItem.top,
+                               ETO_OPAQUE, &pDis->rcItem,
+                               title, strlen (title), NULL);
 
                   SelectObject (hdc, old_font);
                   DeleteObject (menu_font);
@@ -4644,6 +4660,7 @@ int size;
 {
   Lisp_Object bdf_fonts;
   struct font_info *retval = NULL;
+  struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
 
   bdf_fonts = w32_list_bdf_fonts (build_string (fontname), 1);
 
@@ -4651,11 +4668,22 @@ int size;
     {
       char *bdf_name, *bdf_file;
       Lisp_Object bdf_pair;
+      int i;
 
       bdf_name = SDATA (XCAR (bdf_fonts));
       bdf_pair = Fassoc (XCAR (bdf_fonts), Vw32_bdf_filename_alist);
       bdf_file = SDATA (XCDR (bdf_pair));
 
+      // If the font is already loaded, do not load it again.
+      for (i = 0; i < dpyinfo->n_fonts; i++)
+       {
+         if ((dpyinfo->font_table[i].name
+              && !strcmp (dpyinfo->font_table[i].name, bdf_name))
+             || (dpyinfo->font_table[i].full_name
+                 && !strcmp (dpyinfo->font_table[i].full_name, bdf_name)))
+           return dpyinfo->font_table + i;
+       }
+
       retval = w32_load_bdf_font (f, bdf_name, size, bdf_file);
 
       bdf_fonts = XCDR (bdf_fonts);
@@ -5398,19 +5426,17 @@ x_to_w32_font (lpxstr, lplogfont)
 
       if (fields > 0 && name[0] != '*')
         {
+         Lisp_Object string = build_string (name);
           setup_coding_system
             (Fcheck_coding_system (Vlocale_coding_system), &coding);
-         coding.src_multibyte = 1;
-         coding.dst_multibyte = 1;
-         coding.dst_bytes = strlen (name) * 2;
-         coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
+          coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
          /* Disable composition/charset annotation.   */
          coding.common_flags &= ~CODING_ANNOTATION_MASK;
-         if (coding.type == coding_type_iso2022)
-           coding.flags |= CODING_FLAG_ISO_SAFE;
-          coding.mode |= CODING_MODE_LAST_BLOCK;
-          encode_coding_object (&coding, build_string (name), 0, 0,
-                               strlen (name), coding.dst_bytes, Qnil);
+         coding.dst_bytes = SCHARS (string) * 2;
+
+         coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
+          encode_coding_object (&coding, string, 0, 0,
+                               SCHARS (string), SBYTES (string), Qnil);
          if (coding.produced >= LF_FACESIZE)
            coding.produced = LF_FACESIZE - 1;
 
@@ -5641,11 +5667,11 @@ w32_font_match (fontname, pattern)
     char * fontname;
     char * pattern;
 {
-  char *regex = alloca (strlen (pattern) * 2 + 3);
-  char *font_name_copy = alloca (strlen (fontname) + 1);
   char *ptr;
+  char *font_name_copy;
+  char *regex = alloca (strlen (pattern) * 2 + 3);
 
-  /* Copy fontname so we can modify it during comparison.  */
+  font_name_copy = alloca (strlen (fontname) + 1);
   strcpy (font_name_copy, fontname);
 
   ptr = regex;
@@ -5684,8 +5710,8 @@ w32_font_match (fontname, pattern)
       return FALSE;
   }
 
-  return (fast_c_string_match_ignore_case (build_string (regex),
-                                           font_name_copy) >= 0);
+  return (fast_string_match_ignore_case (build_string (regex),
+                                         build_string(font_name_copy)) >= 0);
 }
 
 /* Callback functions, and a structure holding info they need, for
@@ -6431,7 +6457,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
 }
 
 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
-       doc: /* Returns the vendor ID string of the W32 system (Microsoft).
+       doc: /* Returns the "vendor ID" string of the W32 system (Microsoft).
 The optional argument DISPLAY specifies which display to ask about.
 DISPLAY should be either a frame or a display name (a string).
 If omitted or nil, that stands for the selected frame's display.  */)
@@ -6444,7 +6470,7 @@ If omitted or nil, that stands for the selected frame's display.  */)
 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
        doc: /* Returns the version numbers of the server of DISPLAY.
 The value is a list of three integers: the major and minor
-version numbers, and the vendor-specific release
+version numbers of the X Protocol in use, and the distributor-specific release
 number.  See also the function `x-server-vendor'.
 
 The optional argument DISPLAY specifies which display to ask about.
@@ -7749,7 +7775,8 @@ file_dialog_callback (hwnd, msg, wParam, lParam)
     {
       OFNOTIFY * notify = (OFNOTIFY *)lParam;
       /* Detect when the Filter dropdown is changed.  */
-      if (notify->hdr.code == CDN_TYPECHANGE)
+      if (notify->hdr.code == CDN_TYPECHANGE
+         || notify->hdr.code == CDN_INITDONE)
        {
          HWND dialog = GetParent (hwnd);
          HWND edit_control = GetDlgItem (dialog, FILE_NAME_TEXT_FIELD);
@@ -7763,8 +7790,10 @@ file_dialog_callback (hwnd, msg, wParam, lParam)
            }
          else
            {
-             CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD,
-                                              "");
+             /* Don't override default filename on init done.  */
+             if (notify->hdr.code == CDN_TYPECHANGE)
+               CommDlg_OpenSave_SetControlText (dialog,
+                                                FILE_NAME_TEXT_FIELD, "");
              EnableWindow (edit_control, TRUE);
            }
        }
@@ -7772,36 +7801,38 @@ file_dialog_callback (hwnd, msg, wParam, lParam)
   return 0;
 }
 
-DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0,
+DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
        doc: /* Read file name, prompting with PROMPT in directory DIR.
 Use a file selection dialog.
 Select DEFAULT-FILENAME in the dialog's file selection box, if
-specified.  Ensure that file exists if MUSTMATCH is non-nil.  */)
-  (prompt, dir, default_filename, mustmatch)
-     Lisp_Object prompt, dir, default_filename, mustmatch;
+specified.  Ensure that file exists if MUSTMATCH is non-nil.
+If ONLY-DIR-P is non-nil, the user can only select directories.  */)
+  (prompt, dir, default_filename, mustmatch, only_dir_p)
+     Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
 {
   struct frame *f = SELECTED_FRAME ();
   Lisp_Object file = Qnil;
   int count = SPECPDL_INDEX ();
-  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
+  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
   char filename[MAX_PATH + 1];
   char init_dir[MAX_PATH + 1];
+  int default_filter_index = 1; /* 1: All Files, 2: Directories only  */
 
-  GCPRO5 (prompt, dir, default_filename, mustmatch, file);
+  GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
   CHECK_STRING (prompt);
   CHECK_STRING (dir);
 
   /* Create the dialog with PROMPT as title, using DIR as initial
      directory and using "*" as pattern.  */
   dir = Fexpand_file_name (dir, Qnil);
-  strncpy (init_dir, SDATA (dir), MAX_PATH);
+  strncpy (init_dir, SDATA (ENCODE_FILE (dir)), MAX_PATH);
   init_dir[MAX_PATH] = '\0';
   unixtodos_filename (init_dir);
 
   if (STRINGP (default_filename))
     {
       char *file_name_only;
-      char *full_path_name = SDATA (default_filename);
+      char *full_path_name = SDATA (ENCODE_FILE (default_filename));
 
       unixtodos_filename (full_path_name);
 
@@ -7809,9 +7840,7 @@ specified.  Ensure that file exists if MUSTMATCH is non-nil.  */)
       if (!file_name_only)
         file_name_only = full_path_name;
       else
-        {
-          file_name_only++;
-        }
+       file_name_only++;
 
       strncpy (filename, file_name_only, MAX_PATH);
       filename[MAX_PATH] = '\0';
@@ -7836,6 +7865,12 @@ specified.  Ensure that file exists if MUSTMATCH is non-nil.  */)
     file_details.nMaxFile = sizeof (filename);
     file_details.lpstrInitialDir = init_dir;
     file_details.lpstrTitle = SDATA (prompt);
+
+    if (! NILP (only_dir_p))
+      default_filter_index = 2;
+
+    file_details.nFilterIndex = default_filter_index;
+
     file_details.Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR
                          | OFN_EXPLORER | OFN_ENABLEHOOK);
     if (!NILP (mustmatch))
@@ -7848,7 +7883,7 @@ specified.  Ensure that file exists if MUSTMATCH is non-nil.  */)
        dostounix_filename (filename);
        if (file_details.nFilterIndex == 2)
          {
-           /* "Folder Only" selected - strip dummy file name.  */
+           /* "Directories" selected - strip dummy file name.  */
            char * last = strrchr (filename, '/');
            *last = '\0';
          }