aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/w32term.c250
1 files changed, 195 insertions, 55 deletions
diff --git a/src/w32term.c b/src/w32term.c
index 737d189f77f..3b3156d150f 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -48,6 +48,7 @@ Boston, MA 02111-1307, USA. */
48#include "window.h" 48#include "window.h"
49#include "keyboard.h" 49#include "keyboard.h"
50#include "intervals.h" 50#include "intervals.h"
51#include "coding.h"
51 52
52#undef min 53#undef min
53#undef max 54#undef max
@@ -148,6 +149,9 @@ Lisp_Object Vw32_grab_focus_on_raise;
148/* Control whether Caps Lock affects non-ascii characters. */ 149/* Control whether Caps Lock affects non-ascii characters. */
149Lisp_Object Vw32_capslock_is_shiftlock; 150Lisp_Object Vw32_capslock_is_shiftlock;
150 151
152/* Control whether right-alt and left-ctrl should be recognized as AltGr. */
153Lisp_Object Vw32_recognize_altgr;
154
151/* The scroll bar in which the last motion event occurred. 155/* The scroll bar in which the last motion event occurred.
152 156
153 If the last motion event occurred in a scroll bar, we set this 157 If the last motion event occurred in a scroll bar, we set this
@@ -457,13 +461,14 @@ w32_cursor_to (row, col)
457 Call this function with input blocked. */ 461 Call this function with input blocked. */
458 462
459static void 463static void
460dumpglyphs (f, left, top, gp, n, hl, just_foreground) 464dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp)
461 struct frame *f; 465 struct frame *f;
462 int left, top; 466 int left, top;
463 register GLYPH *gp; /* Points to first GLYPH. */ 467 register GLYPH *gp; /* Points to first GLYPH. */
464 register int n; /* Number of glyphs to display. */ 468 register int n; /* Number of glyphs to display. */
465 int hl; 469 int hl;
466 int just_foreground; 470 int just_foreground;
471 struct cmpchar_info *cmpcharp;
467{ 472{
468 /* Holds characters to be displayed. */ 473 /* Holds characters to be displayed. */
469 char *buf = (char *) alloca (f->width * sizeof (*buf)); 474 char *buf = (char *) alloca (f->width * sizeof (*buf));
@@ -480,35 +485,78 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground)
480 { 485 {
481 /* Get the face-code of the next GLYPH. */ 486 /* Get the face-code of the next GLYPH. */
482 int cf, len; 487 int cf, len;
483 int g = *gp; 488 GLYPH g = *gp;
489 int ch, charset;
484 490
485 GLYPH_FOLLOW_ALIASES (tbase, tlen, g); 491 GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
486 cf = FAST_GLYPH_FACE (g); 492 cf = (cmpcharp ? cmpcharp->face_work : FAST_GLYPH_FACE (g));
487 493 ch = FAST_GLYPH_CHAR (g);
494 charset = CHAR_CHARSET (ch);
495 if (charset == CHARSET_COMPOSITION)
496 {
497 struct face *face = FRAME_DEFAULT_FACE (f);
498 XFontStruct *font = FACE_FONT (face);
499 /* We must draw components of the composite character on the
500 same column */
501 cmpcharp = cmpchar_table[COMPOSITE_CHAR_ID (ch)];
502
503 /* Set the face in the slot for work. */
504 cmpcharp->face_work = cf;
505
506 dumpglyphs (f, left, top, cmpcharp->glyph, cmpcharp->glyph_len,
507 hl, just_foreground, cmpcharp);
508 left += FONT_WIDTH (font) * cmpcharp->width;
509 ++gp, --n;
510 while (gp && (*gp & GLYPH_MASK_PADDING)) ++gp, --n;
511 cmpcharp = NULL;
512 continue;
513 }
488 /* Find the run of consecutive glyphs with the same face-code. 514 /* Find the run of consecutive glyphs with the same face-code.
489 Extract their character codes into BUF. */ 515 Extract their character codes into BUF. */
490 cp = buf; 516 cp = buf;
491 while (n > 0) 517 while (n > 0)
492 { 518 {
519 int this_charset, c[2];
520
493 g = *gp; 521 g = *gp;
494 GLYPH_FOLLOW_ALIASES (tbase, tlen, g); 522 GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
495 if (FAST_GLYPH_FACE (g) != cf) 523 ch = FAST_GLYPH_CHAR (g);
524 SPLIT_CHAR (ch, this_charset, c[0], c[1]);
525 if (this_charset != charset
526 || (cmpcharp == NULL && FAST_GLYPH_FACE (g) != cf))
496 break; 527 break;
497 528
498 *cp++ = FAST_GLYPH_CHAR (g); 529 if ( c[1] > 0 )
499 --n; 530 {
500 ++gp; 531 int consumed, produced;
532 /* Handle multibyte characters (still assuming user
533 selects correct font themselves for now */
534 produced = encode_terminal_code(gp, cp, 1,
535 (f->width*sizeof(*buf))-(cp-buf), &consumed);
536 /* If we can't display this glyph, skip it */
537 if (consumed == 0)
538 gp++,n--;
539 else
540 gp += consumed, n-= consumed;
541 cp += produced;
542 }
543 else
544 {
545 *cp++ = c[0];
546 ++gp, --n;
547 }
548 while (gp && (*gp & GLYPH_MASK_PADDING))
549 ++gp, --n;
501 } 550 }
502 551
503 /* LEN gets the length of the run. */ 552 /* LEN gets the length of the run. */
504 len = cp - buf; 553 len = cp - buf;
505
506 /* Now output this run of chars, with the font and pixel values 554 /* Now output this run of chars, with the font and pixel values
507 determined by the face code CF. */ 555 determined by the face code CF. */
508 { 556 {
557 int stippled = 0;
509 struct face *face = FRAME_DEFAULT_FACE (f); 558 struct face *face = FRAME_DEFAULT_FACE (f);
510 XFontStruct *font = FACE_FONT (face); 559 XFontStruct *font = FACE_FONT (face);
511 int stippled = 0;
512 COLORREF fg; 560 COLORREF fg;
513 COLORREF bg; 561 COLORREF bg;
514 562
@@ -662,7 +710,7 @@ w32_write_glyphs (start, len)
662 dumpglyphs (f, 710 dumpglyphs (f,
663 CHAR_TO_PIXEL_COL (f, curs_x), 711 CHAR_TO_PIXEL_COL (f, curs_x),
664 CHAR_TO_PIXEL_ROW (f, curs_y), 712 CHAR_TO_PIXEL_ROW (f, curs_y),
665 start, len, highlight, 0); 713 start, len, highlight, 0, NULL);
666 714
667 /* If we drew on top of the cursor, note that it is turned off. */ 715 /* If we drew on top of the cursor, note that it is turned off. */
668 if (curs_y == f->phys_cursor_y 716 if (curs_y == f->phys_cursor_y
@@ -755,7 +803,7 @@ w32_ring_bell ()
755 BLOCK_INPUT; 803 BLOCK_INPUT;
756 804
757 if (visible_bell) 805 if (visible_bell)
758 FlashWindow (FRAME_W32_WINDOW (selected_frame), FALSE); 806 FlashWindow (FRAME_W32_WINDOW (selected_frame), TRUE);
759 else 807 else
760 w32_sys_ring_bell (); 808 w32_sys_ring_bell ();
761 809
@@ -1012,7 +1060,7 @@ dumprectangle (f, left, top, cols, rows)
1012 CHAR_TO_PIXEL_COL (f, left), 1060 CHAR_TO_PIXEL_COL (f, left),
1013 CHAR_TO_PIXEL_ROW (f, y), 1061 CHAR_TO_PIXEL_ROW (f, y),
1014 line, min (cols, active_frame->used[y] - left), 1062 line, min (cols, active_frame->used[y] - left),
1015 active_frame->highlight[y], 0); 1063 active_frame->highlight[y], 0, NULL);
1016 } 1064 }
1017 1065
1018 /* Turn the cursor on if we turned it off. */ 1066 /* Turn the cursor on if we turned it off. */
@@ -1683,7 +1731,7 @@ show_mouse_face (dpyinfo, hl)
1683 FRAME_CURRENT_GLYPHS (f)->glyphs[i] + column, 1731 FRAME_CURRENT_GLYPHS (f)->glyphs[i] + column,
1684 endcolumn - column, 1732 endcolumn - column,
1685 /* Highlight with mouse face if hl > 0. */ 1733 /* Highlight with mouse face if hl > 0. */
1686 hl > 0 ? 3 : 0, 0); 1734 hl > 0 ? 3 : 0, 0, NULL);
1687 } 1735 }
1688 1736
1689 /* If we turned the cursor off, turn it back on. */ 1737 /* If we turned the cursor off, turn it back on. */
@@ -1913,6 +1961,13 @@ my_set_focus (f, hwnd)
1913 (WPARAM) hwnd, 0); 1961 (WPARAM) hwnd, 0);
1914} 1962}
1915 1963
1964BOOL
1965my_set_foreground_window (hwnd)
1966 HWND hwnd;
1967{
1968 SendMessage (hwnd, WM_EMACS_SETFOREGROUND, (WPARAM) hwnd, 0);
1969}
1970
1916void 1971void
1917my_destroy_window (f, hwnd) 1972my_destroy_window (f, hwnd)
1918 struct frame * f; 1973 struct frame * f;
@@ -2201,6 +2256,19 @@ static void
2201w32_condemn_scroll_bars (frame) 2256w32_condemn_scroll_bars (frame)
2202 FRAME_PTR frame; 2257 FRAME_PTR frame;
2203{ 2258{
2259 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
2260 while (! NILP (FRAME_SCROLL_BARS (frame)))
2261 {
2262 Lisp_Object bar;
2263 bar = FRAME_SCROLL_BARS (frame);
2264 FRAME_SCROLL_BARS (frame) = XSCROLL_BAR (bar)->next;
2265 XSCROLL_BAR (bar)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
2266 XSCROLL_BAR (bar)->prev = Qnil;
2267 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
2268 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = bar;
2269 FRAME_CONDEMNED_SCROLL_BARS (frame) = bar;
2270 }
2271#ifdef PIGSFLY
2204 /* The condemned list should be empty at this point; if it's not, 2272 /* The condemned list should be empty at this point; if it's not,
2205 then the rest of Emacs isn't using the condemn/redeem/judge 2273 then the rest of Emacs isn't using the condemn/redeem/judge
2206 protocol correctly. */ 2274 protocol correctly. */
@@ -2210,6 +2278,7 @@ w32_condemn_scroll_bars (frame)
2210 /* Move them all to the "condemned" list. */ 2278 /* Move them all to the "condemned" list. */
2211 FRAME_CONDEMNED_SCROLL_BARS (frame) = FRAME_SCROLL_BARS (frame); 2279 FRAME_CONDEMNED_SCROLL_BARS (frame) = FRAME_SCROLL_BARS (frame);
2212 FRAME_SCROLL_BARS (frame) = Qnil; 2280 FRAME_SCROLL_BARS (frame) = Qnil;
2281#endif
2213} 2282}
2214 2283
2215/* Unmark WINDOW's scroll bar for deletion in this judgement cycle. 2284/* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
@@ -2233,6 +2302,46 @@ w32_redeem_scroll_bar (window)
2233 if (NILP (bar->prev)) 2302 if (NILP (bar->prev))
2234 { 2303 {
2235 /* If the prev pointer is nil, it must be the first in one of 2304 /* If the prev pointer is nil, it must be the first in one of
2305 the lists. */
2306 if (EQ (FRAME_SCROLL_BARS (f), window->vertical_scroll_bar))
2307 /* It's not condemned. Everything's fine. */
2308 return;
2309 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
2310 window->vertical_scroll_bar))
2311 FRAME_CONDEMNED_SCROLL_BARS (f) = bar->next;
2312 else
2313 /* If its prev pointer is nil, it must be at the front of
2314 one or the other! */
2315 abort ();
2316 }
2317 else
2318 XSCROLL_BAR (bar->prev)->next = bar->next;
2319
2320 if (! NILP (bar->next))
2321 XSCROLL_BAR (bar->next)->prev = bar->prev;
2322
2323 bar->next = FRAME_SCROLL_BARS (f);
2324 bar->prev = Qnil;
2325 XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
2326 if (! NILP (bar->next))
2327 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
2328 }
2329#ifdef PIGSFLY
2330 struct scroll_bar *bar;
2331
2332 /* We can't redeem this window's scroll bar if it doesn't have one. */
2333 if (NILP (window->vertical_scroll_bar))
2334 abort ();
2335
2336 bar = XSCROLL_BAR (window->vertical_scroll_bar);
2337
2338 /* Unlink it from the condemned list. */
2339 {
2340 FRAME_PTR f = XFRAME (WINDOW_FRAME (window));
2341
2342 if (NILP (bar->prev))
2343 {
2344 /* If the prev pointer is nil, it must be the first in one of
2236 the lists. */ 2345 the lists. */
2237 if (EQ (FRAME_SCROLL_BARS (f), window->vertical_scroll_bar)) 2346 if (EQ (FRAME_SCROLL_BARS (f), window->vertical_scroll_bar))
2238 /* It's not condemned. Everything's fine. */ 2347 /* It's not condemned. Everything's fine. */
@@ -2257,6 +2366,7 @@ w32_redeem_scroll_bar (window)
2257 if (! NILP (bar->next)) 2366 if (! NILP (bar->next))
2258 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar); 2367 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
2259 } 2368 }
2369#endif
2260} 2370}
2261 2371
2262/* Remove all scroll bars on FRAME that haven't been saved since the 2372/* Remove all scroll bars on FRAME that haven't been saved since the
@@ -2285,6 +2395,28 @@ w32_judge_scroll_bars (f)
2285 2395
2286 /* Now there should be no references to the condemned scroll bars, 2396 /* Now there should be no references to the condemned scroll bars,
2287 and they should get garbage-collected. */ 2397 and they should get garbage-collected. */
2398#ifdef PIGSFLY
2399 Lisp_Object bar, next;
2400
2401 bar = FRAME_CONDEMNED_SCROLL_BARS (f);
2402
2403 /* Clear out the condemned list now so we won't try to process any
2404 more events on the hapless scroll bars. */
2405 FRAME_CONDEMNED_SCROLL_BARS (f) = Qnil;
2406
2407 for (; ! NILP (bar); bar = next)
2408 {
2409 struct scroll_bar *b = XSCROLL_BAR (bar);
2410
2411 x_scroll_bar_remove (b);
2412
2413 next = b->next;
2414 b->next = b->prev = Qnil;
2415 }
2416
2417 /* Now there should be no references to the condemned scroll bars,
2418 and they should get garbage-collected. */
2419#endif
2288} 2420}
2289 2421
2290/* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind 2422/* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
@@ -2879,44 +3011,6 @@ w32_read_socket (sd, bufp, numchars, expected)
2879 case WM_SIZE: 3011 case WM_SIZE:
2880 f = x_window_to_frame (dpyinfo, msg.msg.hwnd); 3012 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
2881 3013
2882 if (f && !f->async_iconified && msg.msg.wParam != SIZE_MINIMIZED)
2883 {
2884 RECT rect;
2885 int rows;
2886 int columns;
2887 int width;
2888 int height;
2889
2890 GetClientRect(msg.msg.hwnd, &rect);
2891
2892 height = rect.bottom - rect.top;
2893 width = rect.right - rect.left;
2894
2895 rows = PIXEL_TO_CHAR_HEIGHT (f, height);
2896 columns = PIXEL_TO_CHAR_WIDTH (f, width);
2897
2898 /* TODO: Clip size to the screen dimensions. */
2899
2900 /* Even if the number of character rows and columns has
2901 not changed, the font size may have changed, so we need
2902 to check the pixel dimensions as well. */
2903
2904 if (columns != f->width
2905 || rows != f->height
2906 || width != f->output_data.w32->pixel_width
2907 || height != f->output_data.w32->pixel_height)
2908 {
2909 /* I had set this to 0, 0 - I am not sure why?? */
2910
2911 change_frame_size (f, rows, columns, 0, 1);
2912 SET_FRAME_GARBAGED (f);
2913
2914 f->output_data.w32->pixel_width = width;
2915 f->output_data.w32->pixel_height = height;
2916 f->output_data.w32->win_gravity = NorthWestGravity;
2917 }
2918 }
2919
2920 /* Inform lisp of whether frame has been iconified etc. */ 3014 /* Inform lisp of whether frame has been iconified etc. */
2921 if (f) 3015 if (f)
2922 { 3016 {
@@ -2959,6 +3053,44 @@ w32_read_socket (sd, bufp, numchars, expected)
2959 } 3053 }
2960 } 3054 }
2961 3055
3056 if (f && !f->async_iconified && msg.msg.wParam != SIZE_MINIMIZED)
3057 {
3058 RECT rect;
3059 int rows;
3060 int columns;
3061 int width;
3062 int height;
3063
3064 GetClientRect(msg.msg.hwnd, &rect);
3065
3066 height = rect.bottom - rect.top;
3067 width = rect.right - rect.left;
3068
3069 rows = PIXEL_TO_CHAR_HEIGHT (f, height);
3070 columns = PIXEL_TO_CHAR_WIDTH (f, width);
3071
3072 /* TODO: Clip size to the screen dimensions. */
3073
3074 /* Even if the number of character rows and columns has
3075 not changed, the font size may have changed, so we need
3076 to check the pixel dimensions as well. */
3077
3078 if (columns != f->width
3079 || rows != f->height
3080 || width != f->output_data.w32->pixel_width
3081 || height != f->output_data.w32->pixel_height)
3082 {
3083 /* I had set this to 0, 0 - I am not sure why?? */
3084
3085 change_frame_size (f, rows, columns, 0, 1);
3086 SET_FRAME_GARBAGED (f);
3087
3088 f->output_data.w32->pixel_width = width;
3089 f->output_data.w32->pixel_height = height;
3090 f->output_data.w32->win_gravity = NorthWestGravity;
3091 }
3092 }
3093
2962 check_visibility = 1; 3094 check_visibility = 1;
2963 break; 3095 break;
2964 3096
@@ -3200,7 +3332,7 @@ x_draw_single_glyph (f, row, column, glyph, highlight)
3200 dumpglyphs (f, 3332 dumpglyphs (f,
3201 CHAR_TO_PIXEL_COL (f, column), 3333 CHAR_TO_PIXEL_COL (f, column),
3202 CHAR_TO_PIXEL_ROW (f, row), 3334 CHAR_TO_PIXEL_ROW (f, row),
3203 &glyph, 1, highlight, 0); 3335 &glyph, 1, highlight, 0, NULL);
3204} 3336}
3205 3337
3206static void 3338static void
@@ -3750,7 +3882,7 @@ x_focus_on_frame (f)
3750 my_set_focus (f, FRAME_W32_WINDOW (f)); 3882 my_set_focus (f, FRAME_W32_WINDOW (f));
3751 else 3883 else
3752#endif 3884#endif
3753 SetForegroundWindow (FRAME_W32_WINDOW (f)); 3885 my_set_foreground_window (FRAME_W32_WINDOW (f));
3754 UNBLOCK_INPUT; 3886 UNBLOCK_INPUT;
3755} 3887}
3756 3888
@@ -3813,7 +3945,7 @@ x_raise_frame (f)
3813 } 3945 }
3814 else 3946 else
3815 { 3947 {
3816 SetForegroundWindow (FRAME_W32_WINDOW (f)); 3948 my_set_foreground_window (FRAME_W32_WINDOW (f));
3817 } 3949 }
3818 3950
3819 UNBLOCK_INPUT; 3951 UNBLOCK_INPUT;
@@ -4383,4 +4515,12 @@ desirable when using a point-to-focus policy.");
4383 "Apply CapsLock state to non character input keys.\n\ 4515 "Apply CapsLock state to non character input keys.\n\
4384When nil, CapsLock only affects normal character input keys."); 4516When nil, CapsLock only affects normal character input keys.");
4385 Vw32_capslock_is_shiftlock = Qnil; 4517 Vw32_capslock_is_shiftlock = Qnil;
4518
4519 DEFVAR_LISP ("w32-recognize-altgr",
4520 &Vw32_recognize_altgr,
4521 "Recognize right-alt and left-ctrl as AltGr.\n\
4522When nil, the right-alt and left-ctrl key combination is\n\
4523interpreted normally.");
4524 Vw32_recognize_altgr = Qt;
4386} 4525}
4526