From 7fb46567ca81c0e50e691e1968ba1258ef3ec7f6 Mon Sep 17 00:00:00 2001 From: Geoff Voelker Date: Sun, 21 Jan 1996 00:24:03 +0000 Subject: [PATCH] (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. --- src/w32fns.c | 737 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 526 insertions(+), 211 deletions(-) diff --git a/src/w32fns.c b/src/w32fns.c index 11aaf43dd0..4e1092c692 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: + * "[: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(); } -- 2.20.1