/* Implementation of GUI terminal on the Microsoft W32 API.
Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
+#include <setjmp.h>
#include "lisp.h"
#include "blockinput.h"
#include "w32term.h"
#include <ctype.h>
#include <errno.h>
-#include <setjmp.h>
#include <sys/stat.h>
+#include <imm.h>
#include "charset.h"
#include "character.h"
#include "keymap.h"
#include "w32heap.h"
-#include "w32bdf.h"
#include <shellapi.h>
#include "font.h"
/* Last window where we saw the mouse. Used by mouse-autoselect-window. */
static Lisp_Object last_window;
-/* Non-zero means make use of UNDERLINE_POSITION font properties.
- (Not yet supported, see TODO in x_draw_glyph_string.) */
+/* Non-zero means make use of UNDERLINE_POSITION font properties. */
int x_use_underline_position_properties;
/* Non-zero means to draw the underline at the same place as the descent line. */
extern int w32_codepage_for_font (char *fontname);
extern Cursor w32_load_cursor (LPCTSTR name);
-extern glyph_metric *w32_BDF_TextMetric(bdffont *fontp,
- unsigned char *text, int dim);
extern Lisp_Object Vwindow_system;
#define x_any_window_to_frame x_window_to_frame
#endif
-/* Dynamic linking to GetFontUnicodeRanges (not available on 95, 98, ME). */
-DWORD (PASCAL *pfnGetFontUnicodeRanges) (HDC device, GLYPHSET *ranges);
+/* Dynamic linking to SetLayeredWindowAttribute (only since 2000). */
+BOOL (WINAPI *pfnSetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
+
+#ifndef LWA_ALPHA
+#define LWA_ALPHA 0x02
+#endif
+/* WS_EX_LAYERED is defined unconditionally by MingW, but only for W2K and
+ later targets by MSVC headers. */
+#ifndef WS_EX_LAYERED
+#define WS_EX_LAYERED 0x80000
+#endif
/* Frame being updated by update_frame. This is declared in term.c.
This is set by update_begin and looked at by all the
int w32_system_caret_y;
int w32_use_visible_system_caret;
-/* Flag to enable Unicode output in case users wish to use programs
- like Twinbridge on '95 rather than installed system level support
- for Far East languages. */
-int w32_enable_unicode_output;
-
-/* Flag to enable Cleartype hack for font metrics. */
-static int cleartype_active;
-
DWORD dwWindowsThreadId = 0;
HANDLE hWindowsThread = NULL;
DWORD dwMainThreadId = 0;
/* Mouse movement. */
/* Where the mouse was last time we reported a mouse event. */
-
static RECT last_mouse_glyph;
static FRAME_PTR last_mouse_glyph_frame;
static Lisp_Object last_mouse_press_frame;
along with the position query. So, we just keep track of the time
of the last movement we received, and return that in hopes that
it's somewhat accurate. */
-
static Time last_mouse_movement_time;
/* Incremented by w32_read_socket whenever it really tries to read
events. */
-
#ifdef __STDC__
static int volatile input_signal_count;
#else
#endif
/* A mask of extra modifier bits to put into every keyboard char. */
-
extern EMACS_INT extra_keyboard_modifiers;
+/* Keyboard code page - may be changed by language-change events. */
+static int keyboard_codepage;
+
static void x_update_window_end P_ ((struct window *, int, int));
static void w32_handle_tool_bar_click P_ ((struct frame *,
struct input_event *));
void x_wm_set_window_state P_ ((struct frame *, int));
void x_wm_set_icon_pixmap P_ ((struct frame *, int));
static void w32_initialize P_ ((void));
-static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
-int x_compute_min_glyph_bounds P_ ((struct frame *));
static void x_update_end P_ ((struct frame *));
static void w32_frame_up_to_date P_ ((struct frame *));
static void w32_set_terminal_modes P_ ((struct terminal *));
release_frame_dc (f, hdc);
}
+#define OPAQUE_FRAME 255
+
+void
+x_set_frame_alpha (f)
+ struct frame *f;
+{
+ struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
+ double alpha = 1.0;
+ double alpha_min = 1.0;
+ BYTE opac;
+ LONG ex_style;
+ HWND window = FRAME_W32_WINDOW (f);
+
+ /* Older versions of Windows do not support transparency. */
+ if (!pfnSetLayeredWindowAttributes)
+ return;
+
+ if (dpyinfo->x_highlight_frame == f)
+ alpha = f->alpha[0];
+ else
+ alpha = f->alpha[1];
+
+ if (FLOATP (Vframe_alpha_lower_limit))
+ alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
+ else if (INTEGERP (Vframe_alpha_lower_limit))
+ alpha_min = (XINT (Vframe_alpha_lower_limit)) / 100.0;
+
+ if (alpha < 0.0)
+ return;
+ else if (alpha > 1.0)
+ alpha = 1.0;
+ else if (alpha < alpha_min && alpha_min <= 1.0)
+ alpha = alpha_min;
+
+ opac = alpha * OPAQUE_FRAME;
+
+ ex_style = GetWindowLong (window, GWL_EXSTYLE);
+
+ if (opac == OPAQUE_FRAME)
+ ex_style &= ~WS_EX_LAYERED;
+ else
+ ex_style |= WS_EX_LAYERED;
+
+ SetWindowLong (window, GWL_EXSTYLE, ex_style);
+
+ if (opac != OPAQUE_FRAME)
+ pfnSetLayeredWindowAttributes (window, 0, opac, LWA_ALPHA);
+}
+
+int
+x_display_pixel_height (dpyinfo)
+ struct w32_display_info *dpyinfo;
+{
+ HDC dc = GetDC (NULL);
+ int pixels = GetDeviceCaps (dc, VERTRES);
+ ReleaseDC (NULL, dc);
+ return pixels;
+}
+
+int
+x_display_pixel_width (dpyinfo)
+ struct w32_display_info *dpyinfo;
+{
+ HDC dc = GetDC (NULL);
+ int pixels = GetDeviceCaps (dc, HORZRES);
+ ReleaseDC (NULL, dc);
+ return pixels;
+}
+
\f
/***********************************************************************
Starting and ending an update
{
int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
- /* Internal border is drawn below the tool bar. */
- if (WINDOWP (f->tool_bar_window)
- && w == XWINDOW (f->tool_bar_window))
- y -= width;
-
BLOCK_INPUT;
{
HDC hdc = get_frame_dc (f);
if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
|| s->font_not_found_p
|| s->extends_to_end_of_line_p
- || FONT_COMPAT (s->font)->bdf
- || cleartype_active
|| force_p)
{
x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
struct glyph_string *s;
{
int i, x;
- HFONT old_font;
/* If first glyph of S has a left box line, start drawing the text
of S to the right of that box line. */
else
x = s->x;
- if (s->for_overlaps || (s->background_filled_p && s->hl != DRAW_CURSOR)
- || cleartype_active)
- SetBkMode (s->hdc, TRANSPARENT);
- else
- SetBkMode (s->hdc, OPAQUE);
-
SetTextColor (s->hdc, s->gc->foreground);
SetBkColor (s->hdc, s->gc->background);
SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
- if (s->font && FONT_COMPAT (s->font)->hfont)
- old_font = SelectObject (s->hdc, FONT_COMPAT (s->font)->hfont);
-
/* Draw characters of S as rectangles if S's font could not be
loaded. */
if (s->font_not_found_p)
}
else
{
- int boff = s->font->baseline_offset;
struct font *font = s->font;
+ int boff = font->baseline_offset;
int y;
+ HFONT old_font;
+
+ old_font = SelectObject (s->hdc, FONT_HANDLE (font));
- if (s->font->vertical_centering)
- boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff;
+ if (font->vertical_centering)
+ boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
y = s->ybase - boff;
if (s->for_overlaps
font->driver->draw (s, 0, s->nchars, x, y, 1);
if (s->face->overstrike)
font->driver->draw (s, 0, s->nchars, x + 1, y, 0);
- }
- if (s->font && FONT_COMPAT (s->font)->hfont)
- SelectObject (s->hdc, old_font);
+ SelectObject (s->hdc, old_font);
+ }
}
/* Draw the foreground of composite glyph string S. */
struct glyph_string *s;
{
int i, j, x;
- HFONT old_font;
+ struct font *font = s->font;
/* If first glyph of S has a left box line, start drawing the text
of S to the right of that box line. */
else
x = s->x;
- /* S is a glyph string for a composition. S->gidx is the index of
- the first character drawn for glyphs of this composition.
- S->gidx == 0 means we are drawing the very first character of
+ /* S is a glyph string for a composition. S->cmp_from is the index
+ of the first character drawn for glyphs of this composition.
+ S->cmp_from == 0 means we are drawing the very first character of
this composition. */
SetTextColor (s->hdc, s->gc->foreground);
SetBkColor (s->hdc, s->gc->background);
- SetBkMode (s->hdc, TRANSPARENT);
SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
- if (s->font && FONT_COMPAT (s->font)->hfont)
- old_font = SelectObject (s->hdc, FONT_COMPAT (s->font)->hfont);
-
/* Draw a rectangle for the composition if the font for the very
first character of the composition could not be loaded. */
if (s->font_not_found_p)
{
- if (s->gidx == 0)
+ if (s->cmp_from == 0)
w32_draw_rectangle (s->hdc, s->gc, x, s->y, s->width - 1,
s->height - 1);
}
+ else if (! s->first_glyph->u.cmp.automatic)
+ {
+ int y = s->ybase;
+ int width = 0;
+ HFONT old_font;
+ old_font = SelectObject (s->hdc, FONT_HANDLE (font));
+
+ for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
+ if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
+ {
+ int xx = x + s->cmp->offsets[j * 2];
+ int yy = y - s->cmp->offsets[j * 2 + 1];
+
+ font->driver->draw (s, j, j + 1, xx, yy, 0);
+ if (s->face->overstrike)
+ font->driver->draw (s, j, j + 1, xx + 1, yy, 0);
+ }
+ SelectObject (s->hdc, old_font);
+ }
+ else
{
- struct font *font = s->font;
+ Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
+ Lisp_Object glyph;
int y = s->ybase;
int width = 0;
+ HFONT old_font;
- if (s->cmp->method == COMPOSITION_WITH_GLYPH_STRING)
- {
- Lisp_Object gstring = AREF (XHASH_TABLE (composition_hash_table)
- ->key_and_value,
- s->cmp->hash_index * 2);
- int from;
+ old_font = SelectObject (s->hdc, FONT_HANDLE (font));
- for (i = from = 0; i < s->nchars; i++)
+ for (i = j = s->cmp_from; i < s->cmp_to; i++)
+ {
+ glyph = LGSTRING_GLYPH (gstring, i);
+ if (NILP (LGLYPH_ADJUSTMENT (glyph)))
+ width += LGLYPH_WIDTH (glyph);
+ else
{
- Lisp_Object g = LGSTRING_GLYPH (gstring, i);
- Lisp_Object adjustment = LGLYPH_ADJUSTMENT (g);
int xoff, yoff, wadjust;
- if (! VECTORP (adjustment))
- {
- width += LGLYPH_WIDTH (g);
- continue;
- }
- if (from < i)
+ if (j < i)
{
- font->driver->draw (s, from, i, x, y, 0);
+ font->driver->draw (s, j, i, x, y, 0);
x += width;
}
- xoff = XINT (AREF (adjustment, 0));
- yoff = XINT (AREF (adjustment, 1));
- wadjust = XINT (AREF (adjustment, 2));
-
+ xoff = LGLYPH_XOFF (glyph);
+ yoff = LGLYPH_YOFF (glyph);
+ wadjust = LGLYPH_WADJUST (glyph);
font->driver->draw (s, i, i + 1, x + xoff, y + yoff, 0);
x += wadjust;
- from = i + 1;
+ j = i + 1;
width = 0;
}
- if (from < i)
- font->driver->draw (s, from, i, x, y, 0);
}
- else
- {
- for (i = 0, j = s->gidx; i < s->nchars; i++, j++)
- if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
- {
- int xx = x + s->cmp->offsets[j * 2];
- int yy = y - s->cmp->offsets[j * 2 + 1];
+ if (j < i)
+ font->driver->draw (s, j, i, x, y, 0);
- font->driver->draw (s, j, j + 1, xx, yy, 0);
- if (s->face->overstrike)
- font->driver->draw (s, j, j + 1, xx + 1, yy, 0);
- }
- }
+ SelectObject (s->hdc, old_font);
}
-
- if (s->font && FONT_COMPAT (s->font)->hfont)
- SelectObject (s->hdc, old_font);
}
return 1;
}
+/* On frame F, translate pixel colors to RGB values for the NCOLORS
+ colors in COLORS. On W32, we no longer try to map colors to
+ a palette. */
+void
+x_query_colors (f, colors, ncolors)
+ struct frame *f;
+ XColor *colors;
+ int ncolors;
+{
+ int i;
+
+ for (i = 0; i < ncolors; i++)
+ {
+ DWORD pixel = colors[i].pixel;
+ /* Convert to a 16 bit value in range 0 - 0xffff. */
+ colors[i].red = GetRValue (pixel) * 257;
+ colors[i].green = GetGValue (pixel) * 257;
+ colors[i].blue = GetBValue (pixel) * 257;
+ }
+}
+
+void
+x_query_color (f, color)
+ struct frame *f;
+ XColor *color;
+{
+ x_query_colors (f, color, 1);
+}
+
/* Set up the foreground color for drawing relief lines of glyph
string S. RELIEF is a pointer to a struct relief containing the GC
{
int width;
struct glyph_string *next;
- for (width = 0, next = s->next; next;
+ for (width = 0, next = s->next;
+ next && width < s->right_overhang;
width += next->width, next = next->next)
if (next->first_glyph->type != IMAGE_GLYPH)
{
x_set_glyph_string_gc (next);
x_set_glyph_string_clipping (next);
- x_draw_glyph_string_background (next, 1);
+ if (next->first_glyph->type == STRETCH_GLYPH)
+ x_draw_stretch_glyph_string (next);
+ else
+ x_draw_glyph_string_background (next, 1);
next->num_clips = 0;
}
}
break;
case COMPOSITE_GLYPH:
- if (s->for_overlaps || s->gidx > 0)
+ if (s->for_overlaps || (s->cmp_from > 0
+ && ! s->first_glyph->u.cmp.automatic))
s->background_filled_p = 1;
else
x_draw_glyph_string_background (s, 1);
if (s->face->underline_defaulted_p)
{
w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
- y, s->background_width, 1);
+ y, s->width, 1);
}
else
{
w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
- y, s->background_width, 1);
+ y, s->width, 1);
}
}
/* Draw overline. */
if (s->face->overline_color_defaulted_p)
{
w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
- s->y + dy, s->background_width, h);
+ s->y + dy, s->width, h);
}
else
{
w32_fill_area (s->f, s->hdc, s->face->overline_color, s->x,
- s->y + dy, s->background_width, h);
+ s->y + dy, s->width, h);
}
}
/* Draw strike-through. */
if (s->face->strike_through_p
- && (FONT_COMPAT (s->font)->bdf
- || !FONT_COMPAT (s->font)->tm.tmStruckOut))
+ && !FONT_TEXTMETRIC(s->font).tmStruckOut)
{
unsigned long h = 1;
unsigned long dy = (s->height - h) / 2;
struct frame *f;
{
x_update_cursor (f, 1);
+ x_set_frame_alpha (f);
}
static void
struct frame *f;
{
x_update_cursor (f, 1);
+ x_set_frame_alpha (f);
}
/* The focus has changed. Update the frames as necessary to reflect
return value;
}
+static int codepage_for_locale(LCID locale)
+{
+ char cp[20];
+
+ if (GetLocaleInfo (locale, LOCALE_IDEFAULTANSICODEPAGE, cp, 20) > 0)
+ return atoi (cp);
+ else
+ return CP_ACP;
+}
\f
/* Mouse clicks and mouse movement. Rah. */
switch (msg.msg.message)
{
- case WM_PAINT:
+ case WM_EMACS_PAINT:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f)
/* Generate a language change event. */
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
+ /* lParam contains the input lang ID. Use it to update our
+ record of the keyboard codepage. */
+ keyboard_codepage = codepage_for_locale ((LCID)(msg.msg.lParam
+ & 0xffff));
+
if (f)
{
inev.kind = LANGUAGE_CHANGE_EVENT;
{
dbcs[0] = dbcs_lead;
dbcs_lead = 0;
- if (!MultiByteToWideChar (CP_ACP, 0, dbcs, 2, &code, 1))
+ if (!MultiByteToWideChar (keyboard_codepage, 0,
+ dbcs, 2, &code, 1))
{
/* Garbage */
DebPrint (("Invalid DBCS sequence: %d %d\n",
break;
}
}
- else if (IsDBCSLeadByteEx (CP_ACP, (BYTE) msg.msg.wParam))
+ else if (IsDBCSLeadByteEx (keyboard_codepage,
+ (BYTE) msg.msg.wParam))
{
dbcs_lead = (char) msg.msg.wParam;
inev.kind = NO_EVENT;
}
else
{
- if (!MultiByteToWideChar (CP_ACP, 0, &dbcs[1], 1,
- &code, 1))
+ if (!MultiByteToWideChar (keyboard_codepage, 0,
+ &dbcs[1], 1, &code, 1))
{
/* What to do with garbage? */
DebPrint (("Invalid character: %d\n", dbcs[1]));
if (f)
{
- dpyinfo->width = (short) LOWORD (msg.msg.lParam);
- dpyinfo->height = (short) HIWORD (msg.msg.lParam);
dpyinfo->n_cbits = msg.msg.wParam;
- DebPrint (("display change: %d %d\n", dpyinfo->width,
- dpyinfo->height));
+ DebPrint (("display change: %d %d\n",
+ (short) LOWORD (msg.msg.lParam),
+ (short) HIWORD (msg.msg.lParam)));
}
check_visibility = 1;
{
struct frame *f = XFRAME (w->frame);
struct glyph *cursor_glyph;
- int x;
- HDC hdc;
/* If cursor is out of bounds, don't draw garbage. This can happen
in mini-buffer windows when switching between echo area glyphs
{
COLORREF cursor_color = f->output_data.w32->cursor_pixel;
struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
+ int x;
+ HDC hdc;
/* If the glyph's background equals the color we normally draw
the bar cursor in, the bar cursor in its normal color is
x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
- if (width < 0)
- width = FRAME_CURSOR_WIDTH (f);
- width = min (cursor_glyph->pixel_width, width);
-
- w->phys_cursor_width = width;
-
-
hdc = get_frame_dc (f);
w32_clip_to_row (w, row, TEXT_AREA, hdc);
if (kind == BAR_CURSOR)
{
+ if (width < 0)
+ width = FRAME_CURSOR_WIDTH (f);
+ width = min (cursor_glyph->pixel_width, width);
+
+ w->phys_cursor_width = width;
+
w32_fill_area (f, hdc, cursor_color, x,
WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
width, row->height);
}
else
{
+ int dummy_x, dummy_y, dummy_h;
+
+ if (width < 0)
+ width = row->height;
+
+ width = min (row->height, width);
+
+ get_phys_cursor_geometry (w, row, cursor_glyph, &dummy_x,
+ &dummy_y, &dummy_h);
w32_fill_area (f, hdc, cursor_color, x,
WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
row->height - width),
- cursor_glyph->pixel_width, width);
+ w->phys_cursor_width, width);
}
w32_set_clip_rectangle (hdc, NULL);
= (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
+ glyph_row->ascent - w->phys_cursor_ascent);
+ PostMessage (hwnd, WM_IME_STARTCOMPOSITION, 0, 0);
+
/* If the size of the active cursor changed, destroy the old
system caret. */
if (w32_system_caret_hwnd
if (FRAME_FONT (f) == font)
/* This font is already set in frame F. There's nothing more to
do. */
- return fontset_name (fontset);
-
- BLOCK_INPUT;
+ return font_object;
FRAME_FONT (f) = font;
FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
}
-#ifdef HAVE_X_I18N
- if (FRAME_XIC (f)
- && (FRAME_XIC_STYLE (f) & (XIMPreeditPosition | XIMStatusArea)))
- xic_set_xfontset (f, SDATA (fontset_ascii (fontset)));
-#endif
-
- UNBLOCK_INPUT;
+ /* X version sets font of input methods here also. */
- return fontset_name (fontset);
+ return font_object;
}
\f
/* Treat negative positions as relative to the rightmost bottommost
position that fits on the screen. */
if (flags & XNegative)
- f->left_pos = (FRAME_W32_DISPLAY_INFO (f)->width
+ f->left_pos = (x_display_pixel_width (FRAME_W32_DISPLAY_INFO (f))
- FRAME_PIXEL_WIDTH (f)
+ f->left_pos
- (left_right_borders_width - 1));
if (flags & YNegative)
- f->top_pos = (FRAME_W32_DISPLAY_INFO (f)->height
+ f->top_pos = (x_display_pixel_height (FRAME_W32_DISPLAY_INFO (f))
- FRAME_PIXEL_HEIGHT (f)
+ f->top_pos
- (top_bottom_borders_height - 1));
resize will happen asynchronously. But on Windows, the menu bar
automatically wraps when the frame is too narrow to contain it,
and that causes any calculations made here to come out wrong. The
- end is some nasty buggy behaviour, including the potential loss
+ end is some nasty buggy behavior, including the potential loss
of the minibuffer.
Disabling this code is either not sufficient to fix the problems
BLOCK_INPUT;
/* Strictly speaking, raise-frame should only change the frame's Z
- order, leaving input focus unchanged. This is reasonable behaviour
+ order, leaving input focus unchanged. This is reasonable behavior
on X where the usual policy is point-to-focus. However, this
- behaviour would be very odd on Windows where the usual policy is
+ behavior would be very odd on Windows where the usual policy is
click-to-focus.
On X, if the mouse happens to be over the raised frame, it gets
with values obtained from system metrics. */
dpyinfo->resx = 1;
dpyinfo->resy = 1;
- dpyinfo->height_in = 1;
- dpyinfo->width_in = 1;
dpyinfo->n_planes = 1;
dpyinfo->n_cbits = 4;
dpyinfo->n_fonts = 0;
terminal->memory_below_frame = 0; /* We don't remember what scrolls
off the bottom. */
-#ifdef MULTI_KBOARD
/* We don't yet support separate terminals on W32, so don't try to share
keyboards between virtual terminals that are on the same physical
terminal like X does. */
if (current_kboard == initial_kboard)
current_kboard = terminal->kboard;
terminal->kboard->reference_count++;
-#endif
return terminal;
}
struct w32_display_info *dpyinfo = terminal->display_info.w32;
int i;
- /* Protect against recursive calls. Fdelete_frame in
+ /* Protect against recursive calls. delete_frame in
delete_terminal calls us back when it deletes our last frame. */
if (!terminal->name)
return;
dpyinfo->next = x_display_list;
x_display_list = dpyinfo;
- hdc = GetDC (GetDesktopWindow ());
+ hdc = GetDC (NULL);
- dpyinfo->height = GetDeviceCaps (hdc, VERTRES);
- dpyinfo->width = GetDeviceCaps (hdc, HORZRES);
dpyinfo->root_window = GetDesktopWindow ();
dpyinfo->n_planes = GetDeviceCaps (hdc, PLANES);
dpyinfo->n_cbits = GetDeviceCaps (hdc, BITSPIXEL);
dpyinfo->resx = GetDeviceCaps (hdc, LOGPIXELSX);
dpyinfo->resy = GetDeviceCaps (hdc, LOGPIXELSY);
dpyinfo->has_palette = GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE;
- dpyinfo->terminal->image_cache = make_image_cache ();
- dpyinfo->height_in = dpyinfo->height / dpyinfo->resx;
- dpyinfo->width_in = dpyinfo->width / dpyinfo->resy;
- ReleaseDC (GetDesktopWindow (), hdc);
+ ReleaseDC (NULL, hdc);
/* initialise palette with white and black */
{
static void
w32_initialize ()
{
+ HANDLE shell;
+ HRESULT (WINAPI * set_user_model) (wchar_t * id);
+
baud_rate = 19200;
w32_system_caret_hwnd = NULL;
w32_system_caret_x = 0;
w32_system_caret_y = 0;
+ /* On Windows 7 and later, we need to set the user model ID
+ to associate emacsclient launched files with Emacs frames
+ in the UI. */
+ shell = GetModuleHandle ("shell32.dll");
+ if (shell)
+ {
+ set_user_model
+ = (void *) GetProcAddress (shell,
+ "SetCurrentProcessExplicitAppUserModelID");
+
+ /* If the function is defined, then we are running on Windows 7
+ or newer, and the UI uses this to group related windows
+ together. Since emacs, runemacs, emacsclient are related, we
+ want them grouped even though the executables are different,
+ so we need to set a consistent ID between them. */
+ if (set_user_model)
+ set_user_model (L"GNU.Emacs");
+ }
+
/* Initialize w32_use_visible_system_caret based on whether a screen
reader is in use. */
if (!SystemParametersInfo (SPI_GETSCREENREADER, 0,
8 bit character input, standard quit char. */
Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
- /* Create the window thread - it will terminate itself or when the app terminates */
+ {
+ DWORD input_locale_id = (DWORD) GetKeyboardLayout (0);
+ keyboard_codepage = codepage_for_locale ((LCID) (input_locale_id & 0xffff));
+ }
+ /* Create the window thread - it will terminate itself when the app
+ terminates */
init_crit ();
dwMainThreadId = GetCurrentThreadId ();
GetCurrentProcess (), &hMainThread, 0, TRUE, DUPLICATE_SAME_ACCESS);
/* Wait for thread to start */
-
{
MSG msg;
/* Dynamically link to optional system components. */
{
- UINT smoothing_type;
- BOOL smoothing_enabled;
-
- HANDLE gdi_lib = LoadLibrary ("gdi32.dll");
+ HMODULE user_lib = GetModuleHandle ("user32.dll");
#define LOAD_PROC(lib, fn) pfn##fn = (void *) GetProcAddress (lib, #fn)
- LOAD_PROC (gdi_lib, GetFontUnicodeRanges);
+ LOAD_PROC (user_lib, SetLayeredWindowAttributes);
#undef LOAD_PROC
- FreeLibrary (gdi_lib);
-
/* Ensure scrollbar handle is at least 5 pixels. */
vertical_scroll_bar_min_handle = 5;
effectively form the border of the main scroll bar range. */
vertical_scroll_bar_top_border = vertical_scroll_bar_bottom_border
= GetSystemMetrics (SM_CYVSCROLL);
-
- /* Constants that are not always defined by the system headers
- since they only exist on certain versions of Windows. */
-#ifndef SPI_GETFONTSMOOTHING
-#define SPI_GETFONTSMOOTHING 0x4A
-#endif
-#ifndef SPI_GETFONTSMOOTHINGTYPE
-#define SPI_GETFONTSMOOTHINGTYPE 0x0200A
-#endif
-#ifndef FE_FONTSMOOTHINGCLEARTYPE
-#define FE_FONTSMOOTHINGCLEARTYPE 0x2
-#endif
-
- /* Determine if Cleartype is in use. Used to enable a hack in
- the char metric calculations which adds extra pixels to
- compensate for the "sub-pixels" that are not counted by the
- system APIs. */
- cleartype_active =
- SystemParametersInfo (SPI_GETFONTSMOOTHING, 0, &smoothing_enabled, 0)
- && smoothing_enabled
- && SystemParametersInfo (SPI_GETFONTSMOOTHINGTYPE, 0, &smoothing_type, 0)
- && smoothing_type == FE_FONTSMOOTHINGCLEARTYPE;
}
}
interpreted normally. */);
Vw32_recognize_altgr = Qt;
- DEFVAR_BOOL ("w32-enable-unicode-output",
- &w32_enable_unicode_output,
- doc: /* Enable the use of Unicode for text output if non-nil.
-Unicode output may prevent some third party applications for displaying
-Far-East Languages on Windows 95/98 from working properly.
-NT uses Unicode internally anyway, so this flag will probably have no
-effect on NT machines. */);
- w32_enable_unicode_output = 1;
-
DEFVAR_BOOL ("w32-use-visible-system-caret",
&w32_use_visible_system_caret,
doc: /* Flag to make the system caret visible.
doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
A value of nil means ignore them. If you encounter fonts with bogus
UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
-to 4.1, set this to nil.
-
-NOTE: Not supported on MS-Windows yet. */);
+to 4.1, set this to nil. */);
x_use_underline_position_properties = 0;
DEFVAR_BOOL ("x-underline-at-descent-line",