This source file includes following definitions.
- record_event
- XChangeGC
- XCreateGC
- XGetGCValues
- w32_show_back_buffer
- w32_release_paint_buffer
- w32_get_mouse_wheel_vertical_delta
- w32_set_clip_rectangle
- w32_restore_glyph_string_clip
- w32_get_scale_factor
- w32_draw_underwave
- w32_draw_rectangle
- w32_fill_rect
- w32_clear_window
- w32_set_frame_alpha
- w32_display_pixel_height
- w32_display_pixel_width
- w32_update_begin
- w32_update_window_begin
- w32_draw_vertical_window_border
- w32_draw_window_divider
- w32_update_window_end
- w32_update_end
- w32_frame_up_to_date
- w32_buffer_flipping_unblocked_hook
- w32_flip_buffers_if_dirty
- w32_after_update_window_line
- w32_draw_fringe_bitmap
- w32_define_fringe_bitmap
- w32_destroy_fringe_bitmap
- w32_set_cursor_gc
- w32_set_mouse_face_gc
- w32_set_mode_line_face_gc
- w32_set_glyph_string_gc
- w32_set_glyph_string_clipping
- w32_set_glyph_string_clipping_exactly
- w32_compute_glyph_string_overhangs
- w32_clear_glyph_string_rect
- w32_draw_glyph_string_background
- w32_draw_glyph_string_foreground
- w32_draw_composite_glyph_string_foreground
- w32_draw_glyphless_glyph_string_foreground
- w32_alloc_lighter_color
- w32_query_colors
- w32_query_frame_background_color
- w32_setup_relief_color
- w32_setup_relief_colors
- w32_draw_relief_rect
- w32_draw_box_rect
- w32_draw_glyph_string_box
- w32_image_rotations_p
- transform
- w32_draw_image_foreground
- w32_image_size
- w32_draw_image_relief
- w32_draw_image_foreground_1
- w32_draw_glyph_string_bg_rect
- w32_draw_image_glyph_string
- w32_draw_stretch_glyph_string
- w32_draw_glyph_string
- w32_shift_glyphs_for_insert
- w32_delete_glyphs
- w32_clear_frame
- w32_ring_bell
- w32_ins_del_lines
- w32_scroll_run
- w32_frame_highlight
- w32_frame_unhighlight
- w32_new_focus_frame
- w32_focus_changed
- w32_detect_focus_change
- w32_mouse_leave
- w32_frame_rehighlight
- w32_frame_rehighlight_1
- get_keysym_name
- codepage_for_locale
- parse_button
- w32_construct_mouse_click
- w32_construct_mouse_wheel
- w32_construct_drag_n_drop
- w32_lispy_file_action
- w32_queue_notifications
- w32_note_mouse_movement
- w32_define_cursor
- w32_mouse_position
- w32_handle_tab_bar_click
- w32_handle_tool_bar_click
- w32_window_to_scroll_bar
- w32_set_scroll_bar_thumb
- w32_set_horizontal_scroll_bar_thumb
- my_create_vscrollbar
- my_create_hscrollbar
- my_show_window
- my_set_window_pos
- my_set_focus
- my_set_foreground_window
- my_destroy_window
- my_bring_window_to_top
- w32_scroll_bar_create
- w32_scroll_bar_remove
- w32_set_vertical_scroll_bar
- w32_set_horizontal_scroll_bar
- w32_condemn_scroll_bars
- w32_redeem_scroll_bar
- w32_judge_scroll_bars
- w32_scroll_bar_handle_click
- w32_horizontal_scroll_bar_handle_click
- w32_scroll_bar_report_motion
- w32_horizontal_scroll_bar_report_motion
- w32_scroll_bar_clear
- mouse_or_wdesc_frame
- w32_read_socket
- w32_clip_to_row
- w32_draw_hollow_cursor
- w32_draw_bar_cursor
- w32_define_frame_cursor
- w32_clear_frame_area
- w32_draw_window_cursor
- w32_bitmap_icon
- w32_new_font
- w32_calc_absolute_position
- w32_set_offset
- w32fullscreen_hook
- w32_set_window_size
- frame_set_mouse_pixel_position
- w32_get_focus_frame
- w32_focus_frame
- w32_raise_frame
- w32_lower_frame
- w32_frame_raise_lower
- w32_make_frame_visible
- w32_make_frame_invisible
- w32_make_frame_visible_invisible
- w32_iconify_frame
- w32_free_frame_resources
- w32_destroy_window
- w32_wm_set_size_hint
- w32_check_font
- w32_show_hourglass
- w32_hide_hourglass
- w32_arrow_cursor
- w32_toggle_invisible_pointer
- w32_free_pixmap
- w32_initialize_display_info
- w32_make_rdb
- w32_create_terminal
- w32_delete_terminal
- w32_term_init
- w32_delete_display
- w32_init_main_thread
- w32_initialize
- syms_of_w32term
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <config.h>
21 #include <signal.h>
22 #include <stdio.h>
23 #include "lisp.h"
24 #include "blockinput.h"
25 #include "w32term.h"
26 #include "w32common.h"
27
28 #include <ctype.h>
29 #include <errno.h>
30 #include <sys/stat.h>
31 #ifdef CYGWIN
32 #include <fcntl.h>
33 #endif
34 #include <imm.h>
35 #include <math.h>
36
37 #include "coding.h"
38 #include "frame.h"
39 #include "fontset.h"
40 #include "termhooks.h"
41 #include "termopts.h"
42 #include "termchar.h"
43 #include "buffer.h"
44 #include "window.h"
45 #include "keyboard.h"
46 #include "menu.h"
47
48 #ifdef WINDOWSNT
49 #include "w32.h"
50 #endif
51
52 #ifndef WINDOWSNT
53 #include <io.h>
54 #endif
55
56 #include <shellapi.h>
57
58 #include "font.h"
59 #include "w32font.h"
60
61 #if 0
62 #include "bitmaps/gray.xbm"
63 #endif
64
65
66
67 static int max_fringe_bmp = 0;
68 static HBITMAP *fringe_bmp = 0;
69
70
71
72 static int last_mousemove_x = 0;
73 static int last_mousemove_y = 0;
74
75
76 #ifndef GET_WHEEL_DELTA_WPARAM
77 #define GET_WHEEL_DELTA_WPARAM(wparam) ((short)HIWORD (wparam))
78 #endif
79
80
81
82
83 static int any_help_event_p;
84
85 extern unsigned int msh_mousewheel;
86
87 extern int w32_codepage_for_font (char *fontname);
88 extern HCURSOR w32_load_cursor (LPCTSTR name);
89
90
91
92 struct w32_display_info one_w32_display_info;
93 struct w32_display_info *x_display_list;
94
95 #if _WIN32_WINNT < 0x0500 && !defined(MINGW_W64)
96
97
98
99
100 typedef struct tagWCRANGE
101 {
102 WCHAR wcLow;
103 USHORT cGlyphs;
104 } WCRANGE;
105
106 typedef struct tagGLYPHSET
107 {
108 DWORD cbThis;
109 DWORD flAccel;
110 DWORD cGlyphsSupported;
111 DWORD cRanges;
112 WCRANGE ranges[1];
113 } GLYPHSET;
114
115 #endif
116
117
118 BOOL (WINAPI *pfnSetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
119
120
121 BOOL (WINAPI *pfnPlgBlt) (HDC, const POINT *, HDC, int, int, int, int, HBITMAP, int, int);
122
123
124 #ifndef LWA_ALPHA
125 #define LWA_ALPHA 0x02
126 #endif
127
128
129 #ifndef WS_EX_LAYERED
130 #define WS_EX_LAYERED 0x80000
131 #endif
132
133
134
135 #ifndef SM_CXVIRTUALSCREEN
136 #define SM_CXVIRTUALSCREEN 78
137 #endif
138 #ifndef SM_CYVIRTUALSCREEN
139 #define SM_CYVIRTUALSCREEN 79
140 #endif
141
142
143 HWND w32_system_caret_hwnd;
144 int w32_system_caret_height;
145 int w32_system_caret_x;
146 int w32_system_caret_y;
147 struct window *w32_system_caret_window;
148 int w32_system_caret_hdr_height;
149 int w32_system_caret_mode_height;
150 DWORD dwWindowsThreadId = 0;
151 HANDLE hWindowsThread = NULL;
152 DWORD dwMainThreadId = 0;
153 HANDLE hMainThread = NULL;
154
155 int vertical_scroll_bar_min_handle;
156 int horizontal_scroll_bar_min_handle;
157 int vertical_scroll_bar_top_border;
158 int vertical_scroll_bar_bottom_border;
159 int horizontal_scroll_bar_left_border;
160 int horizontal_scroll_bar_right_border;
161
162 int last_scroll_bar_drag_pos;
163
164
165 int w32_keyboard_codepage;
166
167
168
169 static UINT w32_wheel_scroll_lines;
170
171 #ifdef CYGWIN
172 int w32_message_fd = -1;
173 #endif
174
175 static Lisp_Object w32_handle_tab_bar_click (struct frame *,
176 struct input_event *);
177 static void w32_handle_tool_bar_click (struct frame *,
178 struct input_event *);
179 static void w32_define_cursor (Window, Emacs_Cursor);
180
181 static void w32_scroll_bar_clear (struct frame *);
182 static void w32_raise_frame (struct frame *);
183 static void w32_lower_frame (struct frame *);
184 static void w32_initialize (void);
185 static void w32_update_end (struct frame *);
186 static void w32_frame_up_to_date (struct frame *);
187 static void w32_clear_frame (struct frame *);
188 static void w32_frame_highlight (struct frame *);
189 static void w32_frame_unhighlight (struct frame *);
190 static void w32_new_focus_frame (struct w32_display_info *,
191 struct frame *);
192 static void w32_focus_changed (int, int, struct w32_display_info *,
193 struct frame *, struct input_event *);
194 static void w32_detect_focus_change (struct w32_display_info *,
195 W32Msg *, struct input_event *);
196 static void w32_frame_rehighlight (struct frame *);
197 static void w32_frame_rehighlight_1 (struct w32_display_info *);
198 static void w32_draw_hollow_cursor (struct window *, struct glyph_row *);
199 static void w32_draw_bar_cursor (struct window *, struct glyph_row *, int,
200 enum text_cursor_kinds);
201 static void w32_clip_to_row (struct window *, struct glyph_row *,
202 enum glyph_row_area, HDC);
203 static BOOL my_show_window (struct frame *, HWND, int);
204 static void my_set_window_pos (HWND, HWND, int, int, int, int, UINT);
205 #if 0
206 static void my_set_focus (struct frame *, HWND);
207 #endif
208 static void my_set_foreground_window (HWND);
209 static void my_destroy_window (struct frame *, HWND);
210 static void w32fullscreen_hook (struct frame *);
211
212 #ifdef GLYPH_DEBUG
213 static void w32_check_font (struct frame *, struct font *);
214 #endif
215
216
217
218
219
220
221 #if 0
222
223
224
225
226 struct record
227 {
228 char *locus;
229 int type;
230 };
231
232 struct record event_record[100];
233
234 int event_record_index;
235
236 record_event (char *locus, int type)
237 {
238 if (event_record_index == sizeof (event_record) / sizeof (struct record))
239 event_record_index = 0;
240
241 event_record[event_record_index].locus = locus;
242 event_record[event_record_index].type = type;
243 event_record_index++;
244 }
245
246 #endif
247
248
249 static void
250 XChangeGC (void *ignore, Emacs_GC *gc, unsigned long mask,
251 Emacs_GC *egc)
252 {
253 if (mask & GCForeground)
254 gc->foreground = egc->foreground;
255 if (mask & GCBackground)
256 gc->background = egc->background;
257 }
258
259 Emacs_GC *
260 XCreateGC (void *ignore, HWND wignore, unsigned long mask, Emacs_GC *egc)
261 {
262 Emacs_GC *gc = xzalloc (sizeof (*gc));
263
264 XChangeGC (ignore, gc, mask, egc);
265
266 return gc;
267 }
268
269 #if 0
270 static void
271 XGetGCValues (void *ignore, XGCValues *gc,
272 unsigned long mask, XGCValues *xgcv)
273 {
274 XChangeGC (ignore, xgcv, mask, gc);
275 }
276 #endif
277
278 static void
279 w32_show_back_buffer (struct frame *f)
280 {
281 struct w32_output *output;
282 HDC raw_dc;
283
284 output = FRAME_OUTPUT_DATA (f);
285
286 if (!output->want_paint_buffer || w32_disable_double_buffering)
287 return;
288
289 enter_crit ();
290
291 if (output->paint_buffer)
292 {
293 raw_dc = GetDC (output->window_desc);
294
295 if (!raw_dc)
296 emacs_abort ();
297
298 BitBlt (raw_dc, 0, 0, FRAME_PIXEL_WIDTH (f),
299 FRAME_PIXEL_HEIGHT (f),
300 output->paint_dc, 0, 0, SRCCOPY);
301 ReleaseDC (output->window_desc, raw_dc);
302
303 output->paint_buffer_dirty = 0;
304 }
305
306 leave_crit ();
307 }
308
309 void
310 w32_release_paint_buffer (struct frame *f)
311 {
312
313
314
315 enter_crit ();
316 if (FRAME_OUTPUT_DATA (f)->paint_buffer)
317 {
318 deselect_palette (f, FRAME_OUTPUT_DATA (f)->paint_buffer_handle);
319
320 SelectObject (FRAME_OUTPUT_DATA (f)->paint_dc,
321 FRAME_OUTPUT_DATA (f)->paint_dc_object);
322 ReleaseDC (FRAME_OUTPUT_DATA (f)->window_desc,
323 FRAME_OUTPUT_DATA (f)->paint_buffer_handle);
324 DeleteDC (FRAME_OUTPUT_DATA (f)->paint_dc);
325 DeleteObject (FRAME_OUTPUT_DATA (f)->paint_buffer);
326
327 FRAME_OUTPUT_DATA (f)->paint_buffer = NULL;
328 FRAME_OUTPUT_DATA (f)->paint_dc = NULL;
329 FRAME_OUTPUT_DATA (f)->paint_buffer_handle = NULL;
330 }
331 leave_crit ();
332 }
333
334 static void
335 w32_get_mouse_wheel_vertical_delta (void)
336 {
337 if (os_subtype != OS_SUBTYPE_NT)
338 return;
339
340 UINT scroll_lines;
341 BOOL ret = SystemParametersInfo (SPI_GETWHEELSCROLLLINES, 0,
342 &scroll_lines, 0);
343 if (ret)
344 w32_wheel_scroll_lines = scroll_lines;
345 }
346
347 static void
348 w32_set_clip_rectangle (HDC hdc, RECT *rect)
349 {
350 if (rect)
351 {
352 HRGN clip_region = CreateRectRgnIndirect (rect);
353 SelectClipRgn (hdc, clip_region);
354 DeleteObject (clip_region);
355 }
356 else
357 SelectClipRgn (hdc, NULL);
358 }
359
360
361 static void
362 w32_restore_glyph_string_clip (struct glyph_string *s)
363 {
364 RECT *r = s->clip;
365 int n = s->num_clips;
366
367 if (n == 1)
368 w32_set_clip_rectangle (s->hdc, r);
369 else if (n > 1)
370 {
371 HRGN clip1 = CreateRectRgnIndirect (r);
372 HRGN clip2 = CreateRectRgnIndirect (r + 1);
373 if (CombineRgn (clip1, clip1, clip2, RGN_OR) != ERROR)
374 SelectClipRgn (s->hdc, clip1);
375 DeleteObject (clip1);
376 DeleteObject (clip2);
377 }
378 }
379
380 static void
381 w32_get_scale_factor(struct w32_display_info *dpyinfo, int *scale_x, int *scale_y)
382 {
383 const int base_res = 96;
384
385 *scale_x = *scale_y = 1;
386
387 if (dpyinfo)
388 {
389 if (dpyinfo->resx > base_res)
390 *scale_x = floor (dpyinfo->resx / base_res);
391 if (dpyinfo->resy > base_res)
392 *scale_y = floor (dpyinfo->resy / base_res);
393 }
394 }
395
396
397
398
399
400
401
402
403
404
405
406
407 static void
408 w32_draw_underwave (struct glyph_string *s, COLORREF color)
409 {
410 struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f);
411
412 int scale_x, scale_y;
413 w32_get_scale_factor (dpyinfo, &scale_x, &scale_y);
414
415 int wave_height = 3 * scale_y, wave_length = 2 * scale_x, thickness = scale_y;
416 int dx, dy, x0, y0, width, x1, y1, x2, y2, odd, xmax;
417 Emacs_Rectangle wave_clip, string_clip, final_clip;
418 RECT w32_final_clip, w32_string_clip;
419 HPEN hp, oldhp;
420
421 dx = wave_length;
422 dy = wave_height - 1;
423 x0 = s->x;
424 y0 = s->ybase + wave_height / 2 - scale_y;
425 width = s->width;
426 xmax = x0 + width;
427
428
429
430 wave_clip.x = x0;
431 wave_clip.y = y0;
432 wave_clip.width = width;
433 wave_clip.height = wave_height;
434
435 get_glyph_string_clip_rect (s, &w32_string_clip);
436 CONVERT_TO_EMACS_RECT (string_clip, w32_string_clip);
437
438 if (!gui_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
439 return;
440
441 hp = CreatePen (PS_SOLID, thickness, color);
442 oldhp = SelectObject (s->hdc, hp);
443 CONVERT_FROM_EMACS_RECT (final_clip, w32_final_clip);
444 w32_set_clip_rectangle (s->hdc, &w32_final_clip);
445
446
447
448 x1 = x0 - (x0 % dx);
449 x2 = x1 + dx;
450 odd = (x1/dx) % 2;
451 y1 = y2 = y0;
452
453 if (odd)
454 y1 += dy;
455 else
456 y2 += dy;
457
458 MoveToEx (s->hdc, x1, y1, NULL);
459
460 while (x1 <= xmax)
461 {
462 LineTo (s->hdc, x2, y2);
463 x1 = x2, y1 = y2;
464 x2 += dx, y2 = y0 + odd*dy;
465 odd = !odd;
466 }
467
468
469 w32_restore_glyph_string_clip (s);
470 SelectObject (s->hdc, oldhp);
471 DeleteObject (hp);
472 }
473
474
475 static void
476 w32_draw_rectangle (HDC hdc, Emacs_GC *gc, int x, int y,
477 int width, int height)
478 {
479 HBRUSH hb, oldhb;
480 HPEN hp, oldhp;
481
482 hb = CreateSolidBrush (gc->background);
483 hp = CreatePen (PS_SOLID, 0, gc->foreground);
484 oldhb = SelectObject (hdc, hb);
485 oldhp = SelectObject (hdc, hp);
486
487
488
489
490
491
492
493 Rectangle (hdc, x, y, x + width + 1, y + height + 1);
494
495 SelectObject (hdc, oldhb);
496 SelectObject (hdc, oldhp);
497 DeleteObject (hb);
498 DeleteObject (hp);
499 }
500
501
502 void
503 w32_fill_rect (struct frame *f, HDC hdc, COLORREF pix, RECT *lprect)
504 {
505 HBRUSH hb;
506
507 hb = CreateSolidBrush (pix);
508 FillRect (hdc, lprect, hb);
509 DeleteObject (hb);
510 }
511
512 void
513 w32_clear_window (struct frame *f)
514 {
515 RECT rect;
516 HDC hdc = get_frame_dc (f);
517
518
519
520
521 if (hdc)
522 {
523 GetClientRect (FRAME_W32_WINDOW (f), &rect);
524 w32_clear_rect (f, hdc, &rect);
525 }
526
527 release_frame_dc (f, hdc);
528 }
529
530 #define OPAQUE_FRAME 255
531
532 static void
533 w32_set_frame_alpha (struct frame *f)
534 {
535 struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
536 double alpha = 1.0;
537 double alpha_min = 1.0;
538 BYTE opac;
539 LONG ex_style;
540 HWND window = FRAME_W32_WINDOW (f);
541
542
543 if (!pfnSetLayeredWindowAttributes)
544 return;
545
546 if (dpyinfo->w32_focus_frame == f)
547 alpha = f->alpha[0];
548 else
549 alpha = f->alpha[1];
550
551 if (FLOATP (Vframe_alpha_lower_limit))
552 alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
553 else if (FIXNUMP (Vframe_alpha_lower_limit))
554 alpha_min = (XFIXNUM (Vframe_alpha_lower_limit)) / 100.0;
555
556 if (alpha < 0.0)
557 return;
558 else if (alpha > 1.0)
559 alpha = 1.0;
560 else if (alpha < alpha_min && alpha_min <= 1.0)
561 alpha = alpha_min;
562
563 opac = alpha * OPAQUE_FRAME;
564
565 ex_style = GetWindowLong (window, GWL_EXSTYLE);
566
567 if (opac == OPAQUE_FRAME)
568 ex_style &= ~WS_EX_LAYERED;
569 else
570 ex_style |= WS_EX_LAYERED;
571
572 SetWindowLong (window, GWL_EXSTYLE, ex_style);
573
574 if (opac != OPAQUE_FRAME)
575 pfnSetLayeredWindowAttributes (window, 0, opac, LWA_ALPHA);
576 }
577
578 int
579 w32_display_pixel_height (struct w32_display_info *dpyinfo)
580 {
581 int pixels = GetSystemMetrics (SM_CYVIRTUALSCREEN);
582
583 if (pixels == 0)
584
585 pixels = GetSystemMetrics (SM_CYSCREEN);
586
587 return pixels;
588 }
589
590 int
591 w32_display_pixel_width (struct w32_display_info *dpyinfo)
592 {
593 int pixels = GetSystemMetrics (SM_CXVIRTUALSCREEN);
594
595 if (pixels == 0)
596
597 pixels = GetSystemMetrics (SM_CXSCREEN);
598
599 return pixels;
600 }
601
602
603
604
605
606
607
608
609
610
611
612 static void
613 w32_update_begin (struct frame *f)
614 {
615 struct w32_display_info *display_info = FRAME_DISPLAY_INFO (f);
616
617 if (! FRAME_W32_P (f))
618 return;
619
620
621
622 if (display_info->regen_palette)
623 {
624 w32_regenerate_palette (f);
625 display_info->regen_palette = FALSE;
626 }
627 }
628
629
630
631
632 static void
633 w32_update_window_begin (struct window *w)
634 {
635
636 if (w32_use_visible_system_caret && w32_system_caret_hwnd
637 && w == w32_system_caret_window)
638 {
639 SendMessageTimeout (w32_system_caret_hwnd, WM_EMACS_HIDE_CARET, 0, 0,
640 0, 6000, NULL);
641 }
642 }
643
644
645
646 static void
647 w32_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
648 {
649 struct frame *f = XFRAME (WINDOW_FRAME (w));
650 RECT r;
651 HDC hdc;
652 struct face *face;
653
654 r.left = x;
655 r.right = x + 1;
656 r.top = y0;
657 r.bottom = y1;
658
659 hdc = get_frame_dc (f);
660 face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
661 if (face)
662 w32_fill_rect (f, hdc, face->foreground, &r);
663 else
664 w32_fill_rect (f, hdc, FRAME_FOREGROUND_PIXEL (f), &r);
665
666 release_frame_dc (f, hdc);
667 }
668
669
670
671
672 static void
673 w32_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
674 {
675 struct frame *f = XFRAME (WINDOW_FRAME (w));
676 HDC hdc = get_frame_dc (f);
677 struct face *face = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FACE_ID);
678 struct face *face_first
679 = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
680 struct face *face_last
681 = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
682 unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
683 unsigned long color_first = (face_first
684 ? face_first->foreground
685 : FRAME_FOREGROUND_PIXEL (f));
686 unsigned long color_last = (face_last
687 ? face_last->foreground
688 : FRAME_FOREGROUND_PIXEL (f));
689
690 if ((y1 - y0 > x1 - x0) && (x1 - x0 >= 3))
691
692
693 {
694 w32_fill_area_abs (f, hdc, color_first, x0, y0, x0 + 1, y1);
695 w32_fill_area_abs (f, hdc, color, x0 + 1, y0, x1 - 1, y1);
696 w32_fill_area_abs (f, hdc, color_last, x1 - 1, y0, x1, y1);
697 }
698 else if ((x1 - x0 > y1 - y0) && (y1 - y0 >= 3))
699
700
701 {
702 w32_fill_area_abs (f, hdc, color_first, x0, y0, x1, y0 + 1);
703 w32_fill_area_abs (f, hdc, color, x0, y0 + 1, x1, y1 - 1);
704 w32_fill_area_abs (f, hdc, color_last, x0, y1 - 1, x1, y1);
705 }
706 else
707
708
709 w32_fill_area_abs (f, hdc, color, x0, y0, x1, y1);
710
711 release_frame_dc (f, hdc);
712 }
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727 static void
728 w32_update_window_end (struct window *w, bool cursor_on_p,
729 bool mouse_face_overwritten_p)
730 {
731
732
733
734 if (w32_use_visible_system_caret && w32_system_caret_hwnd
735 && w == w32_system_caret_window)
736 {
737 SendMessageTimeout (w32_system_caret_hwnd, WM_EMACS_SHOW_CARET, 0, 0,
738 0, 6000, NULL);
739 }
740 }
741
742
743
744
745
746 static void
747 w32_update_end (struct frame *f)
748 {
749 if (! FRAME_W32_P (f))
750 return;
751
752
753 MOUSE_HL_INFO (f)->mouse_face_defer = false;
754 }
755
756
757
758
759
760 static void
761 w32_frame_up_to_date (struct frame *f)
762 {
763 FRAME_MOUSE_UPDATE (f);
764
765 if (!buffer_flipping_blocked_p ()
766 && FRAME_OUTPUT_DATA (f)->paint_buffer_dirty)
767 w32_show_back_buffer (f);
768 }
769
770 static void
771 w32_buffer_flipping_unblocked_hook (struct frame *f)
772 {
773 if (FRAME_OUTPUT_DATA (f)->paint_buffer_dirty)
774 w32_show_back_buffer (f);
775 }
776
777
778
779
780
781 void
782 w32_flip_buffers_if_dirty (struct frame *f)
783 {
784 if (FRAME_OUTPUT_DATA (f)->paint_buffer
785 && FRAME_OUTPUT_DATA (f)->paint_buffer_dirty
786 && !f->garbaged && !buffer_flipping_blocked_p ())
787 w32_show_back_buffer (f);
788 }
789
790
791
792
793
794
795
796 static void
797 w32_after_update_window_line (struct window *w, struct glyph_row *desired_row)
798 {
799 struct frame *f;
800 int width, height;
801
802 eassert (w);
803
804 if (!desired_row->mode_line_p && !w->pseudo_window_p)
805 desired_row->redraw_fringe_bitmaps_p = true;
806
807
808
809
810
811
812
813 if (windows_or_buffers_changed
814 && desired_row->full_width_p
815 && (f = XFRAME (w->frame),
816 width = FRAME_INTERNAL_BORDER_WIDTH (f),
817 width != 0)
818 && (height = desired_row->visible_height,
819 height > 0))
820 {
821 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
822 int face_id =
823 !NILP (Vface_remapping_alist)
824 ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
825 : INTERNAL_BORDER_FACE_ID;
826 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
827
828 block_input ();
829
830 HDC hdc = get_frame_dc (f);
831 if (face)
832 {
833
834 unsigned long color = face->background;
835
836 w32_fill_area (f, hdc, color, 0, y, width, height);
837 w32_fill_area (f, hdc, color, FRAME_PIXEL_WIDTH (f) - width,
838 y, width, height);
839 }
840 else
841 {
842 w32_clear_area (f, hdc, 0, y, width, height);
843 w32_clear_area (f, hdc, FRAME_PIXEL_WIDTH (f) - width,
844 y, width, height);
845 }
846 release_frame_dc (f, hdc);
847
848 unblock_input ();
849 }
850 }
851
852
853
854
855
856
857
858 static void
859 w32_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
860 struct draw_fringe_bitmap_params *p)
861 {
862 struct frame *f = XFRAME (WINDOW_FRAME (w));
863 HDC hdc;
864 struct face *face = p->face;
865
866 hdc = get_frame_dc (f);
867
868
869 w32_clip_to_row (w, row, ANY_AREA, hdc);
870
871 if (p->bx >= 0 && !p->overlay_p)
872 w32_fill_area (f, hdc, face->background,
873 p->bx, p->by, p->nx, p->ny);
874
875 if (p->which
876 && p->which < max_fringe_bmp
877 && p->which < max_used_fringe_bitmap)
878 {
879 HBITMAP pixmap = fringe_bmp[p->which];
880 HDC compat_hdc;
881 HANDLE horig_obj;
882
883 if (!fringe_bmp[p->which])
884 {
885
886
887
888
889
890
891 gui_define_fringe_bitmap (f, p->which);
892 }
893
894 compat_hdc = CreateCompatibleDC (hdc);
895
896 SaveDC (hdc);
897
898 horig_obj = SelectObject (compat_hdc, pixmap);
899
900
901 if (p->overlay_p)
902 {
903 HBRUSH h_brush, h_orig_brush;
904
905 SetTextColor (hdc, BLACK_PIX_DEFAULT (f));
906 SetBkColor (hdc, WHITE_PIX_DEFAULT (f));
907 h_brush = CreateSolidBrush (face->foreground);
908 h_orig_brush = SelectObject (hdc, h_brush);
909
910 BitBlt (hdc, p->x, p->y, p->wd, p->h,
911 compat_hdc, 0, p->dh,
912 DSTINVERT);
913 BitBlt (hdc, p->x, p->y, p->wd, p->h,
914 compat_hdc, 0, p->dh,
915 0x2E064A);
916 BitBlt (hdc, p->x, p->y, p->wd, p->h,
917 compat_hdc, 0, p->dh,
918 DSTINVERT);
919
920 SelectObject (hdc, h_orig_brush);
921 DeleteObject (h_brush);
922 }
923 else
924 {
925 SetTextColor (hdc, face->background);
926 SetBkColor (hdc, (p->cursor_p
927 ? f->output_data.w32->cursor_pixel
928 : face->foreground));
929
930 BitBlt (hdc, p->x, p->y, p->wd, p->h,
931 compat_hdc, 0, p->dh,
932 SRCCOPY);
933 }
934
935 SelectObject (compat_hdc, horig_obj);
936 DeleteDC (compat_hdc);
937 RestoreDC (hdc, -1);
938 }
939
940 w32_set_clip_rectangle (hdc, NULL);
941
942 release_frame_dc (f, hdc);
943 }
944
945 static void
946 w32_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd)
947 {
948 if (which >= max_fringe_bmp)
949 {
950 int i = max_fringe_bmp;
951 max_fringe_bmp = which + 20;
952 fringe_bmp = (HBITMAP *) xrealloc (fringe_bmp, max_fringe_bmp * sizeof (HBITMAP));
953 while (i < max_fringe_bmp)
954 fringe_bmp[i++] = 0;
955 }
956
957 fringe_bmp[which] = CreateBitmap (wd, h, 1, 1, bits);
958 }
959
960 static void
961 w32_destroy_fringe_bitmap (int which)
962 {
963 if (which >= max_fringe_bmp)
964 return;
965
966 if (fringe_bmp[which])
967 DeleteObject (fringe_bmp[which]);
968 fringe_bmp[which] = 0;
969 }
970
971
972
973
974
975
976
977 static void w32_set_glyph_string_clipping (struct glyph_string *);
978 static void w32_set_glyph_string_gc (struct glyph_string *);
979 static void w32_draw_glyph_string_background (struct glyph_string *,
980 bool);
981 static void w32_draw_glyph_string_foreground (struct glyph_string *);
982 static void w32_draw_composite_glyph_string_foreground (struct glyph_string *);
983 static void w32_draw_glyph_string_box (struct glyph_string *);
984 static void w32_draw_glyph_string (struct glyph_string *);
985 static void w32_set_cursor_gc (struct glyph_string *);
986 static void w32_set_mode_line_face_gc (struct glyph_string *);
987 static void w32_set_mouse_face_gc (struct glyph_string *);
988 static int w32_alloc_lighter_color (struct frame *, COLORREF *, double, int);
989 static void w32_setup_relief_color (struct frame *, struct relief *,
990 double, int, COLORREF);
991 static void w32_setup_relief_colors (struct glyph_string *);
992 static void w32_draw_image_glyph_string (struct glyph_string *);
993 static void w32_draw_image_relief (struct glyph_string *);
994 static void w32_draw_image_foreground (struct glyph_string *);
995 static void w32_draw_image_foreground_1 (struct glyph_string *, HBITMAP);
996 static void w32_clear_glyph_string_rect (struct glyph_string *, int,
997 int, int, int);
998 static void w32_draw_relief_rect (struct frame *, int, int, int, int,
999 int, int, int, int, int, int, int,
1000 RECT *);
1001 static void w32_draw_box_rect (struct glyph_string *, int, int, int, int,
1002 int, int, bool, bool, RECT *);
1003
1004
1005
1006
1007
1008 static void
1009 w32_set_cursor_gc (struct glyph_string *s)
1010 {
1011 if (s->font == FRAME_FONT (s->f)
1012 && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
1013 && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
1014
1015
1016
1017 && s->f->output_data.w32->cursor_gc->foreground == s->face->background
1018 && !s->cmp)
1019 s->gc = s->f->output_data.w32->cursor_gc;
1020 else
1021 {
1022
1023 Emacs_GC egc;
1024 unsigned long mask;
1025
1026 egc.background = s->f->output_data.w32->cursor_pixel;
1027 egc.foreground = s->face->background;
1028
1029
1030 if (egc.foreground == egc.background)
1031 egc.foreground = s->face->foreground;
1032 if (egc.foreground == egc.background)
1033 egc.foreground = s->f->output_data.w32->cursor_foreground_pixel;
1034 if (egc.foreground == egc.background)
1035 egc.foreground = s->face->foreground;
1036
1037
1038 if (egc.background == s->face->background
1039 && egc.foreground == s->face->foreground)
1040 {
1041 egc.background = s->face->foreground;
1042 egc.foreground = s->face->background;
1043 }
1044
1045 IF_DEBUG (w32_check_font (s->f, s->font));
1046 mask = GCForeground | GCBackground;
1047
1048 if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1049 XChangeGC (NULL, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1050 mask, &egc);
1051 else
1052 FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
1053 = XCreateGC (NULL, FRAME_W32_WINDOW (s->f), mask, &egc);
1054
1055 s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1056 }
1057 }
1058
1059
1060
1061
1062 static void
1063 w32_set_mouse_face_gc (struct glyph_string *s)
1064 {
1065
1066 if (s->font == s->face->font)
1067 s->gc = s->face->gc;
1068 else
1069 {
1070
1071
1072 Emacs_GC egc;
1073 unsigned long mask;
1074
1075 egc.background = s->face->background;
1076 egc.foreground = s->face->foreground;
1077 IF_DEBUG (w32_check_font (s->f, s->font));
1078 mask = GCForeground | GCBackground;
1079
1080 if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1081 XChangeGC (NULL, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1082 mask, &egc);
1083 else
1084 FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
1085 = XCreateGC (NULL, FRAME_W32_WINDOW (s->f), mask, &egc);
1086
1087 s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1088 }
1089
1090 eassert (s->gc != 0);
1091 }
1092
1093
1094
1095
1096
1097
1098 static inline void
1099 w32_set_mode_line_face_gc (struct glyph_string *s)
1100 {
1101 s->gc = s->face->gc;
1102 }
1103
1104
1105
1106
1107
1108
1109 static inline void
1110 w32_set_glyph_string_gc (struct glyph_string *s)
1111 {
1112 prepare_face_for_display (s->f, s->face);
1113
1114 if (s->hl == DRAW_NORMAL_TEXT)
1115 {
1116 s->gc = s->face->gc;
1117 s->stippled_p = s->face->stipple != 0;
1118 }
1119 else if (s->hl == DRAW_INVERSE_VIDEO)
1120 {
1121 w32_set_mode_line_face_gc (s);
1122 s->stippled_p = s->face->stipple != 0;
1123 }
1124 else if (s->hl == DRAW_CURSOR)
1125 {
1126 w32_set_cursor_gc (s);
1127 s->stippled_p = false;
1128 }
1129 else if (s->hl == DRAW_MOUSE_FACE)
1130 {
1131 w32_set_mouse_face_gc (s);
1132 s->stippled_p = s->face->stipple != 0;
1133 }
1134 else if (s->hl == DRAW_IMAGE_RAISED
1135 || s->hl == DRAW_IMAGE_SUNKEN)
1136 {
1137 s->gc = s->face->gc;
1138 s->stippled_p = s->face->stipple != 0;
1139 }
1140 else
1141 emacs_abort ();
1142
1143
1144 eassert (s->gc != 0);
1145 }
1146
1147
1148
1149
1150
1151 static inline void
1152 w32_set_glyph_string_clipping (struct glyph_string *s)
1153 {
1154 RECT *r = s->clip;
1155 int n = get_glyph_string_clip_rects (s, r, 2);
1156
1157 if (n == 1)
1158 w32_set_clip_rectangle (s->hdc, r);
1159 else if (n > 1)
1160 {
1161 HRGN clip1 = CreateRectRgnIndirect (r);
1162 HRGN clip2 = CreateRectRgnIndirect (r + 1);
1163 if (CombineRgn (clip1, clip1, clip2, RGN_OR) != ERROR)
1164 SelectClipRgn (s->hdc, clip1);
1165 DeleteObject (clip1);
1166 DeleteObject (clip2);
1167 }
1168 s->num_clips = n;
1169 }
1170
1171
1172
1173
1174
1175 static void
1176 w32_set_glyph_string_clipping_exactly (struct glyph_string *src,
1177 struct glyph_string *dst)
1178 {
1179 RECT r;
1180
1181 r.left = src->x;
1182 r.right = r.left + src->width;
1183 r.top = src->y;
1184 r.bottom = r.top + src->height;
1185 dst->clip[0] = r;
1186 dst->num_clips = 1;
1187 w32_set_clip_rectangle (dst->hdc, &r);
1188 }
1189
1190
1191
1192
1193 static void
1194 w32_compute_glyph_string_overhangs (struct glyph_string *s)
1195 {
1196 if (s->cmp == NULL)
1197 {
1198 struct font_metrics metrics;
1199 if (s->first_glyph->type == CHAR_GLYPH && !s->font_not_found_p)
1200 {
1201 struct font *font = s->font;
1202 font->driver->text_extents (font, s->char2b, s->nchars, &metrics);
1203 s->right_overhang = (metrics.rbearing > metrics.width
1204 ? metrics.rbearing - metrics.width : 0);
1205 s->left_overhang = metrics.lbearing < 0 ? -metrics.lbearing : 0;
1206 }
1207 else if (s->first_glyph->type == COMPOSITE_GLYPH)
1208 {
1209 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1210
1211 composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics);
1212 s->right_overhang = (metrics.rbearing > metrics.width
1213 ? metrics.rbearing - metrics.width : 0);
1214 s->left_overhang = metrics.lbearing < 0 ? -metrics.lbearing : 0;
1215 }
1216 }
1217 else
1218 {
1219 s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
1220 s->left_overhang = -s->cmp->lbearing;
1221 }
1222 }
1223
1224
1225
1226 static inline void
1227 w32_clear_glyph_string_rect (struct glyph_string *s,
1228 int x, int y, int w, int h)
1229 {
1230 int real_x = x;
1231 int real_y = y;
1232 int real_w = w;
1233 int real_h = h;
1234 #if 0
1235
1236 if (s->gc->clip_mask == Rect)
1237 {
1238 real_x = max (real_x, s->gc->clip_rectangle.left);
1239 real_y = max (real_y, s->gc->clip_rectangle.top);
1240 real_w = min (real_w, s->gc->clip_rectangle.right
1241 - s->gc->clip_rectangle.left);
1242 real_h = min (real_h, s->gc->clip_rectangle.bottom
1243 - s->gc->clip_rectangle.top);
1244 }
1245 #endif
1246 w32_fill_area (s->f, s->hdc, s->gc->background, real_x, real_y,
1247 real_w, real_h);
1248 }
1249
1250
1251
1252
1253
1254
1255
1256
1257 static void
1258 w32_draw_glyph_string_background (struct glyph_string *s, bool force_p)
1259 {
1260
1261
1262 if (!s->background_filled_p)
1263 {
1264 int box_line_width = max (s->face->box_horizontal_line_width, 0);
1265
1266 #if 0
1267 if (s->stippled_p)
1268 {
1269
1270 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
1271 XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), s->gc, s->x,
1272 s->y + box_line_width,
1273 s->background_width,
1274 s->height - 2 * box_line_width);
1275 XSetFillStyle (s->display, s->gc, FillSolid);
1276 s->background_filled_p = true;
1277 }
1278 else
1279 #endif
1280 if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
1281
1282
1283
1284
1285 || FONT_TOO_HIGH (s->font)
1286 || s->font_not_found_p
1287 || s->extends_to_end_of_line_p
1288 || force_p)
1289 {
1290 w32_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
1291 s->background_width,
1292 s->height - 2 * box_line_width);
1293 s->background_filled_p = true;
1294 }
1295 }
1296 }
1297
1298
1299
1300
1301 static void
1302 w32_draw_glyph_string_foreground (struct glyph_string *s)
1303 {
1304 int i, x;
1305
1306
1307
1308 if (s->face->box != FACE_NO_BOX
1309 && s->first_glyph->left_box_line_p)
1310 x = s->x + max (s->face->box_vertical_line_width, 0);
1311 else
1312 x = s->x;
1313
1314 SetTextColor (s->hdc, s->gc->foreground);
1315 SetBkColor (s->hdc, s->gc->background);
1316 SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
1317
1318
1319
1320 if (s->font_not_found_p)
1321 {
1322 for (i = 0; i < s->nchars; ++i)
1323 {
1324 struct glyph *g = s->first_glyph + i;
1325
1326 w32_draw_rectangle (s->hdc, s->gc, x, s->y, g->pixel_width - 1,
1327 s->height - 1);
1328 x += g->pixel_width;
1329 }
1330 }
1331 else
1332 {
1333 struct font *font = s->font;
1334 int boff = font->baseline_offset;
1335 int y;
1336 HFONT old_font;
1337
1338 old_font = SelectObject (s->hdc, FONT_HANDLE (font));
1339
1340 if (font->vertical_centering)
1341 boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
1342
1343 y = s->ybase - boff;
1344 if (s->for_overlaps
1345 || (s->background_filled_p && s->hl != DRAW_CURSOR))
1346 font->driver->draw (s, 0, s->nchars, x, y, false);
1347 else
1348 font->driver->draw (s, 0, s->nchars, x, y, true);
1349 if (s->face->overstrike)
1350 font->driver->draw (s, 0, s->nchars, x + 1, y, false);
1351
1352 SelectObject (s->hdc, old_font);
1353 }
1354 }
1355
1356
1357
1358 static void
1359 w32_draw_composite_glyph_string_foreground (struct glyph_string *s)
1360 {
1361 int i, j, x;
1362 struct font *font = s->font;
1363
1364
1365
1366 if (s->face && s->face->box != FACE_NO_BOX
1367 && s->first_glyph->left_box_line_p)
1368 x = s->x + max (s->face->box_vertical_line_width, 0);
1369 else
1370 x = s->x;
1371
1372
1373
1374
1375
1376
1377 SetTextColor (s->hdc, s->gc->foreground);
1378 SetBkColor (s->hdc, s->gc->background);
1379 SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
1380
1381
1382
1383 if (s->font_not_found_p)
1384 {
1385 if (s->cmp_from == 0)
1386 w32_draw_rectangle (s->hdc, s->gc, x, s->y, s->width - 1,
1387 s->height - 1);
1388 }
1389 else if (! s->first_glyph->u.cmp.automatic)
1390 {
1391 int y = s->ybase;
1392 HFONT old_font;
1393
1394 old_font = SelectObject (s->hdc, FONT_HANDLE (font));
1395
1396 for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
1397
1398
1399 if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
1400 {
1401 int xx = x + s->cmp->offsets[j * 2];
1402 int yy = y - s->cmp->offsets[j * 2 + 1];
1403
1404 font->driver->draw (s, j, j + 1, xx, yy, false);
1405 if (s->face->overstrike)
1406 font->driver->draw (s, j, j + 1, xx + 1, yy, false);
1407 }
1408 SelectObject (s->hdc, old_font);
1409 }
1410 else
1411 {
1412 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1413 Lisp_Object glyph;
1414 int y = s->ybase;
1415 int width = 0;
1416 HFONT old_font;
1417
1418 old_font = SelectObject (s->hdc, FONT_HANDLE (font));
1419
1420 for (i = j = s->cmp_from; i < s->cmp_to; i++)
1421 {
1422 glyph = LGSTRING_GLYPH (gstring, i);
1423 if (NILP (LGLYPH_ADJUSTMENT (glyph)))
1424 width += LGLYPH_WIDTH (glyph);
1425 else
1426 {
1427 int xoff, yoff, wadjust;
1428
1429 if (j < i)
1430 {
1431 font->driver->draw (s, j, i, x, y, false);
1432 x += width;
1433 }
1434 xoff = LGLYPH_XOFF (glyph);
1435 yoff = LGLYPH_YOFF (glyph);
1436 wadjust = LGLYPH_WADJUST (glyph);
1437 font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false);
1438 x += wadjust;
1439 j = i + 1;
1440 width = 0;
1441 }
1442 }
1443 if (j < i)
1444 font->driver->draw (s, j, i, x, y, false);
1445
1446 SelectObject (s->hdc, old_font);
1447 }
1448 }
1449
1450
1451
1452
1453 static void
1454 w32_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
1455 {
1456 struct glyph *glyph = s->first_glyph;
1457 unsigned char2b[8];
1458 int x, i, j;
1459 bool with_background;
1460
1461
1462
1463 if (s->face->box != FACE_NO_BOX
1464 && s->first_glyph->left_box_line_p)
1465 x = s->x + max (s->face->box_vertical_line_width, 0);
1466 else
1467 x = s->x;
1468
1469 SetTextColor (s->hdc, s->gc->foreground);
1470 SetBkColor (s->hdc, s->gc->background);
1471 SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
1472
1473 s->char2b = char2b;
1474 with_background = ((s->for_overlaps
1475 || (s->background_filled_p && s->hl != DRAW_CURSOR))) == 0;
1476 for (i = 0; i < s->nchars; i++, glyph++)
1477 {
1478 char buf[7], *str = NULL;
1479 int len = glyph->u.glyphless.len;
1480
1481 if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
1482 {
1483 if (len > 0
1484 && CHAR_TABLE_P (Vglyphless_char_display)
1485 && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
1486 >= 1))
1487 {
1488 Lisp_Object acronym
1489 = (! glyph->u.glyphless.for_no_font
1490 ? CHAR_TABLE_REF (Vglyphless_char_display,
1491 glyph->u.glyphless.ch)
1492 : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
1493 if (CONSP (acronym))
1494 acronym = XCAR (acronym);
1495 if (STRINGP (acronym))
1496 str = SSDATA (acronym);
1497 }
1498 }
1499 else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
1500 {
1501 sprintf ((char *) buf, "%0*X",
1502 glyph->u.glyphless.ch < 0x10000 ? 4 : 6,
1503 (unsigned int) glyph->u.glyphless.ch & 0xffffff);
1504 str = buf;
1505 }
1506
1507 if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
1508 w32_draw_rectangle (s->hdc, s->gc,
1509 x, s->ybase - glyph->ascent,
1510 glyph->pixel_width - 1,
1511 glyph->ascent + glyph->descent - 1);
1512 if (str)
1513 {
1514 struct font *font = s->font;
1515 int upper_len = (len + 1) / 2;
1516 HFONT old_font;
1517
1518 old_font = SelectObject (s->hdc, FONT_HANDLE (font));
1519
1520 for (j = 0; j < len; j++)
1521 char2b[j] = font->driver->encode_char (font, str[j]) & 0xFFFF;
1522 font->driver->draw (s, 0, upper_len,
1523 x + glyph->slice.glyphless.upper_xoff,
1524 s->ybase + glyph->slice.glyphless.upper_yoff,
1525 with_background);
1526 font->driver->draw (s, upper_len, len,
1527 x + glyph->slice.glyphless.lower_xoff,
1528 s->ybase + glyph->slice.glyphless.lower_yoff,
1529 with_background);
1530 SelectObject (s->hdc, old_font);
1531 }
1532 x += glyph->pixel_width;
1533 }
1534 }
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558 static int
1559 w32_alloc_lighter_color (struct frame *f, COLORREF *color,
1560 double factor, int delta)
1561 {
1562 COLORREF new;
1563 long bright;
1564
1565
1566 delta /= 256;
1567
1568
1569 eassert (factor >= 0);
1570 new = PALETTERGB (min (0xff, factor * GetRValue (*color)),
1571 min (0xff, factor * GetGValue (*color)),
1572 min (0xff, factor * GetBValue (*color)));
1573
1574
1575 bright = (2 * GetRValue (*color) + 3 * GetGValue (*color)
1576 + GetBValue (*color)) / 6;
1577
1578
1579
1580 if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
1581
1582
1583 {
1584
1585 double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
1586
1587 int min_delta = delta * dimness * factor / 2;
1588
1589 if (factor < 1)
1590 new = PALETTERGB (max (0, min (0xff, min_delta - GetRValue (*color))),
1591 max (0, min (0xff, min_delta - GetGValue (*color))),
1592 max (0, min (0xff, min_delta - GetBValue (*color))));
1593 else
1594 new = PALETTERGB (max (0, min (0xff, min_delta + GetRValue (*color))),
1595 max (0, min (0xff, min_delta + GetGValue (*color))),
1596 max (0, min (0xff, min_delta + GetBValue (*color))));
1597 }
1598
1599 if (new == *color)
1600 new = PALETTERGB (max (0, min (0xff, delta + GetRValue (*color))),
1601 max (0, min (0xff, delta + GetGValue (*color))),
1602 max (0, min (0xff, delta + GetBValue (*color))));
1603
1604
1605
1606
1607 if (new == *color)
1608 return 0;
1609
1610 *color = new;
1611
1612 return 1;
1613 }
1614
1615
1616
1617
1618 static void
1619 w32_query_colors (struct frame *f, Emacs_Color *colors, int ncolors)
1620 {
1621 int i;
1622
1623 for (i = 0; i < ncolors; i++)
1624 {
1625 DWORD pixel = colors[i].pixel;
1626
1627 colors[i].red = GetRValue (pixel) * 257;
1628 colors[i].green = GetGValue (pixel) * 257;
1629 colors[i].blue = GetBValue (pixel) * 257;
1630 }
1631 }
1632
1633
1634
1635 void
1636 w32_query_frame_background_color (struct frame *f, Emacs_Color *bgcolor)
1637 {
1638 bgcolor->pixel = FRAME_BACKGROUND_PIXEL (f);
1639 w32_query_colors (f, bgcolor, 1);
1640 }
1641
1642
1643
1644
1645
1646
1647
1648
1649 static void
1650 w32_setup_relief_color (struct frame *f, struct relief *relief, double factor,
1651 int delta, COLORREF default_pixel)
1652 {
1653 Emacs_GC egc;
1654 struct w32_output *di = f->output_data.w32;
1655 unsigned long mask = GCForeground;
1656 COLORREF pixel;
1657 COLORREF background = di->relief_background;
1658 #if 0
1659 struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
1660 #endif
1661
1662
1663
1664
1665 egc.foreground = default_pixel;
1666 pixel = background;
1667 if (w32_alloc_lighter_color (f, &pixel, factor, delta))
1668 egc.foreground = relief->pixel = pixel;
1669
1670 if (relief->gc == 0)
1671 {
1672 #if 0
1673 egc.stipple = dpyinfo->gray;
1674 mask |= GCStipple;
1675 #endif
1676 relief->gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, &egc);
1677 }
1678 else
1679 XChangeGC (NULL, relief->gc, mask, &egc);
1680 }
1681
1682
1683
1684
1685 static void
1686 w32_setup_relief_colors (struct glyph_string *s)
1687 {
1688 struct w32_output *di = s->f->output_data.w32;
1689 COLORREF color;
1690
1691 if (s->face->use_box_color_for_shadows_p)
1692 color = s->face->box_color;
1693 else if (s->first_glyph->type == IMAGE_GLYPH
1694 && s->img->pixmap
1695 && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
1696 color = IMAGE_BACKGROUND (s->img, s->f, 0);
1697 else
1698 color = s->gc->background;
1699
1700 if (di->white_relief.gc == 0
1701 || color != di->relief_background)
1702 {
1703 di->relief_background = color;
1704 w32_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
1705 WHITE_PIX_DEFAULT (s->f));
1706 w32_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
1707 BLACK_PIX_DEFAULT (s->f));
1708 }
1709 }
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720 static void
1721 w32_draw_relief_rect (struct frame *f,
1722 int left_x, int top_y, int right_x, int bottom_y,
1723 int hwidth, int vwidth, int raised_p,
1724 int top_p, int bot_p, int left_p, int right_p,
1725 RECT *clip_rect)
1726 {
1727 int i;
1728 Emacs_GC gc;
1729 HDC hdc = get_frame_dc (f);
1730
1731 if (raised_p)
1732 gc.foreground = f->output_data.w32->white_relief.gc->foreground;
1733 else
1734 gc.foreground = f->output_data.w32->black_relief.gc->foreground;
1735
1736 w32_set_clip_rectangle (hdc, clip_rect);
1737
1738
1739 if (top_p)
1740 for (i = 0; i < hwidth; ++i)
1741 w32_fill_area (f, hdc, gc.foreground,
1742 left_x + i * left_p, top_y + i,
1743 right_x - left_x - i * (left_p + right_p ) + 1, 1);
1744
1745
1746 if (left_p)
1747 for (i = 0; i < vwidth; ++i)
1748 w32_fill_area (f, hdc, gc.foreground,
1749 left_x + i, top_y + (i + 1) * top_p, 1,
1750 bottom_y - top_y - (i + 1) * (bot_p + top_p) + 1);
1751
1752 if (raised_p)
1753 gc.foreground = f->output_data.w32->black_relief.gc->foreground;
1754 else
1755 gc.foreground = f->output_data.w32->white_relief.gc->foreground;
1756
1757
1758 if (bot_p)
1759 for (i = 0; i < hwidth; ++i)
1760 w32_fill_area (f, hdc, gc.foreground,
1761 left_x + i * left_p, bottom_y - i,
1762 right_x - left_x - i * (left_p + right_p) + 1, 1);
1763
1764
1765 if (right_p)
1766 for (i = 0; i < vwidth; ++i)
1767 w32_fill_area (f, hdc, gc.foreground,
1768 right_x - i, top_y + (i + 1) * top_p, 1,
1769 bottom_y - top_y - (i + 1) * (bot_p + top_p) + 1);
1770
1771 w32_set_clip_rectangle (hdc, NULL);
1772
1773 release_frame_dc (f, hdc);
1774 }
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784 static void
1785 w32_draw_box_rect (struct glyph_string *s,
1786 int left_x, int top_y, int right_x, int bottom_y, int hwidth,
1787 int vwidth, bool left_p, bool right_p, RECT *clip_rect)
1788 {
1789 w32_set_clip_rectangle (s->hdc, clip_rect);
1790
1791
1792 w32_fill_area (s->f, s->hdc, s->face->box_color,
1793 left_x, top_y, right_x - left_x + 1, hwidth);
1794
1795
1796 if (left_p)
1797 {
1798 w32_fill_area (s->f, s->hdc, s->face->box_color,
1799 left_x, top_y, vwidth, bottom_y - top_y + 1);
1800 }
1801
1802
1803 w32_fill_area (s->f, s->hdc, s->face->box_color,
1804 left_x, bottom_y - hwidth + 1, right_x - left_x + 1, hwidth);
1805
1806
1807 if (right_p)
1808 {
1809 w32_fill_area (s->f, s->hdc, s->face->box_color,
1810 right_x - vwidth + 1, top_y, vwidth, bottom_y - top_y + 1);
1811 }
1812
1813 w32_set_clip_rectangle (s->hdc, NULL);
1814 }
1815
1816
1817
1818
1819 static void
1820 w32_draw_glyph_string_box (struct glyph_string *s)
1821 {
1822 int hwidth, vwidth, left_x, right_x, top_y, bottom_y, last_x;
1823 bool left_p, right_p, raised_p;
1824 struct glyph *last_glyph;
1825 RECT clip_rect;
1826
1827 last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
1828 ? WINDOW_RIGHT_EDGE_X (s->w)
1829 : window_box_right (s->w, s->area));
1830
1831
1832
1833
1834 if (s->cmp || s->img)
1835 last_glyph = s->first_glyph;
1836 else if (s->first_glyph->type == COMPOSITE_GLYPH
1837 && s->first_glyph->u.cmp.automatic)
1838 {
1839
1840
1841 struct glyph *end = s->row->glyphs[s->area] + s->row->used[s->area];
1842 struct glyph *g = s->first_glyph;
1843 for (last_glyph = g++;
1844 g < end && g->u.cmp.automatic && g->u.cmp.id == s->cmp_id
1845 && g->slice.cmp.to < s->cmp_to;
1846 last_glyph = g++)
1847 ;
1848 }
1849 else
1850 last_glyph = s->first_glyph + s->nchars - 1;
1851
1852 vwidth = eabs (s->face->box_vertical_line_width);
1853 hwidth = eabs (s->face->box_horizontal_line_width);
1854 raised_p = s->face->box == FACE_RAISED_BOX;
1855 left_x = s->x;
1856 right_x = ((s->row->full_width_p && s->extends_to_end_of_line_p
1857 ? last_x - 1
1858 : min (last_x, s->x + s->background_width) - 1));
1859 top_y = s->y;
1860 bottom_y = top_y + s->height - 1;
1861
1862 left_p = (s->first_glyph->left_box_line_p
1863 || (s->hl == DRAW_MOUSE_FACE
1864 && (s->prev == NULL
1865 || s->prev->hl != s->hl)));
1866 right_p = (last_glyph->right_box_line_p
1867 || (s->hl == DRAW_MOUSE_FACE
1868 && (s->next == NULL
1869 || s->next->hl != s->hl)));
1870
1871 get_glyph_string_clip_rect (s, &clip_rect);
1872
1873 if (s->face->box == FACE_SIMPLE_BOX)
1874 w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
1875 vwidth, left_p, right_p, &clip_rect);
1876 else
1877 {
1878 w32_setup_relief_colors (s);
1879 w32_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y, hwidth,
1880 vwidth, raised_p, 1, 1, left_p, right_p, &clip_rect);
1881 }
1882 }
1883
1884 bool
1885 w32_image_rotations_p (void)
1886 {
1887 return pfnPlgBlt != NULL;
1888 }
1889
1890 static POINT
1891 transform (int x0, int y0, int x, int y, XFORM *xform)
1892 {
1893 POINT pt;
1894
1895
1896 pt.x =
1897 x0 + (x - x0) * xform->eM11 + (y - y0) * xform->eM21 + xform->eDx + 0.5f;
1898 pt.y =
1899 y0 + (x - x0) * xform->eM12 + (y - y0) * xform->eM22 + xform->eDy + 0.5f;
1900
1901 return pt;
1902 }
1903
1904
1905
1906
1907 static void
1908 w32_draw_image_foreground (struct glyph_string *s)
1909 {
1910 int x = s->x;
1911 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
1912
1913
1914
1915 if (s->face->box != FACE_NO_BOX
1916 && s->first_glyph->left_box_line_p
1917 && s->slice.x == 0)
1918 x += max (s->face->box_vertical_line_width, 0);
1919
1920
1921
1922 if (s->slice.x == 0)
1923 x += s->img->hmargin;
1924 if (s->slice.y == 0)
1925 y += s->img->vmargin;
1926
1927 SaveDC (s->hdc);
1928
1929 if (s->img->pixmap)
1930 {
1931 HDC compat_hdc = CreateCompatibleDC (s->hdc);
1932 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
1933 HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
1934 HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
1935 LONG orig_width, orig_height;
1936 DIBSECTION dib;
1937 SetBkColor (compat_hdc, RGB (255, 255, 255));
1938 SetTextColor (s->hdc, RGB (0, 0, 0));
1939 w32_set_glyph_string_clipping (s);
1940
1941 if (GetObject (s->img->pixmap, sizeof (dib), &dib) > 0)
1942 {
1943 BITMAP bmp = dib.dsBm;
1944 orig_width = bmp.bmWidth;
1945 orig_height = bmp.bmHeight;
1946 }
1947 else
1948 {
1949 DebPrint (("w32_draw_image_foreground: GetObject(pixmap) failed!\n"));
1950 orig_width = s->slice.width;
1951 orig_height = s->slice.height;
1952 }
1953
1954 double w_factor = 1.0, h_factor = 1.0;
1955 bool scaled = false, need_xform = false;
1956 int orig_slice_width = s->slice.width,
1957 orig_slice_height = s->slice.height;
1958 int orig_slice_x = s->slice.x, orig_slice_y = s->slice.y;
1959 POINT corner[3];
1960 if ((s->img->xform.eM12 != 0 || s->img->xform.eM21 != 0
1961 || s->img->xform.eDx != 0 || s->img->xform.eDy != 0)
1962
1963 && pfnPlgBlt)
1964 {
1965 need_xform = true;
1966 corner[0] = transform (x, y, x, y, &s->img->xform);
1967 corner[1] = transform (x, y, x + orig_width, y, &s->img->xform);
1968 corner[2] = transform (x, y, x, y + orig_height, &s->img->xform);
1969 }
1970 else if (s->img->width != orig_width || s->img->height != orig_height)
1971 {
1972
1973
1974 scaled = true;
1975 w_factor = (double) orig_width / (double) s->img->width;
1976 h_factor = (double) orig_height / (double) s->img->height;
1977 orig_slice_width = s->slice.width * w_factor + 0.5;
1978 orig_slice_height = s->slice.height * h_factor + 0.5;
1979 orig_slice_x = s->slice.x * w_factor + 0.5;
1980 orig_slice_y = s->slice.y * h_factor + 0.5;
1981 }
1982
1983 if (s->img->mask)
1984 {
1985 HDC mask_dc = CreateCompatibleDC (s->hdc);
1986 HGDIOBJ mask_orig_obj = SelectObject (mask_dc, s->img->mask);
1987
1988 SetTextColor (s->hdc, RGB (255, 255, 255));
1989 SetBkColor (s->hdc, RGB (0, 0, 0));
1990 if (need_xform)
1991 {
1992 if (!pfnPlgBlt (s->hdc, corner, compat_hdc,
1993 s->slice.x, s->slice.y,
1994 orig_width, orig_height,
1995 s->img->mask, s->slice.x, s->slice.y))
1996 DebPrint (("PlgBlt failed!"));
1997 }
1998 else if (!scaled)
1999 {
2000 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
2001 compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
2002 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
2003 mask_dc, s->slice.x, s->slice.y, SRCAND);
2004 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
2005 compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
2006 }
2007 else
2008 {
2009 int pmode = 0;
2010
2011
2012
2013 if (os_subtype == OS_SUBTYPE_NT
2014 && (pmode = SetStretchBltMode (s->hdc, HALFTONE)) != 0)
2015 SetBrushOrgEx (s->hdc, 0, 0, NULL);
2016 StretchBlt (s->hdc, x, y, s->slice.width, s->slice.height,
2017 compat_hdc, orig_slice_x, orig_slice_y,
2018 orig_slice_width, orig_slice_height, SRCINVERT);
2019 StretchBlt (s->hdc, x, y, s->slice.width, s->slice.height,
2020 mask_dc, orig_slice_x, orig_slice_y,
2021 orig_slice_width, orig_slice_height, SRCAND);
2022 StretchBlt (s->hdc, x, y, s->slice.width, s->slice.height,
2023 compat_hdc, orig_slice_x, orig_slice_y,
2024 orig_slice_width, orig_slice_height, SRCINVERT);
2025 if (pmode)
2026 SetStretchBltMode (s->hdc, pmode);
2027 }
2028 SelectObject (mask_dc, mask_orig_obj);
2029 DeleteDC (mask_dc);
2030 }
2031 else
2032 {
2033 SetTextColor (s->hdc, s->gc->foreground);
2034 SetBkColor (s->hdc, s->gc->background);
2035 if (need_xform)
2036 {
2037 if (!pfnPlgBlt (s->hdc, corner, compat_hdc,
2038 s->slice.x, s->slice.y,
2039 orig_width, orig_height, NULL, 0, 0))
2040 DebPrint (("PlgBlt failed!"));
2041 }
2042 else if (!scaled)
2043 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
2044 compat_hdc, s->slice.x, s->slice.y, SRCCOPY);
2045 else
2046 {
2047 int pmode = 0;
2048
2049 if (os_subtype == OS_SUBTYPE_NT
2050 && (pmode = SetStretchBltMode (s->hdc, HALFTONE)) != 0)
2051 SetBrushOrgEx (s->hdc, 0, 0, NULL);
2052 StretchBlt (s->hdc, x, y, s->slice.width, s->slice.height,
2053 compat_hdc, orig_slice_x, orig_slice_y,
2054 orig_slice_width, orig_slice_height, SRCCOPY);
2055 if (pmode)
2056 SetStretchBltMode (s->hdc, pmode);
2057 }
2058
2059
2060
2061
2062
2063
2064
2065 if (s->hl == DRAW_CURSOR)
2066 {
2067 int r = s->img->relief;
2068 if (r < 0) r = -r;
2069 w32_draw_rectangle (s->hdc, s->gc, x - r, y - r ,
2070 s->slice.width + r*2 - 1,
2071 s->slice.height + r*2 - 1);
2072 }
2073 }
2074
2075 w32_set_clip_rectangle (s->hdc, NULL);
2076 SelectObject (s->hdc, orig_brush);
2077 DeleteObject (fg_brush);
2078 SelectObject (compat_hdc, orig_obj);
2079 DeleteDC (compat_hdc);
2080 }
2081 else
2082 w32_draw_rectangle (s->hdc, s->gc, x, y,
2083 s->slice.width - 1, s->slice.height - 1);
2084
2085 RestoreDC (s->hdc ,-1);
2086 }
2087
2088 size_t
2089 w32_image_size (Emacs_Pixmap pixmap)
2090 {
2091 BITMAP bm_info;
2092 size_t rv = 0;
2093
2094 if (GetObject (pixmap, sizeof (BITMAP), &bm_info))
2095 rv = bm_info.bmWidth * bm_info.bmHeight * bm_info.bmBitsPixel / 8;
2096 return rv;
2097 }
2098
2099
2100
2101
2102 static void
2103 w32_draw_image_relief (struct glyph_string *s)
2104 {
2105 int x1, y1, thick, raised_p, top_p, bot_p, left_p, right_p;
2106 int extra_x, extra_y;
2107 RECT r;
2108 int x = s->x;
2109 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
2110
2111
2112
2113 if (s->face->box != FACE_NO_BOX
2114 && s->first_glyph->left_box_line_p
2115 && s->slice.x == 0)
2116 x += max (s->face->box_vertical_line_width, 0);
2117
2118
2119
2120 if (s->slice.x == 0)
2121 x += s->img->hmargin;
2122 if (s->slice.y == 0)
2123 y += s->img->vmargin;
2124
2125 if (s->hl == DRAW_IMAGE_SUNKEN
2126 || s->hl == DRAW_IMAGE_RAISED)
2127 {
2128 if (s->face->id == TAB_BAR_FACE_ID)
2129 thick = (tab_bar_button_relief < 0
2130 ? DEFAULT_TAB_BAR_BUTTON_RELIEF
2131 : min (tab_bar_button_relief, 1000000));
2132 else
2133 thick = (tool_bar_button_relief < 0
2134 ? DEFAULT_TOOL_BAR_BUTTON_RELIEF
2135 : min (tool_bar_button_relief, 1000000));
2136 raised_p = s->hl == DRAW_IMAGE_RAISED;
2137 }
2138 else
2139 {
2140 thick = eabs (s->img->relief);
2141 raised_p = s->img->relief > 0;
2142 }
2143
2144 x1 = x + s->slice.width - 1;
2145 y1 = y + s->slice.height - 1;
2146
2147 extra_x = extra_y = 0;
2148 if (s->face->id == TAB_BAR_FACE_ID)
2149 {
2150 if (CONSP (Vtab_bar_button_margin)
2151 && FIXNUMP (XCAR (Vtab_bar_button_margin))
2152 && FIXNUMP (XCDR (Vtab_bar_button_margin)))
2153 {
2154 extra_x = XFIXNUM (XCAR (Vtab_bar_button_margin)) - thick;
2155 extra_y = XFIXNUM (XCDR (Vtab_bar_button_margin)) - thick;
2156 }
2157 else if (FIXNUMP (Vtab_bar_button_margin))
2158 extra_x = extra_y = XFIXNUM (Vtab_bar_button_margin) - thick;
2159 }
2160
2161 if (s->face->id == TOOL_BAR_FACE_ID)
2162 {
2163 if (CONSP (Vtool_bar_button_margin)
2164 && FIXNUMP (XCAR (Vtool_bar_button_margin))
2165 && FIXNUMP (XCDR (Vtool_bar_button_margin)))
2166 {
2167 extra_x = XFIXNUM (XCAR (Vtool_bar_button_margin));
2168 extra_y = XFIXNUM (XCDR (Vtool_bar_button_margin));
2169 }
2170 else if (FIXNUMP (Vtool_bar_button_margin))
2171 extra_x = extra_y = XFIXNUM (Vtool_bar_button_margin);
2172 }
2173
2174 top_p = bot_p = left_p = right_p = 0;
2175
2176 if (s->slice.x == 0)
2177 x -= thick + extra_x, left_p = 1;
2178 if (s->slice.y == 0)
2179 y -= thick + extra_y, top_p = 1;
2180 if (s->slice.x + s->slice.width == s->img->width)
2181 x1 += thick + extra_x, right_p = 1;
2182 if (s->slice.y + s->slice.height == s->img->height)
2183 y1 += thick + extra_y, bot_p = 1;
2184
2185 w32_setup_relief_colors (s);
2186 get_glyph_string_clip_rect (s, &r);
2187 w32_draw_relief_rect (s->f, x, y, x1, y1, thick, thick, raised_p,
2188 top_p, bot_p, left_p, right_p, &r);
2189 }
2190
2191
2192
2193
2194 static void
2195 w32_draw_image_foreground_1 (struct glyph_string *s, HBITMAP pixmap)
2196 {
2197 HDC hdc = CreateCompatibleDC (s->hdc);
2198 HGDIOBJ orig_hdc_obj = SelectObject (hdc, pixmap);
2199 int x = 0;
2200 int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
2201
2202
2203
2204 if (s->face->box != FACE_NO_BOX
2205 && s->first_glyph->left_box_line_p
2206 && s->slice.x == 0)
2207 x += max (s->face->box_vertical_line_width, 0);
2208
2209
2210
2211 if (s->slice.x == 0)
2212 x += s->img->hmargin;
2213 if (s->slice.y == 0)
2214 y += s->img->vmargin;
2215
2216
2217
2218
2219
2220 if (s->img->pixmap)
2221 {
2222 HDC compat_hdc = CreateCompatibleDC (hdc);
2223 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
2224 HBRUSH orig_brush = SelectObject (hdc, fg_brush);
2225 HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
2226
2227 if (s->img->mask)
2228 {
2229 HDC mask_dc = CreateCompatibleDC (hdc);
2230 HGDIOBJ mask_orig_obj = SelectObject (mask_dc, s->img->mask);
2231
2232 SetTextColor (hdc, RGB (0, 0, 0));
2233 SetBkColor (hdc, RGB (255, 255, 255));
2234 BitBlt (hdc, x, y, s->slice.width, s->slice.height,
2235 compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
2236 BitBlt (hdc, x, y, s->slice.width, s->slice.height,
2237 mask_dc, s->slice.x, s->slice.y, SRCAND);
2238 BitBlt (hdc, x, y, s->slice.width, s->slice.height,
2239 compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
2240
2241 SelectObject (mask_dc, mask_orig_obj);
2242 DeleteDC (mask_dc);
2243 }
2244 else
2245 {
2246 SetTextColor (hdc, s->gc->foreground);
2247 SetBkColor (hdc, s->gc->background);
2248
2249 BitBlt (hdc, x, y, s->slice.width, s->slice.height,
2250 compat_hdc, s->slice.x, s->slice.y, SRCCOPY);
2251
2252
2253
2254
2255
2256
2257
2258 if (s->hl == DRAW_CURSOR)
2259 {
2260 int r = s->img->relief;
2261 if (r < 0) r = -r;
2262 w32_draw_rectangle (hdc, s->gc, x - r, y - r,
2263 s->slice.width + r*2 - 1,
2264 s->slice.height + r*2 - 1);
2265 }
2266 }
2267
2268 SelectObject (hdc, orig_brush);
2269 DeleteObject (fg_brush);
2270 SelectObject (compat_hdc, orig_obj);
2271 DeleteDC (compat_hdc);
2272 }
2273 else
2274 w32_draw_rectangle (hdc, s->gc, x, y,
2275 s->slice.width - 1, s->slice.height - 1);
2276
2277 SelectObject (hdc, orig_hdc_obj);
2278 DeleteDC (hdc);
2279 }
2280
2281
2282
2283
2284
2285 static void
2286 w32_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
2287 {
2288 #if 0
2289 if (s->stippled_p)
2290 {
2291
2292 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
2293 XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), s->gc, x, y, w, h);
2294 XSetFillStyle (s->display, s->gc, FillSolid);
2295 }
2296 else
2297 #endif
2298 w32_clear_glyph_string_rect (s, x, y, w, h);
2299 }
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316 static void
2317 w32_draw_image_glyph_string (struct glyph_string *s)
2318 {
2319 int x, y;
2320 int box_line_hwidth = max (s->face->box_vertical_line_width, 0);
2321 int box_line_vwidth = max (s->face->box_horizontal_line_width, 0);
2322 int height, width;
2323 HBITMAP pixmap = 0;
2324
2325 height = s->height;
2326 if (s->slice.y == 0)
2327 height -= box_line_vwidth;
2328 if (s->slice.y + s->slice.height >= s->img->height)
2329 height -= box_line_vwidth;
2330
2331
2332
2333
2334 s->stippled_p = s->face->stipple != 0;
2335 if (height > s->slice.height
2336 || s->img->hmargin
2337 || s->img->vmargin
2338 || s->img->mask
2339 || s->img->pixmap == 0
2340 || s->width != s->background_width)
2341 {
2342 width = s->background_width;
2343 x = s->x;
2344 if (s->first_glyph->left_box_line_p
2345 && s->slice.x == 0)
2346 {
2347 x += box_line_hwidth;
2348 width -= box_line_hwidth;
2349 }
2350
2351 y = s->y;
2352 if (s->slice.y == 0)
2353 y += box_line_vwidth;
2354
2355 #if 0
2356 if (s->img->mask)
2357 {
2358
2359
2360
2361 Screen *screen = FRAME_X_SCREEN (s->f);
2362 int depth = DefaultDepthOfScreen (screen);
2363
2364
2365 pixmap = XCreatePixmap (s->display, FRAME_W32_WINDOW (s->f),
2366 s->background_width,
2367 s->height, depth);
2368
2369
2370
2371 XSetClipMask (s->display, s->gc, None);
2372
2373
2374 if (s->stippled_p)
2375 {
2376
2377 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
2378 XFillRectangle (s->display, pixmap, s->gc,
2379 0, 0, s->background_width, s->height);
2380 XSetFillStyle (s->display, s->gc, FillSolid);
2381 }
2382 else
2383 {
2384 XGCValues xgcv;
2385 XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
2386 &xgcv);
2387 XSetForeground (s->display, s->gc, xgcv.background);
2388 XFillRectangle (s->display, pixmap, s->gc,
2389 0, 0, s->background_width, s->height);
2390 XSetForeground (s->display, s->gc, xgcv.foreground);
2391 }
2392 }
2393 else
2394 #endif
2395 w32_draw_glyph_string_bg_rect (s, x, y, width, height);
2396
2397 s->background_filled_p = true;
2398 }
2399
2400
2401 if (pixmap != 0)
2402 {
2403 w32_draw_image_foreground_1 (s, pixmap);
2404 w32_set_glyph_string_clipping (s);
2405 {
2406 HDC compat_hdc = CreateCompatibleDC (s->hdc);
2407 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
2408 HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
2409 HGDIOBJ orig_obj = SelectObject (compat_hdc, pixmap);
2410
2411 SetTextColor (s->hdc, s->gc->foreground);
2412 SetBkColor (s->hdc, s->gc->background);
2413 BitBlt (s->hdc, s->x, s->y, s->background_width, s->height,
2414 compat_hdc, 0, 0, SRCCOPY);
2415
2416 SelectObject (s->hdc, orig_brush);
2417 DeleteObject (fg_brush);
2418 SelectObject (compat_hdc, orig_obj);
2419 DeleteDC (compat_hdc);
2420 }
2421 DeleteObject (pixmap);
2422 pixmap = 0;
2423 }
2424 else
2425 w32_draw_image_foreground (s);
2426
2427
2428 if (s->img->relief
2429 || s->hl == DRAW_IMAGE_RAISED
2430 || s->hl == DRAW_IMAGE_SUNKEN)
2431 w32_draw_image_relief (s);
2432 }
2433
2434
2435
2436
2437 static void
2438 w32_draw_stretch_glyph_string (struct glyph_string *s)
2439 {
2440 eassert (s->first_glyph->type == STRETCH_GLYPH);
2441
2442 if (s->hl == DRAW_CURSOR
2443 && !x_stretch_cursor_p)
2444 {
2445
2446
2447 int width, background_width = s->background_width;
2448 int x = s->x;
2449
2450 if (!s->row->reversed_p)
2451 {
2452 int left_x = window_box_left_offset (s->w, TEXT_AREA);
2453
2454 if (x < left_x)
2455 {
2456 background_width -= left_x - x;
2457 x = left_x;
2458 }
2459 }
2460 else
2461 {
2462
2463
2464 int right_x = window_box_right (s->w, TEXT_AREA);
2465
2466 if (x + background_width > right_x)
2467 background_width -= x - right_x;
2468 x += background_width;
2469 }
2470 width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
2471 if (s->row->reversed_p)
2472 x -= width;
2473
2474
2475 w32_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
2476
2477
2478 if (width < background_width)
2479 {
2480 Emacs_GC *gc = s->face->gc;
2481 int y = s->y;
2482 int w = background_width - width, h = s->height;
2483 RECT r;
2484 HDC hdc = s->hdc;
2485
2486 if (!s->row->reversed_p)
2487 x += width;
2488 else
2489 x = s->x;
2490 if (s->row->mouse_face_p
2491 && cursor_in_mouse_face_p (s->w))
2492 {
2493 w32_set_mouse_face_gc (s);
2494 gc = s->gc;
2495 }
2496 else
2497 gc = s->face->gc;
2498
2499 get_glyph_string_clip_rect (s, &r);
2500 w32_set_clip_rectangle (hdc, &r);
2501
2502 #if 0
2503 if (s->face->stipple)
2504 {
2505
2506 XSetFillStyle (s->display, gc, FillOpaqueStippled);
2507 XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), gc, x, y, w, h);
2508 XSetFillStyle (s->display, gc, FillSolid);
2509 }
2510 else
2511 #endif
2512 {
2513 w32_fill_area (s->f, s->hdc, gc->background, x, y, w, h);
2514 }
2515 }
2516 }
2517 else if (!s->background_filled_p)
2518 {
2519 int background_width = s->background_width;
2520 int x = s->x, text_left_x = window_box_left (s->w, TEXT_AREA);
2521
2522
2523
2524 if (s->area == TEXT_AREA
2525 && x < text_left_x && !s->row->mode_line_p)
2526 {
2527 background_width -= text_left_x - x;
2528 x = text_left_x;
2529 }
2530 if (background_width > 0)
2531 w32_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
2532 }
2533
2534 s->background_filled_p = true;
2535 }
2536
2537
2538
2539
2540 static void
2541 w32_draw_glyph_string (struct glyph_string *s)
2542 {
2543 bool relief_drawn_p = 0;
2544
2545
2546
2547
2548 if (s->next && s->right_overhang && !s->for_overlaps)
2549 {
2550 int width;
2551 struct glyph_string *next;
2552 for (width = 0, next = s->next;
2553 next && width < s->right_overhang;
2554 width += next->width, next = next->next)
2555 if (next->first_glyph->type != IMAGE_GLYPH)
2556 {
2557 w32_set_glyph_string_gc (next);
2558 w32_set_glyph_string_clipping (next);
2559 if (next->first_glyph->type == STRETCH_GLYPH)
2560 w32_draw_stretch_glyph_string (next);
2561 else
2562 w32_draw_glyph_string_background (next, true);
2563 next->num_clips = 0;
2564 }
2565 }
2566
2567
2568 w32_set_glyph_string_gc (s);
2569
2570
2571
2572 if (!s->for_overlaps
2573 && s->face->box != FACE_NO_BOX
2574 && (s->first_glyph->type == CHAR_GLYPH
2575 || s->first_glyph->type == COMPOSITE_GLYPH))
2576
2577 {
2578 w32_set_glyph_string_clipping (s);
2579 w32_draw_glyph_string_background (s, true);
2580 w32_draw_glyph_string_box (s);
2581 w32_set_glyph_string_clipping (s);
2582 relief_drawn_p = 1;
2583 }
2584 else if (!s->clip_head
2585 && !s->clip_tail
2586 && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
2587 || (s->next && s->next->hl != s->hl && s->right_overhang)))
2588
2589
2590
2591 w32_set_glyph_string_clipping_exactly (s, s);
2592 else
2593 w32_set_glyph_string_clipping (s);
2594
2595 switch (s->first_glyph->type)
2596 {
2597 case IMAGE_GLYPH:
2598 w32_draw_image_glyph_string (s);
2599 break;
2600
2601 case STRETCH_GLYPH:
2602 w32_draw_stretch_glyph_string (s);
2603 break;
2604
2605 case CHAR_GLYPH:
2606 if (s->for_overlaps)
2607 s->background_filled_p = true;
2608 else
2609 w32_draw_glyph_string_background (s, false);
2610 w32_draw_glyph_string_foreground (s);
2611 break;
2612
2613 case COMPOSITE_GLYPH:
2614 if (s->for_overlaps || (s->cmp_from > 0
2615 && ! s->first_glyph->u.cmp.automatic))
2616 s->background_filled_p = true;
2617 else
2618 w32_draw_glyph_string_background (s, true);
2619 w32_draw_composite_glyph_string_foreground (s);
2620 break;
2621
2622 case GLYPHLESS_GLYPH:
2623 if (s->for_overlaps)
2624 s->background_filled_p = true;
2625 else
2626 w32_draw_glyph_string_background (s, false);
2627 w32_draw_glyphless_glyph_string_foreground (s);
2628 break;
2629
2630 default:
2631 emacs_abort ();
2632 }
2633
2634 if (!s->for_overlaps)
2635 {
2636
2637 if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
2638 w32_draw_glyph_string_box (s);
2639
2640
2641 if (s->face->underline)
2642 {
2643 if (s->face->underline == FACE_UNDER_WAVE)
2644 {
2645 COLORREF color;
2646
2647 if (s->face->underline_defaulted_p)
2648 color = s->gc->foreground;
2649 else
2650 color = s->face->underline_color;
2651
2652 w32_draw_underwave (s, color);
2653 }
2654 else if (s->face->underline == FACE_UNDER_LINE)
2655 {
2656 unsigned long thickness, position;
2657 int y;
2658
2659 if (s->prev
2660 && s->prev->face->underline == FACE_UNDER_LINE
2661 && (s->prev->face->underline_at_descent_line_p
2662 == s->face->underline_at_descent_line_p)
2663 && (s->prev->face->underline_pixels_above_descent_line
2664 == s->face->underline_pixels_above_descent_line))
2665 {
2666
2667 thickness = s->prev->underline_thickness;
2668 position = s->prev->underline_position;
2669 }
2670 else
2671 {
2672 struct font *font = font_for_underline_metrics (s);
2673 unsigned long minimum_offset;
2674 BOOL underline_at_descent_line;
2675 BOOL use_underline_position_properties;
2676 Lisp_Object val = (WINDOW_BUFFER_LOCAL_VALUE
2677 (Qunderline_minimum_offset, s->w));
2678
2679 if (FIXNUMP (val))
2680 minimum_offset = max (0, XFIXNUM (val));
2681 else
2682 minimum_offset = 1;
2683
2684 val = (WINDOW_BUFFER_LOCAL_VALUE
2685 (Qx_underline_at_descent_line, s->w));
2686 underline_at_descent_line
2687 = (!(NILP (val) || BASE_EQ (val, Qunbound))
2688 || s->face->underline_at_descent_line_p);
2689
2690 val = (WINDOW_BUFFER_LOCAL_VALUE
2691 (Qx_use_underline_position_properties, s->w));
2692 use_underline_position_properties
2693 = !(NILP (val) || BASE_EQ (val, Qunbound));
2694
2695
2696 if (font && font->underline_thickness > 0)
2697 thickness = font->underline_thickness;
2698 else
2699 thickness = 1;
2700 if (underline_at_descent_line
2701 || !font)
2702 position = ((s->height - thickness)
2703 - (s->ybase - s->y)
2704 - s->face->underline_pixels_above_descent_line);
2705 else
2706 {
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716 if (use_underline_position_properties
2717 && font->underline_position >= 0)
2718 position = font->underline_position;
2719 else
2720 position = (font->descent + 1) / 2;
2721 }
2722
2723 if (!(s->face->underline_at_descent_line_p
2724
2725
2726 && s->face->underline_pixels_above_descent_line))
2727 position = max (position, minimum_offset);
2728 }
2729
2730
2731 if (s->y + s->height <= s->ybase + position)
2732 position = (s->height - 1) - (s->ybase - s->y);
2733 if (s->y + s->height < s->ybase + position + thickness)
2734 thickness = (s->y + s->height) - (s->ybase + position);
2735 s->underline_thickness = thickness;
2736 s->underline_position = position;
2737 y = s->ybase + position;
2738 if (s->face->underline_defaulted_p)
2739 {
2740 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
2741 y, s->width, 1);
2742 }
2743 else
2744 {
2745 w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
2746 y, s->width, 1);
2747 }
2748 }
2749 }
2750
2751 if (s->face->overline_p)
2752 {
2753 unsigned long dy = 0, h = 1;
2754
2755 if (s->face->overline_color_defaulted_p)
2756 {
2757 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
2758 s->y + dy, s->width, h);
2759 }
2760 else
2761 {
2762 w32_fill_area (s->f, s->hdc, s->face->overline_color, s->x,
2763 s->y + dy, s->width, h);
2764 }
2765 }
2766
2767
2768 if (s->face->strike_through_p
2769 && !FONT_TEXTMETRIC (s->font).tmStruckOut)
2770 {
2771
2772
2773
2774
2775
2776 int glyph_y = s->ybase - s->first_glyph->ascent;
2777 int glyph_height = s->first_glyph->ascent + s->first_glyph->descent;
2778
2779
2780 unsigned long h = 1;
2781 unsigned long dy = (glyph_height - h) / 2;
2782
2783 if (s->face->strike_through_color_defaulted_p)
2784 {
2785 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
2786 glyph_y + dy, s->width, h);
2787 }
2788 else
2789 {
2790 w32_fill_area (s->f, s->hdc, s->face->strike_through_color, s->x,
2791 glyph_y + dy, s->width, h);
2792 }
2793 }
2794
2795 if (s->prev)
2796 {
2797 struct glyph_string *prev;
2798
2799 for (prev = s->prev; prev; prev = prev->prev)
2800 if (prev->hl != s->hl
2801 && prev->x + prev->width + prev->right_overhang > s->x)
2802 {
2803
2804
2805 enum draw_glyphs_face save = prev->hl;
2806
2807 prev->hl = s->hl;
2808 w32_set_glyph_string_gc (prev);
2809 w32_set_glyph_string_clipping_exactly (s, prev);
2810 if (prev->first_glyph->type == CHAR_GLYPH)
2811 w32_draw_glyph_string_foreground (prev);
2812 else
2813 w32_draw_composite_glyph_string_foreground (prev);
2814 w32_set_clip_rectangle (prev->hdc, NULL);
2815 prev->hl = save;
2816 prev->num_clips = 0;
2817 }
2818 }
2819
2820 if (s->next)
2821 {
2822 struct glyph_string *next;
2823
2824 for (next = s->next; next; next = next->next)
2825 if (next->hl != s->hl
2826 && next->x - next->left_overhang < s->x + s->width)
2827 {
2828
2829
2830 enum draw_glyphs_face save = next->hl;
2831
2832 next->hl = s->hl;
2833 w32_set_glyph_string_gc (next);
2834 w32_set_glyph_string_clipping_exactly (s, next);
2835 if (next->first_glyph->type == CHAR_GLYPH)
2836 w32_draw_glyph_string_foreground (next);
2837 else
2838 w32_draw_composite_glyph_string_foreground (next);
2839 w32_set_clip_rectangle (next->hdc, NULL);
2840 next->hl = save;
2841 next->num_clips = 0;
2842 next->clip_head = s->next;
2843 }
2844 }
2845 }
2846
2847
2848 w32_set_clip_rectangle (s->hdc, NULL);
2849 s->num_clips = 0;
2850 }
2851
2852
2853
2854
2855 static void
2856 w32_shift_glyphs_for_insert (struct frame *f, int x, int y,
2857 int width, int height, int shift_by)
2858 {
2859 HDC hdc;
2860
2861 hdc = get_frame_dc (f);
2862 BitBlt (hdc, x + shift_by, y, width, height,
2863 hdc, x, y, SRCCOPY);
2864
2865 release_frame_dc (f, hdc);
2866 }
2867
2868
2869
2870
2871
2872 static void
2873 w32_delete_glyphs (struct frame *f, register int n)
2874 {
2875 if (! FRAME_W32_P (f))
2876 return;
2877
2878 emacs_abort ();
2879 }
2880
2881
2882
2883
2884 static void
2885 w32_clear_frame (struct frame *f)
2886 {
2887 if (! FRAME_W32_P (f))
2888 return;
2889
2890
2891
2892 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
2893
2894 block_input ();
2895
2896 w32_clear_window (f);
2897
2898
2899
2900 w32_scroll_bar_clear (f);
2901
2902 unblock_input ();
2903 }
2904
2905
2906
2907
2908 static void
2909 w32_ring_bell (struct frame *f)
2910 {
2911 block_input ();
2912
2913 if (FRAME_W32_P (f) && visible_bell)
2914 {
2915 int i;
2916 HWND hwnd = FRAME_W32_WINDOW (f);
2917
2918 for (i = 0; i < 5; i++)
2919 {
2920 FlashWindow (hwnd, TRUE);
2921 Sleep (10);
2922 }
2923 FlashWindow (hwnd, FALSE);
2924 }
2925 else
2926 w32_sys_ring_bell (f);
2927
2928 unblock_input ();
2929 }
2930
2931
2932
2933
2934
2935
2936
2937
2938 static void
2939 w32_ins_del_lines (struct frame *f, int vpos, int n)
2940 {
2941 if (! FRAME_W32_P (f))
2942 return;
2943
2944 emacs_abort ();
2945 }
2946
2947
2948
2949
2950 static void
2951 w32_scroll_run (struct window *w, struct run *run)
2952 {
2953 struct frame *f = XFRAME (w->frame);
2954 int x, y, width, height, from_y, to_y, bottom_y;
2955 HDC hdc;
2956 HWND hwnd = FRAME_W32_WINDOW (f);
2957 HRGN expect_dirty = NULL;
2958
2959
2960
2961
2962 window_box (w, ANY_AREA, &x, &y, &width, &height);
2963
2964 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
2965 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
2966 bottom_y = y + height;
2967
2968 if (to_y < from_y)
2969 {
2970
2971
2972 if (from_y + run->height > bottom_y)
2973 height = bottom_y - from_y;
2974 else
2975 height = run->height;
2976
2977 if (w32_disable_double_buffering)
2978 expect_dirty = CreateRectRgn (x, y + height, x + width, bottom_y);
2979 }
2980 else
2981 {
2982
2983
2984 if (to_y + run->height > bottom_y)
2985 height = bottom_y - to_y;
2986 else
2987 height = run->height;
2988
2989 if (w32_disable_double_buffering)
2990 expect_dirty = CreateRectRgn (x, y, x + width, to_y);
2991 }
2992
2993 block_input ();
2994
2995
2996 gui_clear_cursor (w);
2997 if (!w32_disable_double_buffering)
2998 {
2999 hdc = get_frame_dc (f);
3000 BitBlt (hdc, x, to_y, width, height, hdc, x, from_y, SRCCOPY);
3001 release_frame_dc (f, hdc);
3002 }
3003 else
3004 {
3005 RECT from;
3006 RECT to;
3007 HRGN dirty = CreateRectRgn (0, 0, 0, 0);
3008 HRGN combined = CreateRectRgn (0, 0, 0, 0);
3009
3010 from.left = to.left = x;
3011 from.right = to.right = x + width;
3012 from.top = from_y;
3013 from.bottom = from_y + height;
3014 to.top = y;
3015 to.bottom = bottom_y;
3016
3017 ScrollWindowEx (hwnd, 0, to_y - from_y, &from, &to, dirty,
3018 NULL, SW_INVALIDATE);
3019
3020
3021
3022 CombineRgn (combined, dirty, expect_dirty, RGN_OR);
3023
3024
3025 if (!EqualRgn (combined, expect_dirty))
3026 SET_FRAME_GARBAGED (f);
3027
3028 DeleteObject (dirty);
3029 DeleteObject (combined);
3030 }
3031
3032 unblock_input ();
3033
3034 if (w32_disable_double_buffering
3035 && expect_dirty)
3036 DeleteObject (expect_dirty);
3037 }
3038
3039
3040
3041
3042
3043
3044
3045 static void
3046 w32_frame_highlight (struct frame *f)
3047 {
3048 gui_update_cursor (f, 1);
3049 w32_set_frame_alpha (f);
3050 }
3051
3052 static void
3053 w32_frame_unhighlight (struct frame *f)
3054 {
3055 gui_update_cursor (f, 1);
3056 w32_set_frame_alpha (f);
3057 }
3058
3059
3060
3061
3062
3063
3064
3065 static void
3066 w32_new_focus_frame (struct w32_display_info *dpyinfo, struct frame *frame)
3067 {
3068 struct frame *old_focus = dpyinfo->w32_focus_frame;
3069
3070 if (frame != dpyinfo->w32_focus_frame)
3071 {
3072
3073
3074 dpyinfo->w32_focus_frame = frame;
3075
3076 if (old_focus && old_focus->auto_lower)
3077 w32_lower_frame (old_focus);
3078
3079 if (dpyinfo->w32_focus_frame && dpyinfo->w32_focus_frame->auto_raise)
3080 dpyinfo->w32_pending_autoraise_frame = dpyinfo->w32_focus_frame;
3081 else
3082 dpyinfo->w32_pending_autoraise_frame = NULL;
3083 }
3084
3085 w32_frame_rehighlight_1 (dpyinfo);
3086 }
3087
3088
3089
3090
3091
3092
3093 static void
3094 w32_focus_changed (int type, int state, struct w32_display_info *dpyinfo,
3095 struct frame *frame, struct input_event *bufp)
3096 {
3097 if (type == WM_SETFOCUS)
3098 {
3099 if (dpyinfo->w32_focus_event_frame != frame)
3100 {
3101 w32_new_focus_frame (dpyinfo, frame);
3102 dpyinfo->w32_focus_event_frame = frame;
3103 bufp->kind = FOCUS_IN_EVENT;
3104 XSETFRAME (bufp->frame_or_window, frame);
3105 }
3106
3107 frame->output_data.x->focus_state |= state;
3108
3109
3110 }
3111 else if (type == WM_KILLFOCUS)
3112 {
3113 frame->output_data.x->focus_state &= ~state;
3114
3115 if (dpyinfo->w32_focus_event_frame == frame)
3116 {
3117 dpyinfo->w32_focus_event_frame = 0;
3118 w32_new_focus_frame (dpyinfo, 0);
3119
3120 bufp->kind = FOCUS_OUT_EVENT;
3121 XSETFRAME (bufp->frame_or_window, frame);
3122 }
3123
3124
3125 }
3126 }
3127
3128
3129
3130
3131
3132
3133
3134 static void
3135 w32_detect_focus_change (struct w32_display_info *dpyinfo, W32Msg *event,
3136 struct input_event *bufp)
3137 {
3138 struct frame *frame;
3139
3140 frame = w32_window_to_frame (dpyinfo, event->msg.hwnd);
3141 if (! frame)
3142 return;
3143
3144
3145 w32_focus_changed (event->msg.message,
3146 (event->msg.message == WM_KILLFOCUS ?
3147 FOCUS_IMPLICIT : FOCUS_EXPLICIT),
3148 dpyinfo, frame, bufp);
3149 }
3150
3151
3152 #if 0
3153
3154
3155 static void
3156 w32_mouse_leave (struct w32_display_info *dpyinfo)
3157 {
3158 w32_new_focus_frame (dpyinfo, dpyinfo->w32_focus_event_frame);
3159 }
3160 #endif
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170 static void
3171 w32_frame_rehighlight (struct frame *frame)
3172 {
3173 if (! FRAME_W32_P (frame))
3174 return;
3175 w32_frame_rehighlight_1 (FRAME_DISPLAY_INFO (frame));
3176 }
3177
3178 static void
3179 w32_frame_rehighlight_1 (struct w32_display_info *dpyinfo)
3180 {
3181 struct frame *old_highlight = dpyinfo->highlight_frame;
3182
3183 if (dpyinfo->w32_focus_frame)
3184 {
3185 dpyinfo->highlight_frame
3186 = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame)))
3187 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame))
3188 : dpyinfo->w32_focus_frame);
3189 if (! FRAME_LIVE_P (dpyinfo->highlight_frame))
3190 {
3191 fset_focus_frame (dpyinfo->w32_focus_frame, Qnil);
3192 dpyinfo->highlight_frame = dpyinfo->w32_focus_frame;
3193 }
3194 }
3195 else
3196 dpyinfo->highlight_frame = 0;
3197
3198 if (dpyinfo->highlight_frame != old_highlight)
3199 {
3200 if (old_highlight)
3201 w32_frame_unhighlight (old_highlight);
3202 if (dpyinfo->highlight_frame)
3203 w32_frame_highlight (dpyinfo->highlight_frame);
3204 }
3205 }
3206
3207
3208
3209
3210
3211 char *
3212 get_keysym_name (int keysym)
3213 {
3214
3215 static char value[100];
3216
3217 block_input ();
3218 GetKeyNameText (keysym, value, 100);
3219 unblock_input ();
3220
3221 return value;
3222 }
3223
3224 static int
3225 codepage_for_locale (LCID locale)
3226 {
3227 char cp[20];
3228
3229 if (GetLocaleInfo (locale, LOCALE_IDEFAULTANSICODEPAGE, cp, 20) > 0)
3230 return atoi (cp);
3231 else
3232 return CP_ACP;
3233 }
3234
3235
3236
3237
3238
3239
3240
3241 BOOL
3242 parse_button (int message, int xbutton, int * pbutton, int * pup)
3243 {
3244 int button = 0;
3245 int up = 0;
3246
3247 switch (message)
3248 {
3249 case WM_LBUTTONDOWN:
3250 button = 0;
3251 up = 0;
3252 break;
3253 case WM_LBUTTONUP:
3254 button = 0;
3255 up = 1;
3256 break;
3257 case WM_MBUTTONDOWN:
3258 if (NILP (Vw32_swap_mouse_buttons))
3259 button = 1;
3260 else
3261 button = 2;
3262 up = 0;
3263 break;
3264 case WM_MBUTTONUP:
3265 if (NILP (Vw32_swap_mouse_buttons))
3266 button = 1;
3267 else
3268 button = 2;
3269 up = 1;
3270 break;
3271 case WM_RBUTTONDOWN:
3272 if (NILP (Vw32_swap_mouse_buttons))
3273 button = 2;
3274 else
3275 button = 1;
3276 up = 0;
3277 break;
3278 case WM_RBUTTONUP:
3279 if (NILP (Vw32_swap_mouse_buttons))
3280 button = 2;
3281 else
3282 button = 1;
3283 up = 1;
3284 break;
3285 case WM_XBUTTONDOWN:
3286 button = xbutton + 2;
3287 up = 0;
3288 break;
3289 case WM_XBUTTONUP:
3290 button = xbutton + 2;
3291 up = 1;
3292 break;
3293 default:
3294 return (FALSE);
3295 }
3296
3297 if (pup) *pup = up;
3298 if (pbutton) *pbutton = button;
3299
3300 return (TRUE);
3301 }
3302
3303
3304
3305
3306
3307
3308
3309 static Lisp_Object
3310 w32_construct_mouse_click (struct input_event *result, W32Msg *msg,
3311 struct frame *f)
3312 {
3313 int button = 0;
3314 int up = 0;
3315
3316 parse_button (msg->msg.message, HIWORD (msg->msg.wParam),
3317 &button, &up);
3318
3319
3320
3321 result->kind = MOUSE_CLICK_EVENT;
3322 result->code = button;
3323 result->timestamp = msg->msg.time;
3324 result->modifiers = (msg->dwModifiers
3325 | (up
3326 ? up_modifier
3327 : down_modifier));
3328
3329 XSETINT (result->x, LOWORD (msg->msg.lParam));
3330 XSETINT (result->y, HIWORD (msg->msg.lParam));
3331 XSETFRAME (result->frame_or_window, f);
3332 result->arg = Qnil;
3333 return Qnil;
3334 }
3335
3336 static Lisp_Object
3337 w32_construct_mouse_wheel (struct input_event *result, W32Msg *msg,
3338 struct frame *f)
3339 {
3340 POINT p;
3341 int delta;
3342 static int sum_delta_y = 0;
3343
3344 result->kind = msg->msg.message == WM_MOUSEHWHEEL ? HORIZ_WHEEL_EVENT
3345 : WHEEL_EVENT;
3346 result->code = 0;
3347 result->timestamp = msg->msg.time;
3348 result->arg = Qnil;
3349
3350
3351
3352
3353 delta = GET_WHEEL_DELTA_WPARAM (msg->msg.wParam);
3354 if (delta == 0)
3355 {
3356 result->kind = NO_EVENT;
3357 return Qnil;
3358 }
3359
3360
3361
3362 p.x = (short) LOWORD (msg->msg.lParam);
3363 p.y = (short) HIWORD (msg->msg.lParam);
3364
3365 if (eabs (delta) < WHEEL_DELTA)
3366 {
3367
3368
3369
3370 int scroll_unit = max (w32_wheel_scroll_lines, 1), nlines;
3371 double value_to_report;
3372
3373
3374
3375
3376 if (w32_wheel_scroll_lines == UINT_MAX)
3377 {
3378 Lisp_Object window = window_from_coordinates (f, p.x, p.y, NULL,
3379 false, false);
3380 if (!WINDOWP (window))
3381 {
3382 result->kind = NO_EVENT;
3383 return Qnil;
3384 }
3385 scroll_unit = XWINDOW (window)->pixel_height;
3386 if (scroll_unit < 1)
3387 scroll_unit = 1;
3388 }
3389
3390
3391
3392 if (mwheel_coalesce_scroll_events)
3393 {
3394
3395
3396 if ((delta > 0) != (sum_delta_y > 0))
3397 sum_delta_y = 0;
3398 sum_delta_y += delta;
3399
3400 if (eabs (sum_delta_y) < WHEEL_DELTA)
3401 {
3402 result->kind = NO_EVENT;
3403 return Qnil;
3404 }
3405 value_to_report =
3406 ((double)FRAME_LINE_HEIGHT (f) * scroll_unit)
3407 / ((double)WHEEL_DELTA / sum_delta_y);
3408 sum_delta_y = 0;
3409 }
3410 else
3411 value_to_report =
3412 ((double)FRAME_LINE_HEIGHT (f) * scroll_unit)
3413 / ((double)WHEEL_DELTA / delta);
3414 nlines = value_to_report / FRAME_LINE_HEIGHT (f) + 0.5;
3415 result->arg = list3 (make_fixnum (eabs (nlines)),
3416 make_float (0.0),
3417 make_float (value_to_report));
3418 }
3419
3420
3421
3422 result->modifiers = (msg->dwModifiers
3423 | ((delta < 0 ) ? down_modifier : up_modifier));
3424
3425
3426 ScreenToClient (FRAME_W32_WINDOW (f), &p);
3427 XSETINT (result->x, p.x);
3428 XSETINT (result->y, p.y);
3429 XSETFRAME (result->frame_or_window, f);
3430 return Qnil;
3431 }
3432
3433 static Lisp_Object
3434 w32_construct_drag_n_drop (struct input_event *result, W32Msg *msg,
3435 struct frame *f)
3436 {
3437 Lisp_Object files;
3438 Lisp_Object frame;
3439 HDROP hdrop;
3440 POINT p;
3441 WORD num_files;
3442 wchar_t name_w[MAX_PATH];
3443 #ifdef NTGUI_UNICODE
3444 const int use_unicode = 1;
3445 #else
3446 int use_unicode = w32_unicode_filenames;
3447 char name_a[MAX_PATH];
3448 char file[MAX_UTF8_PATH];
3449 #endif
3450 int i;
3451
3452 result->kind = DRAG_N_DROP_EVENT;
3453 result->code = 0;
3454 result->timestamp = msg->msg.time;
3455 result->modifiers = msg->dwModifiers;
3456
3457 hdrop = (HDROP) msg->msg.wParam;
3458 DragQueryPoint (hdrop, &p);
3459
3460 #if 0
3461 p.x = LOWORD (msg->msg.lParam);
3462 p.y = HIWORD (msg->msg.lParam);
3463 ScreenToClient (msg->msg.hwnd, &p);
3464 #endif
3465
3466 XSETINT (result->x, p.x);
3467 XSETINT (result->y, p.y);
3468
3469 num_files = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0);
3470 files = Qnil;
3471
3472 for (i = 0; i < num_files; i++)
3473 {
3474 if (use_unicode)
3475 {
3476 eassert (DragQueryFileW (hdrop, i, NULL, 0) < MAX_PATH);
3477
3478
3479 if (DragQueryFileW (hdrop, i, name_w, MAX_PATH) == 0)
3480 continue;
3481 #ifdef NTGUI_UNICODE
3482 files = Fcons (from_unicode_buffer (name_w), files);
3483 #else
3484 filename_from_utf16 (name_w, file);
3485 files = Fcons (DECODE_FILE (build_unibyte_string (file)), files);
3486 #endif
3487 }
3488 #ifndef NTGUI_UNICODE
3489 else
3490 {
3491 eassert (DragQueryFileA (hdrop, i, NULL, 0) < MAX_PATH);
3492 if (DragQueryFileA (hdrop, i, name_a, MAX_PATH) == 0)
3493 continue;
3494 filename_from_ansi (name_a, file);
3495 files = Fcons (DECODE_FILE (build_unibyte_string (file)), files);
3496 }
3497 #endif
3498 }
3499
3500 DragFinish (hdrop);
3501
3502 XSETFRAME (frame, f);
3503 result->frame_or_window = frame;
3504 result->arg = files;
3505 return Qnil;
3506 }
3507
3508
3509 #if HAVE_W32NOTIFY
3510
3511
3512
3513 Lisp_Object
3514 w32_lispy_file_action (DWORD action)
3515 {
3516 static char unknown_fmt[] = "unknown-action(%d)";
3517 Lisp_Object retval;
3518
3519 switch (action)
3520 {
3521 case FILE_ACTION_ADDED:
3522 retval = Qadded;
3523 break;
3524 case FILE_ACTION_REMOVED:
3525 retval = Qremoved;
3526 break;
3527 case FILE_ACTION_MODIFIED:
3528 retval = Qmodified;
3529 break;
3530 case FILE_ACTION_RENAMED_OLD_NAME:
3531 retval = Qrenamed_from;
3532 break;
3533 case FILE_ACTION_RENAMED_NEW_NAME:
3534 retval = Qrenamed_to;
3535 break;
3536 default:
3537 {
3538 char buf[sizeof(unknown_fmt) - 1 + INT_STRLEN_BOUND (DWORD)];
3539
3540 sprintf (buf, unknown_fmt, action);
3541 retval = intern (buf);
3542 }
3543 break;
3544 }
3545
3546 return retval;
3547 }
3548
3549 #ifdef WINDOWSNT
3550
3551
3552
3553 static void
3554 w32_queue_notifications (struct input_event *event, W32Msg *msg,
3555 struct frame *f, int *evcount)
3556 {
3557 struct notifications_set *ns = NULL;
3558 Lisp_Object frame;
3559 int done = 0;
3560
3561
3562
3563 if (!initialized)
3564 return;
3565
3566 XSETFRAME (frame, f);
3567
3568 while (!done)
3569 {
3570 ns = NULL;
3571
3572
3573
3574
3575 enter_crit ();
3576 if (notifications_set_head->next != notifications_set_head)
3577 {
3578 ns = notifications_set_head->next;
3579 ns->prev->next = ns->next;
3580 ns->next->prev = ns->prev;
3581 }
3582 else
3583 done = 1;
3584 leave_crit();
3585
3586 if (ns)
3587 {
3588 BYTE *p = ns->notifications;
3589 FILE_NOTIFY_INFORMATION *fni = (PFILE_NOTIFY_INFORMATION)p;
3590 const DWORD min_size
3591 = offsetof (FILE_NOTIFY_INFORMATION, FileName) + sizeof(wchar_t);
3592 DWORD info_size = ns->size;
3593 Lisp_Object cs = Qutf_16le;
3594 Lisp_Object obj = w32_get_watch_object (ns->desc);
3595
3596
3597
3598
3599
3600 if (info_size
3601 && !NILP (obj) && CONSP (obj))
3602 {
3603 Lisp_Object callback = XCDR (obj);
3604
3605 while (info_size >= min_size)
3606 {
3607 Lisp_Object utf_16_fn
3608 = make_unibyte_string ((char *)fni->FileName,
3609 fni->FileNameLength);
3610
3611
3612 Lisp_Object fname
3613 = code_convert_string_norecord (utf_16_fn, cs, 0);
3614 Lisp_Object action = w32_lispy_file_action (fni->Action);
3615
3616 event->kind = FILE_NOTIFY_EVENT;
3617 event->timestamp = msg->msg.time;
3618 event->modifiers = 0;
3619 event->frame_or_window = callback;
3620 event->arg = list3 (make_pointer_integer (ns->desc),
3621 action, fname);
3622 kbd_buffer_store_event (event);
3623 (*evcount)++;
3624 if (!fni->NextEntryOffset)
3625 break;
3626 p += fni->NextEntryOffset;
3627 fni = (PFILE_NOTIFY_INFORMATION)p;
3628 info_size -= fni->NextEntryOffset;
3629 }
3630 }
3631
3632 xfree (ns->notifications);
3633 xfree (ns);
3634 }
3635 }
3636
3637 event->kind = NO_EVENT;
3638 }
3639 #endif
3640 #endif
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651 static int
3652 w32_note_mouse_movement (struct frame *frame, MSG *msg)
3653 {
3654 struct w32_display_info *dpyinfo;
3655 int mouse_x = LOWORD (msg->lParam);
3656 int mouse_y = HIWORD (msg->lParam);
3657 RECT *r;
3658
3659 if (!FRAME_OUTPUT_DATA (frame))
3660 return 0;
3661
3662 dpyinfo = FRAME_DISPLAY_INFO (frame);
3663 dpyinfo->last_mouse_movement_time = msg->time;
3664 dpyinfo->last_mouse_motion_frame = frame;
3665 dpyinfo->last_mouse_motion_x = mouse_x;
3666 dpyinfo->last_mouse_motion_y = mouse_y;
3667
3668 if (msg->hwnd != FRAME_W32_WINDOW (frame))
3669 {
3670 frame->mouse_moved = true;
3671 dpyinfo->last_mouse_scroll_bar = NULL;
3672 note_mouse_highlight (frame, -1, -1);
3673 dpyinfo->last_mouse_glyph_frame = NULL;
3674 return 1;
3675 }
3676
3677
3678 r = &dpyinfo->last_mouse_glyph;
3679 if (frame != dpyinfo->last_mouse_glyph_frame
3680 || mouse_x < r->left || mouse_x >= r->right
3681 || mouse_y < r->top || mouse_y >= r->bottom)
3682 {
3683 frame->mouse_moved = true;
3684 dpyinfo->last_mouse_scroll_bar = NULL;
3685 note_mouse_highlight (frame, mouse_x, mouse_y);
3686
3687
3688
3689
3690 remember_mouse_glyph (frame, mouse_x, mouse_y, r);
3691 dpyinfo->last_mouse_glyph_frame = frame;
3692 return 1;
3693 }
3694
3695 return 0;
3696 }
3697
3698
3699
3700
3701
3702
3703 static struct scroll_bar *w32_window_to_scroll_bar (Window, int);
3704 static void w32_scroll_bar_report_motion (struct frame **, Lisp_Object *,
3705 enum scroll_bar_part *,
3706 Lisp_Object *, Lisp_Object *,
3707 Time *);
3708 static void w32_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object *,
3709 enum scroll_bar_part *,
3710 Lisp_Object *, Lisp_Object *,
3711 Time *);
3712 static void
3713 w32_define_cursor (Window window, Emacs_Cursor cursor)
3714 {
3715 PostMessage (window, WM_EMACS_SETCURSOR, (WPARAM) cursor, 0);
3716 }
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738 static void
3739 w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
3740 enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
3741 Time *time)
3742 {
3743 struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
3744
3745 block_input ();
3746
3747 if (dpyinfo->last_mouse_scroll_bar && insist == 0)
3748 {
3749 struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
3750
3751 if (bar->horizontal)
3752 w32_horizontal_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
3753 else
3754 w32_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
3755 }
3756 else
3757 {
3758 POINT pt;
3759 Lisp_Object frame, tail;
3760 struct frame *f1 = NULL;
3761
3762
3763 FOR_EACH_FRAME (tail, frame)
3764 XFRAME (frame)->mouse_moved = false;
3765
3766 dpyinfo->last_mouse_scroll_bar = NULL;
3767
3768 GetCursorPos (&pt);
3769
3770
3771
3772
3773
3774
3775
3776
3777 if (gui_mouse_grabbed (dpyinfo) && !EQ (track_mouse, Qdropping))
3778 f1 = dpyinfo->last_mouse_frame;
3779 else
3780 {
3781 HWND wfp = WindowFromPoint (pt);
3782
3783 if (wfp)
3784 {
3785 f1 = w32_window_to_frame (dpyinfo, wfp);
3786 if (f1)
3787 {
3788 HWND cwfp = ChildWindowFromPoint (wfp, pt);
3789
3790 if (cwfp)
3791 {
3792 struct frame *f2 = w32_window_to_frame (dpyinfo, cwfp);
3793
3794
3795
3796 if (f2 && FRAME_PARENT_FRAME (f2))
3797 f1 = f2;
3798 }
3799 }
3800 }
3801 }
3802
3803 if (!f1 || FRAME_TOOLTIP_P (f1))
3804
3805 f1 = ((EQ (track_mouse, Qdropping) && gui_mouse_grabbed (dpyinfo))
3806 ? dpyinfo->last_mouse_frame
3807 : NULL);
3808
3809
3810 if (!f1)
3811 {
3812 struct scroll_bar *bar
3813 = w32_window_to_scroll_bar (WindowFromPoint (pt), 2);
3814
3815 if (bar)
3816 f1 = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
3817 }
3818
3819 if (!f1 && insist > 0)
3820 f1 = SELECTED_FRAME ();
3821
3822 if (f1)
3823 {
3824
3825
3826
3827
3828
3829
3830
3831
3832 dpyinfo = FRAME_DISPLAY_INFO (f1);
3833 ScreenToClient (FRAME_W32_WINDOW (f1), &pt);
3834 remember_mouse_glyph (f1, pt.x, pt.y, &dpyinfo->last_mouse_glyph);
3835 dpyinfo->last_mouse_glyph_frame = f1;
3836
3837 *bar_window = Qnil;
3838 *part = scroll_bar_above_handle;
3839 *fp = f1;
3840 XSETINT (*x, pt.x);
3841 XSETINT (*y, pt.y);
3842 *time = dpyinfo->last_mouse_movement_time;
3843 }
3844 }
3845
3846 unblock_input ();
3847 }
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858 static Lisp_Object
3859 w32_handle_tab_bar_click (struct frame *f, struct input_event *button_event)
3860 {
3861 int x = XFIXNAT (button_event->x);
3862 int y = XFIXNAT (button_event->y);
3863
3864 if (button_event->modifiers & down_modifier)
3865 return handle_tab_bar_click (f, x, y, 1, 0);
3866 else
3867 return handle_tab_bar_click (f, x, y, 0,
3868 button_event->modifiers & ~up_modifier);
3869 }
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881 static void
3882 w32_handle_tool_bar_click (struct frame *f, struct input_event *button_event)
3883 {
3884 int x = XFIXNAT (button_event->x);
3885 int y = XFIXNAT (button_event->y);
3886
3887 if (button_event->modifiers & down_modifier)
3888 handle_tool_bar_click (f, x, y, 1, 0);
3889 else
3890 handle_tool_bar_click (f, x, y, 0,
3891 button_event->modifiers & ~up_modifier);
3892 }
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906 static struct scroll_bar *
3907 w32_window_to_scroll_bar (Window window_id, int type)
3908 {
3909 Lisp_Object tail, frame;
3910
3911 FOR_EACH_FRAME (tail, frame)
3912 {
3913 Lisp_Object bar, condemned;
3914
3915
3916
3917 condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame));
3918 for (bar = FRAME_SCROLL_BARS (XFRAME (frame));
3919
3920
3921 ! NILP (bar) || (bar = condemned,
3922 condemned = Qnil,
3923 ! NILP (bar));
3924 bar = XSCROLL_BAR (bar)->next)
3925 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar)) == window_id
3926 && (type == 2
3927 || (type == 1 && XSCROLL_BAR (bar)->horizontal)
3928 || (type == 0 && !XSCROLL_BAR (bar)->horizontal)))
3929 return XSCROLL_BAR (bar);
3930 }
3931
3932 return 0;
3933 }
3934
3935
3936
3937
3938
3939
3940 static void
3941 w32_set_scroll_bar_thumb (struct scroll_bar *bar,
3942 int portion, int position, int whole)
3943 {
3944 Window w = SCROLL_BAR_W32_WINDOW (bar);
3945
3946
3947
3948 double range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height)
3949 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
3950 int sb_page, sb_pos;
3951 BOOL draggingp = bar->dragging ? TRUE : FALSE;
3952 SCROLLINFO si;
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962 if (draggingp)
3963 {
3964 int near_bottom_p;
3965 block_input ();
3966 si.cbSize = sizeof (si);
3967 si.fMask = SIF_POS | SIF_PAGE;
3968 GetScrollInfo (w, SB_CTL, &si);
3969 near_bottom_p = si.nPos + si.nPage >= range;
3970 unblock_input ();
3971 if (!near_bottom_p)
3972 return;
3973 }
3974
3975 if (whole)
3976 {
3977
3978
3979
3980 if (position + portion >= whole && !draggingp)
3981 {
3982 sb_page = range * (whole - position) / whole;
3983 sb_pos = range;
3984 }
3985 else
3986 {
3987 sb_pos = position * range / whole;
3988 sb_page = (min (portion, (whole - position)) * range) / whole;
3989 }
3990 }
3991 else
3992 {
3993 sb_page = range;
3994 sb_pos = 0;
3995 }
3996
3997 sb_page = max (sb_page, VERTICAL_SCROLL_BAR_MIN_HANDLE);
3998
3999 block_input ();
4000
4001 si.cbSize = sizeof (si);
4002 si.fMask = SIF_PAGE | SIF_POS;
4003 si.nPage = sb_page;
4004 si.nPos = sb_pos;
4005
4006 SetScrollInfo (w, SB_CTL, &si, TRUE);
4007
4008 unblock_input ();
4009 }
4010
4011
4012
4013
4014 static void
4015 w32_set_horizontal_scroll_bar_thumb (struct scroll_bar *bar,
4016 int portion, int position, int whole)
4017 {
4018 Window w = SCROLL_BAR_W32_WINDOW (bar);
4019 SCROLLINFO si;
4020
4021 block_input ();
4022
4023 si.cbSize = sizeof (si);
4024 si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
4025 si.nMin = 0;
4026 si.nMax = whole;
4027
4028
4029 si.nPage = min (portion, si.nMax) + 1;
4030 si.nPos = min (position, si.nMax);
4031 SetScrollInfo (w, SB_CTL, &si, TRUE);
4032
4033 unblock_input ();
4034 }
4035
4036
4037
4038
4039
4040
4041 static HWND
4042 my_create_vscrollbar (struct frame * f, struct scroll_bar * bar)
4043 {
4044 return (HWND) SendMessage (FRAME_W32_WINDOW (f),
4045 WM_EMACS_CREATEVSCROLLBAR, (WPARAM) f,
4046 (LPARAM) bar);
4047 }
4048
4049 static HWND
4050 my_create_hscrollbar (struct frame * f, struct scroll_bar * bar)
4051 {
4052 return (HWND) SendMessage (FRAME_W32_WINDOW (f),
4053 WM_EMACS_CREATEHSCROLLBAR, (WPARAM) f,
4054 (LPARAM) bar);
4055 }
4056
4057
4058
4059 static BOOL
4060 my_show_window (struct frame *f, HWND hwnd, int how)
4061 {
4062 #ifndef ATTACH_THREADS
4063 return SendMessageTimeout (FRAME_W32_WINDOW (f), WM_EMACS_SHOWWINDOW,
4064 (WPARAM) hwnd, (LPARAM) how, 0, 6000, NULL);
4065 #else
4066 return ShowWindow (hwnd, how);
4067 #endif
4068 }
4069
4070 static void
4071 my_set_window_pos (HWND hwnd, HWND hwndAfter,
4072 int x, int y, int cx, int cy, UINT flags)
4073 {
4074 #ifndef ATTACH_THREADS
4075 WINDOWPOS pos;
4076 pos.hwndInsertAfter = hwndAfter;
4077 pos.x = x;
4078 pos.y = y;
4079 pos.cx = cx;
4080 pos.cy = cy;
4081 pos.flags = flags;
4082 SendMessageTimeout (hwnd, WM_EMACS_SETWINDOWPOS, (WPARAM) &pos, 0,
4083 0, 6000, NULL);
4084 #else
4085 SetWindowPos (hwnd, hwndAfter, x, y, cx, cy, flags);
4086 #endif
4087 }
4088
4089 #if 0
4090 static void
4091 my_set_focus (struct frame * f, HWND hwnd)
4092 {
4093 SendMessageTimeout (FRAME_W32_WINDOW (f), WM_EMACS_SETFOCUS,
4094 (WPARAM) hwnd, 0, 0, 6000, NULL);
4095 }
4096 #endif
4097
4098 static void
4099 my_set_foreground_window (HWND hwnd)
4100 {
4101 SendMessageTimeout (hwnd, WM_EMACS_SETFOREGROUND, (WPARAM) hwnd, 0,
4102 0, 6000, NULL);
4103 }
4104
4105
4106 static void
4107 my_destroy_window (struct frame * f, HWND hwnd)
4108 {
4109 SendMessageTimeout (FRAME_W32_WINDOW (f), WM_EMACS_DESTROYWINDOW,
4110 (WPARAM) hwnd, 0, 0, 6000, NULL);
4111 }
4112
4113 static void
4114 my_bring_window_to_top (HWND hwnd)
4115 {
4116 SendMessageTimeout (hwnd, WM_EMACS_BRINGTOTOP, (WPARAM) hwnd, 0,
4117 0, 6000, NULL);
4118 }
4119
4120
4121
4122
4123
4124
4125 static struct scroll_bar *
4126 w32_scroll_bar_create (struct window *w, int left, int top,
4127 int width, int height, bool horizontal)
4128 {
4129 struct frame *f = XFRAME (WINDOW_FRAME (w));
4130 HWND hwnd;
4131 SCROLLINFO si;
4132 struct scroll_bar *bar
4133 = ALLOCATE_PSEUDOVECTOR (struct scroll_bar, w32_widget_high, PVEC_OTHER);
4134 Lisp_Object barobj;
4135
4136 block_input ();
4137
4138 XSETWINDOW (bar->window, w);
4139 bar->top = top;
4140 bar->left = left;
4141 bar->width = width;
4142 bar->height = height;
4143 bar->start = 0;
4144 bar->end = 0;
4145 bar->dragging = 0;
4146 bar->horizontal = horizontal;
4147
4148
4149
4150 if (horizontal)
4151 hwnd = my_create_hscrollbar (f, bar);
4152 else
4153 hwnd = my_create_vscrollbar (f, bar);
4154
4155 si.cbSize = sizeof (si);
4156 si.fMask = SIF_ALL;
4157 si.nMin = 0;
4158 if (horizontal)
4159 si.nMax = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, width)
4160 + HORIZONTAL_SCROLL_BAR_MIN_HANDLE;
4161 else
4162 si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
4163 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
4164 si.nPage = si.nMax;
4165 si.nPos = 0;
4166
4167 SetScrollInfo (hwnd, SB_CTL, &si, FALSE);
4168
4169 SET_SCROLL_BAR_W32_WINDOW (bar, hwnd);
4170
4171
4172 bar->next = FRAME_SCROLL_BARS (f);
4173 bar->prev = Qnil;
4174 XSETVECTOR (barobj, bar);
4175 fset_scroll_bars (f, barobj);
4176 if (! NILP (bar->next))
4177 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
4178
4179 unblock_input ();
4180
4181 return bar;
4182 }
4183
4184
4185
4186
4187
4188 static void
4189 w32_scroll_bar_remove (struct scroll_bar *bar)
4190 {
4191 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
4192
4193 block_input ();
4194
4195
4196 my_destroy_window (f, SCROLL_BAR_W32_WINDOW (bar));
4197
4198
4199 if (bar->horizontal)
4200 wset_horizontal_scroll_bar (XWINDOW (bar->window), Qnil);
4201 else
4202 wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil);
4203
4204 unblock_input ();
4205 }
4206
4207
4208
4209
4210
4211 static void
4212 w32_set_vertical_scroll_bar (struct window *w,
4213 int portion, int whole, int position)
4214 {
4215 struct frame *f = XFRAME (w->frame);
4216 Lisp_Object barobj;
4217 struct scroll_bar *bar;
4218 int top, height, left, width;
4219 int window_y, window_height;
4220
4221
4222 window_box (w, ANY_AREA, 0, &window_y, 0, &window_height);
4223 top = window_y;
4224 height = window_height;
4225
4226
4227 left = WINDOW_SCROLL_BAR_AREA_X (w);
4228 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
4229
4230
4231 if (NILP (w->vertical_scroll_bar))
4232 {
4233 HDC hdc;
4234 block_input ();
4235 if (width > 0 && height > 0)
4236 {
4237 hdc = get_frame_dc (f);
4238 w32_clear_area (f, hdc, left, top, width, height);
4239 release_frame_dc (f, hdc);
4240 }
4241 unblock_input ();
4242
4243 bar = w32_scroll_bar_create (w, left, top, width, height, false);
4244 }
4245 else
4246 {
4247
4248 HWND hwnd;
4249
4250 bar = XSCROLL_BAR (w->vertical_scroll_bar);
4251 hwnd = SCROLL_BAR_W32_WINDOW (bar);
4252
4253
4254 if (bar->left == left
4255 && bar->top == top
4256 && bar->width == width
4257 && bar->height == height)
4258 {
4259
4260 if (!my_show_window (f, hwnd, SW_NORMAL))
4261 InvalidateRect (hwnd, NULL, FALSE);
4262 }
4263 else
4264 {
4265 HDC hdc;
4266 SCROLLINFO si;
4267
4268 block_input ();
4269 if (width && height)
4270 {
4271 hdc = get_frame_dc (f);
4272
4273
4274 w32_clear_area (f, hdc, left, top, width, height);
4275 release_frame_dc (f, hdc);
4276 w32_clear_under_internal_border (f);
4277 }
4278
4279
4280 my_show_window (f, hwnd, SW_HIDE);
4281
4282
4283 SetWindowPos (hwnd, HWND_BOTTOM, left, top, width, max (height, 1),
4284 SWP_FRAMECHANGED);
4285
4286 si.cbSize = sizeof (si);
4287 si.fMask = SIF_RANGE;
4288 si.nMin = 0;
4289 si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
4290 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
4291
4292 SetScrollInfo (hwnd, SB_CTL, &si, FALSE);
4293
4294 my_show_window (f, hwnd, SW_NORMAL);
4295
4296
4297
4298 bar->left = left;
4299 bar->top = top;
4300 bar->width = width;
4301 bar->height = height;
4302
4303 unblock_input ();
4304 }
4305 }
4306 w32_set_scroll_bar_thumb (bar, portion, position, whole);
4307 XSETVECTOR (barobj, bar);
4308 wset_vertical_scroll_bar (w, barobj);
4309 }
4310
4311
4312
4313
4314
4315 static void
4316 w32_set_horizontal_scroll_bar (struct window *w,
4317 int portion, int whole, int position)
4318 {
4319 struct frame *f = XFRAME (w->frame);
4320 Lisp_Object barobj;
4321 struct scroll_bar *bar;
4322 int top, height, left, width;
4323 int window_x, window_width;
4324 int clear_left = WINDOW_LEFT_EDGE_X (w);
4325 int clear_width = WINDOW_PIXEL_WIDTH (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
4326
4327
4328 window_box (w, ANY_AREA, &window_x, 0, &window_width, 0);
4329 left = window_x;
4330 height = WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
4331 width = window_width;
4332 top = WINDOW_SCROLL_BAR_AREA_Y (w);
4333
4334
4335 if (NILP (w->horizontal_scroll_bar))
4336 {
4337 HDC hdc;
4338 block_input ();
4339 if (width > 0 && height > 0)
4340 {
4341 hdc = get_frame_dc (f);
4342 w32_clear_area (f, hdc, clear_left, top, clear_width, height);
4343 release_frame_dc (f, hdc);
4344 }
4345 unblock_input ();
4346
4347 bar = w32_scroll_bar_create (w, left, top, width, height, true);
4348 }
4349 else
4350 {
4351
4352 HWND hwnd;
4353
4354 bar = XSCROLL_BAR (w->horizontal_scroll_bar);
4355 hwnd = SCROLL_BAR_W32_WINDOW (bar);
4356
4357
4358 if (bar->left == left && bar->top == top
4359 && bar->width == width && bar->height == height)
4360 {
4361
4362 if (!my_show_window (f, hwnd, SW_NORMAL))
4363 InvalidateRect (hwnd, NULL, FALSE);
4364 }
4365 else
4366 {
4367 HDC hdc;
4368 SCROLLINFO si;
4369
4370 block_input ();
4371 if (width && height)
4372 {
4373 hdc = get_frame_dc (f);
4374
4375
4376 w32_clear_area (f, hdc, clear_left, top, clear_width, height);
4377 release_frame_dc (f, hdc);
4378 w32_clear_under_internal_border (f);
4379 }
4380
4381
4382 my_show_window (f, hwnd, SW_HIDE);
4383
4384
4385 SetWindowPos (hwnd, HWND_BOTTOM, left, top, max (width, 1), height,
4386 SWP_FRAMECHANGED);
4387
4388
4389 si.cbSize = sizeof (si);
4390 si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
4391 si.nMin = 0;
4392 si.nMax = whole;
4393 si.nPage = min (portion, si.nMax) + 1;
4394 si.nPos = min (position, si.nMax);
4395 SetScrollInfo (hwnd, SB_CTL, &si, FALSE);
4396
4397 my_show_window (f, hwnd, SW_NORMAL);
4398
4399
4400
4401 bar->left = left;
4402 bar->top = top;
4403 bar->width = width;
4404 bar->height = height;
4405
4406 unblock_input ();
4407 }
4408 }
4409
4410 w32_set_horizontal_scroll_bar_thumb (bar, portion, position, whole);
4411 XSETVECTOR (barobj, bar);
4412 wset_horizontal_scroll_bar (w, barobj);
4413 }
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428 static void
4429 w32_condemn_scroll_bars (struct frame *frame)
4430 {
4431 if (!NILP (FRAME_SCROLL_BARS (frame)))
4432 {
4433 if (!NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
4434 {
4435
4436 Lisp_Object last = FRAME_SCROLL_BARS (frame);
4437
4438 while (!NILP (XSCROLL_BAR (last)->next))
4439 last = XSCROLL_BAR (last)->next;
4440
4441 XSCROLL_BAR (last)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
4442 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = last;
4443 }
4444
4445 fset_condemned_scroll_bars (frame, FRAME_SCROLL_BARS (frame));
4446 fset_scroll_bars (frame, Qnil);
4447 }
4448 }
4449
4450
4451
4452
4453
4454 static void
4455 w32_redeem_scroll_bar (struct window *w)
4456 {
4457 struct scroll_bar *bar;
4458 Lisp_Object barobj;
4459 struct frame *f;
4460
4461
4462 if (NILP (w->vertical_scroll_bar) && NILP (w->horizontal_scroll_bar))
4463 emacs_abort ();
4464
4465 if (!NILP (w->vertical_scroll_bar) && WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
4466 {
4467 bar = XSCROLL_BAR (w->vertical_scroll_bar);
4468
4469 f = XFRAME (WINDOW_FRAME (w));
4470 if (NILP (bar->prev))
4471 {
4472
4473
4474 if (EQ (FRAME_SCROLL_BARS (f), w->vertical_scroll_bar))
4475
4476 goto horizontal;
4477 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
4478 w->vertical_scroll_bar))
4479 fset_condemned_scroll_bars (f, bar->next);
4480 else
4481
4482
4483 emacs_abort ();
4484 }
4485 else
4486 XSCROLL_BAR (bar->prev)->next = bar->next;
4487
4488 if (! NILP (bar->next))
4489 XSCROLL_BAR (bar->next)->prev = bar->prev;
4490
4491 bar->next = FRAME_SCROLL_BARS (f);
4492 bar->prev = Qnil;
4493 XSETVECTOR (barobj, bar);
4494 fset_scroll_bars (f, barobj);
4495 if (! NILP (bar->next))
4496 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
4497 }
4498
4499 horizontal:
4500 if (!NILP (w->horizontal_scroll_bar) && WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
4501 {
4502 bar = XSCROLL_BAR (w->horizontal_scroll_bar);
4503
4504 f = XFRAME (WINDOW_FRAME (w));
4505 if (NILP (bar->prev))
4506 {
4507
4508
4509 if (EQ (FRAME_SCROLL_BARS (f), w->horizontal_scroll_bar))
4510
4511 return;
4512 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
4513 w->horizontal_scroll_bar))
4514 fset_condemned_scroll_bars (f, bar->next);
4515 else
4516
4517
4518 emacs_abort ();
4519 }
4520 else
4521 XSCROLL_BAR (bar->prev)->next = bar->next;
4522
4523 if (! NILP (bar->next))
4524 XSCROLL_BAR (bar->next)->prev = bar->prev;
4525
4526 bar->next = FRAME_SCROLL_BARS (f);
4527 bar->prev = Qnil;
4528 XSETVECTOR (barobj, bar);
4529 fset_scroll_bars (f, barobj);
4530 if (! NILP (bar->next))
4531 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
4532 }
4533 }
4534
4535
4536
4537
4538 static void
4539 w32_judge_scroll_bars (struct frame *f)
4540 {
4541 Lisp_Object bar, next;
4542
4543 bar = FRAME_CONDEMNED_SCROLL_BARS (f);
4544
4545
4546
4547 fset_condemned_scroll_bars (f, Qnil);
4548
4549 for (; ! NILP (bar); bar = next)
4550 {
4551 struct scroll_bar *b = XSCROLL_BAR (bar);
4552
4553 w32_scroll_bar_remove (b);
4554
4555 next = b->next;
4556 b->next = b->prev = Qnil;
4557 }
4558
4559
4560
4561 }
4562
4563
4564
4565
4566
4567
4568
4569
4570 static int
4571 w32_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg,
4572 struct input_event *emacs_event)
4573 {
4574 if (! WINDOWP (bar->window))
4575 emacs_abort ();
4576
4577 emacs_event->kind = SCROLL_BAR_CLICK_EVENT;
4578 emacs_event->code = 0;
4579
4580 emacs_event->modifiers = msg->dwModifiers;
4581 emacs_event->frame_or_window = bar->window;
4582 emacs_event->arg = Qnil;
4583 emacs_event->timestamp = msg->msg.time;
4584
4585 {
4586 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
4587 int y;
4588 int dragging = bar->dragging;
4589 SCROLLINFO si;
4590 int sb_event = LOWORD (msg->msg.wParam);
4591
4592 si.cbSize = sizeof (si);
4593 if (sb_event == SB_THUMBTRACK)
4594 si.fMask = SIF_TRACKPOS;
4595 else
4596 si.fMask = SIF_POS;
4597
4598 GetScrollInfo ((HWND) msg->msg.lParam, SB_CTL, &si);
4599 if (sb_event == SB_THUMBTRACK)
4600 y = si.nTrackPos;
4601 else
4602 y = si.nPos;
4603
4604 bar->dragging = 0;
4605 struct frame *f;
4606 FRAME_DISPLAY_INFO (f)->last_mouse_scroll_bar_pos = msg->msg.wParam;
4607
4608 switch (sb_event)
4609 {
4610 case SB_LINEDOWN:
4611 emacs_event->part = scroll_bar_down_arrow;
4612 break;
4613 case SB_LINEUP:
4614 emacs_event->part = scroll_bar_up_arrow;
4615 break;
4616 case SB_PAGEUP:
4617 emacs_event->part = scroll_bar_above_handle;
4618 break;
4619 case SB_PAGEDOWN:
4620 emacs_event->part = scroll_bar_below_handle;
4621 break;
4622 case SB_TOP:
4623 emacs_event->part = scroll_bar_handle;
4624 y = 0;
4625 break;
4626 case SB_BOTTOM:
4627 emacs_event->part = scroll_bar_handle;
4628 y = top_range;
4629 break;
4630 case SB_THUMBTRACK:
4631 case SB_THUMBPOSITION:
4632 bar->dragging = 1;
4633 emacs_event->part = scroll_bar_handle;
4634
4635
4636 {
4637 SCROLLINFO si;
4638
4639 si.cbSize = sizeof (si);
4640 si.fMask = SIF_POS;
4641 si.nPos = y;
4642
4643
4644 last_scroll_bar_drag_pos = y;
4645
4646 SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, FALSE);
4647 }
4648 break;
4649 case SB_ENDSCROLL:
4650
4651
4652
4653 if (dragging)
4654 {
4655 SCROLLINFO si;
4656 int start = bar->start;
4657 int end = bar->end;
4658
4659 si.cbSize = sizeof (si);
4660 si.fMask = SIF_PAGE | SIF_POS;
4661 si.nPage = end - start + VERTICAL_SCROLL_BAR_MIN_HANDLE;
4662 si.nPos = last_scroll_bar_drag_pos;
4663 SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE);
4664 }
4665
4666 FALLTHROUGH;
4667 default:
4668 emacs_event->kind = NO_EVENT;
4669 return FALSE;
4670 }
4671
4672 XSETINT (emacs_event->x, y);
4673 XSETINT (emacs_event->y, top_range);
4674
4675 return TRUE;
4676 }
4677 }
4678
4679
4680
4681
4682
4683
4684
4685
4686 static int
4687 w32_horizontal_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg,
4688 struct input_event *emacs_event)
4689 {
4690 if (! WINDOWP (bar->window))
4691 emacs_abort ();
4692
4693 emacs_event->kind = HORIZONTAL_SCROLL_BAR_CLICK_EVENT;
4694 emacs_event->code = 0;
4695
4696 emacs_event->modifiers = msg->dwModifiers;
4697 emacs_event->frame_or_window = bar->window;
4698 emacs_event->arg = Qnil;
4699 emacs_event->timestamp = msg->msg.time;
4700
4701 {
4702 int left_range = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width);
4703 int x, y;
4704 int dragging = bar->dragging;
4705 SCROLLINFO si;
4706 int sb_event = LOWORD (msg->msg.wParam);
4707
4708 si.cbSize = sizeof (si);
4709 if (sb_event == SB_THUMBTRACK)
4710 si.fMask = SIF_TRACKPOS | SIF_PAGE | SIF_RANGE;
4711 else
4712 si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
4713
4714 GetScrollInfo ((HWND) msg->msg.lParam, SB_CTL, &si);
4715 if (sb_event == SB_THUMBTRACK)
4716 x = si.nTrackPos;
4717 else
4718 x = si.nPos;
4719 y = si.nMax - si.nPage;
4720
4721 bar->dragging = 0;
4722 struct frame *f;
4723 FRAME_DISPLAY_INFO (f)->last_mouse_scroll_bar_pos = msg->msg.wParam;
4724
4725 switch (sb_event)
4726 {
4727 case SB_LINELEFT:
4728 emacs_event->part = scroll_bar_left_arrow;
4729 break;
4730 case SB_LINERIGHT:
4731 emacs_event->part = scroll_bar_right_arrow;
4732 break;
4733 case SB_PAGELEFT:
4734 emacs_event->part = scroll_bar_before_handle;
4735 break;
4736 case SB_PAGERIGHT:
4737 emacs_event->part = scroll_bar_after_handle;
4738 break;
4739 case SB_LEFT:
4740 emacs_event->part = scroll_bar_horizontal_handle;
4741 x = 0;
4742 break;
4743 case SB_RIGHT:
4744 emacs_event->part = scroll_bar_horizontal_handle;
4745 x = left_range;
4746 break;
4747 case SB_THUMBTRACK:
4748 case SB_THUMBPOSITION:
4749 bar->dragging = 1;
4750 emacs_event->part = scroll_bar_horizontal_handle;
4751
4752
4753 {
4754 SCROLLINFO si;
4755
4756 si.cbSize = sizeof (si);
4757 si.fMask = SIF_POS;
4758 si.nPos = min (x, XWINDOW (bar->window)->hscroll_whole - 1);
4759
4760
4761 last_scroll_bar_drag_pos = x;
4762
4763 SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, FALSE);
4764 }
4765 break;
4766 case SB_ENDSCROLL:
4767
4768
4769
4770 if (dragging)
4771 {
4772 SCROLLINFO si;
4773
4774 si.cbSize = sizeof (si);
4775 si.fMask = SIF_POS;
4776 si.nPos = min (last_scroll_bar_drag_pos,
4777 XWINDOW (bar->window)->hscroll_whole - 1);
4778 SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE);
4779 }
4780
4781 FALLTHROUGH;
4782 default:
4783 emacs_event->kind = NO_EVENT;
4784 return FALSE;
4785 }
4786
4787 XSETINT (emacs_event->x, x);
4788 XSETINT (emacs_event->y, y);
4789
4790 return TRUE;
4791 }
4792 }
4793
4794
4795
4796 static void
4797 w32_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
4798 enum scroll_bar_part *part,
4799 Lisp_Object *x, Lisp_Object *y,
4800 Time *time)
4801 {
4802 struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
4803 struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
4804 Window w = SCROLL_BAR_W32_WINDOW (bar);
4805 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
4806 int pos;
4807 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
4808 SCROLLINFO si;
4809 int sb_event = LOWORD (dpyinfo->last_mouse_scroll_bar_pos);
4810
4811 block_input ();
4812
4813 *fp = f;
4814 *bar_window = bar->window;
4815
4816 si.cbSize = sizeof (si);
4817 if (sb_event == SB_THUMBTRACK)
4818 si.fMask = SIF_TRACKPOS | SIF_PAGE | SIF_RANGE;
4819 else
4820 si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
4821
4822 GetScrollInfo (w, SB_CTL, &si);
4823 if (sb_event == SB_THUMBTRACK)
4824 pos = si.nTrackPos;
4825 else
4826 pos = si.nPos;
4827 top_range = si.nMax - si.nPage + 1;
4828
4829 *part = scroll_bar_handle;
4830 if (sb_event == SB_LINEDOWN)
4831 pos++;
4832
4833 XSETINT (*x, pos);
4834 XSETINT (*y, top_range);
4835
4836 f->mouse_moved = false;
4837 dpyinfo->last_mouse_scroll_bar = NULL;
4838
4839 *time = dpyinfo->last_mouse_movement_time;
4840
4841 unblock_input ();
4842 }
4843
4844
4845
4846 static void
4847 w32_horizontal_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
4848 enum scroll_bar_part *part,
4849 Lisp_Object *x, Lisp_Object *y,
4850 Time *time)
4851 {
4852 struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
4853 struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
4854 Window w = SCROLL_BAR_W32_WINDOW (bar);
4855 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
4856 int pos;
4857 int left_range = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width);
4858 SCROLLINFO si;
4859 int sb_event = LOWORD (dpyinfo->last_mouse_scroll_bar_pos);
4860
4861 block_input ();
4862
4863 *fp = f;
4864 *bar_window = bar->window;
4865
4866 si.cbSize = sizeof (si);
4867 if (sb_event == SB_THUMBTRACK)
4868 si.fMask = SIF_TRACKPOS | SIF_PAGE | SIF_RANGE;
4869 else
4870 si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
4871
4872 GetScrollInfo (w, SB_CTL, &si);
4873 if (sb_event == SB_THUMBTRACK)
4874 pos = si.nTrackPos;
4875 else
4876 pos = si.nPos;
4877 left_range = si.nMax - si.nPage + 1;
4878
4879 *part = scroll_bar_handle;
4880 if (sb_event == SB_LINERIGHT)
4881 pos++;
4882
4883
4884 XSETINT (*y, pos);
4885 XSETINT (*x, left_range);
4886
4887 f->mouse_moved = false;
4888 dpyinfo->last_mouse_scroll_bar = NULL;
4889
4890 *time = dpyinfo->last_mouse_movement_time;
4891
4892 unblock_input ();
4893 }
4894
4895
4896
4897
4898
4899
4900
4901 static void
4902 w32_scroll_bar_clear (struct frame *f)
4903 {
4904 Lisp_Object bar;
4905
4906
4907
4908
4909
4910 if (!w32_disable_double_buffering
4911 && FRAME_OUTPUT_DATA (f)->want_paint_buffer)
4912 return;
4913
4914
4915
4916
4917 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
4918 || FRAME_HAS_HORIZONTAL_SCROLL_BARS (f))
4919 for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
4920 bar = XSCROLL_BAR (bar)->next)
4921 {
4922 HWND window = SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar));
4923 HDC hdc = GetDC (window);
4924 RECT rect;
4925
4926
4927
4928 my_show_window (f, window, SW_HIDE);
4929
4930 GetClientRect (window, &rect);
4931 select_palette (f, hdc);
4932 w32_clear_rect (f, hdc, &rect);
4933 w32_clear_under_internal_border (f);
4934 deselect_palette (f, hdc);
4935
4936 ReleaseDC (window, hdc);
4937 }
4938 }
4939
4940
4941
4942
4943
4944
4945 static int temp_index;
4946 static short temp_buffer[100];
4947
4948
4949 static char dbcs_lead = 0;
4950
4951
4952 static unsigned short utf16_high;
4953 static DWORD utf16_high_modifiers;
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963 static struct frame *
4964 mouse_or_wdesc_frame (struct w32_display_info *dpyinfo, HWND wdesc)
4965 {
4966 struct frame *lm_f = (gui_mouse_grabbed (dpyinfo)
4967 ? dpyinfo->last_mouse_frame
4968 : NULL);
4969
4970 if (lm_f && !EQ (track_mouse, Qdropping))
4971 return lm_f;
4972 else
4973 {
4974 struct frame *w_f = w32_window_to_frame (dpyinfo, wdesc);
4975
4976
4977 if (!w_f || FRAME_TOOLTIP_P (w_f))
4978 return EQ (track_mouse, Qdropping) ? lm_f : NULL;
4979 else
4980
4981
4982 return w_f;
4983 }
4984 }
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005 extern void menubar_selection_callback (struct frame *, void *);
5006
5007 static int
5008 w32_read_socket (struct terminal *terminal,
5009 struct input_event *hold_quit)
5010 {
5011 int count = 0;
5012 int check_visibility = 0;
5013 W32Msg msg;
5014 struct frame *f;
5015 struct w32_display_info *dpyinfo = &one_w32_display_info;
5016 Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
5017
5018 block_input ();
5019
5020
5021 drain_message_queue ();
5022
5023
5024 while (get_next_msg (&msg, FALSE))
5025 {
5026 struct input_event inev;
5027 int do_help = 0;
5028
5029
5030
5031
5032 bool ignore_dirty_back_buffer = false;
5033
5034
5035
5036
5037
5038 f = NULL;
5039
5040 EVENT_INIT (inev);
5041 inev.kind = NO_EVENT;
5042 inev.arg = Qnil;
5043
5044 switch (msg.msg.message)
5045 {
5046 case WM_EMACS_PAINT:
5047 f = w32_window_to_frame (dpyinfo, msg.msg.hwnd);
5048
5049 if (f)
5050 {
5051 if (msg.rect.right == msg.rect.left ||
5052 msg.rect.bottom == msg.rect.top)
5053 {
5054
5055
5056 DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f,
5057 SDATA (f->name)));
5058 }
5059 else if (FRAME_VISIBLE_P (f) != 1)
5060 {
5061 bool iconified = FRAME_ICONIFIED_P (f);
5062
5063
5064 SET_FRAME_VISIBLE (f, 1);
5065 SET_FRAME_ICONIFIED (f, false);
5066 SET_FRAME_GARBAGED (f);
5067 if (!f->output_data.w32->asked_for_visible)
5068 DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f,
5069 SDATA (f->name)));
5070
5071
5072
5073 if (iconified)
5074 {
5075 inev.kind = DEICONIFY_EVENT;
5076 XSETFRAME (inev.frame_or_window, f);
5077 }
5078 }
5079 else
5080 {
5081 if (w32_disable_double_buffering
5082 || !FRAME_OUTPUT_DATA (f)->paint_buffer)
5083 {
5084
5085
5086
5087
5088
5089
5090 if (!FRAME_GARBAGED_P (f) || FRAME_PARENT_FRAME (f))
5091 {
5092 HDC hdc = get_frame_dc (f);
5093
5094 w32_clear_rect (f, hdc, &msg.rect);
5095 release_frame_dc (f, hdc);
5096 }
5097
5098 expose_frame (f,
5099 msg.rect.left,
5100 msg.rect.top,
5101 msg.rect.right - msg.rect.left,
5102 msg.rect.bottom - msg.rect.top);
5103 w32_clear_under_internal_border (f);
5104 }
5105 else
5106 w32_show_back_buffer (f);
5107 }
5108 }
5109 break;
5110
5111 case WM_INPUTLANGCHANGE:
5112
5113 f = w32_window_to_frame (dpyinfo, msg.msg.hwnd);
5114
5115
5116
5117 w32_keyboard_codepage = codepage_for_locale ((LCID)(msg.msg.lParam
5118 & 0xffff));
5119
5120 if (f)
5121 {
5122 inev.kind = LANGUAGE_CHANGE_EVENT;
5123 XSETFRAME (inev.frame_or_window, f);
5124 inev.code = w32_keyboard_codepage;
5125 inev.modifiers = msg.msg.lParam & 0xffff;
5126 }
5127 break;
5128
5129 case WM_SETTINGCHANGE:
5130
5131
5132
5133 if (msg.msg.wParam == SPI_SETWHEELSCROLLLINES)
5134 w32_get_mouse_wheel_vertical_delta ();
5135 break;
5136
5137 case WM_KEYDOWN:
5138 case WM_SYSKEYDOWN:
5139 f = w32_window_to_frame (dpyinfo, msg.msg.hwnd);
5140
5141 if (f && !FRAME_ICONIFIED_P (f))
5142 {
5143 if (!hlinfo->mouse_face_hidden && FIXNUMP (Vmouse_highlight)
5144 && !EQ (f->tab_bar_window, hlinfo->mouse_face_window)
5145 && !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
5146 {
5147 clear_mouse_face (hlinfo);
5148 hlinfo->mouse_face_hidden = true;
5149 }
5150
5151 if (temp_index == sizeof temp_buffer / sizeof (short))
5152 temp_index = 0;
5153 temp_buffer[temp_index++] = msg.msg.wParam;
5154 inev.kind = NON_ASCII_KEYSTROKE_EVENT;
5155 inev.code = msg.msg.wParam;
5156 inev.modifiers = msg.dwModifiers;
5157 XSETFRAME (inev.frame_or_window, f);
5158 inev.timestamp = msg.msg.time;
5159 }
5160 break;
5161
5162 case WM_UNICHAR:
5163 case WM_SYSCHAR:
5164 case WM_CHAR:
5165 f = w32_window_to_frame (dpyinfo, msg.msg.hwnd);
5166
5167 if (f && !FRAME_ICONIFIED_P (f))
5168 {
5169 if (!hlinfo->mouse_face_hidden && FIXNUMP (Vmouse_highlight)
5170 && !EQ (f->tab_bar_window, hlinfo->mouse_face_window)
5171 && !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
5172 {
5173 clear_mouse_face (hlinfo);
5174 hlinfo->mouse_face_hidden = true;
5175 }
5176
5177 if (temp_index == sizeof temp_buffer / sizeof (short))
5178 temp_index = 0;
5179 temp_buffer[temp_index++] = msg.msg.wParam;
5180
5181 inev.modifiers = msg.dwModifiers;
5182 XSETFRAME (inev.frame_or_window, f);
5183 inev.timestamp = msg.msg.time;
5184
5185 if (utf16_high
5186 && (msg.msg.message != WM_UNICHAR
5187 || UTF_16_HIGH_SURROGATE_P (msg.msg.wParam)))
5188 {
5189
5190
5191
5192 struct input_event inev1;
5193 inev1.modifiers = utf16_high_modifiers;
5194 inev1.code = utf16_high;
5195 inev1.timestamp = inev.timestamp;
5196 inev1.arg = Qnil;
5197 kbd_buffer_store_event_hold (&inev1, hold_quit);
5198 utf16_high = 0;
5199 utf16_high_modifiers = 0;
5200 }
5201
5202 if (msg.msg.message == WM_UNICHAR)
5203 {
5204
5205
5206
5207 if (UTF_16_HIGH_SURROGATE_P (msg.msg.wParam))
5208 {
5209 utf16_high = msg.msg.wParam;
5210 utf16_high_modifiers = inev.modifiers;
5211 inev.kind = NO_EVENT;
5212 break;
5213 }
5214 else if (UTF_16_LOW_SURROGATE_P (msg.msg.wParam)
5215 && utf16_high)
5216 {
5217 inev.code = surrogates_to_codepoint (msg.msg.wParam,
5218 utf16_high);
5219 utf16_high = 0;
5220 utf16_high_modifiers = 0;
5221 }
5222 else
5223 inev.code = msg.msg.wParam;
5224 }
5225 else if (msg.msg.wParam < 256)
5226 {
5227 wchar_t code;
5228 char dbcs[2];
5229 dbcs[0] = 0;
5230 dbcs[1] = (char) msg.msg.wParam;
5231
5232 if (dbcs_lead)
5233 {
5234 dbcs[0] = dbcs_lead;
5235 dbcs_lead = 0;
5236 if (!MultiByteToWideChar (w32_keyboard_codepage, 0,
5237 dbcs, 2, &code, 1))
5238 {
5239
5240 DebPrint (("Invalid DBCS sequence: %d %d\n",
5241 dbcs[0], dbcs[1]));
5242 inev.kind = NO_EVENT;
5243 break;
5244 }
5245 }
5246 else if (IsDBCSLeadByteEx (w32_keyboard_codepage,
5247 (BYTE) msg.msg.wParam))
5248 {
5249 dbcs_lead = (char) msg.msg.wParam;
5250 inev.kind = NO_EVENT;
5251 break;
5252 }
5253 else
5254 {
5255 if (!MultiByteToWideChar (w32_keyboard_codepage, 0,
5256 &dbcs[1], 1, &code, 1))
5257 {
5258
5259 DebPrint (("Invalid character: %d\n", dbcs[1]));
5260 inev.kind = NO_EVENT;
5261 break;
5262 }
5263 }
5264 inev.code = code;
5265 }
5266 else
5267 {
5268
5269
5270 DebPrint (("Non-byte WM_CHAR: %d\n", msg.msg.wParam));
5271 inev.kind = NO_EVENT;
5272 break;
5273 }
5274 inev.kind = inev.code < 128 ? ASCII_KEYSTROKE_EVENT
5275 : MULTIBYTE_CHAR_KEYSTROKE_EVENT;
5276 }
5277 break;
5278
5279 case WM_APPCOMMAND:
5280 f = w32_window_to_frame (dpyinfo, msg.msg.hwnd);
5281
5282 if (f && !FRAME_ICONIFIED_P (f))
5283 {
5284 if (!hlinfo->mouse_face_hidden && FIXNUMP (Vmouse_highlight)
5285 && !EQ (f->tab_bar_window, hlinfo->mouse_face_window)
5286 && !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
5287 {
5288 clear_mouse_face (hlinfo);
5289 hlinfo->mouse_face_hidden = true;
5290 }
5291
5292 if (temp_index == sizeof temp_buffer / sizeof (short))
5293 temp_index = 0;
5294 temp_buffer[temp_index++] = msg.msg.wParam;
5295 inev.kind = MULTIMEDIA_KEY_EVENT;
5296 inev.code = GET_APPCOMMAND_LPARAM (msg.msg.lParam);
5297 inev.modifiers = msg.dwModifiers;
5298 XSETFRAME (inev.frame_or_window, f);
5299 inev.timestamp = msg.msg.time;
5300 }
5301 break;
5302
5303 case WM_MOUSEMOVE:
5304
5305 {
5306 int x = LOWORD (msg.msg.lParam);
5307 int y = HIWORD (msg.msg.lParam);
5308 if (x == last_mousemove_x && y == last_mousemove_y)
5309 break;
5310 last_mousemove_x = x;
5311 last_mousemove_y = y;
5312 }
5313
5314 previous_help_echo_string = help_echo_string;
5315 help_echo_string = Qnil;
5316
5317 if (hlinfo->mouse_face_hidden)
5318 {
5319 hlinfo->mouse_face_hidden = false;
5320 clear_mouse_face (hlinfo);
5321 }
5322
5323 f = mouse_or_wdesc_frame (dpyinfo, msg.msg.hwnd);
5324 if (f)
5325 {
5326
5327
5328 if (!NILP (Vmouse_autoselect_window)
5329 && (f == XFRAME (selected_frame)
5330
5331
5332
5333 || (!NILP (focus_follows_mouse)
5334 && !FRAME_NO_ACCEPT_FOCUS (f))))
5335 {
5336 static Lisp_Object last_mouse_window;
5337 Lisp_Object window = window_from_coordinates
5338 (f, LOWORD (msg.msg.lParam), HIWORD (msg.msg.lParam), 0, 0, 0);
5339
5340
5341
5342
5343
5344 if (WINDOWP (window)
5345 && !EQ (window, last_mouse_window)
5346 && !EQ (window, selected_window))
5347 {
5348 inev.kind = SELECT_WINDOW_EVENT;
5349 inev.frame_or_window = window;
5350 }
5351
5352
5353 last_mouse_window = window;
5354 }
5355
5356 if (!w32_note_mouse_movement (f, &msg.msg))
5357 help_echo_string = previous_help_echo_string;
5358 }
5359 else
5360 {
5361
5362
5363 clear_mouse_face (hlinfo);
5364 }
5365
5366
5367
5368 #if 0
5369
5370
5371 if (help_echo_string != previous_help_echo_string ||
5372 (!NILP (help_echo_string) && !STRINGP (help_echo_string) && f->mouse_moved))
5373 #else
5374 if (!NILP (help_echo_string)
5375 || !NILP (previous_help_echo_string))
5376 do_help = 1;
5377 #endif
5378 break;
5379
5380 case WM_LBUTTONDOWN:
5381 case WM_LBUTTONUP:
5382 case WM_MBUTTONDOWN:
5383 case WM_MBUTTONUP:
5384 case WM_RBUTTONDOWN:
5385 case WM_RBUTTONUP:
5386 case WM_XBUTTONDOWN:
5387 case WM_XBUTTONUP:
5388 {
5389
5390
5391 Lisp_Object tab_bar_arg = Qnil;
5392 bool tab_bar_p = 0;
5393 bool tool_bar_p = 0;
5394 int button = 0;
5395 int up = 0;
5396
5397 f = mouse_or_wdesc_frame (dpyinfo, msg.msg.hwnd);
5398 if (f)
5399 {
5400 w32_construct_mouse_click (&inev, &msg, f);
5401
5402
5403 if (WINDOWP (f->tab_bar_window)
5404 && WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window)))
5405 {
5406 Lisp_Object window;
5407 int x = XFIXNAT (inev.x);
5408 int y = XFIXNAT (inev.y);
5409
5410 window = window_from_coordinates (f, x, y, 0, 1, 1);
5411
5412 if (EQ (window, f->tab_bar_window))
5413 {
5414 tab_bar_arg = w32_handle_tab_bar_click (f, &inev);
5415 tab_bar_p = 1;
5416 }
5417 }
5418
5419 if ((tab_bar_p && NILP (tab_bar_arg))
5420 || (dpyinfo->w32_focus_frame
5421 && f != dpyinfo->w32_focus_frame
5422
5423
5424 && !frame_ancestor_p (f, dpyinfo->w32_focus_frame)))
5425 inev.kind = NO_EVENT;
5426
5427 if (!NILP (tab_bar_arg))
5428 inev.arg = tab_bar_arg;
5429
5430
5431 if (WINDOWP (f->tool_bar_window)
5432 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
5433 {
5434 Lisp_Object window;
5435 int x = XFIXNAT (inev.x);
5436 int y = XFIXNAT (inev.y);
5437
5438 window = window_from_coordinates (f, x, y, 0, 1, 1);
5439
5440 if (EQ (window, f->tool_bar_window)
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450 && (inev.modifiers & down_modifier
5451 || f->last_tool_bar_item != -1))
5452 {
5453 w32_handle_tool_bar_click (f, &inev);
5454 tool_bar_p = 1;
5455 }
5456 }
5457
5458 if (tool_bar_p
5459 || (dpyinfo->w32_focus_frame
5460 && f != dpyinfo->w32_focus_frame
5461
5462
5463 && !frame_ancestor_p (f, dpyinfo->w32_focus_frame)))
5464 inev.kind = NO_EVENT;
5465 }
5466
5467 parse_button (msg.msg.message, HIWORD (msg.msg.wParam),
5468 &button, &up);
5469
5470 if (up)
5471 {
5472 dpyinfo->grabbed &= ~ (1 << button);
5473 }
5474 else
5475 {
5476 dpyinfo->grabbed |= (1 << button);
5477 dpyinfo->last_mouse_frame = f;
5478
5479
5480
5481
5482 if (f != 0)
5483 {
5484 f->mouse_moved = false;
5485 if (!tab_bar_p)
5486 f->last_tab_bar_item = -1;
5487 if (!tool_bar_p)
5488 f->last_tool_bar_item = -1;
5489 }
5490 }
5491 break;
5492 }
5493
5494 case WM_MOUSEWHEEL:
5495 case WM_MOUSEHWHEEL:
5496 {
5497 f = mouse_or_wdesc_frame (dpyinfo, msg.msg.hwnd);
5498 if (f)
5499 {
5500 if (!dpyinfo->w32_focus_frame
5501 || f == dpyinfo->w32_focus_frame)
5502
5503 {
5504 w32_construct_mouse_wheel (&inev, &msg, f);
5505
5506
5507
5508
5509 f->mouse_moved = false;
5510 f->last_tab_bar_item = -1;
5511 f->last_tool_bar_item = -1;
5512 dpyinfo->last_mouse_frame = f;
5513 }
5514 else if (FRAME_NO_ACCEPT_FOCUS (f)
5515 && !gui_mouse_grabbed (dpyinfo))
5516 {
5517 Lisp_Object frame1 = get_frame_param (f, Qmouse_wheel_frame);
5518 struct frame *f1 = FRAMEP (frame1) ? XFRAME (frame1) : NULL;
5519
5520 if (f1 && FRAME_LIVE_P (f1) && FRAME_W32_P (f1))
5521 {
5522 w32_construct_mouse_wheel (&inev, &msg, f1);
5523 f1->mouse_moved = false;
5524 f1->last_tab_bar_item = -1;
5525 f1->last_tool_bar_item = -1;
5526 dpyinfo->last_mouse_frame = f1;
5527 }
5528 else
5529 dpyinfo->last_mouse_frame = f;
5530 }
5531 else
5532 dpyinfo->last_mouse_frame = f;
5533 }
5534 else
5535 dpyinfo->last_mouse_frame = f;
5536 }
5537 break;
5538
5539 case WM_DROPFILES:
5540 f = w32_window_to_frame (dpyinfo, msg.msg.hwnd);
5541
5542 if (f)
5543 w32_construct_drag_n_drop (&inev, &msg, f);
5544 break;
5545
5546 case WM_HSCROLL:
5547 {
5548 struct scroll_bar *bar =
5549 w32_window_to_scroll_bar ((HWND)msg.msg.lParam, 1);
5550
5551 if (bar)
5552 w32_horizontal_scroll_bar_handle_click (bar, &msg, &inev);
5553 break;
5554 }
5555
5556 case WM_VSCROLL:
5557 {
5558 struct scroll_bar *bar =
5559 w32_window_to_scroll_bar ((HWND)msg.msg.lParam, 0);
5560
5561 if (bar)
5562 w32_scroll_bar_handle_click (bar, &msg, &inev);
5563 break;
5564 }
5565
5566 case WM_WINDOWPOSCHANGED:
5567 f = w32_window_to_frame (dpyinfo, msg.msg.hwnd);
5568 ignore_dirty_back_buffer = true;
5569
5570 if (f)
5571 {
5572 RECT rect;
5573 int width, height;
5574
5575 if (GetClientRect (msg.msg.hwnd, &rect)
5576
5577
5578
5579 && !(rect.bottom == 0
5580 && rect.top == 0
5581 && rect.left == 0
5582 && rect.right == 0))
5583 {
5584 height = rect.bottom - rect.top;
5585 width = rect.right - rect.left;
5586 if (width != FRAME_PIXEL_WIDTH (f)
5587 || height != FRAME_PIXEL_HEIGHT (f))
5588 {
5589 change_frame_size
5590 (f, width, height, false, true, false);
5591 SET_FRAME_GARBAGED (f);
5592 cancel_mouse_face (f);
5593 f->win_gravity = NorthWestGravity;
5594 }
5595 }
5596 }
5597
5598 check_visibility = 1;
5599 break;
5600
5601 case WM_ACTIVATE:
5602 case WM_ACTIVATEAPP:
5603 f = w32_window_to_frame (dpyinfo, msg.msg.hwnd);
5604 if (f)
5605 {
5606
5607
5608
5609
5610
5611
5612
5613 if ((msg.msg.message == WM_WINDOWPOSCHANGED || msg.msg.wParam)
5614 && (f->want_fullscreen & FULLSCREEN_WAIT))
5615 {
5616
5617
5618 SET_FRAME_VISIBLE (f, 1);
5619 w32fullscreen_hook (f);
5620 }
5621 }
5622
5623 check_visibility = 1;
5624 break;
5625
5626 case WM_MOVE:
5627 f = w32_window_to_frame (dpyinfo, msg.msg.hwnd);
5628
5629 if (f && FRAME_VISIBLE_P (f) && !FRAME_ICONIFIED_P(f)
5630 && !FRAME_TOOLTIP_P (f))
5631 {
5632 w32_real_positions (f, &f->left_pos, &f->top_pos);
5633 inev.kind = MOVE_FRAME_EVENT;
5634 XSETFRAME (inev.frame_or_window, f);
5635 }
5636
5637 check_visibility = 1;
5638 break;
5639
5640 case WM_SHOWWINDOW:
5641
5642
5643
5644 if (!msg.msg.wParam && msg.msg.hwnd == tip_window)
5645 {
5646 tip_window = NULL;
5647 gui_redo_mouse_highlight (dpyinfo);
5648 }
5649
5650
5651
5652
5653
5654 #if 0
5655 if (msg.msg.lParam != 0)
5656 check_visibility = 1;
5657 else
5658 {
5659 f = w32_window_to_frame (dpyinfo, msg.msg.hwnd);
5660 f->async_visible = msg.msg.wParam;
5661 }
5662 #endif
5663
5664 f = w32_window_to_frame (dpyinfo, msg.msg.hwnd);
5665 if (f)
5666 w32_clear_under_internal_border (f);
5667
5668 check_visibility = 1;
5669 break;
5670
5671 case WM_SIZE:
5672 f = w32_window_to_frame (dpyinfo, msg.msg.hwnd);
5673
5674
5675 if (f)
5676 {
5677 switch (msg.msg.wParam)
5678 {
5679 case SIZE_MINIMIZED:
5680 SET_FRAME_VISIBLE (f, 0);
5681 SET_FRAME_ICONIFIED (f, true);
5682
5683 inev.kind = ICONIFY_EVENT;
5684 XSETFRAME (inev.frame_or_window, f);
5685 break;
5686
5687 case SIZE_MAXIMIZED:
5688 {
5689 bool iconified = FRAME_ICONIFIED_P (f);
5690 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
5691
5692 SET_FRAME_VISIBLE (f, 1);
5693 SET_FRAME_ICONIFIED (f, false);
5694
5695
5696
5697 SET_FRAME_GARBAGED (f);
5698
5699 if (iconified)
5700 {
5701 int x, y;
5702
5703
5704
5705
5706
5707
5708 w32_real_positions (f, &x, &y);
5709 f->left_pos = x;
5710 f->top_pos = y;
5711
5712 inev.kind = DEICONIFY_EVENT;
5713 XSETFRAME (inev.frame_or_window, f);
5714 }
5715
5716
5717
5718
5719
5720
5721 if (EQ (fullscreen, Qfullwidth) || EQ (fullscreen, Qfullheight)
5722 || NILP (fullscreen))
5723 {
5724 int x, y;
5725
5726 w32_real_positions (f, &x, &y);
5727 if (x < 0 || y < 0)
5728 store_frame_param (f, Qfullscreen, Qmaximized);
5729 }
5730 }
5731
5732 break;
5733
5734 case SIZE_RESTORED:
5735 {
5736 bool iconified = FRAME_ICONIFIED_P (f);
5737
5738
5739
5740
5741
5742 if (iconified)
5743 SET_FRAME_VISIBLE (f, 1);
5744 SET_FRAME_ICONIFIED (f, false);
5745
5746
5747
5748 SET_FRAME_GARBAGED (f);
5749
5750 if (iconified)
5751 {
5752
5753
5754
5755
5756
5757 w32_real_positions (f, &f->left_pos, &f->top_pos);
5758
5759 inev.kind = DEICONIFY_EVENT;
5760 XSETFRAME (inev.frame_or_window, f);
5761 }
5762 }
5763
5764 if (EQ (get_frame_param (f, Qfullscreen), Qmaximized))
5765 store_frame_param (f, Qfullscreen, Qnil);
5766
5767 break;
5768 }
5769 }
5770
5771 if (f && !FRAME_ICONIFIED_P (f) && msg.msg.wParam != SIZE_MINIMIZED)
5772 {
5773 RECT rect;
5774 int width, height;
5775
5776 if (GetClientRect (msg.msg.hwnd, &rect)
5777
5778
5779
5780 && !(rect.bottom == 0
5781 && rect.top == 0
5782 && rect.left == 0
5783 && rect.right == 0))
5784 {
5785 height = rect.bottom - rect.top;
5786 width = rect.right - rect.left;
5787
5788 if (width != FRAME_PIXEL_WIDTH (f)
5789 || height != FRAME_PIXEL_HEIGHT (f))
5790 {
5791 w32_release_paint_buffer (f);
5792
5793 change_frame_size
5794 (f, width, height, false, true, false);
5795 SET_FRAME_GARBAGED (f);
5796 cancel_mouse_face (f);
5797 f->win_gravity = NorthWestGravity;
5798 }
5799 }
5800 }
5801
5802 check_visibility = 1;
5803 break;
5804
5805 case WM_MOUSELEAVE:
5806 f = w32_window_to_frame (dpyinfo, msg.msg.hwnd);
5807 if (f)
5808 {
5809 if (f == hlinfo->mouse_face_mouse_frame)
5810 {
5811
5812
5813 clear_mouse_face (hlinfo);
5814 hlinfo->mouse_face_mouse_frame = 0;
5815 }
5816
5817
5818
5819
5820
5821 if (any_help_event_p)
5822 do_help = -1;
5823 }
5824
5825 break;
5826
5827 case WM_SETFOCUS:
5828 w32_detect_focus_change (dpyinfo, &msg, &inev);
5829
5830 dpyinfo->grabbed = 0;
5831 check_visibility = 1;
5832 break;
5833
5834 case WM_KILLFOCUS:
5835 w32_detect_focus_change (dpyinfo, &msg, &inev);
5836 f = w32_window_to_frame (dpyinfo, msg.msg.hwnd);
5837
5838 if (f)
5839 {
5840 if (f == hlinfo->mouse_face_mouse_frame)
5841 {
5842
5843
5844 clear_mouse_face (hlinfo);
5845 hlinfo->mouse_face_mouse_frame = 0;
5846 }
5847
5848
5849
5850
5851
5852 if (any_help_event_p)
5853 do_help = -1;
5854 }
5855
5856 dpyinfo->grabbed = 0;
5857 check_visibility = 1;
5858 break;
5859
5860 case WM_CLOSE:
5861 f = w32_window_to_frame (dpyinfo, msg.msg.hwnd);
5862
5863 if (f)
5864 {
5865 inev.kind = DELETE_WINDOW_EVENT;
5866 XSETFRAME (inev.frame_or_window, f);
5867 }
5868 break;
5869
5870 case WM_ENDSESSION:
5871 inev.kind = END_SESSION_EVENT;
5872 break;
5873
5874 case WM_INITMENU:
5875 f = w32_window_to_frame (dpyinfo, msg.msg.hwnd);
5876
5877 if (f)
5878 {
5879 inev.kind = MENU_BAR_ACTIVATE_EVENT;
5880 XSETFRAME (inev.frame_or_window, f);
5881 }
5882 break;
5883
5884 case WM_COMMAND:
5885 f = w32_window_to_frame (dpyinfo, msg.msg.hwnd);
5886
5887 if (f)
5888 {
5889 menubar_selection_callback (f, (void *)msg.msg.wParam);
5890 }
5891
5892 check_visibility = 1;
5893 break;
5894
5895 case WM_DISPLAYCHANGE:
5896 f = w32_window_to_frame (dpyinfo, msg.msg.hwnd);
5897
5898 if (f)
5899 {
5900 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
5901
5902 dpyinfo->n_cbits = msg.msg.wParam;
5903
5904
5905
5906 if (!NILP (fullscreen))
5907 {
5908 gui_set_fullscreen (f, fullscreen, fullscreen);
5909 w32fullscreen_hook (f);
5910 }
5911
5912 DebPrint (("display change: %d %d\n",
5913 (short) LOWORD (msg.msg.lParam),
5914 (short) HIWORD (msg.msg.lParam)));
5915 }
5916
5917
5918
5919
5920
5921
5922 {
5923 union buffered_input_event *ev;
5924
5925 ev = (kbd_store_ptr == kbd_buffer
5926 ? kbd_buffer + KBD_BUFFER_SIZE - 1
5927 : kbd_store_ptr - 1);
5928
5929 if (kbd_store_ptr != kbd_fetch_ptr
5930 && ev->ie.kind == MONITORS_CHANGED_EVENT
5931 && XTERMINAL (ev->ie.arg) == dpyinfo->terminal)
5932
5933
5934 break;
5935
5936 inev.kind = MONITORS_CHANGED_EVENT;
5937 XSETTERMINAL (inev.arg, dpyinfo->terminal);
5938 }
5939
5940 check_visibility = 1;
5941 break;
5942
5943 #if HAVE_W32NOTIFY
5944 case WM_EMACS_FILENOTIFY:
5945 f = w32_window_to_frame (dpyinfo, msg.msg.hwnd);
5946 if (f)
5947 w32_queue_notifications (&inev, &msg, f, &count);
5948 break;
5949 #endif
5950
5951 default:
5952
5953 if (msg.msg.message == msh_mousewheel)
5954 {
5955
5956 msg.msg.message = WM_MOUSEWHEEL;
5957 prepend_msg (&msg);
5958 }
5959 break;
5960 }
5961
5962 if (inev.kind != NO_EVENT)
5963 {
5964 kbd_buffer_store_event_hold (&inev, hold_quit);
5965 count++;
5966 }
5967
5968 if (do_help
5969 && !(hold_quit && hold_quit->kind != NO_EVENT))
5970 {
5971 Lisp_Object frame;
5972
5973 if (f)
5974 XSETFRAME (frame, f);
5975 else
5976 frame = Qnil;
5977
5978 if (do_help > 0)
5979 {
5980 if (NILP (help_echo_string))
5981 {
5982 help_echo_object = help_echo_window = Qnil;
5983 help_echo_pos = -1;
5984 }
5985
5986 any_help_event_p = 1;
5987 gen_help_event (help_echo_string, frame, help_echo_window,
5988 help_echo_object, help_echo_pos);
5989 }
5990 else
5991 {
5992 help_echo_string = Qnil;
5993 gen_help_event (Qnil, frame, Qnil, Qnil, 0);
5994 }
5995 count++;
5996 }
5997
5998
5999
6000
6001
6002 if (f && !w32_disable_double_buffering
6003 && FRAME_OUTPUT_DATA (f)->paint_buffer_dirty
6004 && !f->garbaged && !ignore_dirty_back_buffer)
6005 w32_show_back_buffer (f);
6006 }
6007
6008
6009
6010 if (dpyinfo->w32_pending_autoraise_frame)
6011 {
6012 w32_raise_frame (dpyinfo->w32_pending_autoraise_frame);
6013 dpyinfo->w32_pending_autoraise_frame = NULL;
6014 }
6015
6016
6017
6018
6019
6020
6021 if (count > 0 || check_visibility)
6022 {
6023 Lisp_Object tail, frame;
6024
6025 FOR_EACH_FRAME (tail, frame)
6026 {
6027 struct frame *f = XFRAME (frame);
6028
6029
6030 if (FRAME_TOOLTIP_P (f))
6031 continue;
6032
6033
6034
6035
6036 if (FRAME_W32_P (f) && FRAME_VISIBLE_P (f))
6037 {
6038 RECT clipbox;
6039 HDC hdc;
6040 bool obscured;
6041
6042 enter_crit ();
6043
6044
6045
6046
6047
6048
6049 hdc = GetWindowDC (FRAME_W32_WINDOW (f));
6050 GetClipBox (hdc, &clipbox);
6051 ReleaseDC (FRAME_W32_WINDOW (f), hdc);
6052 leave_crit ();
6053
6054 obscured = FRAME_OBSCURED_P (f);
6055
6056 if (clipbox.right == clipbox.left || clipbox.bottom == clipbox.top)
6057 {
6058
6059
6060
6061 SET_FRAME_VISIBLE (f, 2);
6062
6063 if (!obscured)
6064 DebPrint (("frame %p (%s) obscured\n", f, SDATA (f->name)));
6065 }
6066 else
6067 {
6068
6069 SET_FRAME_VISIBLE (f, 1);
6070
6071 if (obscured)
6072 {
6073 SET_FRAME_GARBAGED (f);
6074 DebPrint (("obscured frame %p (%s) found to be visible\n",
6075 f, SDATA (f->name)));
6076 }
6077 }
6078 }
6079 }
6080 }
6081
6082 unblock_input ();
6083 return count;
6084 }
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099 static void
6100 w32_clip_to_row (struct window *w, struct glyph_row *row,
6101 enum glyph_row_area area, HDC hdc)
6102 {
6103 RECT clip_rect;
6104 int window_x, window_y, window_width;
6105
6106 window_box (w, area, &window_x, &window_y, &window_width, 0);
6107
6108 clip_rect.left = window_x;
6109 clip_rect.top = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
6110 clip_rect.top = max (clip_rect.top, window_y);
6111 clip_rect.right = clip_rect.left + window_width;
6112 clip_rect.bottom = clip_rect.top + row->visible_height;
6113
6114 w32_set_clip_rectangle (hdc, &clip_rect);
6115 }
6116
6117
6118
6119
6120 static void
6121 w32_draw_hollow_cursor (struct window *w, struct glyph_row *row)
6122 {
6123 struct frame *f = XFRAME (WINDOW_FRAME (w));
6124 HDC hdc;
6125 RECT rect;
6126 int left, top, h;
6127 struct glyph *cursor_glyph;
6128 HBRUSH hb = CreateSolidBrush (f->output_data.w32->cursor_pixel);
6129
6130
6131
6132 cursor_glyph = get_phys_cursor_glyph (w);
6133 if (cursor_glyph == NULL)
6134 {
6135 DeleteObject (hb);
6136 return;
6137 }
6138
6139
6140 get_phys_cursor_geometry (w, row, cursor_glyph, &left, &top, &h);
6141 rect.left = left;
6142
6143
6144
6145 if ((cursor_glyph->resolved_level & 1) != 0
6146 && cursor_glyph->pixel_width > w->phys_cursor_width)
6147 rect.left += cursor_glyph->pixel_width - w->phys_cursor_width;
6148 rect.top = top;
6149 rect.bottom = rect.top + h;
6150 rect.right = rect.left + w->phys_cursor_width;
6151
6152 hdc = get_frame_dc (f);
6153
6154 w32_clip_to_row (w, row, TEXT_AREA, hdc);
6155 FrameRect (hdc, &rect, hb);
6156 DeleteObject (hb);
6157 w32_set_clip_rectangle (hdc, NULL);
6158 release_frame_dc (f, hdc);
6159 }
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169 static void
6170 w32_draw_bar_cursor (struct window *w, struct glyph_row *row,
6171 int width, enum text_cursor_kinds kind)
6172 {
6173 struct frame *f = XFRAME (w->frame);
6174 struct glyph *cursor_glyph;
6175
6176
6177
6178
6179 cursor_glyph = get_phys_cursor_glyph (w);
6180 if (cursor_glyph == NULL)
6181 return;
6182
6183
6184
6185
6186 if (cursor_glyph->type == IMAGE_GLYPH)
6187 {
6188 struct glyph_row *row;
6189 row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
6190 draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
6191 }
6192 else
6193 {
6194 COLORREF cursor_color = f->output_data.w32->cursor_pixel;
6195 struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
6196 int x;
6197 HDC hdc;
6198
6199
6200
6201
6202
6203
6204 if (face->background == cursor_color)
6205 cursor_color = face->foreground;
6206
6207 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
6208
6209 hdc = get_frame_dc (f);
6210 w32_clip_to_row (w, row, TEXT_AREA, hdc);
6211
6212 if (kind == BAR_CURSOR)
6213 {
6214 if (width < 0)
6215 width = FRAME_CURSOR_WIDTH (f);
6216 width = min (cursor_glyph->pixel_width, width);
6217
6218 w->phys_cursor_width = width;
6219
6220
6221
6222 if ((cursor_glyph->resolved_level & 1) != 0)
6223 x += cursor_glyph->pixel_width - width;
6224
6225 w32_fill_area (f, hdc, cursor_color, x,
6226 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
6227 width, row->height);
6228 }
6229 else
6230 {
6231 int dummy_x, dummy_y, dummy_h;
6232
6233 if (width < 0)
6234 width = row->height;
6235
6236 width = min (row->height, width);
6237
6238 get_phys_cursor_geometry (w, row, cursor_glyph, &dummy_x,
6239 &dummy_y, &dummy_h);
6240 if ((cursor_glyph->resolved_level & 1) != 0
6241 && cursor_glyph->pixel_width > w->phys_cursor_width)
6242 x += cursor_glyph->pixel_width - w->phys_cursor_width;
6243 w32_fill_area (f, hdc, cursor_color, x,
6244 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
6245 row->height - width),
6246 w->phys_cursor_width, width);
6247 }
6248
6249 w32_set_clip_rectangle (hdc, NULL);
6250 release_frame_dc (f, hdc);
6251 }
6252 }
6253
6254
6255
6256
6257 static void
6258 w32_define_frame_cursor (struct frame *f, Emacs_Cursor cursor)
6259 {
6260 w32_define_cursor (FRAME_W32_WINDOW (f), cursor);
6261 }
6262
6263
6264
6265
6266 static void
6267 w32_clear_frame_area (struct frame *f, int x, int y, int width, int height)
6268 {
6269 HDC hdc;
6270
6271 hdc = get_frame_dc (f);
6272 w32_clear_area (f, hdc, x, y, width, height);
6273 release_frame_dc (f, hdc);
6274 }
6275
6276
6277
6278 static void
6279 w32_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
6280 int x, int y, enum text_cursor_kinds cursor_type,
6281 int cursor_width, bool on_p, bool active_p)
6282 {
6283 if (on_p)
6284 {
6285
6286
6287 if (w32_use_visible_system_caret)
6288 {
6289
6290
6291
6292 if (w->phys_cursor_type != NO_CURSOR)
6293 erase_phys_cursor (w);
6294
6295 cursor_type = w->phys_cursor_type = NO_CURSOR;
6296 w->phys_cursor_width = -1;
6297 }
6298 else
6299 {
6300 w->phys_cursor_type = cursor_type;
6301 }
6302
6303 w->phys_cursor_on_p = true;
6304
6305
6306
6307
6308 if (active_p)
6309 {
6310 struct frame *f = XFRAME (WINDOW_FRAME (w));
6311 HWND hwnd = FRAME_W32_WINDOW (f);
6312
6313 w32_system_caret_x
6314 = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
6315 w32_system_caret_y
6316 = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
6317 + glyph_row->ascent - w->phys_cursor_ascent);
6318 w32_system_caret_window = w;
6319 w32_system_caret_hdr_height = WINDOW_TAB_LINE_HEIGHT (w)
6320 + WINDOW_HEADER_LINE_HEIGHT (w);
6321 w32_system_caret_mode_height = WINDOW_MODE_LINE_HEIGHT (w);
6322
6323 PostMessage (hwnd, WM_IME_STARTCOMPOSITION, 0, 0);
6324
6325
6326
6327 if (w32_system_caret_hwnd
6328 && (w32_system_caret_height != w->phys_cursor_height))
6329 PostMessage (hwnd, WM_EMACS_DESTROY_CARET, 0, 0);
6330
6331 w32_system_caret_height = w->phys_cursor_height;
6332
6333
6334 PostMessage (hwnd, WM_EMACS_TRACK_CARET, 0, 0);
6335 }
6336
6337 if (glyph_row->exact_window_width_line_p
6338 && (glyph_row->reversed_p
6339 ? (w->phys_cursor.hpos < 0)
6340 : (w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])))
6341 {
6342 glyph_row->cursor_in_fringe_p = true;
6343 draw_fringe_bitmap (w, glyph_row, glyph_row->reversed_p);
6344 return;
6345 }
6346
6347 switch (cursor_type)
6348 {
6349 case HOLLOW_BOX_CURSOR:
6350 w32_draw_hollow_cursor (w, glyph_row);
6351 break;
6352
6353 case FILLED_BOX_CURSOR:
6354 draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
6355 break;
6356
6357 case BAR_CURSOR:
6358 w32_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
6359 break;
6360
6361 case HBAR_CURSOR:
6362 w32_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
6363 break;
6364
6365 case NO_CURSOR:
6366 w->phys_cursor_width = 0;
6367 break;
6368
6369 default:
6370 emacs_abort ();
6371 }
6372 }
6373 }
6374
6375
6376
6377
6378
6379 static bool
6380 w32_bitmap_icon (struct frame *f, Lisp_Object icon)
6381 {
6382 HANDLE main_icon;
6383 HANDLE small_icon = NULL;
6384
6385 if (FRAME_W32_WINDOW (f) == 0)
6386 return 1;
6387
6388 if (NILP (icon))
6389 main_icon = LoadIcon (hinst, EMACS_CLASS);
6390 else if (STRINGP (icon))
6391 {
6392
6393 main_icon = LoadImage (NULL, (LPCTSTR) SDATA (icon), IMAGE_ICON, 0, 0,
6394 LR_DEFAULTSIZE | LR_LOADFROMFILE);
6395
6396 small_icon = LoadImage (NULL, (LPCSTR) SDATA (icon), IMAGE_ICON,
6397 GetSystemMetrics (SM_CXSMICON),
6398 GetSystemMetrics (SM_CYSMICON),
6399 LR_LOADFROMFILE);
6400 }
6401 else if (SYMBOLP (icon))
6402 {
6403 LPCTSTR name;
6404
6405 if (EQ (icon, intern ("application")))
6406 name = (LPCTSTR) IDI_APPLICATION;
6407 else if (EQ (icon, intern ("hand")))
6408 name = (LPCTSTR) IDI_HAND;
6409 else if (EQ (icon, intern ("question")))
6410 name = (LPCTSTR) IDI_QUESTION;
6411 else if (EQ (icon, intern ("exclamation")))
6412 name = (LPCTSTR) IDI_EXCLAMATION;
6413 else if (EQ (icon, intern ("asterisk")))
6414 name = (LPCTSTR) IDI_ASTERISK;
6415 else if (EQ (icon, intern ("winlogo")))
6416 name = (LPCTSTR) IDI_WINLOGO;
6417 else
6418 return 1;
6419
6420 main_icon = LoadIcon (NULL, name);
6421 }
6422 else
6423 return 1;
6424
6425 if (main_icon == NULL)
6426 return 1;
6427
6428 PostMessage (FRAME_W32_WINDOW (f), WM_SETICON, (WPARAM) ICON_BIG,
6429 (LPARAM) main_icon);
6430
6431
6432 if (small_icon)
6433 PostMessage (FRAME_W32_WINDOW (f), WM_SETICON, (WPARAM) ICON_SMALL,
6434 (LPARAM) small_icon);
6435
6436 return 0;
6437 }
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467 static Lisp_Object
6468 w32_new_font (struct frame *f, Lisp_Object font_object, int fontset)
6469 {
6470 struct font *font = XFONT_OBJECT (font_object);
6471 int unit, font_ascent, font_descent;
6472
6473 if (fontset < 0)
6474 fontset = fontset_from_font (font_object);
6475 FRAME_FONTSET (f) = fontset;
6476 if (FRAME_FONT (f) == font)
6477
6478
6479 return font_object;
6480
6481 FRAME_FONT (f) = font;
6482 FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
6483 FRAME_COLUMN_WIDTH (f) = unit = font->average_width;
6484 get_font_ascent_descent (font, &font_ascent, &font_descent);
6485 FRAME_LINE_HEIGHT (f) = font_ascent + font_descent;
6486
6487
6488 unit = FRAME_COLUMN_WIDTH (f);
6489 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
6490 FRAME_CONFIG_SCROLL_BAR_COLS (f)
6491 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + unit - 1) / unit;
6492 else
6493 {
6494 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit;
6495 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) =
6496 FRAME_CONFIG_SCROLL_BAR_COLS (f) * unit;
6497 }
6498
6499 FRAME_TAB_BAR_HEIGHT (f) = FRAME_TAB_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
6500
6501
6502
6503
6504 if (FRAME_NATIVE_WINDOW (f) != 0 && !FRAME_TOOLTIP_P (f))
6505 adjust_frame_size
6506 (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
6507 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, false, Qfont);
6508
6509
6510
6511 return font_object;
6512 }
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533 static void
6534 w32_calc_absolute_position (struct frame *f)
6535 {
6536 int flags = f->size_hint_flags;
6537
6538
6539
6540
6541 unsigned int left_right_borders_width, top_bottom_borders_height;
6542
6543
6544
6545
6546
6547 WINDOWPLACEMENT wp = { 0 };
6548 RECT client_rect = { 0 };
6549
6550 if (GetWindowPlacement (FRAME_W32_WINDOW (f), &wp)
6551 && GetClientRect (FRAME_W32_WINDOW (f), &client_rect))
6552 {
6553 left_right_borders_width =
6554 (wp.rcNormalPosition.right - wp.rcNormalPosition.left) -
6555 (client_rect.right - client_rect.left);
6556
6557 top_bottom_borders_height =
6558 (wp.rcNormalPosition.bottom - wp.rcNormalPosition.top) -
6559 (client_rect.bottom - client_rect.top);
6560 }
6561 else
6562 {
6563
6564 left_right_borders_width = 8;
6565 top_bottom_borders_height = 32;
6566 }
6567
6568
6569
6570
6571
6572 int display_left = 0;
6573 int display_top = 0;
6574 struct frame *p = FRAME_PARENT_FRAME (f);
6575
6576 if (!p && flags & (XNegative | YNegative))
6577 {
6578 Lisp_Object list;
6579
6580 list = Fw32_display_monitor_attributes_list (Qnil);
6581 while (CONSP (list))
6582 {
6583 Lisp_Object attributes = CAR(list);
6584 Lisp_Object geometry;
6585 Lisp_Object monitor_left, monitor_top;
6586
6587 list = CDR(list);
6588
6589 geometry = Fassoc (Qgeometry, attributes, Qnil);
6590 if (!NILP (geometry))
6591 {
6592 monitor_left = Fnth (make_fixnum (1), geometry);
6593 monitor_top = Fnth (make_fixnum (2), geometry);
6594
6595 display_left = min (display_left, XFIXNUM (monitor_left));
6596 display_top = min (display_top, XFIXNUM (monitor_top));
6597 }
6598 }
6599 }
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609 if (flags & XNegative)
6610 {
6611 if (p)
6612 f->left_pos = (FRAME_PIXEL_WIDTH (p)
6613 - FRAME_PIXEL_WIDTH (f)
6614 + f->left_pos
6615 - left_right_borders_width);
6616 else
6617 f->left_pos = (w32_display_pixel_width (FRAME_DISPLAY_INFO (f))
6618 + display_left
6619 - FRAME_PIXEL_WIDTH (f)
6620 + f->left_pos
6621 - left_right_borders_width);
6622 }
6623
6624 if (flags & YNegative)
6625 {
6626 if (p)
6627 f->top_pos = (FRAME_PIXEL_HEIGHT (p)
6628 - FRAME_PIXEL_HEIGHT (f)
6629 + f->top_pos
6630 - top_bottom_borders_height);
6631 else
6632 f->top_pos = (w32_display_pixel_height (FRAME_DISPLAY_INFO (f))
6633 + display_top
6634 - FRAME_PIXEL_HEIGHT (f)
6635 + f->top_pos
6636 - top_bottom_borders_height);
6637 }
6638
6639
6640
6641 f->size_hint_flags &= ~ (XNegative | YNegative);
6642 }
6643
6644
6645
6646
6647
6648
6649
6650 static void
6651 w32_set_offset (struct frame *f, register int xoff, register int yoff,
6652 int change_gravity)
6653 {
6654 int modified_top, modified_left;
6655
6656 if (change_gravity > 0)
6657 {
6658 f->top_pos = yoff;
6659 f->left_pos = xoff;
6660 f->size_hint_flags &= ~ (XNegative | YNegative);
6661 if (xoff < 0)
6662 f->size_hint_flags |= XNegative;
6663 if (yoff < 0)
6664 f->size_hint_flags |= YNegative;
6665 f->win_gravity = NorthWestGravity;
6666 }
6667 w32_calc_absolute_position (f);
6668
6669 block_input ();
6670 w32_wm_set_size_hint (f, (long) 0, false);
6671
6672 modified_left = f->left_pos;
6673 modified_top = f->top_pos;
6674
6675 if (!FRAME_PARENT_FRAME (f))
6676 my_set_window_pos (FRAME_W32_WINDOW (f), NULL,
6677 modified_left, modified_top,
6678 0, 0,
6679 SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
6680 else
6681 my_set_window_pos (FRAME_W32_WINDOW (f), HWND_TOP,
6682 modified_left, modified_top,
6683 0, 0,
6684 SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
6685 unblock_input ();
6686 }
6687
6688 static void
6689 w32fullscreen_hook (struct frame *f)
6690 {
6691 if (FRAME_VISIBLE_P (f))
6692 {
6693 HWND hwnd = FRAME_W32_WINDOW(f);
6694 DWORD dwStyle = GetWindowLong (hwnd, GWL_STYLE);
6695 RECT rect;
6696 enum fullscreen_type prev_fsmode = FRAME_PREV_FSMODE (f);
6697
6698 block_input();
6699 f->want_fullscreen &= ~FULLSCREEN_WAIT;
6700
6701 if (FRAME_PREV_FSMODE (f) == FULLSCREEN_NONE)
6702 GetWindowPlacement (hwnd, &FRAME_NORMAL_PLACEMENT (f));
6703
6704 if (FRAME_PREV_FSMODE (f) == FULLSCREEN_BOTH)
6705 {
6706 if (!FRAME_UNDECORATED (f))
6707 SetWindowLong (hwnd, GWL_STYLE, dwStyle | WS_OVERLAPPEDWINDOW);
6708 SetWindowPlacement (hwnd, &FRAME_NORMAL_PLACEMENT (f));
6709 }
6710 else if (FRAME_PREV_FSMODE (f) == FULLSCREEN_HEIGHT
6711 || FRAME_PREV_FSMODE (f) == FULLSCREEN_WIDTH)
6712 SetWindowPlacement (hwnd, &FRAME_NORMAL_PLACEMENT (f));
6713
6714 FRAME_PREV_FSMODE (f) = f->want_fullscreen;
6715
6716 if (f->want_fullscreen == FULLSCREEN_NONE)
6717 ShowWindow (hwnd, SW_SHOWNORMAL);
6718 else if (f->want_fullscreen == FULLSCREEN_MAXIMIZED)
6719 {
6720 if (prev_fsmode == FULLSCREEN_BOTH
6721 || prev_fsmode == FULLSCREEN_WIDTH
6722 || prev_fsmode == FULLSCREEN_HEIGHT)
6723
6724
6725 ShowWindow (hwnd, SW_SHOWNORMAL);
6726 ShowWindow (hwnd, SW_MAXIMIZE);
6727 }
6728 else if (f->want_fullscreen == FULLSCREEN_BOTH)
6729 {
6730 w32_fullscreen_rect
6731 (hwnd, f->want_fullscreen,
6732 FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect);
6733 if (!FRAME_UNDECORATED (f))
6734 SetWindowLong (hwnd, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW);
6735 SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
6736 rect.right - rect.left, rect.bottom - rect.top,
6737 SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
6738 change_frame_size
6739 (f, rect.right - rect.left, rect.bottom - rect.top,
6740 false, true, false);
6741 }
6742 else
6743 {
6744 ShowWindow (hwnd, SW_SHOWNORMAL);
6745 w32_fullscreen_rect
6746 (hwnd, f->want_fullscreen,
6747 FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect);
6748 SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
6749 rect.right - rect.left, rect.bottom - rect.top, 0);
6750
6751 change_frame_size
6752 (f, rect.right - rect.left, rect.bottom - rect.top,
6753 false, true, false);
6754 }
6755
6756 f->want_fullscreen = FULLSCREEN_NONE;
6757 unblock_input ();
6758
6759 if (f->want_fullscreen == FULLSCREEN_BOTH
6760 || f->want_fullscreen == FULLSCREEN_WIDTH
6761 || f->want_fullscreen == FULLSCREEN_HEIGHT)
6762 do_pending_window_change (0);
6763
6764 }
6765 else
6766 f->want_fullscreen |= FULLSCREEN_WAIT;
6767 }
6768
6769
6770
6771
6772
6773 static void
6774 w32_set_window_size (struct frame *f, bool change_gravity,
6775 int width, int height)
6776 {
6777 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
6778 RECT rect;
6779 MENUBARINFO info;
6780 int menu_bar_height;
6781
6782 block_input ();
6783
6784
6785
6786
6787 info.cbSize = sizeof (info);
6788 info.rcBar.top = info.rcBar.bottom = 0;
6789 GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &info);
6790 menu_bar_height = info.rcBar.bottom - info.rcBar.top;
6791
6792 if (w32_add_wrapped_menu_bar_lines)
6793 {
6794
6795
6796
6797
6798 int default_menu_bar_height;
6799
6800
6801
6802 default_menu_bar_height = GetSystemMetrics (SM_CYMENUSIZE);
6803
6804 if ((default_menu_bar_height > 0)
6805 && (menu_bar_height > default_menu_bar_height)
6806 && ((menu_bar_height % default_menu_bar_height) == 0))
6807 height = height + menu_bar_height - default_menu_bar_height;
6808 }
6809
6810 f->win_gravity = NorthWestGravity;
6811 w32_wm_set_size_hint (f, (long) 0, false);
6812
6813 rect.left = rect.top = 0;
6814 rect.right = width;
6815 rect.bottom = height;
6816
6817 AdjustWindowRect (&rect, f->output_data.w32->dwStyle, menu_bar_height > 0);
6818
6819 if (!(f->after_make_frame)
6820 && !(f->want_fullscreen & FULLSCREEN_WAIT)
6821 && FRAME_VISIBLE_P (f))
6822 {
6823 RECT window_rect;
6824
6825 GetWindowRect (FRAME_W32_WINDOW (f), &window_rect);
6826
6827 if (EQ (fullscreen, Qmaximized)
6828 || EQ (fullscreen, Qfullboth)
6829 || EQ (fullscreen, Qfullwidth))
6830 {
6831 rect.left = window_rect.left;
6832 rect.right = window_rect.right;
6833 width = -1;
6834 }
6835 if (EQ (fullscreen, Qmaximized)
6836 || EQ (fullscreen, Qfullboth)
6837 || EQ (fullscreen, Qfullheight))
6838 {
6839 rect.top = window_rect.top;
6840 rect.bottom = window_rect.bottom;
6841 height = -1;
6842 }
6843 }
6844
6845 if (width > 0 || height > 0)
6846 {
6847 if (!FRAME_PARENT_FRAME (f))
6848 my_set_window_pos (FRAME_W32_WINDOW (f), NULL,
6849 0, 0,
6850 rect.right - rect.left,
6851 rect.bottom - rect.top,
6852 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
6853 else
6854 my_set_window_pos (FRAME_W32_WINDOW (f), HWND_TOP,
6855 0, 0,
6856 rect.right - rect.left,
6857 rect.bottom - rect.top,
6858 SWP_NOMOVE | SWP_NOACTIVATE);
6859
6860 change_frame_size (f, width, height, false, true, false);
6861 SET_FRAME_GARBAGED (f);
6862
6863
6864 mark_window_cursors_off (XWINDOW (f->root_window));
6865
6866
6867
6868
6869
6870
6871 cancel_mouse_face (f);
6872 }
6873
6874 unblock_input ();
6875
6876 do_pending_window_change (false);
6877 }
6878
6879
6880
6881 void
6882 frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y)
6883 {
6884 UINT trail_num = 0;
6885 BOOL ret = false;
6886 RECT rect;
6887 POINT pt;
6888
6889 block_input ();
6890
6891 GetClientRect (FRAME_W32_WINDOW (f), &rect);
6892 pt.x = rect.left + pix_x;
6893 pt.y = rect.top + pix_y;
6894 ClientToScreen (FRAME_W32_WINDOW (f), &pt);
6895
6896
6897
6898
6899 if (os_subtype == OS_SUBTYPE_NT
6900 && w32_major_version + w32_minor_version >= 6)
6901 ret = SystemParametersInfo (SPI_GETMOUSETRAILS, 0, &trail_num, 0);
6902 SetCursorPos (pt.x, pt.y);
6903 if (ret)
6904 SystemParametersInfo (SPI_SETMOUSETRAILS, trail_num, NULL, 0);
6905
6906 unblock_input ();
6907 }
6908
6909 static Lisp_Object
6910 w32_get_focus_frame (struct frame *f)
6911 {
6912 Lisp_Object lisp_focus;
6913
6914 struct frame *focus = FRAME_DISPLAY_INFO (f)->w32_focus_frame;
6915
6916 if (!focus)
6917 return Qnil;
6918
6919 XSETFRAME (lisp_focus, focus);
6920 return lisp_focus;
6921 }
6922
6923
6924
6925
6926
6927
6928
6929
6930 static void
6931 w32_focus_frame (struct frame *f, bool noactivate)
6932 {
6933 #if 0
6934 struct w32_display_info *dpyinfo = &one_w32_display_info;
6935 #endif
6936
6937
6938 block_input ();
6939 #if 0
6940
6941 if (w32_window_to_frame (dpyinfo, GetForegroundWindow ()))
6942 my_set_focus (f, FRAME_W32_WINDOW (f));
6943 else
6944 #endif
6945 my_set_foreground_window (FRAME_W32_WINDOW (f));
6946 unblock_input ();
6947 }
6948
6949
6950 static void
6951 w32_raise_frame (struct frame *f)
6952 {
6953 block_input ();
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974 if (NILP (Vw32_grab_focus_on_raise))
6975 {
6976
6977
6978
6979
6980
6981
6982 HDWP handle = BeginDeferWindowPos (2);
6983 if (handle)
6984 {
6985 handle = DeferWindowPos (handle,
6986 FRAME_W32_WINDOW (f),
6987 HWND_TOP,
6988 0, 0, 0, 0,
6989 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
6990 if (handle)
6991 {
6992 handle = DeferWindowPos (handle,
6993 GetForegroundWindow (),
6994 FRAME_W32_WINDOW (f),
6995 0, 0, 0, 0,
6996 SWP_NOSIZE | SWP_NOMOVE |
6997 SWP_NOACTIVATE);
6998 if (handle)
6999 EndDeferWindowPos (handle);
7000 }
7001 }
7002 }
7003 else
7004 {
7005 my_bring_window_to_top (FRAME_W32_WINDOW (f));
7006 }
7007
7008 unblock_input ();
7009 }
7010
7011
7012 static void
7013 w32_lower_frame (struct frame *f)
7014 {
7015 block_input ();
7016 my_set_window_pos (FRAME_W32_WINDOW (f),
7017 HWND_BOTTOM,
7018 0, 0, 0, 0,
7019 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
7020 unblock_input ();
7021 }
7022
7023 static void
7024 w32_frame_raise_lower (struct frame *f, bool raise_flag)
7025 {
7026 if (! FRAME_W32_P (f))
7027 return;
7028
7029 if (raise_flag)
7030 w32_raise_frame (f);
7031 else
7032 w32_lower_frame (f);
7033 }
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045 void
7046 w32_make_frame_visible (struct frame *f)
7047 {
7048 block_input ();
7049
7050 gui_set_bitmap_icon (f);
7051
7052 if (! FRAME_VISIBLE_P (f))
7053 {
7054
7055
7056
7057
7058 if (! FRAME_ICONIFIED_P (f)
7059 && ! f->output_data.w32->asked_for_visible)
7060 {
7061 if (!FRAME_PARENT_FRAME (f))
7062 {
7063 RECT workarea_rect;
7064 RECT window_rect;
7065
7066
7067
7068 SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea_rect, 0);
7069 GetWindowRect (FRAME_W32_WINDOW (f), &window_rect);
7070 if (window_rect.bottom > workarea_rect.bottom
7071 && window_rect.top > workarea_rect.top)
7072 f->top_pos = max (window_rect.top
7073 - window_rect.bottom + workarea_rect.bottom,
7074 workarea_rect.top);
7075 }
7076
7077 w32_set_offset (f, f->left_pos, f->top_pos, 0);
7078 }
7079
7080 f->output_data.w32->asked_for_visible = 1;
7081
7082
7083
7084
7085
7086
7087
7088
7089 my_show_window (f, FRAME_W32_WINDOW (f),
7090 FRAME_ICONIFIED_P (f)
7091 ? SW_RESTORE
7092 : FRAME_NO_FOCUS_ON_MAP (f)
7093 ? SW_SHOWNOACTIVATE
7094 : SW_SHOWNORMAL);
7095 }
7096
7097 if (!FLOATP (Vx_wait_for_event_timeout))
7098 {
7099 unblock_input ();
7100 return;
7101 }
7102
7103
7104
7105
7106 {
7107 Lisp_Object frame;
7108 double timeout = XFLOAT_DATA (Vx_wait_for_event_timeout);
7109 double start_time = XFLOAT_DATA (Ffloat_time (Qnil));
7110
7111
7112 unblock_input ();
7113
7114 XSETFRAME (frame, f);
7115
7116
7117
7118
7119 while (timeout > (XFLOAT_DATA (Ffloat_time (Qnil)) - start_time) &&
7120 !FRAME_VISIBLE_P (f))
7121 {
7122
7123
7124
7125
7126
7127
7128
7129
7130 if (input_polling_used ())
7131 {
7132
7133
7134 int old_poll_suppress_count = poll_suppress_count;
7135 poll_suppress_count = 1;
7136 poll_for_input_1 ();
7137 poll_suppress_count = old_poll_suppress_count;
7138 }
7139 }
7140 }
7141 }
7142
7143
7144
7145
7146
7147 void
7148 w32_make_frame_invisible (struct frame *f)
7149 {
7150
7151 if (FRAME_DISPLAY_INFO (f)->highlight_frame == f)
7152 FRAME_DISPLAY_INFO (f)->highlight_frame = 0;
7153
7154 block_input ();
7155
7156 my_show_window (f, FRAME_W32_WINDOW (f), SW_HIDE);
7157
7158
7159
7160
7161
7162
7163 SET_FRAME_VISIBLE (f, 0);
7164 SET_FRAME_ICONIFIED (f, false);
7165
7166 unblock_input ();
7167 }
7168
7169 static void
7170 w32_make_frame_visible_invisible (struct frame *f, bool visible)
7171 {
7172 if (visible)
7173 w32_make_frame_visible (f);
7174 else
7175 w32_make_frame_invisible (f);
7176 }
7177
7178
7179
7180 void
7181 w32_iconify_frame (struct frame *f)
7182 {
7183
7184 if (FRAME_DISPLAY_INFO (f)->highlight_frame == f)
7185 FRAME_DISPLAY_INFO (f)->highlight_frame = 0;
7186
7187 if (FRAME_ICONIFIED_P (f))
7188 return;
7189
7190 block_input ();
7191
7192 gui_set_bitmap_icon (f);
7193
7194
7195 SendMessageTimeout (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0,
7196 0, 6000, NULL);
7197
7198 SET_FRAME_VISIBLE (f, 0);
7199 SET_FRAME_ICONIFIED (f, true);
7200
7201 unblock_input ();
7202 }
7203
7204
7205
7206
7207 void
7208 w32_free_frame_resources (struct frame *f)
7209 {
7210 struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
7211 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
7212
7213 block_input ();
7214
7215
7216
7217
7218 free_frame_faces (f);
7219
7220
7221 w32_release_paint_buffer (f);
7222
7223 if (FRAME_W32_WINDOW (f))
7224 my_destroy_window (f, FRAME_W32_WINDOW (f));
7225
7226 free_frame_menubar (f);
7227
7228 xfree (f->output_data.w32);
7229 f->output_data.w32 = NULL;
7230
7231 if (f == dpyinfo->w32_focus_frame)
7232 dpyinfo->w32_focus_frame = 0;
7233 if (f == dpyinfo->w32_focus_event_frame)
7234 dpyinfo->w32_focus_event_frame = 0;
7235 if (f == dpyinfo->highlight_frame)
7236 dpyinfo->highlight_frame = 0;
7237 if (f == hlinfo->mouse_face_mouse_frame)
7238 reset_mouse_highlight (hlinfo);
7239
7240 unblock_input ();
7241 }
7242
7243
7244
7245 static void
7246 w32_destroy_window (struct frame *f)
7247 {
7248 struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
7249
7250 w32_free_frame_resources (f);
7251 dpyinfo->reference_count--;
7252 }
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262 void
7263 w32_wm_set_size_hint (struct frame *f, long flags, bool user_position)
7264 {
7265 Window window = FRAME_W32_WINDOW (f);
7266
7267 enter_crit ();
7268
7269 SetWindowLong (window, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f));
7270 SetWindowLong (window, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f));
7271 SetWindowLong (window, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f));
7272 SetWindowLong (window, WND_VSCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_WIDTH (f));
7273 SetWindowLong (window, WND_HSCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_HEIGHT (f));
7274
7275 leave_crit ();
7276 }
7277
7278
7279
7280
7281
7282
7283 #ifdef GLYPH_DEBUG
7284
7285
7286
7287
7288 static void
7289 w32_check_font (struct frame *f, struct font *font)
7290 {
7291 eassert (font != NULL && ! NILP (font->props[FONT_TYPE_INDEX]));
7292 if (font->driver->check)
7293 eassert (font->driver->check (f, font) == 0);
7294 }
7295
7296 #endif
7297
7298
7299
7300 static void
7301 w32_show_hourglass (struct frame *f)
7302 {
7303 if (!menubar_in_use && !current_popup_menu)
7304 {
7305 struct w32_output *w32 = FRAME_OUTPUT_DATA (f);
7306
7307 w32->hourglass_p = 1;
7308 SetCursor (w32->hourglass_cursor);
7309 }
7310 }
7311
7312
7313
7314 static void
7315 w32_hide_hourglass (struct frame *f)
7316 {
7317 struct w32_output *w32 = FRAME_OUTPUT_DATA (f);
7318
7319 w32->hourglass_p = 0;
7320 if (f->pointer_invisible)
7321 SetCursor (NULL);
7322 else
7323 SetCursor (w32->current_cursor);
7324 }
7325
7326
7327
7328
7329 void
7330 w32_arrow_cursor (void)
7331 {
7332 SetCursor (w32_load_cursor (IDC_ARROW));
7333 }
7334
7335 static void
7336 w32_toggle_invisible_pointer (struct frame *f, bool invisible)
7337 {
7338 block_input ();
7339
7340 if (f->pointer_invisible != invisible)
7341 {
7342 f->pointer_invisible = invisible;
7343 w32_define_cursor (FRAME_W32_WINDOW (f),
7344 f->output_data.w32->current_cursor);
7345 }
7346
7347 unblock_input ();
7348 }
7349
7350
7351
7352
7353
7354
7355 static void
7356 w32_free_pixmap (struct frame *_f, Emacs_Pixmap pixmap)
7357 {
7358 DeleteObject (pixmap);
7359 }
7360
7361
7362
7363
7364
7365
7366 static int w32_initialized = 0;
7367
7368 void
7369 w32_initialize_display_info (Lisp_Object display_name)
7370 {
7371 struct w32_display_info *dpyinfo = &one_w32_display_info;
7372
7373 memset (dpyinfo, 0, sizeof (*dpyinfo));
7374
7375 dpyinfo->name_list_element = Fcons (display_name, Qnil);
7376 static char const title[] = "GNU Emacs";
7377 if (STRINGP (Vsystem_name))
7378 {
7379 static char const at[] = " at ";
7380 ptrdiff_t nbytes = sizeof (title) + sizeof (at);
7381 if (ckd_add (&nbytes, nbytes, SCHARS (Vsystem_name)))
7382 memory_full (SIZE_MAX);
7383 dpyinfo->w32_id_name = xmalloc (nbytes);
7384 sprintf (dpyinfo->w32_id_name, "%s%s%s", title, at, SDATA (Vsystem_name));
7385 }
7386 else
7387 {
7388 dpyinfo->w32_id_name = xmalloc (sizeof (title));
7389 strcpy (dpyinfo->w32_id_name, title);
7390 }
7391
7392
7393
7394 dpyinfo->resx = 1;
7395 dpyinfo->resy = 1;
7396 dpyinfo->n_planes = 1;
7397 dpyinfo->n_cbits = 4;
7398 dpyinfo->n_fonts = 0;
7399 dpyinfo->smallest_font_height = 1;
7400 dpyinfo->smallest_char_width = 1;
7401 dpyinfo->vertical_scroll_bar_cursor = w32_load_cursor (IDC_ARROW);
7402 dpyinfo->horizontal_scroll_bar_cursor = w32_load_cursor (IDC_ARROW);
7403
7404
7405 reset_mouse_highlight (&dpyinfo->mouse_highlight);
7406 }
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420 static char *
7421 w32_make_rdb (char *xrm_option)
7422 {
7423 char *buffer = xmalloc (strlen (xrm_option) + 2);
7424 char *current = buffer;
7425 char ch;
7426 int in_option = 1;
7427 int before_value = 0;
7428
7429 do {
7430 ch = *xrm_option++;
7431
7432 if (ch == '\n')
7433 {
7434 *current++ = '\0';
7435 in_option = 1;
7436 before_value = 0;
7437 }
7438 else if (ch != ' ')
7439 {
7440 *current++ = ch;
7441 if (in_option && (ch == ':'))
7442 {
7443 in_option = 0;
7444 before_value = 1;
7445 }
7446 else if (before_value)
7447 {
7448 before_value = 0;
7449 }
7450 }
7451 else if (!(in_option || before_value))
7452 {
7453 *current++ = ch;
7454 }
7455 } while (ch);
7456
7457 *current = '\0';
7458
7459 return buffer;
7460 }
7461
7462 extern frame_parm_handler w32_frame_parm_handlers[];
7463
7464 static struct redisplay_interface w32_redisplay_interface =
7465 {
7466 w32_frame_parm_handlers,
7467 gui_produce_glyphs,
7468 gui_write_glyphs,
7469 gui_insert_glyphs,
7470 gui_clear_end_of_line,
7471 w32_scroll_run,
7472 w32_after_update_window_line,
7473 w32_update_window_begin,
7474 w32_update_window_end,
7475 0,
7476 gui_clear_window_mouse_face,
7477 gui_get_glyph_overhangs,
7478 gui_fix_overlapping_area,
7479 w32_draw_fringe_bitmap,
7480 w32_define_fringe_bitmap,
7481 w32_destroy_fringe_bitmap,
7482 w32_compute_glyph_string_overhangs,
7483 w32_draw_glyph_string,
7484 w32_define_frame_cursor,
7485 w32_clear_frame_area,
7486 w32_clear_under_internal_border,
7487 w32_draw_window_cursor,
7488 w32_draw_vertical_window_border,
7489 w32_draw_window_divider,
7490 w32_shift_glyphs_for_insert,
7491 w32_show_hourglass,
7492 w32_hide_hourglass,
7493 w32_default_font_parameter
7494 };
7495
7496 static void w32_delete_terminal (struct terminal *term);
7497
7498 static struct terminal *
7499 w32_create_terminal (struct w32_display_info *dpyinfo)
7500 {
7501 struct terminal *terminal;
7502
7503 terminal = create_terminal (output_w32, &w32_redisplay_interface);
7504
7505 terminal->display_info.w32 = dpyinfo;
7506 dpyinfo->terminal = terminal;
7507
7508
7509
7510 terminal->clear_frame_hook = w32_clear_frame;
7511 terminal->ins_del_lines_hook = w32_ins_del_lines;
7512 terminal->delete_glyphs_hook = w32_delete_glyphs;
7513 terminal->ring_bell_hook = w32_ring_bell;
7514 terminal->toggle_invisible_pointer_hook = w32_toggle_invisible_pointer;
7515 terminal->update_begin_hook = w32_update_begin;
7516 terminal->update_end_hook = w32_update_end;
7517 terminal->read_socket_hook = w32_read_socket;
7518 terminal->frame_up_to_date_hook = w32_frame_up_to_date;
7519 terminal->buffer_flipping_unblocked_hook = w32_buffer_flipping_unblocked_hook;
7520 terminal->defined_color_hook = w32_defined_color;
7521 terminal->query_frame_background_color = w32_query_frame_background_color;
7522 terminal->query_colors = w32_query_colors;
7523 terminal->mouse_position_hook = w32_mouse_position;
7524 terminal->get_focus_frame = w32_get_focus_frame;
7525 terminal->focus_frame_hook = w32_focus_frame;
7526 terminal->frame_rehighlight_hook = w32_frame_rehighlight;
7527 terminal->frame_raise_lower_hook = w32_frame_raise_lower;
7528 terminal->frame_visible_invisible_hook = w32_make_frame_visible_invisible;
7529 terminal->fullscreen_hook = w32fullscreen_hook;
7530 terminal->iconify_frame_hook = w32_iconify_frame;
7531 terminal->set_window_size_hook = w32_set_window_size;
7532 terminal->set_frame_offset_hook = w32_set_offset;
7533 terminal->set_frame_alpha_hook = w32_set_frame_alpha;
7534 terminal->set_new_font_hook = w32_new_font;
7535 terminal->set_bitmap_icon_hook = w32_bitmap_icon;
7536 terminal->implicit_set_name_hook = w32_implicitly_set_name;
7537 terminal->menu_show_hook = w32_menu_show;
7538 terminal->activate_menubar_hook = w32_activate_menubar;
7539 terminal->popup_dialog_hook = w32_popup_dialog;
7540 terminal->change_tab_bar_height_hook = w32_change_tab_bar_height;
7541 terminal->change_tool_bar_height_hook = w32_change_tool_bar_height;
7542 terminal->set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar;
7543 terminal->set_horizontal_scroll_bar_hook = w32_set_horizontal_scroll_bar;
7544 terminal->set_scroll_bar_default_width_hook = w32_set_scroll_bar_default_width;
7545 terminal->set_scroll_bar_default_height_hook = w32_set_scroll_bar_default_height;
7546 terminal->condemn_scroll_bars_hook = w32_condemn_scroll_bars;
7547 terminal->redeem_scroll_bar_hook = w32_redeem_scroll_bar;
7548 terminal->judge_scroll_bars_hook = w32_judge_scroll_bars;
7549 terminal->get_string_resource_hook = w32_get_string_resource;
7550 terminal->free_pixmap = w32_free_pixmap;
7551 terminal->delete_frame_hook = w32_destroy_window;
7552 terminal->delete_terminal_hook = w32_delete_terminal;
7553
7554
7555
7556
7557
7558 terminal->kboard = allocate_kboard (Qw32);
7559
7560
7561
7562 if (current_kboard == initial_kboard)
7563 current_kboard = terminal->kboard;
7564 terminal->kboard->reference_count++;
7565
7566 return terminal;
7567 }
7568
7569 static void
7570 w32_delete_terminal (struct terminal *terminal)
7571 {
7572 struct w32_display_info *dpyinfo = terminal->display_info.w32;
7573
7574
7575
7576 if (!terminal->name)
7577 return;
7578
7579 block_input ();
7580
7581 w32_delete_display (dpyinfo);
7582 unblock_input ();
7583 }
7584
7585 struct w32_display_info *
7586 w32_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
7587 {
7588 struct w32_display_info *dpyinfo;
7589 struct terminal *terminal;
7590 HDC hdc;
7591
7592 block_input ();
7593
7594 if (!w32_initialized)
7595 {
7596 w32_initialize ();
7597 w32_initialized = 1;
7598 }
7599
7600 w32_initialize_display_info (display_name);
7601
7602 dpyinfo = &one_w32_display_info;
7603 terminal = w32_create_terminal (dpyinfo);
7604
7605
7606 terminal->name = xlispstrdup (display_name);
7607
7608 dpyinfo->rdb = xrm_option ? w32_make_rdb (xrm_option) : NULL;
7609
7610
7611 dpyinfo->next = x_display_list;
7612 x_display_list = dpyinfo;
7613
7614 hdc = GetDC (NULL);
7615
7616 dpyinfo->root_window = GetDesktopWindow ();
7617 dpyinfo->n_planes = GetDeviceCaps (hdc, PLANES);
7618 dpyinfo->n_cbits = GetDeviceCaps (hdc, BITSPIXEL);
7619 dpyinfo->resx = GetDeviceCaps (hdc, LOGPIXELSX);
7620 dpyinfo->resy = GetDeviceCaps (hdc, LOGPIXELSY);
7621 dpyinfo->has_palette = GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE;
7622 ReleaseDC (NULL, hdc);
7623
7624
7625 {
7626 Emacs_Color color;
7627 w32_defined_color (0, "white", &color, true, false);
7628 w32_defined_color (0, "black", &color, true, false);
7629 }
7630
7631 #ifdef WINDOWSNT
7632
7633
7634
7635 add_keyboard_wait_descriptor (0);
7636 #elif CYGWIN
7637
7638 add_keyboard_wait_descriptor (w32_message_fd);
7639 #endif
7640
7641
7642
7643
7644
7645
7646
7647
7648 gui_init_fringe (terminal->rif);
7649
7650 unblock_input ();
7651
7652 return dpyinfo;
7653 }
7654
7655
7656 void
7657 w32_delete_display (struct w32_display_info *dpyinfo)
7658 {
7659
7660
7661 {
7662 struct w32_palette_entry * plist;
7663
7664 plist = dpyinfo->color_list;
7665 while (plist)
7666 {
7667 struct w32_palette_entry * pentry = plist;
7668 plist = plist->next;
7669 xfree (pentry);
7670 }
7671 dpyinfo->color_list = NULL;
7672 if (dpyinfo->palette)
7673 DeleteObject (dpyinfo->palette);
7674 }
7675
7676 w32_reset_fringes ();
7677 }
7678
7679
7680
7681
7682 void
7683 w32_init_main_thread (void)
7684 {
7685 dwMainThreadId = GetCurrentThreadId ();
7686 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
7687 GetCurrentProcess (), &hMainThread, 0, TRUE,
7688 DUPLICATE_SAME_ACCESS);
7689
7690
7691 }
7692
7693 DWORD WINAPI w32_msg_worker (void * arg);
7694
7695 static void
7696 w32_initialize (void)
7697 {
7698 HANDLE shell;
7699 BOOL caret;
7700 HRESULT (WINAPI * set_user_model) (const wchar_t * id);
7701
7702 baud_rate = 19200;
7703
7704 w32_system_caret_hwnd = NULL;
7705 w32_system_caret_height = 0;
7706 w32_system_caret_x = 0;
7707 w32_system_caret_y = 0;
7708
7709
7710
7711
7712 shell = GetModuleHandle ("shell32.dll");
7713 if (shell)
7714 {
7715 set_user_model
7716 = (void *) GetProcAddress (shell,
7717 "SetCurrentProcessExplicitAppUserModelID");
7718
7719
7720
7721
7722
7723
7724 if (set_user_model)
7725 set_user_model (L"GNU.Emacs");
7726 }
7727
7728 #ifdef CYGWIN
7729 if ((w32_message_fd = emacs_open_noquit ("/dev/windows", O_RDWR, 0))
7730 == -1)
7731 fatal ("opening /dev/windows: %s", strerror (errno));
7732 #endif
7733
7734
7735
7736 if (SystemParametersInfo (SPI_GETSCREENREADER, 0, &caret, 0))
7737 w32_use_visible_system_caret = caret == TRUE;
7738 else
7739 w32_use_visible_system_caret = 0;
7740
7741 any_help_event_p = 0;
7742
7743
7744
7745 Fset_input_mode (Qnil, Qnil, make_fixnum (2), Qnil);
7746
7747 {
7748 LCID input_locale_id = LOWORD (GetKeyboardLayout (0));
7749 w32_keyboard_codepage = codepage_for_locale (input_locale_id);
7750 }
7751
7752
7753
7754 init_crit ();
7755
7756
7757 {
7758 MSG msg;
7759
7760 PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
7761
7762 hWindowsThread = CreateThread (NULL, 0,
7763 w32_msg_worker,
7764 0, 0, &dwWindowsThreadId);
7765
7766 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
7767 }
7768
7769
7770
7771
7772
7773
7774
7775
7776
7777 #ifdef ATTACH_THREADS
7778 AttachThreadInput (dwMainThreadId, dwWindowsThreadId, TRUE);
7779 #endif
7780
7781
7782 {
7783 HMODULE user_lib = GetModuleHandle ("user32.dll");
7784
7785 #define LOAD_PROC(lib, fn) pfn##fn = (void *) GetProcAddress (lib, #fn)
7786
7787 LOAD_PROC (user_lib, SetLayeredWindowAttributes);
7788
7789
7790 HMODULE hgdi = LoadLibrary ("gdi32.dll");
7791 if (hgdi)
7792 LOAD_PROC (hgdi, PlgBlt);
7793
7794 #undef LOAD_PROC
7795
7796
7797 vertical_scroll_bar_min_handle = 5;
7798 horizontal_scroll_bar_min_handle = 5;
7799
7800
7801
7802 vertical_scroll_bar_top_border = vertical_scroll_bar_bottom_border
7803 = GetSystemMetrics (SM_CYVSCROLL);
7804 horizontal_scroll_bar_left_border = horizontal_scroll_bar_right_border
7805 = GetSystemMetrics (SM_CYHSCROLL);
7806 }
7807
7808 w32_get_mouse_wheel_vertical_delta ();
7809 }
7810
7811 void
7812 syms_of_w32term (void)
7813 {
7814 DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
7815
7816 DEFSYM (Qadded, "added");
7817 DEFSYM (Qremoved, "removed");
7818 DEFSYM (Qmodified, "modified");
7819 DEFSYM (Qrenamed_from, "renamed-from");
7820 DEFSYM (Qrenamed_to, "renamed-to");
7821
7822 DEFVAR_LISP ("x-wait-for-event-timeout", Vx_wait_for_event_timeout,
7823 doc: );
7824 Vx_wait_for_event_timeout = make_float (0.1);
7825
7826 DEFVAR_INT ("w32-num-mouse-buttons",
7827 w32_num_mouse_buttons,
7828 doc: );
7829 w32_num_mouse_buttons = 2;
7830
7831 DEFVAR_LISP ("w32-swap-mouse-buttons",
7832 Vw32_swap_mouse_buttons,
7833 doc:
7834 );
7835 Vw32_swap_mouse_buttons = Qnil;
7836
7837 DEFVAR_LISP ("w32-grab-focus-on-raise",
7838 Vw32_grab_focus_on_raise,
7839 doc:
7840
7841
7842 );
7843 Vw32_grab_focus_on_raise = Qt;
7844
7845 DEFVAR_LISP ("w32-capslock-is-shiftlock",
7846 Vw32_capslock_is_shiftlock,
7847 doc:
7848 );
7849 Vw32_capslock_is_shiftlock = Qnil;
7850
7851 DEFVAR_LISP ("w32-recognize-altgr",
7852 Vw32_recognize_altgr,
7853 doc:
7854
7855 );
7856 Vw32_recognize_altgr = Qt;
7857
7858 DEFVAR_BOOL ("w32-use-visible-system-caret",
7859 w32_use_visible_system_caret,
7860 doc:
7861
7862
7863
7864
7865
7866
7867
7868
7869 );
7870
7871 w32_use_visible_system_caret = 0;
7872
7873
7874
7875 DEFVAR_BOOL ("x-use-underline-position-properties",
7876 x_use_underline_position_properties,
7877 doc: );
7878 x_use_underline_position_properties = 0;
7879 DEFSYM (Qx_use_underline_position_properties,
7880 "x-use-underline-position-properties");
7881
7882 DEFVAR_BOOL ("x-underline-at-descent-line",
7883 x_underline_at_descent_line,
7884 doc: );
7885 x_underline_at_descent_line = 0;
7886 DEFSYM (Qx_underline_at_descent_line, "x-underline-at-descent-line");
7887
7888 DEFVAR_LISP ("x-toolkit-scroll-bars", Vx_toolkit_scroll_bars,
7889 doc: );
7890 Vx_toolkit_scroll_bars = Qt;
7891
7892 DEFVAR_BOOL ("w32-unicode-filenames",
7893 w32_unicode_filenames,
7894 doc:
7895
7896
7897
7898
7899
7900
7901 );
7902 if (os_subtype == OS_SUBTYPE_9X)
7903 w32_unicode_filenames = 0;
7904 else
7905 w32_unicode_filenames = 1;
7906
7907 DEFVAR_BOOL ("w32-use-native-image-API",
7908 w32_use_native_image_api,
7909 doc:
7910
7911
7912
7913
7914
7915 );
7916
7917
7918
7919 #if defined WINDOWSNT && HAVE_NATIVE_IMAGE_API
7920 if (os_subtype == OS_SUBTYPE_9X)
7921 w32_use_native_image_api = 0;
7922 else
7923 w32_use_native_image_api = 1;
7924 #else
7925 w32_use_native_image_api = 0;
7926 #endif
7927
7928 DEFVAR_BOOL ("w32-yes-no-dialog-show-cancel",
7929 w32_yes_no_dialog_show_cancel,
7930 doc: );
7931 w32_yes_no_dialog_show_cancel = 1;
7932
7933
7934
7935
7936 DEFVAR_BOOL ("w32-add-wrapped-menu-bar-lines",
7937 w32_add_wrapped_menu_bar_lines,
7938 doc:
7939
7940
7941
7942
7943
7944 );
7945 w32_add_wrapped_menu_bar_lines = 1;
7946
7947
7948 Fprovide (Qw32, Qnil);
7949 }