aboutsummaryrefslogtreecommitdiffstats
path: root/src/w32term.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/w32term.c')
-rw-r--r--src/w32term.c116
1 files changed, 66 insertions, 50 deletions
diff --git a/src/w32term.c b/src/w32term.c
index 62ad4eb086b..8955ce26b4b 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -3211,71 +3211,85 @@ static void
3211queue_notifications (struct input_event *event, W32Msg *msg, struct frame *f, 3211queue_notifications (struct input_event *event, W32Msg *msg, struct frame *f,
3212 int *evcount) 3212 int *evcount)
3213{ 3213{
3214 BYTE *p = file_notifications; 3214 struct notifications_set *ns = NULL;
3215 FILE_NOTIFY_INFORMATION *fni = (PFILE_NOTIFY_INFORMATION)p;
3216 const DWORD min_size
3217 = offsetof (FILE_NOTIFY_INFORMATION, FileName) + sizeof(wchar_t);
3218 Lisp_Object frame; 3215 Lisp_Object frame;
3216 int done = 0;
3219 3217
3220 /* We cannot process notification before Emacs is fully initialized, 3218 /* We cannot process notification before Emacs is fully initialized,
3221 since we need the UTF-16LE coding-system to be set up. */ 3219 since we need the UTF-16LE coding-system to be set up. */
3222 if (!initialized) 3220 if (!initialized)
3223 { 3221 return;
3224 notification_buffer_in_use = 0;
3225 return;
3226 }
3227 3222
3228 XSETFRAME (frame, f); 3223 XSETFRAME (frame, f);
3229 3224
3230 enter_crit (); 3225 while (!done)
3231 if (notification_buffer_in_use)
3232 { 3226 {
3233 DWORD info_size = notifications_size; 3227 ns = NULL;
3234 Lisp_Object cs = Qutf_16le; 3228
3235 Lisp_Object obj = w32_get_watch_object (notifications_desc); 3229 /* Find out if there is a record available in the linked list of
3236 3230 notifications sets. If so, unlink the set from the linked
3237 /* notifications_size could be zero when the buffer of 3231 list. Use critical section. */
3238 notifications overflowed on the OS level, or when the 3232 enter_crit ();
3239 directory being watched was itself deleted. Do nothing in 3233 if (notifications_set_head->next != notifications_set_head)
3240 that case. */
3241 if (info_size
3242 && !NILP (obj) && CONSP (obj))
3243 { 3234 {
3244 Lisp_Object callback = XCDR (obj); 3235 ns = notifications_set_head->next;
3236 ns->prev->next = ns->next;
3237 ns->next->prev = ns->prev;
3238 }
3239 else
3240 done = 1;
3241 leave_crit();
3245 3242
3246 while (info_size >= min_size) 3243 if (ns)
3244 {
3245 BYTE *p = ns->notifications;
3246 FILE_NOTIFY_INFORMATION *fni = (PFILE_NOTIFY_INFORMATION)p;
3247 const DWORD min_size
3248 = offsetof (FILE_NOTIFY_INFORMATION, FileName) + sizeof(wchar_t);
3249 DWORD info_size = ns->size;
3250 Lisp_Object cs = Qutf_16le;
3251 Lisp_Object obj = w32_get_watch_object (ns->desc);
3252
3253 /* notifications size could be zero when the buffer of
3254 notifications overflowed on the OS level, or when the
3255 directory being watched was itself deleted. Do nothing in
3256 that case. */
3257 if (info_size
3258 && !NILP (obj) && CONSP (obj))
3247 { 3259 {
3248 Lisp_Object utf_16_fn 3260 Lisp_Object callback = XCDR (obj);
3249 = make_unibyte_string ((char *)fni->FileName, 3261
3250 fni->FileNameLength); 3262 while (info_size >= min_size)
3251 /* Note: mule-conf is preloaded, so utf-16le must 3263 {
3252 already be defined at this point. */ 3264 Lisp_Object utf_16_fn
3253 Lisp_Object fname 3265 = make_unibyte_string ((char *)fni->FileName,
3254 = code_convert_string_norecord (utf_16_fn, cs, 0); 3266 fni->FileNameLength);
3255 Lisp_Object action = lispy_file_action (fni->Action); 3267 /* Note: mule-conf is preloaded, so utf-16le must
3256 3268 already be defined at this point. */
3257 event->kind = FILE_NOTIFY_EVENT; 3269 Lisp_Object fname
3258 event->timestamp = msg->msg.time; 3270 = code_convert_string_norecord (utf_16_fn, cs, 0);
3259 event->modifiers = 0; 3271 Lisp_Object action = lispy_file_action (fni->Action);
3260 event->frame_or_window = callback; 3272
3261 event->arg = list3 (make_pointer_integer (notifications_desc), 3273 event->kind = FILE_NOTIFY_EVENT;
3262 action, fname); 3274 event->timestamp = msg->msg.time;
3263 kbd_buffer_store_event (event); 3275 event->modifiers = 0;
3264 (*evcount)++; 3276 event->frame_or_window = callback;
3265 3277 event->arg = list3 (make_pointer_integer (ns->desc),
3266 if (!fni->NextEntryOffset) 3278 action, fname);
3267 break; 3279 kbd_buffer_store_event (event);
3268 p += fni->NextEntryOffset; 3280 (*evcount)++;
3269 fni = (PFILE_NOTIFY_INFORMATION)p; 3281 if (!fni->NextEntryOffset)
3270 info_size -= fni->NextEntryOffset; 3282 break;
3283 p += fni->NextEntryOffset;
3284 fni = (PFILE_NOTIFY_INFORMATION)p;
3285 info_size -= fni->NextEntryOffset;
3286 }
3271 } 3287 }
3288 /* Free this notifications set. */
3289 xfree (ns->notifications);
3290 xfree (ns);
3272 } 3291 }
3273 notification_buffer_in_use = 0;
3274 } 3292 }
3275 else
3276 DebPrint (("We were promised notifications, but in-use flag is zero!\n"));
3277 leave_crit ();
3278
3279 /* We've stuffed all the events ourselves, so w32_read_socket shouldn't. */ 3293 /* We've stuffed all the events ourselves, so w32_read_socket shouldn't. */
3280 event->kind = NO_EVENT; 3294 event->kind = NO_EVENT;
3281} 3295}
@@ -6949,6 +6963,8 @@ w32_init_main_thread (void)
6949 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (), 6963 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
6950 GetCurrentProcess (), &hMainThread, 0, TRUE, 6964 GetCurrentProcess (), &hMainThread, 0, TRUE,
6951 DUPLICATE_SAME_ACCESS); 6965 DUPLICATE_SAME_ACCESS);
6966
6967
6952} 6968}
6953 6969
6954DWORD WINAPI w32_msg_worker (void * arg); 6970DWORD WINAPI w32_msg_worker (void * arg);