*** empty log message ***
[emacs.git] / src / w32xfns.c
blob9624e0dd4eb4101f8176b2b25aa65c25fdc03dca
1 /* Functions taken directly from X sources for use with the Microsoft W32 API.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1999 Free Software Foundation.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 #include <config.h>
22 #include <signal.h>
23 #include <stdio.h>
24 #include "lisp.h"
25 #include "keyboard.h"
26 #include "frame.h"
27 #include "charset.h"
28 #include "fontset.h"
29 #include "blockinput.h"
30 #include "w32term.h"
31 #include "windowsx.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;
41 void
42 init_crit ()
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 signalled 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 signalled. */
56 interrupt_handle = CreateEvent (NULL, TRUE, FALSE, NULL);
59 void
60 delete_crit ()
62 DeleteCriticalSection (&critsect);
64 if (input_available)
66 CloseHandle (input_available);
67 input_available = NULL;
69 if (interrupt_handle)
71 CloseHandle (interrupt_handle);
72 interrupt_handle = NULL;
76 void
77 signal_quit ()
79 /* Make sure this event never remains signalled; if the main thread
80 isn't in a blocking call, then this should do nothing. */
81 PulseEvent (interrupt_handle);
84 void
85 select_palette (FRAME_PTR f, HDC hdc)
87 if (!NILP (Vw32_enable_palette))
88 f->output_data.w32->old_palette =
89 SelectPalette (hdc, one_w32_display_info.palette, FALSE);
90 else
91 f->output_data.w32->old_palette = NULL;
93 if (RealizePalette (hdc))
95 Lisp_Object frame, framelist;
96 FOR_EACH_FRAME (framelist, frame)
98 SET_FRAME_GARBAGED (XFRAME (frame));
103 void
104 deselect_palette (FRAME_PTR f, HDC hdc)
106 if (f->output_data.w32->old_palette)
107 SelectPalette (hdc, f->output_data.w32->old_palette, FALSE);
110 /* Get a DC for frame and select palette for drawing; force an update of
111 all frames if palette's mapping changes. */
113 get_frame_dc (FRAME_PTR f)
115 HDC hdc;
117 enter_crit ();
119 hdc = GetDC (f->output_data.w32->window_desc);
120 select_palette (f, hdc);
122 return hdc;
126 release_frame_dc (FRAME_PTR f, HDC hdc)
128 int ret;
130 deselect_palette (f, hdc);
131 ret = ReleaseDC (f->output_data.w32->window_desc, hdc);
133 leave_crit ();
135 return ret;
138 typedef struct int_msg
140 W32Msg w32msg;
141 struct int_msg *lpNext;
142 } int_msg;
144 int_msg *lpHead = NULL;
145 int_msg *lpTail = NULL;
146 int nQueue = 0;
148 BOOL
149 get_next_msg (lpmsg, bWait)
150 W32Msg * lpmsg;
151 BOOL bWait;
153 BOOL bRet = FALSE;
155 enter_crit ();
157 /* The while loop takes care of multiple sets */
159 while (!nQueue && bWait)
161 leave_crit ();
162 WaitForSingleObject (input_available, INFINITE);
163 enter_crit ();
166 if (nQueue)
168 bcopy (&(lpHead->w32msg), lpmsg, sizeof (W32Msg));
171 int_msg * lpCur = lpHead;
173 lpHead = lpHead->lpNext;
175 myfree (lpCur);
178 nQueue--;
180 bRet = TRUE;
183 if (nQueue == 0)
184 ResetEvent (input_available);
186 leave_crit ();
188 return (bRet);
191 BOOL
192 post_msg (lpmsg)
193 W32Msg * lpmsg;
195 int_msg * lpNew = (int_msg *) myalloc (sizeof (int_msg));
197 if (!lpNew)
198 return (FALSE);
200 bcopy (lpmsg, &(lpNew->w32msg), sizeof (W32Msg));
201 lpNew->lpNext = NULL;
203 enter_crit ();
205 if (nQueue++)
207 lpTail->lpNext = lpNew;
209 else
211 lpHead = lpNew;
214 lpTail = lpNew;
215 SetEvent (input_available);
217 leave_crit ();
219 return (TRUE);
222 BOOL
223 prepend_msg (W32Msg *lpmsg)
225 int_msg * lpNew = (int_msg *) myalloc (sizeof (int_msg));
227 if (!lpNew)
228 return (FALSE);
230 bcopy (lpmsg, &(lpNew->w32msg), sizeof (W32Msg));
232 enter_crit ();
234 nQueue++;
235 lpNew->lpNext = lpHead;
236 lpHead = lpNew;
238 leave_crit ();
240 return (TRUE);
243 /* Process all messages in the current thread's queue. */
244 void
245 drain_message_queue ()
247 MSG msg;
248 while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
250 TranslateMessage (&msg);
251 DispatchMessage (&msg);
257 * XParseGeometry parses strings of the form
258 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
259 * width, height, xoffset, and yoffset are unsigned integers.
260 * Example: "=80x24+300-49"
261 * The equal sign is optional.
262 * It returns a bitmask that indicates which of the four values
263 * were actually found in the string. For each value found,
264 * the corresponding argument is updated; for each value
265 * not found, the corresponding argument is left unchanged.
268 static int
269 read_integer (string, NextString)
270 register char *string;
271 char **NextString;
273 register int Result = 0;
274 int Sign = 1;
276 if (*string == '+')
277 string++;
278 else if (*string == '-')
280 string++;
281 Sign = -1;
283 for (; (*string >= '0') && (*string <= '9'); string++)
285 Result = (Result * 10) + (*string - '0');
287 *NextString = string;
288 if (Sign >= 0)
289 return (Result);
290 else
291 return (-Result);
294 int
295 XParseGeometry (string, x, y, width, height)
296 char *string;
297 int *x, *y;
298 unsigned int *width, *height; /* RETURN */
300 int mask = NoValue;
301 register char *strind;
302 unsigned int tempWidth, tempHeight;
303 int tempX, tempY;
304 char *nextCharacter;
306 if ((string == NULL) || (*string == '\0')) return (mask);
307 if (*string == '=')
308 string++; /* ignore possible '=' at beg of geometry spec */
310 strind = (char *)string;
311 if (*strind != '+' && *strind != '-' && *strind != 'x')
313 tempWidth = read_integer (strind, &nextCharacter);
314 if (strind == nextCharacter)
315 return (0);
316 strind = nextCharacter;
317 mask |= WidthValue;
320 if (*strind == 'x' || *strind == 'X')
322 strind++;
323 tempHeight = read_integer (strind, &nextCharacter);
324 if (strind == nextCharacter)
325 return (0);
326 strind = nextCharacter;
327 mask |= HeightValue;
330 if ((*strind == '+') || (*strind == '-'))
332 if (*strind == '-')
334 strind++;
335 tempX = -read_integer (strind, &nextCharacter);
336 if (strind == nextCharacter)
337 return (0);
338 strind = nextCharacter;
339 mask |= XNegative;
342 else
344 strind++;
345 tempX = read_integer (strind, &nextCharacter);
346 if (strind == nextCharacter)
347 return (0);
348 strind = nextCharacter;
350 mask |= XValue;
351 if ((*strind == '+') || (*strind == '-'))
353 if (*strind == '-')
355 strind++;
356 tempY = -read_integer (strind, &nextCharacter);
357 if (strind == nextCharacter)
358 return (0);
359 strind = nextCharacter;
360 mask |= YNegative;
363 else
365 strind++;
366 tempY = read_integer (strind, &nextCharacter);
367 if (strind == nextCharacter)
368 return (0);
369 strind = nextCharacter;
371 mask |= YValue;
375 /* If strind isn't at the end of the string the it's an invalid
376 geometry specification. */
378 if (*strind != '\0') return (0);
380 if (mask & XValue)
381 *x = tempX;
382 if (mask & YValue)
383 *y = tempY;
384 if (mask & WidthValue)
385 *width = tempWidth;
386 if (mask & HeightValue)
387 *height = tempHeight;
388 return (mask);
391 /* x_sync is a no-op on W32. */
392 void
393 x_sync (f)
394 void *f;