diff src/objects-msw.c @ 371:cc15677e0335 r21-2b1

Import from CVS: tag r21-2b1
author cvs
date Mon, 13 Aug 2007 11:03:08 +0200
parents 7347b34c275b
children 6240c7796c7a
line wrap: on
line diff
--- a/src/objects-msw.c	Mon Aug 13 11:01:58 2007 +0200
+++ b/src/objects-msw.c	Mon Aug 13 11:03:08 2007 +0200
@@ -49,16 +49,14 @@
 #include "device.h"
 #include "insdel.h"
 
-#if defined (__CYGWIN32__) && CYGWIN_VERSION_DLL_MAJOR < 21
+#ifdef __CYGWIN32__
 #define stricmp strcasecmp
-#define FONTENUMPROC FONTENUMEXPROC
-#define ntmTm ntmentm
 #endif
 
 typedef struct colormap_t 
 {
-  CONST char *name;
-  CONST COLORREF colorref;
+  char *name;
+  COLORREF colorref;
 } colormap_t;
 
 /* Colors from X11R6 "XConsortium: rgb.txt,v 10.41 94/02/20 18:39:36 rws Exp" */
@@ -723,58 +721,6 @@
   {"LightGreen"			, PALETTERGB (144, 238, 144) }
 };
 
-
-typedef struct fontmap_t 
-{
-  CONST char *name;
-  CONST int value;
-} fontmap_t;
-
-/* Default weight first, preferred names listed before synonyms */
-static CONST fontmap_t fontweight_map[] = 
-{
-  {"Regular"		, FW_REGULAR},	/* The standard font weight */
-  {"Thin"		, FW_THIN},
-  {"Extra Light"	, FW_EXTRALIGHT},
-  {"Ultra Light"	, FW_ULTRALIGHT},
-  {"Light"		, FW_LIGHT},
-  {"Normal"		, FW_NORMAL},
-  {"Medium"		, FW_MEDIUM},
-  {"Semi Bold"		, FW_SEMIBOLD},
-  {"Demi Bold"		, FW_DEMIBOLD},
-  {"Bold"		, FW_BOLD},	/* The standard bold font weight */
-  {"Extra Bold"		, FW_EXTRABOLD},
-  {"Ultra Bold"		, FW_ULTRABOLD},
-  {"Heavy"		, FW_HEAVY},
-  {"Black"		, FW_BLACK}
-};
-
-/* Default charset first, no synonyms allowed because these names are 
- * matched against the names reported by win32 by match_font() */
-static CONST fontmap_t charset_map[] = 
-{
-  {"Western"		, ANSI_CHARSET},
-  {"Symbol"		, SYMBOL_CHARSET},
-  {"Shift JIS"		, SHIFTJIS_CHARSET},	/* #### Name to be verified */
-  {"GB2312"		, GB2312_CHARSET},	/* #### Name to be verified */
-  {"Hanguel"		, HANGEUL_CHARSET},
-  {"Chinese Big 5"	, CHINESEBIG5_CHARSET},	/* #### Name to be verified */
-#if (WINVER >= 0x0400)
-  {"Johab"		, JOHAB_CHARSET},	/* #### Name to be verified */
-  {"Hebrew"		, HEBREW_CHARSET},	/* #### Name to be verified */
-  {"Arabic"		, ARABIC_CHARSET},	/* #### Name to be verified */
-  {"Greek"		, GREEK_CHARSET},
-  {"Turkish"		, TURKISH_CHARSET},
-  {"Vietnamese"		, VIETNAMESE_CHARSET},	/* #### Name to be verified */
-  {"Thai"		, THAI_CHARSET},	/* #### Name to be verified */
-  {"Central European"	, EASTEUROPE_CHARSET},
-  {"Cyrillic"		, RUSSIAN_CHARSET},
-  {"Mac"		, MAC_CHARSET},
-  {"Baltic"		, BALTIC_CHARSET},
-#endif
-  {"OEM/DOS"		, OEM_CHARSET}
-};
-
 
 /************************************************************************/
 /*                               helpers                                */
@@ -926,120 +872,6 @@
   return 1;
 }
 
