#include <signal.h>
#include <config.h>
#include <stdio.h>
#include "lisp.h"
#include "charset.h"
#include "fontset.h"
#include "blockinput.h"
#include "w32heap.h"
#include "w32term.h"
#include <shellapi.h>
#include "systty.h"
#include "systime.h"
#include <ctype.h>
#include <errno.h>
#include <setjmp.h>
#include <sys/stat.h>
#include "frame.h"
#include "dispextern.h"
#include "termhooks.h"
#include "termopts.h"
#include "termchar.h"
#include "gnu.h"
#include "disptab.h"
#include "buffer.h"
#include "window.h"
#include "keyboard.h"
#include "intervals.h"
#include "coding.h"
#undef min
#undef max
#define min(x, y) (((x) < (y)) ? (x) : (y))
#define max(x, y) (((x) > (y)) ? (x) : (y))
#define CP_DEFAULT 1004
extern unsigned int msh_mousewheel;
extern void free_frame_menubar ();
extern Lisp_Object Vwindow_system;
#define x_any_window_to_frame x_window_to_frame
#define x_top_window_to_frame x_window_to_frame
struct w32_display_info one_w32_display_info;
Lisp_Object w32_display_name_list;
extern struct frame *updating_frame;
struct frame *pending_autoraise_frame;
static int flexlines;
static int highlight;
static int curs_x;
static int curs_y;
int w32_enable_unicode_output;
DWORD dwWindowsThreadId = 0;
HANDLE hWindowsThread = NULL;
DWORD dwMainThreadId = 0;
HANDLE hMainThread = NULL;
#ifndef SIF_ALL
#define SIF_RANGE 0x0001
#define SIF_PAGE 0x0002
#define SIF_POS 0x0004
#define SIF_DISABLENOSCROLL 0x0008
#define SIF_TRACKPOS 0x0010
#define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
typedef struct tagSCROLLINFO
{
UINT cbSize;
UINT fMask;
int nMin;
int nMax;
UINT nPage;
int nPos;
int nTrackPos;
} SCROLLINFO, FAR *LPSCROLLINFO;
typedef SCROLLINFO CONST FAR *LPCSCROLLINFO;
#endif
int (PASCAL *pfnSetScrollInfo) (HWND hwnd, int fnBar, LPSCROLLINFO lpsi, BOOL fRedraw);
BOOL (PASCAL *pfnGetScrollInfo) (HWND hwnd, int fnBar, LPSCROLLINFO lpsi);
int vertical_scroll_bar_min_handle;
int vertical_scroll_bar_top_border;
int vertical_scroll_bar_bottom_border;
int last_scroll_bar_drag_pos;
static FRAME_PTR last_mouse_frame;
static RECT last_mouse_glyph;
Lisp_Object Vw32_num_mouse_buttons;
Lisp_Object Vw32_swap_mouse_buttons;
Lisp_Object Vw32_grab_focus_on_raise;
Lisp_Object Vw32_capslock_is_shiftlock;
Lisp_Object Vw32_recognize_altgr;
Lisp_Object last_mouse_scroll_bar;
int last_mouse_scroll_bar_pos;
Time last_mouse_movement_time;
Lisp_Object Vw32_charset_to_codepage_alist;
#ifdef __STDC__
static int volatile input_signal_count;
#else
static int input_signal_count;
#endif
extern Lisp_Object Vcommand_line_args, Vsystem_name;
extern Lisp_Object Qface, Qmouse_face;
extern int errno;
extern int extra_keyboard_modifiers;
static Lisp_Object Qvendor_specific_keysyms;
void w32_delete_display ();
static void redraw_previous_char ();
static void redraw_following_char ();
static unsigned int w32_get_modifiers ();
static int fast_find_position ();
static void note_mouse_highlight ();
static void clear_mouse_face ();
static void show_mouse_face ();
static void do_line_dance ();
static void w32_clear_frame ();
static void w32_clear_end_of_line (int);
static void w32_ins_del_lines (int, int);
static void w32_change_line_highlight (int, int, int);
static void w32_insert_glyphs (GLYPH *, int);
static void w32_write_glyphs (GLYPH *, int);
static void w32_delete_glyphs (int);
static void w32_ring_bell ();
static void w32_reset_terminal_modes ();
static void w32_set_terminal_modes ();
static void w32_update_begin (FRAME_PTR);
static void w32_update_end (FRAME_PTR);
static void w32_set_terminal_window (int);
extern int w32_read_socket (int, struct input_event *, int, int);
static void w32_frame_up_to_date (FRAME_PTR);
static void w32_cursor_to (int, int);
static void w32_reassert_line_highlight (int, int);
static void w32_mouse_position (FRAME_PTR *, int, Lisp_Object *,
enum scroll_bar_part *, Lisp_Object *,
Lisp_Object *, unsigned long *);
static void w32_frame_rehighlight (FRAME_PTR);
static void w32_frame_raise_lower (FRAME_PTR, int);
static void w32_set_vertical_scroll_bar (struct window *, int, int, int);
static void w32_condemn_scroll_bars (FRAME_PTR);
static void w32_redeem_scroll_bar (struct window *);
static void w32_judge_scroll_bars (FRAME_PTR);
#if 0
struct record
{
char *locus;
int type;
};
struct record event_record[100];
int event_record_index;
record_event (locus, type)
char *locus;
int type;
{
if (event_record_index == sizeof (event_record) / sizeof (struct record))
event_record_index = 0;
event_record[event_record_index].locus = locus;
event_record[event_record_index].type = type;
event_record_index++;
}
#endif
struct w32_display_info *
w32_display_info_for_display ()
{
return (&one_w32_display_info);
}
void
w32_fill_rect (f, _hdc, pix, lprect)
FRAME_PTR f;
HDC _hdc;
COLORREF pix;
RECT * lprect;
{
HDC hdc;
HBRUSH hb;
RECT rect;
if (_hdc)
hdc = _hdc;
else
{
if (!f) return;
hdc = get_frame_dc (f);
}
hb = CreateSolidBrush (pix);
FillRect (hdc, lprect, hb);
DeleteObject (hb);
if (!_hdc)
release_frame_dc (f, hdc);
}
void
w32_clear_window (f)
FRAME_PTR f;
{
RECT rect;
GetClientRect (FRAME_W32_WINDOW (f), &rect);
w32_clear_rect (f, NULL, &rect);
}
static void
w32_update_begin (f)
struct frame *f;
{
if (f == 0)
abort ();
flexlines = f->height;
highlight = 0;
BLOCK_INPUT;
if (FRAME_W32_DISPLAY_INFO (f)->regen_palette)
{
w32_regenerate_palette (f);
FRAME_W32_DISPLAY_INFO (f)->regen_palette = FALSE;
}
if (f == FRAME_W32_DISPLAY_INFO (f)->mouse_face_mouse_frame)
{
FRAME_W32_DISPLAY_INFO (f)->mouse_face_defer = 1;
if (FRAME_GARBAGED_P (f))
FRAME_W32_DISPLAY_INFO (f)->mouse_face_window = Qnil;
if (!NILP (FRAME_W32_DISPLAY_INFO (f)->mouse_face_window))
{
int firstline, lastline, i;
struct window *w = XWINDOW (FRAME_W32_DISPLAY_INFO (f)->mouse_face_window);
for (firstline = 0; firstline < f->height; firstline++)
if (FRAME_DESIRED_GLYPHS (f)->enable[firstline])
break;
lastline = f->height;
for (i = f->height - 1; i >= 0; i--)
{
if (FRAME_DESIRED_GLYPHS (f)->enable[i])
break;
else
lastline = i;
}
if (! (firstline > (XFASTINT (w->top) + window_internal_height (w))
|| lastline < XFASTINT (w->top)))
clear_mouse_face (FRAME_W32_DISPLAY_INFO (f));
}
}
UNBLOCK_INPUT;
}
static void
w32_update_end (f)
struct frame *f;
{
BLOCK_INPUT;
do_line_dance ();
x_display_cursor (f, 1);
if (f == FRAME_W32_DISPLAY_INFO (f)->mouse_face_mouse_frame)
FRAME_W32_DISPLAY_INFO (f)->mouse_face_defer = 0;
UNBLOCK_INPUT;
}
static void
w32_frame_up_to_date (f)
FRAME_PTR f;
{
BLOCK_INPUT;
if (FRAME_W32_DISPLAY_INFO (f)->mouse_face_deferred_gc
|| f == FRAME_W32_DISPLAY_INFO (f)->mouse_face_mouse_frame)
{
note_mouse_highlight (FRAME_W32_DISPLAY_INFO (f)->mouse_face_mouse_frame,
FRAME_W32_DISPLAY_INFO (f)->mouse_face_mouse_x,
FRAME_W32_DISPLAY_INFO (f)->mouse_face_mouse_y);
FRAME_W32_DISPLAY_INFO (f)->mouse_face_deferred_gc = 0;
}
UNBLOCK_INPUT;
}
static void
w32_reassert_line_highlight (new, vpos)
int new, vpos;
{
highlight = new;
}
static void
w32_change_line_highlight (new_highlight, vpos, first_unused_hpos)
int new_highlight, vpos, first_unused_hpos;
{
highlight = new_highlight;
w32_cursor_to (vpos, 0);
w32_clear_end_of_line (updating_frame->width);
}
static void
w32_set_terminal_modes (void)
{
}
static void
w32_reset_terminal_modes (void)
{
}
static void
w32_cursor_to (row, col)
register int row, col;
{
int orow = row;
curs_x = col;
curs_y = row;
if (updating_frame == 0)
{
BLOCK_INPUT;
x_display_cursor (selected_frame, 1);
UNBLOCK_INPUT;
}
}
int
w32_codepage_for_font (char *fontname)
{
Lisp_Object codepage;
char charset_str[20], *charset, *end;
if (sscanf (fontname,
"-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%19s",
charset_str) == EOF)
return CP_DEFAULT;
if (strncmp ("*-", charset_str, 2) == 0)
charset = charset_str + 2;
else
charset = charset_str;
if (end = strchr (charset, '*'))
{
if (end > charset && *(end-1) == '-')
end--;
*end = '\0';
}
codepage = Fcdr (Fassoc (build_string(charset),
Vw32_charset_to_codepage_alist));
if (INTEGERP (codepage))
return XINT (codepage);
else
return CP_DEFAULT;
}
BOOL
w32_use_unicode_for_codepage (codepage)
{
return (w32_enable_unicode_output
&& codepage != CP_DEFAULT && IsValidCodePage (codepage));
}
#define BUILD_WCHAR_T(byte1, byte2) \
((wchar_t)(((byte1 & 0x00ff) << 8) | (byte2 & 0x00ff)))
#define BYTE1(ch) \
((ch & 0xff00) >> 8)
#define BYTE2(ch) \
(ch & 0x00ff)
#define W32_TEXTOUT(start_offset,nchars) \
{ \
int charset_dim = CHARSET_DIMENSION(charset); \
if (font->bdf) \
w32_BDF_TextOut (font->bdf, hdc, left + xoffset, \
top + yoffset, \
x_1byte_buffer + start_offset, \
charset_dim, nchars, 0); \
else if (print_via_unicode) \
ExtTextOutW (hdc, left + xoffset, top + yoffset, \
fuOptions, clip_region, \
x_2byte_buffer + start_offset, nchars, NULL); \
else \
ExtTextOut (hdc, left + xoffset, top + yoffset, \
fuOptions, clip_region, \
x_1byte_buffer + start_offset, \
nchars * charset_dim, NULL); \
start_offset += nchars * (print_via_unicode ? 1 : charset_dim ); \
xoffset += nchars * glyph_width; \
}
static int
dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp)
struct frame *f;
int left, top;
register GLYPH *gp;
register int n;
int hl;
int just_foreground;
struct cmpchar_info *cmpcharp;
{
wchar_t *x_2byte_buffer
= (wchar_t *) alloca (FRAME_WINDOW_WIDTH (f) * sizeof (*x_2byte_buffer));
register wchar_t *cp;
unsigned char *x_1byte_buffer
= (unsigned char *) alloca (2 * FRAME_WINDOW_WIDTH (f)
* sizeof (*x_1byte_buffer));
register unsigned char *bp;
register int tlen = GLYPH_TABLE_LENGTH;
register Lisp_Object *tbase = GLYPH_TABLE_BASE;
Window window = FRAME_W32_WINDOW (f);
HDC hdc = get_frame_dc (f);
int orig_left = left;
int gidx = 0;
int i;
while (n > 0)
{
int cf, len, n_chars;
GLYPH g = *gp;
int ch, charset;
Lisp_Object first_ch;
int highest, lowest;
GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
cf = (cmpcharp ? cmpcharp->face_work : FAST_GLYPH_FACE (g));
ch = FAST_GLYPH_CHAR (g);
if (unibyte_display_via_language_environment
&& SINGLE_BYTE_CHAR_P (ch)
&& ch >= 160)
ch = unibyte_char_to_multibyte (ch);
if (gidx == 0) XSETFASTINT (first_ch, ch);
charset = CHAR_CHARSET (ch);
if (charset == CHARSET_COMPOSITION)
{
cmpcharp = cmpchar_table[COMPOSITE_CHAR_ID (ch)];
cmpcharp->face_work = cf;
dumpglyphs (f, left, top, cmpcharp->glyph, cmpcharp->glyph_len,
hl, just_foreground, cmpcharp);
left += FONT_WIDTH (FRAME_FONT (f)) * cmpcharp->width;
++gp, --n;
while (gp && (*gp & GLYPH_MASK_PADDING)) ++gp, --n;
cmpcharp = NULL;
continue;
}
cp = x_2byte_buffer;
while (n > 0)
{
int this_charset, c1, c2;
g = *gp;
GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
ch = FAST_GLYPH_CHAR (g);
if (unibyte_display_via_language_environment
&& SINGLE_BYTE_CHAR_P (ch)
&& ch >= 160)
ch = unibyte_char_to_multibyte (ch);
SPLIT_CHAR (ch, this_charset, c1, c2);
if (this_charset != charset
|| (cmpcharp == NULL && FAST_GLYPH_FACE (g) != cf))
break;
if (c2 > 0)
*cp = BUILD_WCHAR_T (c1, c2);
else
*cp = BUILD_WCHAR_T (0, c1);
++cp;
++gp, --n;
while (gp && (*gp & GLYPH_MASK_PADDING))
++gp, --n;
}
len = cp - x_2byte_buffer;
{
struct face *face = FRAME_DEFAULT_FACE (f);
XFontStruct *font = NULL;
int fontset;
struct font_info *fontp;
int font_id;
COLORREF fg;
COLORREF bg;
int stippled = 0;
int line_height = FRAME_LINE_HEIGHT (f);
int glyph_width
= (FONT_WIDTH (FRAME_FONT (f))
* (cmpcharp ? cmpcharp->width : CHARSET_WIDTH (charset)));
int run_width
= (FONT_WIDTH (FRAME_FONT (f))
* (cmpcharp ? cmpcharp->width : len * CHARSET_WIDTH (charset)));
int background_filled;
int baseline;
int relative_compose = 0, default_ascent = 0;
int require_clipping;
RECT clip_rectangle;
LPRECT clip_region = NULL;
UINT fuOptions = 0;
int codepage = CP_DEFAULT;
BOOL print_via_unicode = FALSE;
if (hl == 3)
cf = FRAME_W32_DISPLAY_INFO (f)->mouse_face_face_id;
if (cf != 0)
{
if (cf < 0 || cf >= FRAME_N_COMPUTED_FACES (f)
|| FRAME_COMPUTED_FACES (f) [cf] == 0)
cf = 0;
if (cf == 1)
face = FRAME_MODE_LINE_FACE (f);
else
face = intern_face (f, FRAME_COMPUTED_FACES (f) [cf]);
if (FACE_STIPPLE (face))
stippled = 1;
}
else if (hl == 0)
;
else if (hl == 1)
{
face = FRAME_MODE_LINE_FACE (f);
if (FACE_STIPPLE (face))
stippled = 1;
}
if (charset != CHARSET_ASCII)
{
fontset = FACE_FONTSET (face);
if ((fontset < 0 && (fontset = FRAME_FONTSET (f)) < 0)
|| !(fontp = FS_LOAD_FONT (f, FRAME_W32_FONT_TABLE (f),
charset, NULL, fontset)))
goto font_not_found;
font = (XFontStruct *) (fontp->font);
codepage = w32_codepage_for_font (fontp->name);
if ( font && !font->bdf )
print_via_unicode = w32_use_unicode_for_codepage (codepage);
baseline = FONT_BASE (font) + fontp->baseline_offset;
if (cmpcharp && cmpcharp->cmp_rule == NULL)
{
relative_compose = fontp->relative_compose;
default_ascent = fontp->default_ascent;
}
if (fontp->font_encoder)
{
struct ccl_program *ccl = fontp->font_encoder;
if (CHARSET_DIMENSION (charset) == 1)
for (cp = x_2byte_buffer; cp < x_2byte_buffer + len; cp++)
{
ccl->reg[0] = charset;
ccl->reg[1] = BYTE2 (*cp);
ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
#if 0
if (font->tm.tmLastChar < 256)
*cp = BUILD_WCHAR_T (0, ccl->reg[1]);
else
*cp = BUILD_WCHAR_T (ccl->reg[1], ccl->reg[2]);
#else
*cp = BUILD_WCHAR_T (0, ccl->reg[1]);
#endif
}
else
for (cp = x_2byte_buffer; cp < x_2byte_buffer + len; cp++)
{
ccl->reg[0] = charset;
ccl->reg[1] = BYTE1 (*cp) , ccl->reg[2] = BYTE2 (*cp);
ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
#if 0
if (font->tm.tmLastChar < 256)
*cp = BUILD_WCHAR_T (0, ccl->reg[1]);
else
*cp = BUILD_WCHAR_T (ccl->reg[1],ccl->reg[2]);
#else
*cp = BUILD_WCHAR_T (ccl->reg[1],ccl->reg[2]);
#endif
}
}
else if (fontp->encoding[charset])
{
int enc = fontp->encoding[charset];
if ((enc == 1 || enc == 2) && CHARSET_DIMENSION (charset) == 2)
for (cp = x_2byte_buffer; cp < x_2byte_buffer + len; cp++)
*cp = BUILD_WCHAR_T (BYTE1 (*cp) | 0x80, BYTE2 (*cp));
if (enc == 1 || enc == 3)
for (cp = x_2byte_buffer; cp < x_2byte_buffer + len; cp++)
*cp = BUILD_WCHAR_T (BYTE1 (*cp), BYTE2 (*cp) | 0x80);
if (enc == 4)
{
if (CHARSET_DIMENSION (charset) == 2)
{
int sjis1, sjis2;
for (cp = x_2byte_buffer;
cp < x_2byte_buffer + len; cp++)
{
ENCODE_SJIS (BYTE1 (*cp), BYTE2 (*cp),
sjis1, sjis2);
*cp = BUILD_WCHAR_T (sjis1, sjis2);
}
}
else
for (cp = x_2byte_buffer;
cp < x_2byte_buffer + len; cp++)
*cp = BUILD_WCHAR_T (BYTE1 (*cp),
BYTE2 (*cp) | 0x80);
}
}
}
else
{
font_not_found:
if (charset == CHARSET_ASCII || charset == charset_latin_iso8859_1)
{
font = FACE_FONT (face);
if (!font || font == (XFontStruct *) FACE_DEFAULT)
font = FRAME_FONT (f);
baseline = FONT_BASE (FRAME_FONT (f));
if (charset == charset_latin_iso8859_1)
{
if (!font->bdf && font->tm.tmLastChar < 0x80)
font = NULL;
else
{
for (cp = x_2byte_buffer;
cp < x_2byte_buffer + len; cp++)
*cp = BUILD_WCHAR_T (BYTE1 (*cp),
BYTE2 (*cp) | 0x80);
}
}
}
}
fg = face->foreground;
bg = face->background;
if (hl == 2)
{
stippled = 0;
if (font == FRAME_FONT (f)
&& face->background == FRAME_BACKGROUND_PIXEL (f)
&& face->foreground == FRAME_FOREGROUND_PIXEL (f)
&& !cmpcharp)
{
bg = f->output_data.w32->cursor_pixel;
fg = face->background;
}
else
{
bg = f->output_data.w32->cursor_pixel;
fg = face->background;
if (fg == bg)
fg = face->foreground;
if (fg == bg)
fg = f->output_data.w32->cursor_foreground_pixel;
if (fg == bg)
fg = face->foreground;
if (bg == face->background
&& fg == face->foreground)
{
bg = face->foreground;
fg = face->background;
}
}
}
if (font)
require_clipping = (!NILP (Vclip_large_size_font)
&& ((font->bdf
? (font->bdf->ury > baseline
|| font->bdf->lly > line_height - baseline)
: (font->tm.tmAscent > baseline
|| font->tm.tmDescent > line_height - baseline))
|| (!cmpcharp && FONT_MAX_WIDTH (font) > glyph_width)));
if (font && (just_foreground || (cmpcharp && gidx > 0)))
background_filled = 1;
else if (!font
|| font->bdf
|| FONT_BASE (font) < baseline
|| (FONT_HEIGHT (font) - FONT_BASE (font)
< line_height - baseline)
|| FONT_WIDTH (font) < glyph_width
|| FONT_MAX_WIDTH (font) != FONT_WIDTH (font)
|| font->tm.tmItalic
|| cmpcharp)
{
w32_fill_area (f, hdc, bg,
left,
top,
run_width,
line_height);
background_filled = 1;
if (cmpcharp)
just_foreground = 1;
}
else
background_filled = 0;
SetBkMode (hdc, background_filled ? TRANSPARENT : OPAQUE);
SetTextColor (hdc, fg);
SetBkColor (hdc, bg);
SetTextAlign (hdc, TA_BASELINE | TA_LEFT);
if (!print_via_unicode
&& codepage == CP_DEFAULT
&& w32_enable_unicode_output
&& os_subtype == OS_NT
&& font && !font->bdf)
{
print_via_unicode = TRUE;
}
if (!print_via_unicode
|| (charset != CHARSET_ASCII && charset != charset_latin_iso8859_1))
{
bp = x_1byte_buffer;
for (i = 0; i < len; i++)
{
if (BYTE1 (*(x_2byte_buffer + i)))
*bp++ = BYTE1 (*(x_2byte_buffer + i));
*bp++ = BYTE2 (*(x_2byte_buffer + i));
}
n_chars = bp - x_1byte_buffer;
}
else
n_chars = len;
if (print_via_unicode
&& charset != CHARSET_ASCII && charset != charset_latin_iso8859_1)
{
i = MultiByteToWideChar
(codepage, 0, x_1byte_buffer, n_chars,
x_2byte_buffer, FRAME_WINDOW_WIDTH (f));
if (i == 0)
print_via_unicode = FALSE;
else
n_chars = i;
}
if (font)
{
if (font->hfont)
SelectObject (hdc, font->hfont);
if (!cmpcharp)
{
int xoffset = 0, yoffset = baseline;
if (require_clipping || FONT_WIDTH (font) != glyph_width
|| FONT_MAX_WIDTH (font) != FONT_WIDTH (font))
{
for (i = 0; i < n_chars; )
{
if (require_clipping)
{
fuOptions |= ETO_CLIPPED;
clip_rectangle.left = left + i * glyph_width;
clip_rectangle.right
= left + (i + 1) * glyph_width;
clip_rectangle.top = top;
clip_rectangle.bottom = top + line_height;
clip_region = &clip_rectangle;
}
W32_TEXTOUT (i, 1);
}
}
else
{
i = 0;
W32_TEXTOUT (i, len);
}
}
else
{
RECT clip_rectangle;
LPRECT clip_region = NULL;
UINT fuOptions = 0;
ABC char_placement;
int char_width = 0;
i = 0;
if (require_clipping)
{
fuOptions |= ETO_CLIPPED;
clip_rectangle.left = left;
clip_rectangle.right = left + glyph_width;
clip_rectangle.top = top;
clip_rectangle.bottom = top + line_height;
clip_region = &clip_rectangle;
}
if ((cmpcharp->cmp_rule || relative_compose)
&& gidx == 0)
{
int xoffset = 0;
int yoffset = baseline;
if (default_ascent
&& CHAR_TABLE_P (Vuse_default_ascent)
&& !NILP (Faref (Vuse_default_ascent, first_ch)))
{
highest = default_ascent;
lowest = 0;
}
else
{
highest = FONT_BASE (font) + 1;
lowest = - (FONT_HEIGHT (font) - FONT_BASE (font));
}
if (cmpcharp->cmp_rule)
xoffset = (int)(cmpcharp->col_offset[0]
* FONT_WIDTH (FRAME_FONT (f)));
if (font->bdf)
{
char_width = FONT_WIDTH(font);
}
else if (print_via_unicode ?
GetCharABCWidthsW (hdc, *x_2byte_buffer,
*x_2byte_buffer,
&char_placement)
: GetCharABCWidths (hdc, *x_1byte_buffer,
*x_1byte_buffer,
&char_placement))
{
char_width = char_placement.abcA
+ char_placement.abcB + char_placement.abcC;
xoffset += FONT_WIDTH (font) - char_width;
}
if (xoffset > glyph_width - char_width)
xoffset = glyph_width - char_width;
if (xoffset < 0)
xoffset = 0;
W32_TEXTOUT (i, 1);
gidx++;
}
for (; i < n_chars; gidx++)
{
int xoffset = 0, yoffset = FONT_BASE (font);
if (relative_compose)
{
if (NILP (Vignore_relative_composition)
|| NILP (Faref (Vignore_relative_composition,
make_number (cmpcharp->glyph[gidx]))))
{
if (- (FONT_HEIGHT (font) - FONT_BASE (font))
>= relative_compose)
{
yoffset = highest + FONT_HEIGHT (font);
highest += FONT_HEIGHT (font);
}
else if (FONT_BASE (font) <= 0)
{
yoffset = lowest;
lowest -= FONT_HEIGHT (font);
}
}
else
{
if (FONT_BASE (font) > highest)
highest = FONT_BASE (font);
else if (- (FONT_HEIGHT (font) - FONT_BASE (font))
< lowest)
lowest = - (FONT_HEIGHT (font) -
FONT_BASE (font));
}
}
else if (cmpcharp->cmp_rule)
{
int gref = (cmpcharp->cmp_rule[gidx] - 0xA0) / 9;
int nref = (cmpcharp->cmp_rule[gidx] - 0xA0) % 9;
int bottom, top;
gref = gref / 3 + (gref == 4) * 2;
nref = nref / 3 + (nref == 4) * 2;
bottom = ((gref == 0 ? highest : gref == 1 ? 0
: gref == 2 ? lowest
: (highest + lowest) / 2)
- (nref == 0 ? FONT_HEIGHT (font)
: nref == 1 ? (FONT_HEIGHT (font) -
FONT_BASE (font))
: nref == 2 ? 0
: (FONT_HEIGHT (font) / 2)));
top = bottom + FONT_HEIGHT (font);
if (top > highest)
highest = top;
if (bottom < lowest)
lowest = bottom;
yoffset = bottom + FONT_HEIGHT (font);
xoffset = (int)(cmpcharp->col_offset[gidx]
* FONT_WIDTH (FRAME_FONT(f)));
}
if (font->bdf)
{
char_width = FONT_WIDTH (font);
}
else if (print_via_unicode ?
GetCharABCWidthsW (hdc, *(x_2byte_buffer + i),
*(x_2byte_buffer + i),
&char_placement)
: GetCharABCWidths (hdc, *(x_1byte_buffer + i),
*(x_1byte_buffer + i),
&char_placement))
{
char_width = char_placement.abcA
+ char_placement.abcB + char_placement.abcC;
xoffset += FONT_WIDTH (font) - char_width;
}
if (xoffset > glyph_width - char_width)
xoffset = glyph_width - char_width;
if (xoffset < 0)
xoffset = 0;
W32_TEXTOUT (i, 1);
}
}
}
if (!font)
{
int limit = cmpcharp ? 1 : len;
HBRUSH hb, oldhb;
HPEN hp, oldhp;
hb = CreateSolidBrush (bg);
hp = CreatePen (PS_SOLID, 0, fg);
oldhb = SelectObject(hdc, hb);
oldhp = SelectObject(hdc, hp);
for (i = 0; i < limit; i++)
Rectangle (hdc, left + glyph_width * i, top,
left + glyph_width * (i + 1),
top + line_height);
SelectObject(hdc, oldhb);
SelectObject(hdc, oldhp);
DeleteObject (hb);
DeleteObject (hp);
}
else if (require_clipping && !NILP (Vhighlight_wrong_size_font))
{
int limit = cmpcharp ? 1 : len;
for (i = 0; i < limit; i++)
{
w32_fill_area (f, hdc, fg, left + glyph_width * i,
top + line_height - 1, glyph_width, 1);
w32_fill_area (f, hdc, fg, left + glyph_width * i,
top + line_height - 3, 1, 2);
}
}
{
int underline_position = 1;
if (FONT_HEIGHT (FRAME_FONT (f)) - FONT_BASE(FRAME_FONT (f))
<= underline_position)
underline_position = (FONT_HEIGHT (FRAME_FONT (f)) -
FONT_BASE(FRAME_FONT (f))) - 1;
if (face->underline)
w32_fill_area (f, hdc, fg, left,
top + FONT_BASE (FRAME_FONT (f))
+ underline_position,
run_width, 1);
}
if (!cmpcharp)
left += run_width;
}
}
release_frame_dc (f, hdc);
return (left - orig_left);
}
static void
w32_write_glyphs (start, len)
register GLYPH *start;
int len;
{
register int temp_length;
struct frame *f;
BLOCK_INPUT;
do_line_dance ();
f = updating_frame;
if (f == 0)
{
f = selected_frame;
curs_x = f->cursor_x;
curs_y = f->cursor_y;
}
dumpglyphs (f,
CHAR_TO_PIXEL_COL (f, curs_x),
CHAR_TO_PIXEL_ROW (f, curs_y),
start, len, highlight, 0, NULL);
if (curs_y == f->phys_cursor_y
&& curs_x <= f->phys_cursor_x
&& curs_x + len > f->phys_cursor_x)
f->phys_cursor_on = 0;
if (updating_frame == 0)
{
f->cursor_x += len;
x_display_cursor (f, 1);
f->cursor_x -= len;
}
else
curs_x += len;
UNBLOCK_INPUT;
}
static void
w32_clear_end_of_line (first_unused)
register int first_unused;
{
struct frame *f = updating_frame;
if (f == 0)
abort ();
if (curs_y < 0 || curs_y >= f->height)
return;
if (first_unused <= 0)
return;
if (first_unused >= f->width)
first_unused = f->width;
first_unused += FRAME_LEFT_SCROLL_BAR_WIDTH (f);
BLOCK_INPUT;
do_line_dance ();
if (curs_y == f->phys_cursor_y
&& curs_x <= f->phys_cursor_x
&& f->phys_cursor_x < first_unused)
f->phys_cursor_on = 0;
w32_clear_area (f, NULL,
CHAR_TO_PIXEL_COL (f, curs_x),
CHAR_TO_PIXEL_ROW (f, curs_y),
FONT_WIDTH (f->output_data.w32->font) * (first_unused - curs_x),
f->output_data.w32->line_height);
UNBLOCK_INPUT;
}
static void
w32_clear_frame ()
{
struct frame *f = updating_frame;
if (f == 0)
f = selected_frame;
f->phys_cursor_on = 0;
curs_x = 0;
curs_y = 0;
BLOCK_INPUT;
w32_clear_window (f);
x_scroll_bar_clear (f);
UNBLOCK_INPUT;
}
static void
w32_ring_bell (void)
{
BLOCK_INPUT;
if (visible_bell)
{
int i;
HWND hwnd = FRAME_W32_WINDOW (selected_frame);
for (i = 0; i < 5; i++)
{
FlashWindow (hwnd, TRUE);
Sleep (10);
}
FlashWindow (hwnd, FALSE);
}
else
w32_sys_ring_bell ();
UNBLOCK_INPUT;
}
static void
w32_insert_glyphs (start, len)
register GLYPH *start;
register int len;
{
abort ();
}
static void
w32_delete_glyphs (n)
register int n;
{
abort ();
}
static void
w32_set_terminal_window (n)
register int n;
{
if (updating_frame == 0)
abort ();
if ((n <= 0) || (n > updating_frame->height))
flexlines = updating_frame->height;
else
flexlines = n;
}
static int *line_dance;
static int line_dance_len;
static int line_dance_in_progress;
static void
w32_ins_del_lines (vpos, n)
int vpos, n;
{
register int fence, i;
if (vpos >= flexlines)
return;
if (!line_dance_in_progress)
{
int ht = updating_frame->height;
if (ht > line_dance_len)
{
line_dance = (int *)xrealloc (line_dance, ht * sizeof (int));
line_dance_len = ht;
}
for (i = 0; i < ht; ++i) line_dance[i] = i;
line_dance_in_progress = 1;
}
if (n >= 0)
{
if (n > flexlines - vpos)
n = flexlines - vpos;
fence = vpos + n;
for (i = flexlines; --i >= fence;)
line_dance[i] = line_dance[i-n];
for (i = fence; --i >= vpos;)
line_dance[i] = -1;
}
else
{
n = -n;
if (n > flexlines - vpos)
n = flexlines - vpos;
fence = flexlines - n;
for (i = vpos; i < fence; ++i)
line_dance[i] = line_dance[i + n];
for (i = fence; i < flexlines; ++i)
line_dance[i] = -1;
}
}
static void
do_line_dance ()
{
register int i, j, distance;
register struct frame *f;
int ht;
int intborder;
HDC hdc;
if (!line_dance_in_progress)
return;
f = updating_frame;
if (f == 0)
abort ();
ht = f->height;
intborder = CHAR_TO_PIXEL_COL (f, FRAME_LEFT_SCROLL_BAR_WIDTH (f));
x_display_cursor (updating_frame, 0);
hdc = get_frame_dc (f);
for (i = 0; i < ht; ++i)
if (line_dance[i] != -1 && (distance = line_dance[i]-i) > 0)
{
for (j = i; (j < ht && line_dance[j] != -1
&& line_dance[j]-j == distance); ++j);
BitBlt (hdc,
intborder, CHAR_TO_PIXEL_ROW (f, i+distance),
FRAME_WINDOW_WIDTH (f) * FONT_WIDTH (FRAME_FONT (f)),
(j-i) * FRAME_LINE_HEIGHT (f),
hdc,
intborder, CHAR_TO_PIXEL_ROW (f, i),
SRCCOPY);
i = j-1;
}
for (i = ht; --i >=0; )
if (line_dance[i] != -1 && (distance = line_dance[i]-i) < 0)
{
for (j = i; (--j >= 0 && line_dance[j] != -1
&& line_dance[j]-j == distance););
BitBlt (hdc,
intborder, CHAR_TO_PIXEL_ROW (f, j+1+distance),
FRAME_WINDOW_WIDTH (f) * FONT_WIDTH (FRAME_FONT (f)),
(i-j) * FRAME_LINE_HEIGHT (f),
hdc,
intborder, CHAR_TO_PIXEL_ROW (f, j+1),
SRCCOPY);
i = j+1;
}
for (i = 0; i < ht; ++i)
if (line_dance[i] == -1)
{
for (j = i; j < ht && line_dance[j] == -1; ++j);
w32_clear_area (f, hdc,
intborder,
CHAR_TO_PIXEL_ROW (f, i),
FRAME_WINDOW_WIDTH (f) * FONT_WIDTH (FRAME_FONT (f)),
(j-i) * FRAME_LINE_HEIGHT (f));
i = j-1;
}
line_dance_in_progress = 0;
release_frame_dc (f, hdc);
}
static void clear_cursor ();
void
dumprectangle (f, left, top, cols, rows)
struct frame *f;
register int left, top, cols, rows;
{
register struct frame_glyphs *active_frame = FRAME_CURRENT_GLYPHS (f);
int cursor_cleared = 0;
int bottom, right;
register int y;
if (FRAME_GARBAGED_P (f))
return;
bottom = top + rows;
right = left + cols;
top = PIXEL_TO_CHAR_ROW (f, top);
left = PIXEL_TO_CHAR_COL (f, left);
bottom += (f->output_data.w32->line_height - 1);
right += (FONT_WIDTH (f->output_data.w32->font) - 1);
bottom = PIXEL_TO_CHAR_ROW (f, bottom);
right = PIXEL_TO_CHAR_COL (f, right);
if (left < FRAME_LEFT_SCROLL_BAR_WIDTH (f))
left = FRAME_LEFT_SCROLL_BAR_WIDTH (f);
if (top < 0)
top = 0;
if (right > f->width + FRAME_LEFT_SCROLL_BAR_WIDTH (f))
right = f->width + FRAME_LEFT_SCROLL_BAR_WIDTH (f);
if (bottom > f->height)
bottom = f->height;
cols = right - left;
rows = bottom - top;
if (rows <= 0) return;
if (cols <= 0) return;
if ((f->phys_cursor_x >= left) && (f->phys_cursor_x < right)
&& (f->phys_cursor_y >= top) && (f->phys_cursor_y < bottom))
{
clear_cursor (f);
cursor_cleared = 1;
}
for (y = top; y < bottom; y++)
{
GLYPH *line = &active_frame->glyphs[y][left];
if (! active_frame->enable[y] || left > active_frame->used[y])
continue;
while (*line & GLYPH_MASK_PADDING)
{
left--;
line--;
cols++;
}
dumpglyphs (f,
CHAR_TO_PIXEL_COL (f, left),
CHAR_TO_PIXEL_ROW (f, y),
line, min (cols, active_frame->used[y] - left),
active_frame->highlight[y], 0, NULL);
}
if (cursor_cleared)
x_display_cursor (f, 1);
}
static void
frame_highlight (f)
struct frame *f;
{
x_display_cursor (f, 1);
}
static void
frame_unhighlight (f)
struct frame *f;
{
x_display_cursor (f, 1);
}
static void x_frame_rehighlight ();
void
x_new_focus_frame (dpyinfo, frame)
struct w32_display_info *dpyinfo;
struct frame *frame;
{
struct frame *old_focus = dpyinfo->w32_focus_frame;
int events_enqueued = 0;
if (frame != dpyinfo->w32_focus_frame)
{
dpyinfo->w32_focus_frame = frame;
if (old_focus && old_focus->auto_lower)
x_lower_frame (old_focus);
if (dpyinfo->w32_focus_frame && dpyinfo->w32_focus_frame->auto_raise)
pending_autoraise_frame = dpyinfo->w32_focus_frame;
else
pending_autoraise_frame = 0;
}
x_frame_rehighlight (dpyinfo);
}
void
x_mouse_leave (dpyinfo)
struct w32_display_info *dpyinfo;
{
x_new_focus_frame (dpyinfo, dpyinfo->w32_focus_event_frame);
}
static void
w32_frame_rehighlight (frame)
struct frame *frame;
{
x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame));
}
static void
x_frame_rehighlight (dpyinfo)
struct w32_display_info *dpyinfo;
{
struct frame *old_highlight = dpyinfo->w32_highlight_frame;
if (dpyinfo->w32_focus_frame)
{
dpyinfo->w32_highlight_frame
= ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame)))
? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame))
: dpyinfo->w32_focus_frame);
if (! FRAME_LIVE_P (dpyinfo->w32_highlight_frame))
{
FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame) = Qnil;
dpyinfo->w32_highlight_frame = dpyinfo->w32_focus_frame;
}
}
else
dpyinfo->w32_highlight_frame = 0;
if (dpyinfo->w32_highlight_frame != old_highlight)
{
if (old_highlight)
frame_unhighlight (old_highlight);
if (dpyinfo->w32_highlight_frame)
frame_highlight (dpyinfo->w32_highlight_frame);
}
}
char *
x_get_keysym_name (keysym)
int keysym;
{
static char value[100];
BLOCK_INPUT;
GetKeyNameText(keysym, value, 100);
UNBLOCK_INPUT;
return value;
}
void
pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
FRAME_PTR f;
register int pix_x, pix_y;
register int *x, *y;
RECT *bounds;
int noclip;
{
if (NILP (Vwindow_system))
{
*x = pix_x;
*y = pix_y;
return;
}
if (pix_x < 0)
pix_x -= FONT_WIDTH ((f)->output_data.w32->font) - 1;
if (pix_y < 0)
pix_y -= (f)->output_data.w32->line_height - 1;
pix_x = PIXEL_TO_CHAR_COL (f, pix_x);
pix_y = PIXEL_TO_CHAR_ROW (f, pix_y);
if (bounds)
{
bounds->left = CHAR_TO_PIXEL_COL (f, pix_x);
bounds->top = CHAR_TO_PIXEL_ROW (f, pix_y);
bounds->right = bounds->left + FONT_WIDTH (f->output_data.w32->font) - 1;
bounds->bottom = bounds->top + f->output_data.w32->line_height - 1;
}
if (!noclip)
{
if (pix_x < 0)
pix_x = 0;
else if (pix_x > f->width)
pix_x = f->width;
if (pix_y < 0)
pix_y = 0;
else if (pix_y > f->height)
pix_y = f->height;
}
*x = pix_x;
*y = pix_y;
}
void
glyph_to_pixel_coords (f, x, y, pix_x, pix_y)
FRAME_PTR f;
register int x, y;
register int *pix_x, *pix_y;
{
if (NILP (Vwindow_system))
{
*pix_x = x;
*pix_y = y;
return;
}
*pix_x = CHAR_TO_PIXEL_COL (f, x);
*pix_y = CHAR_TO_PIXEL_ROW (f, y);
}
BOOL
parse_button (message, pbutton, pup)
int message;
int * pbutton;
int * pup;
{
int button = 0;
int up = 0;
switch (message)
{
case WM_LBUTTONDOWN:
button = 0;
up = 0;
break;
case WM_LBUTTONUP:
button = 0;
up = 1;
break;
case WM_MBUTTONDOWN:
if (NILP (Vw32_swap_mouse_buttons))
button = 1;
else
button = 2;
up = 0;
break;
case WM_MBUTTONUP:
if (NILP (Vw32_swap_mouse_buttons))
button = 1;
else
button = 2;
up = 1;
break;
case WM_RBUTTONDOWN:
if (NILP (Vw32_swap_mouse_buttons))
button = 2;
else
button = 1;
up = 0;
break;
case WM_RBUTTONUP:
if (NILP (Vw32_swap_mouse_buttons))
button = 2;
else
button = 1;
up = 1;
break;
default:
return (FALSE);
}
if (pup) *pup = up;
if (pbutton) *pbutton = button;
return (TRUE);
}
static void
construct_mouse_click (result, msg, f)
struct input_event *result;
W32Msg *msg;
struct frame *f;
{
int button;
int up;
parse_button (msg->msg.message, &button, &up);
result->kind = mouse_click;
result->code = button;
result->timestamp = msg->msg.time;
result->modifiers = (msg->dwModifiers
| (up
? up_modifier
: down_modifier));
{
int row, column;
XSETINT (result->x, LOWORD (msg->msg.lParam));
XSETINT (result->y, HIWORD (msg->msg.lParam));
XSETFRAME (result->frame_or_window, f);
}
}
static void
construct_mouse_wheel (result, msg, f)
struct input_event *result;
W32Msg *msg;
struct frame *f;
{
POINT p;
result->kind = mouse_wheel;
result->code = (short) HIWORD (msg->msg.wParam);
result->timestamp = msg->msg.time;
result->modifiers = msg->dwModifiers;
p.x = LOWORD (msg->msg.lParam);
p.y = HIWORD (msg->msg.lParam);
ScreenToClient(msg->msg.hwnd, &p);
XSETINT (result->x, p.x);
XSETINT (result->y, p.y);
XSETFRAME (result->frame_or_window, f);
}
static void
construct_drag_n_drop (result, msg, f)
struct input_event *result;
W32Msg *msg;
struct frame *f;
{
Lisp_Object files;
Lisp_Object frame;
HDROP hdrop;
POINT p;
WORD num_files;
char *name;
int i, len;
result->kind = drag_n_drop;
result->code = 0;
result->timestamp = msg->msg.time;
result->modifiers = msg->dwModifiers;
hdrop = (HDROP) msg->msg.wParam;
DragQueryPoint (hdrop, &p);
#if 0
p.x = LOWORD (msg->msg.lParam);
p.y = HIWORD (msg->msg.lParam);
ScreenToClient (msg->msg.hwnd, &p);
#endif
XSETINT (result->x, p.x);
XSETINT (result->y, p.y);
num_files = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0);
files = Qnil;
for (i = 0; i < num_files; i++)
{
len = DragQueryFile (hdrop, i, NULL, 0);
if (len <= 0)
continue;
name = alloca (len + 1);
DragQueryFile (hdrop, i, name, len + 1);
files = Fcons (build_string (name), files);
}
DragFinish (hdrop);
XSETFRAME (frame, f);
result->frame_or_window = Fcons (frame, files);
}
static void
note_mouse_movement (frame, msg)
FRAME_PTR frame;
MSG *msg;
{
last_mouse_movement_time = msg->time;
if (msg->hwnd != FRAME_W32_WINDOW (frame))
{
frame->mouse_moved = 1;
last_mouse_scroll_bar = Qnil;
note_mouse_highlight (frame, -1, -1);
}
else if (LOWORD (msg->lParam) < last_mouse_glyph.left
|| LOWORD (msg->lParam) > last_mouse_glyph.right
|| HIWORD (msg->lParam) < last_mouse_glyph.top
|| HIWORD (msg->lParam) > last_mouse_glyph.bottom)
{
frame->mouse_moved = 1;
last_mouse_scroll_bar = Qnil;
note_mouse_highlight (frame, LOWORD (msg->lParam), HIWORD (msg->lParam));
}
}
static int disable_mouse_highlight;
static void
note_mouse_highlight (f, x, y)
FRAME_PTR f;
int x, y;
{
int row, column, portion;
RECT new_glyph;
Lisp_Object window;
struct window *w;
if (disable_mouse_highlight)
return;
FRAME_W32_DISPLAY_INFO (f)->mouse_face_mouse_x = x;
FRAME_W32_DISPLAY_INFO (f)->mouse_face_mouse_y = y;
FRAME_W32_DISPLAY_INFO (f)->mouse_face_mouse_frame = f;
if (FRAME_W32_DISPLAY_INFO (f)->mouse_face_defer)
return;
if (gc_in_progress)
{
FRAME_W32_DISPLAY_INFO (f)->mouse_face_deferred_gc = 1;
return;
}
pixel_to_glyph_coords (f, x, y, &column, &row,
&new_glyph, FRAME_W32_DISPLAY_INFO (f)->grabbed);
window = window_from_coordinates (f, column, row, &portion);
w = XWINDOW (window);
if (! EQ (window, FRAME_W32_DISPLAY_INFO (f)->mouse_face_window))
clear_mouse_face (FRAME_W32_DISPLAY_INFO (f));
if (WINDOWP (window) && portion == 0 && row >= 0 && column >= 0
&& row < FRAME_HEIGHT (f) && column < FRAME_WIDTH (f)
&& EQ (w->window_end_valid, w->buffer)
&& w->last_modified == BUF_MODIFF (XBUFFER (w->buffer))
&& w->last_overlay_modified == BUF_OVERLAY_MODIFF (XBUFFER (w->buffer)))
{
int *ptr = FRAME_CURRENT_GLYPHS (f)->charstarts[row];
int i, pos;
for (i = column; i >= 0; i--)
if (ptr[i] > 0)
break;
pos = ptr[i];
if (pos <= 0)
clear_mouse_face (FRAME_W32_DISPLAY_INFO (f));
else if (! (EQ (window, FRAME_W32_DISPLAY_INFO (f)->mouse_face_window)
&& row >= FRAME_W32_DISPLAY_INFO (f)->mouse_face_beg_row
&& row <= FRAME_W32_DISPLAY_INFO (f)->mouse_face_end_row
&& (row > FRAME_W32_DISPLAY_INFO (f)->mouse_face_beg_row
|| column >= FRAME_W32_DISPLAY_INFO (f)->mouse_face_beg_col)
&& (row < FRAME_W32_DISPLAY_INFO (f)->mouse_face_end_row
|| column < FRAME_W32_DISPLAY_INFO (f)->mouse_face_end_col
|| FRAME_W32_DISPLAY_INFO (f)->mouse_face_past_end)))
{
Lisp_Object mouse_face, overlay, position;
Lisp_Object *overlay_vec;
int len, noverlays, ignor1;
struct buffer *obuf;
int obegv, ozv;
if (pos > BUF_Z (XBUFFER (w->buffer)))
return;
obuf = current_buffer;
current_buffer = XBUFFER (w->buffer);
obegv = BEGV;
ozv = ZV;
BEGV = BEG;
ZV = Z;
clear_mouse_face (FRAME_W32_DISPLAY_INFO (f));
XSETINT (position, pos);
len = 10;
overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
NULL, NULL);
noverlays = sort_overlays (overlay_vec, noverlays, w);
overlay = Qnil;
for (i = 0; i < noverlays; i++)
{
mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
if (!NILP (mouse_face))
{
overlay = overlay_vec[i];
break;
}
}
free (overlay_vec);
if (NILP (overlay))
mouse_face = Fget_text_property (position, Qmouse_face, w->buffer);
if (! NILP (overlay))
{
Lisp_Object before, after;
int ignore;
before = Foverlay_start (overlay);
after = Foverlay_end (overlay);
fast_find_position (window, before,
&FRAME_W32_DISPLAY_INFO (f)->mouse_face_beg_col,
&FRAME_W32_DISPLAY_INFO (f)->mouse_face_beg_row);
FRAME_W32_DISPLAY_INFO (f)->mouse_face_past_end
= !fast_find_position (window, after,
&FRAME_W32_DISPLAY_INFO (f)->mouse_face_end_col,
&FRAME_W32_DISPLAY_INFO (f)->mouse_face_end_row);
FRAME_W32_DISPLAY_INFO (f)->mouse_face_window = window;
FRAME_W32_DISPLAY_INFO (f)->mouse_face_face_id
= compute_char_face (f, w, pos, 0, 0,
&ignore, pos + 1, 1);
show_mouse_face (FRAME_W32_DISPLAY_INFO (f), 1);
}
else if (! NILP (mouse_face))
{
Lisp_Object before, after, beginning, end;
int ignore;
beginning = Fmarker_position (w->start);
XSETINT (end, (BUF_Z (XBUFFER (w->buffer))
- XFASTINT (w->window_end_pos)));
before
= Fprevious_single_property_change (make_number (pos + 1),
Qmouse_face,
w->buffer, beginning);
after
= Fnext_single_property_change (position, Qmouse_face,
w->buffer, end);
fast_find_position (window, before,
&FRAME_W32_DISPLAY_INFO (f)->mouse_face_beg_col,
&FRAME_W32_DISPLAY_INFO (f)->mouse_face_beg_row);
FRAME_W32_DISPLAY_INFO (f)->mouse_face_past_end
= !fast_find_position (window, after,
&FRAME_W32_DISPLAY_INFO (f)->mouse_face_end_col,
&FRAME_W32_DISPLAY_INFO (f)->mouse_face_end_row);
FRAME_W32_DISPLAY_INFO (f)->mouse_face_window = window;
FRAME_W32_DISPLAY_INFO (f)->mouse_face_face_id
= compute_char_face (f, w, pos, 0, 0,
&ignore, pos + 1, 1);
show_mouse_face (FRAME_W32_DISPLAY_INFO (f), 1);
}
BEGV = obegv;
ZV = ozv;
current_buffer = obuf;
}
}
}
static int
fast_find_position (window, pos, columnp, rowp)
Lisp_Object window;
int pos;
int *columnp, *rowp;
{
struct window *w = XWINDOW (window);
FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
int i;
int row = 0;
int left = WINDOW_LEFT_MARGIN (w);
int top = w->top;
int height = XFASTINT (w->height) - ! MINI_WINDOW_P (w);
int width = window_internal_width (w);
int *charstarts;
int lastcol;
int maybe_next_line = 0;
for (i = 0;
i < height;
i++)
{
int linestart = FRAME_CURRENT_GLYPHS (f)->charstarts[top + i][left];
if (linestart > pos)
break;
if (linestart == pos && pos == BUF_ZV (XBUFFER (w->buffer)))
{
maybe_next_line = 1;
break;
}
if (linestart > 0)
row = i;
}
charstarts = FRAME_CURRENT_GLYPHS (f)->charstarts[top + row];
lastcol = left;
for (i = 0; i < width; i++)
{
if (charstarts[left + i] == pos)
{
*rowp = row + top;
*columnp = i + left;
return 1;
}
else if (charstarts[left + i] > pos)
break;
else if (charstarts[left + i] > 0)
lastcol = left + i;
}
if (maybe_next_line)
{
row++;
i = 0;
}
*rowp = row + top;
*columnp = lastcol;
return 0;
}
static void
show_mouse_face (dpyinfo, hl)
struct w32_display_info *dpyinfo;
int hl;
{
struct window *w = XWINDOW (dpyinfo->mouse_face_window);
int width = window_internal_width (w);
FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
int i;
int cursor_off = 0;
int old_curs_x = curs_x;
int old_curs_y = curs_y;
curs_x = f->phys_cursor_x;
curs_y = f->phys_cursor_y;
for (i = FRAME_W32_DISPLAY_INFO (f)->mouse_face_beg_row;
i <= FRAME_W32_DISPLAY_INFO (f)->mouse_face_end_row; i++)
{
int column = (i == FRAME_W32_DISPLAY_INFO (f)->mouse_face_beg_row
? FRAME_W32_DISPLAY_INFO (f)->mouse_face_beg_col
: WINDOW_LEFT_MARGIN (w));
int endcolumn = (i == FRAME_W32_DISPLAY_INFO (f)->mouse_face_end_row
? FRAME_W32_DISPLAY_INFO (f)->mouse_face_end_col
: WINDOW_LEFT_MARGIN (w) + width);
endcolumn = min (endcolumn, FRAME_CURRENT_GLYPHS (f)->used[i]);
if (i == curs_y
&& curs_x >= column - 1
&& curs_x <= endcolumn)
{
x_display_cursor (f, 0);
cursor_off = 1;
}
dumpglyphs (f,
CHAR_TO_PIXEL_COL (f, column),
CHAR_TO_PIXEL_ROW (f, i),
FRAME_CURRENT_GLYPHS (f)->glyphs[i] + column,
endcolumn - column,
hl > 0 ? 3 : 0, 0, NULL);
}
if (cursor_off)
x_display_cursor (f, 1);
curs_x = old_curs_x;
curs_y = old_curs_y;
if (hl > 0)
SetCursor (f->output_data.w32->cross_cursor);
else
SetCursor (f->output_data.w32->text_cursor);
}
static void
clear_mouse_face (dpyinfo)
struct w32_display_info *dpyinfo;
{
if (! NILP (dpyinfo->mouse_face_window))
show_mouse_face (dpyinfo, 0);
dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
dpyinfo->mouse_face_window = Qnil;
}
void
cancel_mouse_face (f)
FRAME_PTR f;
{
Lisp_Object window;
struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
window = dpyinfo->mouse_face_window;
if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
{
dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
dpyinfo->mouse_face_window = Qnil;
}
}
struct scroll_bar *x_window_to_scroll_bar ();
static void x_scroll_bar_report_motion ();
static void
w32_mouse_position (fp, insist, bar_window, part, x, y, time)
FRAME_PTR *fp;
int insist;
Lisp_Object *bar_window;
enum scroll_bar_part *part;
Lisp_Object *x, *y;
unsigned long *time;
{
FRAME_PTR f1;
BLOCK_INPUT;
if (! NILP (last_mouse_scroll_bar) && insist == 0)
x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
else
{
POINT pt;
Lisp_Object frame, tail;
FOR_EACH_FRAME (tail, frame)
XFRAME (frame)->mouse_moved = 0;
last_mouse_scroll_bar = Qnil;
GetCursorPos (&pt);
{
if (FRAME_W32_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
&& FRAME_LIVE_P (last_mouse_frame))
{
f1 = last_mouse_frame;
}
else
{
f1 = x_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp), WindowFromPoint(pt));
}
if (! f1)
{
struct scroll_bar *bar = x_window_to_scroll_bar (WindowFromPoint(pt));
if (bar)
{
f1 = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
}
}
if (f1 == 0 && insist > 0)
f1 = selected_frame;
if (f1)
{
int ignore1, ignore2;
ScreenToClient (FRAME_W32_WINDOW (f1), &pt);
pixel_to_glyph_coords (f1, pt.x, pt.y, &ignore1, &ignore2,
&last_mouse_glyph,
FRAME_W32_DISPLAY_INFO (f1)->grabbed
|| insist);
*bar_window = Qnil;
*part = 0;
*fp = f1;
XSETINT (*x, pt.x);
XSETINT (*y, pt.y);
*time = last_mouse_movement_time;
}
}
}
UNBLOCK_INPUT;
}
struct scroll_bar *
x_window_to_scroll_bar (window_id)
Window window_id;
{
Lisp_Object tail, frame;
for (tail = Vframe_list;
XGCTYPE (tail) == Lisp_Cons;
tail = XCONS (tail)->cdr)
{
Lisp_Object frame, bar, condemned;
frame = XCONS (tail)->car;
if (! GC_FRAMEP (frame))
abort ();
condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame));
for (bar = FRAME_SCROLL_BARS (XFRAME (frame));
! GC_NILP (bar) || (bar = condemned,
condemned = Qnil,
! GC_NILP (bar));
bar = XSCROLL_BAR (bar)->next)
if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar)) == window_id)
return XSCROLL_BAR (bar);
}
return 0;
}
HWND
my_create_scrollbar (f, bar)
struct frame * f;
struct scroll_bar * bar;
{
return (HWND) SendMessage (FRAME_W32_WINDOW (f),
WM_EMACS_CREATESCROLLBAR, (WPARAM) f,
(LPARAM) bar);
}
BOOL
my_show_window (FRAME_PTR f, HWND hwnd, int how)
{
#ifndef ATTACH_THREADS
return SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SHOWWINDOW,
(WPARAM) hwnd, (LPARAM) how);
#else
return ShowWindow (hwnd, how);
#endif
}
void
my_set_window_pos (HWND hwnd, HWND hwndAfter,
int x, int y, int cx, int cy, UINT flags)
{
#ifndef ATTACH_THREADS
WINDOWPOS pos;
pos.hwndInsertAfter = hwndAfter;
pos.x = x;
pos.y = y;
pos.cx = cx;
pos.cy = cy;
pos.flags = flags;
SendMessage (hwnd, WM_EMACS_SETWINDOWPOS, (WPARAM) &pos, 0);
#else
SetWindowPos (hwnd, hwndAfter, x, y, cx, cy, flags);
#endif
}
BOOL
my_set_focus (f, hwnd)
struct frame * f;
HWND hwnd;
{
SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SETFOCUS,
(WPARAM) hwnd, 0);
}
BOOL
my_set_foreground_window (hwnd)
HWND hwnd;
{
SendMessage (hwnd, WM_EMACS_SETFOREGROUND, (WPARAM) hwnd, 0);
}
void
my_destroy_window (f, hwnd)
struct frame * f;
HWND hwnd;
{
SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_DESTROYWINDOW,
(WPARAM) hwnd, 0);
}
static struct scroll_bar *
x_scroll_bar_create (window, top, left, width, height)
struct window *window;
int top, left, width, height;
{
FRAME_PTR f = XFRAME (WINDOW_FRAME (window));
struct scroll_bar *bar
= XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
HWND hwnd;
BLOCK_INPUT;
XSETWINDOW (bar->window, window);
XSETINT (bar->top, top);
XSETINT (bar->left, left);
XSETINT (bar->width, width);
XSETINT (bar->height, height);
XSETINT (bar->start, 0);
XSETINT (bar->end, 0);
bar->dragging = Qnil;
hwnd = my_create_scrollbar (f, bar);
if (pfnSetScrollInfo)
{
SCROLLINFO si;
si.cbSize = sizeof (si);
si.fMask = SIF_ALL;
si.nMin = 0;
si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (height)
+ VERTICAL_SCROLL_BAR_MIN_HANDLE;
si.nPage = si.nMax;
si.nPos = 0;
pfnSetScrollInfo (hwnd, SB_CTL, &si, FALSE);
}
else
{
SetScrollRange (hwnd, SB_CTL, 0, VERTICAL_SCROLL_BAR_TOP_RANGE (height), FALSE);
SetScrollPos (hwnd, SB_CTL, 0, FALSE);
}
SET_SCROLL_BAR_W32_WINDOW (bar, hwnd);
bar->next = FRAME_SCROLL_BARS (f);
bar->prev = Qnil;
XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
if (! NILP (bar->next))
XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
UNBLOCK_INPUT;
return bar;
}
static void
x_scroll_bar_set_handle (bar, start, end, rebuild)
struct scroll_bar *bar;
int start, end;
int rebuild;
{
int dragging = ! NILP (bar->dragging);
Window w = SCROLL_BAR_W32_WINDOW (bar);
FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
if (! rebuild
&& start == XINT (bar->start)
&& end == XINT (bar->end))
return;
BLOCK_INPUT;
{
int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (XINT (bar->height));
{
int length = end - start;
if (start < 0)
start = 0;
else if (start > top_range)
start = top_range;
end = start + length;
if (end < start)
end = start;
else if (end > top_range && ! dragging)
end = top_range;
}
}
XSETINT (bar->start, start);
XSETINT (bar->end, end);
if (!dragging)
{
if (pfnSetScrollInfo)
{
SCROLLINFO si;
si.cbSize = sizeof (si);
si.fMask = SIF_PAGE | SIF_POS;
si.nPage = end - start + VERTICAL_SCROLL_BAR_MIN_HANDLE;
si.nPos = start;
pfnSetScrollInfo (w, SB_CTL, &si, TRUE);
}
else
SetScrollPos (w, SB_CTL, start, TRUE);
}
UNBLOCK_INPUT;
}
static void
x_scroll_bar_move (bar, top, left, width, height)
struct scroll_bar *bar;
int top, left, width, height;
{
Window w = SCROLL_BAR_W32_WINDOW (bar);
FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
if ( XINT (bar->left) == left
&& XINT (bar->top) == top
&& XINT (bar->width) == width
&& XINT (bar->height) == height )
{
if (!my_show_window (f, w, SW_NORMAL))
InvalidateRect (w, NULL, FALSE);
return;
}
BLOCK_INPUT;
my_show_window (f, w, SW_HIDE);
MoveWindow (w, left, top, width, height, TRUE);
if (pfnSetScrollInfo)
{
SCROLLINFO si;
si.cbSize = sizeof (si);
si.fMask = SIF_RANGE;
si.nMin = 0;
si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (height)
+ VERTICAL_SCROLL_BAR_MIN_HANDLE;
pfnSetScrollInfo (w, SB_CTL, &si, FALSE);
}
else
SetScrollRange (w, SB_CTL, 0, VERTICAL_SCROLL_BAR_TOP_RANGE (height), FALSE);
my_show_window (f, w, SW_NORMAL);
XSETINT (bar->left, left);
XSETINT (bar->top, top);
XSETINT (bar->width, width);
XSETINT (bar->height, height);
UNBLOCK_INPUT;
}
static void
x_scroll_bar_remove (bar)
struct scroll_bar *bar;
{
FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
BLOCK_INPUT;
my_destroy_window (f, SCROLL_BAR_W32_WINDOW (bar));
XWINDOW (bar->window)->vertical_scroll_bar = Qnil;
UNBLOCK_INPUT;
}
static void
w32_set_vertical_scroll_bar (window, portion, whole, position)
struct window *window;
int portion, whole, position;
{
FRAME_PTR f = XFRAME (WINDOW_FRAME (window));
int top = XINT (window->top);
int left = WINDOW_VERTICAL_SCROLL_BAR_COLUMN (window);
int height = WINDOW_VERTICAL_SCROLL_BAR_HEIGHT (window);
int pixel_top = CHAR_TO_PIXEL_ROW (f, top);
int pixel_left = CHAR_TO_PIXEL_COL (f, left);
int pixel_width
= (FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0
? FRAME_SCROLL_BAR_PIXEL_WIDTH (f)
: (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.w32->font)));
int pixel_height = VERTICAL_SCROLL_BAR_PIXEL_HEIGHT (f, height);
struct scroll_bar *bar;
if (NILP (window->vertical_scroll_bar))
bar = x_scroll_bar_create (window,
pixel_top, pixel_left,
pixel_width, pixel_height);
else
{
bar = XSCROLL_BAR (window->vertical_scroll_bar);
x_scroll_bar_move (bar, pixel_top, pixel_left, pixel_width, pixel_height);
}
{
int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (pixel_height);
if (whole == 0)
x_scroll_bar_set_handle (bar, 0, top_range, 0);
else
{
int start = (int) (((double) position * top_range) / whole);
int end = (int) (((double) (position + portion) * top_range) / whole);
x_scroll_bar_set_handle (bar, start, end, 0);
}
}
XSETVECTOR (window->vertical_scroll_bar, bar);
}
static void
w32_condemn_scroll_bars (frame)
FRAME_PTR frame;
{
while (! NILP (FRAME_SCROLL_BARS (frame)))
{
Lisp_Object bar;
bar = FRAME_SCROLL_BARS (frame);
FRAME_SCROLL_BARS (frame) = XSCROLL_BAR (bar)->next;
XSCROLL_BAR (bar)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
XSCROLL_BAR (bar)->prev = Qnil;
if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = bar;
FRAME_CONDEMNED_SCROLL_BARS (frame) = bar;
}
#ifdef PIGSFLY
if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
abort ();
FRAME_CONDEMNED_SCROLL_BARS (frame) = FRAME_SCROLL_BARS (frame);
FRAME_SCROLL_BARS (frame) = Qnil;
#endif
}
static void
w32_redeem_scroll_bar (window)
struct window *window;
{
struct scroll_bar *bar;
if (NILP (window->vertical_scroll_bar))
abort ();
bar = XSCROLL_BAR (window->vertical_scroll_bar);
{
FRAME_PTR f = XFRAME (WINDOW_FRAME (window));
if (NILP (bar->prev))
{
if (EQ (FRAME_SCROLL_BARS (f), window->vertical_scroll_bar))
return;
else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
window->vertical_scroll_bar))
FRAME_CONDEMNED_SCROLL_BARS (f) = bar->next;
else
abort ();
}
else
XSCROLL_BAR (bar->prev)->next = bar->next;
if (! NILP (bar->next))
XSCROLL_BAR (bar->next)->prev = bar->prev;
bar->next = FRAME_SCROLL_BARS (f);
bar->prev = Qnil;
XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
if (! NILP (bar->next))
XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
}
#ifdef PIGSFLY
struct scroll_bar *bar;
if (NILP (window->vertical_scroll_bar))
abort ();
bar = XSCROLL_BAR (window->vertical_scroll_bar);
{
FRAME_PTR f = XFRAME (WINDOW_FRAME (window));
if (NILP (bar->prev))
{
if (EQ (FRAME_SCROLL_BARS (f), window->vertical_scroll_bar))
return;
else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
window->vertical_scroll_bar))
FRAME_CONDEMNED_SCROLL_BARS (f) = bar->next;
else
abort ();
}
else
XSCROLL_BAR (bar->prev)->next = bar->next;
if (! NILP (bar->next))
XSCROLL_BAR (bar->next)->prev = bar->prev;
bar->next = FRAME_SCROLL_BARS (f);
bar->prev = Qnil;
XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
if (! NILP (bar->next))
XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
}
#endif
}
static void
w32_judge_scroll_bars (f)
FRAME_PTR f;
{
Lisp_Object bar, next;
bar = FRAME_CONDEMNED_SCROLL_BARS (f);
FRAME_CONDEMNED_SCROLL_BARS (f) = Qnil;
for (; ! NILP (bar); bar = next)
{
struct scroll_bar *b = XSCROLL_BAR (bar);
x_scroll_bar_remove (b);
next = b->next;
b->next = b->prev = Qnil;
}
#ifdef PIGSFLY
Lisp_Object bar, next;
bar = FRAME_CONDEMNED_SCROLL_BARS (f);
FRAME_CONDEMNED_SCROLL_BARS (f) = Qnil;
for (; ! NILP (bar); bar = next)
{
struct scroll_bar *b = XSCROLL_BAR (bar);
x_scroll_bar_remove (b);
next = b->next;
b->next = b->prev = Qnil;
}
#endif
}
static int
x_scroll_bar_handle_click (bar, msg, emacs_event)
struct scroll_bar *bar;
W32Msg *msg;
struct input_event *emacs_event;
{
if (! GC_WINDOWP (bar->window))
abort ();
emacs_event->kind = w32_scroll_bar_click;
emacs_event->code = 0;
emacs_event->modifiers = msg->dwModifiers;
emacs_event->frame_or_window = bar->window;
emacs_event->timestamp = msg->msg.time;
{
int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (XINT (bar->height));
int y;
int dragging = !NILP (bar->dragging);
if (pfnGetScrollInfo)
{
SCROLLINFO si;
si.cbSize = sizeof (si);
si.fMask = SIF_POS;
pfnGetScrollInfo ((HWND) msg->msg.lParam, SB_CTL, &si);
y = si.nPos;
}
else
y = GetScrollPos ((HWND) msg->msg.lParam, SB_CTL);
bar->dragging = Qnil;
switch (LOWORD (msg->msg.wParam))
{
case SB_LINEDOWN:
emacs_event->part = scroll_bar_down_arrow;
break;
case SB_LINEUP:
emacs_event->part = scroll_bar_up_arrow;
break;
case SB_PAGEUP:
emacs_event->part = scroll_bar_above_handle;
break;
case SB_PAGEDOWN:
emacs_event->part = scroll_bar_below_handle;
break;
case SB_TOP:
emacs_event->part = scroll_bar_handle;
y = 0;
break;
case SB_BOTTOM:
emacs_event->part = scroll_bar_handle;
y = top_range;
break;
case SB_THUMBTRACK:
case SB_THUMBPOSITION:
if (VERTICAL_SCROLL_BAR_TOP_RANGE (XINT (bar->height)) <= 0xffff)
y = HIWORD (msg->msg.wParam);
bar->dragging = Qt;
emacs_event->part = scroll_bar_handle;
if (pfnSetScrollInfo)
{
SCROLLINFO si;
si.cbSize = sizeof (si);
si.fMask = SIF_POS;
#if 0
{
int start = XINT (bar->start);
int end = XINT (bar->end);
int len = end - start;
if (y + len > top_range - 2)
{
len -= min (top_range / 10, (len / 3) + 2);
if (len < 0)
len = 0;
}
si.nPage = len + VERTICAL_SCROLL_BAR_MIN_HANDLE;
si.fMask |= SIF_PAGE;
}
#endif
si.nPos = y;
last_scroll_bar_drag_pos = y;
pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, FALSE);
}
else
SetScrollPos (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, y, FALSE);
break;
case SB_ENDSCROLL:
if (dragging)
{
if (pfnSetScrollInfo)
{
SCROLLINFO si;
int start = XINT (bar->start);
int end = XINT (bar->end);
si.cbSize = sizeof (si);
si.fMask = SIF_PAGE | SIF_POS;
si.nPage = end - start + VERTICAL_SCROLL_BAR_MIN_HANDLE;
si.nPos = last_scroll_bar_drag_pos;
pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE);
}
else
SetScrollPos (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, y, TRUE);
}
default:
emacs_event->kind = no_event;
return FALSE;
}
XSETINT (emacs_event->x, y);
XSETINT (emacs_event->y, top_range);
return TRUE;
}
}
static void
x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
FRAME_PTR *fp;
Lisp_Object *bar_window;
enum scroll_bar_part *part;
Lisp_Object *x, *y;
unsigned long *time;
{
struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
Window w = SCROLL_BAR_W32_WINDOW (bar);
FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
int pos;
int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (XINT (bar->height));
BLOCK_INPUT;
*fp = f;
*bar_window = bar->window;
if (pfnGetScrollInfo)
{
SCROLLINFO si;
si.cbSize = sizeof (si);
si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
pfnGetScrollInfo (w, SB_CTL, &si);
pos = si.nPos;
top_range = si.nMax - si.nPage + 1;
}
else
pos = GetScrollPos (w, SB_CTL);
switch (LOWORD (last_mouse_scroll_bar_pos))
{
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
*part = scroll_bar_handle;
if (VERTICAL_SCROLL_BAR_TOP_RANGE (XINT (bar->height)) <= 0xffff)
pos = HIWORD (last_mouse_scroll_bar_pos);
break;
case SB_LINEDOWN:
*part = scroll_bar_handle;
pos++;
break;
default:
*part = scroll_bar_handle;
break;
}
XSETINT(*x, pos);
XSETINT(*y, top_range);
f->mouse_moved = 0;
last_mouse_scroll_bar = Qnil;
*time = last_mouse_movement_time;
UNBLOCK_INPUT;
}
x_scroll_bar_clear (f)
FRAME_PTR f;
{
Lisp_Object bar;
for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
bar = XSCROLL_BAR (bar)->next)
{
HWND window = SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar));
HDC hdc = GetDC (window);
RECT rect;
my_show_window (f, window, SW_HIDE);
GetClientRect (window, &rect);
select_palette (f, hdc);
w32_clear_rect (f, hdc, &rect);
deselect_palette (f, hdc);
ReleaseDC (window, hdc);
}
}
show_scroll_bars (f, how)
FRAME_PTR f;
int how;
{
Lisp_Object bar;
for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
bar = XSCROLL_BAR (bar)->next)
{
HWND window = SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar));
my_show_window (f, window, how);
}
}
static Time enter_timestamp;
int temp_index;
short temp_buffer[100];
int
w32_read_socket (sd, bufp, numchars, expected)
register int sd;
register struct input_event *bufp;
register int numchars;
int expected;
{
int count = 0;
int check_visibility = 0;
W32Msg msg;
struct frame *f;
Lisp_Object part;
struct w32_display_info *dpyinfo = &one_w32_display_info;
if (interrupt_input_blocked)
{
interrupt_input_pending = 1;
return -1;
}
interrupt_input_pending = 0;
BLOCK_INPUT;
input_signal_count++;
if (numchars <= 0)
abort ();
while (get_next_msg (&msg, FALSE))
{
switch (msg.msg.message)
{
case WM_PAINT:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f)
{
if (msg.rect.right == msg.rect.left ||
msg.rect.bottom == msg.rect.top)
{
DebPrint (("clipped frame %04x (%s) got WM_PAINT\n", f,
XSTRING (f->name)->data));
}
else if (f->async_visible != 1)
{
f->async_visible = 1;
f->async_iconified = 0;
SET_FRAME_GARBAGED (f);
DebPrint (("frame %04x (%s) reexposed\n", f,
XSTRING (f->name)->data));
if (f->iconified)
{
bufp->kind = deiconify_event;
XSETFRAME (bufp->frame_or_window, f);
bufp++;
count++;
numchars--;
}
else if (! NILP(Vframe_list)
&& ! NILP (XCONS (Vframe_list)->cdr))
record_asynch_buffer_change ();
}
else
{
w32_clear_rect (f, NULL, &msg.rect);
dumprectangle (f,
msg.rect.left,
msg.rect.top,
msg.rect.right - msg.rect.left,
msg.rect.bottom - msg.rect.top);
}
}
break;
case WM_INPUTLANGCHANGE:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f)
{
if (numchars == 0)
abort ();
bufp->kind = language_change_event;
XSETFRAME (bufp->frame_or_window, f);
bufp->code = msg.msg.wParam;
bufp->modifiers = msg.msg.lParam & 0xffff;
bufp++;
count++;
numchars--;
}
break;
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f && !f->iconified)
{
if (temp_index == sizeof temp_buffer / sizeof (short))
temp_index = 0;
temp_buffer[temp_index++] = msg.msg.wParam;
bufp->kind = non_ascii_keystroke;
bufp->code = msg.msg.wParam;
bufp->modifiers = msg.dwModifiers;
XSETFRAME (bufp->frame_or_window, f);
bufp->timestamp = msg.msg.time;
bufp++;
numchars--;
count++;
}
break;
case WM_SYSCHAR:
case WM_CHAR:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f && !f->iconified)
{
if (temp_index == sizeof temp_buffer / sizeof (short))
temp_index = 0;
temp_buffer[temp_index++] = msg.msg.wParam;
bufp->kind = ascii_keystroke;
bufp->code = msg.msg.wParam;
bufp->modifiers = msg.dwModifiers;
XSETFRAME (bufp->frame_or_window, f);
bufp->timestamp = msg.msg.time;
bufp++;
numchars--;
count++;
}
break;
case WM_MOUSEMOVE:
if (dpyinfo->grabbed && last_mouse_frame
&& FRAME_LIVE_P (last_mouse_frame))
f = last_mouse_frame;
else
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f)
note_mouse_movement (f, &msg.msg);
else
clear_mouse_face (FRAME_W32_DISPLAY_INFO (f));
break;
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
{
int button;
int up;
if (dpyinfo->grabbed && last_mouse_frame
&& FRAME_LIVE_P (last_mouse_frame))
f = last_mouse_frame;
else
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f)
{
if ((!dpyinfo->w32_focus_frame || f == dpyinfo->w32_focus_frame)
&& (numchars >= 1))
{
construct_mouse_click (bufp, &msg, f);
bufp++;
count++;
numchars--;
}
}
parse_button (msg.msg.message, &button, &up);
if (up)
{
dpyinfo->grabbed &= ~ (1 << button);
}
else
{
dpyinfo->grabbed |= (1 << button);
last_mouse_frame = f;
}
break;
}
case WM_MOUSEWHEEL:
if (dpyinfo->grabbed && last_mouse_frame
&& FRAME_LIVE_P (last_mouse_frame))
f = last_mouse_frame;
else
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f)
{
if ((!dpyinfo->w32_focus_frame
|| f == dpyinfo->w32_focus_frame)
&& (numchars >= 1))
{
construct_mouse_wheel (bufp, &msg, f);
bufp++;
count++;
numchars--;
}
}
break;
case WM_DROPFILES:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f)
{
construct_drag_n_drop (bufp, &msg, f);
bufp++;
count++;
numchars--;
}
break;
case WM_VSCROLL:
{
struct scroll_bar *bar =
x_window_to_scroll_bar ((HWND)msg.msg.lParam);
if (bar && numchars >= 1)
{
if (x_scroll_bar_handle_click (bar, &msg, bufp))
{
bufp++;
count++;
numchars--;
}
}
break;
}
case WM_WINDOWPOSCHANGED:
case WM_ACTIVATE:
case WM_ACTIVATEAPP:
check_visibility = 1;
break;
case WM_MOVE:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f && !f->async_iconified)
{
int x, y;
x_real_positions (f, &x, &y);
f->output_data.w32->left_pos = x;
f->output_data.w32->top_pos = y;
}
check_visibility = 1;
break;
case WM_SHOWWINDOW:
#if 0
if (msg.msg.lParam != 0)
check_visibility = 1;
else
{
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
f->async_visible = msg.msg.wParam;
}
#endif
check_visibility = 1;
break;
case WM_SIZE:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f)
{
switch (msg.msg.wParam)
{
case SIZE_MINIMIZED:
f->async_visible = 0;
f->async_iconified = 1;
bufp->kind = iconify_event;
XSETFRAME (bufp->frame_or_window, f);
bufp++;
count++;
numchars--;
break;
case SIZE_MAXIMIZED:
case SIZE_RESTORED:
f->async_visible = 1;
f->async_iconified = 0;
SET_FRAME_GARBAGED (f);
if (f->iconified)
{
int x, y;
x_real_positions (f, &x, &y);
f->output_data.w32->left_pos = x;
f->output_data.w32->top_pos = y;
bufp->kind = deiconify_event;
XSETFRAME (bufp->frame_or_window, f);
bufp++;
count++;
numchars--;
}
else
record_asynch_buffer_change ();
break;
}
}
if (f && !f->async_iconified && msg.msg.wParam != SIZE_MINIMIZED)
{
RECT rect;
int rows;
int columns;
int width;
int height;
GetClientRect(msg.msg.hwnd, &rect);
height = rect.bottom - rect.top;
width = rect.right - rect.left;
rows = PIXEL_TO_CHAR_HEIGHT (f, height);
columns = PIXEL_TO_CHAR_WIDTH (f, width);
if (columns != f->width
|| rows != f->height
|| width != f->output_data.w32->pixel_width
|| height != f->output_data.w32->pixel_height)
{
change_frame_size (f, rows, columns, 0, 1);
SET_FRAME_GARBAGED (f);
cancel_mouse_face (f);
f->output_data.w32->pixel_width = width;
f->output_data.w32->pixel_height = height;
f->output_data.w32->win_gravity = NorthWestGravity;
}
}
check_visibility = 1;
break;
case WM_SETFOCUS:
case WM_KILLFOCUS:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (msg.msg.message == WM_SETFOCUS)
{
x_new_focus_frame (dpyinfo, f);
}
else if (f == dpyinfo->w32_focus_frame)
{
x_new_focus_frame (dpyinfo, 0);
if (f == dpyinfo->mouse_face_mouse_frame)
clear_mouse_face (dpyinfo);
}
dpyinfo->grabbed = 0;
check_visibility = 1;
break;
case WM_CLOSE:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f)
{
if (numchars == 0)
abort ();
bufp->kind = delete_window_event;
XSETFRAME (bufp->frame_or_window, f);
bufp++;
count++;
numchars--;
}
break;
case WM_INITMENU:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f)
{
if (numchars == 0)
abort ();
bufp->kind = menu_bar_activate_event;
XSETFRAME (bufp->frame_or_window, f);
bufp++;
count++;
numchars--;
}
break;
case WM_COMMAND:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f)
{
extern void menubar_selection_callback
(FRAME_PTR f, void * client_data);
menubar_selection_callback (f, (void *)msg.msg.wParam);
}
check_visibility = 1;
break;
case WM_DISPLAYCHANGE:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
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));
}
check_visibility = 1;
break;
default:
if (msg.msg.message == msh_mousewheel)
{
if (dpyinfo->grabbed && last_mouse_frame
&& FRAME_LIVE_P (last_mouse_frame))
f = last_mouse_frame;
else
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f)
{
if ((!dpyinfo->w32_focus_frame
|| f == dpyinfo->w32_focus_frame)
&& (numchars >= 1))
{
construct_mouse_wheel (bufp, &msg, f);
bufp++;
count++;
numchars--;
}
}
}
break;
}
}
if (pending_autoraise_frame)
{
x_raise_frame (pending_autoraise_frame);
pending_autoraise_frame = 0;
}
if (count > 0 || check_visibility)
{
Lisp_Object tail, frame;
FOR_EACH_FRAME (tail, frame)
{
FRAME_PTR f = XFRAME (frame);
if (FRAME_W32_P (f) && f->async_visible)
{
RECT clipbox;
HDC hdc = get_frame_dc (f);
GetClipBox (hdc, &clipbox);
release_frame_dc (f, hdc);
if (clipbox.right == clipbox.left
|| clipbox.bottom == clipbox.top)
{
f->async_visible = 2;
if (!FRAME_OBSCURED_P (f))
{
DebPrint (("frame %04x (%s) obscured\n", f,
XSTRING (f->name)->data));
}
}
else
{
f->async_visible = 1;
if (FRAME_OBSCURED_P (f))
{
SET_FRAME_GARBAGED (f);
DebPrint (("frame %04x (%s) reexposed\n", f,
XSTRING (f->name)->data));
record_asynch_buffer_change ();
}
}
}
}
}
UNBLOCK_INPUT;
return count;
}
static void
x_draw_box (f)
struct frame *f;
{
RECT rect;
HBRUSH hb;
HDC hdc;
hdc = get_frame_dc (f);
hb = CreateSolidBrush (f->output_data.w32->cursor_pixel);
rect.left = CHAR_TO_PIXEL_COL (f, curs_x);
rect.top = CHAR_TO_PIXEL_ROW (f, curs_y);
rect.right = rect.left + FONT_WIDTH (f->output_data.w32->font);
rect.bottom = rect.top + f->output_data.w32->line_height;
FrameRect (hdc, &rect, hb);
DeleteObject (hb);
release_frame_dc (f, hdc);
}
static void
clear_cursor (f)
struct frame *f;
{
if (! FRAME_VISIBLE_P (f)
|| !f->phys_cursor_on)
return;
x_display_cursor (f, 0);
f->phys_cursor_on = 0;
}
static void
x_draw_single_glyph (f, row, column, glyph, highlight)
struct frame *f;
int row, column;
GLYPH glyph;
int highlight;
{
dumpglyphs (f,
CHAR_TO_PIXEL_COL (f, column),
CHAR_TO_PIXEL_ROW (f, row),
&glyph, 1, highlight, 0, NULL);
}
static void
x_display_bar_cursor (f, on)
struct frame *f;
int on;
{
struct frame_glyphs *current_glyphs = FRAME_CURRENT_GLYPHS (f);
if (! FRAME_VISIBLE_P (f) || FRAME_GARBAGED_P (f))
return;
if (! on && ! f->phys_cursor_on)
return;
if (f->phys_cursor_on
&& (!on
|| f->phys_cursor_x != curs_x
|| f->phys_cursor_y != curs_y
|| f->output_data.w32->current_cursor != bar_cursor))
{
x_draw_single_glyph (f, f->phys_cursor_y, f->phys_cursor_x,
f->phys_cursor_glyph,
current_glyphs->highlight[f->phys_cursor_y]);
f->phys_cursor_on = 0;
}
if (on
&& (! f->phys_cursor_on
|| (f->output_data.w32->current_cursor != bar_cursor)))
{
f->phys_cursor_glyph
= ((current_glyphs->enable[curs_y]
&& curs_x < current_glyphs->used[curs_y])
? current_glyphs->glyphs[curs_y][curs_x]
: SPACEGLYPH);
w32_fill_area (f, NULL, f->output_data.w32->cursor_pixel,
CHAR_TO_PIXEL_COL (f, curs_x),
CHAR_TO_PIXEL_ROW (f, curs_y),
max (f->output_data.w32->cursor_width, 1),
f->output_data.w32->line_height);
f->phys_cursor_x = curs_x;
f->phys_cursor_y = curs_y;
f->phys_cursor_on = 1;
f->output_data.w32->current_cursor = bar_cursor;
}
}
static void
x_display_box_cursor (f, on)
struct frame *f;
int on;
{
struct frame_glyphs *current_glyphs = FRAME_CURRENT_GLYPHS (f);
if (! FRAME_VISIBLE_P (f) || FRAME_GARBAGED_P (f))
return;
if (!on && ! f->phys_cursor_on)
return;
if (f->phys_cursor_on
&& (!on
|| f->phys_cursor_x != curs_x
|| f->phys_cursor_y != curs_y
|| (f->output_data.w32->current_cursor != hollow_box_cursor
&& (f != FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame))))
{
int mouse_face_here = 0;
struct frame_glyphs *active_glyphs = FRAME_CURRENT_GLYPHS (f);
if (f == FRAME_W32_DISPLAY_INFO (f)->mouse_face_mouse_frame
&& (f->phys_cursor_y > FRAME_W32_DISPLAY_INFO (f)->mouse_face_beg_row
|| (f->phys_cursor_y == FRAME_W32_DISPLAY_INFO (f)->mouse_face_beg_row
&& f->phys_cursor_x >= FRAME_W32_DISPLAY_INFO (f)->mouse_face_beg_col))
&& (f->phys_cursor_y < FRAME_W32_DISPLAY_INFO (f)->mouse_face_end_row
|| (f->phys_cursor_y == FRAME_W32_DISPLAY_INFO (f)->mouse_face_end_row
&& f->phys_cursor_x < FRAME_W32_DISPLAY_INFO (f)->mouse_face_end_col))
&& active_glyphs->used[f->phys_cursor_y] > f->phys_cursor_x)
mouse_face_here = 1;
if (FONT_HEIGHT (f->output_data.w32->font) != f->output_data.w32->line_height)
w32_clear_area (f, NULL,
CHAR_TO_PIXEL_COL (f, f->phys_cursor_x),
CHAR_TO_PIXEL_ROW (f, f->phys_cursor_y),
FONT_WIDTH (f->output_data.w32->font),
f->output_data.w32->line_height);
x_draw_single_glyph (f, f->phys_cursor_y, f->phys_cursor_x,
f->phys_cursor_glyph,
(mouse_face_here
? 3
: current_glyphs->highlight[f->phys_cursor_y]));
f->phys_cursor_on = 0;
}
if (on
&& (! f->phys_cursor_on
|| (f->output_data.w32->current_cursor != filled_box_cursor
&& f == FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame)))
{
f->phys_cursor_glyph
= ((current_glyphs->enable[curs_y]
&& curs_x < current_glyphs->used[curs_y])
? current_glyphs->glyphs[curs_y][curs_x]
: SPACEGLYPH);
if (f != FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame)
{
x_draw_box (f);
f->output_data.w32->current_cursor = hollow_box_cursor;
}
else
{
x_draw_single_glyph (f, curs_y, curs_x,
f->phys_cursor_glyph, 2);
f->output_data.w32->current_cursor = filled_box_cursor;
}
f->phys_cursor_x = curs_x;
f->phys_cursor_y = curs_y;
f->phys_cursor_on = 1;
}
}
x_display_cursor (f, on)
struct frame *f;
int on;
{
BLOCK_INPUT;
if (f != updating_frame)
{
curs_x = FRAME_CURSOR_X (f);
curs_y = FRAME_CURSOR_Y (f);
}
if (FRAME_DESIRED_CURSOR (f) == filled_box_cursor)
x_display_box_cursor (f, on);
else if (FRAME_DESIRED_CURSOR (f) == bar_cursor)
x_display_bar_cursor (f, on);
else
abort ();
UNBLOCK_INPUT;
}
Lisp_Object
x_new_font (f, fontname)
struct frame *f;
register char *fontname;
{
struct font_info *fontp
= fs_load_font (f, FRAME_W32_FONT_TABLE (f), CHARSET_ASCII,
fontname, -1);
if (!fontp)
return Qnil;
FRAME_FONT (f) = (XFontStruct *) (fontp->font);
f->output_data.w32->font_baseline
= FONT_BASE (FRAME_FONT (f)) + fontp->baseline_offset;
FRAME_FONTSET (f) = -1;
if (f->scroll_bar_pixel_width > 0)
{
int wid = FONT_WIDTH (f->output_data.w32->font);
f->scroll_bar_cols = (f->scroll_bar_pixel_width + wid-1) / wid;
}
else
f->scroll_bar_cols = 2;
if (FRAME_W32_WINDOW (f) != 0)
{
frame_update_line_height (f);
x_set_window_size (f, 0, f->width, f->height);
}
else
f->output_data.w32->line_height = FONT_HEIGHT (f->output_data.w32->font);
{
Lisp_Object lispy_name;
lispy_name = build_string (fontname);
return lispy_name;
}
}
Lisp_Object
x_new_fontset (f, fontsetname)
struct frame *f;
char *fontsetname;
{
int fontset = fs_query_fontset (f, fontsetname);
struct fontset_info *fontsetp;
Lisp_Object result;
if (fontset < 0)
return Qnil;
if (FRAME_FONTSET (f) == fontset)
return build_string (fontsetname);
fontsetp = FRAME_FONTSET_DATA (f)->fontset_table[fontset];
if (!fontsetp->fontname[CHARSET_ASCII])
return Qnil;
result = x_new_font (f, fontsetp->fontname[CHARSET_ASCII]);
if (!STRINGP (result))
return Qnil;
FRAME_FONTSET(f) = fontset;
FS_LOAD_FONT (f, FRAME_W32_FONT_TABLE (f),
CHARSET_ASCII, XSTRING (result)->data, fontset);
return build_string (fontsetname);
}
x_calc_absolute_position (f)
struct frame *f;
{
Window win, child;
POINT pt;
int flags = f->output_data.w32->size_hint_flags;
pt.x = pt.y = 0;
if (f->output_data.w32->parent_desc != FRAME_W32_DISPLAY_INFO (f)->root_window)
{
BLOCK_INPUT;
MapWindowPoints (FRAME_W32_WINDOW (f),
f->output_data.w32->parent_desc,
&pt, 1);
UNBLOCK_INPUT;
}
{
RECT rt;
rt.left = rt.right = rt.top = rt.bottom = 0;
BLOCK_INPUT;
AdjustWindowRect(&rt, f->output_data.w32->dwStyle,
FRAME_EXTERNAL_MENU_BAR (f));
UNBLOCK_INPUT;
pt.x += (rt.right - rt.left);
pt.y += (rt.bottom - rt.top);
}
if (flags & XNegative)
f->output_data.w32->left_pos = (FRAME_W32_DISPLAY_INFO (f)->width
- 2 * f->output_data.w32->border_width - pt.x
- PIXEL_WIDTH (f)
+ f->output_data.w32->left_pos);
if (flags & YNegative)
f->output_data.w32->top_pos = (FRAME_W32_DISPLAY_INFO (f)->height
- 2 * f->output_data.w32->border_width - pt.y
- PIXEL_HEIGHT (f)
+ f->output_data.w32->top_pos);
f->output_data.w32->size_hint_flags &= ~ (XNegative | YNegative);
}
x_set_offset (f, xoff, yoff, change_gravity)
struct frame *f;
register int xoff, yoff;
int change_gravity;
{
int modified_top, modified_left;
if (change_gravity > 0)
{
f->output_data.w32->top_pos = yoff;
f->output_data.w32->left_pos = xoff;
f->output_data.w32->size_hint_flags &= ~ (XNegative | YNegative);
if (xoff < 0)
f->output_data.w32->size_hint_flags |= XNegative;
if (yoff < 0)
f->output_data.w32->size_hint_flags |= YNegative;
f->output_data.w32->win_gravity = NorthWestGravity;
}
x_calc_absolute_position (f);
BLOCK_INPUT;
x_wm_set_size_hint (f, (long) 0, 0);
modified_left = f->output_data.w32->left_pos;
modified_top = f->output_data.w32->top_pos;
#ifndef HAVE_NTGUI
if (change_gravity != 0)
{
modified_left += f->output_data.w32->border_width;
modified_top += f->output_data.w32->border_width;
}
#endif
my_set_window_pos (FRAME_W32_WINDOW (f),
NULL,
modified_left, modified_top,
0, 0,
SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
UNBLOCK_INPUT;
}
x_set_window_size (f, change_gravity, cols, rows)
struct frame *f;
int change_gravity;
int cols, rows;
{
int pixelwidth, pixelheight;
struct w32_display_info *dpyinfo = &one_w32_display_info;
BLOCK_INPUT;
check_frame_size (f, &rows, &cols);
f->output_data.w32->vertical_scroll_bar_extra
= (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
? 0
: FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0
? FRAME_SCROLL_BAR_PIXEL_WIDTH (f)
: (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.w32->font)));
pixelwidth = CHAR_TO_PIXEL_WIDTH (f, cols);
pixelheight = CHAR_TO_PIXEL_HEIGHT (f, rows);
f->output_data.w32->win_gravity = NorthWestGravity;
x_wm_set_size_hint (f, (long) 0, 0);
{
RECT rect;
rect.left = rect.top = 0;
rect.right = pixelwidth;
rect.bottom = pixelheight;
AdjustWindowRect(&rect, f->output_data.w32->dwStyle,
FRAME_EXTERNAL_MENU_BAR (f));
my_set_window_pos (FRAME_W32_WINDOW (f),
NULL,
0, 0,
rect.right - rect.left,
rect.bottom - rect.top,
SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
}
change_frame_size (f, rows, cols, 0, 0);
PIXEL_WIDTH (f) = pixelwidth;
PIXEL_HEIGHT (f) = pixelheight;
SET_FRAME_GARBAGED (f);
if (f->phys_cursor_y >= rows
|| f->phys_cursor_x >= cols)
{
f->phys_cursor_x = 0;
f->phys_cursor_y = 0;
f->phys_cursor_on = 0;
}
cancel_mouse_face (f);
UNBLOCK_INPUT;
}
void
x_set_mouse_pixel_position (f, pix_x, pix_y)
struct frame *f;
int pix_x, pix_y;
{
RECT rect;
POINT pt;
BLOCK_INPUT;
GetClientRect (FRAME_W32_WINDOW (f), &rect);
pt.x = rect.left + pix_x;
pt.y = rect.top + pix_y;
ClientToScreen (FRAME_W32_WINDOW (f), &pt);
SetCursorPos (pt.x, pt.y);
UNBLOCK_INPUT;
}
void
x_set_mouse_position (f, x, y)
struct frame *f;
int x, y;
{
int pix_x, pix_y;
pix_x = CHAR_TO_PIXEL_COL (f, x) + FONT_WIDTH (f->output_data.w32->font) / 2;
pix_y = CHAR_TO_PIXEL_ROW (f, y) + f->output_data.w32->line_height / 2;
if (pix_x < 0) pix_x = 0;
if (pix_x > PIXEL_WIDTH (f)) pix_x = PIXEL_WIDTH (f);
if (pix_y < 0) pix_y = 0;
if (pix_y > PIXEL_HEIGHT (f)) pix_y = PIXEL_HEIGHT (f);
x_set_mouse_pixel_position (f, pix_x, pix_y);
}
x_focus_on_frame (f)
struct frame *f;
{
struct w32_display_info *dpyinfo = &one_w32_display_info;
BLOCK_INPUT;
#if 0
if (x_window_to_frame (dpyinfo, GetForegroundWindow ()))
my_set_focus (f, FRAME_W32_WINDOW (f));
else
#endif
my_set_foreground_window (FRAME_W32_WINDOW (f));
UNBLOCK_INPUT;
}
x_unfocus_frame (f)
struct frame *f;
{
}
x_raise_frame (f)
struct frame *f;
{
BLOCK_INPUT;
if (NILP (Vw32_grab_focus_on_raise))
{
HDWP handle = BeginDeferWindowPos (2);
if (handle)
{
DeferWindowPos (handle,
FRAME_W32_WINDOW (f),
HWND_TOP,
0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
DeferWindowPos (handle,
GetForegroundWindow (),
FRAME_W32_WINDOW (f),
0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
EndDeferWindowPos (handle);
}
}
else
{
my_set_foreground_window (FRAME_W32_WINDOW (f));
}
UNBLOCK_INPUT;
}
x_lower_frame (f)
struct frame *f;
{
BLOCK_INPUT;
my_set_window_pos (FRAME_W32_WINDOW (f),
HWND_BOTTOM,
0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
UNBLOCK_INPUT;
}
static void
w32_frame_raise_lower (f, raise)
FRAME_PTR f;
int raise;
{
if (raise)
x_raise_frame (f);
else
x_lower_frame (f);
}
x_make_frame_visible (f)
struct frame *f;
{
BLOCK_INPUT;
if (! FRAME_VISIBLE_P (f))
{
if (! FRAME_ICONIFIED_P (f)
&& ! f->output_data.w32->asked_for_visible)
x_set_offset (f, f->output_data.w32->left_pos, f->output_data.w32->top_pos, 0);
f->output_data.w32->asked_for_visible = 1;
my_show_window (f, FRAME_W32_WINDOW (f), SW_SHOWNORMAL);
}
{
Lisp_Object frame;
int count = input_signal_count;
UNBLOCK_INPUT;
XSETFRAME (frame, f);
while (1)
{
if (input_signal_count != count)
break;
if (input_polling_used ())
{
alarm (0);
input_poll_signal (0);
}
if (input_signal_count != count)
break;
}
FRAME_SAMPLE_VISIBILITY (f);
}
}
x_make_frame_invisible (f)
struct frame *f;
{
Window window;
if (FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame == f)
FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame = 0;
BLOCK_INPUT;
my_show_window (f, FRAME_W32_WINDOW (f), SW_HIDE);
f->visible = 0;
FRAME_ICONIFIED_P (f) = 0;
f->async_visible = 0;
f->async_iconified = 0;
UNBLOCK_INPUT;
}
void
x_iconify_frame (f)
struct frame *f;
{
int result;
if (FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame == f)
FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame = 0;
if (f->async_iconified)
return;
BLOCK_INPUT;
SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0);
UNBLOCK_INPUT;
}
x_destroy_window (f)
struct frame *f;
{
struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
BLOCK_INPUT;
my_destroy_window (f, FRAME_W32_WINDOW (f));
free_frame_menubar (f);
free_frame_faces (f);
xfree (f->output_data.w32);
f->output_data.w32 = 0;
if (f == dpyinfo->w32_focus_frame)
dpyinfo->w32_focus_frame = 0;
if (f == dpyinfo->w32_focus_event_frame)
dpyinfo->w32_focus_event_frame = 0;
if (f == dpyinfo->w32_highlight_frame)
dpyinfo->w32_highlight_frame = 0;
dpyinfo->reference_count--;
if (f == dpyinfo->mouse_face_mouse_frame)
{
dpyinfo->mouse_face_beg_row
= dpyinfo->mouse_face_beg_col = -1;
dpyinfo->mouse_face_end_row
= dpyinfo->mouse_face_end_col = -1;
dpyinfo->mouse_face_window = Qnil;
}
UNBLOCK_INPUT;
}
x_wm_set_size_hint (f, flags, user_position)
struct frame *f;
long flags;
int user_position;
{
Window window = FRAME_W32_WINDOW (f);
flexlines = f->height;
enter_crit ();
SetWindowLong (window, WND_FONTWIDTH_INDEX, FONT_WIDTH (f->output_data.w32->font));
SetWindowLong (window, WND_LINEHEIGHT_INDEX, f->output_data.w32->line_height);
SetWindowLong (window, WND_BORDER_INDEX, f->output_data.w32->internal_border_width);
SetWindowLong (window, WND_SCROLLBAR_INDEX, f->output_data.w32->vertical_scroll_bar_extra);
leave_crit ();
}
x_wm_set_icon_position (f, icon_x, icon_y)
struct frame *f;
int icon_x, icon_y;
{
#if 0
Window window = FRAME_W32_WINDOW (f);
f->display.x->wm_hints.flags |= IconPositionHint;
f->display.x->wm_hints.icon_x = icon_x;
f->display.x->wm_hints.icon_y = icon_y;
XSetWMHints (FRAME_X_DISPLAY (f), window, &f->display.x->wm_hints);
#endif
}
#ifdef USE_X_TOOLKIT
static XrmOptionDescRec emacs_options[] = {
{"-geometry", ".geometry", XrmoptionSepArg, NULL},
{"-iconic", ".iconic", XrmoptionNoArg, (XtPointer) "yes"},
{"-internal-border-width", "*EmacsScreen.internalBorderWidth",
XrmoptionSepArg, NULL},
{"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg, NULL},
{"-T", "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
{"-wn", "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
{"-title", "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
{"-iconname", "*EmacsShell.iconName", XrmoptionSepArg, (XtPointer) NULL},
{"-in", "*EmacsShell.iconName", XrmoptionSepArg, (XtPointer) NULL},
{"-mc", "*pointerColor", XrmoptionSepArg, (XtPointer) NULL},
{"-cr", "*cursorColor", XrmoptionSepArg, (XtPointer) NULL}
};
#endif
static int w32_initialized = 0;
struct w32_display_info *
w32_term_init (display_name, xrm_option, resource_name)
Lisp_Object display_name;
char *xrm_option;
char *resource_name;
{
Lisp_Object frame;
char *defaultvalue;
struct w32_display_info *dpyinfo;
HDC hdc;
BLOCK_INPUT;
if (!w32_initialized)
{
w32_initialize ();
w32_initialized = 1;
}
{
int argc = 0;
char *argv[3];
argv[0] = "";
argc = 1;
if (xrm_option)
{
argv[argc++] = "-xrm";
argv[argc++] = xrm_option;
}
}
dpyinfo = &one_w32_display_info;
dpyinfo->next = NULL;
w32_display_name_list = Fcons (Fcons (display_name, Qnil),
w32_display_name_list);
dpyinfo->name_list_element = XCONS (w32_display_name_list)->car;
dpyinfo->w32_id_name
= (char *) xmalloc (XSTRING (Vinvocation_name)->size
+ XSTRING (Vsystem_name)->size
+ 2);
sprintf (dpyinfo->w32_id_name, "%s@%s",
XSTRING (Vinvocation_name)->data, XSTRING (Vsystem_name)->data);
#if 0
xrdb = x_load_resources (dpyinfo->display, xrm_option,
resource_name, EMACS_CLASS);
dpyinfo->xrdb = xrdb;
#endif
hdc = GetDC (GetDesktopWindow ());
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->height_in = GetDeviceCaps (hdc, LOGPIXELSX);
dpyinfo->width_in = GetDeviceCaps (hdc, LOGPIXELSY);
dpyinfo->has_palette = GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE;
dpyinfo->grabbed = 0;
dpyinfo->reference_count = 0;
dpyinfo->n_fonts = 0;
dpyinfo->font_table_size = 0;
dpyinfo->bitmaps = 0;
dpyinfo->bitmaps_size = 0;
dpyinfo->bitmaps_last = 0;
dpyinfo->mouse_face_mouse_frame = 0;
dpyinfo->mouse_face_deferred_gc = 0;
dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
dpyinfo->mouse_face_face_id = 0;
dpyinfo->mouse_face_window = Qnil;
dpyinfo->mouse_face_mouse_x = dpyinfo->mouse_face_mouse_y = 0;
dpyinfo->mouse_face_defer = 0;
dpyinfo->w32_focus_frame = 0;
dpyinfo->w32_focus_event_frame = 0;
dpyinfo->w32_highlight_frame = 0;
ReleaseDC (GetDesktopWindow (), hdc);
XSETINT (Vw32_num_mouse_buttons, GetSystemMetrics (SM_CMOUSEBUTTONS));
{
COLORREF color;
defined_color (0, "white", &color, 1);
defined_color (0, "black", &color, 1);
}
#ifndef F_SETOWN_BUG
#ifdef F_SETOWN
#ifdef F_SETOWN_SOCK_NEG
fcntl (connection, F_SETOWN, -getpid ());
#else
fcntl (connection, F_SETOWN, getpid ());
#endif
#endif
#endif
#ifdef SIGIO
if (interrupt_input)
init_sigio (connection);
#endif
UNBLOCK_INPUT;
return dpyinfo;
}
void
x_delete_display (dpyinfo)
struct w32_display_info *dpyinfo;
{
if (! NILP (w32_display_name_list)
&& EQ (XCONS (w32_display_name_list)->car, dpyinfo->name_list_element))
w32_display_name_list = XCONS (w32_display_name_list)->cdr;
else
{
Lisp_Object tail;
tail = w32_display_name_list;
while (CONSP (tail) && CONSP (XCONS (tail)->cdr))
{
if (EQ (XCONS (XCONS (tail)->cdr)->car,
dpyinfo->name_list_element))
{
XCONS (tail)->cdr = XCONS (XCONS (tail)->cdr)->cdr;
break;
}
tail = XCONS (tail)->cdr;
}
}
{
struct w32_palette_entry * plist;
plist = dpyinfo->color_list;
while (plist)
{
struct w32_palette_entry * pentry = plist;
plist = plist->next;
xfree(pentry);
}
dpyinfo->color_list = NULL;
if (dpyinfo->palette)
DeleteObject(dpyinfo->palette);
}
xfree (dpyinfo->font_table);
xfree (dpyinfo->w32_id_name);
}
DWORD w32_msg_worker ();
w32_initialize ()
{
clear_frame_hook = (void (*)(void)) w32_clear_frame;
clear_end_of_line_hook = w32_clear_end_of_line;
ins_del_lines_hook = w32_ins_del_lines;
change_line_highlight_hook = w32_change_line_highlight;
insert_glyphs_hook = w32_insert_glyphs;
write_glyphs_hook = w32_write_glyphs;
delete_glyphs_hook = w32_delete_glyphs;
ring_bell_hook = (void (*)(void)) w32_ring_bell;
reset_terminal_modes_hook = (void (*)(void)) w32_reset_terminal_modes;
set_terminal_modes_hook = (void (*)(void)) w32_set_terminal_modes;
update_begin_hook = w32_update_begin;
update_end_hook = w32_update_end;
set_terminal_window_hook = w32_set_terminal_window;
read_socket_hook = w32_read_socket;
frame_up_to_date_hook = w32_frame_up_to_date;
cursor_to_hook = w32_cursor_to;
reassert_line_highlight_hook = w32_reassert_line_highlight;
mouse_position_hook = w32_mouse_position;
frame_rehighlight_hook = w32_frame_rehighlight;
frame_raise_lower_hook = w32_frame_raise_lower;
set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar;
condemn_scroll_bars_hook = w32_condemn_scroll_bars;
redeem_scroll_bar_hook = w32_redeem_scroll_bar;
judge_scroll_bars_hook = w32_judge_scroll_bars;
scroll_region_ok = 1;
char_ins_del_ok = 0;
line_ins_del_ok = 1;
fast_clear_end_of_line = 1;
memory_below_frame = 0;
baud_rate = 19200;
Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
init_crit ();
dwMainThreadId = GetCurrentThreadId ();
DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
GetCurrentProcess (), &hMainThread, 0, TRUE, DUPLICATE_SAME_ACCESS);
{
MSG msg;
PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
hWindowsThread = CreateThread (NULL, 0,
(LPTHREAD_START_ROUTINE) w32_msg_worker,
0, 0, &dwWindowsThreadId);
GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
}
#ifdef ATTACH_THREADS
AttachThreadInput (dwMainThreadId, dwWindowsThreadId, TRUE);
#endif
{
HANDLE user_lib = LoadLibrary ("user32.dll");
#define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
LOAD_PROC( SetScrollInfo );
LOAD_PROC( GetScrollInfo );
#undef LOAD_PROC
FreeLibrary (user_lib);
vertical_scroll_bar_min_handle = (pfnSetScrollInfo != NULL) ? 5 :
GetSystemMetrics (SM_CYVTHUMB);
vertical_scroll_bar_top_border = vertical_scroll_bar_bottom_border
= GetSystemMetrics (SM_CYVSCROLL);
}
}
void
syms_of_w32term ()
{
Lisp_Object codepage;
staticpro (&w32_display_name_list);
w32_display_name_list = Qnil;
staticpro (&last_mouse_scroll_bar);
last_mouse_scroll_bar = Qnil;
staticpro (&Qvendor_specific_keysyms);
Qvendor_specific_keysyms = intern ("vendor-specific-keysyms");
DEFVAR_INT ("w32-num-mouse-buttons",
&Vw32_num_mouse_buttons,
"Number of physical mouse buttons.");
Vw32_num_mouse_buttons = Qnil;
DEFVAR_LISP ("w32-swap-mouse-buttons",
&Vw32_swap_mouse_buttons,
"Swap the mapping of middle and right mouse buttons.\n\
When nil, middle button is mouse-2 and right button is mouse-3.");
Vw32_swap_mouse_buttons = Qnil;
DEFVAR_LISP ("w32-grab-focus-on-raise",
&Vw32_grab_focus_on_raise,
"Raised frame grabs input focus.\n\
When t, `raise-frame' grabs input focus as well. This fits well\n\
with the normal Windows click-to-focus policy, but might not be\n\
desirable when using a point-to-focus policy.");
Vw32_grab_focus_on_raise = Qt;
DEFVAR_LISP ("w32-capslock-is-shiftlock",
&Vw32_capslock_is_shiftlock,
"Apply CapsLock state to non character input keys.\n\
When nil, CapsLock only affects normal character input keys.");
Vw32_capslock_is_shiftlock = Qnil;
DEFVAR_LISP ("w32-recognize-altgr",
&Vw32_recognize_altgr,
"Recognize right-alt and left-ctrl as AltGr.\n\
When nil, the right-alt and left-ctrl key combination is\n\
interpreted normally.");
Vw32_recognize_altgr = Qt;
DEFVAR_BOOL ("w32-enable-unicode-output",
&w32_enable_unicode_output,
"Enable the use of Unicode for text output if non-nil.\n\
Unicode output may prevent some third party applications for displaying\n\
Far-East Languages on Windows 95/98 from working properly.\n\
NT uses Unicode internally anyway, so this flag will probably have no\n\
affect on NT machines.");
w32_enable_unicode_output = 1;
DEFVAR_LISP ("w32-charset-to-codepage-alist",
&Vw32_charset_to_codepage_alist,
"Alist linking character sets to Windows Codepages.");
Vw32_charset_to_codepage_alist = Qnil;
XSETFASTINT (codepage, 936);
store_in_alist (&Vw32_charset_to_codepage_alist,
build_string ("gb2312"), codepage);
XSETFASTINT (codepage, 950);
store_in_alist (&Vw32_charset_to_codepage_alist,
build_string ("big5"), codepage);
XSETFASTINT (codepage, 949);
store_in_alist (&Vw32_charset_to_codepage_alist,
build_string ("ksc5601.1987"), codepage);
XSETFASTINT (codepage, 1361);
store_in_alist (&Vw32_charset_to_codepage_alist,
build_string ("ksc5601.1992"), codepage);
XSETFASTINT (codepage, 932);
store_in_alist (&Vw32_charset_to_codepage_alist,
build_string ("jisx0208-sjis"), codepage);
XSETFASTINT (codepage, 874);
store_in_alist (&Vw32_charset_to_codepage_alist,
build_string ("tis620"), codepage);
XSETFASTINT (codepage, 20866);
store_in_alist (&Vw32_charset_to_codepage_alist,
build_string ("koi8-r"), codepage);
XSETFASTINT (codepage, 1257);
store_in_alist (&Vw32_charset_to_codepage_alist,
build_string ("iso8859-13"), codepage);
XSETFASTINT (codepage, 1254);
store_in_alist (&Vw32_charset_to_codepage_alist,
build_string ("iso8859-9"), codepage);
XSETFASTINT (codepage, 1255);
store_in_alist (&Vw32_charset_to_codepage_alist,
build_string ("iso8859-8"), codepage);
XSETFASTINT (codepage, 28597);
store_in_alist (&Vw32_charset_to_codepage_alist,
build_string ("iso8859-7"), codepage);
XSETFASTINT (codepage, 28596);
store_in_alist (&Vw32_charset_to_codepage_alist,
build_string ("iso8859-6"), codepage);
XSETFASTINT (codepage, 28595);
store_in_alist (&Vw32_charset_to_codepage_alist,
build_string ("iso8859-5"), codepage);
XSETFASTINT (codepage, 28594);
store_in_alist (&Vw32_charset_to_codepage_alist,
build_string ("iso8859-4"), codepage);
XSETFASTINT (codepage, 28593);
store_in_alist (&Vw32_charset_to_codepage_alist,
build_string ("iso8859-3"), codepage);
XSETFASTINT (codepage, 28592);
store_in_alist (&Vw32_charset_to_codepage_alist,
build_string ("iso8859-2"), codepage);
XSETFASTINT (codepage, 1252);
store_in_alist (&Vw32_charset_to_codepage_alist,
build_string ("iso8859-1"), codepage);
}