/* Console functions for mswindows.
- Copyright (C) 1996 Ben Wing.
+ Copyright (C) 1996, 2000 Ben Wing.
This file is part of XEmacs.
#include <config.h>
#include "lisp.h"
+#include "events.h"
+#include "opaque.h"
#include "console-msw.h"
-
DEFINE_CONSOLE_TYPE (mswindows);
+DEFINE_CONSOLE_TYPE (msprinter);
+/************************************************************************/
+/* mswindows console methods */
+/************************************************************************/
static int
mswindows_initially_selected_for_input (struct console *con)
return 1;
}
+static HWND msw_console_hwnd = 0;
+#define KLUDGE_BUFSIZE 1024 /* buffer size for console window titles */
-\f
-/************************************************************************/
-/* initialization */
-/************************************************************************/
+/* Direct from the horse's mouth: Microsoft KB article Q124103 */
+static HWND
+GetConsoleHwnd (void)
+{
+ HWND hwndFound; /* this is what is returned to the caller */
+ char pszNewWindowTitle[KLUDGE_BUFSIZE]; /* contains fabricated WindowTitle */
+ char pszOldWindowTitle[KLUDGE_BUFSIZE]; /* contains original WindowTitle */
-void
-syms_of_console_mswindows (void)
+ /* fetch current window title */
+
+ GetConsoleTitle(pszOldWindowTitle, KLUDGE_BUFSIZE);
+
+ /* format a "unique" NewWindowTitle */
+
+ wsprintf(pszNewWindowTitle,"%d/%d",
+ GetTickCount(),
+ GetCurrentProcessId());
+
+ /* change current window title */
+
+ SetConsoleTitle(pszNewWindowTitle);
+
+ /* ensure window title has been updated */
+
+ Sleep(40);
+
+ /* look for NewWindowTitle */
+
+ hwndFound=FindWindow(NULL, pszNewWindowTitle);
+
+ /* restore original window title */
+
+ SetConsoleTitle(pszOldWindowTitle);
+
+ return(hwndFound);
+}
+
+HWND
+msw_get_console_hwnd (void)
{
+ if (!msw_console_hwnd)
+ msw_console_hwnd = GetConsoleHwnd ();
+ return msw_console_hwnd;
}
-void
-console_type_create_mswindows (void)
+int
+msw_ensure_console_allocated (void)
{
- INITIALIZE_CONSOLE_TYPE (mswindows, "mswindows", "console-mswindows-p");
+ HWND fgwin = GetForegroundWindow ();
+ /* stupid mswin api won't let you create the console window
+ hidden! creating it changes the focus! fuck me! */
+ if (AllocConsole ())
+ {
+ SetForegroundWindow (fgwin);
+ return 1;
+ }
+ return 0;
+}
- /* console methods */
-/* CONSOLE_HAS_METHOD (mswindows, init_console); */
-/* CONSOLE_HAS_METHOD (mswindows, mark_console); */
- CONSOLE_HAS_METHOD (mswindows, initially_selected_for_input);
-/* CONSOLE_HAS_METHOD (mswindows, delete_console); */
-/* CONSOLE_HAS_METHOD (mswindows, canonicalize_console_connection); */
-/* CONSOLE_HAS_METHOD (mswindows, canonicalize_device_connection); */
-/* CONSOLE_HAS_METHOD (mswindows, semi_canonicalize_console_connection); */
-/* CONSOLE_HAS_METHOD (mswindows, semi_canonicalize_device_connection); */
+static Lisp_Object
+mswindows_canonicalize_console_connection (Lisp_Object connection,
+ Error_behavior errb)
+{
+ /* Do not allow more than one mswindows device, by explicitly
+ requiring that CONNECTION is nil, the only allowed connection in
+ Windows. */
+ if (!NILP (connection))
+ {
+ if (ERRB_EQ (errb, ERROR_ME))
+ signal_simple_error
+ ("Invalid (non-nil) connection for mswindows device/console",
+ connection);
+ else
+ return Qunbound;
+ }
+
+ return Qnil;
+}
+
+static Lisp_Object
+mswindows_canonicalize_device_connection (Lisp_Object connection,
+ Error_behavior errb)
+{
+ return mswindows_canonicalize_console_connection (connection, errb);
}
void
-reinit_console_type_create_mswindows (void)
+msw_hide_console (void)
{
- REINITIALIZE_CONSOLE_TYPE (mswindows);
+ ShowWindow (msw_get_console_hwnd (), SW_HIDE);
}
void
-vars_of_console_mswindows (void)
+msw_show_console (void)
{
- Fprovide (Qmswindows);
+ HWND hwnd = msw_get_console_hwnd ();
+ ShowWindow (hwnd, SW_SHOWNA);
+
+ /* I tried to raise the window to the top without activating
+ it, but this fails. Apparently Windows just doesn't like
+ having the active window not be on top. So instead, we
+ at least put it just below our own window, where part of it
+ will likely be seen. */
+ SetWindowPos (hwnd, GetForegroundWindow (), 0, 0, 0, 0,
+ SWP_NOSIZE | SWP_NOMOVE | SWP_NOSENDCHANGING |
+ SWP_NOACTIVATE);
+}
+
+static int msw_console_buffered = 0;
+HANDLE msw_console_buffer;
+
+static void
+msw_ensure_console_buffered (void)
+{
+ if (!msw_console_buffered)
+ {
+ COORD new_size;
+
+ new_size.X = 80;
+ new_size.Y = 1000;
+ msw_ensure_console_allocated ();
+ msw_console_buffer =
+ CreateConsoleScreenBuffer (GENERIC_WRITE, 0, NULL,
+ CONSOLE_TEXTMODE_BUFFER, NULL);
+ SetConsoleScreenBufferSize (msw_console_buffer, new_size);
+ SetConsoleActiveScreenBuffer (msw_console_buffer);
+ msw_console_buffered = 1;
+ }
+}
+
+int
+msw_output_console_string (CONST Extbyte *str, Extcount len)
+{
+ DWORD num_written;
+
+ msw_ensure_console_buffered ();
+ msw_show_console ();
+ return WriteConsole (msw_console_buffer, str, len, &num_written, NULL);
+}
+
+/* Determine if running on Windows 9x and not NT */
+int
+msw_windows9x_p (void)
+{
+ return GetVersion () & 0x80000000;
}
#ifdef DEBUG_XEMACS
-#include "events.h"
-#include "opaque.h"
+
/*
* Random helper functions for debugging.
* Intended for use in the MSVC "Watch" window which doesn't like
return OPAQUEP (obj) ? OPAQUE_DATA (XOPAQUE (obj)) : NULL;
}
-struct Lisp_Event *
+Lisp_Event *
DEVENT (Lisp_Object obj)
{
return EVENTP (obj) ? XEVENT (obj) : NULL;
}
-struct Lisp_Cons *
+Lisp_Cons *
DCONS (Lisp_Object obj)
{
return CONSP (obj) ? XCONS (obj) : NULL;
}
-struct Lisp_Cons *
+Lisp_Cons *
DCONSCDR (Lisp_Object obj)
{
return (CONSP (obj) && CONSP (XCDR (obj))) ? XCONS (XCDR (obj)) : 0;
return STRINGP (obj) ? XSTRING_DATA (obj) : NULL;
}
-struct Lisp_Vector *
+Lisp_Vector *
DVECTOR (Lisp_Object obj)
{
return VECTORP (obj) ? XVECTOR (obj) : NULL;
}
-struct Lisp_Symbol *
+Lisp_Symbol *
DSYMBOL (Lisp_Object obj)
{
return SYMBOLP (obj) ? XSYMBOL (obj) : NULL;
return SYMBOLP (obj) ? string_data (XSYMBOL (obj)->name) : NULL;
}
-#endif
+#endif /* DEBUG_XEMACS */
+
+
+\f
+/************************************************************************/
+/* initialization */
+/************************************************************************/
+
+void
+syms_of_console_mswindows (void)
+{
+}
+
+void
+console_type_create_mswindows (void)
+{
+ INITIALIZE_CONSOLE_TYPE (mswindows, "mswindows", "console-mswindows-p");
+
+ /* console methods */
+/* CONSOLE_HAS_METHOD (mswindows, init_console); */
+/* CONSOLE_HAS_METHOD (mswindows, mark_console); */
+ CONSOLE_HAS_METHOD (mswindows, initially_selected_for_input);
+/* CONSOLE_HAS_METHOD (mswindows, delete_console); */
+ CONSOLE_HAS_METHOD (mswindows, canonicalize_console_connection);
+ CONSOLE_HAS_METHOD (mswindows, canonicalize_device_connection);
+/* CONSOLE_HAS_METHOD (mswindows, semi_canonicalize_console_connection); */
+/* CONSOLE_HAS_METHOD (mswindows, semi_canonicalize_device_connection); */
+
+ INITIALIZE_CONSOLE_TYPE (msprinter, "msprinter", "console-msprinter-p");
+}
+
+void
+reinit_console_type_create_mswindows (void)
+{
+ REINITIALIZE_CONSOLE_TYPE (mswindows);
+ REINITIALIZE_CONSOLE_TYPE (msprinter);
+}
+
+void
+vars_of_console_mswindows (void)
+{
+ Fprovide (Qmswindows);
+}