-
-
-
-
-/************************************************************************/
-/*                                 exports                              */
-/************************************************************************/
-
-struct font_enum_t
-{
-  HDC hdc;
-  struct device *d;
-};
-
-static int CALLBACK
-font_enum_callback_2 (ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, 
-		      int FontType, struct font_enum_t *font_enum)
-{
-  struct mswindows_font_enum *fontlist, **fonthead;
-  char fontname[MSW_FONTSIZE];
-  int i;
-
-  /*
-   * The enumerated font weights are not to be trusted because:
-   *  a) lpelfe->elfStyle is only filled in for TrueType fonts.
-   *  b) Not all Bold and Italic styles of all fonts (inluding some Vector,
-   *     Truetype and Raster fonts) are enumerated.
-   * I guess that fonts for which Bold and Italic styles are generated
-   * 'on-the-fly' are not enumerated. It would be overly restrictive to
-   * disallow Bold And Italic weights for these fonts, so we just leave
-   * weights unspecified. This means that we have to weed out duplicates of
-   * those fonts that do get enumerated with different weights.
-   */
-  if (FontType == 0 /*vector*/ || FontType == TRUETYPE_FONTTYPE)
-    /* Scalable, so leave pointsize blank */
-    sprintf (fontname, "%s::::", lpelfe->elfLogFont.lfFaceName);
-  else
-    /* Formula for pointsize->height from LOGFONT docs in Platform SDK */
-    sprintf (fontname, "%s::%d::", lpelfe->elfLogFont.lfFaceName,
-	     MulDiv (lpntme->ntmTm.tmHeight - lpntme->ntmTm.tmInternalLeading,
-	             72, DEVICE_MSWINDOWS_LOGPIXELSY (font_enum->d)));
-
-  /*
-   * The enumerated font character set strings are not to be trusted because
-   * lpelfe->elfScript is returned in the host language and not in English.
-   * We can't know a priori the translations of "Western", "Central European"
-   * etc into the host language, so we must use English. The same argument
-   * applies to the font weight string when matching fonts.
-   */
-  for (i=0; i<countof (charset_map); i++)
-    if (lpelfe->elfLogFont.lfCharSet == charset_map[i].value)
-      {
-	strcat (fontname, charset_map[i].name);
-	break;
-      }
-  if (i==countof (charset_map))
-    strcpy (fontname, charset_map[0].name);
-
-  /* Check that the new font is not a duplicate */
-  fonthead = &DEVICE_MSWINDOWS_FONTLIST (font_enum->d);
-  fontlist = *fonthead;
-  while (fontlist)
-    if (!strcmp (fontname, fontlist->fontname))
-      return 1;		/* found a duplicate */
-    else
-      fontlist = fontlist->next;
-
-  /* Insert entry at head */
-  fontlist = *fonthead;
-  *fonthead = xmalloc (sizeof (struct mswindows_font_enum));
-  if (*fonthead == NULL)
-    {
-      *fonthead = fontlist;
-      return 0;
-    }
-  strcpy ((*fonthead)->fontname, fontname);
-  (*fonthead)->next = fontlist;
-  return 1;
-}
-
-static int CALLBACK
-font_enum_callback_1 (ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, 
-		      int FontType, struct font_enum_t *font_enum)
-{
-  /* This function gets called once per facename per character set.
-   * We call a second callback to enumerate the fonts in each facename */
-  return EnumFontFamiliesEx (font_enum->hdc, &lpelfe->elfLogFont,
-			     (FONTENUMPROC) font_enum_callback_2,
-			     (LPARAM) font_enum, 0);
-}
-
-/*
- * Enumerate the available fonts. Called by mswindows_init_device().
- * Fills in the device's device-type-specfic fontlist.
- */
-void
-mswindows_enumerate_fonts (struct device *d)
-{
-  HDC hdc = CreateCompatibleDC (NULL);
-  LOGFONT logfont;
-  struct font_enum_t font_enum;
-
-  assert (hdc!=NULL);
-  logfont.lfCharSet = DEFAULT_CHARSET;
-  logfont.lfFaceName[0] = '\0';
-  logfont.lfPitchAndFamily = DEFAULT_PITCH;
-  font_enum.hdc = hdc;
-  font_enum.d = d;
-  DEVICE_MSWINDOWS_FONTLIST (d) = NULL;
-  EnumFontFamiliesEx (hdc, &logfont, (FONTENUMPROC) font_enum_callback_1,
-		      (LPARAM) (&font_enum), 0);
-  DeleteDC (hdc);
-}
-
 
 /************************************************************************/
 /*                               methods                                */
