aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGeoff Voelker1997-09-03 01:07:37 +0000
committerGeoff Voelker1997-09-03 01:07:37 +0000
commit689004fa098a77e837676652eb658ddd5ac88674 (patch)
treeefede553506d8b68275995be675a2167a7917041 /src
parentb2fc9f3d6b10a339618ce7adfa1ea3557e7a820d (diff)
downloademacs-689004fa098a77e837676652eb658ddd5ac88674.tar.gz
emacs-689004fa098a77e837676652eb658ddd5ac88674.zip
(SIF_*): Win95 macros defined for NT.
(struct tagSCROLLINFO): Win95 struct defined for NT. (vertical_scroll_bar_min_handle, vertical_scroll_bar_top_border, vertical_scroll_bar_bottom_border, last_scroll_bar_drag_pos, Vw32_gab_focus_on_raise, Vw32_capslock_is_shiftlock): New variables. (w32_frame_up_to_date): Block input. (do_line_dance): Use DC while erasing, release at end. (show_mouse_face): Use column and endcolumn calculated at start of loop. (my_create_scrollbar, my_show_window, my_set_window_pos, my_set_focus) [! ATTACH_THREADS]: Send message to window instead of invoking Windows procedure. (x_scroll_bar_create, x_scroll_bar_move, x_scroll_bar_handle_click, x_scroll_bar_report_motion): Use SCROLLINFO for proportional handle. (x_scroll_bar_set_handle): Create proportional sized scroll handle. (w32_set_vertical_scroll_bar): Size handle according to how much is showing in window. (x_scroll_bar_set_report_motion): Use top_range, calculated above. (x_scroll_bar_clear): Hide scroll bar until ready to repaint. (show_scroll_bars): Pass in frame to my_show_window. (w32_read_socket): Distinguish between invisible and obscured frames when handling PAINT messages. Fixup off-by-one calculation for PAINT and SIZE. Pass in new parameter to w32_kbd_mods_to_emacs. Handle WM_DISPLAYCHANGE, WINDOWPOSCHANGED, ACTIVATE, SHOWWINDOW, INITMENU, and ACTIVATEAPP messages. Explicitly check for visibile and obscured frames, and to see if any event should cause a redisplay. (x_display_bar_cursor): Don't check whether frame is updating here. (x_display_cursor): Check it here instead. (x_set_offset) [HAVE_NTGUI]: Don't add border widths. Set NOACTIVATE when setting window position. (x_set_window_size): Fixup off-by-one calculation when setting window position. Mark frame garbaged earlier. Clear mouse highlighting state. (x_focus_on_frame): Set focus by making frame the foreground window. (x_raise_frame): Support frames to be raised without grabbing focus. (x_lower_frame): Set NOACTIVATE flag when setting window position. (x_make_frame_visible, x_make_frame_invisible): Pass in frame to my_show_window. to my_show_window. (x_iconify_frame): Send a MINIMIZE message to the window. (x_wm_set_size_hint): Set font width, line height, border, and scroll bar indexes instead of X and Y unit indexes. (w32_initialize): Set input mode. Use w32_msg_worker instead of windows_msg_worker. Dynamically link proportional scroll bar functions and intialize proportional scroll bar variables. (syms_of_w32term): DEFVAR new variables. (construct_mouse_wheel): New function. Constructs an input event from a WM_MOUSEWHEEL message. (w32_read_socket): Handle WM_MOUSEWHEEL. (w32_read_socket): Pass in new parameter to key_event. Let key_event determine whether key is dead. For MOVE, use x_real_positions to map to client coords. (x_set_mouse_pixel_position): Offset to use client area as origin.
Diffstat (limited to 'src')
-rw-r--r--src/w32term.c877
1 files changed, 682 insertions, 195 deletions
diff --git a/src/w32term.c b/src/w32term.c
index 75e53a1216f..a433abc6bb4 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -27,7 +27,7 @@ Boston, MA 02111-1307, USA. */
27#include "charset.h" 27#include "charset.h"
28#include "blockinput.h" 28#include "blockinput.h"
29 29
30#include <w32term.h> 30#include "w32term.h"
31 31
32#include "systty.h" 32#include "systty.h"
33#include "systime.h" 33#include "systime.h"
@@ -95,6 +95,38 @@ HANDLE hWindowsThread = NULL;
95DWORD dwMainThreadId = 0; 95DWORD dwMainThreadId = 0;
96HANDLE hMainThread = NULL; 96HANDLE hMainThread = NULL;
97 97
98#ifndef SIF_ALL
99/* These definitions are new with Windows 95. */
100#define SIF_RANGE 0x0001
101#define SIF_PAGE 0x0002
102#define SIF_POS 0x0004
103#define SIF_DISABLENOSCROLL 0x0008
104#define SIF_TRACKPOS 0x0010
105#define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
106
107typedef struct tagSCROLLINFO
108{
109 UINT cbSize;
110 UINT fMask;
111 int nMin;
112 int nMax;
113 UINT nPage;
114 int nPos;
115 int nTrackPos;
116} SCROLLINFO, FAR *LPSCROLLINFO;
117typedef SCROLLINFO CONST FAR *LPCSCROLLINFO;
118#endif /* SIF_ALL */
119
120/* Dynamic linking to new proportional scroll bar functions. */
121int (PASCAL *pfnSetScrollInfo) (HWND hwnd, int fnBar, LPSCROLLINFO lpsi, BOOL fRedraw);
122BOOL (PASCAL *pfnGetScrollInfo) (HWND hwnd, int fnBar, LPSCROLLINFO lpsi);
123
124int vertical_scroll_bar_min_handle;
125int vertical_scroll_bar_top_border;
126int vertical_scroll_bar_bottom_border;
127
128int last_scroll_bar_drag_pos;
129
98/* Mouse movement. */ 130/* Mouse movement. */
99 131
100/* Where the mouse was last time we reported a mouse event. */ 132/* Where the mouse was last time we reported a mouse event. */
@@ -105,6 +137,12 @@ Lisp_Object Vw32_num_mouse_buttons;
105 137
106Lisp_Object Vw32_swap_mouse_buttons; 138Lisp_Object Vw32_swap_mouse_buttons;
107 139
140/* Control whether x_raise_frame also sets input focus. */
141Lisp_Object Vw32_grab_focus_on_raise;
142
143/* Control whether Caps Lock affects non-ascii characters. */
144Lisp_Object Vw32_capslock_is_shiftlock;
145
108/* The scroll bar in which the last motion event occurred. 146/* The scroll bar in which the last motion event occurred.
109 147
110 If the last motion event occurred in a scroll bar, we set this 148 If the last motion event occurred in a scroll bar, we set this
@@ -324,6 +362,7 @@ static
324w32_frame_up_to_date (f) 362w32_frame_up_to_date (f)
325 FRAME_PTR f; 363 FRAME_PTR f;
326{ 364{
365 BLOCK_INPUT;
327 if (FRAME_W32_DISPLAY_INFO (f)->mouse_face_deferred_gc 366 if (FRAME_W32_DISPLAY_INFO (f)->mouse_face_deferred_gc
328 || f == FRAME_W32_DISPLAY_INFO (f)->mouse_face_mouse_frame) 367 || f == FRAME_W32_DISPLAY_INFO (f)->mouse_face_mouse_frame)
329 { 368 {
@@ -332,6 +371,7 @@ w32_frame_up_to_date (f)
332 FRAME_W32_DISPLAY_INFO (f)->mouse_face_mouse_y); 371 FRAME_W32_DISPLAY_INFO (f)->mouse_face_mouse_y);
333 FRAME_W32_DISPLAY_INFO (f)->mouse_face_deferred_gc = 0; 372 FRAME_W32_DISPLAY_INFO (f)->mouse_face_deferred_gc = 0;
334 } 373 }
374 UNBLOCK_INPUT;
335} 375}
336 376
337/* External interface to control of standout mode. 377/* External interface to control of standout mode.
@@ -875,14 +915,12 @@ do_line_dance ()
875 i = j+1; 915 i = j+1;
876 } 916 }
877 917
878 release_frame_dc (f, hdc);
879
880 for (i = 0; i < ht; ++i) 918 for (i = 0; i < ht; ++i)
881 if (line_dance[i] == -1) 919 if (line_dance[i] == -1)
882 { 920 {
883 for (j = i; j < ht && line_dance[j] == -1; ++j); 921 for (j = i; j < ht && line_dance[j] == -1; ++j);
884 /* Clear [i,j) */ 922 /* Clear [i,j) */
885 w32_clear_area (f, NULL, 923 w32_clear_area (f, hdc,
886 intborder, 924 intborder,
887 CHAR_TO_PIXEL_ROW (f, i), 925 CHAR_TO_PIXEL_ROW (f, i),
888 f->width * FONT_WIDTH (f->output_data.w32->font), 926 f->width * FONT_WIDTH (f->output_data.w32->font),
@@ -890,6 +928,8 @@ do_line_dance ()
890 i = j-1; 928 i = j-1;
891 } 929 }
892 line_dance_in_progress = 0; 930 line_dance_in_progress = 0;
931
932 release_frame_dc (f, hdc);
893} 933}
894 934
895/* Support routines for exposure events. */ 935/* Support routines for exposure events. */
@@ -1265,6 +1305,25 @@ construct_mouse_click (result, msg, f)
1265 } 1305 }
1266} 1306}
1267 1307
1308static void
1309construct_mouse_wheel (result, msg, f)
1310 struct input_event *result;
1311 W32Msg *msg;
1312 struct frame *f;
1313{
1314 POINT p;
1315 result->kind = mouse_wheel;
1316 result->code = (short) HIWORD (msg->msg.wParam);
1317 result->timestamp = msg->msg.time;
1318 result->modifiers = msg->dwModifiers;
1319 p.x = LOWORD (msg->msg.lParam);
1320 p.y = HIWORD (msg->msg.lParam);
1321 ScreenToClient(msg->msg.hwnd, &p);
1322 XSETINT (result->x, p.x);
1323 XSETINT (result->y, p.y);
1324 XSETFRAME (result->frame_or_window, f);
1325}
1326
1268 1327
1269/* Function to report a mouse movement to the mainstream Emacs code. 1328/* Function to report a mouse movement to the mainstream Emacs code.
1270 The input handler calls this. 1329 The input handler calls this.
@@ -1606,8 +1665,8 @@ show_mouse_face (dpyinfo, hl)
1606 /* If the cursor's in the text we are about to rewrite, 1665 /* If the cursor's in the text we are about to rewrite,
1607 turn the cursor off. */ 1666 turn the cursor off. */
1608 if (i == curs_y 1667 if (i == curs_y
1609 && curs_x >= FRAME_W32_DISPLAY_INFO (f)->mouse_face_beg_col - 1 1668 && curs_x >= column - 1
1610 && curs_x <= FRAME_W32_DISPLAY_INFO (f)->mouse_face_end_col) 1669 && curs_x <= endcolumn)
1611 { 1670 {
1612 x_display_cursor (f, 0); 1671 x_display_cursor (f, 0);
1613 cursor_off = 1; 1672 cursor_off = 1;
@@ -1690,6 +1749,7 @@ w32_mouse_position (fp, insist, bar_window, part, x, y, time)
1690 BLOCK_INPUT; 1749 BLOCK_INPUT;
1691 1750
1692 if (! NILP (last_mouse_scroll_bar)) 1751 if (! NILP (last_mouse_scroll_bar))
1752 /* This is never called at the moment. */
1693 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time); 1753 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
1694 else 1754 else
1695 { 1755 {
@@ -1803,34 +1863,31 @@ my_create_scrollbar (f, bar)
1803 struct frame * f; 1863 struct frame * f;
1804 struct scroll_bar * bar; 1864 struct scroll_bar * bar;
1805{ 1865{
1806 MSG msg; 1866 return (HWND) SendMessage (FRAME_W32_WINDOW (f),
1807 1867 WM_EMACS_CREATESCROLLBAR, (WPARAM) f,
1808 PostThreadMessage (dwWindowsThreadId, WM_EMACS_CREATESCROLLBAR, (WPARAM) f, 1868 (LPARAM) bar);
1809 (LPARAM) bar);
1810 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
1811
1812 return ((HWND) msg.wParam);
1813} 1869}
1814 1870
1815//#define ATTACH_THREADS 1871//#define ATTACH_THREADS
1816 1872
1817void 1873BOOL
1818my_show_window (HWND hwnd, int how) 1874my_show_window (FRAME_PTR f, HWND hwnd, int how)
1819{ 1875{
1820#ifndef ATTACH_THREADS 1876#ifndef ATTACH_THREADS
1821 SendMessage (hwnd, WM_EMACS_SHOWWINDOW, (WPARAM) how, 0); 1877 return SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SHOWWINDOW,
1878 (WPARAM) hwnd, (LPARAM) how);
1822#else 1879#else
1823 ShowWindow (hwnd , how); 1880 return ShowWindow (hwnd, how);
1824#endif 1881#endif
1825} 1882}
1826 1883
1827void 1884void
1828my_set_window_pos (HWND hwnd, HWND hwndAfter, 1885my_set_window_pos (HWND hwnd, HWND hwndAfter,
1829 int x, int y, int cx, int cy, int flags) 1886 int x, int y, int cx, int cy, UINT flags)
1830{ 1887{
1831#ifndef ATTACH_THREADS 1888#ifndef ATTACH_THREADS
1832 W32WindowPos pos; 1889 WINDOWPOS pos;
1833 pos.hwndAfter = hwndAfter; 1890 pos.hwndInsertAfter = hwndAfter;
1834 pos.x = x; 1891 pos.x = x;
1835 pos.y = y; 1892 pos.y = y;
1836 pos.cx = cx; 1893 pos.cx = cx;
@@ -1842,6 +1899,15 @@ my_set_window_pos (HWND hwnd, HWND hwndAfter,
1842#endif 1899#endif
1843} 1900}
1844 1901
1902BOOL
1903my_set_focus (f, hwnd)
1904 struct frame * f;
1905 HWND hwnd;
1906{
1907 SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SETFOCUS,
1908 (WPARAM) hwnd, 0);
1909}
1910
1845void 1911void
1846my_destroy_window (f, hwnd) 1912my_destroy_window (f, hwnd)
1847 struct frame * f; 1913 struct frame * f;
@@ -1878,8 +1944,25 @@ x_scroll_bar_create (window, top, left, width, height)
1878 1944
1879 hwnd = my_create_scrollbar (f, bar); 1945 hwnd = my_create_scrollbar (f, bar);
1880 1946
1881 SetScrollRange (hwnd, SB_CTL, 0, height, FALSE); 1947 if (pfnSetScrollInfo)
1882 SetScrollPos (hwnd, SB_CTL, 0, TRUE); 1948 {
1949 SCROLLINFO si;
1950
1951 si.cbSize = sizeof (si);
1952 si.fMask = SIF_ALL;
1953 si.nMin = 0;
1954 si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (height)
1955 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
1956 si.nPage = si.nMax;
1957 si.nPos = 0;
1958
1959 pfnSetScrollInfo (hwnd, SB_CTL, &si, FALSE);
1960 }
1961 else
1962 {
1963 SetScrollRange (hwnd, SB_CTL, 0, VERTICAL_SCROLL_BAR_TOP_RANGE (height), FALSE);
1964 SetScrollPos (hwnd, SB_CTL, 0, FALSE);
1965 }
1883 1966
1884 SET_SCROLL_BAR_W32_WINDOW (bar, hwnd); 1967 SET_SCROLL_BAR_W32_WINDOW (bar, hwnd);
1885 1968
@@ -1924,11 +2007,48 @@ x_scroll_bar_set_handle (bar, start, end, rebuild)
1924 2007
1925 BLOCK_INPUT; 2008 BLOCK_INPUT;
1926 2009
2010 {
2011 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (XINT (bar->height));
2012
2013 /* Make sure the values are reasonable, and try to preserve
2014 the distance between start and end. */
2015 {
2016 int length = end - start;
2017
2018 if (start < 0)
2019 start = 0;
2020 else if (start > top_range)
2021 start = top_range;
2022 end = start + length;
2023
2024 if (end < start)
2025 end = start;
2026 else if (end > top_range && ! dragging)
2027 end = top_range;
2028 }
2029 }
2030
1927 /* Store the adjusted setting in the scroll bar. */ 2031 /* Store the adjusted setting in the scroll bar. */
1928 XSETINT (bar->start, start); 2032 XSETINT (bar->start, start);
1929 XSETINT (bar->end, end); 2033 XSETINT (bar->end, end);
1930 2034
1931 SetScrollPos (w, SB_CTL, start, TRUE); 2035 /* If being dragged, let scroll bar update itself. */
2036 if (!dragging)
2037 {
2038 if (pfnSetScrollInfo)
2039 {
2040 SCROLLINFO si;
2041
2042 si.cbSize = sizeof (si);
2043 si.fMask = SIF_PAGE | SIF_POS;
2044 si.nPage = end - start + VERTICAL_SCROLL_BAR_MIN_HANDLE;
2045 si.nPos = start;
2046
2047 pfnSetScrollInfo (w, SB_CTL, &si, TRUE);
2048 }
2049 else
2050 SetScrollPos (w, SB_CTL, start, TRUE);
2051 }
1932 2052
1933 UNBLOCK_INPUT; 2053 UNBLOCK_INPUT;
1934} 2054}
@@ -1943,12 +2063,40 @@ x_scroll_bar_move (bar, top, left, width, height)
1943 Window w = SCROLL_BAR_W32_WINDOW (bar); 2063 Window w = SCROLL_BAR_W32_WINDOW (bar);
1944 FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); 2064 FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
1945 2065
2066 /* If already correctly positioned, do nothing. */
2067 if ( XINT (bar->left) == left
2068 && XINT (bar->top) == top
2069 && XINT (bar->width) == width
2070 && XINT (bar->height) == height )
2071 {
2072 /* Redraw after clear_frame. */
2073 if (!my_show_window (f, w, SW_NORMAL))
2074 InvalidateRect (w, NULL, FALSE);
2075 return;
2076 }
2077
1946 BLOCK_INPUT; 2078 BLOCK_INPUT;
1947 2079
2080 /* Make sure scroll bar is "visible" before moving, to ensure the
2081 area of the parent window now exposed will be refreshed. */
2082 my_show_window (f, w, SW_HIDE);
1948 MoveWindow (w, left, top, width, height, TRUE); 2083 MoveWindow (w, left, top, width, height, TRUE);
1949 SetScrollRange (w, SB_CTL, 0, height, FALSE); 2084 if (pfnSetScrollInfo)
1950 InvalidateRect (w, NULL, FALSE); 2085 {
1951 my_show_window (w, SW_NORMAL); 2086 SCROLLINFO si;
2087
2088 si.cbSize = sizeof (si);
2089 si.fMask = SIF_RANGE;
2090 si.nMin = 0;
2091 si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (height)
2092 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
2093
2094 pfnSetScrollInfo (w, SB_CTL, &si, FALSE);
2095 }
2096 else
2097 SetScrollRange (w, SB_CTL, 0, VERTICAL_SCROLL_BAR_TOP_RANGE (height), FALSE);
2098 my_show_window (f, w, SW_NORMAL);
2099// InvalidateRect (w, NULL, FALSE);
1952 2100
1953 XSETINT (bar->left, left); 2101 XSETINT (bar->left, left);
1954 XSETINT (bar->top, top); 2102 XSETINT (bar->top, top);
@@ -2014,22 +2162,20 @@ w32_set_vertical_scroll_bar (window, portion, whole, position)
2014 x_scroll_bar_move (bar, pixel_top, pixel_left, pixel_width, pixel_height); 2162 x_scroll_bar_move (bar, pixel_top, pixel_left, pixel_width, pixel_height);
2015 } 2163 }
2016 2164
2017 /* Set the scroll bar's current state, unless we're currently being 2165 /* Set the scroll bar's current state. */
2018 dragged. */ 2166 {
2019 if (NILP (bar->dragging)) 2167 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (pixel_height);
2020 {
2021 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (pixel_height);
2022 2168
2023 if (whole == 0) 2169 if (whole == 0)
2024 x_scroll_bar_set_handle (bar, 0, top_range, 0); 2170 x_scroll_bar_set_handle (bar, 0, top_range, 0);
2025 else 2171 else
2026 { 2172 {
2027 int start = (int) (((double) position * top_range) / whole); 2173 int start = (int) (((double) position * top_range) / whole);
2028 int end = (int) (((double) (position + portion) * top_range) / whole); 2174 int end = (int) (((double) (position + portion) * top_range) / whole);
2029 2175
2030 x_scroll_bar_set_handle (bar, start, end, 0); 2176 x_scroll_bar_set_handle (bar, start, end, 0);
2031 } 2177 }
2032 } 2178 }
2033 2179
2034 XSETVECTOR (window->vertical_scroll_bar, bar); 2180 XSETVECTOR (window->vertical_scroll_bar, bar);
2035} 2181}
@@ -2159,19 +2305,27 @@ x_scroll_bar_handle_click (bar, msg, emacs_event)
2159 emacs_event->timestamp = msg->msg.time; 2305 emacs_event->timestamp = msg->msg.time;
2160 2306
2161 { 2307 {
2162 int internal_height 2308 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (XINT (bar->height));
2163 = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (XINT (bar->height)); 2309 int y;
2164 int top_range 2310 int dragging = !NILP (bar->dragging);
2165 = VERTICAL_SCROLL_BAR_TOP_RANGE (XINT (bar->height)); 2311
2166 int y = GetScrollPos ((HWND) msg->msg.lParam, SB_CTL); 2312 if (pfnGetScrollInfo)
2313 {
2314 SCROLLINFO si;
2315
2316 si.cbSize = sizeof (si);
2317 si.fMask = SIF_POS;
2318
2319 pfnGetScrollInfo ((HWND) msg->msg.lParam, SB_CTL, &si);
2320 y = si.nPos;
2321 }
2322 else
2323 y = GetScrollPos ((HWND) msg->msg.lParam, SB_CTL);
2324
2325 bar->dragging = Qnil;
2167 2326
2168 switch (LOWORD (msg->msg.wParam)) 2327 switch (LOWORD (msg->msg.wParam))
2169 { 2328 {
2170 case SB_THUMBTRACK:
2171 emacs_event->part = scroll_bar_handle;
2172 if (VERTICAL_SCROLL_BAR_TOP_RANGE (XINT (bar->height)) <= 0xffff)
2173 y = HIWORD (msg->msg.wParam);
2174 break;
2175 case SB_LINEDOWN: 2329 case SB_LINEDOWN:
2176 emacs_event->part = scroll_bar_down_arrow; 2330 emacs_event->part = scroll_bar_down_arrow;
2177 break; 2331 break;
@@ -2192,12 +2346,76 @@ x_scroll_bar_handle_click (bar, msg, emacs_event)
2192 emacs_event->part = scroll_bar_handle; 2346 emacs_event->part = scroll_bar_handle;
2193 y = top_range; 2347 y = top_range;
2194 break; 2348 break;
2349 case SB_THUMBTRACK:
2195 case SB_THUMBPOSITION: 2350 case SB_THUMBPOSITION:
2351 if (VERTICAL_SCROLL_BAR_TOP_RANGE (XINT (bar->height)) <= 0xffff)
2352 y = HIWORD (msg->msg.wParam);
2353 bar->dragging = Qt;
2196 emacs_event->part = scroll_bar_handle; 2354 emacs_event->part = scroll_bar_handle;
2355
2356 /* "Silently" update current position. */
2357 if (pfnSetScrollInfo)
2358 {
2359 SCROLLINFO si;
2360
2361 si.cbSize = sizeof (si);
2362 si.fMask = SIF_POS;
2363
2364#if 0
2365 /* Shrink handle if necessary to allow full range for position. */
2366 {
2367 int start = XINT (bar->start);
2368 int end = XINT (bar->end);
2369 int len = end - start;
2370
2371 /* If new end is nearly hitting bottom, we must shrink
2372 handle. How much we shrink it depends on the relative
2373 sizes of len and top_range. */
2374 if (y + len > top_range - 2)
2375 {
2376 len -= min (top_range / 10, (len / 3) + 2);
2377 if (len < 0)
2378 len = 0;
2379 }
2380 si.nPage = len + VERTICAL_SCROLL_BAR_MIN_HANDLE;
2381 si.fMask |= SIF_PAGE;
2382 }
2383#endif
2384 si.nPos = y;
2385 /* Remember apparent position (we actually lag behind the real
2386 position, so don't set that directly. */
2387 last_scroll_bar_drag_pos = y;
2388
2389 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, FALSE);
2390 }
2391 else
2392 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, y, FALSE);
2197 break; 2393 break;
2198 case SB_ENDSCROLL: 2394 case SB_ENDSCROLL:
2395 /* If this is the end of a drag sequence, then reset the scroll
2396 handle size to normal and do a final redraw. Otherwise do
2397 nothing. */
2398 if (dragging)
2399 {
2400 if (pfnSetScrollInfo)
2401 {
2402 SCROLLINFO si;
2403 int start = XINT (bar->start);
2404 int end = XINT (bar->end);
2405
2406 si.cbSize = sizeof (si);
2407 si.fMask = SIF_PAGE | SIF_POS;
2408 si.nPage = end - start + VERTICAL_SCROLL_BAR_MIN_HANDLE;
2409 si.nPos = last_scroll_bar_drag_pos;
2410
2411 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE);
2412 }
2413 else
2414 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, y, TRUE);
2415 }
2416 /* fall through */
2199 default: 2417 default:
2200 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, y, TRUE); 2418 emacs_event->kind = no_event;
2201 return FALSE; 2419 return FALSE;
2202 } 2420 }
2203 2421
@@ -2222,13 +2440,26 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
2222 Window w = SCROLL_BAR_W32_WINDOW (bar); 2440 Window w = SCROLL_BAR_W32_WINDOW (bar);
2223 FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); 2441 FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
2224 int pos; 2442 int pos;
2443 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (XINT (bar->height));
2225 2444
2226 BLOCK_INPUT; 2445 BLOCK_INPUT;
2227 2446
2228 *fp = f; 2447 *fp = f;
2229 *bar_window = bar->window; 2448 *bar_window = bar->window;
2230 2449
2231 pos = GetScrollPos (w, SB_CTL); 2450 if (pfnGetScrollInfo)
2451 {
2452 SCROLLINFO si;
2453
2454 si.cbSize = sizeof (si);
2455 si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
2456
2457 pfnGetScrollInfo (w, SB_CTL, &si);
2458 pos = si.nPos;
2459 top_range = si.nMax - si.nPage + 1;
2460 }
2461 else
2462 pos = GetScrollPos (w, SB_CTL);
2232 2463
2233 switch (LOWORD (last_mouse_scroll_bar_pos)) 2464 switch (LOWORD (last_mouse_scroll_bar_pos))
2234 { 2465 {
@@ -2248,7 +2479,7 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
2248 } 2479 }
2249 2480
2250 XSETINT(*x, pos); 2481 XSETINT(*x, pos);
2251 XSETINT(*y, VERTICAL_SCROLL_BAR_TOP_RANGE (XINT (bar->height))); 2482 XSETINT(*y, top_range);
2252 2483
2253 f->mouse_moved = 0; 2484 f->mouse_moved = 0;
2254 last_mouse_scroll_bar = Qnil; 2485 last_mouse_scroll_bar = Qnil;
@@ -2275,11 +2506,16 @@ x_scroll_bar_clear (f)
2275 HDC hdc = GetDC (window); 2506 HDC hdc = GetDC (window);
2276 RECT rect; 2507 RECT rect;
2277 2508
2278 my_show_window (window, SW_HIDE); 2509 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
2510 arranges to refresh the scroll bar if hidden. */
2511 my_show_window (f, window, SW_HIDE);
2512
2279 GetClientRect (window, &rect); 2513 GetClientRect (window, &rect);
2280 select_palette (f, hdc); 2514 select_palette (f, hdc);
2281 w32_clear_rect (f, hdc, &rect); 2515 w32_clear_rect (f, hdc, &rect);
2282 deselect_palette (f, hdc); 2516 deselect_palette (f, hdc);
2517
2518 ReleaseDC (window, hdc);
2283 } 2519 }
2284} 2520}
2285 2521
@@ -2293,7 +2529,7 @@ show_scroll_bars (f, how)
2293 bar = XSCROLL_BAR (bar)->next) 2529 bar = XSCROLL_BAR (bar)->next)
2294 { 2530 {
2295 HWND window = SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar)); 2531 HWND window = SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar));
2296 my_show_window (window, how); 2532 my_show_window (f, window, how);
2297 } 2533 }
2298} 2534}
2299 2535
@@ -2310,7 +2546,7 @@ static Time enter_timestamp;
2310int temp_index; 2546int temp_index;
2311short temp_buffer[100]; 2547short temp_buffer[100];
2312 2548
2313extern int key_event (KEY_EVENT_RECORD *, struct input_event *); 2549extern int key_event (KEY_EVENT_RECORD *, struct input_event *, int *isdead);
2314 2550
2315/* Map a W32 WM_CHAR message into a KEY_EVENT_RECORD so that 2551/* Map a W32 WM_CHAR message into a KEY_EVENT_RECORD so that
2316 we can use the same routines to handle input in both console 2552 we can use the same routines to handle input in both console
@@ -2369,12 +2605,9 @@ w32_read_socket (sd, bufp, numchars, expected)
2369 int expected; 2605 int expected;
2370{ 2606{
2371 int count = 0; 2607 int count = 0;
2372 int nbytes = 0; 2608 int check_visibility = 0;
2373 int items_pending; /* How many items are in the X queue. */
2374 W32Msg msg; 2609 W32Msg msg;
2375 struct frame *f; 2610 struct frame *f;
2376 int event_found = 0;
2377 int prefix;
2378 Lisp_Object part; 2611 Lisp_Object part;
2379 struct w32_display_info *dpyinfo = &one_w32_display_info; 2612 struct w32_display_info *dpyinfo = &one_w32_display_info;
2380 2613
@@ -2398,16 +2631,34 @@ w32_read_socket (sd, bufp, numchars, expected)
2398 switch (msg.msg.message) 2631 switch (msg.msg.message)
2399 { 2632 {
2400 case WM_PAINT: 2633 case WM_PAINT:
2401 {
2402 f = x_window_to_frame (dpyinfo, msg.msg.hwnd); 2634 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
2403 2635
2404 if (f) 2636 if (f)
2405 { 2637 {
2406 if (f->async_visible == 0) 2638 if (f->async_visible != 1)
2407 { 2639 {
2640 /* Definitely not obscured, so mark as visible. */
2408 f->async_visible = 1; 2641 f->async_visible = 1;
2409 f->async_iconified = 0; 2642 f->async_iconified = 0;
2410 SET_FRAME_GARBAGED (f); 2643 SET_FRAME_GARBAGED (f);
2644 DebPrint (("frame %04x (%s) reexposed\n", f,
2645 XSTRING (f->name)->data));
2646
2647 /* WM_PAINT serves as MapNotify as well, so report
2648 visibility changes properly. */
2649 if (f->iconified)
2650 {
2651 bufp->kind = deiconify_event;
2652 XSETFRAME (bufp->frame_or_window, f);
2653 bufp++;
2654 count++;
2655 numchars--;
2656 }
2657 else if (! NILP(Vframe_list)
2658 && ! NILP (XCONS (Vframe_list)->cdr))
2659 /* Force a redisplay sooner or later to update the
2660 frame titles in case this is the second frame. */
2661 record_asynch_buffer_change ();
2411 } 2662 }
2412 else 2663 else
2413 { 2664 {
@@ -2416,12 +2667,12 @@ w32_read_socket (sd, bufp, numchars, expected)
2416 dumprectangle (f, 2667 dumprectangle (f,
2417 msg.rect.left, 2668 msg.rect.left,
2418 msg.rect.top, 2669 msg.rect.top,
2419 msg.rect.right-msg.rect.left+1, 2670 msg.rect.right - msg.rect.left,
2420 msg.rect.bottom-msg.rect.top+1); 2671 msg.rect.bottom - msg.rect.top);
2421 } 2672 }
2422 } 2673 }
2423 }
2424 break; 2674 break;
2675
2425 case WM_KEYDOWN: 2676 case WM_KEYDOWN:
2426 case WM_SYSKEYDOWN: 2677 case WM_SYSKEYDOWN:
2427 f = x_window_to_frame (dpyinfo, msg.msg.hwnd); 2678 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
@@ -2433,7 +2684,8 @@ w32_read_socket (sd, bufp, numchars, expected)
2433 temp_buffer[temp_index++] = msg.msg.wParam; 2684 temp_buffer[temp_index++] = msg.msg.wParam;
2434 bufp->kind = non_ascii_keystroke; 2685 bufp->kind = non_ascii_keystroke;
2435 bufp->code = msg.msg.wParam; 2686 bufp->code = msg.msg.wParam;
2436 bufp->modifiers = w32_kbd_mods_to_emacs (msg.dwModifiers); 2687 bufp->modifiers = w32_kbd_mods_to_emacs (msg.dwModifiers,
2688 msg.msg.wParam);
2437 XSETFRAME (bufp->frame_or_window, f); 2689 XSETFRAME (bufp->frame_or_window, f);
2438 bufp->timestamp = msg.msg.time; 2690 bufp->timestamp = msg.msg.time;
2439 bufp++; 2691 bufp++;
@@ -2441,6 +2693,7 @@ w32_read_socket (sd, bufp, numchars, expected)
2441 count++; 2693 count++;
2442 } 2694 }
2443 break; 2695 break;
2696
2444 case WM_SYSCHAR: 2697 case WM_SYSCHAR:
2445 case WM_CHAR: 2698 case WM_CHAR:
2446 f = x_window_to_frame (dpyinfo, msg.msg.hwnd); 2699 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
@@ -2450,13 +2703,14 @@ w32_read_socket (sd, bufp, numchars, expected)
2450 if (numchars > 1) 2703 if (numchars > 1)
2451 { 2704 {
2452 int add; 2705 int add;
2706 int isdead = 0;
2453 KEY_EVENT_RECORD key, *keyp = &key; 2707 KEY_EVENT_RECORD key, *keyp = &key;
2454 2708
2455 if (temp_index == sizeof temp_buffer / sizeof (short)) 2709 if (temp_index == sizeof temp_buffer / sizeof (short))
2456 temp_index = 0; 2710 temp_index = 0;
2457 2711
2458 convert_to_key_event (&msg, keyp); 2712 convert_to_key_event (&msg, keyp);
2459 add = key_event (keyp, bufp); 2713 add = key_event (keyp, bufp, &isdead);
2460 XSETFRAME (bufp->frame_or_window, f); 2714 XSETFRAME (bufp->frame_or_window, f);
2461 if (add == -1) 2715 if (add == -1)
2462 { 2716 {
@@ -2470,12 +2724,7 @@ w32_read_socket (sd, bufp, numchars, expected)
2470 add = 1; 2724 add = 1;
2471 } 2725 }
2472 2726
2473 /* Throw dead keys away. However, be sure not to 2727 if (isdead)
2474 throw away the dead key if it was produced using
2475 AltGr and there is a valid AltGr scan code for
2476 this key. */
2477 if (is_dead_key (msg.msg.wParam)
2478 && !((VkKeyScan ((char) bufp->code) & 0xff00) == 0x600))
2479 break; 2728 break;
2480 2729
2481 bufp += add; 2730 bufp += add;
@@ -2488,6 +2737,7 @@ w32_read_socket (sd, bufp, numchars, expected)
2488 } 2737 }
2489 } 2738 }
2490 break; 2739 break;
2740
2491 case WM_MOUSEMOVE: 2741 case WM_MOUSEMOVE:
2492 if (dpyinfo->grabbed && last_mouse_frame 2742 if (dpyinfo->grabbed && last_mouse_frame
2493 && FRAME_LIVE_P (last_mouse_frame)) 2743 && FRAME_LIVE_P (last_mouse_frame))
@@ -2501,6 +2751,7 @@ w32_read_socket (sd, bufp, numchars, expected)
2501 clear_mouse_face (FRAME_W32_DISPLAY_INFO (f)); 2751 clear_mouse_face (FRAME_W32_DISPLAY_INFO (f));
2502 2752
2503 break; 2753 break;
2754
2504 case WM_LBUTTONDOWN: 2755 case WM_LBUTTONDOWN:
2505 case WM_LBUTTONUP: 2756 case WM_LBUTTONUP:
2506 case WM_MBUTTONDOWN: 2757 case WM_MBUTTONDOWN:
@@ -2540,12 +2791,34 @@ w32_read_socket (sd, bufp, numchars, expected)
2540 dpyinfo->grabbed |= (1 << button); 2791 dpyinfo->grabbed |= (1 << button);
2541 last_mouse_frame = f; 2792 last_mouse_frame = f;
2542 } 2793 }
2794 break;
2543 } 2795 }
2544 2796
2797 case WM_MOUSEWHEEL:
2798 if (dpyinfo->grabbed && last_mouse_frame
2799 && FRAME_LIVE_P (last_mouse_frame))
2800 f = last_mouse_frame;
2801 else
2802 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
2803
2804 if (f)
2805 {
2806 if ((!dpyinfo->w32_focus_frame
2807 || f == dpyinfo->w32_focus_frame)
2808 && (numchars >= 1))
2809 {
2810 construct_mouse_wheel (bufp, &msg, f);
2811 bufp++;
2812 count++;
2813 numchars--;
2814 }
2815 }
2545 break; 2816 break;
2817
2546 case WM_VSCROLL: 2818 case WM_VSCROLL:
2547 { 2819 {
2548 struct scroll_bar *bar = x_window_to_scroll_bar ((HWND)msg.msg.lParam); 2820 struct scroll_bar *bar =
2821 x_window_to_scroll_bar ((HWND)msg.msg.lParam);
2549 2822
2550 if (bar && numchars >= 1) 2823 if (bar && numchars >= 1)
2551 { 2824 {
@@ -2556,19 +2829,48 @@ w32_read_socket (sd, bufp, numchars, expected)
2556 numchars--; 2829 numchars--;
2557 } 2830 }
2558 } 2831 }
2832 break;
2559 } 2833 }
2560 2834
2835 case WM_WINDOWPOSCHANGED:
2836 case WM_ACTIVATE:
2837 case WM_ACTIVATEAPP:
2838 check_visibility = 1;
2561 break; 2839 break;
2840
2562 case WM_MOVE: 2841 case WM_MOVE:
2563 f = x_window_to_frame (dpyinfo, msg.msg.hwnd); 2842 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
2564 2843
2565 if (f && !f->async_iconified) 2844 if (f && !f->async_iconified)
2566 { 2845 {
2567 f->output_data.w32->left_pos = LOWORD (msg.msg.lParam); 2846 int x, y;
2568 f->output_data.w32->top_pos = HIWORD (msg.msg.lParam); 2847
2848 x_real_positions (f, &x, &y);
2849 f->output_data.w32->left_pos = x;
2850 f->output_data.w32->top_pos = y;
2569 } 2851 }
2570 2852
2853 check_visibility = 1;
2854 break;
2855
2856 case WM_SHOWWINDOW:
2857 /* If window has been obscured or exposed by another window
2858 being maximised or minimised/restored, then recheck
2859 visibility of all frames. Direct changes to our own
2860 windows get handled by WM_SIZE. */
2861#if 0
2862 if (msg.msg.lParam != 0)
2863 check_visibility = 1;
2864 else
2865 {
2866 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
2867 f->async_visible = msg.msg.wParam;
2868 }
2869#endif
2870
2871 check_visibility = 1;
2571 break; 2872 break;
2873
2572 case WM_SIZE: 2874 case WM_SIZE:
2573 f = x_window_to_frame (dpyinfo, msg.msg.hwnd); 2875 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
2574 2876
@@ -2582,12 +2884,14 @@ w32_read_socket (sd, bufp, numchars, expected)
2582 2884
2583 GetClientRect(msg.msg.hwnd, &rect); 2885 GetClientRect(msg.msg.hwnd, &rect);
2584 2886
2585 height = rect.bottom - rect.top + 1; 2887 height = rect.bottom - rect.top;
2586 width = rect.right - rect.left + 1; 2888 width = rect.right - rect.left;
2587 2889
2588 rows = PIXEL_TO_CHAR_HEIGHT (f, height); 2890 rows = PIXEL_TO_CHAR_HEIGHT (f, height);
2589 columns = PIXEL_TO_CHAR_WIDTH (f, width); 2891 columns = PIXEL_TO_CHAR_WIDTH (f, width);
2590 2892
2893 /* TODO: Clip size to the screen dimensions. */
2894
2591 /* Even if the number of character rows and columns has 2895 /* Even if the number of character rows and columns has
2592 not changed, the font size may have changed, so we need 2896 not changed, the font size may have changed, so we need
2593 to check the pixel dimensions as well. */ 2897 to check the pixel dimensions as well. */
@@ -2607,45 +2911,14 @@ w32_read_socket (sd, bufp, numchars, expected)
2607 f->output_data.w32->win_gravity = NorthWestGravity; 2911 f->output_data.w32->win_gravity = NorthWestGravity;
2608 } 2912 }
2609 } 2913 }
2610 2914
2611 break; 2915 /* Inform lisp of whether frame has been iconified etc. */
2612 case WM_SETFOCUS: 2916 if (f)
2613 case WM_KILLFOCUS:
2614 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
2615
2616 if (msg.msg.message == WM_SETFOCUS)
2617 {
2618 x_new_focus_frame (dpyinfo, f);
2619 }
2620 else if (f == dpyinfo->w32_focus_frame)
2621 x_new_focus_frame (dpyinfo, 0);
2622
2623 break;
2624 case WM_SYSCOMMAND:
2625 switch (msg.msg.wParam & 0xfff0) /* Lower 4 bits used by Windows. */
2626 { 2917 {
2627 case SC_CLOSE: 2918 switch (msg.msg.wParam)
2628 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
2629
2630 if (f)
2631 {
2632 if (numchars == 0)
2633 abort ();
2634
2635 bufp->kind = delete_window_event;
2636 XSETFRAME (bufp->frame_or_window, f);
2637 bufp++;
2638 count++;
2639 numchars--;
2640 }
2641
2642 break;
2643 case SC_MINIMIZE:
2644 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
2645
2646 if (f)
2647 { 2919 {
2648 f->async_visible = 1; 2920 case SIZE_MINIMIZED:
2921 f->async_visible = 0;
2649 f->async_iconified = 1; 2922 f->async_iconified = 1;
2650 2923
2651 bufp->kind = iconify_event; 2924 bufp->kind = iconify_event;
@@ -2653,15 +2926,10 @@ w32_read_socket (sd, bufp, numchars, expected)
2653 bufp++; 2926 bufp++;
2654 count++; 2927 count++;
2655 numchars--; 2928 numchars--;
2656 } 2929 break;
2657 2930
2658 break; 2931 case SIZE_MAXIMIZED:
2659 case SC_MAXIMIZE: 2932 case SIZE_RESTORED:
2660 case SC_RESTORE:
2661 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
2662
2663 if (f)
2664 {
2665 f->async_visible = 1; 2933 f->async_visible = 1;
2666 f->async_iconified = 0; 2934 f->async_iconified = 0;
2667 2935
@@ -2682,12 +2950,29 @@ w32_read_socket (sd, bufp, numchars, expected)
2682 to update the frame titles 2950 to update the frame titles
2683 in case this is the second frame. */ 2951 in case this is the second frame. */
2684 record_asynch_buffer_change (); 2952 record_asynch_buffer_change ();
2953 break;
2685 } 2954 }
2686
2687 break;
2688 } 2955 }
2956
2957 check_visibility = 1;
2958 break;
2959
2960 case WM_SETFOCUS:
2961 case WM_KILLFOCUS:
2962 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
2689 2963
2964 if (msg.msg.message == WM_SETFOCUS)
2965 {
2966 x_new_focus_frame (dpyinfo, f);
2967 }
2968 else if (f == dpyinfo->w32_focus_frame)
2969 {
2970 x_new_focus_frame (dpyinfo, 0);
2971 }
2972
2973 check_visibility = 1;
2690 break; 2974 break;
2975
2691 case WM_CLOSE: 2976 case WM_CLOSE:
2692 f = x_window_to_frame (dpyinfo, msg.msg.hwnd); 2977 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
2693 2978
@@ -2702,11 +2987,28 @@ w32_read_socket (sd, bufp, numchars, expected)
2702 count++; 2987 count++;
2703 numchars--; 2988 numchars--;
2704 } 2989 }
2990 break;
2991
2992 case WM_INITMENU:
2993 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
2994
2995 if (f)
2996 {
2997 if (numchars == 0)
2998 abort ();
2705 2999
3000 bufp->kind = menu_bar_activate_event;
3001 XSETFRAME (bufp->frame_or_window, f);
3002 bufp++;
3003 count++;
3004 numchars--;
3005 }
2706 break; 3006 break;
3007
2707 case WM_COMMAND: 3008 case WM_COMMAND:
2708 f = x_window_to_frame (dpyinfo, msg.msg.hwnd); 3009 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
2709 3010
3011#if 1
2710 if (f) 3012 if (f)
2711 { 3013 {
2712 if (msg.msg.lParam == 0) 3014 if (msg.msg.lParam == 0)
@@ -2743,6 +3045,24 @@ w32_read_socket (sd, bufp, numchars, expected)
2743 /* Came from popup menu */ 3045 /* Came from popup menu */
2744 } 3046 }
2745 } 3047 }
3048#endif
3049
3050 check_visibility = 1;
3051 break;
3052
3053 case WM_DISPLAYCHANGE:
3054 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
3055
3056 if (f)
3057 {
3058 dpyinfo->width = (short) LOWORD (msg.msg.lParam);
3059 dpyinfo->height = (short) HIWORD (msg.msg.lParam);
3060 dpyinfo->n_cbits = msg.msg.wParam;
3061 DebPrint (("display change: %d %d\n", dpyinfo->width,
3062 dpyinfo->height));
3063 }
3064
3065 check_visibility = 1;
2746 break; 3066 break;
2747 } 3067 }
2748 } 3068 }
@@ -2756,6 +3076,62 @@ w32_read_socket (sd, bufp, numchars, expected)
2756 pending_autoraise_frame = 0; 3076 pending_autoraise_frame = 0;
2757 } 3077 }
2758 3078
3079 /* Check which frames are still visisble, if we have enqueued any user
3080 events or been notified of events that may affect visibility. We
3081 do this here because there doesn't seem to be any direct
3082 notification from Windows that the visibility of a window has
3083 changed (at least, not in all cases). */
3084 if (count > 0 || check_visibility)
3085 {
3086 Lisp_Object tail, frame;
3087
3088 FOR_EACH_FRAME (tail, frame)
3089 {
3090 FRAME_PTR f = XFRAME (frame);
3091 /* Check "visible" frames and mark each as obscured or not.
3092 Note that async_visible is nonzero for unobscured and
3093 obscured frames, but zero for hidden and iconified frames. */
3094 if (FRAME_W32_P (f) && f->async_visible)
3095 {
3096 RECT clipbox;
3097 HDC hdc = get_frame_dc (f);
3098 GetClipBox (hdc, &clipbox);
3099 release_frame_dc (f, hdc);
3100
3101 if (clipbox.right == clipbox.left
3102 || clipbox.bottom == clipbox.top)
3103 {
3104 /* Frame has become completely obscured so mark as
3105 such (we do this by setting async_visible to 2 so
3106 that FRAME_VISIBLE_P is still true, but redisplay
3107 will skip it). */
3108 f->async_visible = 2;
3109
3110 if (!FRAME_OBSCURED_P (f))
3111 {
3112 DebPrint (("frame %04x (%s) obscured\n", f,
3113 XSTRING (f->name)->data));
3114 }
3115 }
3116 else
3117 {
3118 /* Frame is not obscured, so mark it as such. */
3119 f->async_visible = 1;
3120
3121 if (FRAME_OBSCURED_P (f))
3122 {
3123 SET_FRAME_GARBAGED (f);
3124 DebPrint (("frame %04x (%s) reexposed\n", f,
3125 XSTRING (f->name)->data));
3126
3127 /* Force a redisplay sooner or later. */
3128 record_asynch_buffer_change ();
3129 }
3130 }
3131 }
3132 }
3133 }
3134
2759 UNBLOCK_INPUT; 3135 UNBLOCK_INPUT;
2760 return count; 3136 return count;
2761} 3137}
@@ -2838,14 +3214,6 @@ x_display_bar_cursor (f, on)
2838 if (! on && f->phys_cursor_x < 0) 3214 if (! on && f->phys_cursor_x < 0)
2839 return; 3215 return;
2840 3216
2841 /* If we're not updating, then we want to use the current frame's
2842 cursor position, not our local idea of where the cursor ought to be. */
2843 if (f != updating_frame)
2844 {
2845 curs_x = FRAME_CURSOR_X (f);
2846 curs_y = FRAME_CURSOR_Y (f);
2847 }
2848
2849 /* If there is anything wrong with the current cursor state, remove it. */ 3217 /* If there is anything wrong with the current cursor state, remove it. */
2850 if (f->phys_cursor_x >= 0 3218 if (f->phys_cursor_x >= 0
2851 && (!on 3219 && (!on
@@ -2905,14 +3273,6 @@ x_display_box_cursor (f, on)
2905 if (!on && f->phys_cursor_x < 0) 3273 if (!on && f->phys_cursor_x < 0)
2906 return; 3274 return;
2907 3275
2908 /* If we're not updating, then we want to use the current frame's
2909 cursor position, not our local idea of where the cursor ought to be. */
2910 if (f != updating_frame)
2911 {
2912 curs_x = FRAME_CURSOR_X (f);
2913 curs_y = FRAME_CURSOR_Y (f);
2914 }
2915
2916 /* If cursor is currently being shown and we don't want it to be 3276 /* If cursor is currently being shown and we don't want it to be
2917 or it is in the wrong place, 3277 or it is in the wrong place,
2918 or we want a hollow box and it's not so, (pout!) 3278 or we want a hollow box and it's not so, (pout!)
@@ -2930,14 +3290,12 @@ x_display_box_cursor (f, on)
2930 /* If the cursor is in the mouse face area, redisplay that when 3290 /* If the cursor is in the mouse face area, redisplay that when
2931 we clear the cursor. */ 3291 we clear the cursor. */
2932 if (f == FRAME_W32_DISPLAY_INFO (f)->mouse_face_mouse_frame 3292 if (f == FRAME_W32_DISPLAY_INFO (f)->mouse_face_mouse_frame
2933 && 3293 && (f->phys_cursor_y > FRAME_W32_DISPLAY_INFO (f)->mouse_face_beg_row
2934 (f->phys_cursor_y > FRAME_W32_DISPLAY_INFO (f)->mouse_face_beg_row 3294 || (f->phys_cursor_y == FRAME_W32_DISPLAY_INFO (f)->mouse_face_beg_row
2935 || (f->phys_cursor_y == FRAME_W32_DISPLAY_INFO (f)->mouse_face_beg_row 3295 && f->phys_cursor_x >= FRAME_W32_DISPLAY_INFO (f)->mouse_face_beg_col))
2936 && f->phys_cursor_x >= FRAME_W32_DISPLAY_INFO (f)->mouse_face_beg_col)) 3296 && (f->phys_cursor_y < FRAME_W32_DISPLAY_INFO (f)->mouse_face_end_row
2937 && 3297 || (f->phys_cursor_y == FRAME_W32_DISPLAY_INFO (f)->mouse_face_end_row
2938 (f->phys_cursor_y < FRAME_W32_DISPLAY_INFO (f)->mouse_face_end_row 3298 && f->phys_cursor_x < FRAME_W32_DISPLAY_INFO (f)->mouse_face_end_col))
2939 || (f->phys_cursor_y == FRAME_W32_DISPLAY_INFO (f)->mouse_face_end_row
2940 && f->phys_cursor_x < FRAME_W32_DISPLAY_INFO (f)->mouse_face_end_col))
2941 /* Don't redraw the cursor's spot in mouse face 3299 /* Don't redraw the cursor's spot in mouse face
2942 if it is at the end of a line (on a newline). 3300 if it is at the end of a line (on a newline).
2943 The cursor appears there, but mouse highlighting does not. */ 3301 The cursor appears there, but mouse highlighting does not. */
@@ -2991,12 +3349,26 @@ x_display_box_cursor (f, on)
2991 } 3349 }
2992} 3350}
2993 3351
3352/* Display the cursor on frame F, or clear it, according to ON.
3353 Use the position specified by curs_x and curs_y
3354 if we are doing an update of frame F now.
3355 Otherwise use the position in the FRAME_CURSOR_X and FRAME_CURSOR_Y fields
3356 of F. */
3357
2994x_display_cursor (f, on) 3358x_display_cursor (f, on)
2995 struct frame *f; 3359 struct frame *f;
2996 int on; 3360 int on;
2997{ 3361{
2998 BLOCK_INPUT; 3362 BLOCK_INPUT;
2999 3363
3364 /* If we're not updating, then we want to use the current frame's
3365 cursor position, not our local idea of where the cursor ought to be. */
3366 if (f != updating_frame)
3367 {
3368 curs_x = FRAME_CURSOR_X (f);
3369 curs_y = FRAME_CURSOR_Y (f);
3370 }
3371
3000 if (FRAME_DESIRED_CURSOR (f) == filled_box_cursor) 3372 if (FRAME_DESIRED_CURSOR (f) == filled_box_cursor)
3001 x_display_box_cursor (f, on); 3373 x_display_box_cursor (f, on);
3002 else if (FRAME_DESIRED_CURSOR (f) == bar_cursor) 3374 else if (FRAME_DESIRED_CURSOR (f) == bar_cursor)
@@ -3122,6 +3494,9 @@ x_new_font (f, fontname)
3122 } 3494 }
3123} 3495}
3124 3496
3497/* Calculate the absolute position in frame F
3498 from its current recorded position values and gravity. */
3499
3125x_calc_absolute_position (f) 3500x_calc_absolute_position (f)
3126 struct frame *f; 3501 struct frame *f;
3127{ 3502{
@@ -3207,17 +3582,20 @@ x_set_offset (f, xoff, yoff, change_gravity)
3207 when the frame is already visible, but experiment says we do. */ 3582 when the frame is already visible, but experiment says we do. */
3208 modified_left = f->output_data.w32->left_pos; 3583 modified_left = f->output_data.w32->left_pos;
3209 modified_top = f->output_data.w32->top_pos; 3584 modified_top = f->output_data.w32->top_pos;
3585#ifndef HAVE_NTGUI
3586 /* Do not add in border widths under W32. */
3210 if (change_gravity != 0) 3587 if (change_gravity != 0)
3211 { 3588 {
3212 modified_left += f->output_data.w32->border_width; 3589 modified_left += f->output_data.w32->border_width;
3213 modified_top += f->output_data.w32->border_width; 3590 modified_top += f->output_data.w32->border_width;
3214 } 3591 }
3592#endif
3215 3593
3216 my_set_window_pos (FRAME_W32_WINDOW (f), 3594 my_set_window_pos (FRAME_W32_WINDOW (f),
3217 NULL, 3595 NULL,
3218 modified_left, modified_top, 3596 modified_left, modified_top,
3219 0,0, 3597 0,0,
3220 SWP_NOZORDER | SWP_NOSIZE); 3598 SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
3221 UNBLOCK_INPUT; 3599 UNBLOCK_INPUT;
3222} 3600}
3223 3601
@@ -3232,6 +3610,8 @@ x_set_window_size (f, change_gravity, cols, rows)
3232 int cols, rows; 3610 int cols, rows;
3233{ 3611{
3234 int pixelwidth, pixelheight; 3612 int pixelwidth, pixelheight;
3613 Lisp_Object window;
3614 struct w32_display_info *dpyinfo = &one_w32_display_info;
3235 3615
3236 BLOCK_INPUT; 3616 BLOCK_INPUT;
3237 3617
@@ -3258,14 +3638,12 @@ x_set_window_size (f, change_gravity, cols, rows)
3258 AdjustWindowRect(&rect, f->output_data.w32->dwStyle, 3638 AdjustWindowRect(&rect, f->output_data.w32->dwStyle,
3259 FRAME_EXTERNAL_MENU_BAR (f)); 3639 FRAME_EXTERNAL_MENU_BAR (f));
3260 3640
3261 /* All windows have an extra pixel */
3262
3263 my_set_window_pos (FRAME_W32_WINDOW (f), 3641 my_set_window_pos (FRAME_W32_WINDOW (f),
3264 NULL, 3642 NULL,
3265 0, 0, 3643 0, 0,
3266 rect.right - rect.left + 1, 3644 rect.right - rect.left,
3267 rect.bottom - rect.top + 1, 3645 rect.bottom - rect.top,
3268 SWP_NOZORDER | SWP_NOMOVE); 3646 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
3269 } 3647 }
3270 3648
3271 /* Now, strictly speaking, we can't be sure that this is accurate, 3649 /* Now, strictly speaking, we can't be sure that this is accurate,
@@ -3282,6 +3660,12 @@ x_set_window_size (f, change_gravity, cols, rows)
3282 PIXEL_WIDTH (f) = pixelwidth; 3660 PIXEL_WIDTH (f) = pixelwidth;
3283 PIXEL_HEIGHT (f) = pixelheight; 3661 PIXEL_HEIGHT (f) = pixelheight;
3284 3662
3663 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
3664 receive in the ConfigureNotify event; if we get what we asked
3665 for, then the event won't cause the screen to become garbaged, so
3666 we have to make sure to do it here. */
3667 SET_FRAME_GARBAGED (f);
3668
3285 /* If cursor was outside the new size, mark it as off. */ 3669 /* If cursor was outside the new size, mark it as off. */
3286 if (f->phys_cursor_y >= rows 3670 if (f->phys_cursor_y >= rows
3287 || f->phys_cursor_x >= cols) 3671 || f->phys_cursor_x >= cols)
@@ -3290,11 +3674,17 @@ x_set_window_size (f, change_gravity, cols, rows)
3290 f->phys_cursor_y = -1; 3674 f->phys_cursor_y = -1;
3291 } 3675 }
3292 3676
3293 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to 3677 /* Clear out any recollection of where the mouse highlighting was,
3294 receive in the ConfigureNotify event; if we get what we asked 3678 since it might be in a place that's outside the new frame size.
3295 for, then the event won't cause the screen to become garbaged, so 3679 Actually checking whether it is outside is a pain in the neck,
3296 we have to make sure to do it here. */ 3680 so don't try--just let the highlighting be done afresh with new size. */
3297 SET_FRAME_GARBAGED (f); 3681 window = dpyinfo->mouse_face_window;
3682 if (! NILP (window) && XFRAME (window) == f)
3683 {
3684 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
3685 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
3686 dpyinfo->mouse_face_window = Qnil;
3687 }
3298 3688
3299 UNBLOCK_INPUT; 3689 UNBLOCK_INPUT;
3300} 3690}
@@ -3306,12 +3696,17 @@ x_set_mouse_pixel_position (f, pix_x, pix_y)
3306 struct frame *f; 3696 struct frame *f;
3307 int pix_x, pix_y; 3697 int pix_x, pix_y;
3308{ 3698{
3699 RECT rect;
3700 POINT pt;
3701
3309 BLOCK_INPUT; 3702 BLOCK_INPUT;
3310 3703
3311 pix_x += f->output_data.w32->left_pos; 3704 GetClientRect (FRAME_W32_WINDOW (f), &rect);
3312 pix_y += f->output_data.w32->top_pos; 3705 pt.x = rect.left + pix_x;
3706 pt.y = rect.top + pix_y;
3707 ClientToScreen (FRAME_W32_WINDOW (f), &pt);
3313 3708
3314 SetCursorPos (pix_x, pix_y); 3709 SetCursorPos (pt.x, pt.y);
3315 3710
3316 UNBLOCK_INPUT; 3711 UNBLOCK_INPUT;
3317} 3712}
@@ -3340,6 +3735,18 @@ x_set_mouse_position (f, x, y)
3340x_focus_on_frame (f) 3735x_focus_on_frame (f)
3341 struct frame *f; 3736 struct frame *f;
3342{ 3737{
3738 struct w32_display_info *dpyinfo = &one_w32_display_info;
3739
3740 /* Give input focus to frame. */
3741 BLOCK_INPUT;
3742#if 0
3743 /* Try not to change its Z-order if possible. */
3744 if (x_window_to_frame (dpyinfo, GetForegroundWindow ()))
3745 my_set_focus (f, FRAME_W32_WINDOW (f));
3746 else
3747#endif
3748 SetForegroundWindow (FRAME_W32_WINDOW (f));
3749 UNBLOCK_INPUT;
3343} 3750}
3344 3751
3345x_unfocus_frame (f) 3752x_unfocus_frame (f)
@@ -3352,15 +3759,59 @@ x_unfocus_frame (f)
3352x_raise_frame (f) 3759x_raise_frame (f)
3353 struct frame *f; 3760 struct frame *f;
3354{ 3761{
3355// if (f->async_visible) 3762 BLOCK_INPUT;
3763
3764 /* Strictly speaking, raise-frame should only change the frame's Z
3765 order, leaving input focus unchanged. This is reasonable behaviour
3766 on X where the usual policy is point-to-focus. However, this
3767 behaviour would be very odd on Windows where the usual policy is
3768 click-to-focus.
3769
3770 On X, if the mouse happens to be over the raised frame, it gets
3771 input focus anyway (so the window with focus will never be
3772 completely obscured) - if not, then just moving the mouse over it
3773 is sufficient to give it focus. On Windows, the user must actually
3774 click on the frame (preferrably the title bar so as not to move
3775 point), which is more awkward. Also, no other Windows program
3776 raises a window to the top but leaves another window (possibly now
3777 completely obscured) with input focus.
3778
3779 Because there is a system setting on Windows that allows the user
3780 to choose the point to focus policy, we make the strict semantics
3781 optional, but by default we grab focus when raising. */
3782
3783 if (NILP (Vw32_grab_focus_on_raise))
3356 { 3784 {
3357 BLOCK_INPUT; 3785 /* The obvious call to my_set_window_pos doesn't work if Emacs is
3358 my_set_window_pos (FRAME_W32_WINDOW (f), 3786 not already the foreground application: the frame is raised
3359 HWND_TOP, 3787 above all other frames belonging to us, but not above the
3360 0, 0, 0, 0, 3788 current top window. To achieve that, we have to resort to this
3361 SWP_NOSIZE | SWP_NOMOVE); 3789 more cumbersome method. */
3362 UNBLOCK_INPUT; 3790
3791 HDWP handle = BeginDeferWindowPos (2);
3792 if (handle)
3793 {
3794 DeferWindowPos (handle,
3795 FRAME_W32_WINDOW (f),
3796 HWND_TOP,
3797 0, 0, 0, 0,
3798 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
3799
3800 DeferWindowPos (handle,
3801 GetForegroundWindow (),
3802 FRAME_W32_WINDOW (f),
3803 0, 0, 0, 0,
3804 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
3805
3806 EndDeferWindowPos (handle);
3807 }
3363 } 3808 }
3809 else
3810 {
3811 SetForegroundWindow (FRAME_W32_WINDOW (f));
3812 }
3813
3814 UNBLOCK_INPUT;
3364} 3815}
3365 3816
3366/* Lower frame F. */ 3817/* Lower frame F. */
@@ -3368,15 +3819,12 @@ x_raise_frame (f)
3368x_lower_frame (f) 3819x_lower_frame (f)
3369 struct frame *f; 3820 struct frame *f;
3370{ 3821{
3371// if (f->async_visible) 3822 BLOCK_INPUT;
3372 { 3823 my_set_window_pos (FRAME_W32_WINDOW (f),
3373 BLOCK_INPUT; 3824 HWND_BOTTOM,
3374 my_set_window_pos (FRAME_W32_WINDOW (f), 3825 0, 0, 0, 0,
3375 HWND_BOTTOM, 3826 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
3376 0, 0, 0, 0, 3827 UNBLOCK_INPUT;
3377 SWP_NOSIZE | SWP_NOMOVE);
3378 UNBLOCK_INPUT;
3379 }
3380} 3828}
3381 3829
3382static void 3830static void
@@ -3412,14 +3860,12 @@ x_make_frame_visible (f)
3412 before the window gets really visible. */ 3860 before the window gets really visible. */
3413 if (! FRAME_ICONIFIED_P (f) 3861 if (! FRAME_ICONIFIED_P (f)
3414 && ! f->output_data.w32->asked_for_visible) 3862 && ! f->output_data.w32->asked_for_visible)
3415 {
3416 x_set_offset (f, f->output_data.w32->left_pos, f->output_data.w32->top_pos, 0); 3863 x_set_offset (f, f->output_data.w32->left_pos, f->output_data.w32->top_pos, 0);
3417// SetForegroundWindow (FRAME_W32_WINDOW (f));
3418 }
3419 3864
3420 f->output_data.w32->asked_for_visible = 1; 3865 f->output_data.w32->asked_for_visible = 1;
3421 3866
3422 my_show_window (FRAME_W32_WINDOW (f), SW_SHOWNORMAL); 3867// my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW);
3868 my_show_window (f, FRAME_W32_WINDOW (f), SW_SHOWNORMAL);
3423 } 3869 }
3424 3870
3425 /* Synchronize to ensure Emacs knows the frame is visible 3871 /* Synchronize to ensure Emacs knows the frame is visible
@@ -3482,7 +3928,7 @@ x_make_frame_invisible (f)
3482 3928
3483 BLOCK_INPUT; 3929 BLOCK_INPUT;
3484 3930
3485 my_show_window (FRAME_W32_WINDOW (f), SW_HIDE); 3931 my_show_window (f, FRAME_W32_WINDOW (f), SW_HIDE);
3486 3932
3487 /* We can't distinguish this from iconification 3933 /* We can't distinguish this from iconification
3488 just by the event that we get from the server. 3934 just by the event that we get from the server.
@@ -3514,9 +3960,8 @@ x_iconify_frame (f)
3514 3960
3515 BLOCK_INPUT; 3961 BLOCK_INPUT;
3516 3962
3517 my_show_window (FRAME_W32_WINDOW (f), SW_SHOWMINIMIZED); 3963 /* Simulate the user minimizing the frame. */
3518 /* The frame doesn't seem to be lowered automatically. */ 3964 PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0);
3519 x_lower_frame (f);
3520 3965
3521 f->async_iconified = 1; 3966 f->async_iconified = 1;
3522 3967
@@ -3578,8 +4023,10 @@ x_wm_set_size_hint (f, flags, user_position)
3578 4023
3579 enter_crit (); 4024 enter_crit ();
3580 4025
3581 SetWindowLong (window, WND_X_UNITS_INDEX, FONT_WIDTH (f->output_data.w32->font)); 4026 SetWindowLong (window, WND_FONTWIDTH_INDEX, FONT_WIDTH (f->output_data.w32->font));
3582 SetWindowLong (window, WND_Y_UNITS_INDEX, f->output_data.w32->line_height); 4027 SetWindowLong (window, WND_LINEHEIGHT_INDEX, f->output_data.w32->line_height);
4028 SetWindowLong (window, WND_BORDER_INDEX, f->output_data.w32->internal_border_width);
4029 SetWindowLong (window, WND_SCROLLBAR_INDEX, f->output_data.w32->vertical_scroll_bar_extra);
3583 4030
3584 leave_crit (); 4031 leave_crit ();
3585} 4032}
@@ -3794,7 +4241,7 @@ x_delete_display (dpyinfo)
3794 4241
3795/* Set up use of W32. */ 4242/* Set up use of W32. */
3796 4243
3797DWORD windows_msg_worker (); 4244DWORD w32_msg_worker ();
3798 4245
3799w32_initialize () 4246w32_initialize ()
3800{ 4247{
@@ -3831,8 +4278,9 @@ w32_initialize ()
3831 off the bottom */ 4278 off the bottom */
3832 baud_rate = 19200; 4279 baud_rate = 19200;
3833 4280
3834 /* Try to use interrupt input; if we can't, then start polling. */ 4281 /* Initialize input mode: interrupt_input off, no flow control, allow
3835 Fset_input_mode (Qt, Qnil, Qt, Qnil); 4282 8 bit character input, standard quit char. */
4283 Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
3836 4284
3837 /* Create the window thread - it will terminate itself or when the app terminates */ 4285 /* Create the window thread - it will terminate itself or when the app terminates */
3838 4286
@@ -3850,7 +4298,7 @@ w32_initialize ()
3850 PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE); 4298 PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
3851 4299
3852 hWindowsThread = CreateThread (NULL, 0, 4300 hWindowsThread = CreateThread (NULL, 0,
3853 (LPTHREAD_START_ROUTINE) windows_msg_worker, 4301 (LPTHREAD_START_ROUTINE) w32_msg_worker,
3854 0, 0, &dwWindowsThreadId); 4302 0, 0, &dwWindowsThreadId);
3855 4303
3856 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE); 4304 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
@@ -3867,6 +4315,31 @@ w32_initialize ()
3867#ifdef ATTACH_THREADS 4315#ifdef ATTACH_THREADS
3868 AttachThreadInput (dwMainThreadId, dwWindowsThreadId, TRUE); 4316 AttachThreadInput (dwMainThreadId, dwWindowsThreadId, TRUE);
3869#endif 4317#endif
4318
4319 /* Dynamically link to optional system components. */
4320 {
4321 HANDLE user_lib = LoadLibrary ("user32.dll");
4322
4323#define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
4324
4325 /* New proportional scroll bar functions. */
4326 LOAD_PROC( SetScrollInfo );
4327 LOAD_PROC( GetScrollInfo );
4328
4329#undef LOAD_PROC
4330
4331 FreeLibrary (user_lib);
4332
4333 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
4334 otherwise use the fixed height. */
4335 vertical_scroll_bar_min_handle = (pfnSetScrollInfo != NULL) ? 5 :
4336 GetSystemMetrics (SM_CYVTHUMB);
4337
4338 /* For either kind of scroll bar, take account of the arrows; these
4339 effectively form the border of the main scroll bar range. */
4340 vertical_scroll_bar_top_border = vertical_scroll_bar_bottom_border
4341 = GetSystemMetrics (SM_CYVSCROLL);
4342 }
3870} 4343}
3871 4344
3872void 4345void
@@ -3891,4 +4364,18 @@ syms_of_w32term ()
3891 "Swap the mapping of middle and right mouse buttons.\n\ 4364 "Swap the mapping of middle and right mouse buttons.\n\
3892When nil, middle button is mouse-2 and right button is mouse-3."); 4365When nil, middle button is mouse-2 and right button is mouse-3.");
3893 Vw32_swap_mouse_buttons = Qnil; 4366 Vw32_swap_mouse_buttons = Qnil;
4367
4368 DEFVAR_LISP ("w32-grab-focus-on-raise",
4369 &Vw32_grab_focus_on_raise,
4370 "Raised frame grabs input focus.\n\
4371When t, `raise-frame' grabs input focus as well. This fits well\n\
4372with the normal Windows click-to-focus policy, but might not be\n\
4373desirable when using a point-to-focus policy.");
4374 Vw32_grab_focus_on_raise = Qt;
4375
4376 DEFVAR_LISP ("w32-capslock-is-shiftlock",
4377 &Vw32_capslock_is_shiftlock,
4378 "Apply CapsLock state to non character input keys.\n\
4379When nil, CapsLock only affects normal character input keys.");
4380 Vw32_capslock_is_shiftlock = Qnil;
3894} 4381}