Commit 7fb46567 authored by Geoff Voelker's avatar Geoff Voelker

(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.
parent 819053bf
......@@ -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)