1 /* Functions taken directly from X sources for use with the Microsoft W32 API.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1999, 2001, 2002, 2003,
3 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
30 #include "blockinput.h"
34 #define myalloc(cb) GlobalAllocPtr (GPTR, cb)
35 #define myfree(lp) GlobalFreePtr (lp)
37 CRITICAL_SECTION critsect
;
38 extern HANDLE keyboard_handle
;
39 HANDLE input_available
= NULL
;
40 HANDLE interrupt_handle
= NULL
;
45 InitializeCriticalSection (&critsect
);
47 /* For safety, input_available should only be reset by get_next_msg
48 when the input queue is empty, so make it a manual reset event. */
49 keyboard_handle
= input_available
= CreateEvent (NULL
, TRUE
, FALSE
, NULL
);
51 /* interrupt_handle is signalled when quit (C-g) is detected, so that
52 blocking system calls can be interrupted. We make it a manual
53 reset event, so that if we should ever have multiple threads
54 performing system calls, they will all be interrupted (I'm guessing
55 that would the right response). Note that we use PulseEvent to
56 signal this event, so that it never remains signalled. */
57 interrupt_handle
= CreateEvent (NULL
, TRUE
, FALSE
, NULL
);
63 DeleteCriticalSection (&critsect
);
67 CloseHandle (input_available
);
68 input_available
= NULL
;
72 CloseHandle (interrupt_handle
);
73 interrupt_handle
= NULL
;
80 /* Make sure this event never remains signalled; if the main thread
81 isn't in a blocking call, then this should do nothing. */
82 PulseEvent (interrupt_handle
);
86 select_palette (FRAME_PTR f
, HDC hdc
)
88 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
90 if (!display_info
->has_palette
)
93 if (display_info
->palette
== 0)
96 if (!NILP (Vw32_enable_palette
))
97 f
->output_data
.w32
->old_palette
=
98 SelectPalette (hdc
, display_info
->palette
, FALSE
);
100 f
->output_data
.w32
->old_palette
= NULL
;
102 if (RealizePalette (hdc
))
104 Lisp_Object frame
, framelist
;
105 FOR_EACH_FRAME (framelist
, frame
)
107 SET_FRAME_GARBAGED (XFRAME (frame
));
113 deselect_palette (FRAME_PTR f
, HDC hdc
)
115 if (f
->output_data
.w32
->old_palette
)
116 SelectPalette (hdc
, f
->output_data
.w32
->old_palette
, FALSE
);
119 /* Get a DC for frame and select palette for drawing; force an update of
120 all frames if palette's mapping changes. */
122 get_frame_dc (FRAME_PTR f
)
126 if (f
->output_method
!= output_w32
)
131 hdc
= GetDC (f
->output_data
.w32
->window_desc
);
133 /* If this gets called during startup before the frame is valid,
134 there is a chance of corrupting random data or crashing. */
136 select_palette (f
, hdc
);
142 release_frame_dc (FRAME_PTR f
, HDC hdc
)
146 deselect_palette (f
, hdc
);
147 ret
= ReleaseDC (f
->output_data
.w32
->window_desc
, hdc
);
154 typedef struct int_msg
157 struct int_msg
*lpNext
;
160 int_msg
*lpHead
= NULL
;
161 int_msg
*lpTail
= NULL
;
165 get_next_msg (lpmsg
, bWait
)
173 /* The while loop takes care of multiple sets */
175 while (!nQueue
&& bWait
)
178 WaitForSingleObject (input_available
, INFINITE
);
184 bcopy (&(lpHead
->w32msg
), lpmsg
, sizeof (W32Msg
));
187 int_msg
* lpCur
= lpHead
;
189 lpHead
= lpHead
->lpNext
;
195 /* Consolidate WM_PAINT messages to optimise redrawing. */
196 if (lpmsg
->msg
.message
== WM_PAINT
&& nQueue
)
198 int_msg
* lpCur
= lpHead
;
199 int_msg
* lpPrev
= NULL
;
200 int_msg
* lpNext
= NULL
;
202 while (lpCur
&& nQueue
)
204 lpNext
= lpCur
->lpNext
;
205 if (lpCur
->w32msg
.msg
.message
== WM_PAINT
)
207 /* Remove this message from the queue. */
209 lpPrev
->lpNext
= lpNext
;
216 /* Adjust clip rectangle to cover both. */
217 if (!UnionRect (&(lpmsg
->rect
), &(lpmsg
->rect
),
218 &(lpCur
->w32msg
.rect
)))
220 SetRectEmpty(&(lpmsg
->rect
));
241 ResetEvent (input_available
);
252 int_msg
* lpNew
= (int_msg
*) myalloc (sizeof (int_msg
));
257 bcopy (lpmsg
, &(lpNew
->w32msg
), sizeof (W32Msg
));
258 lpNew
->lpNext
= NULL
;
264 lpTail
->lpNext
= lpNew
;
272 SetEvent (input_available
);
280 prepend_msg (W32Msg
*lpmsg
)
282 int_msg
* lpNew
= (int_msg
*) myalloc (sizeof (int_msg
));
287 bcopy (lpmsg
, &(lpNew
->w32msg
), sizeof (W32Msg
));
292 lpNew
->lpNext
= lpHead
;
300 /* Process all messages in the current thread's queue. */
302 drain_message_queue ()
305 while (PeekMessage (&msg
, NULL
, 0, 0, PM_REMOVE
))
307 TranslateMessage (&msg
);
308 DispatchMessage (&msg
);
314 * XParseGeometry parses strings of the form
315 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
316 * width, height, xoffset, and yoffset are unsigned integers.
317 * Example: "=80x24+300-49"
318 * The equal sign is optional.
319 * It returns a bitmask that indicates which of the four values
320 * were actually found in the string. For each value found,
321 * the corresponding argument is updated; for each value
322 * not found, the corresponding argument is left unchanged.
326 read_integer (string
, NextString
)
327 register char *string
;
330 register int Result
= 0;
335 else if (*string
== '-')
340 for (; (*string
>= '0') && (*string
<= '9'); string
++)
342 Result
= (Result
* 10) + (*string
- '0');
344 *NextString
= string
;
352 XParseGeometry (string
, x
, y
, width
, height
)
355 unsigned int *width
, *height
; /* RETURN */
358 register char *strind
;
359 unsigned int tempWidth
, tempHeight
;
363 if ((string
== NULL
) || (*string
== '\0')) return (mask
);
365 string
++; /* ignore possible '=' at beg of geometry spec */
367 strind
= (char *)string
;
368 if (*strind
!= '+' && *strind
!= '-' && *strind
!= 'x')
370 tempWidth
= read_integer (strind
, &nextCharacter
);
371 if (strind
== nextCharacter
)
373 strind
= nextCharacter
;
377 if (*strind
== 'x' || *strind
== 'X')
380 tempHeight
= read_integer (strind
, &nextCharacter
);
381 if (strind
== nextCharacter
)
383 strind
= nextCharacter
;
387 if ((*strind
== '+') || (*strind
== '-'))
392 tempX
= -read_integer (strind
, &nextCharacter
);
393 if (strind
== nextCharacter
)
395 strind
= nextCharacter
;
402 tempX
= read_integer (strind
, &nextCharacter
);
403 if (strind
== nextCharacter
)
405 strind
= nextCharacter
;
408 if ((*strind
== '+') || (*strind
== '-'))
413 tempY
= -read_integer (strind
, &nextCharacter
);
414 if (strind
== nextCharacter
)
416 strind
= nextCharacter
;
423 tempY
= read_integer (strind
, &nextCharacter
);
424 if (strind
== nextCharacter
)
426 strind
= nextCharacter
;
432 /* If strind isn't at the end of the string the it's an invalid
433 geometry specification. */
435 if (*strind
!= '\0') return (0);
441 if (mask
& WidthValue
)
443 if (mask
& HeightValue
)
444 *height
= tempHeight
;
448 /* x_sync is a no-op on W32. */
455 /* arch-tag: 4fab3695-4ad3-4cc6-a2b1-fd2c67dc46be
456 (do not change this comment) */