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, 2009, 2010 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 of the License, or
10 (at your option) any later version.
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. If not, see <http://www.gnu.org/licenses/>. */
29 #include "blockinput.h"
33 #define myalloc(cb) GlobalAllocPtr (GPTR, cb)
34 #define myfree(lp) GlobalFreePtr (lp)
36 CRITICAL_SECTION critsect
;
37 extern HANDLE keyboard_handle
;
38 HANDLE input_available
= NULL
;
39 HANDLE interrupt_handle
= NULL
;
44 InitializeCriticalSection (&critsect
);
46 /* For safety, input_available should only be reset by get_next_msg
47 when the input queue is empty, so make it a manual reset event. */
48 keyboard_handle
= input_available
= CreateEvent (NULL
, TRUE
, FALSE
, NULL
);
50 /* interrupt_handle is signaled when quit (C-g) is detected, so that
51 blocking system calls can be interrupted. We make it a manual
52 reset event, so that if we should ever have multiple threads
53 performing system calls, they will all be interrupted (I'm guessing
54 that would the right response). Note that we use PulseEvent to
55 signal this event, so that it never remains signaled. */
56 interrupt_handle
= CreateEvent (NULL
, TRUE
, FALSE
, NULL
);
62 DeleteCriticalSection (&critsect
);
66 CloseHandle (input_available
);
67 input_available
= NULL
;
71 CloseHandle (interrupt_handle
);
72 interrupt_handle
= NULL
;
79 /* Make sure this event never remains signaled; if the main thread
80 isn't in a blocking call, then this should do nothing. */
81 PulseEvent (interrupt_handle
);
85 select_palette (FRAME_PTR f
, HDC hdc
)
87 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
89 if (!display_info
->has_palette
)
92 if (display_info
->palette
== 0)
95 if (!NILP (Vw32_enable_palette
))
96 f
->output_data
.w32
->old_palette
=
97 SelectPalette (hdc
, display_info
->palette
, FALSE
);
99 f
->output_data
.w32
->old_palette
= NULL
;
101 if (RealizePalette (hdc
))
103 Lisp_Object frame
, framelist
;
104 FOR_EACH_FRAME (framelist
, frame
)
106 SET_FRAME_GARBAGED (XFRAME (frame
));
112 deselect_palette (FRAME_PTR f
, HDC hdc
)
114 if (f
->output_data
.w32
->old_palette
)
115 SelectPalette (hdc
, f
->output_data
.w32
->old_palette
, FALSE
);
118 /* Get a DC for frame and select palette for drawing; force an update of
119 all frames if palette's mapping changes. */
121 get_frame_dc (FRAME_PTR f
)
125 if (f
->output_method
!= output_w32
)
130 hdc
= GetDC (f
->output_data
.w32
->window_desc
);
132 /* If this gets called during startup before the frame is valid,
133 there is a chance of corrupting random data or crashing. */
135 select_palette (f
, hdc
);
141 release_frame_dc (FRAME_PTR f
, HDC hdc
)
145 deselect_palette (f
, hdc
);
146 ret
= ReleaseDC (f
->output_data
.w32
->window_desc
, hdc
);
153 typedef struct int_msg
156 struct int_msg
*lpNext
;
159 int_msg
*lpHead
= NULL
;
160 int_msg
*lpTail
= NULL
;
164 get_next_msg (W32Msg
* lpmsg
, BOOL bWait
)
170 /* The while loop takes care of multiple sets */
172 while (!nQueue
&& bWait
)
175 WaitForSingleObject (input_available
, INFINITE
);
181 memcpy (lpmsg
, &lpHead
->w32msg
, sizeof (W32Msg
));
184 int_msg
* lpCur
= lpHead
;
186 lpHead
= lpHead
->lpNext
;
192 /* Consolidate WM_PAINT messages to optimise redrawing. */
193 if (lpmsg
->msg
.message
== WM_PAINT
&& nQueue
)
195 int_msg
* lpCur
= lpHead
;
196 int_msg
* lpPrev
= NULL
;
197 int_msg
* lpNext
= NULL
;
199 while (lpCur
&& nQueue
)
201 lpNext
= lpCur
->lpNext
;
202 if (lpCur
->w32msg
.msg
.message
== WM_PAINT
)
204 /* Remove this message from the queue. */
206 lpPrev
->lpNext
= lpNext
;
213 /* Adjust clip rectangle to cover both. */
214 if (!UnionRect (&(lpmsg
->rect
), &(lpmsg
->rect
),
215 &(lpCur
->w32msg
.rect
)))
217 SetRectEmpty (&(lpmsg
->rect
));
238 ResetEvent (input_available
);
246 post_msg (W32Msg
* lpmsg
)
248 int_msg
* lpNew
= (int_msg
*) myalloc (sizeof (int_msg
));
253 memcpy (&lpNew
->w32msg
, lpmsg
, sizeof (W32Msg
));
254 lpNew
->lpNext
= NULL
;
260 lpTail
->lpNext
= lpNew
;
268 SetEvent (input_available
);
276 prepend_msg (W32Msg
*lpmsg
)
278 int_msg
* lpNew
= (int_msg
*) myalloc (sizeof (int_msg
));
283 memcpy (&lpNew
->w32msg
, lpmsg
, sizeof (W32Msg
));
288 lpNew
->lpNext
= lpHead
;
296 /* Process all messages in the current thread's queue. */
298 drain_message_queue (void)
301 while (PeekMessage (&msg
, NULL
, 0, 0, PM_REMOVE
))
303 TranslateMessage (&msg
);
304 DispatchMessage (&msg
);
310 * XParseGeometry parses strings of the form
311 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
312 * width, height, xoffset, and yoffset are unsigned integers.
313 * Example: "=80x24+300-49"
314 * The equal sign is optional.
315 * It returns a bitmask that indicates which of the four values
316 * were actually found in the string. For each value found,
317 * the corresponding argument is updated; for each value
318 * not found, the corresponding argument is left unchanged.
322 read_integer (register char *string
, char **NextString
)
324 register int Result
= 0;
329 else if (*string
== '-')
334 for (; (*string
>= '0') && (*string
<= '9'); string
++)
336 Result
= (Result
* 10) + (*string
- '0');
338 *NextString
= string
;
346 XParseGeometry (char *string
,
348 unsigned int *width
, unsigned int *height
)
351 register char *strind
;
352 unsigned int tempWidth
, tempHeight
;
356 if ((string
== NULL
) || (*string
== '\0')) return (mask
);
358 string
++; /* ignore possible '=' at beg of geometry spec */
360 strind
= (char *)string
;
361 if (*strind
!= '+' && *strind
!= '-' && *strind
!= 'x')
363 tempWidth
= read_integer (strind
, &nextCharacter
);
364 if (strind
== nextCharacter
)
366 strind
= nextCharacter
;
370 if (*strind
== 'x' || *strind
== 'X')
373 tempHeight
= read_integer (strind
, &nextCharacter
);
374 if (strind
== nextCharacter
)
376 strind
= nextCharacter
;
380 if ((*strind
== '+') || (*strind
== '-'))
385 tempX
= -read_integer (strind
, &nextCharacter
);
386 if (strind
== nextCharacter
)
388 strind
= nextCharacter
;
395 tempX
= read_integer (strind
, &nextCharacter
);
396 if (strind
== nextCharacter
)
398 strind
= nextCharacter
;
401 if ((*strind
== '+') || (*strind
== '-'))
406 tempY
= -read_integer (strind
, &nextCharacter
);
407 if (strind
== nextCharacter
)
409 strind
= nextCharacter
;
415 tempY
= read_integer (strind
, &nextCharacter
);
416 if (strind
== nextCharacter
)
418 strind
= nextCharacter
;
424 /* If strind isn't at the end of the string then it's an invalid
425 geometry specification. */
427 if (*strind
!= '\0') return (0);
433 if (mask
& WidthValue
)
435 if (mask
& HeightValue
)
436 *height
= tempHeight
;
440 /* x_sync is a no-op on W32. */
446 /* arch-tag: 4fab3695-4ad3-4cc6-a2b1-fd2c67dc46be
447 (do not change this comment) */