-/* Functions taken directly from X sources
- Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation.
+/* Functions taken directly from X sources for use with the Microsoft W32 API.
+ Copyright (C) 1989, 1992, 1993, 1994, 1995, 1999, 2002, 2003, 2004,
+ 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Emacs.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
-#include <signal.h>
#include <config.h>
+#include <signal.h>
#include <stdio.h>
#include "lisp.h"
+#include "keyboard.h"
+#include "frame.h"
+#include "charset.h"
+#include "fontset.h"
#include "blockinput.h"
#include "w32term.h"
#include "windowsx.h"
CRITICAL_SECTION critsect;
extern HANDLE keyboard_handle;
-HANDLE hEvent = NULL;
+HANDLE input_available = NULL;
+HANDLE interrupt_handle = NULL;
-void
+void
init_crit ()
{
InitializeCriticalSection (&critsect);
- keyboard_handle = hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
+
+ /* For safety, input_available should only be reset by get_next_msg
+ when the input queue is empty, so make it a manual reset event. */
+ keyboard_handle = input_available = CreateEvent (NULL, TRUE, FALSE, NULL);
+
+ /* interrupt_handle is signalled when quit (C-g) is detected, so that
+ blocking system calls can be interrupted. We make it a manual
+ reset event, so that if we should ever have multiple threads
+ performing system calls, they will all be interrupted (I'm guessing
+ that would the right response). Note that we use PulseEvent to
+ signal this event, so that it never remains signalled. */
+ interrupt_handle = CreateEvent (NULL, TRUE, FALSE, NULL);
}
-void
-enter_crit ()
+void
+delete_crit ()
{
- EnterCriticalSection (&critsect);
+ DeleteCriticalSection (&critsect);
+
+ if (input_available)
+ {
+ CloseHandle (input_available);
+ input_available = NULL;
+ }
+ if (interrupt_handle)
+ {
+ CloseHandle (interrupt_handle);
+ interrupt_handle = NULL;
+ }
}
-void
-leave_crit ()
+void
+signal_quit ()
{
- LeaveCriticalSection (&critsect);
+ /* Make sure this event never remains signalled; if the main thread
+ isn't in a blocking call, then this should do nothing. */
+ PulseEvent (interrupt_handle);
}
-void
-delete_crit ()
+void
+select_palette (FRAME_PTR f, HDC hdc)
{
- DeleteCriticalSection (&critsect);
- if (hEvent)
+ struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f);
+
+ if (!display_info->has_palette)
+ return;
+
+ if (display_info->palette == 0)
+ return;
+
+ if (!NILP (Vw32_enable_palette))
+ f->output_data.w32->old_palette =
+ SelectPalette (hdc, display_info->palette, FALSE);
+ else
+ f->output_data.w32->old_palette = NULL;
+
+ if (RealizePalette (hdc))
+ {
+ Lisp_Object frame, framelist;
+ FOR_EACH_FRAME (framelist, frame)
{
- CloseHandle (hEvent);
- hEvent = NULL;
+ SET_FRAME_GARBAGED (XFRAME (frame));
}
+ }
+}
+
+void
+deselect_palette (FRAME_PTR f, HDC hdc)
+{
+ if (f->output_data.w32->old_palette)
+ SelectPalette (hdc, f->output_data.w32->old_palette, FALSE);
+}
+
+/* Get a DC for frame and select palette for drawing; force an update of
+ all frames if palette's mapping changes. */
+HDC
+get_frame_dc (FRAME_PTR f)
+{
+ HDC hdc;
+
+ if (f->output_method != output_w32)
+ abort ();
+
+ enter_crit ();
+
+ hdc = GetDC (f->output_data.w32->window_desc);
+
+ /* If this gets called during startup before the frame is valid,
+ there is a chance of corrupting random data or crashing. */
+ if (hdc)
+ select_palette (f, hdc);
+
+ return hdc;
+}
+
+int
+release_frame_dc (FRAME_PTR f, HDC hdc)
+{
+ int ret;
+
+ deselect_palette (f, hdc);
+ ret = ReleaseDC (f->output_data.w32->window_desc, hdc);
+
+ leave_crit ();
+
+ return ret;
}
typedef struct int_msg
{
- Win32Msg w32msg;
+ W32Msg w32msg;
struct int_msg *lpNext;
} int_msg;
int_msg *lpTail = NULL;
int nQueue = 0;
-BOOL
+BOOL
get_next_msg (lpmsg, bWait)
- Win32Msg * lpmsg;
+ W32Msg * lpmsg;
BOOL bWait;
{
BOOL bRet = FALSE;
-
+
enter_crit ();
-
+
/* The while loop takes care of multiple sets */
-
+
while (!nQueue && bWait)
{
leave_crit ();
- WaitForSingleObject (hEvent, INFINITE);
+ WaitForSingleObject (input_available, INFINITE);
enter_crit ();
}
-
+
if (nQueue)
{
- bcopy (&(lpHead->w32msg), lpmsg, sizeof (Win32Msg));
+ bcopy (&(lpHead->w32msg), lpmsg, sizeof (W32Msg));
{
int_msg * lpCur = lpHead;
-
+
lpHead = lpHead->lpNext;
-
+
myfree (lpCur);
}
bRet = TRUE;
}
-
+
+ if (nQueue == 0)
+ ResetEvent (input_available);
+
leave_crit ();
-
+
return (bRet);
}
-BOOL
+BOOL
post_msg (lpmsg)
- Win32Msg * lpmsg;
+ W32Msg * lpmsg;
{
int_msg * lpNew = (int_msg *) myalloc (sizeof (int_msg));
- if (!lpNew) return (FALSE);
+ if (!lpNew)
+ return (FALSE);
- bcopy (lpmsg, &(lpNew->w32msg), sizeof (Win32Msg));
+ bcopy (lpmsg, &(lpNew->w32msg), sizeof (W32Msg));
lpNew->lpNext = NULL;
enter_crit ();
{
lpTail->lpNext = lpNew;
}
- else
+ else
{
lpHead = lpNew;
- SetEvent (hEvent);
}
lpTail = lpNew;
-
+ SetEvent (input_available);
+
+ leave_crit ();
+
+ return (TRUE);
+}
+
+BOOL
+prepend_msg (W32Msg *lpmsg)
+{
+ int_msg * lpNew = (int_msg *) myalloc (sizeof (int_msg));
+
+ if (!lpNew)
+ return (FALSE);
+
+ bcopy (lpmsg, &(lpNew->w32msg), sizeof (W32Msg));
+
+ enter_crit ();
+
+ nQueue++;
+ lpNew->lpNext = lpHead;
+ lpHead = lpNew;
+
leave_crit ();
return (TRUE);
}
+/* Process all messages in the current thread's queue. */
+void
+drain_message_queue ()
+{
+ MSG msg;
+ while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage (&msg);
+ DispatchMessage (&msg);
+ }
+}
+
+
/*
* XParseGeometry parses strings of the form
* "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
* It returns a bitmask that indicates which of the four values
* were actually found in the string. For each value found,
* the corresponding argument is updated; for each value
- * not found, the corresponding argument is left unchanged.
+ * not found, the corresponding argument is left unchanged.
*/
static int
{
register int Result = 0;
int Sign = 1;
-
+
if (*string == '+')
string++;
else if (*string == '-')
return (-Result);
}
-int
+int
XParseGeometry (string, x, y, width, height)
char *string;
int *x, *y;
unsigned int tempWidth, tempHeight;
int tempX, tempY;
char *nextCharacter;
-
+
if ((string == NULL) || (*string == '\0')) return (mask);
if (*string == '=')
string++; /* ignore possible '=' at beg of geometry spec */
-
+
strind = (char *)string;
- if (*strind != '+' && *strind != '-' && *strind != 'x')
+ if (*strind != '+' && *strind != '-' && *strind != 'x')
{
tempWidth = read_integer (strind, &nextCharacter);
- if (strind == nextCharacter)
+ if (strind == nextCharacter)
return (0);
strind = nextCharacter;
mask |= WidthValue;
}
-
- if (*strind == 'x' || *strind == 'X')
- {
+
+ if (*strind == 'x' || *strind == 'X')
+ {
strind++;
tempHeight = read_integer (strind, &nextCharacter);
if (strind == nextCharacter)
strind = nextCharacter;
mask |= HeightValue;
}
-
- if ((*strind == '+') || (*strind == '-'))
+
+ if ((*strind == '+') || (*strind == '-'))
{
- if (*strind == '-')
+ if (*strind == '-')
{
strind++;
tempX = -read_integer (strind, &nextCharacter);
}
else
- {
+ {
strind++;
tempX = read_integer (strind, &nextCharacter);
if (strind == nextCharacter)
strind = nextCharacter;
}
mask |= XValue;
- if ((*strind == '+') || (*strind == '-'))
+ if ((*strind == '+') || (*strind == '-'))
{
- if (*strind == '-')
+ if (*strind == '-')
{
strind++;
tempY = -read_integer (strind, &nextCharacter);
mask |= YValue;
}
}
-
+
/* If strind isn't at the end of the string the it's an invalid
geometry specification. */
-
+
if (*strind != '\0') return (0);
-
+
if (mask & XValue)
*x = tempX;
if (mask & YValue)
return (mask);
}
-/* We can use mouse menus when we wish. */
-int
-have_menus_p (void)
-{
- return 1;
-}
-
-/* x_sync is a no-op on Win32. */
+/* x_sync is a no-op on W32. */
void
x_sync (f)
void *f;
{
}
+/* arch-tag: 4fab3695-4ad3-4cc6-a2b1-fd2c67dc46be
+ (do not change this comment) */