X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/82e7c0a907a11f84d9eaf9750266db104974e9ab..40aeecadb8fc54c941eb36c6584654627c300c39:/src/w32proc.c diff --git a/src/w32proc.c b/src/w32proc.c index 81cdcbf93b..21bdebbbec 100644 --- a/src/w32proc.c +++ b/src/w32proc.c @@ -1,5 +1,5 @@ /* Process support for GNU Emacs on the Microsoft W32 API. - Copyright (C) 1992, 1995 Free Software Foundation, Inc. + Copyright (C) 1992, 1995, 1999 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -91,10 +91,6 @@ Lisp_Object Vw32_get_true_file_attributes; Lisp_Object Qhigh, Qlow; -#ifndef SYS_SIGLIST_DECLARED -extern char *sys_siglist[]; -#endif - #ifdef EMACSDEBUG void _DebPrint (const char *fmt, ...) { @@ -546,13 +542,11 @@ get_result: else if (WIFSIGNALED (retval)) { int code = WTERMSIG (retval); - char *signame = 0; - - if (code < NSIG) - { - /* Suppress warning if the table has const char *. */ - signame = (char *) sys_siglist[code]; - } + char *signame; + + synchronize_system_messages_locale (); + signame = strsignal (code); + if (signame == 0) signame = "unknown"; @@ -639,7 +633,10 @@ w32_executable_type (char * filename, int * is_dos_app, int * is_cygnus_app) { char * dllname = RVA_TO_PTR (imports->Name, section, executable); - if (strcmp (dllname, "cygwin.dll") == 0) + /* The exact name of the cygwin dll has changed with + various releases, but hopefully this will be reasonably + future proof. */ + if (strncmp (dllname, "cygwin", 6) == 0) { *is_cygnus_app = TRUE; break; @@ -1172,9 +1169,15 @@ count_children: return 0; } - /* Wait for input or child death to be signalled. */ start_time = GetTickCount (); - active = WaitForMultipleObjects (nh + nc, wait_hnd, FALSE, timeout_ms); + + /* Wait for input or child death to be signalled. If user input is + allowed, then also accept window messages. */ + if (FD_ISSET (0, &orfds)) + active = MsgWaitForMultipleObjects (nh + nc, wait_hnd, FALSE, timeout_ms, + QS_ALLINPUT); + else + active = WaitForMultipleObjects (nh + nc, wait_hnd, FALSE, timeout_ms); if (active == WAIT_FAILED) { @@ -1210,7 +1213,26 @@ count_children: processed - otherwise higher numbered channels could be starved. */ do { - if (active >= nh) + if (active == nh + nc) + { + /* There are messages in the lisp thread's queue; we must + drain the queue now to ensure they are processed promptly, + because if we don't do so, we will not be woken again until + further messages arrive. + + NB. If ever we allow window message procedures to callback + into lisp, we will need to ensure messages are dispatched + at a safe time for lisp code to be run (*), and we may also + want to provide some hooks in the dispatch loop to cater + for modeless dialogs created by lisp (ie. to register + window handles to pass to IsDialogMessage). + + (*) Note that MsgWaitForMultipleObjects above is an + internal dispatch point for messages that are sent to + windows created by this thread. */ + drain_message_queue (); + } + else if (active >= nh) { cp = cps[active - nh]; @@ -1356,25 +1378,58 @@ sys_kill (int pid, int sig) } foreground_window = GetForegroundWindow (); - if (foreground_window && SetForegroundWindow (cp->hwnd)) + if (foreground_window) { - /* Generate keystrokes as if user had typed Ctrl-Break or - Ctrl-C. */ - keybd_event (VK_CONTROL, control_scan_code, 0, 0); - keybd_event (vk_break_code, break_scan_code, - (vk_break_code == 'C' ? 0 : KEYEVENTF_EXTENDEDKEY), 0); - keybd_event (vk_break_code, break_scan_code, - (vk_break_code == 'C' ? 0 : KEYEVENTF_EXTENDEDKEY) - | KEYEVENTF_KEYUP, 0); - keybd_event (VK_CONTROL, control_scan_code, KEYEVENTF_KEYUP, 0); - - /* Sleep for a bit to give time for Emacs frame to respond - to focus change events (if Emacs was active app). */ - Sleep (10); - - SetForegroundWindow (foreground_window); - } - } + /* NT 5.0, and apparently also Windows 98, will not allow + a Window to be set to foreground directly without the + user's involvement. The workaround is to attach + ourselves to the thread that owns the foreground + window, since that is the only thread that can set the + foreground window. */ + DWORD foreground_thread, child_thread; + foreground_thread = + GetWindowThreadProcessId (foreground_window, NULL); + if (foreground_thread == GetCurrentThreadId () + || !AttachThreadInput (GetCurrentThreadId (), + foreground_thread, TRUE)) + foreground_thread = 0; + + child_thread = GetWindowThreadProcessId (cp->hwnd, NULL); + if (child_thread == GetCurrentThreadId () + || !AttachThreadInput (GetCurrentThreadId (), + child_thread, TRUE)) + child_thread = 0; + + /* Set the foreground window to the child. */ + if (SetForegroundWindow (cp->hwnd)) + { + /* Generate keystrokes as if user had typed Ctrl-Break or + Ctrl-C. */ + keybd_event (VK_CONTROL, control_scan_code, 0, 0); + keybd_event (vk_break_code, break_scan_code, + (vk_break_code == 'C' ? 0 : KEYEVENTF_EXTENDEDKEY), 0); + keybd_event (vk_break_code, break_scan_code, + (vk_break_code == 'C' ? 0 : KEYEVENTF_EXTENDEDKEY) + | KEYEVENTF_KEYUP, 0); + keybd_event (VK_CONTROL, control_scan_code, + KEYEVENTF_KEYUP, 0); + + /* Sleep for a bit to give time for Emacs frame to respond + to focus change events (if Emacs was active app). */ + Sleep (100); + + SetForegroundWindow (foreground_window); + } + /* Detach from the foreground and child threads now that + the foreground switching is over. */ + if (foreground_thread) + AttachThreadInput (GetCurrentThreadId (), + foreground_thread, FALSE); + if (child_thread) + AttachThreadInput (GetCurrentThreadId (), + child_thread, FALSE); + } + } /* Ctrl-Break is NT equivalent of SIGINT. */ else if (!GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, pid)) { @@ -2007,11 +2062,11 @@ If successful, the new layout id is returned, otherwise nil.") DWORD kl; CHECK_CONS (layout, 0); - CHECK_NUMBER (XCONS (layout)->car, 0); - CHECK_NUMBER (XCONS (layout)->cdr, 0); + CHECK_NUMBER (XCAR (layout), 0); + CHECK_NUMBER (XCDR (layout), 0); - kl = (XINT (XCONS (layout)->car) & 0xffff) - | (XINT (XCONS (layout)->cdr) << 16); + kl = (XINT (XCAR (layout)) & 0xffff) + | (XINT (XCDR (layout)) << 16); /* Synchronize layout with input thread. */ if (dwWindowsThreadId)