@@ -1138,23 +970,19 @@
     }
 }
 
-
 static int
 mswindows_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object name,
 				    Lisp_Object device, Error_behavior errb)
 {
   CONST char *extname;
   LOGFONT logfont;
-  int fields, i;
+  int fields;
   int pt;
   char fontname[LF_FACESIZE], weight[LF_FACESIZE], *style, points[8];
   char effects[LF_FACESIZE], charset[LF_FACESIZE];
   char *c;
-  HDC hdc;
-  HFONT holdfont;
-  TEXTMETRIC metrics;
-
-  extname = XSTRING_DATA (name);
+  
+  GET_C_STRING_CTEXT_DATA_ALLOCA (f->name, extname);
 
   /*
    * mswindows fonts look like:
@@ -1175,12 +1003,12 @@
   /* This function is implemented in a fairly ad-hoc manner.
    * The general idea is to validate and canonicalize each of the above fields
    * at the same time as we build up the win32 LOGFONT structure. This enables
-   * us to use match_font() on a canonicalized font string to check the
+   * us to use math_font() on a canonicalized font string to check the
    * availability of the requested font */
 
-  if (fields < 0)
+  if (fields<0)
   {
-    maybe_signal_simple_error ("Invalid font", name, Qfont, errb);
+    maybe_signal_simple_error ("Invalid font", f->name, Qfont, errb);
     return (0);
   }
 
@@ -1191,13 +1019,13 @@
   }
   else
   {
-    maybe_signal_simple_error ("Must specify a font name", name, Qfont, errb);
+    maybe_signal_simple_error ("Must specify a font name", f->name, Qfont, errb);
     return (0);
   }
 
   /* weight */
   if (fields < 2)
-    strcpy (weight, fontweight_map[0].name);
+    strcpy (weight, "Regular");
 
   /* Maybe split weight into weight and style */
   if ((c=strchr(weight, ' ')))
@@ -1208,25 +1036,36 @@
   else
     style = NULL;
 
