(special-display-p, same-window-p): Add missing
[bpt/emacs.git] / src / w32xfns.c
CommitLineData
ee78dc32
GV
1/* Functions taken directly from X sources
2 Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
3b7ad313
EN
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
ee78dc32
GV
20
21#include <signal.h>
22#include <config.h>
23#include <stdio.h>
24#include "lisp.h"
97aab3a2 25#include "frame.h"
ee78dc32
GV
26#include "blockinput.h"
27#include "w32term.h"
28#include "windowsx.h"
29
30#define myalloc(cb) GlobalAllocPtr (GPTR, cb)
31#define myfree(lp) GlobalFreePtr (lp)
32
dd118a07 33CRITICAL_SECTION critsect;
ee78dc32 34extern HANDLE keyboard_handle;
97aab3a2 35HANDLE input_available = NULL;
ee78dc32
GV
36
37void
38init_crit ()
39{
dd118a07 40 InitializeCriticalSection (&critsect);
ee78dc32 41
97aab3a2
GV
42 /* For safety, input_available should only be reset by get_next_msg
43 when the input queue is empty, so make it a manual reset event. */
44 keyboard_handle = input_available = CreateEvent (NULL, TRUE, FALSE, NULL);
ee78dc32
GV
45}
46
dd118a07 47void
97aab3a2 48delete_crit ()
ee78dc32 49{
97aab3a2
GV
50 DeleteCriticalSection (&critsect);
51
52 if (input_available)
53 {
54 CloseHandle (input_available);
55 input_available = NULL;
56 }
d484dc55
GV
57}
58
97aab3a2
GV
59void
60select_palette (FRAME_PTR f, HDC hdc)
d484dc55 61{
97aab3a2
GV
62 if (!NILP (Vwin32_enable_palette))
63 f->output_data.win32->old_palette =
64 SelectPalette (hdc, one_win32_display_info.palette, FALSE);
65 else
66 f->output_data.win32->old_palette = NULL;
67
68 if (RealizePalette (hdc))
69 {
70 Lisp_Object frame, framelist;
71 FOR_EACH_FRAME (framelist, frame)
dd118a07 72 {
97aab3a2 73 SET_FRAME_GARBAGED (XFRAME (frame));
dd118a07 74 }
97aab3a2
GV
75 }
76}
77
78void
79deselect_palette (FRAME_PTR f, HDC hdc)
80{
81 if (f->output_data.win32->old_palette)
82 SelectPalette (hdc, f->output_data.win32->old_palette, FALSE);
83}
84
85/* Get a DC for frame and select palette for drawing; force an update of
86 all frames if palette's mapping changes. */
87HDC
88get_frame_dc (FRAME_PTR f)
89{
90 HDC hdc;
91
92 enter_crit ();
93
94 hdc = GetDC (f->output_data.win32->window_desc);
95 select_palette (f, hdc);
96
97 return hdc;
98}
99
100int
101release_frame_dc (FRAME_PTR f, HDC hdc)
102{
103 int ret;
104
105 deselect_palette (f, hdc);
106 ret = ReleaseDC (f->output_data.win32->window_desc, hdc);
107
108 leave_crit ();
109
110 return ret;
ee78dc32
GV
111}
112
113typedef struct int_msg
114{
115 Win32Msg w32msg;
116 struct int_msg *lpNext;
117} int_msg;
118
119int_msg *lpHead = NULL;
120int_msg *lpTail = NULL;
121int nQueue = 0;
122
123BOOL
124get_next_msg (lpmsg, bWait)
125 Win32Msg * lpmsg;
126 BOOL bWait;
127{
128 BOOL bRet = FALSE;
129
dd118a07 130 enter_crit ();
ee78dc32
GV
131
132 /* The while loop takes care of multiple sets */
133
134 while (!nQueue && bWait)
135 {
dd118a07 136 leave_crit ();
97aab3a2 137 WaitForSingleObject (input_available, INFINITE);
dd118a07 138 enter_crit ();
ee78dc32
GV
139 }
140
141 if (nQueue)
142 {
143 bcopy (&(lpHead->w32msg), lpmsg, sizeof (Win32Msg));
144
145 {
146 int_msg * lpCur = lpHead;
147
148 lpHead = lpHead->lpNext;
149
150 myfree (lpCur);
151 }
152
153 nQueue--;
154
155 bRet = TRUE;
156 }
97aab3a2
GV
157
158 if (nQueue == 0)
159 ResetEvent (input_available);
ee78dc32 160
dd118a07 161 leave_crit ();
ee78dc32
GV
162
163 return (bRet);
164}
165
166BOOL
167post_msg (lpmsg)
168 Win32Msg * lpmsg;
169{
170 int_msg * lpNew = (int_msg *) myalloc (sizeof (int_msg));
171
97aab3a2
GV
172 if (!lpNew)
173 return (FALSE);
ee78dc32
GV
174
175 bcopy (lpmsg, &(lpNew->w32msg), sizeof (Win32Msg));
176 lpNew->lpNext = NULL;
177
dd118a07 178 enter_crit ();
ee78dc32
GV
179
180 if (nQueue++)
dd118a07
GV
181 {
182 lpTail->lpNext = lpNew;
183 }
ee78dc32 184 else
dd118a07
GV
185 {
186 lpHead = lpNew;
dd118a07 187 }
ee78dc32
GV
188
189 lpTail = lpNew;
97aab3a2 190 SetEvent (input_available);
ee78dc32 191
dd118a07 192 leave_crit ();
ee78dc32
GV
193
194 return (TRUE);
195}
196
7c69181b
GV
197BOOL
198prepend_msg (Win32Msg *lpmsg)
199{
200 int_msg * lpNew = (int_msg *) myalloc (sizeof (int_msg));
201
202 if (!lpNew)
203 return (FALSE);
204
205 bcopy (lpmsg, &(lpNew->w32msg), sizeof (Win32Msg));
206
207 enter_crit ();
208
209 nQueue++;
210 lpNew->lpNext = lpHead;
211 lpHead = lpNew;
212
213 leave_crit ();
214
215 return (TRUE);
216}
217
ee78dc32
GV
218/*
219 * XParseGeometry parses strings of the form
220 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
221 * width, height, xoffset, and yoffset are unsigned integers.
222 * Example: "=80x24+300-49"
223 * The equal sign is optional.
224 * It returns a bitmask that indicates which of the four values
225 * were actually found in the string. For each value found,
226 * the corresponding argument is updated; for each value
227 * not found, the corresponding argument is left unchanged.
228 */
229
230static int
231read_integer (string, NextString)
232 register char *string;
233 char **NextString;
234{
235 register int Result = 0;
236 int Sign = 1;
237
238 if (*string == '+')
239 string++;
240 else if (*string == '-')
241 {
242 string++;
243 Sign = -1;
244 }
245 for (; (*string >= '0') && (*string <= '9'); string++)
246 {
247 Result = (Result * 10) + (*string - '0');
248 }
249 *NextString = string;
250 if (Sign >= 0)
251 return (Result);
252 else
253 return (-Result);
254}
255
256int
257XParseGeometry (string, x, y, width, height)
258 char *string;
259 int *x, *y;
260 unsigned int *width, *height; /* RETURN */
261{
262 int mask = NoValue;
263 register char *strind;
264 unsigned int tempWidth, tempHeight;
265 int tempX, tempY;
266 char *nextCharacter;
267
268 if ((string == NULL) || (*string == '\0')) return (mask);
269 if (*string == '=')
270 string++; /* ignore possible '=' at beg of geometry spec */
271
272 strind = (char *)string;
273 if (*strind != '+' && *strind != '-' && *strind != 'x')
274 {
275 tempWidth = read_integer (strind, &nextCharacter);
276 if (strind == nextCharacter)
277 return (0);
278 strind = nextCharacter;
279 mask |= WidthValue;
280 }
281
282 if (*strind == 'x' || *strind == 'X')
283 {
284 strind++;
285 tempHeight = read_integer (strind, &nextCharacter);
286 if (strind == nextCharacter)
287 return (0);
288 strind = nextCharacter;
289 mask |= HeightValue;
290 }
291
292 if ((*strind == '+') || (*strind == '-'))
293 {
294 if (*strind == '-')
295 {
296 strind++;
297 tempX = -read_integer (strind, &nextCharacter);
298 if (strind == nextCharacter)
299 return (0);
300 strind = nextCharacter;
301 mask |= XNegative;
302
303 }
304 else
305 {
306 strind++;
307 tempX = read_integer (strind, &nextCharacter);
308 if (strind == nextCharacter)
309 return (0);
310 strind = nextCharacter;
311 }
312 mask |= XValue;
313 if ((*strind == '+') || (*strind == '-'))
314 {
315 if (*strind == '-')
316 {
317 strind++;
318 tempY = -read_integer (strind, &nextCharacter);
319 if (strind == nextCharacter)
320 return (0);
321 strind = nextCharacter;
322 mask |= YNegative;
323
324 }
325 else
326 {
327 strind++;
328 tempY = read_integer (strind, &nextCharacter);
329 if (strind == nextCharacter)
330 return (0);
331 strind = nextCharacter;
332 }
333 mask |= YValue;
334 }
335 }
336
337 /* If strind isn't at the end of the string the it's an invalid
338 geometry specification. */
339
340 if (*strind != '\0') return (0);
341
342 if (mask & XValue)
343 *x = tempX;
344 if (mask & YValue)
345 *y = tempY;
346 if (mask & WidthValue)
347 *width = tempWidth;
348 if (mask & HeightValue)
349 *height = tempHeight;
350 return (mask);
351}
352
142aad74 353/* We can use mouse menus when we wish. */
ee78dc32 354int
142aad74 355have_menus_p (void)
ee78dc32
GV
356{
357 return 1;
358}
359
360/* x_sync is a no-op on Win32. */
361void
362x_sync (f)
363 void *f;
364{
365}
366