summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGeoff Voelker <voelker@cs.washington.edu>1996-01-21 00:24:03 +0000
committerGeoff Voelker <voelker@cs.washington.edu>1996-01-21 00:24:03 +0000
commit90ed8fe71fc11bd4a7b6868a908260ee50312d0a (patch)
tree9a120d154813fcdf3577fd3a004f3bafa21e7c18 /src
parent9a918ef3e513a089c75a44a32d549f1b37dd0cb6 (diff)
downloademacs-90ed8fe71fc11bd4a7b6868a908260ee50312d0a.tar.gz
(Vwin32_enable_italics, Vwin32_enable_palette):
New variables. (syms_of_win32fns): Set up new lisp variables. (x_set_frame_parameters, x_real_positions, win32_load_font, win32_abort): Conform to coding style. (Fwin32_define_rgb_color, Fwin32_load_color_file, Fwin32_map_color, Fwin32_unmap_color, Fwin32_regenerate_palette): New functions. (syms_of_win32fns): Set up new lisp subroutines. (defined_color): Use palettes. (map_mode): Function removed. (win32_init_class): Don't CS_OWNDC. (win32_wnd_proc): Use segregated critical sections appropriately. Handle WM_PALETTECHANGED. Record WINDOWPLACEMENT structure length. (x_to_win32_weight, win32_to_x_weight): Handle "heavy", "extrabold", "light", "extralight", and "thin" fonts. (x_to_win32_charset, win32_to_x_charset): New functions. (win32_to_x_font): Use win32_to_x_charset. (x_to_win32_font): Use x_to_win32_charset. Support Windows font names. (Fx_list_fonts, Fx_display_color_cells, Fx_display_mm_height. Fx_display_mm_width): Use GetDC directly. (Fx_open_connection): Support external color mapping files.
Diffstat (limited to 'src')
-rw-r--r--src/w32fns.c737
1 files changed, 526 insertions, 211 deletions
diff --git a/src/w32fns.c b/src/w32fns.c
index 11aaf43dd01..4e1092c6924 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -45,6 +45,13 @@ extern struct scroll_bar *x_window_to_scroll_bar ();
/* The colormap for converting color names to RGB values */
Lisp_Object Vwin32_color_map;
+/* Switch to control whether we inhibit requests for italicised fonts (which
+ are synthesized, look ugly, and are trashed by cursor movement under NT). */
+Lisp_Object Vwin32_enable_italics;
+
+/* Enable palette management. */
+Lisp_Object Vwin32_enable_palette;
+
/* The name we're using in resource queries. */
Lisp_Object Vx_resource_name;
@@ -611,7 +618,7 @@ x_set_frame_parameters (f, alist)
if (NATNUMP (param_index)
&& (XFASTINT (param_index)
< sizeof (x_frame_parms)/sizeof (x_frame_parms[0])))
- (*x_frame_parms[XINT (param_index)].setter)(f, val, old_value);
+ (*x_frame_parms[XINT (param_index)].setter) (f, val, old_value);
}
}
@@ -755,18 +762,16 @@ x_real_positions (f, xptr, yptr)
int *xptr, *yptr;
{
POINT pt;
-
- {
- RECT rect;
+ RECT rect;
- GetClientRect(FRAME_WIN32_WINDOW(f), &rect);
- AdjustWindowRect(&rect, f->output_data.win32->dwStyle, FRAME_EXTERNAL_MENU_BAR(f));
+ GetClientRect (FRAME_WIN32_WINDOW (f), &rect);
+ AdjustWindowRect (&rect, f->output_data.win32->dwStyle,
+ FRAME_EXTERNAL_MENU_BAR (f));
- pt.x = rect.left;
- pt.y = rect.top;
- }
+ pt.x = rect.left;
+ pt.y = rect.top;
- ClientToScreen (FRAME_WIN32_WINDOW(f), &pt);
+ ClientToScreen (FRAME_WIN32_WINDOW (f), &pt);
*xptr = pt.x;
*yptr = pt.y;
@@ -816,25 +821,91 @@ x_report_frame_params (f, alistptr)
}
-#if 0
-DEFUN ("win32-rgb", Fwin32_rgb, Swin32_rgb, 3, 3, 0,
- "Convert RGB numbers to a windows color reference.")
- (red, green, blue)
- Lisp_Object red, green, blue;
+DEFUN ("win32-define-rgb-color", Fwin32_define_rgb_color, Swin32_define_rgb_color, 4, 4, 0,
+ "Convert RGB numbers to a windows color reference and associate with\n\
+NAME (a string). This adds or updates a named color to win32-color-map,\n\
+making it available for use. The original entry's RGB ref is returned,\n\
+or nil if the entry is new.")
+ (red, green, blue, name)
+ Lisp_Object red, green, blue, name;
{
Lisp_Object rgb;
+ Lisp_Object oldrgb = Qnil;
+ Lisp_Object entry;
CHECK_NUMBER (red, 0);
CHECK_NUMBER (green, 0);
CHECK_NUMBER (blue, 0);
+ CHECK_STRING (name, 0);
- XSET (rgb, Lisp_Int, RGB(XUINT(red), XUINT(green), XUINT(blue)));
+ XSET (rgb, Lisp_Int, RGB (XUINT (red), XUINT (green), XUINT (blue)));
+
+ BLOCK_INPUT;
+
+ /* replace existing entry in win32-color-map or add new entry. */
+ entry = Fassoc (name, Vwin32_color_map);
+ if (NILP (entry))
+ {
+ entry = Fcons (name, rgb);
+ Vwin32_color_map = Fcons (entry, Vwin32_color_map);
+ }
+ else
+ {
+ oldrgb = Fcdr (entry);
+ Fsetcdr (entry, rgb);
+ }
+
+ UNBLOCK_INPUT;
- return (rgb);
+ return (oldrgb);
}
+DEFUN ("win32-load-color-file", Fwin32_load_color_file, Swin32_load_color_file, 1, 1, 0,
+ "Create an alist of color entries from an external file (ie. rgb.txt).\n\
+Assign this value to win32-color-map to replace the existing color map.\n\
+The file should define one named RGB color per line like so:\
+ R G B name\n\
+where R,G,B are numbers between 0 and 255 and name is an arbitrary string.")
+ (filename)
+ Lisp_Object filename;
+{
+ FILE *fp;
+ Lisp_Object cmap = Qnil;
+ Lisp_Object abspath;
+
+ CHECK_STRING (filename, 0);
+ abspath = Fexpand_file_name (filename, Qnil);
+
+ fp = fopen (XSTRING (filename)->data, "rt");
+ if (fp)
+ {
+ char buf[512];
+ int red, green, blue;
+ int num;
+
+ BLOCK_INPUT;
+
+ while (fgets (buf, sizeof (buf), fp) != NULL)
+ {
+ if (sscanf (buf, "%u %u %u %n]", &red, &green, &blue, &num) == 3)
+ {
+ char *name = buf + num;
+ num = strlen (name) - 1;
+ if (name[num] == '\n')
+ name[num] = 0;
+ cmap = Fcons (Fcons (build_string (name),
+ make_number (RGB (red, green, blue))),
+ cmap);
+ }
+ }
+ fclose (fp);
+
+ UNBLOCK_INPUT;
+ }
+
+ return cmap;
+}
-#else
/* The default colors for the win32 color map */
typedef struct colormap_t
{
@@ -1108,7 +1179,6 @@ DEFUN ("win32-default-color-map", Fwin32_default_color_map, Swin32_default_color
return (cmap);
}
-#endif
Lisp_Object
win32_to_x_color (rgb)
@@ -1161,6 +1231,121 @@ x_to_win32_color (colorname)
return ret;
}
+
+void
+win32_regenerate_palette (FRAME_PTR f)
+{
+ struct win32_palette_entry * pList;
+ LOGPALETTE * p_palette;
+ HPALETTE h_new_palette;
+ int i;
+
+ /* don't bother trying to create palette if not supported */
+ if (! FRAME_WIN32_DISPLAY_INFO (f)->has_palette)
+ return;
+
+ p_palette = (LOGPALETTE *)
+ xmalloc (sizeof (LOGPALETTE) +
+ FRAME_WIN32_DISPLAY_INFO (f)->n_colors_in_use * sizeof (PALETTEENTRY));
+ p_palette->palVersion = 0x300;
+ p_palette->palNumEntries = FRAME_WIN32_DISPLAY_INFO (f)->n_colors_in_use;
+
+ pList = FRAME_WIN32_DISPLAY_INFO (f)->p_colors_in_use;
+ for (i = 0; i < FRAME_WIN32_DISPLAY_INFO (f)->n_colors_in_use;
+ i++, pList = pList->next)
+ p_palette->palPalEntry[i] = pList->entry;
+
+ h_new_palette = CreatePalette ((LPLOGPALETTE) p_palette);
+
+ enter_crit (CRIT_GDI);
+
+ if (FRAME_WIN32_DISPLAY_INFO (f)->h_palette)
+ DeleteObject (FRAME_WIN32_DISPLAY_INFO (f)->h_palette);
+ FRAME_WIN32_DISPLAY_INFO (f)->h_palette = h_new_palette;
+
+ /* Realize display palette and garbage all frames. */
+ ReleaseFrameDC (f, GetFrameDC (f));
+
+ leave_crit (CRIT_GDI);
+
+ xfree (p_palette);
+}
+
+#define WIN32_COLOR(pe) RGB (pe.peRed, pe.peGreen, pe.peBlue)
+#define SET_WIN32_COLOR(pe, color) \
+ do { \
+ pe.peRed = GetRValue (color); \
+ pe.peGreen = GetGValue (color); \
+ pe.peBlue = GetBValue (color); \
+ pe.peFlags = 0; \
+ } while (0)
+
+#if 0
+/* Keep these around in case we ever want to track color usage. */
+void
+win32_map_color (FRAME_PTR f, COLORREF color)
+{
+ struct win32_palette_entry * pList = FRAME_WIN32_DISPLAY_INFO (f)->p_colors_in_use;
+
+ if (NILP (Vwin32_enable_palette))
+ return;
+
+ /* check if color is already mapped */
+ while (pList)
+ {
+ if (WIN32_COLOR (pList->entry) == color)
+ {
+ ++pList->refcount;
+ return;
+ }
+ pList = pList->next;
+ }
+
+ /* not already mapped, so add to list and recreate Windows palette */
+ pList = (struct win32_palette_entry *) xmalloc (sizeof (struct win32_palette_entry));
+ SET_WIN32_COLOR (pList->entry, color);
+ pList->refcount = 1;
+ pList->next = FRAME_WIN32_DISPLAY_INFO (f)->p_colors_in_use;
+ FRAME_WIN32_DISPLAY_INFO (f)->p_colors_in_use = pList;
+ FRAME_WIN32_DISPLAY_INFO (f)->n_colors_in_use++;
+
+ /* set flag that palette must be regenerated */
+ FRAME_WIN32_DISPLAY_INFO (f)->regen_palette = TRUE;
+}
+
+void
+win32_unmap_color (FRAME_PTR f, COLORREF color)
+{
+ struct win32_palette_entry * pList = FRAME_WIN32_DISPLAY_INFO (f)->p_colors_in_use;
+ struct win32_palette_entry **ppPrev = &FRAME_WIN32_DISPLAY_INFO (f)->p_colors_in_use;
+
+ if (NILP (Vwin32_enable_palette))
+ return;
+
+ /* check if color is already mapped */
+ while (pList)
+ {
+ if (WIN32_COLOR (pList->entry) == color)
+ {
+ if (--pList->refcount == 0)
+ {
+ *ppPrev = pList->next;
+ xfree (pList);
+ FRAME_WIN32_DISPLAY_INFO (f)->n_colors_in_use--;
+ break;
+ }
+ else
+ return;
+ }
+ ppPrev = &pList->next;
+ pList = pList->next;
+ }
+
+ /* set flag that palette must be regenerated */
+ FRAME_WIN32_DISPLAY_INFO (f)->regen_palette = TRUE;
+}
+#endif
+
/* Decide if color named COLOR is valid for the display associated with
the selected frame; if so, return the rgb values in COLOR_DEF.
If ALLOC is nonzero, allocate a new colormap cell. */
@@ -1173,18 +1358,49 @@ defined_color (f, color, color_def, alloc)
int alloc;
{
register Lisp_Object tem;
-
+
tem = x_to_win32_color (color);
-
+
if (!NILP (tem))
{
- *color_def = XUINT (tem);
+ if (!NILP (Vwin32_enable_palette))
+ {
+ struct win32_palette_entry * pEntry =
+ FRAME_WIN32_DISPLAY_INFO (f)->p_colors_in_use;
+ struct win32_palette_entry ** ppLast =
+ &FRAME_WIN32_DISPLAY_INFO (f)->p_colors_in_use;
+
+ /* check if color is already mapped */
+ while (pEntry)
+ {
+ if (WIN32_COLOR (pEntry->entry) == XUINT(tem))
+ break;
+ ppLast = &pEntry->next;
+ pEntry = pEntry->next;
+ }
+
+ if (pEntry == NULL && alloc)
+ {
+ /* not already mapped, so add to list */
+ pEntry = (struct win32_palette_entry *)
+ xmalloc (sizeof (struct win32_palette_entry));
+ SET_WIN32_COLOR (pEntry->entry, XUINT(tem));
+ pEntry->next = NULL;
+ *ppLast = pEntry;
+ FRAME_WIN32_DISPLAY_INFO (f)->n_colors_in_use++;
+
+ /* set flag that palette must be regenerated */
+ FRAME_WIN32_DISPLAY_INFO (f)->regen_palette = TRUE;
+ }
+ }
+ /* whether or not frame can display arbitrary RGB colors, force
+ COLORREF value to snap to nearest color in system palette by
+ simulating the PALETTE_RGB macro. */
+ *color_def = XUINT (tem) | 0x2000000;
return 1;
- }
- else
- {
- return 0;
}
+ else
+ return 0;
}
/* Given a string ARG naming a color, compute a pixel value from it
@@ -2323,7 +2539,7 @@ win32_init_class (hinst)
{
WNDCLASS wc;
- wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
+ wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) win32_wnd_proc;
wc.cbClsExtra = 0;
wc.cbWndExtra = WND_EXTRA_BYTES;
@@ -2427,26 +2643,6 @@ win_msg_worker (dw)
return (0);
}
-HDC
-map_mode (hdc)
- HDC hdc;
-{
- if (hdc)
- {
-#if 0
- /* Make mapping mode be in 1/20 of point */
-
- SetMapMode (hdc, MM_ANISOTROPIC);
- SetWindowExtEx (hdc, 1440, 1440, NULL);
- SetViewportExtEx (hdc,
- GetDeviceCaps (hdc, LOGPIXELSX),
- GetDeviceCaps (hdc, LOGPIXELSY),
- NULL);
-#endif
- }
- return (hdc);
-}
-
/* Convert between the modifier bits Win32 uses and the modifier bits
Emacs uses. */
unsigned int
@@ -2493,50 +2689,33 @@ win32_wnd_proc (hwnd, msg, wParam, lParam)
switch (msg)
{
case WM_ERASEBKGND:
+ enter_crit (CRIT_GDI);
+ GetUpdateRect (hwnd, &wmsg.rect, FALSE);
+ leave_crit (CRIT_GDI);
+ my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
+ return 1;
+ case WM_PALETTECHANGED:
+ /* ignore our own changes */
+ if ((HWND)wParam != hwnd)
{
- HBRUSH hb;
- HANDLE oldobj;
- RECT rect;
-
- GetClientRect (hwnd, &rect);
-
- hb = CreateSolidBrush (GetWindowLong (hwnd, WND_BACKGROUND_INDEX));
-
- oldobj = SelectObject ((HDC)wParam, hb);
-
- FillRect((HDC)wParam, &rect, hb);
-
- SelectObject((HDC)wParam, oldobj);
-
- DeleteObject (hb);
-
- return (0);
+ /* simply notify main thread it may need to update frames */
+ my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
}
+ return 0;
case WM_PAINT:
{
PAINTSTRUCT paintStruct;
-
+
+ enter_crit (CRIT_GDI);
BeginPaint (hwnd, &paintStruct);
wmsg.rect = paintStruct.rcPaint;
EndPaint (hwnd, &paintStruct);
-
+ leave_crit (CRIT_GDI);
+
my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
return (0);
}
-
- case WM_CREATE:
- {
- HDC hdc = my_get_dc (hwnd);
-
- /* Make mapping mode be in 1/20 of point */
-
- map_mode (hdc);
-
- ReleaseDC (hwnd, hdc);
- }
-
- return (0);
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
#if 0
@@ -2561,7 +2740,7 @@ win32_wnd_proc (hwnd, msg, wParam, lParam)
|| wParam == VK_SHIFT
|| wParam == VK_CONTROL
|| wParam == VK_CAPITAL)
- break;
+ goto dflt;
/* Anything we do not have a name for needs to be translated or
returned as ascii keystroke. */
@@ -2624,7 +2803,8 @@ win32_wnd_proc (hwnd, msg, wParam, lParam)
{
WINDOWPLACEMENT wp;
LPWINDOWPOS lppos = (WINDOWPOS *) lParam;
-
+
+ wp.length = sizeof (wp);
GetWindowPlacement (hwnd, &wp);
if (wp.showCmd != SW_SHOWMINIMIZED && ! (lppos->flags & SWP_NOSIZE))
@@ -2638,12 +2818,12 @@ win32_wnd_proc (hwnd, msg, wParam, lParam)
GetWindowRect (hwnd, &wr);
- enter_crit ();
+ enter_crit (CRIT_MSG);
dwXUnits = GetWindowLong (hwnd, WND_X_UNITS_INDEX);
dwYUnits = GetWindowLong (hwnd, WND_Y_UNITS_INDEX);
- leave_crit ();
+ leave_crit (CRIT_MSG);
memset (&rect, 0, sizeof (rect));
AdjustWindowRect (&rect, GetWindowLong (hwnd, GWL_STYLE),
@@ -2929,7 +3109,7 @@ This function is an internal primitive--use `make-frame' instead.")
font = x_new_font (f, "-*-system-medium-r-normal-*-*-200-*-*-c-120-*-*");
#endif
if (! STRINGP (font))
- font = x_new_font (f, "-*-terminal-medium-r-normal-*-*-180-*-*-c-120-*-*");
+ font = x_new_font (f, "-*-Fixedsys-*-r-*-*-12-90-*-*-c-*-*-*");
UNBLOCK_INPUT;
if (! STRINGP (font))
font = build_string ("-*-system");
@@ -3117,54 +3297,50 @@ DEFUN ("unfocus-frame", Funfocus_frame, Sunfocus_frame, 0, 0, 0,
return Qnil;
}
-XFontStruct
-*win32_load_font (dpyinfo,name)
-struct win32_display_info *dpyinfo;
-char * name;
+XFontStruct *
+win32_load_font (dpyinfo,name)
+ struct win32_display_info *dpyinfo;
+ char *name;
{
XFontStruct * font = NULL;
BOOL ok;
-
- {
- LOGFONT lf;
-
- if (!name || !x_to_win32_font(name, &lf))
- return (NULL);
-
- font = (XFontStruct *) xmalloc (sizeof (XFontStruct));
-
- if (!font) return (NULL);
-
- BLOCK_INPUT;
-
- font->hfont = CreateFontIndirect(&lf);
+ LOGFONT lf;
+
+ if (!name || !x_to_win32_font (name, &lf))
+ return (NULL);
+
+ font = (XFontStruct *) xmalloc (sizeof (XFontStruct));
+ if (!font) return (NULL);
+
+ BLOCK_INPUT;
+
+ font->hfont = CreateFontIndirect (&lf);
+
+ if (font->hfont == NULL)
+ {
+ ok = FALSE;
+ }
+ else
+ {
+ HDC hdc;
+ HANDLE oldobj;
+
+ hdc = GetDC (dpyinfo->root_window);
+
+ oldobj = SelectObject (hdc, font->hfont);
+
+ ok = GetTextMetrics (hdc, &font->tm);
+
+ SelectObject (hdc, oldobj);
+
+ ReleaseDC (dpyinfo->root_window, hdc);
}
-
- if (font->hfont == NULL)
- {
- ok = FALSE;
- }
- else
- {
- HDC hdc;
- HANDLE oldobj;
- hdc = my_get_dc (dpyinfo->root_window);
-
- oldobj = SelectObject (hdc, font->hfont);
-
- ok = GetTextMetrics (hdc, &font->tm);
-
- SelectObject (hdc, oldobj);
-
- ReleaseDC (dpyinfo->root_window, hdc);
- }
-
UNBLOCK_INPUT;
-
+
if (ok) return (font);
-
- win32_unload_font(dpyinfo, font);
+
+ win32_unload_font (dpyinfo, font);
return (NULL);
}
@@ -3175,7 +3351,7 @@ win32_unload_font (dpyinfo, font)
{
if (font)
{
- if (font->hfont) DeleteObject(font->hfont);
+ if (font->hfont) DeleteObject (font->hfont);
xfree (font);
}
}
@@ -3260,7 +3436,11 @@ x_to_win32_weight (lpw)
{
if (!lpw) return (FW_DONTCARE);
- if (stricmp (lpw, "bold") == 0)
+ if (stricmp (lpw, "heavy") == 0)
+ return (FW_HEAVY);
+ else if (stricmp (lpw, "extrabold") == 0)
+ return (FW_EXTRABOLD);
+ else if (stricmp (lpw, "bold") == 0)
return (FW_BOLD);
else if (stricmp (lpw, "demibold") == 0)
return (FW_SEMIBOLD);
@@ -3268,22 +3448,81 @@ x_to_win32_weight (lpw)
return (FW_MEDIUM);
else if (stricmp (lpw, "normal") == 0)
return (FW_NORMAL);
+ else if (stricmp (lpw, "light") == 0)
+ return (FW_LIGHT);
+ else if (stricmp (lpw, "extralight") == 0)
+ return (FW_EXTRALIGHT);
+ else if (stricmp (lpw, "thin") == 0)
+ return (FW_THIN);
else
return (FW_DONTCARE);
}
+
char *
win32_to_x_weight (fnweight)
int fnweight;
{
- if (fnweight >= FW_BOLD)
- return ("bold");
- else if (fnweight >= FW_SEMIBOLD)
- return ("demibold");
- else if (fnweight >= FW_MEDIUM)
- return ("medium");
- else
- return ("normal");
+ if (fnweight >= FW_HEAVY)
+ return "heavy";
+ else if (fnweight >= FW_EXTRABOLD)
+ return "extrabold";
+ else if (fnweight >= FW_BOLD)
+ return "bold";
+ else if (fnweight >= FW_SEMIBOLD)
+ return "semibold";
+ else if (fnweight >= FW_MEDIUM)
+ return "medium";
+ else if (fnweight >= FW_NORMAL)
+ return "normal";
+ else if (fnweight >= FW_LIGHT)
+ return "light";
+ else if (fnweight >= FW_EXTRALIGHT)
+ return "extralight";
+ else if (fnweight >= FW_THIN)
+ return "thin";
+ else
+ return "*";
+}
+
+LONG
+x_to_win32_charset (lpcs)
+ char * lpcs;
+{
+ if (!lpcs) return (0);
+
+ if (stricmp (lpcs, "ansi") == 0)
+ return (ANSI_CHARSET);
+ else if (stricmp (lpcs, "iso8859-1") == 0)
+ return (ANSI_CHARSET);
+ else if (stricmp (lpcs, "iso8859") == 0)
+ return (ANSI_CHARSET);
+ else if (stricmp (lpcs, "oem") == 0)
+ return (OEM_CHARSET);
+#ifdef UNICODE_CHARSET
+ else if (stricmp (lpcs, "unicode") == 0)
+ return (UNICODE_CHARSET);
+ else if (stricmp (lpcs, "iso10646") == 0)
+ return (UNICODE_CHARSET);
+#endif
+ else
+ return (0);
+}
+
+char *
+win32_to_x_charset (fncharset)
+ int fncharset;
+{
+ switch (fncharset)
+ {
+ case ANSI_CHARSET: return "ansi";
+ case OEM_CHARSET: return "oem";
+ case SYMBOL_CHARSET: return "symbol";
+#ifdef UNICODE_CHARSET
+ case UNICODE_CHARSET: return "unicode";
+#endif
+ }
+ return "*";
}
BOOL
@@ -3294,29 +3533,25 @@ win32_to_x_font (lplogfont, lpxstr, len)
{
if (!lpxstr) return (FALSE);
- if (lplogfont)
+ if (lplogfont)
{
- int height = (lplogfont->lfHeight * 1440)
- / one_win32_display_info.height_in;
- int width = (lplogfont->lfWidth * 1440)
- / one_win32_display_info.width_in;
-
- height = abs (height);
_snprintf (lpxstr, len - 1,
- "-*-%s-%s-%c-%s-%s-*-%d-*-*-%c-%d-*-*-",
+ "-*-%s-%s-%c-*-*-%d-%d-*-*-%c-%d-*-%s-",
lplogfont->lfFaceName,
win32_to_x_weight (lplogfont->lfWeight),
lplogfont->lfItalic ? 'i' : 'r',
- "*", "*",
- height,
+ abs (lplogfont->lfHeight),
+ (abs (lplogfont->lfHeight) * 720) / one_win32_display_info.height_in,
((lplogfont->lfPitchAndFamily & 0x3) == VARIABLE_PITCH) ? 'p' : 'c',
- width);
- }
- else
+ lplogfont->lfWidth * 10,
+ win32_to_x_charset (lplogfont->lfCharSet)
+ );
+ }
+ else
{
strncpy (lpxstr, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*-", len - 1);
}
-
+
lpxstr[len - 1] = 0; /* just to be sure */
return (TRUE);
}
@@ -3330,56 +3565,119 @@ x_to_win32_font (lpxstr, lplogfont)
memset (lplogfont, 0, sizeof (*lplogfont));
- lplogfont->lfCharSet = OEM_CHARSET;
lplogfont->lfOutPrecision = OUT_DEFAULT_PRECIS;
lplogfont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
lplogfont->lfQuality = DEFAULT_QUALITY;
- if (lpxstr && *lpxstr == '-') lpxstr++;
+ if (!lpxstr)
+ return FALSE;
+
+ /* Provide a simple escape mechanism for specifying Windows font names
+ * directly -- if font spec does not beginning with '-', assume this
+ * format:
+ * "<font name>[:height in pixels[:width in pixels[:weight]]]"
+ */
- {
- int fields;
- char name[50], weight[20], slant, pitch, height[10], width[10];
-
- fields = (lpxstr
- ? sscanf (lpxstr,
- "%*[^-]-%[^-]-%[^-]-%c-%*[^-]-%*[^-]-%*[^-]-%[^-]-%*[^-]-%*[^-]-%c-%[^-]",
- name, weight, &slant, height, &pitch, width)
- : 0);
-
- if (fields == EOF) return (FALSE);
-
- if (fields > 0 && name[0] != '*')
- {
- strncpy (lplogfont->lfFaceName, name, LF_FACESIZE);
- }
- else
- {
+ if (*lpxstr == '-')
+ {
+ int fields;
+ char name[50], weight[20], slant, pitch, pixels[10], height[10], width[10], remainder[20];
+ char * encoding;
+
+ fields = sscanf (lpxstr,
+ "-%*[^-]-%49[^-]-%19[^-]-%c-%*[^-]-%*[^-]-%9[^-]-%9[^-]-%*[^-]-%*[^-]-%c-%9[^-]-%19s",
+ name, weight, &slant, pixels, height, &pitch, width, remainder);
+
+ if (fields == EOF) return (FALSE);
+
+ if (fields > 0 && name[0] != '*')
+ {
+ strncpy (lplogfont->lfFaceName,name, LF_FACESIZE);
+ lplogfont->lfFaceName[LF_FACESIZE-1] = 0;
+ }
+ else
lplogfont->lfFaceName[0] = 0;
+
+ fields--;
+
+ lplogfont->lfWeight = x_to_win32_weight((fields > 0 ? weight : ""));
+
+ fields--;
+
+ if (!NILP (Vwin32_enable_italics))
+ lplogfont->lfItalic = (fields > 0 && slant == 'i');
+
+ fields--;
+
+ if (fields > 0 && pixels[0] != '*')
+ lplogfont->lfHeight = atoi (pixels);
+
+ fields--;
+
+ if (fields > 0 && lplogfont->lfHeight == 0 && height[0] != '*')
+ lplogfont->lfHeight = (atoi (height)
+ * one_win32_display_info.height_in) / 720;
+
+ fields--;
+
+ lplogfont->lfPitchAndFamily =
+ (fields > 0 && pitch == 'p') ? VARIABLE_PITCH : FIXED_PITCH;
+
+ fields--;
+
+ if (fields > 0 && width[0] != '*')
+ lplogfont->lfWidth = atoi (width) / 10;
+
+ fields--;
+
+ /* Not all font specs include the registry field, so we allow for an
+ optional registry field before the encoding when parsing
+ remainder. Also we strip the trailing '-' if present. */
+ {
+ int len = strlen (remainder);
+ if (len > 0 && remainder[len-1] == '-')
+ remainder[len-1] = 0;
}
-
- fields--;
-
- lplogfont->lfWeight = x_to_win32_weight((fields > 0 ? weight : ""));
-
- fields--;
-
- lplogfont->lfItalic = (fields > 0 && slant == 'i');
-
- fields--;
-
- if (fields > 0 && height[0] != '*')
- lplogfont->lfHeight = (atoi (height) * one_win32_display_info.height_in) / 1440;
-
- fields--;
-
- lplogfont->lfPitchAndFamily = (fields > 0 && pitch == 'p') ? VARIABLE_PITCH : FIXED_PITCH;
-
- fields--;
-
- if (fields > 0 && width[0] != '*')
- lplogfont->lfWidth = (atoi (width) * one_win32_display_info.width_in) / 1440;
- }
+ encoding = remainder;
+ if (strncmp (encoding, "*-", 2) == 0)
+ encoding += 2;
+ lplogfont->lfCharSet = x_to_win32_charset (fields > 0 ? encoding : "");
+ }
+ else
+ {
+ int fields;
+ char name[100], height[10], width[10], weight[20];
+
+ fields = sscanf (lpxstr,
+ "%99[^:]:%9[^:]:%9[^:]:%19s",
+ name, height, width, weight);
+
+ if (fields == EOF) return (FALSE);
+
+ if (fields > 0)
+ {
+ strncpy (lplogfont->lfFaceName,name, LF_FACESIZE);
+ lplogfont->lfFaceName[LF_FACESIZE-1] = 0;
+ }
+ else
+ {
+ lplogfont->lfFaceName[0] = 0;
+ }
+
+ fields--;
+
+ if (fields > 0)
+ lplogfont->lfHeight = atoi (height);
+
+ fields--;
+
+ if (fields > 0)
+ lplogfont->lfWidth = atoi (width);
+
+ fields--;
+
+ lplogfont->lfWeight = x_to_win32_weight ((fields > 0 ? weight : ""));
+ }
return (TRUE);
}
@@ -3573,7 +3871,7 @@ even if they match PATTERN and FACE.")
ef.numFonts = 0;
{
- ef.hdc = my_get_dc (FRAME_WIN32_WINDOW (f));
+ ef.hdc = GetDC (FRAME_WIN32_WINDOW (f));
EnumFontFamilies (ef.hdc, NULL, (FONTENUMPROC) enum_font_cb1, (LPARAM)&ef);
@@ -3759,9 +4057,11 @@ If omitted or nil, that stands for the selected frame's display.")
HDC hdc;
int cap;
- hdc = my_get_dc (dpyinfo->root_window);
-
- cap = GetDeviceCaps (hdc,NUMCOLORS);
+ hdc = GetDC (dpyinfo->root_window);
+ if (dpyinfo->has_palette)
+ cap = GetDeviceCaps (hdc, SIZEPALETTE);
+ else
+ cap = GetDeviceCaps (hdc, NUMCOLORS);
ReleaseDC (dpyinfo->root_window, hdc);
@@ -3840,10 +4140,8 @@ If omitted or nil, that stands for the selected frame's display.")
HDC hdc;
int cap;
- hdc = my_get_dc (dpyinfo->root_window);
-
+ hdc = GetDC (dpyinfo->root_window);
cap = GetDeviceCaps (hdc, VERTSIZE);
-
ReleaseDC (dpyinfo->root_window, hdc);
return make_number (cap);
@@ -3862,10 +4160,8 @@ If omitted or nil, that stands for the selected frame's display.")
HDC hdc;
int cap;
- hdc = my_get_dc (dpyinfo->root_window);
-
+ hdc = GetDC (dpyinfo->root_window);
cap = GetDeviceCaps (hdc, HORZSIZE);
-
ReleaseDC (dpyinfo->root_window, hdc);
return make_number (cap);
@@ -4014,12 +4310,22 @@ terminate Emacs if we can't open the connection.")
unsigned int n_planes;
unsigned char *xrm_option;
struct win32_display_info *dpyinfo;
+ Lisp_Object color_file = Qnil;
CHECK_STRING (display, 0);
if (! NILP (xrm_string))
CHECK_STRING (xrm_string, 1);
- Vwin32_color_map = Fwin32_default_color_map ();
+ /* Allow color mapping to be defined externally; first look in user's
+ HOME directory, then in Emacs etc dir for a file called rgb.txt. */
+ color_file = build_string ("~/rgb.txt");
+ if (NILP (color_file) || NILP (Ffile_readable_p (color_file)))
+ color_file = concat2 (Vdoc_directory, build_string ("rgb.txt"));
+
+ Vwin32_color_map = Fwin32_load_color_file (color_file);
+
+ if (NILP (Vwin32_color_map))
+ Vwin32_color_map = Fwin32_default_color_map ();
if (! NILP (xrm_string))
xrm_option = (unsigned char *) XSTRING (xrm_string)->data;
@@ -4039,8 +4345,7 @@ terminate Emacs if we can't open the connection.")
if (dpyinfo == 0)
{
if (!NILP (must_succeed))
- fatal ("Cannot connect to server %s.\n",
- XSTRING (display)->data);
+ fatal ("Cannot connect to server %s.\n", XSTRING (display)->data);
else
error ("Cannot connect to server %s", XSTRING (display)->data);
}
@@ -4131,7 +4436,7 @@ DEFUN ("win32-select-font", Fwin32_select_font, Swin32_select_font, 0, 1, 0,
cf.lpLogFont = &lf;
if (!ChooseFont (&cf) || !win32_to_x_font (&lf, buf, 100))
- return Qnil;
+ return Qnil;
return build_string (buf);
}
@@ -4219,6 +4524,14 @@ syms_of_win32fns ()
"A array of color name mappings for windows.");
Vwin32_color_map = Qnil;
+ DEFVAR_LISP ("win32-enable-italics", &Vwin32_enable_italics,
+ "Non-nil enables selection of artificially italicized fonts.");
+ Vwin32_enable_italics = Qnil;
+
+ DEFVAR_LISP ("win32-enable-palette", &Vwin32_enable_palette,
+ "Non-nil enables Windows palette management to map colors exactly.");
+ Vwin32_enable_palette = Qt;
+
init_x_parm_symbols ();
DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
@@ -4294,6 +4607,8 @@ unless you set it to something else.");
/* Win32 specific functions */
defsubr (&Swin32_select_font);
+ defsubr (&Swin32_define_rgb_color);
+ defsubr (&Swin32_load_color_file);
}
#undef abort
@@ -4301,9 +4616,9 @@ unless you set it to something else.");
void
win32_abort()
{
- MessageBox (NULL,
- "A fatal error has occurred - aborting!",
- "Emacs Abort Dialog",
- MB_OK|MB_ICONEXCLAMATION);
- abort();
+ MessageBox (NULL,
+ "A fatal error has occurred - aborting!",
+ "Emacs Abort Dialog",
+ MB_OK | MB_ICONEXCLAMATION);
+ abort();
}