/* 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.
Lisp_Object Qhigh, Qlow;
-#ifndef SYS_SIGLIST_DECLARED
-extern char *sys_siglist[];
-#endif
-
#ifdef EMACSDEBUG
void _DebPrint (const char *fmt, ...)
{
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";
{
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;
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)
{
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];
}
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))
{
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)