This source file includes following definitions.
- init_crit
- delete_crit
- signal_quit
- select_palette
- deselect_palette
- get_frame_dc
- release_frame_dc
- get_next_msg
- notify_msg_ready
- post_msg
- prepend_msg
- drain_message_queue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <config.h>
21 #include <signal.h>
22 #include <stdio.h>
23 #include <windows.h>
24 #include <windowsx.h>
25
26 #include "lisp.h"
27 #include "frame.h"
28 #include "w32term.h"
29
30 #define myalloc(cb) GlobalAllocPtr (GPTR, cb)
31 #define myfree(lp) GlobalFreePtr (lp)
32
33 CRITICAL_SECTION critsect;
34
35 #ifdef WINDOWSNT
36 extern HANDLE keyboard_handle;
37 #endif
38
39 HANDLE input_available = NULL;
40 HANDLE interrupt_handle = NULL;
41
42 void
43 init_crit (void)
44 {
45 InitializeCriticalSection (&critsect);
46
47
48
49 input_available = CreateEvent (NULL, TRUE, FALSE, NULL);
50
51 #if HAVE_W32NOTIFY
52
53
54
55 notifications_set_head = malloc (sizeof(struct notifications_set));
56 if (notifications_set_head)
57 {
58 memset (notifications_set_head, 0, sizeof(struct notifications_set));
59 notifications_set_head->next
60 = notifications_set_head->prev = notifications_set_head;
61 }
62 else
63 DebPrint(("Out of memory: can't initialize notifications sets."));
64 #endif
65
66 #ifdef WINDOWSNT
67 keyboard_handle = input_available;
68 #endif
69
70
71
72
73
74
75
76 interrupt_handle = CreateEvent (NULL, TRUE, FALSE, NULL);
77 }
78
79 void
80 delete_crit (void)
81 {
82 DeleteCriticalSection (&critsect);
83
84 if (input_available)
85 {
86 CloseHandle (input_available);
87 input_available = NULL;
88 }
89 if (interrupt_handle)
90 {
91 CloseHandle (interrupt_handle);
92 interrupt_handle = NULL;
93 }
94
95 #if HAVE_W32NOTIFY
96 if (notifications_set_head)
97 {
98
99 while (notifications_set_head->next != notifications_set_head)
100 {
101 struct notifications_set *ns = notifications_set_head->next;
102 notifications_set_head->next = ns->next;
103 ns->next->prev = notifications_set_head;
104 if (ns->notifications)
105 free (ns->notifications);
106 free (ns);
107 }
108 }
109 free (notifications_set_head);
110 #endif
111 }
112
113 void
114 signal_quit (void)
115 {
116
117
118 PulseEvent (interrupt_handle);
119 }
120
121 void
122 select_palette (struct frame *f, HDC hdc)
123 {
124 struct w32_display_info *display_info = FRAME_DISPLAY_INFO (f);
125
126 if (!display_info->has_palette)
127 return;
128
129 if (display_info->palette == 0)
130 return;
131
132 if (!NILP (Vw32_enable_palette))
133 f->output_data.w32->old_palette =
134 SelectPalette (hdc, display_info->palette, FALSE);
135 else
136 f->output_data.w32->old_palette = NULL;
137
138 if (RealizePalette (hdc) != GDI_ERROR)
139 {
140 Lisp_Object frame, framelist;
141 FOR_EACH_FRAME (framelist, frame)
142 {
143 SET_FRAME_GARBAGED (XFRAME (frame));
144 }
145 }
146 }
147
148 void
149 deselect_palette (struct frame *f, HDC hdc)
150 {
151 if (f->output_data.w32->old_palette)
152 SelectPalette (hdc, f->output_data.w32->old_palette, FALSE);
153 }
154
155
156
157 HDC
158 get_frame_dc (struct frame *f)
159 {
160 HDC hdc, paint_dc;
161 HBITMAP back_buffer;
162 HGDIOBJ obj;
163 struct w32_output *output;
164
165 if (f->output_method != output_w32)
166 emacs_abort ();
167
168 enter_crit ();
169 output = FRAME_OUTPUT_DATA (f);
170
171 if (output->paint_dc)
172 {
173 if (output->paint_buffer_width != FRAME_PIXEL_WIDTH (f)
174 || output->paint_buffer_height != FRAME_PIXEL_HEIGHT (f)
175 || w32_disable_double_buffering)
176 w32_release_paint_buffer (f);
177 else
178 {
179 output->paint_buffer_dirty = 1;
180 return output->paint_dc;
181 }
182 }
183
184 hdc = GetDC (output->window_desc);
185
186
187
188 if (hdc)
189 {
190 select_palette (f, hdc);
191
192 if (!w32_disable_double_buffering
193 && FRAME_OUTPUT_DATA (f)->want_paint_buffer)
194 {
195 back_buffer
196 = CreateCompatibleBitmap (hdc, FRAME_PIXEL_WIDTH (f),
197 FRAME_PIXEL_HEIGHT (f));
198
199 if (back_buffer)
200 {
201 paint_dc = CreateCompatibleDC (hdc);
202
203 if (!paint_dc)
204 DeleteObject (back_buffer);
205 else
206 {
207 obj = SelectObject (paint_dc, back_buffer);
208
209 output->paint_dc_object = obj;
210 output->paint_dc = paint_dc;
211 output->paint_buffer_handle = hdc;
212 output->paint_buffer = back_buffer;
213 output->paint_buffer_width = FRAME_PIXEL_WIDTH (f);
214 output->paint_buffer_height = FRAME_PIXEL_HEIGHT (f);
215 output->paint_buffer_dirty = 1;
216
217 SET_FRAME_GARBAGED (f);
218
219 return paint_dc;
220 }
221 }
222 }
223 }
224
225 return hdc;
226 }
227
228 int
229 release_frame_dc (struct frame *f, HDC hdc)
230 {
231 int ret;
232
233
234
235 if (hdc != FRAME_OUTPUT_DATA (f)->paint_dc)
236 {
237 deselect_palette (f, hdc);
238 ret = ReleaseDC (f->output_data.w32->window_desc, hdc);
239 }
240 else
241 ret = 0;
242
243 leave_crit ();
244
245 return ret;
246 }
247
248 typedef struct int_msg
249 {
250 W32Msg w32msg;
251 struct int_msg *lpNext;
252 } int_msg;
253
254 int_msg *lpHead = NULL;
255 int_msg *lpTail = NULL;
256 int nQueue = 0;
257
258 BOOL
259 get_next_msg (W32Msg * lpmsg, BOOL bWait)
260 {
261 BOOL bRet = FALSE;
262
263 enter_crit ();
264
265
266
267 while (!nQueue && bWait)
268 {
269 leave_crit ();
270 WaitForSingleObject (input_available, INFINITE);
271 enter_crit ();
272 }
273
274 if (nQueue)
275 {
276 memcpy (lpmsg, &lpHead->w32msg, sizeof (W32Msg));
277
278 {
279 int_msg * lpCur = lpHead;
280
281 lpHead = lpHead->lpNext;
282
283 myfree (lpCur);
284 }
285
286 nQueue--;
287
288 if (lpmsg->msg.message == WM_PAINT && nQueue)
289 {
290 int_msg * lpCur = lpHead;
291 int_msg * lpPrev = NULL;
292 int_msg * lpNext = NULL;
293
294 while (lpCur && nQueue)
295 {
296 lpNext = lpCur->lpNext;
297 if (lpCur->w32msg.msg.message == WM_PAINT)
298 {
299
300 if (lpPrev)
301 lpPrev->lpNext = lpNext;
302 else
303 lpHead = lpNext;
304
305 if (lpCur == lpTail)
306 lpTail = lpPrev;
307
308
309 if (!UnionRect (&(lpmsg->rect), &(lpmsg->rect),
310 &(lpCur->w32msg.rect)))
311 {
312 SetRectEmpty (&(lpmsg->rect));
313 }
314
315 myfree (lpCur);
316
317 nQueue--;
318
319 lpCur = lpNext;
320 }
321 else
322 {
323 lpPrev = lpCur;
324 lpCur = lpNext;
325 }
326 }
327 }
328
329 bRet = TRUE;
330 }
331
332 if (nQueue == 0)
333 ResetEvent (input_available);
334
335 leave_crit ();
336
337 return (bRet);
338 }
339
340 extern char * w32_strerror (int error_no);
341
342
343
344 static void
345 notify_msg_ready (void)
346 {
347 SetEvent (input_available);
348
349 #ifdef CYGWIN
350
351
352 (void) PostThreadMessage (dwMainThreadId, WM_EMACS_INPUT_READY, 0, 0);
353 #endif
354 }
355
356 BOOL
357 post_msg (W32Msg * lpmsg)
358 {
359 int_msg * lpNew = (int_msg *) myalloc (sizeof (int_msg));
360
361 if (!lpNew)
362 return (FALSE);
363
364 memcpy (&lpNew->w32msg, lpmsg, sizeof (W32Msg));
365 lpNew->lpNext = NULL;
366
367 enter_crit ();
368
369 if (nQueue++)
370 {
371 lpTail->lpNext = lpNew;
372 }
373 else
374 {
375 lpHead = lpNew;
376 }
377
378 lpTail = lpNew;
379 notify_msg_ready ();
380 leave_crit ();
381
382 return (TRUE);
383 }
384
385 BOOL
386 prepend_msg (W32Msg *lpmsg)
387 {
388 int_msg * lpNew = (int_msg *) myalloc (sizeof (int_msg));
389
390 if (!lpNew)
391 return (FALSE);
392
393 memcpy (&lpNew->w32msg, lpmsg, sizeof (W32Msg));
394
395 enter_crit ();
396
397 nQueue++;
398 lpNew->lpNext = lpHead;
399 lpHead = lpNew;
400 notify_msg_ready ();
401 leave_crit ();
402
403 return (TRUE);
404 }
405
406
407
408 int
409 drain_message_queue (void)
410 {
411 MSG msg;
412 int retval = 0;
413
414 while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
415 {
416 if (msg.message == WM_EMACS_FILENOTIFY)
417 retval = 1;
418 TranslateMessage (&msg);
419 DispatchMessage (&msg);
420 }
421 return retval;
422 }