comparison src/event-msw.c @ 410:de805c49cfc1 r21-2-35

Import from CVS: tag r21-2-35
author cvs
date Mon, 13 Aug 2007 11:19:21 +0200
parents 501cfd01ee6d
children 697ef44129c6
comparison
equal deleted inserted replaced
409:301b9ebbdf3b 410:de805c49cfc1
67 67
68 #include "events-mod.h" 68 #include "events-mod.h"
69 #ifdef HAVE_MSG_SELECT 69 #ifdef HAVE_MSG_SELECT
70 #include "sysfile.h" 70 #include "sysfile.h"
71 #include "console-tty.h" 71 #include "console-tty.h"
72 #elif defined(__CYGWIN32__) 72 #elif defined(CYGWIN)
73 typedef unsigned int SOCKET; 73 typedef unsigned int SOCKET;
74 #endif 74 #endif
75 #include <io.h> 75 #include <io.h>
76 #include <errno.h> 76 #include <errno.h>
77 77
78 #if !(defined(__CYGWIN32__) || defined(__MINGW32__)) 78 #if !(defined(CYGWIN) || defined(MINGW))
79 # include <shlobj.h> /* For IShellLink */ 79 # include <shlobj.h> /* For IShellLink */
80 #endif 80 #endif
81 81
82 #ifdef HAVE_MENUBARS 82 #ifdef HAVE_MENUBARS
83 #define ADJR_MENUFLAG TRUE 83 #define ADJR_MENUFLAG TRUE
469 /************************************************************************/ 469 /************************************************************************/
470 470
471 #define NTPIPE_SHOVE_STREAM_DATA(stream) \ 471 #define NTPIPE_SHOVE_STREAM_DATA(stream) \
472 LSTREAM_TYPE_DATA (stream, ntpipe_shove) 472 LSTREAM_TYPE_DATA (stream, ntpipe_shove)
473 473
474 #define MAX_SHOVE_BUFFER_SIZE 128 474 #define MAX_SHOVE_BUFFER_SIZE 512
475 475
476 struct ntpipe_shove_stream 476 struct ntpipe_shove_stream
477 { 477 {
478 LPARAM user_data; /* Any user data stored in the stream object */ 478 LPARAM user_data; /* Any user data stored in the stream object */
479 HANDLE hev_thread; /* Our thread blocks on this, signaled by caller */ 479 HANDLE hev_thread; /* Our thread blocks on this, signaled by caller */
503 503
504 /* Block on event and wait for a job */ 504 /* Block on event and wait for a job */
505 InterlockedIncrement (&s->idle_p); 505 InterlockedIncrement (&s->idle_p);
506 WaitForSingleObject (s->hev_thread, INFINITE); 506 WaitForSingleObject (s->hev_thread, INFINITE);
507 507
508 if (s->die_p) 508 /* Write passed buffer if any */
509 break; 509 if (s->size > 0)
510 510 {
511 /* Write passed buffer */ 511 if (!WriteFile (s->hpipe, s->buffer, s->size, &bytes_written, NULL)
512 if (!WriteFile (s->hpipe, s->buffer, s->size, &bytes_written, NULL) 512 || bytes_written != s->size)
513 || bytes_written != s->size) 513 {
514 { 514 s->error_p = TRUE;
515 s->error_p = TRUE; 515 InterlockedIncrement (&s->die_p);
516 InterlockedIncrement (&s->die_p); 516 }
517 /* Set size to zero so we won't write it again if the closer sets
518 die_p and kicks us */
519 s->size = 0;
517 } 520 }
518 521
519 if (s->die_p) 522 if (s->die_p)
520 break; 523 break;
521 } 524 }
544 { 547 {
545 Lstream_delete (lstr); 548 Lstream_delete (lstr);
546 return Qnil; 549 return Qnil;
547 } 550 }
548 551
552 /* Set the priority of the thread higher so we don't end up waiting
553 on it to send things. */
554 if (!SetThreadPriority (s->hthread, THREAD_PRIORITY_HIGHEST))
555 {
556 CloseHandle (s->hthread);
557 Lstream_delete (lstr);
558 return Qnil;
559 }
560
549 /* hev_thread is an auto-reset event, initially nonsignaled */ 561 /* hev_thread is an auto-reset event, initially nonsignaled */
550 s->hev_thread = CreateEvent (NULL, FALSE, FALSE, NULL); 562 s->hev_thread = CreateEvent (NULL, FALSE, FALSE, NULL);
551 563
552 /* Now let it go */ 564 /* Now let it go */
553 ResumeThread (s->hthread); 565 ResumeThread (s->hthread);
584 s->size = size; 596 s->size = size;
585 597
586 /* Start output */ 598 /* Start output */
587 InterlockedDecrement (&s->idle_p); 599 InterlockedDecrement (&s->idle_p);
588 SetEvent (s->hev_thread); 600 SetEvent (s->hev_thread);
601 /* Give it a chance to run -- this dramatically improves performance
602 of things like crypt. */
603 (void) SwitchToThread ();
589 return size; 604 return size;
590 } 605 }
591 606
592 static int 607 static int
593 ntpipe_shove_was_blocked_p (Lstream *stream) 608 ntpipe_shove_was_blocked_p (Lstream *stream)
602 struct ntpipe_shove_stream* s = NTPIPE_SHOVE_STREAM_DATA(stream); 617 struct ntpipe_shove_stream* s = NTPIPE_SHOVE_STREAM_DATA(stream);
603 618
604 /* Force thread stop */ 619 /* Force thread stop */
605 InterlockedIncrement (&s->die_p); 620 InterlockedIncrement (&s->die_p);
606 621
622 /* Thread will end upon unblocking. If it's already unblocked this will
623 do nothing, but the thread won't look at die_p until it's written any
624 pending output. */
625 SetEvent (s->hev_thread);
626
627 /* Wait while thread terminates */
628 WaitForSingleObject (s->hthread, INFINITE);
629
607 /* Close pipe handle, possibly breaking it */ 630 /* Close pipe handle, possibly breaking it */
608 CloseHandle (s->hpipe); 631 CloseHandle (s->hpipe);
609 632
610 /* Thread will end upon unblocking */ 633 /* Close the thread handle */
611 SetEvent (s->hev_thread);
612
613 /* Wait while thread terminates */
614 WaitForSingleObject (s->hthread, INFINITE);
615 CloseHandle (s->hthread); 634 CloseHandle (s->hthread);
616 635
617 /* Destroy the event */ 636 /* Destroy the event */
618 CloseHandle (s->hev_thread); 637 CloseHandle (s->hev_thread);
619 638
1249 /* should call mswindows_need_event_in_modal_loop() if in modal loop */ 1268 /* should call mswindows_need_event_in_modal_loop() if in modal loop */
1250 assert (!mswindows_in_modal_loop); 1269 assert (!mswindows_in_modal_loop);
1251 1270
1252 while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) 1271 while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
1253 { 1272 {
1254 /* We have to translate messages that are not sent to the main 1273 /* We have to translate messages that are not sent to an XEmacs
1255 window. This is so that key presses work ok in things like 1274 frame. This is so that key presses work ok in things like
1256 edit fields. However, we *musn't* translate message for the 1275 edit fields. However, we *musn't* translate message for XEmacs
1257 main window as this is handled in the wnd proc. 1276 frames as this is handled in the wnd proc.
1258 We also have to avoid generating paint magic events for windows 1277 We also have to avoid generating paint magic events for windows
1259 that aren't XEmacs frames */ 1278 that aren't XEmacs frames */
1260 if (GetWindowLong (msg.hwnd, GWL_STYLE) & (WS_CHILD|WS_POPUP)) 1279 /* GetClassName will truncate a longer class name. By adding one
1261 { 1280 extra character, we are forcing textual comparison to fail
1281 if the name is longer than XEMACS_CLASS */
1282 char class_name_buf [sizeof (XEMACS_CLASS) + 2] = "";
1283 GetClassName (msg.hwnd, class_name_buf, sizeof (class_name_buf) - 1);
1284 if (stricmp (class_name_buf, XEMACS_CLASS) != 0)
1285 {
1286 /* Not an XEmacs frame */
1262 TranslateMessage (&msg); 1287 TranslateMessage (&msg);
1263 } 1288 }
1264 else if (msg.message == WM_PAINT) 1289 else if (msg.message == WM_PAINT)
1265 { 1290 {
1266 struct mswindows_frame* msframe; 1291 struct mswindows_frame* msframe;
1268 /* hdc will be NULL unless this is a subwindow - in which case we 1293 /* hdc will be NULL unless this is a subwindow - in which case we
1269 shouldn't have received a paint message for it here. */ 1294 shouldn't have received a paint message for it here. */
1270 assert (msg.wParam == 0); 1295 assert (msg.wParam == 0);
1271 1296
1272 /* Queue a magic event for handling when safe */ 1297 /* Queue a magic event for handling when safe */
1273 msframe = FRAME_MSWINDOWS_DATA ( 1298 msframe =
1274 XFRAME (mswindows_find_frame (msg.hwnd))); 1299 FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (msg.hwnd)));
1275 if (!msframe->paint_pending) 1300 if (!msframe->paint_pending)
1276 { 1301 {
1277 msframe->paint_pending = 1; 1302 msframe->paint_pending = 1;
1278 mswindows_enqueue_magic_event (msg.hwnd, WM_PAINT); 1303 mswindows_enqueue_magic_event (msg.hwnd, WM_PAINT);
1279 } 1304 }
1598 if (*(++end)==']') 1623 if (*(++end)==']')
1599 end++; 1624 end++;
1600 if (*end) 1625 if (*end)
1601 return DDE_FNOTPROCESSED; 1626 return DDE_FNOTPROCESSED;
1602 1627
1603 #ifdef __CYGWIN32__ 1628 #ifdef CYGWIN
1604 filename = alloca (cygwin32_win32_to_posix_path_list_buf_size (cmd) + 5); 1629 filename = alloca (cygwin32_win32_to_posix_path_list_buf_size (cmd) + 5);
1605 strcpy (filename, "file:"); 1630 strcpy (filename, "file:");
1606 cygwin32_win32_to_posix_path_list (cmd, filename+5); 1631 cygwin32_win32_to_posix_path_list (cmd, filename+5);
1607 #else 1632 #else
1608 dostounix_filename (cmd); 1633 dostounix_filename (cmd);
1753 manually press the Right arrow a bunch of times, I want 1778 manually press the Right arrow a bunch of times, I want
1754 to see one Control-Right and then a bunch of Rights. 1779 to see one Control-Right and then a bunch of Rights.
1755 This means that we need to distinguish between an 1780 This means that we need to distinguish between an
1756 auto-repeated key and a key pressed and released a bunch 1781 auto-repeated key and a key pressed and released a bunch
1757 of times. */ 1782 of times. */
1758 else if (downp && !keyp || 1783 else if ((downp && !keyp) ||
1759 (downp && keyp && last_downkey && 1784 (downp && keyp && last_downkey &&
1760 (wParam != last_downkey || 1785 (wParam != last_downkey ||
1761 /* the "previous key state" bit indicates autorepeat */ 1786 /* the "previous key state" bit indicates autorepeat */
1762 ! (lParam & (1 << 30))))) 1787 ! (lParam & (1 << 30)))))
1763 { 1788 {
1808 need_to_add_mask |= mask; \ 1833 need_to_add_mask |= mask; \
1809 } \ 1834 } \
1810 } \ 1835 } \
1811 } while (0) 1836 } while (0)
1812 1837
1813 if (wParam == VK_CONTROL && (lParam & 0x1000000) 1838 if ((wParam == VK_CONTROL && (lParam & 0x1000000))
1814 || wParam == VK_RCONTROL) 1839 || wParam == VK_RCONTROL)
1815 FROB (XEMSW_RCONTROL); 1840 FROB (XEMSW_RCONTROL);
1816 if (wParam == VK_CONTROL && !(lParam & 0x1000000) 1841 if ((wParam == VK_CONTROL && !(lParam & 0x1000000))
1817 || wParam == VK_LCONTROL) 1842 || wParam == VK_LCONTROL)
1818 FROB (XEMSW_LCONTROL); 1843 FROB (XEMSW_LCONTROL);
1819 1844
1820 if (wParam == VK_SHIFT && (lParam & 0x1000000) 1845 if ((wParam == VK_SHIFT && (lParam & 0x1000000))
1821 || wParam == VK_RSHIFT) 1846 || wParam == VK_RSHIFT)
1822 FROB (XEMSW_RSHIFT); 1847 FROB (XEMSW_RSHIFT);
1823 if (wParam == VK_SHIFT && !(lParam & 0x1000000) 1848 if ((wParam == VK_SHIFT && !(lParam & 0x1000000))
1824 || wParam == VK_LSHIFT) 1849 || wParam == VK_LSHIFT)
1825 FROB (XEMSW_LSHIFT); 1850 FROB (XEMSW_LSHIFT);
1826 1851
1827 if (wParam == VK_MENU && (lParam & 0x1000000) 1852 if ((wParam == VK_MENU && (lParam & 0x1000000))
1828 || wParam == VK_RMENU) 1853 || wParam == VK_RMENU)
1829 FROB (XEMSW_RMENU); 1854 FROB (XEMSW_RMENU);
1830 if (wParam == VK_MENU && !(lParam & 0x1000000) 1855 if ((wParam == VK_MENU && !(lParam & 0x1000000))
1831 || wParam == VK_LMENU) 1856 || wParam == VK_LMENU)
1832 FROB (XEMSW_LMENU); 1857 FROB (XEMSW_LMENU);
1833 } 1858 }
1834 #undef FROB 1859 #undef FROB
1835 1860
1886 last_downkey = 0; 1911 last_downkey = 0;
1887 down_mask = 0; 1912 down_mask = 0;
1888 } 1913 }
1889 1914
1890 #ifdef DEBUG_XEMACS 1915 #ifdef DEBUG_XEMACS
1916
1917 #if 0
1891 1918
1892 static void 1919 static void
1893 output_modifier_keyboard_state (void) 1920 output_modifier_keyboard_state (void)
1894 { 1921 {
1895 BYTE keymap[256]; 1922 BYTE keymap[256];
1917 keymap[VK_LSHIFT] & 0x1 ? 1 : 0, 1944 keymap[VK_LSHIFT] & 0x1 ? 1 : 0,
1918 keymap[VK_RSHIFT] & 0x80 ? 1 : 0, 1945 keymap[VK_RSHIFT] & 0x80 ? 1 : 0,
1919 keymap[VK_RSHIFT] & 0x1 ? 1 : 0); 1946 keymap[VK_RSHIFT] & 0x1 ? 1 : 0);
1920 } 1947 }
1921 1948
1949 #endif
1950
1922 /* try to debug the stuck-alt-key problem. 1951 /* try to debug the stuck-alt-key problem.
1923 1952
1924 #### this happens only inconsistently, and may only happen when using 1953 #### this happens only inconsistently, and may only happen when using
1925 StickyKeys in the Win2000 accessibility section of the control panel, 1954 StickyKeys in the Win2000 accessibility section of the control panel,
1926 which is extremely broken for other reasons. */ 1955 which is extremely broken for other reasons. */
1969 1998
1970 /* 1999 /*
1971 * The windows procedure for the window class XEMACS_CLASS 2000 * The windows procedure for the window class XEMACS_CLASS
1972 */ 2001 */
1973 LRESULT WINAPI 2002 LRESULT WINAPI
1974 mswindows_wnd_proc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 2003 mswindows_wnd_proc (HWND hwnd, UINT message_, WPARAM wParam, LPARAM lParam)
1975 { 2004 {
1976 /* Note: Remember to initialize emacs_event and event before use. 2005 /* Note: Remember to initialize emacs_event and event before use.
1977 This code calls code that can GC. You must GCPRO before calling such code. */ 2006 This code calls code that can GC. You must GCPRO before calling such code. */
1978 Lisp_Object emacs_event = Qnil; 2007 Lisp_Object emacs_event = Qnil;
1979 Lisp_Object fobj = Qnil; 2008 Lisp_Object fobj = Qnil;
1981 Lisp_Event *event; 2010 Lisp_Event *event;
1982 struct frame *frame; 2011 struct frame *frame;
1983 struct mswindows_frame* msframe; 2012 struct mswindows_frame* msframe;
1984 2013
1985 assert (!GetWindowLong (hwnd, GWL_USERDATA)); 2014 assert (!GetWindowLong (hwnd, GWL_USERDATA));
1986 switch (message) 2015 switch (message_)
1987 { 2016 {
1988 case WM_DESTROYCLIPBOARD: 2017 case WM_DESTROYCLIPBOARD:
1989 /* We own the clipboard and someone else wants it. Delete our 2018 /* We own the clipboard and someone else wants it. Delete our
1990 cached copy of the clipboard contents so we'll ask for it from 2019 cached copy of the clipboard contents so we'll ask for it from
1991 Windows again when someone does a paste. */ 2020 Windows again when someone does a paste, and destroy any memory
1992 handle_selection_clear(QCLIPBOARD); 2021 objects we hold on the clipboard that are not in the list of types
2022 that Windows will delete itself. */
2023 mswindows_destroy_selection (QCLIPBOARD);
2024 handle_selection_clear (QCLIPBOARD);
1993 break; 2025 break;
1994 2026
1995 case WM_ERASEBKGND: 2027 case WM_ERASEBKGND:
1996 /* Erase background only during non-dynamic sizing */ 2028 /* Erase background only during non-dynamic sizing */
1997 msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); 2029 msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
2014 2046
2015 #ifdef DEBUG_XEMACS 2047 #ifdef DEBUG_XEMACS
2016 if (mswindows_debug_events) 2048 if (mswindows_debug_events)
2017 { 2049 {
2018 stderr_out ("%s wparam=%d lparam=%d\n", 2050 stderr_out ("%s wparam=%d lparam=%d\n",
2019 message == WM_KEYUP ? "WM_KEYUP" : "WM_SYSKEYUP", 2051 message_ == WM_KEYUP ? "WM_KEYUP" : "WM_SYSKEYUP",
2020 wParam, (int)lParam); 2052 wParam, (int)lParam);
2021 output_alt_keyboard_state (); 2053 output_alt_keyboard_state ();
2022 } 2054 }
2023 #endif /* DEBUG_XEMACS */ 2055 #endif /* DEBUG_XEMACS */
2024 2056
2035 keymap [(lParam & 0x1000000) ? VK_RMENU : VK_LMENU] &= ~0x80; 2067 keymap [(lParam & 0x1000000) ? VK_RMENU : VK_LMENU] &= ~0x80;
2036 should_set_keymap = 1; 2068 should_set_keymap = 1;
2037 } 2069 }
2038 2070
2039 if (should_set_keymap) 2071 if (should_set_keymap)
2040 // && (message != WM_SYSKEYUP 2072 // && (message_ != WM_SYSKEYUP
2041 // || NILP (Vmenu_accelerator_enabled))) 2073 // || NILP (Vmenu_accelerator_enabled)))
2042 SetKeyboardState (keymap); 2074 SetKeyboardState (keymap);
2043 2075
2044 } 2076 }
2045 2077
2071 2103
2072 #ifdef DEBUG_XEMACS 2104 #ifdef DEBUG_XEMACS
2073 if (mswindows_debug_events) 2105 if (mswindows_debug_events)
2074 { 2106 {
2075 stderr_out ("%s wparam=%d lparam=%d\n", 2107 stderr_out ("%s wparam=%d lparam=%d\n",
2076 message == WM_KEYDOWN ? "WM_KEYDOWN" : "WM_SYSKEYDOWN", 2108 message_ == WM_KEYDOWN ? "WM_KEYDOWN" : "WM_SYSKEYDOWN",
2077 wParam, (int)lParam); 2109 wParam, (int)lParam);
2078 output_alt_keyboard_state (); 2110 output_alt_keyboard_state ();
2079 } 2111 }
2080 #endif /* DEBUG_XEMACS */ 2112 #endif /* DEBUG_XEMACS */
2081 2113
2085 mswindows_handle_sticky_modifiers (wParam, lParam, 1, 1))) 2117 mswindows_handle_sticky_modifiers (wParam, lParam, 1, 1)))
2086 { 2118 {
2087 GetKeyboardState (keymap_sticky); 2119 GetKeyboardState (keymap_sticky);
2088 if (keymap_sticky[VK_MENU] & 0x80) 2120 if (keymap_sticky[VK_MENU] & 0x80)
2089 { 2121 {
2090 message = WM_SYSKEYDOWN; 2122 message_ = WM_SYSKEYDOWN;
2091 /* We have to set the "context bit" so that the 2123 /* We have to set the "context bit" so that the
2092 TranslateMessage() call below that generates the 2124 TranslateMessage() call below that generates the
2093 SYSCHAR message does its thing; see the documentation 2125 SYSCHAR message does its thing; see the documentation
2094 on WM_SYSKEYDOWN */ 2126 on WM_SYSKEYDOWN */
2095 lParam |= 1 << 29; 2127 lParam |= 1 << 29;
2116 MSG msg, tranmsg; 2148 MSG msg, tranmsg;
2117 int potential_accelerator = 0; 2149 int potential_accelerator = 0;
2118 int got_accelerator = 0; 2150 int got_accelerator = 0;
2119 2151
2120 msg.hwnd = hwnd; 2152 msg.hwnd = hwnd;
2121 msg.message = message; 2153 msg.message = message_;
2122 msg.wParam = wParam; 2154 msg.wParam = wParam;
2123 msg.lParam = lParam; 2155 msg.lParam = lParam;
2124 msg.time = GetMessageTime(); 2156 msg.time = GetMessageTime();
2125 msg.pt = pnt; 2157 msg.pt = pnt;
2126 2158
2137 keymap_orig[extendedp ? VK_RMENU : VK_LMENU] |= 0x80; 2169 keymap_orig[extendedp ? VK_RMENU : VK_LMENU] |= 0x80;
2138 keymap_sticky[extendedp ? VK_RMENU : VK_LMENU] |= 0x80; 2170 keymap_sticky[extendedp ? VK_RMENU : VK_LMENU] |= 0x80;
2139 } 2171 }
2140 2172
2141 if (!NILP (Vmenu_accelerator_enabled) && 2173 if (!NILP (Vmenu_accelerator_enabled) &&
2142 !(mods & XEMACS_MOD_SHIFT) && message == WM_SYSKEYDOWN) 2174 !(mods & XEMACS_MOD_SHIFT) && message_ == WM_SYSKEYDOWN)
2143 potential_accelerator = 1; 2175 potential_accelerator = 1;
2144 2176
2145 /* Remove shift modifier from an ascii character */ 2177 /* Remove shift modifier from an ascii character */
2146 mods &= ~XEMACS_MOD_SHIFT; 2178 mods &= ~XEMACS_MOD_SHIFT;
2147 2179
2184 { 2216 {
2185 mods1 |= FAKE_MOD_QUIT; 2217 mods1 |= FAKE_MOD_QUIT;
2186 ++mswindows_quit_chars_count; 2218 ++mswindows_quit_chars_count;
2187 } 2219 }
2188 else if (potential_accelerator && !got_accelerator && 2220 else if (potential_accelerator && !got_accelerator &&
2189 msw_char_is_accelerator (frame, ch)) 2221 mswindows_char_is_accelerator (frame, ch))
2190 { 2222 {
2191 got_accelerator = 1; 2223 got_accelerator = 1;
2192 break; 2224 break;
2193 } 2225 }
2194 mswindows_enqueue_keypress_event (hwnd, make_char (ch), mods1); 2226 mswindows_enqueue_keypress_event (hwnd, make_char (ch), mods1);
2216 case WM_MBUTTONDOWN: 2248 case WM_MBUTTONDOWN:
2217 case WM_MBUTTONUP: 2249 case WM_MBUTTONUP:
2218 /* Real middle mouse button has nothing to do with emulated one: 2250 /* Real middle mouse button has nothing to do with emulated one:
2219 if one wants to exercise fingers playing chords on the mouse, 2251 if one wants to exercise fingers playing chords on the mouse,
2220 he is allowed to do that! */ 2252 he is allowed to do that! */
2221 mswindows_enqueue_mouse_button_event (hwnd, message, 2253 mswindows_enqueue_mouse_button_event (hwnd, message_,
2222 MAKEPOINTS (lParam), GetMessageTime()); 2254 MAKEPOINTS (lParam), GetMessageTime());
2223 break; 2255 break;
2224 2256
2225 case WM_LBUTTONUP: 2257 case WM_LBUTTONUP:
2226 msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); 2258 msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
2531 break; 2563 break;
2532 2564
2533 case WM_DISPLAYCHANGE: 2565 case WM_DISPLAYCHANGE:
2534 { 2566 {
2535 struct device *d; 2567 struct device *d;
2568 DWORD message_tick = GetMessageTime ();
2536 2569
2537 fobj = mswindows_find_frame (hwnd); 2570 fobj = mswindows_find_frame (hwnd);
2538 frame = XFRAME (fobj); 2571 frame = XFRAME (fobj);
2539 d = XDEVICE (FRAME_DEVICE (frame)); 2572 d = XDEVICE (FRAME_DEVICE (frame));
2540 2573
2541 DEVICE_MSWINDOWS_HORZRES(d) = LOWORD (lParam); 2574 /* Do this only once per message. XEmacs can receive this message
2542 DEVICE_MSWINDOWS_VERTRES(d) = HIWORD (lParam); 2575 through as many frames as it currently has open. Message time
2543 DEVICE_MSWINDOWS_BITSPIXEL(d) = wParam; 2576 will be the same for all these messages. Despite extreme
2544 break; 2577 efficiency, the code below has about one in 4 billion
2578 probability that the HDC is not recreated, provided that
2579 XEmacs is running sufficiently longer than 52 days. */
2580 if (DEVICE_MSWINDOWS_UPDATE_TICK(d) != message_tick)
2581 {
2582 DEVICE_MSWINDOWS_UPDATE_TICK(d) = message_tick;
2583 DeleteDC (DEVICE_MSWINDOWS_HCDC(d));
2584 DEVICE_MSWINDOWS_HCDC(d) = CreateCompatibleDC (NULL);
2585 }
2545 } 2586 }
2587 break;
2546 2588
2547 /* Misc magic events which only require that the frame be identified */ 2589 /* Misc magic events which only require that the frame be identified */
2548 case WM_SETFOCUS: 2590 case WM_SETFOCUS:
2549 case WM_KILLFOCUS: 2591 case WM_KILLFOCUS:
2550 mswindows_enqueue_magic_event (hwnd, message); 2592 mswindows_enqueue_magic_event (hwnd, message_);
2551 break; 2593 break;
2552 2594
2553 case WM_WINDOWPOSCHANGING: 2595 case WM_WINDOWPOSCHANGING:
2554 { 2596 {
2555 WINDOWPOS *wp = (LPWINDOWPOS) lParam; 2597 WINDOWPOS *wp = (LPWINDOWPOS) lParam;
2694 #ifdef HAVE_MENUBARS 2736 #ifdef HAVE_MENUBARS
2695 if (!NILP (mswindows_handle_wm_command (frame, id))) 2737 if (!NILP (mswindows_handle_wm_command (frame, id)))
2696 break; 2738 break;
2697 #endif 2739 #endif
2698 2740
2699 return DefWindowProc (hwnd, message, wParam, lParam); 2741 return DefWindowProc (hwnd, message_, wParam, lParam);
2700 /* Bite me - a spurious command. This used to not be able to 2742 /* Bite me - a spurious command. This used to not be able to
2701 happen but with the introduction of widgets its now 2743 happen but with the introduction of widgets its now
2702 possible. */ 2744 possible. */
2703 } 2745 }
2704 break; 2746 break;
2794 * they just need to be good enough to keep dragdrop.el happy. */ 2836 * they just need to be good enough to keep dragdrop.el happy. */
2795 fname = (char *)xmalloc (len+1); 2837 fname = (char *)xmalloc (len+1);
2796 DragQueryFile ((HANDLE) wParam, i, fname, len+1); 2838 DragQueryFile ((HANDLE) wParam, i, fname, len+1);
2797 2839
2798 /* May be a shell link aka "shortcut" - replace fname if so */ 2840 /* May be a shell link aka "shortcut" - replace fname if so */
2799 #if !(defined(__CYGWIN32__) || defined(__MINGW32__)) 2841 #if !(defined(CYGWIN) || defined(MINGW))
2800 /* cygwin doesn't define this COM stuff */ 2842 /* cygwin doesn't define this COM stuff */
2801 if (!stricmp (fname + strlen (fname) - 4, ".LNK")) 2843 if (!stricmp (fname + strlen (fname) - 4, ".LNK"))
2802 { 2844 {
2803 IShellLink* psl; 2845 IShellLink* psl;
2804 2846
2831 psl->lpVtbl->Release (psl); 2873 psl->lpVtbl->Release (psl);
2832 } 2874 }
2833 } 2875 }
2834 #endif 2876 #endif
2835 2877
2836 #ifdef __CYGWIN32__ 2878 #ifdef CYGWIN
2837 filename = xmalloc (cygwin32_win32_to_posix_path_list_buf_size (fname) + 5); 2879 filename = xmalloc (cygwin32_win32_to_posix_path_list_buf_size (fname) + 5);
2838 strcpy (filename, "file:"); 2880 strcpy (filename, "file:");
2839 cygwin32_win32_to_posix_path_list (fname, filename+5); 2881 cygwin32_win32_to_posix_path_list (fname, filename+5);
2840 #else 2882 #else
2841 filename = (char *)xmalloc (len+6); 2883 filename = (char *)xmalloc (len+6);
2856 break; 2898 break;
2857 #endif 2899 #endif
2858 2900
2859 defproc: 2901 defproc:
2860 default: 2902 default:
2861 return DefWindowProc (hwnd, message, wParam, lParam); 2903 return DefWindowProc (hwnd, message_, wParam, lParam);
2862 } 2904 }
2863 return (0); 2905 return (0);
2864 } 2906 }
2865 2907
2866 2908