-  for (i=0; i<countof (fontweight_map); i++)
-    if (!stricmp (weight, fontweight_map[i].name))
-      {	
-	logfont.lfWeight = fontweight_map[i].value;
-	break;
-      }
-  if (i == countof (fontweight_map))	/* No matching weight */
+#define FROB(wgt)				\
+  if (stricmp (weight, #wgt) == 0)		\
+    logfont.lfWeight = FW_##wgt
+
+  FROB (REGULAR);
+  else FROB (THIN);
+  else FROB (EXTRALIGHT);
+  else FROB (ULTRALIGHT);
+  else FROB (LIGHT);
+  else FROB (NORMAL);
+  else FROB (MEDIUM);
+  else FROB (SEMIBOLD);
+  else FROB (DEMIBOLD);
+  else FROB (BOLD);
+  else FROB (EXTRABOLD);
+  else FROB (ULTRABOLD);
+  else FROB (HEAVY);
+  else FROB (BLACK);
+  else if (!style)
     {
-      if (!style)
-	{
-	  logfont.lfWeight = FW_REGULAR;
-	  style = weight;	/* May have specified style without weight */
-	}
-      else
-	{
-	  maybe_signal_simple_error ("Invalid font weight", name, Qfont, errb);
-	  return (0);
-	}
+      logfont.lfWeight = FW_REGULAR;
+      style = weight;	/* May have specified style without weight */
     }
+  else
+    {
+      maybe_signal_simple_error ("Invalid font weight", f->name, Qfont, errb);
+      return (0);
+    }
+
+#undef FROB
 
   if (style)
     {
@@ -1235,7 +1074,7 @@
 	logfont.lfItalic = TRUE;
       else
       {
-        maybe_signal_simple_error ("Invalid font weight or style", name, Qfont, errb);
+        maybe_signal_simple_error ("Invalid font weight or style", f->name, Qfont, errb);
 	return (0);
       }
 
@@ -1250,12 +1089,12 @@
     pt = 10;	/* #### Should we reject strings that don't specify a size? */
   else if ((pt=atoi(points)) == 0)
     {
-      maybe_signal_simple_error ("Invalid font pointsize", name, Qfont, errb);
+      maybe_signal_simple_error ("Invalid font pointsize", f->name, Qfont, errb);
       return (0);
     }
 
   /* Formula for pointsize->height from LOGFONT docs in MSVC5 Platform SDK */
-  logfont.lfHeight = -MulDiv(pt, DEVICE_MSWINDOWS_LOGPIXELSY (XDEVICE (device)), 72);
+  logfont.lfHeight = -MulDiv(pt, DEVICE_MSWINDOWS_LOGPIXELSY(XDEVICE (device)), 72);
   logfont.lfWidth = 0;
 
   /* Effects */
@@ -1280,7 +1119,8 @@
 	logfont.lfStrikeOut = TRUE;
       else
         {
-          maybe_signal_simple_error ("Invalid font effect", name, Qfont, errb);
+          maybe_signal_simple_error ("Invalid font effect", f->name,
+				     Qfont, errb);
 	  return (0);
 	}
 
@@ -1292,7 +1132,7 @@
 	    logfont.lfStrikeOut = TRUE;
 	  else
 	    {
-	      maybe_signal_simple_error ("Invalid font effect", name,
+	      maybe_signal_simple_error ("Invalid font effect", f->name,
 					 Qfont, errb);
 	      return (0);
 	    }
@@ -1312,50 +1152,63 @@
   else
     effects[0] = '\0';
 
-  /* Charset */
+#define FROB(cs)				\
+  else if (stricmp (charset, #cs) == 0)		\
+    logfont.lfCharSet = cs##_CHARSET
+
+  /* Charset aliases. Hangeul = Hangul is defined in windows.h.
+     We do not use the name "russian", only "cyrillic", as it is
+     the common name of this charset, used in other languages
+     than Russian. */
+#define CYRILLIC_CHARSET RUSSIAN_CHARSET
+#define CENTRALEUROPEAN_CHARSET EASTEUROPE_CHARSET
+#define CENTRALEUROPEAN_CHARSET EASTEUROPE_CHARSET
+
   /* charset can be specified even if earlier fields havn't been */
-  if (fields < 5)
+  if ((fields < 5) && (c=strchr (extname, ':')) && (c=strchr (c+1, ':')) &&
+      (c=strchr (c+1, ':')) && (c=strchr (c+1, ':')))
+    {
+      strncpy (charset, c+1, LF_FACESIZE);
+      charset[LF_FACESIZE-1] = '\0';
+    }
+  else
+    charset[0] = '\0';
+	  
+  if (charset[0] == '\0' || (stricmp (charset, "ansi") == 0) ||
+      (stricmp (charset, "western") == 0))
     {
-      if ((c=strchr (extname, ':')) && (c=strchr (c+1, ':')) &&
-	  (c=strchr (c+1, ':')) && (c=strchr (c+1, ':')))
-	{
-	  strncpy (charset, c+1, LF_FACESIZE);
-	  charset[LF_FACESIZE-1] = '\0';
-	}
-      else
-	strcpy (charset, charset_map[0].name);
+      logfont.lfCharSet = ANSI_CHARSET;
+      strcpy (charset, "western");
     }
-
-  for (i=0; i<countof (charset_map); i++)
-    if (!stricmp (charset, charset_map[i].name))
-      {
-	logfont.lfCharSet = charset_map[i].value;
-	break;
-      }
-
-  if (i == countof (charset_map))	/* No matching charset */
+  FROB (SYMBOL);
+  FROB (SHIFTJIS);
+  FROB (GB2312);
+  FROB (HANGEUL);
+  FROB (CHINESEBIG5);
+  FROB (JOHAB);
+  FROB (HEBREW);
+  FROB (ARABIC);
+  FROB (GREEK);
+  FROB (TURKISH);
+  FROB (THAI);
+  FROB (EASTEUROPE);
+  FROB (CENTRALEUROPEAN);
+  FROB (CYRILLIC);
+  FROB (MAC);
+  FROB (BALTIC);
+  else if (stricmp (charset, "oem/dos") == 0)
+    logfont.lfCharSet = OEM_CHARSET;
+  else
     {
-      maybe_signal_simple_error ("Invalid charset", name, Qfont, errb);
+      maybe_signal_simple_error ("Invalid charset", f->name, Qfont, errb);
       return 0;
     }
 
-  /* Misc crud */
-  logfont.lfEscapement = logfont.lfOrientation = 0;
-#if 1
-  logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
-  logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
-  logfont.lfQuality = DEFAULT_QUALITY;
-#else
-  logfont.lfOutPrecision = OUT_STROKE_PRECIS;
-  logfont.lfClipPrecision = CLIP_STROKE_PRECIS;
-  logfont.lfQuality = PROOF_QUALITY;
-#endif
-  /* Default to monospaced if the specified fontname doesn't exist. */
-  logfont.lfPitchAndFamily = FF_MODERN;
+#undef FROB
 
   /* Windows will silently substitute a default font if the fontname 
    * specifies a non-existent font. So we check the font against the device's
-   * list of font patterns to make sure that at least one of them matches. */
+   * list of font patterns to make sure that at least one of them matches */
   {
     struct mswindows_font_enum *fontlist;
     char truename[MSW_FONTSIZE];
@@ -1370,37 +1223,58 @@
       }
     if (!done)
       {
-	maybe_signal_simple_error ("No matching font", name, Qfont, errb);
+	maybe_signal_simple_error ("No matching font", f->name, Qfont, errb);
 	return 0;
       }
   }
 
+  /* Misc crud */
+  logfont.lfEscapement = logfont.lfOrientation = 0;
+#if 1
+  logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
+  logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+  logfont.lfQuality = DEFAULT_QUALITY;
+#else
+  logfont.lfOutPrecision = OUT_STROKE_PRECIS;
+  logfont.lfClipPrecision = CLIP_STROKE_PRECIS;
+  logfont.lfQuality = PROOF_QUALITY;
+#endif
+  /* Default to monospaced if the specified fontname doesn't exist.
+   * The match_font calls above should mean that this can't happen. */
+  logfont.lfPitchAndFamily = FF_MODERN;
+
   if ((f->data = CreateFontIndirect(&logfont)) == NULL)
   {
-    maybe_signal_simple_error ("Couldn't create font", name, Qfont, errb);
+    maybe_signal_simple_error ("Couldn't create font", f->name, Qfont, errb);
     return 0;
   }
 
-  hdc = CreateCompatibleDC (NULL);
-  if (hdc)
-    {
-      holdfont = SelectObject(hdc, f->data);
-      if (holdfont)
-	{
-	  GetTextMetrics (hdc, &metrics);
-	  SelectObject(hdc, holdfont);
-	  DeleteDC (hdc);
-	  f->width = (unsigned short) metrics.tmAveCharWidth;
-	  f->height = (unsigned short) metrics.tmHeight;
-	  f->ascent = (unsigned short) metrics.tmAscent;
-	  f->descent = (unsigned short) metrics.tmDescent;
-	  f->proportional_p = (metrics.tmPitchAndFamily & TMPF_FIXED_PITCH);
-	  return 1;
-	}
-      DeleteDC (hdc);
-    }
-  mswindows_finalize_font_instance (f);
-  maybe_signal_simple_error ("Couldn't map font", name, Qfont, errb);
+  {
+    HDC hdc;
+    HFONT holdfont;
+    TEXTMETRIC metrics;
+
+    hdc = CreateCompatibleDC (NULL);
+    if (hdc)
+      {
+	holdfont = SelectObject(hdc, f->data);
+	if (holdfont)
+	  {
+	    GetTextMetrics (hdc, &metrics);
+	    SelectObject(hdc, holdfont);
+	    DeleteDC (hdc);
+	    f->width = (unsigned short) metrics.tmAveCharWidth;
+	    f->height = (unsigned short) metrics.tmHeight;
+	    f->ascent = (unsigned short) metrics.tmAscent;
+	    f->descent = (unsigned short) metrics.tmDescent;
+	    f->proportional_p = (metrics.tmPitchAndFamily & TMPF_FIXED_PITCH);
+	    return 1;
+	  }
+	DeleteDC (hdc);
+      }
+    mswindows_finalize_font_instance (f);
+    maybe_signal_simple_error ("Couldn't map font", f->name, Qfont, errb);
+  }
   return 0;
 }
 
@@ -1464,92 +1338,6 @@
 
 #endif /* MULE */
 
-DEFUN ("mswindows-shell-execute", Fmswindows_shell_execute, 2, 4, 0, /*
-Get Windows to perform OPERATION on DOCUMENT.
-This is a wrapper around the ShellExecute system function, which
-invokes the application registered to handle OPERATION for DOCUMENT.
-OPERATION is typically \"open\", \"print\" or \"explore\" (but can be
-nil for the default action), and DOCUMENT is typically the name of a
-document file or URL, but can also be a program executable to run or
-a directory to open in the Windows Explorer.
-
-If DOCUMENT is a program executable, PARAMETERS can be a string
-containing command line parameters, but otherwise should be nil.
-
-SHOW-FLAG can be used to control whether the invoked application is hidden
-or minimized.  If SHOW-FLAG is nil, the application is displayed normally,
-otherwise it is an integer representing a ShowWindow flag:
-
-  0 - start hidden
-  1 - start normally
-  3 - start maximized
-  6 - start minimized
-*/
-       (operation, document, parameters, show_flag))
-{
-  /* Encode filename and current directory.  */
-  Lisp_Object current_dir = Ffile_name_directory (document);
-  char* path = NULL;
-  char* doc = NULL;
-  Extbyte* f=0;
-  int ret;
-  struct gcpro gcpro1, gcpro2;
-
-  CHECK_STRING (document);
-
-  if (NILP (current_dir))
-    current_dir = current_buffer->directory;
-
-  GCPRO2 (current_dir, document);
-
-  /* Use mule and cygwin-safe APIs top get at file data. */
-  if (STRINGP (current_dir))
-    {
-      GET_C_STRING_FILENAME_DATA_ALLOCA (current_dir, f);
-#ifdef __CYGWIN32__
-      CYGWIN_WIN32_PATH (f, path);
-#else
-      path = f;
-#endif
-    }
-
-  if (STRINGP (document))
-    {
-      GET_C_STRING_FILENAME_DATA_ALLOCA (document, f);
-#ifdef __CYGWIN32__
-      CYGWIN_WIN32_PATH (f, doc);
-#else
-      doc = f;
-#endif
-    }
-
-  UNGCPRO;
-
-  ret = (int) ShellExecute (NULL,
-			    (STRINGP (operation) ?
-			     XSTRING_DATA (operation) : NULL),
-			    doc, 
-			    (STRINGP (parameters) ?
-			     XSTRING_DATA (parameters) : NULL),
-			    path,
-			    (INTP (show_flag) ?
-			     XINT (show_flag) : SW_SHOWDEFAULT));
-
-  if (ret > 32)
-    return Qt;
-  
-  if (ret == ERROR_FILE_NOT_FOUND)
-    signal_simple_error ("file not found", document);
-  else if (ret == ERROR_PATH_NOT_FOUND)
-    signal_simple_error ("path not found", current_dir);
-  else if (ret == ERROR_BAD_FORMAT)
-    signal_simple_error ("bad executable format", document);
-  else
-    error ("internal error");
-
-  return Qnil;
-}
-
 
 /************************************************************************/
 /*                             non-methods                              */
@@ -1579,7 +1367,6 @@
 syms_of_objects_mswindows (void)
 {
   DEFSUBR (Fmswindows_color_list);
-  DEFSUBR (Fmswindows_shell_execute);
 }
 
 void