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 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/>. */
28 #include "blockinput.h"
32 #define myalloc(cb) GlobalAllocPtr (GPTR, cb)
33 #define myfree(lp) GlobalFreePtr (lp)
35 CRITICAL_SECTION critsect
;
36 extern HANDLE keyboard_handle
;
37 HANDLE input_available
= NULL
;
38 HANDLE interrupt_handle
= NULL
;
43 InitializeCriticalSection (&critsect
);
45 /* For safety, input_available should only be reset by get_next_msg
46 when the input queue is empty, so make it a manual reset event. */
47 keyboard_handle
= input_available
= CreateEvent (NULL
, TRUE
, FALSE
, NULL
);
49 /* interrupt_handle is signaled when quit (C-g) is detected, so that
50 blocking system calls can be interrupted. We make it a manual
51 reset event, so that if we should ever have multiple threads
52 performing system calls, they will all be interrupted (I'm guessing
53 that would the right response). Note that we use PulseEvent to
54 signal this event, so that it never remains signaled. */
55 interrupt_handle
= CreateEvent (NULL
, TRUE
, FALSE
, NULL
);
61 DeleteCriticalSection (&critsect
);
65 CloseHandle (input_available
);
66 input_available
= NULL
;
70 CloseHandle (interrupt_handle
);
71 interrupt_handle
= NULL
;
78 /* Make sure this event never remains signaled; if the main thread
79 isn't in a blocking call, then this should do nothing. */
80 PulseEvent (interrupt_handle
);
84 select_palette (FRAME_PTR f
, HDC hdc
)
86 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
88 if (!display_info
->has_palette
)
91 if (display_info
->palette
== 0)
94 if (!NILP (Vw32_enable_palette
))
95 f
->output_data
.w32
->old_palette
=
96 SelectPalette (hdc
, display_info
->palette
, FALSE
);
98 f
->output_data
.w32
->old_palette
= NULL
;
100 if (RealizePalette (hdc
))
102 Lisp_Object frame
, framelist
;
103 FOR_EACH_FRAME (framelist
, frame
)
105 SET_FRAME_GARBAGED (XFRAME (frame
));
111 deselect_palette (FRAME_PTR f
, HDC hdc
)
113 if (f
->output_data
.w32
->old_palette
)
114 SelectPalette (hdc
, f
->output_data
.w32
->old_palette
, FALSE
);
117 /* Get a DC for frame and select palette for drawing; force an update of
118 all frames if palette's mapping changes. */
120 get_frame_dc (FRAME_PTR f
)
124 if (f
->output_method
!= output_w32
)
129 hdc
= GetDC (f
->output_data
.w32
->window_desc
);
131 /* If this gets called during startup before the frame is valid,
132 there is a chance of corrupting random data or crashing. */
134 select_palette (f
, hdc
);
140 release_frame_dc (FRAME_PTR f
, HDC hdc
)
144 deselect_palette (f
, hdc
);
145 ret
= ReleaseDC (f
->output_data
.w32
->window_desc
, hdc
);
152 typedef struct int_msg
155 struct int_msg
*lpNext
;
158 int_msg
*lpHead
= NULL
;
159 int_msg
*lpTail
= NULL
;
163 get_next_msg (lpmsg
, bWait
)
171 /* The while loop takes care of multiple sets */
173 while (!nQueue
&& bWait
)
176 WaitForSingleObject (input_available
, INFINITE
);
182 bcopy (&(lpHead
->w32msg
), lpmsg
, sizeof (W32Msg
));
185 int_msg
* lpCur
= lpHead
;
187 lpHead
= lpHead
->lpNext
;
193 /* Consolidate WM_PAINT messages to optimise redrawing. */
194 if (lpmsg
->msg
.message
== WM_PAINT
&& nQueue
)
196 int_msg
* lpCur
= lpHead
;
197 int_msg
* lpPrev
= NULL
;
198 int_msg
* lpNext
= NULL
;
200 while (lpCur
&& nQueue
)
202 lpNext
= lpCur
->lpNext
;
203 if (lpCur
->w32msg
.msg
.message
== WM_PAINT
)
205 /* Remove this message from the queue. */
207 lpPrev
->lpNext
= lpNext
;
214 /* Adjust clip rectangle to cover both. */
215 if (!UnionRect (&(lpmsg
->rect
), &(lpmsg
->rect
),
216 &(lpCur
->w32msg
.rect
)))
218 SetRectEmpty(&(lpmsg
->rect
));
239 ResetEvent (input_available
);
250 int_msg
* lpNew
= (int_msg
*) myalloc (sizeof (int_msg
));
255 bcopy (lpmsg
, &(lpNew
->w32msg
), sizeof (W32Msg
));
256 lpNew
->lpNext
= NULL
;
262 lpTail
->lpNext
= lpNew
;
270 SetEvent (input_available
);
278 prepend_msg (W32Msg
*lpmsg
)
280 int_msg
* lpNew
= (int_msg
*) myalloc (sizeof (int_msg
));
285 bcopy (lpmsg
, &(lpNew
->w32msg
), sizeof (W32Msg
));
290 lpNew
->lpNext
= lpHead
;
298 /* Process all messages in the current thread's queue. */
300 drain_message_queue ()
303 while (PeekMessage (&msg
, NULL
, 0, 0, PM_REMOVE
))
305 TranslateMessage (&msg
);
306 DispatchMessage (&msg
);
312 * XParseGeometry parses strings of the form
313 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
314 * width, height, xoffset, and yoffset are unsigned integers.
315 * Example: "=80x24+300-49"
316 * The equal sign is optional.
317 * It returns a bitmask that indicates which of the four values
318 * were actually found in the string. For each value found,
319 * the corresponding argument is updated; for each value
320 * not found, the corresponding argument is left unchanged.
324 read_integer (string
, NextString
)
325 register char *string
;
328 register int Result
= 0;
333 else if (*string
== '-')
338 for (; (*string
>= '0') && (*string
<= '9'); string
++)
340 Result
= (Result
* 10) + (*string
- '0');
342 *NextString
= string
;
350 XParseGeometry (string
, x
, y
, width
, height
)
353 unsigned int *width
, *height
; /* RETURN */
356 register char *strind
;
357 unsigned int tempWidth
, tempHeight
;
361 if ((string
== NULL
) || (*string
== '\0')) return (mask
);
363 string
++; /* ignore possible '=' at beg of geometry spec */
365 strind
= (char *)string
;
366 if (*strind
!= '+' && *strind
!= '-' && *strind
!= 'x')
368 tempWidth
= read_integer (strind
, &nextCharacter
);
369 if (strind
== nextCharacter
)
371 strind
= nextCharacter
;
375 if (*strind
== 'x' || *strind
== 'X')
378 tempHeight
= read_integer (strind
, &nextCharacter
);
379 if (strind
== nextCharacter
)
381 strind
= nextCharacter
;
385 if ((*strind
== '+') || (*strind
== '-'))
390 tempX
= -read_integer (strind
, &nextCharacter
);
391 if (strind
== nextCharacter
)
393 strind
= nextCharacter
;
400 tempX
= read_integer (strind
, &nextCharacter
);
401 if (strind
== nextCharacter
)
403 strind
= nextCharacter
;
406 if ((*strind
== '+') || (*strind
== '-'))
411 tempY
= -read_integer (strind
, &nextCharacter
);
412 if (strind
== nextCharacter
)
414 strind
= nextCharacter
;
421 tempY
= read_integer (strind
, &nextCharacter
);
422 if (strind
== nextCharacter
)
424 strind
= nextCharacter
;
430 /* If strind isn't at the end of the string the it's an invalid
431 geometry specification. */
433 if (*strind
!= '\0') return (0);
439 if (mask
& WidthValue
)
441 if (mask
& HeightValue
)
442 *height
= tempHeight
;
446 /* x_sync is a no-op on W32. */
453 /* arch-tag: 4fab3695-4ad3-4cc6-a2b1-fd2c67dc46be
454 (do not change this comment) */