1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
20
21 #include <config.h>
22 #include <signal.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <setjmp.h>
26 #include "lisp.h"
27 #include "blockinput.h"
28 #include "w32term.h"
29
30 #include "systty.h"
31 #include "systime.h"
32
33 #include <ctype.h>
34 #include <errno.h>
35 #include <sys/stat.h>
36 #include <imm.h>
37
38 #include "charset.h"
39 #include "character.h"
40 #include "coding.h"
41 #include "ccl.h"
42 #include "frame.h"
43 #include "dispextern.h"
44 #include "fontset.h"
45 #include "termhooks.h"
46 #include "termopts.h"
47 #include "termchar.h"
48 #include "disptab.h"
49 #include "buffer.h"
50 #include "window.h"
51 #include "keyboard.h"
52 #include "intervals.h"
53 #include "process.h"
54 #include "atimer.h"
55 #include "keymap.h"
56
57 #include "w32heap.h"
58 #include <shellapi.h>
59
60 #include "font.h"
61 #include "w32font.h"
62
63
64
65 static int max_fringe_bmp = 0;
66 static HBITMAP *fringe_bmp = 0;
67
68
69
70 Lisp_Object Vx_toolkit_scroll_bars;
71
72
73
74 static int last_mousemove_x = 0;
75 static int last_mousemove_y = 0;
76
77
78 #ifndef GET_WHEEL_DELTA_WPARAM
79 #define GET_WHEEL_DELTA_WPARAM(wparam) ((short)HIWORD (wparam))
80 #endif
81
82 83
84
85 static int any_help_event_p;
86
87
88 static Lisp_Object last_window;
89
90
91 int x_use_underline_position_properties;
92
93
94
95 int x_underline_at_descent_line;
96
97 extern unsigned int msh_mousewheel;
98
99 extern void free_frame_menubar ();
100
101 extern int w32_codepage_for_font (char *fontname);
102 extern Cursor w32_load_cursor (LPCTSTR name);
103
104 extern Lisp_Object Vwindow_system;
105
106 #define x_any_window_to_frame x_window_to_frame
107 #define x_top_window_to_frame x_window_to_frame
108
109
110
111 struct w32_display_info one_w32_display_info;
112 struct w32_display_info *x_display_list;
113
114 115 116 117
118 Lisp_Object w32_display_name_list;
119
120
121 #ifndef GLYPHSET
122 123
124
125 typedef struct tagWCRANGE
126 {
127 WCHAR wcLow;
128 USHORT cGlyphs;
129 } WCRANGE;
130
131 typedef struct tagGLYPHSET
132 {
133 DWORD cbThis;
134 DWORD flAccel;
135 DWORD cGlyphsSupported;
136 DWORD cRanges;
137 WCRANGE ranges[1];
138 } GLYPHSET;
139
140 #endif
141
142
143 BOOL (WINAPI *pfnSetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
144
145 #ifndef LWA_ALPHA
146 #define LWA_ALPHA 0x02
147 #endif
148 149
150 #ifndef WS_EX_LAYERED
151 #define WS_EX_LAYERED 0x80000
152 #endif
153
154 155 156 157 158
159 extern struct frame *updating_frame;
160
161
162 struct frame *pending_autoraise_frame;
163
164
165 HWND w32_system_caret_hwnd;
166 int w32_system_caret_height;
167 int w32_system_caret_x;
168 int w32_system_caret_y;
169 int w32_use_visible_system_caret;
170
171 DWORD dwWindowsThreadId = 0;
172 HANDLE hWindowsThread = NULL;
173 DWORD dwMainThreadId = 0;
174 HANDLE hMainThread = NULL;
175
176 int vertical_scroll_bar_min_handle;
177 int vertical_scroll_bar_top_border;
178 int vertical_scroll_bar_bottom_border;
179
180 int last_scroll_bar_drag_pos;
181
182
183
184
185 static RECT last_mouse_glyph;
186 static FRAME_PTR last_mouse_glyph_frame;
187 static Lisp_Object last_mouse_press_frame;
188
189 int w32_num_mouse_buttons;
190
191 Lisp_Object Vw32_swap_mouse_buttons;
192
193
194 Lisp_Object Vw32_grab_focus_on_raise;
195
196
197 Lisp_Object Vw32_capslock_is_shiftlock;
198
199
200 Lisp_Object Vw32_recognize_altgr;
201
202 203 204 205 206 207 208 209
210 static Lisp_Object last_mouse_scroll_bar;
211 static int last_mouse_scroll_bar_pos;
212
213 214 215 216 217 218
219 static Time last_mouse_movement_time;
220
221 222
223 #ifdef __STDC__
224 static int volatile input_signal_count;
225 #else
226 static int input_signal_count;
227 #endif
228
229 extern Lisp_Object Vcommand_line_args, Vsystem_name;
230
231
232 extern EMACS_INT extra_keyboard_modifiers;
233
234
235 static int keyboard_codepage;
236
237 static void x_update_window_end P_ ((struct window *, int, int));
238 static void w32_handle_tool_bar_click P_ ((struct frame *,
239 struct input_event *));
240 static void w32_define_cursor P_ ((Window, Cursor));
241
242 void x_lower_frame P_ ((struct frame *));
243 void x_scroll_bar_clear P_ ((struct frame *));
244 void x_wm_set_size_hint P_ ((struct frame *, long, int));
245 void x_raise_frame P_ ((struct frame *));
246 void x_set_window_size P_ ((struct frame *, int, int, int));
247 void x_wm_set_window_state P_ ((struct frame *, int));
248 void x_wm_set_icon_pixmap P_ ((struct frame *, int));
249 static void w32_initialize P_ ((void));
250 static void x_update_end P_ ((struct frame *));
251 static void w32_frame_up_to_date P_ ((struct frame *));
252 static void w32_set_terminal_modes P_ ((struct terminal *));
253 static void w32_reset_terminal_modes P_ ((struct terminal *));
254 static void x_clear_frame P_ ((struct frame *));
255 static void frame_highlight P_ ((struct frame *));
256 static void frame_unhighlight P_ ((struct frame *));
257 static void x_new_focus_frame P_ ((struct w32_display_info *,
258 struct frame *));
259 static void x_focus_changed P_ ((int, int, struct w32_display_info *,
260 struct frame *, struct input_event *));
261 static void w32_detect_focus_change P_ ((struct w32_display_info *,
262 W32Msg *, struct input_event *));
263 static void w32_frame_rehighlight P_ ((struct frame *));
264 static void x_frame_rehighlight P_ ((struct w32_display_info *));
265 static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
266 static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int,
267 enum text_cursor_kinds));
268 static void w32_clip_to_row P_ ((struct window *, struct glyph_row *, int, HDC));
269 static BOOL my_show_window P_ ((struct frame *, HWND, int));
270 static void my_set_window_pos P_ ((HWND, HWND, int, int, int, int, UINT));
271 static void my_set_focus P_ ((struct frame *, HWND));
272 static void my_set_foreground_window P_ ((HWND));
273 static void my_destroy_window P_ ((struct frame *, HWND));
274
275 static Lisp_Object Qvendor_specific_keysyms;
276
277
278 279 280
281
282 #if 0
283
284 285
286
287 struct record
288 {
289 char *locus;
290 int type;
291 };
292
293 struct record event_record[100];
294
295 int event_record_index;
296
297 record_event (locus, type)
298 char *locus;
299 int type;
300 {
301 if (event_record_index == sizeof (event_record) / sizeof (struct record))
302 event_record_index = 0;
303
304 event_record[event_record_index].locus = locus;
305 event_record[event_record_index].type = type;
306 event_record_index++;
307 }
308
309 #endif
310
311
312 void
313 XChangeGC (void * ignore, XGCValues* gc, unsigned long mask,
314 XGCValues *xgcv)
315 {
316 if (mask & GCForeground)
317 gc->foreground = xgcv->foreground;
318 if (mask & GCBackground)
319 gc->background = xgcv->background;
320 if (mask & GCFont)
321 gc->font = xgcv->font;
322 }
323
324 XGCValues *XCreateGC (void * ignore, Window window, unsigned long mask,
325 XGCValues *xgcv)
326 {
327 XGCValues *gc = (XGCValues *) xmalloc (sizeof (XGCValues));
328 bzero (gc, sizeof (XGCValues));
329
330 XChangeGC (ignore, gc, mask, xgcv);
331
332 return gc;
333 }
334
335 void
336 XGetGCValues (void* ignore, XGCValues *gc,
337 unsigned long mask, XGCValues *xgcv)
338 {
339 XChangeGC (ignore, xgcv, mask, gc);
340 }
341
342 static void
343 w32_set_clip_rectangle (HDC hdc, RECT *rect)
344 {
345 if (rect)
346 {
347 HRGN clip_region = CreateRectRgnIndirect (rect);
348 SelectClipRgn (hdc, clip_region);
349 DeleteObject (clip_region);
350 }
351 else
352 SelectClipRgn (hdc, NULL);
353 }
354
355
356
357 void
358 w32_draw_rectangle (HDC hdc, XGCValues *gc, int x, int y,
359 int width, int height)
360 {
361 HBRUSH hb, oldhb;
362 HPEN hp, oldhp;
363
364 hb = CreateSolidBrush (gc->background);
365 hp = CreatePen (PS_SOLID, 0, gc->foreground);
366 oldhb = SelectObject (hdc, hb);
367 oldhp = SelectObject (hdc, hp);
368
369 Rectangle (hdc, x, y, x + width, y + height);
370
371 SelectObject (hdc, oldhb);
372 SelectObject (hdc, oldhp);
373 DeleteObject (hb);
374 DeleteObject (hp);
375 }
376
377
378 void
379 w32_fill_rect (f, hdc, pix, lprect)
380 FRAME_PTR f;
381 HDC hdc;
382 COLORREF pix;
383 RECT * lprect;
384 {
385 HBRUSH hb;
386
387 hb = CreateSolidBrush (pix);
388 FillRect (hdc, lprect, hb);
389 DeleteObject (hb);
390 }
391
392 void
393 w32_clear_window (f)
394 FRAME_PTR f;
395 {
396 RECT rect;
397 HDC hdc = get_frame_dc (f);
398
399 400 401
402 if (hdc)
403 {
404 GetClientRect (FRAME_W32_WINDOW (f), &rect);
405 w32_clear_rect (f, hdc, &rect);
406 }
407
408 release_frame_dc (f, hdc);
409 }
410
411 #define OPAQUE_FRAME 255
412
413 void
414 x_set_frame_alpha (f)
415 struct frame *f;
416 {
417 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
418 double alpha = 1.0;
419 double alpha_min = 1.0;
420 BYTE opac;
421 LONG ex_style;
422 HWND window = FRAME_W32_WINDOW (f);
423
424
425 if (!pfnSetLayeredWindowAttributes)
426 return;
427
428 if (dpyinfo->x_highlight_frame == f)
429 alpha = f->alpha[0];
430 else
431 alpha = f->alpha[1];
432
433 if (FLOATP (Vframe_alpha_lower_limit))
434 alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
435 else if (INTEGERP (Vframe_alpha_lower_limit))
436 alpha_min = (XINT (Vframe_alpha_lower_limit)) / 100.0;
437
438 if (alpha < 0.0)
439 return;
440 else if (alpha > 1.0)
441 alpha = 1.0;
442 else if (alpha < alpha_min && alpha_min <= 1.0)
443 alpha = alpha_min;
444
445 opac = alpha * OPAQUE_FRAME;
446
447 ex_style = GetWindowLong (window, GWL_EXSTYLE);
448
449 if (opac == OPAQUE_FRAME)
450 ex_style &= ~WS_EX_LAYERED;
451 else
452 ex_style |= WS_EX_LAYERED;
453
454 SetWindowLong (window, GWL_EXSTYLE, ex_style);
455
456 if (opac != OPAQUE_FRAME)
457 pfnSetLayeredWindowAttributes (window, 0, opac, LWA_ALPHA);
458 }
459
460 int
461 x_display_pixel_height (dpyinfo)
462 struct w32_display_info *dpyinfo;
463 {
464 HDC dc = GetDC (NULL);
465 int pixels = GetDeviceCaps (dc, VERTRES);
466 ReleaseDC (NULL, dc);
467 return pixels;
468 }
469
470 int
471 x_display_pixel_width (dpyinfo)
472 struct w32_display_info *dpyinfo;
473 {
474 HDC dc = GetDC (NULL);
475 int pixels = GetDeviceCaps (dc, HORZRES);
476 ReleaseDC (NULL, dc);
477 return pixels;
478 }
479
480
481 482 483
484
485 486 487 488
489
490 static void
491 x_update_begin (f)
492 struct frame *f;
493 {
494 struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f);
495
496 if (! FRAME_W32_P (f))
497 return;
498
499 500
501 if (display_info->regen_palette)
502 {
503 w32_regenerate_palette (f);
504 display_info->regen_palette = FALSE;
505 }
506 }
507
508
509 510 511
512
513 static void
514 x_update_window_begin (w)
515 struct window *w;
516 {
517 struct frame *f = XFRAME (WINDOW_FRAME (w));
518 struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f);
519
520
521 if (w32_use_visible_system_caret && w32_system_caret_hwnd)
522 {
523 SendMessage (w32_system_caret_hwnd, WM_EMACS_HIDE_CARET, 0, 0);
524 }
525
526 updated_window = w;
527 set_output_cursor (&w->cursor);
528
529 BLOCK_INPUT;
530
531 if (f == display_info->mouse_face_mouse_frame)
532 {
533
534 display_info->mouse_face_defer = 1;
535
536 537
538 if (FRAME_GARBAGED_P (f))
539 display_info->mouse_face_window = Qnil;
540
541 #if 0 542 543 544 545 546
547
548 549 550 551 552
553 if (!NILP (display_info->mouse_face_window)
554 && w == XWINDOW (display_info->mouse_face_window))
555 {
556 int i;
557
558 for (i = 0; i < w->desired_matrix->nrows; ++i)
559 if (MATRIX_ROW_ENABLED_P (w->desired_matrix, i))
560 break;
561
562 if (i < w->desired_matrix->nrows)
563 clear_mouse_face (display_info);
564 }
565 #endif
566 }
567
568 UNBLOCK_INPUT;
569 }
570
571
572
573 static void
574 w32_draw_vertical_window_border (w, x, y0, y1)
575 struct window *w;
576 int x, y0, y1;
577 {
578 struct frame *f = XFRAME (WINDOW_FRAME (w));
579 RECT r;
580 HDC hdc;
581 struct face *face;
582
583 r.left = x;
584 r.right = x + 1;
585 r.top = y0;
586 r.bottom = y1;
587
588 hdc = get_frame_dc (f);
589 face = FACE_FROM_ID (f, VERTICAL_BORDER_FACE_ID);
590 if (face)
591 w32_fill_rect (f, hdc, face->foreground, &r);
592 else
593 w32_fill_rect (f, hdc, FRAME_FOREGROUND_PIXEL (f), &r);
594
595 release_frame_dc (f, hdc);
596 }
597
598
599 600 601 602 603 604 605 606 607 608 609 610
611
612 static void
613 x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
614 struct window *w;
615 int cursor_on_p, mouse_face_overwritten_p;
616 {
617 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
618
619 if (!w->pseudo_window_p)
620 {
621 BLOCK_INPUT;
622
623 if (cursor_on_p)
624 display_and_set_cursor (w, 1, output_cursor.hpos,
625 output_cursor.vpos,
626 output_cursor.x, output_cursor.y);
627
628 if (draw_window_fringes (w, 1))
629 x_draw_vertical_border (w);
630
631 UNBLOCK_INPUT;
632 }
633
634 635
636 if (mouse_face_overwritten_p)
637 {
638 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
639 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
640 dpyinfo->mouse_face_window = Qnil;
641 }
642
643 644 645
646 if (w32_use_visible_system_caret && w32_system_caret_hwnd)
647 {
648 SendMessage (w32_system_caret_hwnd, WM_EMACS_SHOW_CARET, 0, 0);
649 }
650
651 updated_window = NULL;
652 }
653
654
655 656
657
658 static void
659 x_update_end (f)
660 struct frame *f;
661 {
662 if (! FRAME_W32_P (f))
663 return;
664
665
666 FRAME_W32_DISPLAY_INFO (f)->mouse_face_defer = 0;
667 }
668
669
670 671 672
673
674 static void
675 w32_frame_up_to_date (f)
676 struct frame *f;
677 {
678 if (FRAME_W32_P (f))
679 {
680 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
681
682 if (dpyinfo->mouse_face_deferred_gc
683 || f == dpyinfo->mouse_face_mouse_frame)
684 {
685 BLOCK_INPUT;
686 if (dpyinfo->mouse_face_mouse_frame)
687 note_mouse_highlight (dpyinfo->mouse_face_mouse_frame,
688 dpyinfo->mouse_face_mouse_x,
689 dpyinfo->mouse_face_mouse_y);
690 dpyinfo->mouse_face_deferred_gc = 0;
691 UNBLOCK_INPUT;
692 }
693 }
694 }
695
696
697 698 699 700 701 702
703
704 static void
705 x_after_update_window_line (desired_row)
706 struct glyph_row *desired_row;
707 {
708 struct window *w = updated_window;
709 struct frame *f;
710 int width, height;
711
712 xassert (w);
713
714 if (!desired_row->mode_line_p && !w->pseudo_window_p)
715 desired_row->redraw_fringe_bitmaps_p = 1;
716
717 718 719 720 721 722
723 if (windows_or_buffers_changed
724 && desired_row->full_width_p
725 && (f = XFRAME (w->frame),
726 width = FRAME_INTERNAL_BORDER_WIDTH (f),
727 width != 0)
728 && (height = desired_row->visible_height,
729 height > 0))
730 {
731 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
732
733 BLOCK_INPUT;
734 {
735 HDC hdc = get_frame_dc (f);
736 w32_clear_area (f, hdc, 0, y, width, height);
737 w32_clear_area (f, hdc, FRAME_PIXEL_WIDTH (f) - width,
738 y, width, height);
739 release_frame_dc (f, hdc);
740 }
741 UNBLOCK_INPUT;
742 }
743 }
744
745
746 747 748 749
750
751 static void
752 w32_draw_fringe_bitmap (w, row, p)
753 struct window *w;
754 struct glyph_row *row;
755 struct draw_fringe_bitmap_params *p;
756 {
757 struct frame *f = XFRAME (WINDOW_FRAME (w));
758 HDC hdc;
759 struct face *face = p->face;
760 int rowY;
761
762 hdc = get_frame_dc (f);
763
764 if (!p->overlay_p)
765 {
766 int bx = p->bx, by = p->by, nx = p->nx, ny = p->ny;
767
768 769 770
771 if ((WINDOW_LEFTMOST_P (w)
772 && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
773 || (WINDOW_RIGHTMOST_P (w)
774 && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)))
775 {
776 int sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
777
778 if (sb_width > 0)
779 {
780 int left = WINDOW_SCROLL_BAR_AREA_X (w);
781 int width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
782 * FRAME_COLUMN_WIDTH (f));
783
784 if (bx < 0)
785 {
786
787 if (left + width == p->x)
788 bx = left + sb_width;
789 else if (p->x + p->wd == left)
790 bx = left;
791 if (bx >= 0)
792 {
793 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
794
795 nx = width - sb_width;
796 by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
797 row->y));
798 ny = row->visible_height;
799 }
800 }
801 else
802 {
803 if (left + width == bx)
804 {
805 bx = left + sb_width;
806 nx += width - sb_width;
807 }
808 else if (bx + nx == left)
809 nx += width - sb_width;
810 }
811 }
812 }
813
814 if (bx >= 0 && nx > 0)
815 w32_fill_area (f, hdc, face->background, bx, by, nx, ny);
816 }
817
818
819 rowY = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
820 if (p->y < rowY)
821 {
822 823
824 int oldY = row->y;
825 int oldVH = row->visible_height;
826 row->visible_height = p->h;
827 row->y -= rowY - p->y;
828 w32_clip_to_row (w, row, -1, hdc);
829 row->y = oldY;
830 row->visible_height = oldVH;
831 }
832 else
833 w32_clip_to_row (w, row, -1, hdc);
834
835 if (p->which && p->which < max_fringe_bmp)
836 {
837 HBITMAP pixmap = fringe_bmp[p->which];
838 HDC compat_hdc;
839 HANDLE horig_obj;
840
841 compat_hdc = CreateCompatibleDC (hdc);
842
843 SaveDC (hdc);
844
845 horig_obj = SelectObject (compat_hdc, pixmap);
846
847
848 if (p->overlay_p)
849 {
850 HBRUSH h_brush, h_orig_brush;
851
852 SetTextColor (hdc, BLACK_PIX_DEFAULT (f));
853 SetBkColor (hdc, WHITE_PIX_DEFAULT (f));
854 h_brush = CreateSolidBrush (face->foreground);
855 h_orig_brush = SelectObject (hdc, h_brush);
856
857 BitBlt (hdc, p->x, p->y, p->wd, p->h,
858 compat_hdc, 0, p->dh,
859 DSTINVERT);
860 BitBlt (hdc, p->x, p->y, p->wd, p->h,
861 compat_hdc, 0, p->dh,
862 0x2E064A);
863 BitBlt (hdc, p->x, p->y, p->wd, p->h,
864 compat_hdc, 0, p->dh,
865 DSTINVERT);
866
867 SelectObject (hdc, h_orig_brush);
868 DeleteObject (h_brush);
869 }
870 else
871 {
872 SetTextColor (hdc, face->background);
873 SetBkColor (hdc, (p->cursor_p
874 ? f->output_data.w32->cursor_pixel
875 : face->foreground));
876
877 BitBlt (hdc, p->x, p->y, p->wd, p->h,
878 compat_hdc, 0, p->dh,
879 SRCCOPY);
880 }
881
882 SelectObject (compat_hdc, horig_obj);
883 DeleteDC (compat_hdc);
884 RestoreDC (hdc, -1);
885 }
886
887 w32_set_clip_rectangle (hdc, NULL);
888
889 release_frame_dc (f, hdc);
890 }
891
892 static void
893 w32_define_fringe_bitmap (which, bits, h, wd)
894 int which;
895 unsigned short *bits;
896 int h, wd;
897 {
898 if (which >= max_fringe_bmp)
899 {
900 int i = max_fringe_bmp;
901 max_fringe_bmp = which + 20;
902 fringe_bmp = (HBITMAP *) xrealloc (fringe_bmp, max_fringe_bmp * sizeof (HBITMAP));
903 while (i < max_fringe_bmp)
904 fringe_bmp[i++] = 0;
905 }
906
907 fringe_bmp[which] = CreateBitmap (wd, h, 1, 1, bits);
908 }
909
910 static void
911 w32_destroy_fringe_bitmap (which)
912 int which;
913 {
914 if (which >= max_fringe_bmp)
915 return;
916
917 if (fringe_bmp[which])
918 DeleteObject (fringe_bmp[which]);
919 fringe_bmp[which] = 0;
920 }
921
922
923
924 925 926 927
928
929 static void
930 w32_set_terminal_modes (struct terminal *term)
931 {
932 }
933
934 935
936
937 static void
938 w32_reset_terminal_modes (struct terminal *term)
939 {
940 }
941
942
943
944 945 946
947
948
949
950 static void x_set_glyph_string_clipping P_ ((struct glyph_string *));
951 static void x_set_glyph_string_gc P_ ((struct glyph_string *));
952 static void x_draw_glyph_string_background P_ ((struct glyph_string *,
953 int));
954 static void x_draw_glyph_string_foreground P_ ((struct glyph_string *));
955 static void x_draw_composite_glyph_string_foreground P_ ((struct glyph_string *));
956 static void x_draw_glyph_string_box P_ ((struct glyph_string *));
957 static void x_draw_glyph_string P_ ((struct glyph_string *));
958 static void x_set_cursor_gc P_ ((struct glyph_string *));
959 static void x_set_mode_line_face_gc P_ ((struct glyph_string *));
960 static void x_set_mouse_face_gc P_ ((struct glyph_string *));
961 static int w32_alloc_lighter_color (struct frame *, COLORREF *, double, int);
962 static void w32_setup_relief_color P_ ((struct frame *, struct relief *,
963 double, int, COLORREF));
964 static void x_setup_relief_colors P_ ((struct glyph_string *));
965 static void x_draw_image_glyph_string P_ ((struct glyph_string *));
966 static void x_draw_image_relief P_ ((struct glyph_string *));
967 static void x_draw_image_foreground P_ ((struct glyph_string *));
968 static void w32_draw_image_foreground_1 P_ ((struct glyph_string *, HBITMAP));
969 static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int,
970 int, int, int));
971 static void w32_draw_relief_rect P_ ((struct frame *, int, int, int, int,
972 int, int, int, int, int, int,
973 RECT *));
974 static void w32_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
975 int, int, int, RECT *));
976
977
978 979
980
981 static void
982 x_set_cursor_gc (s)
983 struct glyph_string *s;
984 {
985 if (s->font == FRAME_FONT (s->f)
986 && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
987 && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
988 && !s->cmp)
989 s->gc = s->f->output_data.w32->cursor_gc;
990 else
991 {
992
993 XGCValues xgcv;
994 unsigned long mask;
995
996 xgcv.background = s->f->output_data.w32->cursor_pixel;
997 xgcv.foreground = s->face->background;
998
999
1000 if (xgcv.foreground == xgcv.background)
1001 xgcv.foreground = s->face->foreground;
1002 if (xgcv.foreground == xgcv.background)
1003 xgcv.foreground = s->f->output_data.w32->cursor_foreground_pixel;
1004 if (xgcv.foreground == xgcv.background)
1005 xgcv.foreground = s->face->foreground;
1006
1007
1008 if (xgcv.background == s->face->background
1009 && xgcv.foreground == s->face->foreground)
1010 {
1011 xgcv.background = s->face->foreground;
1012 xgcv.foreground = s->face->background;
1013 }
1014
1015 IF_DEBUG (x_check_font (s->f, s->font));
1016 xgcv.font = s->font;
1017 mask = GCForeground | GCBackground | GCFont;
1018
1019 if (FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1020 XChangeGC (NULL, FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1021 mask, &xgcv);
1022 else
1023 FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc
1024 = XCreateGC (NULL, s->window, mask, &xgcv);
1025
1026 s->gc = FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1027 }
1028 }
1029
1030
1031
1032
1033 static void
1034 x_set_mouse_face_gc (s)
1035 struct glyph_string *s;
1036 {
1037 int face_id;
1038 struct face *face;
1039
1040
1041 face_id = FRAME_W32_DISPLAY_INFO (s->f)->mouse_face_face_id;
1042 face = FACE_FROM_ID (s->f, face_id);
1043 if (face == NULL)
1044 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
1045
1046 if (s->first_glyph->type == CHAR_GLYPH)
1047 face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
1048 else
1049 face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
1050 s->face = FACE_FROM_ID (s->f, face_id);
1051 PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
1052
1053
1054 if (s->font == s->face->font)
1055 s->gc = s->face->gc;
1056 else
1057 {
1058 1059
1060 XGCValues xgcv;
1061 unsigned long mask;
1062
1063 xgcv.background = s->face->background;
1064 xgcv.foreground = s->face->foreground;
1065 IF_DEBUG (x_check_font (s->f, s->font));
1066 xgcv.font = s->font;
1067 mask = GCForeground | GCBackground | GCFont;
1068
1069 if (FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1070 XChangeGC (NULL, FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1071 mask, &xgcv);
1072 else
1073 FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc
1074 = XCreateGC (NULL, s->window, mask, &xgcv);
1075
1076 s->gc = FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1077 }
1078
1079 xassert (s->gc != 0);
1080 }
1081
1082
1083 1084 1085
1086
1087 static INLINE void
1088 x_set_mode_line_face_gc (s)
1089 struct glyph_string *s;
1090 {
1091 s->gc = s->face->gc;
1092 }
1093
1094
1095 1096 1097
1098
1099 static INLINE void
1100 x_set_glyph_string_gc (s)
1101 struct glyph_string *s;
1102 {
1103 PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
1104
1105 if (s->hl == DRAW_NORMAL_TEXT)
1106 {
1107 s->gc = s->face->gc;
1108 s->stippled_p = s->face->stipple != 0;
1109 }
1110 else if (s->hl == DRAW_INVERSE_VIDEO)
1111 {
1112 x_set_mode_line_face_gc (s);
1113 s->stippled_p = s->face->stipple != 0;
1114 }
1115 else if (s->hl == DRAW_CURSOR)
1116 {
1117 x_set_cursor_gc (s);
1118 s->stippled_p = 0;
1119 }
1120 else if (s->hl == DRAW_MOUSE_FACE)
1121 {
1122 x_set_mouse_face_gc (s);
1123 s->stippled_p = s->face->stipple != 0;
1124 }
1125 else if (s->hl == DRAW_IMAGE_RAISED
1126 || s->hl == DRAW_IMAGE_SUNKEN)
1127 {
1128 s->gc = s->face->gc;
1129 s->stippled_p = s->face->stipple != 0;
1130 }
1131 else
1132 {
1133 s->gc = s->face->gc;
1134 s->stippled_p = s->face->stipple != 0;
1135 }
1136
1137
1138 xassert (s->gc != 0);
1139 }
1140
1141
1142 1143
1144
1145 static INLINE void
1146 x_set_glyph_string_clipping (s)
1147 struct glyph_string *s;
1148 {
1149 RECT *r = s->clip;
1150 int n = get_glyph_string_clip_rects (s, r, 2);
1151
1152 if (n == 1)
1153 w32_set_clip_rectangle (s->hdc, r);
1154 else if (n > 1)
1155 {
1156 HRGN full_clip, clip1, clip2;
1157 clip1 = CreateRectRgnIndirect (r);
1158 clip2 = CreateRectRgnIndirect (r + 1);
1159 if (CombineRgn (full_clip, clip1, clip2, RGN_OR) != ERROR)
1160 {
1161 SelectClipRgn (s->hdc, full_clip);
1162 }
1163 DeleteObject (clip1);
1164 DeleteObject (clip2);
1165 DeleteObject (full_clip);
1166 }
1167 s->num_clips = n;
1168 }
1169
1170 1171 1172
1173
1174 static void
1175 x_set_glyph_string_clipping_exactly (src, dst)
1176 struct glyph_string *src, *dst;
1177 {
1178 RECT r;
1179
1180 r.left = src->x;
1181 r.right = r.left + src->width;
1182 r.top = src->y;
1183 r.bottom = r.top + src->height;
1184 dst->clip[0] = r;
1185 dst->num_clips = 1;
1186 w32_set_clip_rectangle (dst->hdc, &r);
1187 }
1188
1189 1190
1191
1192 static void
1193 w32_compute_glyph_string_overhangs (s)
1194 struct glyph_string *s;
1195 {
1196 if (s->cmp == NULL
1197 && s->first_glyph->type == CHAR_GLYPH
1198 && !s->font_not_found_p)
1199 {
1200 unsigned *code = alloca (sizeof (unsigned) * s->nchars);
1201 struct font *font = s->font;
1202 struct font_metrics metrics;
1203 int i;
1204
1205 for (i = 0; i < s->nchars; i++)
1206 code[i] = s->char2b[i];
1207 font->driver->text_extents (font, code, s->nchars, &metrics);
1208 s->right_overhang = (metrics.rbearing > metrics.width
1209 ? metrics.rbearing - metrics.width : 0);
1210 s->left_overhang = metrics.lbearing < 0 ? -metrics.lbearing : 0;
1211 }
1212 else if (s->cmp)
1213 {
1214 s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
1215 s->left_overhang = -s->cmp->lbearing;
1216 }
1217 }
1218
1219
1220
1221 static INLINE void
1222 x_clear_glyph_string_rect (s, x, y, w, h)
1223 struct glyph_string *s;
1224 int x, y, w, h;
1225 {
1226 int real_x = x;
1227 int real_y = y;
1228 int real_w = w;
1229 int real_h = h;
1230 #if 0
1231
1232 if (s->gc->clip_mask == Rect)
1233 {
1234 real_x = max (real_x, s->gc->clip_rectangle.left);
1235 real_y = max (real_y, s->gc->clip_rectangle.top);
1236 real_w = min (real_w, s->gc->clip_rectangle.right
1237 - s->gc->clip_rectangle.left);
1238 real_h = min (real_h, s->gc->clip_rectangle.bottom
1239 - s->gc->clip_rectangle.top);
1240 }
1241 #endif
1242 w32_fill_area (s->f, s->hdc, s->gc->background, real_x, real_y,
1243 real_w, real_h);
1244 }
1245
1246
1247 1248 1249 1250 1251
1252
1253 static void
1254 x_draw_glyph_string_background (s, force_p)
1255 struct glyph_string *s;
1256 int force_p;
1257 {
1258 1259
1260 if (!s->background_filled_p)
1261 {
1262 int box_line_width = max (s->face->box_line_width, 0);
1263
1264 #if 0
1265 if (s->stippled_p)
1266 {
1267
1268 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
1269 XFillRectangle (s->display, s->window, s->gc, s->x,
1270 s->y + box_line_width,
1271 s->background_width,
1272 s->height - 2 * box_line_width);
1273 XSetFillStyle (s->display, s->gc, FillSolid);
1274 s->background_filled_p = 1;
1275 }
1276 else
1277 #endif
1278 if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
1279 || s->font_not_found_p
1280 || s->extends_to_end_of_line_p
1281 || force_p)
1282 {
1283 x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
1284 s->background_width,
1285 s->height - 2 * box_line_width);
1286 s->background_filled_p = 1;
1287 }
1288 }
1289 }
1290
1291
1292
1293
1294 static void
1295 x_draw_glyph_string_foreground (s)
1296 struct glyph_string *s;
1297 {
1298 int i, x;
1299
1300 1301
1302 if (s->face->box != FACE_NO_BOX
1303 && s->first_glyph->left_box_line_p)
1304 x = s->x + eabs (s->face->box_line_width);
1305 else
1306 x = s->x;
1307
1308 SetTextColor (s->hdc, s->gc->foreground);
1309 SetBkColor (s->hdc, s->gc->background);
1310 SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
1311
1312 1313
1314 if (s->font_not_found_p)
1315 {
1316 for (i = 0; i < s->nchars; ++i)
1317 {
1318 struct glyph *g = s->first_glyph + i;
1319
1320 w32_draw_rectangle (s->hdc, s->gc, x, s->y, g->pixel_width - 1,
1321 s->height - 1);
1322 x += g->pixel_width;
1323 }
1324 }
1325 else
1326 {
1327 struct font *font = s->font;
1328 int boff = font->baseline_offset;
1329 int y;
1330 HFONT old_font;
1331
1332 old_font = SelectObject (s->hdc, FONT_HANDLE (font));
1333
1334 if (font->vertical_centering)
1335 boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
1336
1337 y = s->ybase - boff;
1338 if (s->for_overlaps
1339 || (s->background_filled_p && s->hl != DRAW_CURSOR))
1340 font->driver->draw (s, 0, s->nchars, x, y, 0);
1341 else
1342 font->driver->draw (s, 0, s->nchars, x, y, 1);
1343 if (s->face->overstrike)
1344 font->driver->draw (s, 0, s->nchars, x + 1, y, 0);
1345
1346 SelectObject (s->hdc, old_font);
1347 }
1348 }
1349
1350
1351
1352 static void
1353 x_draw_composite_glyph_string_foreground (s)
1354 struct glyph_string *s;
1355 {
1356 int i, j, x;
1357 struct font *font = s->font;
1358
1359 1360
1361 if (s->face && s->face->box != FACE_NO_BOX
1362 && s->first_glyph->left_box_line_p)
1363 x = s->x + eabs (s->face->box_line_width);
1364 else
1365 x = s->x;
1366
1367 1368 1369 1370
1371
1372 SetTextColor (s->hdc, s->gc->foreground);
1373 SetBkColor (s->hdc, s->gc->background);
1374 SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
1375
1376 1377
1378 if (s->font_not_found_p)
1379 {
1380 if (s->cmp_from == 0)
1381 w32_draw_rectangle (s->hdc, s->gc, x, s->y, s->width - 1,
1382 s->height - 1);
1383 }
1384 else if (! s->first_glyph->u.cmp.automatic)
1385 {
1386 int y = s->ybase;
1387 int width = 0;
1388 HFONT old_font;
1389
1390 old_font = SelectObject (s->hdc, FONT_HANDLE (font));
1391
1392 for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
1393 if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
1394 {
1395 int xx = x + s->cmp->offsets[j * 2];
1396 int yy = y - s->cmp->offsets[j * 2 + 1];
1397
1398 font->driver->draw (s, j, j + 1, xx, yy, 0);
1399 if (s->face->overstrike)
1400 font->driver->draw (s, j, j + 1, xx + 1, yy, 0);
1401 }
1402 SelectObject (s->hdc, old_font);
1403 }
1404 else
1405 {
1406 Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1407 Lisp_Object glyph;
1408 int y = s->ybase;
1409 int width = 0;
1410 HFONT old_font;
1411
1412 old_font = SelectObject (s->hdc, FONT_HANDLE (font));
1413
1414 for (i = j = s->cmp_from; i < s->cmp_to; i++)
1415 {
1416 glyph = LGSTRING_GLYPH (gstring, i);
1417 if (NILP (LGLYPH_ADJUSTMENT (glyph)))
1418 width += LGLYPH_WIDTH (glyph);
1419 else
1420 {
1421 int xoff, yoff, wadjust;
1422
1423 if (j < i)
1424 {
1425 font->driver->draw (s, j, i, x, y, 0);
1426 x += width;
1427 }
1428 xoff = LGLYPH_XOFF (glyph);
1429 yoff = LGLYPH_YOFF (glyph);
1430 wadjust = LGLYPH_WADJUST (glyph);
1431 font->driver->draw (s, i, i + 1, x + xoff, y + yoff, 0);
1432 x += wadjust;
1433 j = i + 1;
1434 width = 0;
1435 }
1436 }
1437 if (j < i)
1438 font->driver->draw (s, j, i, x, y, 0);
1439
1440 SelectObject (s->hdc, old_font);
1441 }
1442 }
1443
1444
1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455
1456 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
1457
1458
1459 1460 1461 1462 1463 1464
1465
1466 static int
1467 w32_alloc_lighter_color (f, color, factor, delta)
1468 struct frame *f;
1469 COLORREF *color;
1470 double factor;
1471 int delta;
1472 {
1473 COLORREF new;
1474 long bright;
1475
1476
1477 delta /= 256;
1478
1479
1480 xassert (factor >= 0);
1481 new = PALETTERGB (min (0xff, factor * GetRValue (*color)),
1482 min (0xff, factor * GetGValue (*color)),
1483 min (0xff, factor * GetBValue (*color)));
1484
1485
1486 bright = (2 * GetRValue (*color) + 3 * GetGValue (*color)
1487 + GetBValue (*color)) / 6;
1488
1489 1490
1491 if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
1492 1493
1494 {
1495
1496 double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
1497
1498 int min_delta = delta * dimness * factor / 2;
1499
1500 if (factor < 1)
1501 new = PALETTERGB (max (0, min (0xff, min_delta - GetRValue (*color))),
1502 max (0, min (0xff, min_delta - GetGValue (*color))),
1503 max (0, min (0xff, min_delta - GetBValue (*color))));
1504 else
1505 new = PALETTERGB (max (0, min (0xff, min_delta + GetRValue (*color))),
1506 max (0, min (0xff, min_delta + GetGValue (*color))),
1507 max (0, min (0xff, min_delta + GetBValue (*color))));
1508 }
1509
1510 if (new == *color)
1511 new = PALETTERGB (max (0, min (0xff, delta + GetRValue (*color))),
1512 max (0, min (0xff, delta + GetGValue (*color))),
1513 max (0, min (0xff, delta + GetBValue (*color))));
1514
1515
1516
1517
1518 if (new == *color)
1519 return 0;
1520
1521 *color = new;
1522
1523 return 1;
1524 }
1525
1526 1527 1528
1529 void
1530 x_query_colors (f, colors, ncolors)
1531 struct frame *f;
1532 XColor *colors;
1533 int ncolors;
1534 {
1535 int i;
1536
1537 for (i = 0; i < ncolors; i++)
1538 {
1539 DWORD pixel = colors[i].pixel;
1540
1541 colors[i].red = GetRValue (pixel) * 257;
1542 colors[i].green = GetGValue (pixel) * 257;
1543 colors[i].blue = GetBValue (pixel) * 257;
1544 }
1545 }
1546
1547 void
1548 x_query_color (f, color)
1549 struct frame *f;
1550 XColor *color;
1551 {
1552 x_query_colors (f, color, 1);
1553 }
1554
1555
1556 1557 1558 1559 1560 1561
1562
1563 static void
1564 w32_setup_relief_color (f, relief, factor, delta, default_pixel)
1565 struct frame *f;
1566 struct relief *relief;
1567 double factor;
1568 int delta;
1569 COLORREF default_pixel;
1570 {
1571 XGCValues xgcv;
1572 struct w32_output *di = f->output_data.w32;
1573 unsigned long mask = GCForeground;
1574 COLORREF pixel;
1575 COLORREF background = di->relief_background;
1576 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
1577
1578
1579
1580
1581 xgcv.foreground = default_pixel;
1582 pixel = background;
1583 if (w32_alloc_lighter_color (f, &pixel, factor, delta))
1584 {
1585 relief->allocated_p = 1;
1586 xgcv.foreground = relief->pixel = pixel;
1587 }
1588
1589 if (relief->gc == 0)
1590 {
1591 #if 0
1592 xgcv.stipple = dpyinfo->gray;
1593 mask |= GCStipple;
1594 #endif
1595 relief->gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, &xgcv);
1596 }
1597 else
1598 XChangeGC (NULL, relief->gc, mask, &xgcv);
1599 }
1600
1601
1602
1603
1604 static void
1605 x_setup_relief_colors (s)
1606 struct glyph_string *s;
1607 {
1608 struct w32_output *di = s->f->output_data.w32;
1609 COLORREF color;
1610
1611 if (s->face->use_box_color_for_shadows_p)
1612 color = s->face->box_color;
1613 else if (s->first_glyph->type == IMAGE_GLYPH
1614 && s->img->pixmap
1615 && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
1616 color = IMAGE_BACKGROUND (s->img, s->f, 0);
1617 else
1618 color = s->gc->background;
1619
1620 if (di->white_relief.gc == 0
1621 || color != di->relief_background)
1622 {
1623 di->relief_background = color;
1624 w32_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
1625 WHITE_PIX_DEFAULT (s->f));
1626 w32_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
1627 BLACK_PIX_DEFAULT (s->f));
1628 }
1629 }
1630
1631
1632 1633 1634 1635 1636 1637 1638
1639
1640 static void
1641 w32_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
1642 raised_p, top_p, bot_p, left_p, right_p, clip_rect)
1643 struct frame *f;
1644 int left_x, top_y, right_x, bottom_y, width;
1645 int top_p, bot_p, left_p, right_p, raised_p;
1646 RECT *clip_rect;
1647 {
1648 int i;
1649 XGCValues gc;
1650 HDC hdc = get_frame_dc (f);
1651
1652 if (raised_p)
1653 gc.foreground = f->output_data.w32->white_relief.gc->foreground;
1654 else
1655 gc.foreground = f->output_data.w32->black_relief.gc->foreground;
1656
1657 w32_set_clip_rectangle (hdc, clip_rect);
1658
1659
1660 if (top_p)
1661 for (i = 0; i < width; ++i)
1662 w32_fill_area (f, hdc, gc.foreground,
1663 left_x + i * left_p, top_y + i,
1664 right_x - left_x - i * (left_p + right_p ) + 1, 1);
1665
1666
1667 if (left_p)
1668 for (i = 0; i < width; ++i)
1669 w32_fill_area (f, hdc, gc.foreground,
1670 left_x + i, top_y + i, 1,
1671 bottom_y - top_y - 2 * i + 1);
1672
1673 if (raised_p)
1674 gc.foreground = f->output_data.w32->black_relief.gc->foreground;
1675 else
1676 gc.foreground = f->output_data.w32->white_relief.gc->foreground;
1677
1678
1679 if (bot_p)
1680 for (i = 0; i < width; ++i)
1681 w32_fill_area (f, hdc, gc.foreground,
1682 left_x + i * left_p, bottom_y - i,
1683 right_x - left_x - i * (left_p + right_p) + 1, 1);
1684
1685
1686 if (right_p)
1687 for (i = 0; i < width; ++i)
1688 w32_fill_area (f, hdc, gc.foreground,
1689 right_x - i, top_y + i + 1, 1,
1690 bottom_y - top_y - 2 * i - 1);
1691
1692 w32_set_clip_rectangle (hdc, NULL);
1693
1694 release_frame_dc (f, hdc);
1695 }
1696
1697
1698 1699 1700 1701 1702 1703
1704
1705 static void
1706 w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
1707 left_p, right_p, clip_rect)
1708 struct glyph_string *s;
1709 int left_x, top_y, right_x, bottom_y, width, left_p, right_p;
1710 RECT *clip_rect;
1711 {
1712 w32_set_clip_rectangle (s->hdc, clip_rect);
1713
1714
1715 w32_fill_area (s->f, s->hdc, s->face->box_color,
1716 left_x, top_y, right_x - left_x + 1, width);
1717
1718
1719 if (left_p)
1720 {
1721 w32_fill_area (s->f, s->hdc, s->face->box_color,
1722 left_x, top_y, width, bottom_y - top_y + 1);
1723 }
1724
1725
1726 w32_fill_area (s->f, s->hdc, s->face->box_color,
1727 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
1728
1729
1730 if (right_p)
1731 {
1732 w32_fill_area (s->f, s->hdc, s->face->box_color,
1733 right_x - width + 1, top_y, width, bottom_y - top_y + 1);
1734 }
1735
1736 w32_set_clip_rectangle (s->hdc, NULL);
1737 }
1738
1739
1740
1741
1742 static void
1743 x_draw_glyph_string_box (s)
1744 struct glyph_string *s;
1745 {
1746 int width, left_x, right_x, top_y, bottom_y, last_x, raised_p;
1747 int left_p, right_p;
1748 struct glyph *last_glyph;
1749 RECT clip_rect;
1750
1751 last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
1752 ? WINDOW_RIGHT_EDGE_X (s->w)
1753 : window_box_right (s->w, s->area));
1754
1755
1756 last_glyph = (s->cmp || s->img
1757 ? s->first_glyph
1758 : s->first_glyph + s->nchars - 1);
1759
1760 width = eabs (s->face->box_line_width);
1761 raised_p = s->face->box == FACE_RAISED_BOX;
1762 left_x = s->x;
1763 right_x = ((s->row->full_width_p && s->extends_to_end_of_line_p
1764 ? last_x - 1
1765 : min (last_x, s->x + s->background_width) - 1));
1766 top_y = s->y;
1767 bottom_y = top_y + s->height - 1;
1768
1769 left_p = (s->first_glyph->left_box_line_p
1770 || (s->hl == DRAW_MOUSE_FACE
1771 && (s->prev == NULL
1772 || s->prev->hl != s->hl)));
1773 right_p = (last_glyph->right_box_line_p
1774 || (s->hl == DRAW_MOUSE_FACE
1775 && (s->next == NULL
1776 || s->next->hl != s->hl)));
1777
1778 get_glyph_string_clip_rect (s, &clip_rect);
1779
1780 if (s->face->box == FACE_SIMPLE_BOX)
1781 w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
1782 left_p, right_p, &clip_rect);
1783 else
1784 {
1785 x_setup_relief_colors (s);
1786 w32_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
1787 width, raised_p, 1, 1, left_p, right_p, &clip_rect);
1788 }
1789 }
1790
1791
1792
1793
1794 static void
1795 x_draw_image_foreground (s)
1796 struct glyph_string *s;
1797 {
1798 int x = s->x;
1799 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
1800
1801 1802
1803 if (s->face->box != FACE_NO_BOX
1804 && s->first_glyph->left_box_line_p
1805 && s->slice.x == 0)
1806 x += eabs (s->face->box_line_width);
1807
1808 1809
1810 if (s->slice.x == 0)
1811 x += s->img->hmargin;
1812 if (s->slice.y == 0)
1813 y += s->img->vmargin;
1814
1815 SaveDC (s->hdc);
1816
1817 if (s->img->pixmap)
1818 {
1819 HDC compat_hdc = CreateCompatibleDC (s->hdc);
1820 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
1821 HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
1822 HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
1823 SetBkColor (compat_hdc, RGB (255, 255, 255));
1824 SetTextColor (s->hdc, RGB (0, 0, 0));
1825 x_set_glyph_string_clipping (s);
1826
1827 if (s->img->mask)
1828 {
1829 HDC mask_dc = CreateCompatibleDC (s->hdc);
1830 HGDIOBJ mask_orig_obj = SelectObject (mask_dc, s->img->mask);
1831
1832 SetTextColor (s->hdc, RGB (255, 255, 255));
1833 SetBkColor (s->hdc, RGB (0, 0, 0));
1834
1835 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
1836 compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
1837 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
1838 mask_dc, s->slice.x, s->slice.y, SRCAND);
1839 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
1840 compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
1841
1842 SelectObject (mask_dc, mask_orig_obj);
1843 DeleteDC (mask_dc);
1844 }
1845 else
1846 {
1847 SetTextColor (s->hdc, s->gc->foreground);
1848 SetBkColor (s->hdc, s->gc->background);
1849
1850 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
1851 compat_hdc, s->slice.x, s->slice.y, SRCCOPY);
1852
1853 1854 1855 1856 1857 1858
1859 if (s->hl == DRAW_CURSOR)
1860 {
1861 int r = s->img->relief;
1862 if (r < 0) r = -r;
1863 w32_draw_rectangle (s->hdc, s->gc, x - r, y - r ,
1864 s->slice.width + r*2 - 1,
1865 s->slice.height + r*2 - 1);
1866 }
1867 }
1868
1869 w32_set_clip_rectangle (s->hdc, NULL);
1870 SelectObject (s->hdc, orig_brush);
1871 DeleteObject (fg_brush);
1872 SelectObject (compat_hdc, orig_obj);
1873 DeleteDC (compat_hdc);
1874 }
1875 else
1876 w32_draw_rectangle (s->hdc, s->gc, x, y,
1877 s->slice.width - 1, s->slice.height - 1);
1878
1879 RestoreDC (s->hdc ,-1);
1880 }
1881
1882
1883
1884
1885 static void
1886 x_draw_image_relief (s)
1887 struct glyph_string *s;
1888 {
1889 int x0, y0, x1, y1, thick, raised_p;
1890 RECT r;
1891 int x = s->x;
1892 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
1893
1894 1895
1896 if (s->face->box != FACE_NO_BOX
1897 && s->first_glyph->left_box_line_p
1898 && s->slice.x == 0)
1899 x += eabs (s->face->box_line_width);
1900
1901 1902
1903 if (s->slice.x == 0)
1904 x += s->img->hmargin;
1905 if (s->slice.y == 0)
1906 y += s->img->vmargin;
1907
1908 if (s->hl == DRAW_IMAGE_SUNKEN
1909 || s->hl == DRAW_IMAGE_RAISED)
1910 {
1911 thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
1912 raised_p = s->hl == DRAW_IMAGE_RAISED;
1913 }
1914 else
1915 {
1916 thick = eabs (s->img->relief);
1917 raised_p = s->img->relief > 0;
1918 }
1919
1920 x0 = x - thick;
1921 y0 = y - thick;
1922 x1 = x + s->slice.width + thick - 1;
1923 y1 = y + s->slice.height + thick - 1;
1924
1925 x_setup_relief_colors (s);
1926 get_glyph_string_clip_rect (s, &r);
1927 w32_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p,
1928 s->slice.y == 0,
1929 s->slice.y + s->slice.height == s->img->height,
1930 s->slice.x == 0,
1931 s->slice.x + s->slice.width == s->img->width,
1932 &r);
1933 }
1934
1935
1936
1937
1938 static void
1939 w32_draw_image_foreground_1 (s, pixmap)
1940 struct glyph_string *s;
1941 HBITMAP pixmap;
1942 {
1943 HDC hdc = CreateCompatibleDC (s->hdc);
1944 HGDIOBJ orig_hdc_obj = SelectObject (hdc, pixmap);
1945 int x = 0;
1946 int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
1947
1948 1949
1950 if (s->face->box != FACE_NO_BOX
1951 && s->first_glyph->left_box_line_p
1952 && s->slice.x == 0)
1953 x += eabs (s->face->box_line_width);
1954
1955 1956
1957 if (s->slice.x == 0)
1958 x += s->img->hmargin;
1959 if (s->slice.y == 0)
1960 y += s->img->vmargin;
1961
1962 if (s->img->pixmap)
1963 {
1964 HDC compat_hdc = CreateCompatibleDC (hdc);
1965 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
1966 HBRUSH orig_brush = SelectObject (hdc, fg_brush);
1967 HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
1968
1969 if (s->img->mask)
1970 {
1971 HDC mask_dc = CreateCompatibleDC (hdc);
1972 HGDIOBJ mask_orig_obj = SelectObject (mask_dc, s->img->mask);
1973
1974 SetTextColor (hdc, RGB (0, 0, 0));
1975 SetBkColor (hdc, RGB (255, 255, 255));
1976 BitBlt (hdc, x, y, s->slice.width, s->slice.height,
1977 compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
1978 BitBlt (hdc, x, y, s->slice.width, s->slice.height,
1979 mask_dc, s->slice.x, s->slice.y, SRCAND);
1980 BitBlt (hdc, x, y, s->slice.width, s->slice.height,
1981 compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
1982
1983 SelectObject (mask_dc, mask_orig_obj);
1984 DeleteDC (mask_dc);
1985 }
1986 else
1987 {
1988 SetTextColor (hdc, s->gc->foreground);
1989 SetBkColor (hdc, s->gc->background);
1990
1991 BitBlt (hdc, x, y, s->slice.width, s->slice.height,
1992 compat_hdc, s->slice.x, s->slice.y, SRCCOPY);
1993
1994 1995 1996 1997 1998 1999
2000 if (s->hl == DRAW_CURSOR)
2001 {
2002 int r = s->img->relief;
2003 if (r < 0) r = -r;
2004 w32_draw_rectangle (hdc, s->gc, x - r, y - r,
2005 s->slice.width + r*2 - 1,
2006 s->slice.height + r*2 - 1);
2007 }
2008 }
2009
2010 SelectObject (hdc, orig_brush);
2011 DeleteObject (fg_brush);
2012 SelectObject (compat_hdc, orig_obj);
2013 DeleteDC (compat_hdc);
2014 }
2015 else
2016 w32_draw_rectangle (hdc, s->gc, x, y,
2017 s->slice.width - 1, s->slice.height - 1);
2018
2019 SelectObject (hdc, orig_hdc_obj);
2020 DeleteDC (hdc);
2021 }
2022
2023
2024 2025
2026
2027 static void
2028 x_draw_glyph_string_bg_rect (s, x, y, w, h)
2029 struct glyph_string *s;
2030 int x, y, w, h;
2031 {
2032 #if 0
2033 if (s->stippled_p)
2034 {
2035
2036 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
2037 XFillRectangle (s->display, s->window, s->gc, x, y, w, h);
2038 XSetFillStyle (s->display, s->gc, FillSolid);
2039 }
2040 else
2041 #endif
2042 x_clear_glyph_string_rect (s, x, y, w, h);
2043 }
2044
2045
2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058
2059
2060 static void
2061 x_draw_image_glyph_string (s)
2062 struct glyph_string *s;
2063 {
2064 int x, y;
2065 int box_line_hwidth = eabs (s->face->box_line_width);
2066 int box_line_vwidth = max (s->face->box_line_width, 0);
2067 int height;
2068 HBITMAP pixmap = 0;
2069
2070 height = s->height - 2 * box_line_vwidth;
2071
2072 2073 2074
2075 s->stippled_p = s->face->stipple != 0;
2076 if (height > s->slice.height
2077 || s->img->hmargin
2078 || s->img->vmargin
2079 || s->img->mask
2080 || s->img->pixmap == 0
2081 || s->width != s->background_width)
2082 {
2083 x = s->x;
2084 if (s->first_glyph->left_box_line_p
2085 && s->slice.x == 0)
2086 x += box_line_hwidth;
2087
2088 y = s->y;
2089 if (s->slice.y == 0)
2090 y += box_line_vwidth;
2091
2092 #if 0
2093 if (s->img->mask)
2094 {
2095 2096 2097
2098 Screen *screen = FRAME_X_SCREEN (s->f);
2099 int depth = DefaultDepthOfScreen (screen);
2100
2101
2102 pixmap = XCreatePixmap (s->display, s->window,
2103 s->background_width,
2104 s->height, depth);
2105
2106 2107
2108 XSetClipMask (s->display, s->gc, None);
2109
2110
2111 if (s->stippled_p)
2112 {
2113
2114 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
2115 XFillRectangle (s->display, pixmap, s->gc,
2116 0, 0, s->background_width, s->height);
2117 XSetFillStyle (s->display, s->gc, FillSolid);
2118 }
2119 else
2120 {
2121 XGCValues xgcv;
2122 XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
2123 &xgcv);
2124 XSetForeground (s->display, s->gc, xgcv.background);
2125 XFillRectangle (s->display, pixmap, s->gc,
2126 0, 0, s->background_width, s->height);
2127 XSetForeground (s->display, s->gc, xgcv.foreground);
2128 }
2129 }
2130 else
2131 #endif
2132 x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height);
2133
2134 s->background_filled_p = 1;
2135 }
2136
2137
2138 if (pixmap != 0)
2139 {
2140 w32_draw_image_foreground_1 (s, pixmap);
2141 x_set_glyph_string_clipping (s);
2142 {
2143 HDC compat_hdc = CreateCompatibleDC (s->hdc);
2144 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
2145 HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
2146 HGDIOBJ orig_obj = SelectObject (compat_hdc, pixmap);
2147
2148 SetTextColor (s->hdc, s->gc->foreground);
2149 SetBkColor (s->hdc, s->gc->background);
2150 BitBlt (s->hdc, s->x, s->y, s->background_width, s->height,
2151 compat_hdc, 0, 0, SRCCOPY);
2152
2153 SelectObject (s->hdc, orig_brush);
2154 DeleteObject (fg_brush);
2155 SelectObject (compat_hdc, orig_obj);
2156 DeleteDC (compat_hdc);
2157 }
2158 DeleteObject (pixmap);
2159 pixmap = 0;
2160 }
2161 else
2162 x_draw_image_foreground (s);
2163
2164
2165 if (s->img->relief
2166 || s->hl == DRAW_IMAGE_RAISED
2167 || s->hl == DRAW_IMAGE_SUNKEN)
2168 x_draw_image_relief (s);
2169 }
2170
2171
2172
2173
2174 static void
2175 x_draw_stretch_glyph_string (s)
2176 struct glyph_string *s;
2177 {
2178 xassert (s->first_glyph->type == STRETCH_GLYPH);
2179
2180 if (s->hl == DRAW_CURSOR
2181 && !x_stretch_cursor_p)
2182 {
2183 2184
2185 int width, background_width = s->background_width;
2186 int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
2187
2188 if (x < left_x)
2189 {
2190 background_width -= left_x - x;
2191 x = left_x;
2192 }
2193 width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
2194
2195
2196 x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
2197
2198
2199 if (width < background_width)
2200 {
2201 XGCValues *gc = s->face->gc;
2202 int y = s->y;
2203 int w = background_width - width, h = s->height;
2204 RECT r;
2205 HDC hdc = s->hdc;
2206
2207 x += width;
2208 if (s->row->mouse_face_p
2209 && cursor_in_mouse_face_p (s->w))
2210 {
2211 x_set_mouse_face_gc (s);
2212 gc = s->gc;
2213 }
2214 else
2215 gc = s->face->gc;
2216
2217 get_glyph_string_clip_rect (s, &r);
2218 w32_set_clip_rectangle (hdc, &r);
2219
2220 #if 0
2221 if (s->face->stipple)
2222 {
2223
2224 XSetFillStyle (s->display, gc, FillOpaqueStippled);
2225 XFillRectangle (s->display, s->window, gc, x, y, w, h);
2226 XSetFillStyle (s->display, gc, FillSolid);
2227 }
2228 else
2229 #endif
2230 {
2231 w32_fill_area (s->f, s->hdc, gc->background, x, y, w, h);
2232 }
2233 }
2234 }
2235 else if (!s->background_filled_p)
2236 {
2237 int background_width = s->background_width;
2238 int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
2239
2240 2241
2242 if (x < left_x && !s->row->mode_line_p)
2243 {
2244 background_width -= left_x - x;
2245 x = left_x;
2246 }
2247 if (background_width > 0)
2248 x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
2249 }
2250
2251 s->background_filled_p = 1;
2252 }
2253
2254
2255
2256
2257 static void
2258 x_draw_glyph_string (s)
2259 struct glyph_string *s;
2260 {
2261 int relief_drawn_p = 0;
2262
2263 2264 2265
2266 if (s->next && s->right_overhang && !s->for_overlaps)
2267 {
2268 int width;
2269 struct glyph_string *next;
2270 for (width = 0, next = s->next;
2271 next && width < s->right_overhang;
2272 width += next->width, next = next->next)
2273 if (next->first_glyph->type != IMAGE_GLYPH)
2274 {
2275 x_set_glyph_string_gc (next);
2276 x_set_glyph_string_clipping (next);
2277 if (next->first_glyph->type == STRETCH_GLYPH)
2278 x_draw_stretch_glyph_string (next);
2279 else
2280 x_draw_glyph_string_background (next, 1);
2281 next->num_clips = 0;
2282 }
2283 }
2284
2285
2286 x_set_glyph_string_gc (s);
2287
2288 2289
2290 if (!s->for_overlaps
2291 && s->face->box != FACE_NO_BOX
2292 && (s->first_glyph->type == CHAR_GLYPH
2293 || s->first_glyph->type == COMPOSITE_GLYPH))
2294
2295 {
2296 x_set_glyph_string_clipping (s);
2297 x_draw_glyph_string_background (s, 1);
2298 x_draw_glyph_string_box (s);
2299 x_set_glyph_string_clipping (s);
2300 relief_drawn_p = 1;
2301 }
2302 else if (!s->clip_head
2303 && !s->clip_tail
2304 && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
2305 || (s->next && s->next->hl != s->hl && s->right_overhang)))
2306 2307 2308
2309 x_set_glyph_string_clipping_exactly (s, s);
2310 else
2311 x_set_glyph_string_clipping (s);
2312
2313 switch (s->first_glyph->type)
2314 {
2315 case IMAGE_GLYPH:
2316 x_draw_image_glyph_string (s);
2317 break;
2318
2319 case STRETCH_GLYPH:
2320 x_draw_stretch_glyph_string (s);
2321 break;
2322
2323 case CHAR_GLYPH:
2324 if (s->for_overlaps)
2325 s->background_filled_p = 1;
2326 else
2327 x_draw_glyph_string_background (s, 0);
2328 x_draw_glyph_string_foreground (s);
2329 break;
2330
2331 case COMPOSITE_GLYPH:
2332 if (s->for_overlaps || (s->cmp_from > 0
2333 && ! s->first_glyph->u.cmp.automatic))
2334 s->background_filled_p = 1;
2335 else
2336 x_draw_glyph_string_background (s, 1);
2337 x_draw_composite_glyph_string_foreground (s);
2338 break;
2339
2340 default:
2341 abort ();
2342 }
2343
2344 if (!s->for_overlaps)
2345 {
2346
2347 if (s->face->underline_p)
2348 {
2349 unsigned long thickness, position;
2350 int y;
2351
2352 if (s->prev && s->prev->face->underline_p)
2353 {
2354
2355 thickness = s->prev->underline_thickness;
2356 position = s->prev->underline_position;
2357 }
2358 else
2359 {
2360
2361 if (s->font && s->font->underline_thickness > 0)
2362 thickness = s->font->underline_thickness;
2363 else
2364 thickness = 1;
2365 if (x_underline_at_descent_line)
2366 position = (s->height - thickness) - (s->ybase - s->y);
2367 else
2368 {
2369 2370 2371 2372 2373 2374 2375
2376
2377 if (x_use_underline_position_properties
2378 && s->font && s->font->underline_position >= 0)
2379 position = s->font->underline_position;
2380 else if (s->font)
2381 position = (s->font->descent + 1) / 2;
2382 }
2383 position = max (position, underline_minimum_offset);
2384 }
2385 2386
2387 if (s->y + s->height <= s->ybase + position)
2388 position = (s->height - 1) - (s->ybase - s->y);
2389 if (s->y + s->height < s->ybase + position + thickness)
2390 thickness = (s->y + s->height) - (s->ybase + position);
2391 s->underline_thickness = thickness;
2392 s->underline_position =position;
2393 y = s->ybase + position;
2394 if (s->face->underline_defaulted_p)
2395 {
2396 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
2397 y, s->width, 1);
2398 }
2399 else
2400 {
2401 w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
2402 y, s->width, 1);
2403 }
2404 }
2405
2406 if (s->face->overline_p)
2407 {
2408 unsigned long dy = 0, h = 1;
2409
2410 if (s->face->overline_color_defaulted_p)
2411 {
2412 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
2413 s->y + dy, s->width, h);
2414 }
2415 else
2416 {
2417 w32_fill_area (s->f, s->hdc, s->face->overline_color, s->x,
2418 s->y + dy, s->width, h);
2419 }
2420 }
2421
2422
2423 if (s->face->strike_through_p
2424 && !FONT_TEXTMETRIC(s->font).tmStruckOut)
2425 {
2426 unsigned long h = 1;
2427 unsigned long dy = (s->height - h) / 2;
2428
2429 if (s->face->strike_through_color_defaulted_p)
2430 {
2431 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x, s->y + dy,
2432 s->width, h);
2433 }
2434 else
2435 {
2436 w32_fill_area (s->f, s->hdc, s->face->strike_through_color, s->x,
2437 s->y + dy, s->width, h);
2438 }
2439 }
2440
2441
2442 if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
2443 x_draw_glyph_string_box (s);
2444
2445 if (s->prev)
2446 {
2447 struct glyph_string *prev;
2448
2449 for (prev = s->prev; prev; prev = prev->prev)
2450 if (prev->hl != s->hl
2451 && prev->x + prev->width + prev->right_overhang > s->x)
2452 {
2453 2454
2455 enum draw_glyphs_face save = prev->hl;
2456
2457 prev->hl = s->hl;
2458 x_set_glyph_string_gc (prev);
2459 x_set_glyph_string_clipping_exactly (s, prev);
2460 if (prev->first_glyph->type == CHAR_GLYPH)
2461 x_draw_glyph_string_foreground (prev);
2462 else
2463 x_draw_composite_glyph_string_foreground (prev);
2464 w32_set_clip_rectangle (prev->hdc, NULL);
2465 prev->hl = save;
2466 prev->num_clips = 0;
2467 }
2468 }
2469
2470 if (s->next)
2471 {
2472 struct glyph_string *next;
2473
2474 for (next = s->next; next; next = next->next)
2475 if (next->hl != s->hl
2476 && next->x - next->left_overhang < s->x + s->width)
2477 {
2478 2479
2480 enum draw_glyphs_face save = next->hl;
2481
2482 next->hl = s->hl;
2483 x_set_glyph_string_gc (next);
2484 x_set_glyph_string_clipping_exactly (s, next);
2485 if (next->first_glyph->type == CHAR_GLYPH)
2486 x_draw_glyph_string_foreground (next);
2487 else
2488 x_draw_composite_glyph_string_foreground (next);
2489 w32_set_clip_rectangle (next->hdc, NULL);
2490 next->hl = save;
2491 next->num_clips = 0;
2492 }
2493 }
2494 }
2495
2496
2497 w32_set_clip_rectangle (s->hdc, NULL);
2498 s->num_clips = 0;
2499 }
2500
2501
2502
2503
2504 void
2505 w32_shift_glyphs_for_insert (f, x, y, width, height, shift_by)
2506 struct frame *f;
2507 int x, y, width, height, shift_by;
2508 {
2509 HDC hdc;
2510
2511 hdc = get_frame_dc (f);
2512 BitBlt (hdc, x + shift_by, y, width, height,
2513 hdc, x, y, SRCCOPY);
2514
2515 release_frame_dc (f, hdc);
2516 }
2517
2518
2519 2520
2521
2522 static void
2523 x_delete_glyphs (f, n)
2524 struct frame *f;
2525 register int n;
2526 {
2527 if (! FRAME_W32_P (f))
2528 return;
2529
2530 abort ();
2531 }
2532
2533
2534 2535
2536
2537 static void
2538 x_clear_frame (struct frame *f)
2539 {
2540 if (! FRAME_W32_P (f))
2541 return;
2542
2543 2544
2545 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
2546 output_cursor.hpos = output_cursor.vpos = 0;
2547 output_cursor.x = -1;
2548
2549 2550
2551 BLOCK_INPUT;
2552
2553 w32_clear_window (f);
2554
2555 2556
2557 x_scroll_bar_clear (f);
2558
2559 UNBLOCK_INPUT;
2560 }
2561
2562
2563
2564
2565 static void
2566 w32_ring_bell (struct frame *f)
2567 {
2568 BLOCK_INPUT;
2569
2570 if (FRAME_W32_P (f) && visible_bell)
2571 {
2572 int i;
2573 HWND hwnd = FRAME_W32_WINDOW (f);
2574
2575 for (i = 0; i < 5; i++)
2576 {
2577 FlashWindow (hwnd, TRUE);
2578 Sleep (10);
2579 }
2580 FlashWindow (hwnd, FALSE);
2581 }
2582 else
2583 w32_sys_ring_bell (f);
2584
2585 UNBLOCK_INPUT;
2586 }
2587
2588
2589 2590 2591 2592
2593
2594 static void
2595 w32_set_terminal_window (n)
2596 register int n;
2597 {
2598
2599 }
2600
2601
2602 2603 2604
2605
2606 2607
2608
2609 static void
2610 x_ins_del_lines (f, vpos, n)
2611 struct frame *f;
2612 int vpos, n;
2613 {
2614 if (! FRAME_W32_P (f))
2615 return;
2616
2617 abort ();
2618 }
2619
2620
2621
2622
2623 static void
2624 x_scroll_run (w, run)
2625 struct window *w;
2626 struct run *run;
2627 {
2628 struct frame *f = XFRAME (w->frame);
2629 int x, y, width, height, from_y, to_y, bottom_y;
2630 HWND hwnd = FRAME_W32_WINDOW (f);
2631 HRGN expect_dirty;
2632
2633 2634 2635
2636 window_box (w, -1, &x, &y, &width, &height);
2637
2638 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
2639 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
2640 bottom_y = y + height;
2641
2642 if (to_y < from_y)
2643 {
2644 2645
2646 if (from_y + run->height > bottom_y)
2647 height = bottom_y - from_y;
2648 else
2649 height = run->height;
2650 expect_dirty = CreateRectRgn (x, y + height, x + width, bottom_y);
2651 }
2652 else
2653 {
2654 2655
2656 if (to_y + run->height > bottom_y)
2657 height = bottom_y - to_y;
2658 else
2659 height = run->height;
2660 expect_dirty = CreateRectRgn (x, y, x + width, to_y);
2661 }
2662
2663 BLOCK_INPUT;
2664
2665
2666 updated_window = w;
2667 x_clear_cursor (w);
2668
2669 {
2670 RECT from;
2671 RECT to;
2672 HRGN dirty = CreateRectRgn (0, 0, 0, 0);
2673 HRGN combined = CreateRectRgn (0, 0, 0, 0);
2674
2675 from.left = to.left = x;
2676 from.right = to.right = x + width;
2677 from.top = from_y;
2678 from.bottom = from_y + height;
2679 to.top = y;
2680 to.bottom = bottom_y;
2681
2682 ScrollWindowEx (hwnd, 0, to_y - from_y, &from, &to, dirty,
2683 NULL, SW_INVALIDATE);
2684
2685 2686
2687 CombineRgn (combined, dirty, expect_dirty, RGN_OR);
2688
2689
2690 if (!EqualRgn (combined, expect_dirty))
2691 SET_FRAME_GARBAGED (f);
2692
2693 DeleteObject (dirty);
2694 DeleteObject (combined);
2695 }
2696
2697 UNBLOCK_INPUT;
2698 DeleteObject (expect_dirty);
2699 }
2700
2701
2702
2703 2704 2705
2706
2707 static void
2708 frame_highlight (f)
2709 struct frame *f;
2710 {
2711 x_update_cursor (f, 1);
2712 x_set_frame_alpha (f);
2713 }
2714
2715 static void
2716 frame_unhighlight (f)
2717 struct frame *f;
2718 {
2719 x_update_cursor (f, 1);
2720 x_set_frame_alpha (f);
2721 }
2722
2723 2724 2725 2726 2727
2728
2729 static void
2730 x_new_focus_frame (dpyinfo, frame)
2731 struct w32_display_info *dpyinfo;
2732 struct frame *frame;
2733 {
2734 struct frame *old_focus = dpyinfo->w32_focus_frame;
2735
2736 if (frame != dpyinfo->w32_focus_frame)
2737 {
2738 2739
2740 dpyinfo->w32_focus_frame = frame;
2741
2742 if (old_focus && old_focus->auto_lower)
2743 x_lower_frame (old_focus);
2744
2745 if (dpyinfo->w32_focus_frame && dpyinfo->w32_focus_frame->auto_raise)
2746 pending_autoraise_frame = dpyinfo->w32_focus_frame;
2747 else
2748 pending_autoraise_frame = 0;
2749 }
2750
2751 x_frame_rehighlight (dpyinfo);
2752 }
2753
2754
2755 2756 2757
2758
2759 static void
2760 x_focus_changed (type, state, dpyinfo, frame, bufp)
2761 int type;
2762 int state;
2763 struct w32_display_info *dpyinfo;
2764 struct frame *frame;
2765 struct input_event *bufp;
2766 {
2767 if (type == WM_SETFOCUS)
2768 {
2769 if (dpyinfo->w32_focus_event_frame != frame)
2770 {
2771 x_new_focus_frame (dpyinfo, frame);
2772 dpyinfo->w32_focus_event_frame = frame;
2773
2774 2775
2776 if (NILP (Vterminal_frame)
2777 && CONSP (Vframe_list)
2778 && !NILP (XCDR (Vframe_list)))
2779 {
2780 bufp->kind = FOCUS_IN_EVENT;
2781 XSETFRAME (bufp->frame_or_window, frame);
2782 }
2783 }
2784
2785 frame->output_data.x->focus_state |= state;
2786
2787
2788 }
2789 else if (type == WM_KILLFOCUS)
2790 {
2791 frame->output_data.x->focus_state &= ~state;
2792
2793 if (dpyinfo->w32_focus_event_frame == frame)
2794 {
2795 dpyinfo->w32_focus_event_frame = 0;
2796 x_new_focus_frame (dpyinfo, 0);
2797 }
2798
2799
2800 }
2801 }
2802
2803
2804 2805 2806 2807
2808
2809 static void
2810 w32_detect_focus_change (dpyinfo, event, bufp)
2811 struct w32_display_info *dpyinfo;
2812 W32Msg *event;
2813 struct input_event *bufp;
2814 {
2815 struct frame *frame;
2816
2817 frame = x_any_window_to_frame (dpyinfo, event->msg.hwnd);
2818 if (! frame)
2819 return;
2820
2821
2822 x_focus_changed (event->msg.message,
2823 (event->msg.message == WM_KILLFOCUS ?
2824 FOCUS_IMPLICIT : FOCUS_EXPLICIT),
2825 dpyinfo, frame, bufp);
2826 }
2827
2828
2829
2830
2831 void
2832 x_mouse_leave (dpyinfo)
2833 struct w32_display_info *dpyinfo;
2834 {
2835 x_new_focus_frame (dpyinfo, dpyinfo->w32_focus_event_frame);
2836 }
2837
2838 2839 2840 2841 2842 2843 2844
2845
2846 static void
2847 w32_frame_rehighlight (frame)
2848 struct frame *frame;
2849 {
2850 if (! FRAME_W32_P (frame))
2851 return;
2852 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame));
2853 }
2854
2855 static void
2856 x_frame_rehighlight (dpyinfo)
2857 struct w32_display_info *dpyinfo;
2858 {
2859 struct frame *old_highlight = dpyinfo->x_highlight_frame;
2860
2861 if (dpyinfo->w32_focus_frame)
2862 {
2863 dpyinfo->x_highlight_frame
2864 = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame)))
2865 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame))
2866 : dpyinfo->w32_focus_frame);
2867 if (! FRAME_LIVE_P (dpyinfo->x_highlight_frame))
2868 {
2869 FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame) = Qnil;
2870 dpyinfo->x_highlight_frame = dpyinfo->w32_focus_frame;
2871 }
2872 }
2873 else
2874 dpyinfo->x_highlight_frame = 0;
2875
2876 if (dpyinfo->x_highlight_frame != old_highlight)
2877 {
2878 if (old_highlight)
2879 frame_unhighlight (old_highlight);
2880 if (dpyinfo->x_highlight_frame)
2881 frame_highlight (dpyinfo->x_highlight_frame);
2882 }
2883 }
2884
2885
2886
2887
2888
2889 char *
2890 x_get_keysym_name (keysym)
2891 int keysym;
2892 {
2893
2894 static char value[100];
2895
2896 BLOCK_INPUT;
2897 GetKeyNameText (keysym, value, 100);
2898 UNBLOCK_INPUT;
2899
2900 return value;
2901 }
2902
2903 static int codepage_for_locale(LCID locale)
2904 {
2905 char cp[20];
2906
2907 if (GetLocaleInfo (locale, LOCALE_IDEFAULTANSICODEPAGE, cp, 20) > 0)
2908 return atoi (cp);
2909 else
2910 return CP_ACP;
2911 }
2912
2913
2914
2915
2916 2917 2918
2919 BOOL
2920 parse_button (message, xbutton, pbutton, pup)
2921 int message;
2922 int xbutton;
2923 int * pbutton;
2924 int * pup;
2925 {
2926 int button = 0;
2927 int up = 0;
2928
2929 switch (message)
2930 {
2931 case WM_LBUTTONDOWN:
2932 button = 0;
2933 up = 0;
2934 break;
2935 case WM_LBUTTONUP:
2936 button = 0;
2937 up = 1;
2938 break;
2939 case WM_MBUTTONDOWN:
2940 if (NILP (Vw32_swap_mouse_buttons))
2941 button = 1;
2942 else
2943 button = 2;
2944 up = 0;
2945 break;
2946 case WM_MBUTTONUP:
2947 if (NILP (Vw32_swap_mouse_buttons))
2948 button = 1;
2949 else
2950 button = 2;
2951 up = 1;
2952 break;
2953 case WM_RBUTTONDOWN:
2954 if (NILP (Vw32_swap_mouse_buttons))
2955 button = 2;
2956 else
2957 button = 1;
2958 up = 0;
2959 break;
2960 case WM_RBUTTONUP:
2961 if (NILP (Vw32_swap_mouse_buttons))
2962 button = 2;
2963 else
2964 button = 1;
2965 up = 1;
2966 break;
2967 case WM_XBUTTONDOWN:
2968 button = xbutton + 2;
2969 up = 0;
2970 break;
2971 case WM_XBUTTONUP:
2972 button = xbutton + 2;
2973 up = 1;
2974 break;
2975 default:
2976 return (FALSE);
2977 }
2978
2979 if (pup) *pup = up;
2980 if (pbutton) *pbutton = button;
2981
2982 return (TRUE);
2983 }
2984
2985
2986 2987 2988 2989
2990
2991 static Lisp_Object
2992 construct_mouse_click (result, msg, f)
2993 struct input_event *result;
2994 W32Msg *msg;
2995 struct frame *f;
2996 {
2997 int button;
2998 int up;
2999
3000 parse_button (msg->msg.message, HIWORD (msg->msg.wParam),
3001 &button, &up);
3002
3003 3004
3005 result->kind = MOUSE_CLICK_EVENT;
3006 result->code = button;
3007 result->timestamp = msg->msg.time;
3008 result->modifiers = (msg->dwModifiers
3009 | (up
3010 ? up_modifier
3011 : down_modifier));
3012
3013 XSETINT (result->x, LOWORD (msg->msg.lParam));
3014 XSETINT (result->y, HIWORD (msg->msg.lParam));
3015 XSETFRAME (result->frame_or_window, f);
3016 result->arg = Qnil;
3017 return Qnil;
3018 }
3019
3020 static Lisp_Object
3021 construct_mouse_wheel (result, msg, f)
3022 struct input_event *result;
3023 W32Msg *msg;
3024 struct frame *f;
3025 {
3026 POINT p;
3027 int delta;
3028
3029 result->kind = msg->msg.message == WM_MOUSEHWHEEL ? HORIZ_WHEEL_EVENT
3030 : WHEEL_EVENT;
3031 result->code = 0;
3032 result->timestamp = msg->msg.time;
3033
3034 3035 3036
3037 delta = GET_WHEEL_DELTA_WPARAM (msg->msg.wParam);
3038
3039 3040
3041 result->modifiers = (msg->dwModifiers
3042 | ((delta < 0 ) ? down_modifier : up_modifier));
3043
3044 3045
3046 p.x = (short) LOWORD (msg->msg.lParam);
3047 p.y = (short) HIWORD (msg->msg.lParam);
3048 ScreenToClient (msg->msg.hwnd, &p);
3049 XSETINT (result->x, p.x);
3050 XSETINT (result->y, p.y);
3051 XSETFRAME (result->frame_or_window, f);
3052 result->arg = Qnil;
3053 return Qnil;
3054 }
3055
3056 static Lisp_Object
3057 construct_drag_n_drop (result, msg, f)
3058 struct input_event *result;
3059 W32Msg *msg;
3060 struct frame *f;
3061 {
3062 Lisp_Object files;
3063 Lisp_Object frame;
3064 HDROP hdrop;
3065 POINT p;
3066 WORD num_files;
3067 char *name;
3068 int i, len;
3069
3070 result->kind = DRAG_N_DROP_EVENT;
3071 result->code = 0;
3072 result->timestamp = msg->msg.time;
3073 result->modifiers = msg->dwModifiers;
3074
3075 hdrop = (HDROP) msg->msg.wParam;
3076 DragQueryPoint (hdrop, &p);
3077
3078 #if 0
3079 p.x = LOWORD (msg->msg.lParam);
3080 p.y = HIWORD (msg->msg.lParam);
3081 ScreenToClient (msg->msg.hwnd, &p);
3082 #endif
3083
3084 XSETINT (result->x, p.x);
3085 XSETINT (result->y, p.y);
3086
3087 num_files = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0);
3088 files = Qnil;
3089
3090 for (i = 0; i < num_files; i++)
3091 {
3092 len = DragQueryFile (hdrop, i, NULL, 0);
3093 if (len <= 0)
3094 continue;
3095 name = alloca (len + 1);
3096 DragQueryFile (hdrop, i, name, len + 1);
3097 files = Fcons (DECODE_FILE (build_string (name)), files);
3098 }
3099
3100 DragFinish (hdrop);
3101
3102 XSETFRAME (frame, f);
3103 result->frame_or_window = frame;
3104 result->arg = files;
3105 return Qnil;
3106 }
3107
3108
3109 3110 3111 3112 3113 3114 3115
3116
3117 static MSG last_mouse_motion_event;
3118 static Lisp_Object last_mouse_motion_frame;
3119
3120 static int
3121 note_mouse_movement (frame, msg)
3122 FRAME_PTR frame;
3123 MSG *msg;
3124 {
3125 int mouse_x = LOWORD (msg->lParam);
3126 int mouse_y = HIWORD (msg->lParam);
3127
3128 last_mouse_movement_time = msg->time;
3129 memcpy (&last_mouse_motion_event, msg, sizeof (last_mouse_motion_event));
3130 XSETFRAME (last_mouse_motion_frame, frame);
3131
3132 if (!FRAME_X_OUTPUT (frame))
3133 return 0;
3134
3135 if (msg->hwnd != FRAME_W32_WINDOW (frame))
3136 {
3137 frame->mouse_moved = 1;
3138 last_mouse_scroll_bar = Qnil;
3139 note_mouse_highlight (frame, -1, -1);
3140 last_mouse_glyph_frame = 0;
3141 return 1;
3142 }
3143
3144
3145 if (frame != last_mouse_glyph_frame
3146 || mouse_x < last_mouse_glyph.left
3147 || mouse_x >= last_mouse_glyph.right
3148 || mouse_y < last_mouse_glyph.top
3149 || mouse_y >= last_mouse_glyph.bottom)
3150 {
3151 frame->mouse_moved = 1;
3152 last_mouse_scroll_bar = Qnil;
3153 note_mouse_highlight (frame, mouse_x, mouse_y);
3154 3155 3156 3157
3158 remember_mouse_glyph (frame, mouse_x, mouse_y, &last_mouse_glyph);
3159 last_mouse_glyph_frame = frame;
3160 return 1;
3161 }
3162
3163 return 0;
3164 }
3165
3166
3167 3168 3169
3170
3171 static struct scroll_bar *x_window_to_scroll_bar ();
3172 static void x_scroll_bar_report_motion ();
3173 static void x_check_fullscreen P_ ((struct frame *));
3174
3175 static void
3176 redo_mouse_highlight ()
3177 {
3178 if (!NILP (last_mouse_motion_frame)
3179 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame)))
3180 note_mouse_highlight (XFRAME (last_mouse_motion_frame),
3181 LOWORD (last_mouse_motion_event.lParam),
3182 HIWORD (last_mouse_motion_event.lParam));
3183 }
3184
3185 static void
3186 w32_define_cursor (window, cursor)
3187 Window window;
3188 Cursor cursor;
3189 {
3190 PostMessage (window, WM_EMACS_SETCURSOR, (WPARAM) cursor, 0);
3191 }
3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210
3211
3212 static void
3213 w32_mouse_position (fp, insist, bar_window, part, x, y, time)
3214 FRAME_PTR *fp;
3215 int insist;
3216 Lisp_Object *bar_window;
3217 enum scroll_bar_part *part;
3218 Lisp_Object *x, *y;
3219 unsigned long *time;
3220 {
3221 FRAME_PTR f1;
3222
3223 BLOCK_INPUT;
3224
3225 if (! NILP (last_mouse_scroll_bar) && insist == 0)
3226 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
3227 else
3228 {
3229 POINT pt;
3230
3231 Lisp_Object frame, tail;
3232
3233
3234 FOR_EACH_FRAME (tail, frame)
3235 XFRAME (frame)->mouse_moved = 0;
3236
3237 last_mouse_scroll_bar = Qnil;
3238
3239 GetCursorPos (&pt);
3240
3241 3242
3243 {
3244 if (FRAME_W32_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
3245 && FRAME_LIVE_P (last_mouse_frame))
3246 {
3247 3248
3249 f1 = last_mouse_frame;
3250 }
3251 else
3252 {
3253
3254 f1 = x_any_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp),
3255 WindowFromPoint (pt));
3256 }
3257
3258
3259 if (! f1)
3260 {
3261 struct scroll_bar *bar
3262 = x_window_to_scroll_bar (WindowFromPoint (pt));
3263
3264 if (bar)
3265 {
3266 f1 = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
3267 }
3268 }
3269
3270 if (f1 == 0 && insist > 0)
3271 f1 = SELECTED_FRAME ();
3272
3273 if (f1)
3274 {
3275 3276 3277 3278 3279 3280 3281
3282
3283 ScreenToClient (FRAME_W32_WINDOW (f1), &pt);
3284 remember_mouse_glyph (f1, pt.x, pt.y, &last_mouse_glyph);
3285 last_mouse_glyph_frame = f1;
3286
3287 *bar_window = Qnil;
3288 *part = 0;
3289 *fp = f1;
3290 XSETINT (*x, pt.x);
3291 XSETINT (*y, pt.y);
3292 *time = last_mouse_movement_time;
3293 }
3294 }
3295 }
3296
3297 UNBLOCK_INPUT;
3298 }
3299
3300
3301 3302 3303
3304
3305 3306 3307
3308
3309 static void
3310 w32_handle_tool_bar_click (f, button_event)
3311 struct frame *f;
3312 struct input_event *button_event;
3313 {
3314 int x = XFASTINT (button_event->x);
3315 int y = XFASTINT (button_event->y);
3316
3317 if (button_event->modifiers & down_modifier)
3318 handle_tool_bar_click (f, x, y, 1, 0);
3319 else
3320 handle_tool_bar_click (f, x, y, 0,
3321 button_event->modifiers & ~up_modifier);
3322 }
3323
3324
3325
3326 3327 3328
3329
3330
3331
3332 3333 3334
3335
3336 static struct scroll_bar *
3337 x_window_to_scroll_bar (window_id)
3338 Window window_id;
3339 {
3340 Lisp_Object tail;
3341
3342 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
3343 {
3344 Lisp_Object frame, bar, condemned;
3345
3346 frame = XCAR (tail);
3347
3348 if (! FRAMEP (frame))
3349 abort ();
3350
3351 3352
3353 condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame));
3354 for (bar = FRAME_SCROLL_BARS (XFRAME (frame));
3355 3356
3357 ! NILP (bar) || (bar = condemned,
3358 condemned = Qnil,
3359 ! NILP (bar));
3360 bar = XSCROLL_BAR (bar)->next)
3361 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar)) == window_id)
3362 return XSCROLL_BAR (bar);
3363 }
3364
3365 return 0;
3366 }
3367
3368
3369
3370 3371
3372
3373 static void
3374 w32_set_scroll_bar_thumb (bar, portion, position, whole)
3375 struct scroll_bar *bar;
3376 int portion, position, whole;
3377 {
3378 Window w = SCROLL_BAR_W32_WINDOW (bar);
3379 3380 3381
3382 double range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height))
3383 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
3384 int sb_page, sb_pos;
3385 BOOL draggingp = !NILP (bar->dragging) ? TRUE : FALSE;
3386 SCROLLINFO si;
3387
3388 3389 3390 3391 3392 3393 3394
3395
3396 if (draggingp)
3397 {
3398 int near_bottom_p;
3399 BLOCK_INPUT;
3400 si.cbSize = sizeof (si);
3401 si.fMask = SIF_POS | SIF_PAGE;
3402 GetScrollInfo(w, SB_CTL, &si);
3403 near_bottom_p = si.nPos + si.nPage >= range;
3404 UNBLOCK_INPUT;
3405 if (!near_bottom_p)
3406 return;
3407 }
3408
3409 if (whole)
3410 {
3411 3412 3413
3414 if (position + portion >= whole && !draggingp)
3415 {
3416 sb_page = range * (whole - position) / whole;
3417 sb_pos = range;
3418 }
3419 else
3420 {
3421 sb_pos = position * range / whole;
3422 sb_page = (min (portion, (whole - position)) * range) / whole;
3423 }
3424 }
3425 else
3426 {
3427 sb_page = range;
3428 sb_pos = 0;
3429 }
3430
3431 sb_page = max (sb_page, VERTICAL_SCROLL_BAR_MIN_HANDLE);
3432
3433 BLOCK_INPUT;
3434
3435 si.cbSize = sizeof (si);
3436 si.fMask = SIF_PAGE | SIF_POS;
3437 si.nPage = sb_page;
3438 si.nPos = sb_pos;
3439
3440 SetScrollInfo (w, SB_CTL, &si, TRUE);
3441
3442 UNBLOCK_INPUT;
3443 }
3444
3445
3446 3447 3448
3449
3450 static HWND
3451 my_create_scrollbar (f, bar)
3452 struct frame * f;
3453 struct scroll_bar * bar;
3454 {
3455 return (HWND) SendMessage (FRAME_W32_WINDOW (f),
3456 WM_EMACS_CREATESCROLLBAR, (WPARAM) f,
3457 (LPARAM) bar);
3458 }
3459
3460
3461
3462 static BOOL
3463 my_show_window (FRAME_PTR f, HWND hwnd, int how)
3464 {
3465 #ifndef ATTACH_THREADS
3466 return SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SHOWWINDOW,
3467 (WPARAM) hwnd, (LPARAM) how);
3468 #else
3469 return ShowWindow (hwnd, how);
3470 #endif
3471 }
3472
3473 static void
3474 my_set_window_pos (HWND hwnd, HWND hwndAfter,
3475 int x, int y, int cx, int cy, UINT flags)
3476 {
3477 #ifndef ATTACH_THREADS
3478 WINDOWPOS pos;
3479 pos.hwndInsertAfter = hwndAfter;
3480 pos.x = x;
3481 pos.y = y;
3482 pos.cx = cx;
3483 pos.cy = cy;
3484 pos.flags = flags;
3485 SendMessage (hwnd, WM_EMACS_SETWINDOWPOS, (WPARAM) &pos, 0);
3486 #else
3487 SetWindowPos (hwnd, hwndAfter, x, y, cx, cy, flags);
3488 #endif
3489 }
3490
3491 static void
3492 my_set_focus (f, hwnd)
3493 struct frame * f;
3494 HWND hwnd;
3495 {
3496 SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SETFOCUS,
3497 (WPARAM) hwnd, 0);
3498 }
3499
3500 static void
3501 my_set_foreground_window (hwnd)
3502 HWND hwnd;
3503 {
3504 SendMessage (hwnd, WM_EMACS_SETFOREGROUND, (WPARAM) hwnd, 0);
3505 }
3506
3507
3508 static void
3509 my_destroy_window (f, hwnd)
3510 struct frame * f;
3511 HWND hwnd;
3512 {
3513 SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_DESTROYWINDOW,
3514 (WPARAM) hwnd, 0);
3515 }
3516
3517 3518 3519 3520
3521
3522 static struct scroll_bar *
3523 x_scroll_bar_create (w, top, left, width, height)
3524 struct window *w;
3525 int top, left, width, height;
3526 {
3527 struct frame *f = XFRAME (WINDOW_FRAME (w));
3528 HWND hwnd;
3529 SCROLLINFO si;
3530 struct scroll_bar *bar
3531 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
3532
3533 BLOCK_INPUT;
3534
3535 XSETWINDOW (bar->window, w);
3536 XSETINT (bar->top, top);
3537 XSETINT (bar->left, left);
3538 XSETINT (bar->width, width);
3539 XSETINT (bar->height, height);
3540 XSETINT (bar->start, 0);
3541 XSETINT (bar->end, 0);
3542 bar->dragging = Qnil;
3543 bar->fringe_extended_p = Qnil;
3544
3545
3546
3547 hwnd = my_create_scrollbar (f, bar);
3548
3549 si.cbSize = sizeof (si);
3550 si.fMask = SIF_ALL;
3551 si.nMin = 0;
3552 si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
3553 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
3554 si.nPage = si.nMax;
3555 si.nPos = 0;
3556
3557 SetScrollInfo (hwnd, SB_CTL, &si, FALSE);
3558
3559 SET_SCROLL_BAR_W32_WINDOW (bar, hwnd);
3560
3561
3562 bar->next = FRAME_SCROLL_BARS (f);
3563 bar->prev = Qnil;
3564 XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
3565 if (! NILP (bar->next))
3566 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
3567
3568 UNBLOCK_INPUT;
3569
3570 return bar;
3571 }
3572
3573
3574 3575
3576
3577 static void
3578 x_scroll_bar_remove (bar)
3579 struct scroll_bar *bar;
3580 {
3581 FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
3582
3583 BLOCK_INPUT;
3584
3585
3586 my_destroy_window (f, SCROLL_BAR_W32_WINDOW (bar));
3587
3588
3589 XWINDOW (bar->window)->vertical_scroll_bar = Qnil;
3590
3591 UNBLOCK_INPUT;
3592 }
3593
3594 3595 3596 3597
3598 static void
3599 w32_set_vertical_scroll_bar (w, portion, whole, position)
3600 struct window *w;
3601 int portion, whole, position;
3602 {
3603 struct frame *f = XFRAME (w->frame);
3604 struct scroll_bar *bar;
3605 int top, height, left, sb_left, width, sb_width;
3606 int window_y, window_height;
3607 int fringe_extended_p;
3608
3609
3610 window_box (w, -1, 0, &window_y, 0, &window_height);
3611 top = window_y;
3612 width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f);
3613 height = window_height;
3614
3615
3616 left = WINDOW_SCROLL_BAR_AREA_X (w);
3617
3618 3619
3620 if (WINDOW_CONFIG_SCROLL_BAR_WIDTH (w) > 0)
3621 sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
3622 else
3623 sb_width = width;
3624
3625
3626 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
3627 sb_left = left + (WINDOW_RIGHTMOST_P (w) ? width - sb_width : 0);
3628 else
3629 sb_left = left + (WINDOW_LEFTMOST_P (w) ? 0 : width - sb_width);
3630
3631 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
3632 fringe_extended_p = (WINDOW_LEFTMOST_P (w)
3633 && WINDOW_LEFT_FRINGE_WIDTH (w)
3634 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
3635 || WINDOW_LEFT_MARGIN_COLS (w) == 0));
3636 else
3637 fringe_extended_p = (WINDOW_RIGHTMOST_P (w)
3638 && WINDOW_RIGHT_FRINGE_WIDTH (w)
3639 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
3640 || WINDOW_RIGHT_MARGIN_COLS (w) == 0));
3641
3642
3643 if (NILP (w->vertical_scroll_bar))
3644 {
3645 HDC hdc;
3646 BLOCK_INPUT;
3647 if (width > 0 && height > 0)
3648 {
3649 hdc = get_frame_dc (f);
3650 if (fringe_extended_p)
3651 w32_clear_area (f, hdc, sb_left, top, sb_width, height);
3652 else
3653 w32_clear_area (f, hdc, left, top, width, height);
3654 release_frame_dc (f, hdc);
3655 }
3656 UNBLOCK_INPUT;
3657
3658 bar = x_scroll_bar_create (w, top, sb_left, sb_width, height);
3659 }
3660 else
3661 {
3662
3663 HWND hwnd;
3664
3665 bar = XSCROLL_BAR (w->vertical_scroll_bar);
3666 hwnd = SCROLL_BAR_W32_WINDOW (bar);
3667
3668
3669 if ( XINT (bar->left) == sb_left
3670 && XINT (bar->top) == top
3671 && XINT (bar->width) == sb_width
3672 && XINT (bar->height) == height
3673 && !NILP (bar->fringe_extended_p) == fringe_extended_p )
3674 {
3675
3676 if (!my_show_window (f, hwnd, SW_NORMAL))
3677 InvalidateRect (hwnd, NULL, FALSE);
3678 }
3679 else
3680 {
3681 HDC hdc;
3682 SCROLLINFO si;
3683
3684 BLOCK_INPUT;
3685 if (width && height)
3686 {
3687 hdc = get_frame_dc (f);
3688 3689
3690 if (fringe_extended_p)
3691 w32_clear_area (f, hdc, sb_left, top, sb_width, height);
3692 else
3693 w32_clear_area (f, hdc, left, top, width, height);
3694 release_frame_dc (f, hdc);
3695 }
3696 3697
3698 my_show_window (f, hwnd, SW_HIDE);
3699 MoveWindow (hwnd, sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
3700 top, sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
3701 max (height, 1), TRUE);
3702
3703 si.cbSize = sizeof (si);
3704 si.fMask = SIF_RANGE;
3705 si.nMin = 0;
3706 si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
3707 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
3708
3709 SetScrollInfo (hwnd, SB_CTL, &si, FALSE);
3710
3711 my_show_window (f, hwnd, SW_NORMAL);
3712
3713
3714
3715 XSETINT (bar->left, sb_left);
3716 XSETINT (bar->top, top);
3717 XSETINT (bar->width, sb_width);
3718 XSETINT (bar->height, height);
3719
3720 UNBLOCK_INPUT;
3721 }
3722 }
3723 bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil;
3724
3725 w32_set_scroll_bar_thumb (bar, portion, position, whole);
3726
3727 XSETVECTOR (w->vertical_scroll_bar, bar);
3728 }
3729
3730
3731 3732 3733 3734 3735 3736 3737
3738
3739 3740 3741
3742
3743 static void
3744 w32_condemn_scroll_bars (frame)
3745 FRAME_PTR frame;
3746 {
3747
3748 while (! NILP (FRAME_SCROLL_BARS (frame)))
3749 {
3750 Lisp_Object bar;
3751 bar = FRAME_SCROLL_BARS (frame);
3752 FRAME_SCROLL_BARS (frame) = XSCROLL_BAR (bar)->next;
3753 XSCROLL_BAR (bar)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
3754 XSCROLL_BAR (bar)->prev = Qnil;
3755 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
3756 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = bar;
3757 FRAME_CONDEMNED_SCROLL_BARS (frame) = bar;
3758 }
3759 }
3760
3761
3762 3763
3764
3765 static void
3766 w32_redeem_scroll_bar (window)
3767 struct window *window;
3768 {
3769 struct scroll_bar *bar;
3770 struct frame *f;
3771
3772
3773 if (NILP (window->vertical_scroll_bar))
3774 abort ();
3775
3776 bar = XSCROLL_BAR (window->vertical_scroll_bar);
3777
3778
3779 f = XFRAME (WINDOW_FRAME (window));
3780 if (NILP (bar->prev))
3781 {
3782 3783
3784 if (EQ (FRAME_SCROLL_BARS (f), window->vertical_scroll_bar))
3785
3786 return;
3787 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
3788 window->vertical_scroll_bar))
3789 FRAME_CONDEMNED_SCROLL_BARS (f) = bar->next;
3790 else
3791 3792
3793 abort ();
3794 }
3795 else
3796 XSCROLL_BAR (bar->prev)->next = bar->next;
3797
3798 if (! NILP (bar->next))
3799 XSCROLL_BAR (bar->next)->prev = bar->prev;
3800
3801 bar->next = FRAME_SCROLL_BARS (f);
3802 bar->prev = Qnil;
3803 XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
3804 if (! NILP (bar->next))
3805 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
3806 }
3807
3808 3809
3810
3811 static void
3812 w32_judge_scroll_bars (f)
3813 FRAME_PTR f;
3814 {
3815 Lisp_Object bar, next;
3816
3817 bar = FRAME_CONDEMNED_SCROLL_BARS (f);
3818
3819 3820
3821 FRAME_CONDEMNED_SCROLL_BARS (f) = Qnil;
3822
3823 for (; ! NILP (bar); bar = next)
3824 {
3825 struct scroll_bar *b = XSCROLL_BAR (bar);
3826
3827 x_scroll_bar_remove (b);
3828
3829 next = b->next;
3830 b->next = b->prev = Qnil;
3831 }
3832
3833 3834
3835 }
3836
3837 3838 3839 3840 3841
3842
3843 static int
3844 w32_scroll_bar_handle_click (bar, msg, emacs_event)
3845 struct scroll_bar *bar;
3846 W32Msg *msg;
3847 struct input_event *emacs_event;
3848 {
3849 if (! WINDOWP (bar->window))
3850 abort ();
3851
3852 emacs_event->kind = SCROLL_BAR_CLICK_EVENT;
3853 emacs_event->code = 0;
3854
3855 emacs_event->modifiers = msg->dwModifiers;
3856 emacs_event->frame_or_window = bar->window;
3857 emacs_event->arg = Qnil;
3858 emacs_event->timestamp = msg->msg.time;
3859
3860 {
3861 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
3862 int y;
3863 int dragging = !NILP (bar->dragging);
3864 SCROLLINFO si;
3865
3866 si.cbSize = sizeof (si);
3867 si.fMask = SIF_POS;
3868
3869 GetScrollInfo ((HWND) msg->msg.lParam, SB_CTL, &si);
3870 y = si.nPos;
3871
3872 bar->dragging = Qnil;
3873
3874
3875 last_mouse_scroll_bar_pos = msg->msg.wParam;
3876
3877 switch (LOWORD (msg->msg.wParam))
3878 {
3879 case SB_LINEDOWN:
3880 emacs_event->part = scroll_bar_down_arrow;
3881 break;
3882 case SB_LINEUP:
3883 emacs_event->part = scroll_bar_up_arrow;
3884 break;
3885 case SB_PAGEUP:
3886 emacs_event->part = scroll_bar_above_handle;
3887 break;
3888 case SB_PAGEDOWN:
3889 emacs_event->part = scroll_bar_below_handle;
3890 break;
3891 case SB_TOP:
3892 emacs_event->part = scroll_bar_handle;
3893 y = 0;
3894 break;
3895 case SB_BOTTOM:
3896 emacs_event->part = scroll_bar_handle;
3897 y = top_range;
3898 break;
3899 case SB_THUMBTRACK:
3900 case SB_THUMBPOSITION:
3901 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)) <= 0xffff)
3902 y = HIWORD (msg->msg.wParam);
3903 bar->dragging = Qt;
3904 emacs_event->part = scroll_bar_handle;
3905
3906
3907 {
3908 SCROLLINFO si;
3909
3910 si.cbSize = sizeof (si);
3911 si.fMask = SIF_POS;
3912 si.nPos = y;
3913 3914
3915 last_scroll_bar_drag_pos = y;
3916
3917 SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, FALSE);
3918 }
3919 break;
3920 case SB_ENDSCROLL:
3921 3922 3923
3924 if (dragging)
3925 {
3926 SCROLLINFO si;
3927 int start = XINT (bar->start);
3928 int end = XINT (bar->end);
3929
3930 si.cbSize = sizeof (si);
3931 si.fMask = SIF_PAGE | SIF_POS;
3932 si.nPage = end - start + VERTICAL_SCROLL_BAR_MIN_HANDLE;
3933 si.nPos = last_scroll_bar_drag_pos;
3934 SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE);
3935 }
3936
3937 default:
3938 emacs_event->kind = NO_EVENT;
3939 return FALSE;
3940 }
3941
3942 XSETINT (emacs_event->x, y);
3943 XSETINT (emacs_event->y, top_range);
3944
3945 return TRUE;
3946 }
3947 }
3948
3949 3950
3951
3952 static void
3953 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
3954 FRAME_PTR *fp;
3955 Lisp_Object *bar_window;
3956 enum scroll_bar_part *part;
3957 Lisp_Object *x, *y;
3958 unsigned long *time;
3959 {
3960 struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
3961 Window w = SCROLL_BAR_W32_WINDOW (bar);
3962 FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
3963 int pos;
3964 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
3965 SCROLLINFO si;
3966
3967 BLOCK_INPUT;
3968
3969 *fp = f;
3970 *bar_window = bar->window;
3971
3972 si.cbSize = sizeof (si);
3973 si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
3974
3975 GetScrollInfo (w, SB_CTL, &si);
3976 pos = si.nPos;
3977 top_range = si.nMax - si.nPage + 1;
3978
3979 switch (LOWORD (last_mouse_scroll_bar_pos))
3980 {
3981 case SB_THUMBPOSITION:
3982 case SB_THUMBTRACK:
3983 *part = scroll_bar_handle;
3984 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)) <= 0xffff)
3985 pos = HIWORD (last_mouse_scroll_bar_pos);
3986 break;
3987 case SB_LINEDOWN:
3988 *part = scroll_bar_handle;
3989 pos++;
3990 break;
3991 default:
3992 *part = scroll_bar_handle;
3993 break;
3994 }
3995
3996 XSETINT (*x, pos);
3997 XSETINT (*y, top_range);
3998
3999 f->mouse_moved = 0;
4000 last_mouse_scroll_bar = Qnil;
4001
4002 *time = last_mouse_movement_time;
4003
4004 UNBLOCK_INPUT;
4005 }
4006
4007
4008 4009 4010 4011
4012
4013 void
4014 x_scroll_bar_clear (f)
4015 FRAME_PTR f;
4016 {
4017 Lisp_Object bar;
4018
4019 4020 4021
4022 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
4023 for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
4024 bar = XSCROLL_BAR (bar)->next)
4025 {
4026 HWND window = SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar));
4027 HDC hdc = GetDC (window);
4028 RECT rect;
4029
4030 4031
4032 my_show_window (f, window, SW_HIDE);
4033
4034 GetClientRect (window, &rect);
4035 select_palette (f, hdc);
4036 w32_clear_rect (f, hdc, &rect);
4037 deselect_palette (f, hdc);
4038
4039 ReleaseDC (window, hdc);
4040 }
4041 }
4042
4043
4044
4045
4046 4047
4048
4049 static int temp_index;
4050 static short temp_buffer[100];
4051
4052
4053 static char dbcs_lead = 0;
4054
4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071
4072
4073 int
4074 w32_read_socket (sd, expected, hold_quit)
4075 register int sd;
4076 int expected;
4077 struct input_event *hold_quit;
4078 {
4079 int count = 0;
4080 int check_visibility = 0;
4081 W32Msg msg;
4082 struct frame *f;
4083 struct w32_display_info *dpyinfo = &one_w32_display_info;
4084
4085 if (interrupt_input_blocked)
4086 {
4087 interrupt_input_pending = 1;
4088 return -1;
4089 }
4090
4091 interrupt_input_pending = 0;
4092 BLOCK_INPUT;
4093
4094
4095 input_signal_count++;
4096
4097
4098 while (get_next_msg (&msg, FALSE))
4099 {
4100 struct input_event inev;
4101 int do_help = 0;
4102
4103 EVENT_INIT (inev);
4104 inev.kind = NO_EVENT;
4105 inev.arg = Qnil;
4106
4107 switch (msg.msg.message)
4108 {
4109 case WM_EMACS_PAINT:
4110 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4111
4112 if (f)
4113 {
4114 if (msg.rect.right == msg.rect.left ||
4115 msg.rect.bottom == msg.rect.top)
4116 {
4117 4118
4119 DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f,
4120 SDATA (f->name)));
4121 }
4122 else if (f->async_visible != 1)
4123 {
4124
4125 f->async_visible = 1;
4126 f->async_iconified = 0;
4127 SET_FRAME_GARBAGED (f);
4128 DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f,
4129 SDATA (f->name)));
4130
4131 4132
4133 if (f->iconified)
4134 {
4135 inev.kind = DEICONIFY_EVENT;
4136 XSETFRAME (inev.frame_or_window, f);
4137 }
4138 else if (! NILP (Vframe_list)
4139 && ! NILP (XCDR (Vframe_list)))
4140 4141
4142 record_asynch_buffer_change ();
4143 }
4144 else
4145 {
4146 HDC hdc = get_frame_dc (f);
4147
4148
4149 w32_clear_rect (f, hdc, &msg.rect);
4150 release_frame_dc (f, hdc);
4151 expose_frame (f,
4152 msg.rect.left,
4153 msg.rect.top,
4154 msg.rect.right - msg.rect.left,
4155 msg.rect.bottom - msg.rect.top);
4156 }
4157 }
4158 break;
4159
4160 case WM_INPUTLANGCHANGE:
4161
4162 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4163
4164 4165
4166 keyboard_codepage = codepage_for_locale ((LCID)(msg.msg.lParam
4167 & 0xffff));
4168
4169 if (f)
4170 {
4171 inev.kind = LANGUAGE_CHANGE_EVENT;
4172 XSETFRAME (inev.frame_or_window, f);
4173 inev.code = msg.msg.wParam;
4174 inev.modifiers = msg.msg.lParam & 0xffff;
4175 }
4176 break;
4177
4178 case WM_KEYDOWN:
4179 case WM_SYSKEYDOWN:
4180 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4181
4182 if (f && !f->iconified)
4183 {
4184 if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
4185 && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
4186 {
4187 clear_mouse_face (dpyinfo);
4188 dpyinfo->mouse_face_hidden = 1;
4189 }
4190
4191 if (temp_index == sizeof temp_buffer / sizeof (short))
4192 temp_index = 0;
4193 temp_buffer[temp_index++] = msg.msg.wParam;
4194 inev.kind = NON_ASCII_KEYSTROKE_EVENT;
4195 inev.code = msg.msg.wParam;
4196 inev.modifiers = msg.dwModifiers;
4197 XSETFRAME (inev.frame_or_window, f);
4198 inev.timestamp = msg.msg.time;
4199 }
4200 break;
4201
4202 case WM_UNICHAR:
4203 case WM_SYSCHAR:
4204 case WM_CHAR:
4205 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4206
4207 if (f && !f->iconified)
4208 {
4209 if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
4210 && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
4211 {
4212 clear_mouse_face (dpyinfo);
4213 dpyinfo->mouse_face_hidden = 1;
4214 }
4215
4216 if (temp_index == sizeof temp_buffer / sizeof (short))
4217 temp_index = 0;
4218 temp_buffer[temp_index++] = msg.msg.wParam;
4219
4220 inev.modifiers = msg.dwModifiers;
4221 XSETFRAME (inev.frame_or_window, f);
4222 inev.timestamp = msg.msg.time;
4223
4224 if (msg.msg.message == WM_UNICHAR)
4225 {
4226 inev.code = msg.msg.wParam;
4227 }
4228 else if (msg.msg.wParam < 256)
4229 {
4230 wchar_t code;
4231 char dbcs[2];
4232 dbcs[0] = 0;
4233 dbcs[1] = (char) msg.msg.wParam;
4234
4235 if (dbcs_lead)
4236 {
4237 dbcs[0] = dbcs_lead;
4238 dbcs_lead = 0;
4239 if (!MultiByteToWideChar (keyboard_codepage, 0,
4240 dbcs, 2, &code, 1))
4241 {
4242
4243 DebPrint (("Invalid DBCS sequence: %d %d\n",
4244 dbcs[0], dbcs[1]));
4245 inev.kind = NO_EVENT;
4246 break;
4247 }
4248 }
4249 else if (IsDBCSLeadByteEx (keyboard_codepage,
4250 (BYTE) msg.msg.wParam))
4251 {
4252 dbcs_lead = (char) msg.msg.wParam;
4253 inev.kind = NO_EVENT;
4254 break;
4255 }
4256 else
4257 {
4258 if (!MultiByteToWideChar (keyboard_codepage, 0,
4259 &dbcs[1], 1, &code, 1))
4260 {
4261
4262 DebPrint (("Invalid character: %d\n", dbcs[1]));
4263 inev.kind = NO_EVENT;
4264 break;
4265 }
4266 }
4267 inev.code = code;
4268 }
4269 else
4270 {
4271 4272
4273 DebPrint (("Non-byte WM_CHAR: %d\n", msg.msg.wParam));
4274 inev.kind = NO_EVENT;
4275 break;
4276 }
4277 inev.kind = inev.code < 128 ? ASCII_KEYSTROKE_EVENT
4278 : MULTIBYTE_CHAR_KEYSTROKE_EVENT;
4279 }
4280 break;
4281
4282 case WM_APPCOMMAND:
4283 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4284
4285 if (f && !f->iconified)
4286 {
4287 if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
4288 && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
4289 {
4290 clear_mouse_face (dpyinfo);
4291 dpyinfo->mouse_face_hidden = 1;
4292 }
4293
4294 if (temp_index == sizeof temp_buffer / sizeof (short))
4295 temp_index = 0;
4296 temp_buffer[temp_index++] = msg.msg.wParam;
4297 inev.kind = MULTIMEDIA_KEY_EVENT;
4298 inev.code = GET_APPCOMMAND_LPARAM(msg.msg.lParam);
4299 inev.modifiers = msg.dwModifiers;
4300 XSETFRAME (inev.frame_or_window, f);
4301 inev.timestamp = msg.msg.time;
4302 }
4303 break;
4304
4305 case WM_MOUSEMOVE:
4306
4307 {
4308 int x = LOWORD (msg.msg.lParam);
4309 int y = HIWORD (msg.msg.lParam);
4310 if (x == last_mousemove_x && y == last_mousemove_y)
4311 break;
4312 last_mousemove_x = x;
4313 last_mousemove_y = y;
4314 }
4315
4316 previous_help_echo_string = help_echo_string;
4317 help_echo_string = Qnil;
4318
4319 if (dpyinfo->grabbed && last_mouse_frame
4320 && FRAME_LIVE_P (last_mouse_frame))
4321 f = last_mouse_frame;
4322 else
4323 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4324
4325 if (dpyinfo->mouse_face_hidden)
4326 {
4327 dpyinfo->mouse_face_hidden = 0;
4328 clear_mouse_face (dpyinfo);
4329 }
4330
4331 if (f)
4332 {
4333
4334 if (!NILP (Vmouse_autoselect_window))
4335 {
4336 Lisp_Object window;
4337 int x = LOWORD (msg.msg.lParam);
4338 int y = HIWORD (msg.msg.lParam);
4339
4340 window = window_from_coordinates (f, x, y, 0, 0, 0, 0);
4341
4342 4343 4344 4345
4346 if (WINDOWP(window)
4347 && !EQ (window, last_window)
4348 && !EQ (window, selected_window)
4349 4350 4351
4352 && (focus_follows_mouse
4353 || (EQ (XWINDOW (window)->frame,
4354 XWINDOW (selected_window)->frame))))
4355 {
4356 inev.kind = SELECT_WINDOW_EVENT;
4357 inev.frame_or_window = window;
4358 }
4359
4360 last_window=window;
4361 }
4362 if (!note_mouse_movement (f, &msg.msg))
4363 help_echo_string = previous_help_echo_string;
4364 }
4365 else
4366 {
4367 4368
4369 clear_mouse_face (dpyinfo);
4370 }
4371
4372 4373
4374 #if 0 4375 4376
4377 if (help_echo_string != previous_help_echo_string ||
4378 (!NILP (help_echo_string) && !STRINGP (help_echo_string) && f->mouse_moved))
4379 #else
4380 if (!NILP (help_echo_string)
4381 || !NILP (previous_help_echo_string))
4382 do_help = 1;
4383 #endif
4384 break;
4385
4386 case WM_LBUTTONDOWN:
4387 case WM_LBUTTONUP:
4388 case WM_MBUTTONDOWN:
4389 case WM_MBUTTONUP:
4390 case WM_RBUTTONDOWN:
4391 case WM_RBUTTONUP:
4392 case WM_XBUTTONDOWN:
4393 case WM_XBUTTONUP:
4394 {
4395 4396
4397 int tool_bar_p = 0;
4398 int button;
4399 int up;
4400
4401 if (dpyinfo->grabbed && last_mouse_frame
4402 && FRAME_LIVE_P (last_mouse_frame))
4403 f = last_mouse_frame;
4404 else
4405 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4406
4407 if (f)
4408 {
4409 construct_mouse_click (&inev, &msg, f);
4410
4411
4412 if (WINDOWP (f->tool_bar_window)
4413 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
4414 {
4415 Lisp_Object window;
4416 int x = XFASTINT (inev.x);
4417 int y = XFASTINT (inev.y);
4418
4419 window = window_from_coordinates (f, x, y, 0, 0, 0, 1);
4420
4421 if (EQ (window, f->tool_bar_window))
4422 {
4423 w32_handle_tool_bar_click (f, &inev);
4424 tool_bar_p = 1;
4425 }
4426 }
4427
4428 if (tool_bar_p
4429 || (dpyinfo->w32_focus_frame
4430 && f != dpyinfo->w32_focus_frame))
4431 inev.kind = NO_EVENT;
4432 }
4433
4434 parse_button (msg.msg.message, HIWORD (msg.msg.wParam),
4435 &button, &up);
4436
4437 if (up)
4438 {
4439 dpyinfo->grabbed &= ~ (1 << button);
4440 }
4441 else
4442 {
4443 dpyinfo->grabbed |= (1 << button);
4444 last_mouse_frame = f;
4445 4446 4447 4448
4449 if (f != 0)
4450 f->mouse_moved = 0;
4451
4452 if (!tool_bar_p)
4453 last_tool_bar_item = -1;
4454 }
4455 break;
4456 }
4457
4458 case WM_MOUSEWHEEL:
4459 case WM_MOUSEHWHEEL:
4460 {
4461 if (dpyinfo->grabbed && last_mouse_frame
4462 && FRAME_LIVE_P (last_mouse_frame))
4463 f = last_mouse_frame;
4464 else
4465 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4466
4467 if (f)
4468 {
4469
4470 if (!dpyinfo->w32_focus_frame
4471 || f == dpyinfo->w32_focus_frame)
4472 {
4473
4474 construct_mouse_wheel (&inev, &msg, f);
4475 }
4476 4477 4478 4479
4480 f->mouse_moved = 0;
4481 }
4482 last_mouse_frame = f;
4483 last_tool_bar_item = -1;
4484 }
4485 break;
4486
4487 case WM_DROPFILES:
4488 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4489
4490 if (f)
4491 construct_drag_n_drop (&inev, &msg, f);
4492 break;
4493
4494 case WM_VSCROLL:
4495 {
4496 struct scroll_bar *bar =
4497 x_window_to_scroll_bar ((HWND)msg.msg.lParam);
4498
4499 if (bar)
4500 w32_scroll_bar_handle_click (bar, &msg, &inev);
4501 break;
4502 }
4503
4504 case WM_WINDOWPOSCHANGED:
4505 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4506 if (f)
4507 {
4508 if (f->want_fullscreen & FULLSCREEN_WAIT)
4509 f->want_fullscreen &= ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH);
4510 }
4511 check_visibility = 1;
4512 break;
4513
4514 case WM_ACTIVATE:
4515 case WM_ACTIVATEAPP:
4516 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4517 if (f)
4518 x_check_fullscreen (f);
4519 check_visibility = 1;
4520 break;
4521
4522 case WM_MOVE:
4523 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4524
4525 if (f && !f->async_iconified)
4526 {
4527 int x, y;
4528
4529 x_real_positions (f, &x, &y);
4530 f->left_pos = x;
4531 f->top_pos = y;
4532 }
4533
4534 check_visibility = 1;
4535 break;
4536
4537 case WM_SHOWWINDOW:
4538 4539
4540
4541 if (!msg.msg.wParam && msg.msg.hwnd == tip_window)
4542 {
4543 tip_window = NULL;
4544 redo_mouse_highlight ();
4545 }
4546
4547 4548 4549 4550
4551 #if 0
4552 if (msg.msg.lParam != 0)
4553 check_visibility = 1;
4554 else
4555 {
4556 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4557 f->async_visible = msg.msg.wParam;
4558 }
4559 #endif
4560
4561 check_visibility = 1;
4562 break;
4563
4564 case WM_SIZE:
4565 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4566
4567
4568 if (f)
4569 {
4570 switch (msg.msg.wParam)
4571 {
4572 case SIZE_MINIMIZED:
4573 f->async_visible = 0;
4574 f->async_iconified = 1;
4575
4576 inev.kind = ICONIFY_EVENT;
4577 XSETFRAME (inev.frame_or_window, f);
4578 break;
4579
4580 case SIZE_MAXIMIZED:
4581 case SIZE_RESTORED:
4582 f->async_visible = 1;
4583 f->async_iconified = 0;
4584
4585 4586
4587 SET_FRAME_GARBAGED (f);
4588
4589 if (f->iconified)
4590 {
4591 int x, y;
4592
4593 4594 4595 4596 4597
4598 x_real_positions (f, &x, &y);
4599 f->left_pos = x;
4600 f->top_pos = y;
4601
4602 inev.kind = DEICONIFY_EVENT;
4603 XSETFRAME (inev.frame_or_window, f);
4604 }
4605 else if (! NILP (Vframe_list)
4606 && ! NILP (XCDR (Vframe_list)))
4607 4608 4609
4610 record_asynch_buffer_change ();
4611 break;
4612 }
4613 }
4614
4615 if (f && !f->async_iconified && msg.msg.wParam != SIZE_MINIMIZED)
4616 {
4617 RECT rect;
4618 int rows;
4619 int columns;
4620 int width;
4621 int height;
4622
4623 GetClientRect (msg.msg.hwnd, &rect);
4624
4625 height = rect.bottom - rect.top;
4626 width = rect.right - rect.left;
4627
4628 rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height);
4629 columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width);
4630
4631
4632
4633 4634 4635
4636
4637 if (columns != FRAME_COLS (f)
4638 || rows != FRAME_LINES (f)
4639 || width != FRAME_PIXEL_WIDTH (f)
4640 || height != FRAME_PIXEL_HEIGHT (f))
4641 {
4642 change_frame_size (f, rows, columns, 0, 1, 0);
4643 SET_FRAME_GARBAGED (f);
4644 cancel_mouse_face (f);
4645 FRAME_PIXEL_WIDTH (f) = width;
4646 FRAME_PIXEL_HEIGHT (f) = height;
4647 f->win_gravity = NorthWestGravity;
4648 }
4649 }
4650
4651 check_visibility = 1;
4652 break;
4653
4654 case WM_MOUSELEAVE:
4655 f = x_any_window_to_frame (dpyinfo, msg.msg.hwnd);
4656 if (f)
4657 {
4658 if (f == dpyinfo->mouse_face_mouse_frame)
4659 {
4660 4661
4662 clear_mouse_face (dpyinfo);
4663 dpyinfo->mouse_face_mouse_frame = 0;
4664 }
4665
4666 4667 4668 4669
4670 if (any_help_event_p)
4671 do_help = -1;
4672 }
4673 break;
4674
4675 case WM_SETFOCUS:
4676 w32_detect_focus_change (dpyinfo, &msg, &inev);
4677
4678 dpyinfo->grabbed = 0;
4679 check_visibility = 1;
4680 break;
4681
4682 case WM_KILLFOCUS:
4683 f = x_top_window_to_frame (dpyinfo, msg.msg.hwnd);
4684
4685 if (f)
4686 {
4687 if (f == dpyinfo->w32_focus_event_frame)
4688 dpyinfo->w32_focus_event_frame = 0;
4689
4690 if (f == dpyinfo->w32_focus_frame)
4691 x_new_focus_frame (dpyinfo, 0);
4692
4693 if (f == dpyinfo->mouse_face_mouse_frame)
4694 {
4695 4696
4697 clear_mouse_face (dpyinfo);
4698 dpyinfo->mouse_face_mouse_frame = 0;
4699 }
4700
4701 4702 4703 4704
4705 if (any_help_event_p)
4706 do_help = -1;
4707 }
4708
4709 dpyinfo->grabbed = 0;
4710 check_visibility = 1;
4711 break;
4712
4713 case WM_CLOSE:
4714 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4715
4716 if (f)
4717 {
4718 inev.kind = DELETE_WINDOW_EVENT;
4719 XSETFRAME (inev.frame_or_window, f);
4720 }
4721 break;
4722
4723 case WM_INITMENU:
4724 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4725
4726 if (f)
4727 {
4728 inev.kind = MENU_BAR_ACTIVATE_EVENT;
4729 XSETFRAME (inev.frame_or_window, f);
4730 }
4731 break;
4732
4733 case WM_COMMAND:
4734 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4735
4736 if (f)
4737 {
4738 extern void menubar_selection_callback
4739 (FRAME_PTR f, void * client_data);
4740 menubar_selection_callback (f, (void *)msg.msg.wParam);
4741 }
4742
4743 check_visibility = 1;
4744 break;
4745
4746 case WM_DISPLAYCHANGE:
4747 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4748
4749 if (f)
4750 {
4751 dpyinfo->n_cbits = msg.msg.wParam;
4752 DebPrint (("display change: %d %d\n",
4753 (short) LOWORD (msg.msg.lParam),
4754 (short) HIWORD (msg.msg.lParam)));
4755 }
4756
4757 check_visibility = 1;
4758 break;
4759
4760 default:
4761
4762 if (msg.msg.message == msh_mousewheel)
4763 {
4764
4765 msg.msg.message = WM_MOUSEWHEEL;
4766 prepend_msg (&msg);
4767 }
4768 break;
4769 }
4770
4771 if (inev.kind != NO_EVENT)
4772 {
4773 kbd_buffer_store_event_hold (&inev, hold_quit);
4774 count++;
4775 }
4776
4777 if (do_help
4778 && !(hold_quit && hold_quit->kind != NO_EVENT))
4779 {
4780 Lisp_Object frame;
4781
4782 if (f)
4783 XSETFRAME (frame, f);
4784 else
4785 frame = Qnil;
4786
4787 if (do_help > 0)
4788 {
4789 if (NILP (help_echo_string))
4790 {
4791 help_echo_object = help_echo_window = Qnil;
4792 help_echo_pos = -1;
4793 }
4794
4795 any_help_event_p = 1;
4796 gen_help_event (help_echo_string, frame, help_echo_window,
4797 help_echo_object, help_echo_pos);
4798 }
4799 else
4800 {
4801 help_echo_string = Qnil;
4802 gen_help_event (Qnil, frame, Qnil, Qnil, 0);
4803 }
4804 count++;
4805 }
4806 }
4807
4808 4809
4810
4811 if (pending_autoraise_frame)
4812 {
4813 x_raise_frame (pending_autoraise_frame);
4814 pending_autoraise_frame = 0;
4815 }
4816
4817 4818 4819 4820 4821
4822 if (count > 0 || check_visibility)
4823 {
4824 Lisp_Object tail, frame;
4825
4826 FOR_EACH_FRAME (tail, frame)
4827 {
4828 FRAME_PTR f = XFRAME (frame);
4829 4830
4831 if (EQ (frame, tip_frame))
4832 continue;
4833
4834 4835 4836
4837 if (FRAME_W32_P (f) && f->async_visible)
4838 {
4839 RECT clipbox;
4840 HDC hdc;
4841
4842 enter_crit ();
4843 4844 4845 4846 4847 4848
4849 hdc = GetWindowDC (FRAME_W32_WINDOW (f));
4850 GetClipBox (hdc, &clipbox);
4851 ReleaseDC (FRAME_W32_WINDOW (f), hdc);
4852 leave_crit ();
4853
4854 if (clipbox.right == clipbox.left
4855 || clipbox.bottom == clipbox.top)
4856 {
4857 4858 4859 4860
4861 f->async_visible = 2;
4862
4863 if (!FRAME_OBSCURED_P (f))
4864 {
4865 DebPrint (("frame %p (%s) obscured\n", f,
4866 SDATA (f->name)));
4867 }
4868 }
4869 else
4870 {
4871
4872 f->async_visible = 1;
4873
4874 if (FRAME_OBSCURED_P (f))
4875 {
4876 SET_FRAME_GARBAGED (f);
4877 DebPrint (("obscured frame %p (%s) found to be visible\n", f,
4878 SDATA (f->name)));
4879
4880
4881 record_asynch_buffer_change ();
4882 }
4883 }
4884 }
4885 }
4886 }
4887
4888 UNBLOCK_INPUT;
4889 return count;
4890 }
4891
4892
4893
4894 4895 4896
4897
4898 4899 4900 4901 4902 4903
4904
4905 static void
4906 w32_clip_to_row (w, row, area, hdc)
4907 struct window *w;
4908 struct glyph_row *row;
4909 int area;
4910 HDC hdc;
4911 {
4912 struct frame *f = XFRAME (WINDOW_FRAME (w));
4913 RECT clip_rect;
4914 int window_x, window_y, window_width;
4915
4916 window_box (w, area, &window_x, &window_y, &window_width, 0);
4917
4918 clip_rect.left = window_x;
4919 clip_rect.top = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
4920 clip_rect.top = max (clip_rect.top, window_y);
4921 clip_rect.right = clip_rect.left + window_width;
4922 clip_rect.bottom = clip_rect.top + row->visible_height;
4923
4924 w32_set_clip_rectangle (hdc, &clip_rect);
4925 }
4926
4927
4928
4929
4930 static void
4931 x_draw_hollow_cursor (w, row)
4932 struct window *w;
4933 struct glyph_row *row;
4934 {
4935 struct frame *f = XFRAME (WINDOW_FRAME (w));
4936 HDC hdc;
4937 RECT rect;
4938 int left, top, h;
4939 struct glyph *cursor_glyph;
4940 HBRUSH hb = CreateSolidBrush (f->output_data.w32->cursor_pixel);
4941
4942 4943
4944 cursor_glyph = get_phys_cursor_glyph (w);
4945 if (cursor_glyph == NULL)
4946 return;
4947
4948
4949 get_phys_cursor_geometry (w, row, cursor_glyph, &left, &top, &h);
4950 rect.left = left;
4951 rect.top = top;
4952 rect.bottom = rect.top + h;
4953 rect.right = rect.left + w->phys_cursor_width;
4954
4955 hdc = get_frame_dc (f);
4956
4957 w32_clip_to_row (w, row, TEXT_AREA, hdc);
4958 FrameRect (hdc, &rect, hb);
4959 DeleteObject (hb);
4960 w32_set_clip_rectangle (hdc, NULL);
4961 release_frame_dc (f, hdc);
4962 }
4963
4964
4965 4966 4967 4968 4969 4970
4971
4972 static void
4973 x_draw_bar_cursor (w, row, width, kind)
4974 struct window *w;
4975 struct glyph_row *row;
4976 int width;
4977 enum text_cursor_kinds kind;
4978 {
4979 struct frame *f = XFRAME (w->frame);
4980 struct glyph *cursor_glyph;
4981
4982 4983 4984
4985 cursor_glyph = get_phys_cursor_glyph (w);
4986 if (cursor_glyph == NULL)
4987 return;
4988
4989 4990 4991
4992 if (cursor_glyph->type == IMAGE_GLYPH)
4993 {
4994 struct glyph_row *row;
4995 row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
4996 draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
4997 }
4998 else
4999 {
5000 COLORREF cursor_color = f->output_data.w32->cursor_pixel;
5001 struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
5002 int x;
5003 HDC hdc;
5004
5005 5006 5007 5008 5009
5010 if (face->background == cursor_color)
5011 cursor_color = face->foreground;
5012
5013 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
5014
5015 hdc = get_frame_dc (f);
5016 w32_clip_to_row (w, row, TEXT_AREA, hdc);
5017
5018 if (kind == BAR_CURSOR)
5019 {
5020 if (width < 0)
5021 width = FRAME_CURSOR_WIDTH (f);
5022 width = min (cursor_glyph->pixel_width, width);
5023
5024 w->phys_cursor_width = width;
5025
5026 w32_fill_area (f, hdc, cursor_color, x,
5027 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
5028 width, row->height);
5029 }
5030 else
5031 {
5032 int dummy_x, dummy_y, dummy_h;
5033
5034 if (width < 0)
5035 width = row->height;
5036
5037 width = min (row->height, width);
5038
5039 get_phys_cursor_geometry (w, row, cursor_glyph, &dummy_x,
5040 &dummy_y, &dummy_h);
5041 w32_fill_area (f, hdc, cursor_color, x,
5042 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
5043 row->height - width),
5044 w->phys_cursor_width, width);
5045 }
5046
5047 w32_set_clip_rectangle (hdc, NULL);
5048 release_frame_dc (f, hdc);
5049 }
5050 }
5051
5052
5053
5054
5055 static void
5056 w32_define_frame_cursor (f, cursor)
5057 struct frame *f;
5058 Cursor cursor;
5059 {
5060 w32_define_cursor (FRAME_W32_WINDOW (f), cursor);
5061 }
5062
5063
5064
5065
5066 static void
5067 w32_clear_frame_area (f, x, y, width, height)
5068 struct frame *f;
5069 int x, y, width, height;
5070 {
5071 HDC hdc;
5072
5073 hdc = get_frame_dc (f);
5074 w32_clear_area (f, hdc, x, y, width, height);
5075 release_frame_dc (f, hdc);
5076 }
5077
5078
5079
5080 static void
5081 w32_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, active_p)
5082 struct window *w;
5083 struct glyph_row *glyph_row;
5084 int x, y;
5085 int cursor_type, cursor_width;
5086 int on_p, active_p;
5087 {
5088 if (on_p)
5089 {
5090 5091
5092 if (w32_use_visible_system_caret)
5093 {
5094 5095 5096
5097 if (w->phys_cursor_type != NO_CURSOR)
5098 erase_phys_cursor (w);
5099
5100 cursor_type = w->phys_cursor_type = NO_CURSOR;
5101 w->phys_cursor_width = -1;
5102 }
5103 else
5104 {
5105 w->phys_cursor_type = cursor_type;
5106 }
5107
5108 w->phys_cursor_on_p = 1;
5109
5110 5111 5112
5113 if (active_p)
5114 {
5115 struct frame *f = XFRAME (WINDOW_FRAME (w));
5116 HWND hwnd = FRAME_W32_WINDOW (f);
5117
5118 w32_system_caret_x
5119 = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
5120 w32_system_caret_y
5121 = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
5122 + glyph_row->ascent - w->phys_cursor_ascent);
5123
5124 PostMessage (hwnd, WM_IME_STARTCOMPOSITION, 0, 0);
5125
5126 5127
5128 if (w32_system_caret_hwnd
5129 && (w32_system_caret_height != w->phys_cursor_height))
5130 PostMessage (hwnd, WM_EMACS_DESTROY_CARET, 0, 0);
5131
5132 w32_system_caret_height = w->phys_cursor_height;
5133
5134
5135 PostMessage (hwnd, WM_EMACS_TRACK_CARET, 0, 0);
5136 }
5137
5138 if (glyph_row->exact_window_width_line_p
5139 && (glyph_row->reversed_p
5140 ? (w->phys_cursor.hpos < 0)
5141 : (w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])))
5142 {
5143 glyph_row->cursor_in_fringe_p = 1;
5144 draw_fringe_bitmap (w, glyph_row, glyph_row->reversed_p);
5145 return;
5146 }
5147
5148 switch (cursor_type)
5149 {
5150 case HOLLOW_BOX_CURSOR:
5151 x_draw_hollow_cursor (w, glyph_row);
5152 break;
5153
5154 case FILLED_BOX_CURSOR:
5155 draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
5156 break;
5157
5158 case BAR_CURSOR:
5159 x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
5160 break;
5161
5162 case HBAR_CURSOR:
5163 x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
5164 break;
5165
5166 case NO_CURSOR:
5167 w->phys_cursor_width = 0;
5168 break;
5169
5170 default:
5171 abort ();
5172 }
5173 }
5174 }
5175
5176
5177
5178
5179
5180 int
5181 x_bitmap_icon (f, icon)
5182 struct frame *f;
5183 Lisp_Object icon;
5184 {
5185 HANDLE main_icon;
5186 HANDLE small_icon = NULL;
5187
5188 if (FRAME_W32_WINDOW (f) == 0)
5189 return 1;
5190
5191 if (NILP (icon))
5192 main_icon = LoadIcon (hinst, EMACS_CLASS);
5193 else if (STRINGP (icon))
5194 {
5195
5196 main_icon = LoadImage (NULL, (LPCTSTR) SDATA (icon), IMAGE_ICON, 0, 0,
5197 LR_DEFAULTSIZE | LR_LOADFROMFILE);
5198
5199 small_icon = LoadImage (NULL, (LPCSTR) SDATA (icon), IMAGE_ICON,
5200 GetSystemMetrics (SM_CXSMICON),
5201 GetSystemMetrics (SM_CYSMICON),
5202 LR_LOADFROMFILE);
5203 }
5204 else if (SYMBOLP (icon))
5205 {
5206 LPCTSTR name;
5207
5208 if (EQ (icon, intern ("application")))
5209 name = (LPCTSTR) IDI_APPLICATION;
5210 else if (EQ (icon, intern ("hand")))
5211 name = (LPCTSTR) IDI_HAND;
5212 else if (EQ (icon, intern ("question")))
5213 name = (LPCTSTR) IDI_QUESTION;
5214 else if (EQ (icon, intern ("exclamation")))
5215 name = (LPCTSTR) IDI_EXCLAMATION;
5216 else if (EQ (icon, intern ("asterisk")))
5217 name = (LPCTSTR) IDI_ASTERISK;
5218 else if (EQ (icon, intern ("winlogo")))
5219 name = (LPCTSTR) IDI_WINLOGO;
5220 else
5221 return 1;
5222
5223 main_icon = LoadIcon (NULL, name);
5224 }
5225 else
5226 return 1;
5227
5228 if (main_icon == NULL)
5229 return 1;
5230
5231 PostMessage (FRAME_W32_WINDOW (f), WM_SETICON, (WPARAM) ICON_BIG,
5232 (LPARAM) main_icon);
5233
5234
5235 if (small_icon)
5236 PostMessage (FRAME_W32_WINDOW (f), WM_SETICON, (WPARAM) ICON_SMALL,
5237 (LPARAM) small_icon);
5238
5239 return 0;
5240 }
5241
5242
5243 5244 5245
5246
5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266
5267
5268
5269
5270
5271 Lisp_Object
5272 x_new_font (f, font_object, fontset)
5273 struct frame *f;
5274 Lisp_Object font_object;
5275 int fontset;
5276 {
5277 struct font *font = XFONT_OBJECT (font_object);
5278
5279 if (fontset < 0)
5280 fontset = fontset_from_font (font_object);
5281 FRAME_FONTSET (f) = fontset;
5282 if (FRAME_FONT (f) == font)
5283 5284
5285 return font_object;
5286
5287 FRAME_FONT (f) = font;
5288 FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
5289 FRAME_COLUMN_WIDTH (f) = font->average_width;
5290 FRAME_SPACE_WIDTH (f) = font->space_width;
5291 FRAME_LINE_HEIGHT (f) = font->height;
5292
5293 compute_fringe_widths (f, 1);
5294
5295
5296 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
5297 {
5298 int wid = FRAME_COLUMN_WIDTH (f);
5299 FRAME_CONFIG_SCROLL_BAR_COLS (f)
5300 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid - 1) / wid;
5301 }
5302 else
5303 {
5304 int wid = FRAME_COLUMN_WIDTH (f);
5305 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
5306 }
5307
5308
5309 if (FRAME_X_WINDOW (f) != 0)
5310 {
5311 5312 5313
5314 if (NILP (tip_frame) || XFRAME (tip_frame) != f)
5315 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
5316 }
5317
5318
5319
5320 return font_object;
5321 }
5322
5323
5324 5325 5326
5327 5328 5329 5330 5331 5332 5333 5334 5335 5336
5337
5338
5339 5340
5341
5342 void
5343 x_calc_absolute_position (f)
5344 struct frame *f;
5345 {
5346 int flags = f->size_hint_flags;
5347
5348 5349 5350
5351 unsigned int left_right_borders_width, top_bottom_borders_height;
5352
5353 5354 5355 5356
5357 WINDOWPLACEMENT wp = { 0 };
5358 RECT client_rect = { 0 };
5359
5360 if (GetWindowPlacement (FRAME_W32_WINDOW (f), &wp)
5361 && GetClientRect (FRAME_W32_WINDOW (f), &client_rect))
5362 {
5363 left_right_borders_width =
5364 (wp.rcNormalPosition.right - wp.rcNormalPosition.left) -
5365 (client_rect.right - client_rect.left);
5366
5367 top_bottom_borders_height =
5368 (wp.rcNormalPosition.bottom - wp.rcNormalPosition.top) -
5369 (client_rect.bottom - client_rect.top);
5370 }
5371 else
5372 {
5373
5374 left_right_borders_width = 8;
5375 top_bottom_borders_height = 32;
5376 }
5377
5378 5379
5380 if (flags & XNegative)
5381 f->left_pos = (x_display_pixel_width (FRAME_W32_DISPLAY_INFO (f))
5382 - FRAME_PIXEL_WIDTH (f)
5383 + f->left_pos
5384 - (left_right_borders_width - 1));
5385
5386 if (flags & YNegative)
5387 f->top_pos = (x_display_pixel_height (FRAME_W32_DISPLAY_INFO (f))
5388 - FRAME_PIXEL_HEIGHT (f)
5389 + f->top_pos
5390 - (top_bottom_borders_height - 1));
5391
5392 5393
5394 f->size_hint_flags &= ~ (XNegative | YNegative);
5395 }
5396
5397 5398 5399 5400 5401
5402
5403 void
5404 x_set_offset (f, xoff, yoff, change_gravity)
5405 struct frame *f;
5406 register int xoff, yoff;
5407 int change_gravity;
5408 {
5409 int modified_top, modified_left;
5410
5411 if (change_gravity > 0)
5412 {
5413 f->top_pos = yoff;
5414 f->left_pos = xoff;
5415 f->size_hint_flags &= ~ (XNegative | YNegative);
5416 if (xoff < 0)
5417 f->size_hint_flags |= XNegative;
5418 if (yoff < 0)
5419 f->size_hint_flags |= YNegative;
5420 f->win_gravity = NorthWestGravity;
5421 }
5422 x_calc_absolute_position (f);
5423
5424 BLOCK_INPUT;
5425 x_wm_set_size_hint (f, (long) 0, 0);
5426
5427 modified_left = f->left_pos;
5428 modified_top = f->top_pos;
5429
5430 my_set_window_pos (FRAME_W32_WINDOW (f),
5431 NULL,
5432 modified_left, modified_top,
5433 0, 0,
5434 SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
5435 UNBLOCK_INPUT;
5436 }
5437
5438
5439 5440
5441 static void
5442 x_check_fullscreen (f)
5443 struct frame *f;
5444 {
5445 if (f->want_fullscreen & FULLSCREEN_BOTH)
5446 {
5447 int width, height, ign;
5448
5449 x_real_positions (f, &f->left_pos, &f->top_pos);
5450
5451 x_fullscreen_adjust (f, &width, &height, &ign, &ign);
5452
5453 5454
5455 if (FRAME_COLS (f) != width || FRAME_LINES (f) != height)
5456 {
5457 change_frame_size (f, height, width, 0, 1, 0);
5458 SET_FRAME_GARBAGED (f);
5459 cancel_mouse_face (f);
5460
5461
5462 f->want_fullscreen |= FULLSCREEN_WAIT;
5463 }
5464 }
5465 }
5466
5467 5468 5469 5470
5471
5472 void
5473 x_set_window_size (f, change_gravity, cols, rows)
5474 struct frame *f;
5475 int change_gravity;
5476 int cols, rows;
5477 {
5478 int pixelwidth, pixelheight;
5479
5480 BLOCK_INPUT;
5481
5482 check_frame_size (f, &rows, &cols);
5483 f->scroll_bar_actual_width
5484 = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
5485
5486 compute_fringe_widths (f, 0);
5487
5488 pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols);
5489 pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
5490
5491 f->win_gravity = NorthWestGravity;
5492 x_wm_set_size_hint (f, (long) 0, 0);
5493
5494 {
5495 RECT rect;
5496
5497 rect.left = rect.top = 0;
5498 rect.right = pixelwidth;
5499 rect.bottom = pixelheight;
5500
5501 AdjustWindowRect(&rect, f->output_data.w32->dwStyle,
5502 FRAME_EXTERNAL_MENU_BAR (f));
5503
5504 my_set_window_pos (FRAME_W32_WINDOW (f),
5505 NULL,
5506 0, 0,
5507 rect.right - rect.left,
5508 rect.bottom - rect.top,
5509 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
5510 }
5511
5512 #if 0
5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539
5540 change_frame_size (f, rows, cols, 0, 1, 0);
5541 FRAME_PIXEL_WIDTH (f) = pixelwidth;
5542 FRAME_PIXEL_HEIGHT (f) = pixelheight;
5543
5544 5545 5546 5547
5548 SET_FRAME_GARBAGED (f);
5549
5550
5551 mark_window_cursors_off (XWINDOW (f->root_window));
5552
5553 5554 5555 5556
5557 cancel_mouse_face (f);
5558 #endif
5559
5560 UNBLOCK_INPUT;
5561 }
5562
5563
5564
5565 void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y);
5566
5567 void
5568 x_set_mouse_position (f, x, y)
5569 struct frame *f;
5570 int x, y;
5571 {
5572 int pix_x, pix_y;
5573
5574 pix_x = FRAME_COL_TO_PIXEL_X (f, x) + FRAME_COLUMN_WIDTH (f) / 2;
5575 pix_y = FRAME_LINE_TO_PIXEL_Y (f, y) + FRAME_LINE_HEIGHT (f) / 2;
5576
5577 if (pix_x < 0) pix_x = 0;
5578 if (pix_x > FRAME_PIXEL_WIDTH (f)) pix_x = FRAME_PIXEL_WIDTH (f);
5579
5580 if (pix_y < 0) pix_y = 0;
5581 if (pix_y > FRAME_PIXEL_HEIGHT (f)) pix_y = FRAME_PIXEL_HEIGHT (f);
5582
5583 x_set_mouse_pixel_position (f, pix_x, pix_y);
5584 }
5585
5586 void
5587 x_set_mouse_pixel_position (f, pix_x, pix_y)
5588 struct frame *f;
5589 int pix_x, pix_y;
5590 {
5591 RECT rect;
5592 POINT pt;
5593
5594 BLOCK_INPUT;
5595
5596 GetClientRect (FRAME_W32_WINDOW (f), &rect);
5597 pt.x = rect.left + pix_x;
5598 pt.y = rect.top + pix_y;
5599 ClientToScreen (FRAME_W32_WINDOW (f), &pt);
5600
5601 SetCursorPos (pt.x, pt.y);
5602
5603 UNBLOCK_INPUT;
5604 }
5605
5606
5607
5608
5609 void
5610 x_focus_on_frame (f)
5611 struct frame *f;
5612 {
5613 struct w32_display_info *dpyinfo = &one_w32_display_info;
5614
5615
5616 BLOCK_INPUT;
5617 #if 0
5618
5619 if (x_window_to_frame (dpyinfo, GetForegroundWindow ()))
5620 my_set_focus (f, FRAME_W32_WINDOW (f));
5621 else
5622 #endif
5623 my_set_foreground_window (FRAME_W32_WINDOW (f));
5624 UNBLOCK_INPUT;
5625 }
5626
5627 void
5628 x_unfocus_frame (f)
5629 struct frame *f;
5630 {
5631 }
5632
5633
5634 void
5635 x_raise_frame (f)
5636 struct frame *f;
5637 {
5638 BLOCK_INPUT;
5639
5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657
5658
5659 if (NILP (Vw32_grab_focus_on_raise))
5660 {
5661 5662 5663 5664 5665
5666
5667 HDWP handle = BeginDeferWindowPos (2);
5668 if (handle)
5669 {
5670 DeferWindowPos (handle,
5671 FRAME_W32_WINDOW (f),
5672 HWND_TOP,
5673 0, 0, 0, 0,
5674 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
5675
5676 DeferWindowPos (handle,
5677 GetForegroundWindow (),
5678 FRAME_W32_WINDOW (f),
5679 0, 0, 0, 0,
5680 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
5681
5682 EndDeferWindowPos (handle);
5683 }
5684 }
5685 else
5686 {
5687 my_set_foreground_window (FRAME_W32_WINDOW (f));
5688 }
5689
5690 UNBLOCK_INPUT;
5691 }
5692
5693
5694 void
5695 x_lower_frame (f)
5696 struct frame *f;
5697 {
5698 BLOCK_INPUT;
5699 my_set_window_pos (FRAME_W32_WINDOW (f),
5700 HWND_BOTTOM,
5701 0, 0, 0, 0,
5702 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
5703 UNBLOCK_INPUT;
5704 }
5705
5706 static void
5707 w32_frame_raise_lower (f, raise_flag)
5708 FRAME_PTR f;
5709 int raise_flag;
5710 {
5711 if (! FRAME_W32_P (f))
5712 return;
5713
5714 if (raise_flag)
5715 x_raise_frame (f);
5716 else
5717 x_lower_frame (f);
5718 }
5719
5720
5721
5722 5723 5724 5725 5726 5727
5728
5729 void
5730 x_make_frame_visible (f)
5731 struct frame *f;
5732 {
5733 Lisp_Object type;
5734
5735 BLOCK_INPUT;
5736
5737 type = x_icon_type (f);
5738 if (!NILP (type))
5739 x_bitmap_icon (f, type);
5740
5741 if (! FRAME_VISIBLE_P (f))
5742 {
5743 5744 5745 5746
5747 if (! FRAME_ICONIFIED_P (f)
5748 && ! f->output_data.w32->asked_for_visible)
5749 {
5750 RECT workarea_rect;
5751 RECT window_rect;
5752
5753 5754
5755 SystemParametersInfo(SPI_GETWORKAREA, 0, &workarea_rect, 0);
5756 GetWindowRect(FRAME_W32_WINDOW(f), &window_rect);
5757 if (window_rect.bottom > workarea_rect.bottom
5758 && window_rect.top > workarea_rect.top)
5759 f->top_pos = max (window_rect.top
5760 - window_rect.bottom + workarea_rect.bottom,
5761 workarea_rect.top);
5762
5763 x_set_offset (f, f->left_pos, f->top_pos, 0);
5764 }
5765
5766 f->output_data.w32->asked_for_visible = 1;
5767
5768 5769 5770 5771 5772 5773
5774 my_show_window (f, FRAME_W32_WINDOW (f),
5775 f->async_iconified ? SW_RESTORE : SW_SHOW);
5776
5777 }
5778
5779 5780 5781
5782 {
5783 Lisp_Object frame;
5784 int count;
5785
5786
5787 UNBLOCK_INPUT;
5788
5789 XSETFRAME (frame, f);
5790
5791 5792 5793
5794 for (count = input_signal_count + 10;
5795 input_signal_count < count && !FRAME_VISIBLE_P (f);)
5796 {
5797
5798
5799
5800 5801 5802 5803 5804
5805 if (input_polling_used ())
5806 {
5807 5808
5809 int old_poll_suppress_count = poll_suppress_count;
5810 poll_suppress_count = 1;
5811 poll_for_input_1 ();
5812 poll_suppress_count = old_poll_suppress_count;
5813 }
5814 }
5815 FRAME_SAMPLE_VISIBILITY (f);
5816 }
5817 }
5818
5819
5820
5821
5822
5823 x_make_frame_invisible (f)
5824 struct frame *f;
5825 {
5826
5827 if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f)
5828 FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame = 0;
5829
5830 BLOCK_INPUT;
5831
5832 my_show_window (f, FRAME_W32_WINDOW (f), SW_HIDE);
5833
5834 5835 5836 5837 5838
5839 f->visible = 0;
5840 FRAME_ICONIFIED_P (f) = 0;
5841 f->async_visible = 0;
5842 f->async_iconified = 0;
5843
5844 UNBLOCK_INPUT;
5845 }
5846
5847
5848
5849 void
5850 x_iconify_frame (f)
5851 struct frame *f;
5852 {
5853 Lisp_Object type;
5854
5855
5856 if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f)
5857 FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame = 0;
5858
5859 if (f->async_iconified)
5860 return;
5861
5862 BLOCK_INPUT;
5863
5864 type = x_icon_type (f);
5865 if (!NILP (type))
5866 x_bitmap_icon (f, type);
5867
5868
5869 SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0);
5870
5871 UNBLOCK_INPUT;
5872 }
5873
5874
5875
5876
5877 void
5878 x_free_frame_resources (f)
5879 struct frame *f;
5880 {
5881 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
5882
5883 BLOCK_INPUT;
5884
5885 5886 5887
5888 if (FRAME_FACE_CACHE (f))
5889 free_frame_faces (f);
5890
5891 if (FRAME_W32_WINDOW (f))
5892 my_destroy_window (f, FRAME_W32_WINDOW (f));
5893
5894 free_frame_menubar (f);
5895
5896 unload_color (f, FRAME_FOREGROUND_PIXEL (f));
5897 unload_color (f, FRAME_BACKGROUND_PIXEL (f));
5898 unload_color (f, f->output_data.w32->cursor_pixel);
5899 unload_color (f, f->output_data.w32->cursor_foreground_pixel);
5900 unload_color (f, f->output_data.w32->border_pixel);
5901 unload_color (f, f->output_data.w32->mouse_pixel);
5902 if (f->output_data.w32->white_relief.allocated_p)
5903 unload_color (f, f->output_data.w32->white_relief.pixel);
5904 if (f->output_data.w32->black_relief.allocated_p)
5905 unload_color (f, f->output_data.w32->black_relief.pixel);
5906
5907 if (FRAME_FACE_CACHE (f))
5908 free_frame_faces (f);
5909
5910 xfree (f->output_data.w32);
5911 f->output_data.w32 = NULL;
5912
5913 if (f == dpyinfo->w32_focus_frame)
5914 dpyinfo->w32_focus_frame = 0;
5915 if (f == dpyinfo->w32_focus_event_frame)
5916 dpyinfo->w32_focus_event_frame = 0;
5917 if (f == dpyinfo->x_highlight_frame)
5918 dpyinfo->x_highlight_frame = 0;
5919
5920 if (f == dpyinfo->mouse_face_mouse_frame)
5921 {
5922 dpyinfo->mouse_face_beg_row
5923 = dpyinfo->mouse_face_beg_col = -1;
5924 dpyinfo->mouse_face_end_row
5925 = dpyinfo->mouse_face_end_col = -1;
5926 dpyinfo->mouse_face_window = Qnil;
5927 dpyinfo->mouse_face_deferred_gc = 0;
5928 dpyinfo->mouse_face_mouse_frame = 0;
5929 }
5930
5931 UNBLOCK_INPUT;
5932 }
5933
5934
5935
5936 void
5937 x_destroy_window (f)
5938 struct frame *f;
5939 {
5940 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
5941
5942 x_free_frame_resources (f);
5943 dpyinfo->reference_count--;
5944 }
5945
5946
5947
5948
5949 5950 5951 5952 5953
5954 void
5955 x_wm_set_size_hint (f, flags, user_position)
5956 struct frame *f;
5957 long flags;
5958 int user_position;
5959 {
5960 Window window = FRAME_W32_WINDOW (f);
5961
5962 enter_crit ();
5963
5964 SetWindowLong (window, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f));
5965 SetWindowLong (window, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f));
5966 SetWindowLong (window, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f));
5967 SetWindowLong (window, WND_SCROLLBAR_INDEX, f->scroll_bar_actual_width);
5968
5969 leave_crit ();
5970 }
5971
5972
5973 void
5974 x_wm_set_icon_position (f, icon_x, icon_y)
5975 struct frame *f;
5976 int icon_x, icon_y;
5977 {
5978 #if 0
5979 Window window = FRAME_W32_WINDOW (f);
5980
5981 f->display.x->wm_hints.flags |= IconPositionHint;
5982 f->display.x->wm_hints.icon_x = icon_x;
5983 f->display.x->wm_hints.icon_y = icon_y;
5984
5985 XSetWMHints (FRAME_X_DISPLAY (f), window, &f->display.x->wm_hints);
5986 #endif
5987 }
5988
5989
5990 5991 5992
5993
5994 static int w32_initialized = 0;
5995
5996 void
5997 w32_initialize_display_info (display_name)
5998 Lisp_Object display_name;
5999 {
6000 struct w32_display_info *dpyinfo = &one_w32_display_info;
6001
6002 bzero (dpyinfo, sizeof (*dpyinfo));
6003
6004
6005 w32_display_name_list = Fcons (Fcons (display_name, Qnil),
6006 w32_display_name_list);
6007 dpyinfo->name_list_element = XCAR (w32_display_name_list);
6008
6009 dpyinfo->w32_id_name
6010 = (char *) xmalloc (SCHARS (Vinvocation_name)
6011 + SCHARS (Vsystem_name)
6012 + 2);
6013 sprintf (dpyinfo->w32_id_name, "%s@%s",
6014 SDATA (Vinvocation_name), SDATA (Vsystem_name));
6015
6016 6017
6018 dpyinfo->resx = 1;
6019 dpyinfo->resy = 1;
6020 dpyinfo->n_planes = 1;
6021 dpyinfo->n_cbits = 4;
6022 dpyinfo->n_fonts = 0;
6023 dpyinfo->smallest_font_height = 1;
6024 dpyinfo->smallest_char_width = 1;
6025
6026 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
6027 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
6028 dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID;
6029 dpyinfo->mouse_face_window = Qnil;
6030 dpyinfo->mouse_face_overlay = Qnil;
6031 dpyinfo->mouse_face_hidden = 0;
6032
6033 dpyinfo->vertical_scroll_bar_cursor = w32_load_cursor (IDC_ARROW);
6034
6035
6036 }
6037
6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048
6049
6050 static char *
6051 w32_make_rdb (xrm_option)
6052 char *xrm_option;
6053 {
6054 char *buffer = xmalloc (strlen (xrm_option) + 2);
6055 char *current = buffer;
6056 char ch;
6057 int in_option = 1;
6058 int before_value = 0;
6059
6060 do {
6061 ch = *xrm_option++;
6062
6063 if (ch == '\n')
6064 {
6065 *current++ = '\0';
6066 in_option = 1;
6067 before_value = 0;
6068 }
6069 else if (ch != ' ')
6070 {
6071 *current++ = ch;
6072 if (in_option && (ch == ':'))
6073 {
6074 in_option = 0;
6075 before_value = 1;
6076 }
6077 else if (before_value)
6078 {
6079 before_value = 0;
6080 }
6081 }
6082 else if (!(in_option || before_value))
6083 {
6084 *current++ = ch;
6085 }
6086 } while (ch);
6087
6088 *current = '\0';
6089
6090 return buffer;
6091 }
6092
6093 void
6094 x_flush (struct frame * f)
6095 { }
6096
6097
6098 extern frame_parm_handler w32_frame_parm_handlers[];
6099
6100 static struct redisplay_interface w32_redisplay_interface =
6101 {
6102 w32_frame_parm_handlers,
6103 x_produce_glyphs,
6104 x_write_glyphs,
6105 x_insert_glyphs,
6106 x_clear_end_of_line,
6107 x_scroll_run,
6108 x_after_update_window_line,
6109 x_update_window_begin,
6110 x_update_window_end,
6111 x_cursor_to,
6112 x_flush,
6113 0,
6114 x_clear_window_mouse_face,
6115 x_get_glyph_overhangs,
6116 x_fix_overlapping_area,
6117 w32_draw_fringe_bitmap,
6118 w32_define_fringe_bitmap,
6119 w32_destroy_fringe_bitmap,
6120 w32_compute_glyph_string_overhangs,
6121 x_draw_glyph_string,
6122 w32_define_frame_cursor,
6123 w32_clear_frame_area,
6124 w32_draw_window_cursor,
6125 w32_draw_vertical_window_border,
6126 w32_shift_glyphs_for_insert
6127 };
6128
6129 static void x_delete_terminal (struct terminal *term);
6130
6131 static struct terminal *
6132 w32_create_terminal (struct w32_display_info *dpyinfo)
6133 {
6134 struct terminal *terminal;
6135
6136 terminal = create_terminal ();
6137
6138 terminal->type = output_w32;
6139 terminal->display_info.w32 = dpyinfo;
6140 dpyinfo->terminal = terminal;
6141
6142 6143
6144 terminal->clear_frame_hook = x_clear_frame;
6145 terminal->ins_del_lines_hook = x_ins_del_lines;
6146 terminal->delete_glyphs_hook = x_delete_glyphs;
6147 terminal->ring_bell_hook = w32_ring_bell;
6148 terminal->reset_terminal_modes_hook = w32_reset_terminal_modes;
6149 terminal->set_terminal_modes_hook = w32_set_terminal_modes;
6150 terminal->update_begin_hook = x_update_begin;
6151 terminal->update_end_hook = x_update_end;
6152 terminal->set_terminal_window_hook = w32_set_terminal_window;
6153 terminal->read_socket_hook = w32_read_socket;
6154 terminal->frame_up_to_date_hook = w32_frame_up_to_date;
6155 terminal->mouse_position_hook = w32_mouse_position;
6156 terminal->frame_rehighlight_hook = w32_frame_rehighlight;
6157 terminal->frame_raise_lower_hook = w32_frame_raise_lower;
6158 6159 terminal->set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar;
6160 terminal->condemn_scroll_bars_hook = w32_condemn_scroll_bars;
6161 terminal->redeem_scroll_bar_hook = w32_redeem_scroll_bar;
6162 terminal->judge_scroll_bars_hook = w32_judge_scroll_bars;
6163
6164 terminal->delete_frame_hook = x_destroy_window;
6165 terminal->delete_terminal_hook = x_delete_terminal;
6166
6167 terminal->rif = &w32_redisplay_interface;
6168 terminal->scroll_region_ok = 1;
6169 terminal->char_ins_del_ok = 1;
6170 terminal->line_ins_del_ok = 1;
6171 terminal->fast_clear_end_of_line = 1;
6172 terminal->memory_below_frame = 0; 6173
6174
6175 6176 6177
6178 terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
6179 init_kboard (terminal->kboard);
6180 terminal->kboard->Vwindow_system = intern ("w32");
6181 terminal->kboard->next_kboard = all_kboards;
6182 all_kboards = terminal->kboard;
6183 6184 6185
6186 if (current_kboard == initial_kboard)
6187 current_kboard = terminal->kboard;
6188 terminal->kboard->reference_count++;
6189
6190 return terminal;
6191 }
6192
6193 static void
6194 x_delete_terminal (struct terminal *terminal)
6195 {
6196 struct w32_display_info *dpyinfo = terminal->display_info.w32;
6197 int i;
6198
6199 6200
6201 if (!terminal->name)
6202 return;
6203
6204 BLOCK_INPUT;
6205
6206 x_delete_display (dpyinfo);
6207 UNBLOCK_INPUT;
6208 }
6209
6210 struct w32_display_info *
6211 w32_term_init (display_name, xrm_option, resource_name)
6212 Lisp_Object display_name;
6213 char *xrm_option;
6214 char *resource_name;
6215 {
6216 struct w32_display_info *dpyinfo;
6217 struct terminal *terminal;
6218 HDC hdc;
6219
6220 BLOCK_INPUT;
6221
6222 if (!w32_initialized)
6223 {
6224 w32_initialize ();
6225 w32_initialized = 1;
6226 }
6227
6228 w32_initialize_display_info (display_name);
6229
6230 dpyinfo = &one_w32_display_info;
6231 terminal = w32_create_terminal (dpyinfo);
6232
6233
6234 terminal->name = (char *) xmalloc (SBYTES (display_name) + 1);
6235 strncpy (terminal->name, SDATA (display_name), SBYTES (display_name));
6236 terminal->name[SBYTES (display_name)] = 0;
6237
6238 dpyinfo->xrdb = xrm_option ? w32_make_rdb (xrm_option) : NULL;
6239
6240
6241 dpyinfo->next = x_display_list;
6242 x_display_list = dpyinfo;
6243
6244 hdc = GetDC (NULL);
6245
6246 dpyinfo->root_window = GetDesktopWindow ();
6247 dpyinfo->n_planes = GetDeviceCaps (hdc, PLANES);
6248 dpyinfo->n_cbits = GetDeviceCaps (hdc, BITSPIXEL);
6249 dpyinfo->resx = GetDeviceCaps (hdc, LOGPIXELSX);
6250 dpyinfo->resy = GetDeviceCaps (hdc, LOGPIXELSY);
6251 dpyinfo->has_palette = GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE;
6252 ReleaseDC (NULL, hdc);
6253
6254
6255 {
6256 XColor color;
6257 w32_defined_color (0, "white", &color, 1);
6258 w32_defined_color (0, "black", &color, 1);
6259 }
6260
6261
6262 add_keyboard_wait_descriptor (0);
6263
6264 6265 6266 6267 6268 6269 6270
6271 w32_init_fringe (terminal->rif);
6272
6273 #ifdef F_SETOWN
6274 fcntl (connection, F_SETOWN, getpid ());
6275 #endif
6276
6277 #ifdef SIGIO
6278 if (interrupt_input)
6279 init_sigio (connection);
6280 #endif
6281
6282 UNBLOCK_INPUT;
6283
6284 return dpyinfo;
6285 }
6286
6287
6288 void
6289 x_delete_display (dpyinfo)
6290 struct w32_display_info *dpyinfo;
6291 {
6292 6293
6294 if (! NILP (w32_display_name_list)
6295 && EQ (XCAR (w32_display_name_list), dpyinfo->name_list_element))
6296 w32_display_name_list = XCDR (w32_display_name_list);
6297 else
6298 {
6299 Lisp_Object tail;
6300
6301 tail = w32_display_name_list;
6302 while (CONSP (tail) && CONSP (XCDR (tail)))
6303 {
6304 if (EQ (XCAR (XCDR (tail)), dpyinfo->name_list_element))
6305 {
6306 XSETCDR (tail, XCDR (XCDR (tail)));
6307 break;
6308 }
6309 tail = XCDR (tail);
6310 }
6311 }
6312
6313
6314 {
6315 struct w32_palette_entry * plist;
6316
6317 plist = dpyinfo->color_list;
6318 while (plist)
6319 {
6320 struct w32_palette_entry * pentry = plist;
6321 plist = plist->next;
6322 xfree (pentry);
6323 }
6324 dpyinfo->color_list = NULL;
6325 if (dpyinfo->palette)
6326 DeleteObject(dpyinfo->palette);
6327 }
6328 xfree (dpyinfo->w32_id_name);
6329
6330 w32_reset_fringes ();
6331 }
6332
6333
6334
6335 DWORD WINAPI w32_msg_worker (void * arg);
6336
6337 static void
6338 w32_initialize ()
6339 {
6340 HANDLE shell;
6341 HRESULT (WINAPI * set_user_model) (wchar_t * id);
6342
6343 baud_rate = 19200;
6344
6345 w32_system_caret_hwnd = NULL;
6346 w32_system_caret_height = 0;
6347 w32_system_caret_x = 0;
6348 w32_system_caret_y = 0;
6349
6350 6351 6352
6353 shell = GetModuleHandle ("shell32.dll");
6354 if (shell)
6355 {
6356 set_user_model
6357 = (void *) GetProcAddress (shell,
6358 "SetCurrentProcessExplicitAppUserModelID");
6359
6360 6361 6362 6363 6364
6365 if (set_user_model)
6366 set_user_model (L"GNU.Emacs");
6367 }
6368
6369 6370
6371 if (!SystemParametersInfo (SPI_GETSCREENREADER, 0,
6372 &w32_use_visible_system_caret, 0))
6373 w32_use_visible_system_caret = 0;
6374
6375 last_tool_bar_item = -1;
6376 any_help_event_p = 0;
6377
6378 6379
6380 Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
6381
6382 {
6383 DWORD input_locale_id = (DWORD) GetKeyboardLayout (0);
6384 keyboard_codepage = codepage_for_locale ((LCID) (input_locale_id & 0xffff));
6385 }
6386
6387 6388
6389 init_crit ();
6390
6391 dwMainThreadId = GetCurrentThreadId ();
6392 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
6393 GetCurrentProcess (), &hMainThread, 0, TRUE, DUPLICATE_SAME_ACCESS);
6394
6395
6396 {
6397 MSG msg;
6398
6399 PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
6400
6401 hWindowsThread = CreateThread (NULL, 0,
6402 w32_msg_worker,
6403 0, 0, &dwWindowsThreadId);
6404
6405 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
6406 }
6407
6408 6409 6410 6411 6412 6413 6414 6415
6416 #ifdef ATTACH_THREADS
6417 AttachThreadInput (dwMainThreadId, dwWindowsThreadId, TRUE);
6418 #endif
6419
6420
6421 {
6422 HMODULE user_lib = GetModuleHandle ("user32.dll");
6423
6424 #define LOAD_PROC(lib, fn) pfn##fn = (void *) GetProcAddress (lib, #fn)
6425
6426 LOAD_PROC (user_lib, SetLayeredWindowAttributes);
6427
6428 #undef LOAD_PROC
6429
6430
6431 vertical_scroll_bar_min_handle = 5;
6432
6433 6434
6435 vertical_scroll_bar_top_border = vertical_scroll_bar_bottom_border
6436 = GetSystemMetrics (SM_CYVSCROLL);
6437 }
6438 }
6439
6440 void
6441 syms_of_w32term ()
6442 {
6443 staticpro (&w32_display_name_list);
6444 w32_display_name_list = Qnil;
6445
6446 staticpro (&last_mouse_scroll_bar);
6447 last_mouse_scroll_bar = Qnil;
6448
6449 DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
6450
6451 DEFVAR_INT ("w32-num-mouse-buttons",
6452 &w32_num_mouse_buttons,
6453 doc: );
6454 w32_num_mouse_buttons = 2;
6455
6456 DEFVAR_LISP ("w32-swap-mouse-buttons",
6457 &Vw32_swap_mouse_buttons,
6458 doc: 6459 );
6460 Vw32_swap_mouse_buttons = Qnil;
6461
6462 DEFVAR_LISP ("w32-grab-focus-on-raise",
6463 &Vw32_grab_focus_on_raise,
6464 doc: 6465 6466 6467 );
6468 Vw32_grab_focus_on_raise = Qt;
6469
6470 DEFVAR_LISP ("w32-capslock-is-shiftlock",
6471 &Vw32_capslock_is_shiftlock,
6472 doc: 6473 );
6474 Vw32_capslock_is_shiftlock = Qnil;
6475
6476 DEFVAR_LISP ("w32-recognize-altgr",
6477 &Vw32_recognize_altgr,
6478 doc: 6479 6480 );
6481 Vw32_recognize_altgr = Qt;
6482
6483 DEFVAR_BOOL ("w32-use-visible-system-caret",
6484 &w32_use_visible_system_caret,
6485 doc: 6486 6487 6488 6489 6490 6491 6492 6493 6494 );
6495
6496 w32_use_visible_system_caret = 0;
6497
6498 6499
6500 DEFVAR_BOOL ("x-use-underline-position-properties",
6501 &x_use_underline_position_properties,
6502 doc: 6503 6504 6505 );
6506 x_use_underline_position_properties = 0;
6507
6508 DEFVAR_BOOL ("x-underline-at-descent-line",
6509 &x_underline_at_descent_line,
6510 doc: 6511 6512 6513 );
6514 x_underline_at_descent_line = 0;
6515
6516 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
6517 doc: );
6518 Vx_toolkit_scroll_bars = Qt;
6519
6520 staticpro (&last_mouse_motion_frame);
6521 last_mouse_motion_frame = Qnil;
6522 }
6523
6524 6525