static int handle_file_notifications (struct input_event *hold_quit) { BYTE *p = file_notifications; FILE_NOTIFY_INFORMATION *fni = (PFILE_NOTIFY_INFORMATION)p; const DWORD min_size = offsetof (FILE_NOTIFY_INFORMATION, FileName) + sizeof(wchar_t); struct input_event inev; int nevents = 0; /* We cannot process notification before Emacs is fully initialized, since we need the UTF-16LE coding-system to be set up. */ if (!initialized) { notification_buffer_in_use = 0; return nevents; } enter_crit (); if (notification_buffer_in_use) { DWORD info_size = notifications_size; Lisp_Object cs = intern ("utf-16le"); Lisp_Object obj = w32_get_watch_object (notifications_desc); /* notifications_size could be zero when the buffer of notifications overflowed on the OS level, or when the directory being watched was itself deleted. Do nothing in that case. */ if (info_size && !NILP (obj) && CONSP (obj)) { Lisp_Object callback = XCDR (obj); EVENT_INIT (inev); while (info_size >= min_size) { Lisp_Object utf_16_fn = make_unibyte_string ((char *)fni->FileName, fni->FileNameLength); /* Note: mule-conf is preloaded, so utf-16le must already be defined at this point. */ Lisp_Object fname = code_convert_string_norecord (utf_16_fn, cs, 0); Lisp_Object action = lispy_file_action (fni->Action); inev.kind = FILE_NOTIFY_EVENT; inev.code = (ptrdiff_t)XINT (XIL ((EMACS_INT)notifications_desc)); inev.timestamp = GetTickCount (); inev.modifiers = 0; inev.frame_or_window = callback; inev.arg = Fcons (action, fname); kbd_buffer_store_event_hold (&inev, hold_quit); if (!fni->NextEntryOffset) break; p += fni->NextEntryOffset; fni = (PFILE_NOTIFY_INFORMATION)p; info_size -= fni->NextEntryOffset; } } notification_buffer_in_use = 0; } leave_crit (); return nevents; }
int handle_file_notifications (struct input_event *hold_quit) { struct notifications_set *ns = NULL; int nevents = 0; int done = 0; /* We cannot process notification before Emacs is fully initialized, since we need the UTF-16LE coding-system to be set up. */ if (!initialized) { return nevents; } while (!done) { ns = NULL; /* Find out if there is a record available in the linked list of notifications sets. If so, unlink te set from the linked list. Use the critical section. */ enter_crit (); if (notifications_set_head->next != notifications_set_head) { ns = notifications_set_head->next; ns->prev->next = ns->next; ns->next->prev = ns->prev; } else done = 1; leave_crit(); if (ns) { BYTE *p = ns->notifications; FILE_NOTIFY_INFORMATION *fni = (PFILE_NOTIFY_INFORMATION)p; const DWORD min_size = offsetof (FILE_NOTIFY_INFORMATION, FileName) + sizeof(wchar_t); struct input_event inev; DWORD info_size = ns->size; Lisp_Object cs = Qutf_16le; Lisp_Object obj = w32_get_watch_object (ns->desc); /* notifications size could be zero when the buffer of notifications overflowed on the OS level, or when the directory being watched was itself deleted. Do nothing in that case. */ if (info_size && !NILP (obj) && CONSP (obj)) { Lisp_Object callback = XCDR (obj); EVENT_INIT (inev); while (info_size >= min_size) { Lisp_Object utf_16_fn = make_unibyte_string ((char *)fni->FileName, fni->FileNameLength); /* Note: mule-conf is preloaded, so utf-16le must already be defined at this point. */ Lisp_Object fname = code_convert_string_norecord (utf_16_fn, cs, 0); Lisp_Object action = lispy_file_action (fni->Action); inev.kind = FILE_NOTIFY_EVENT; inev.timestamp = GetTickCount (); inev.modifiers = 0; inev.frame_or_window = callback; inev.arg = Fcons (action, fname); inev.arg = list3 (make_pointer_integer (ns->desc), action, fname); kbd_buffer_store_event_hold (&inev, hold_quit); nevents++; if (!fni->NextEntryOffset) break; p += fni->NextEntryOffset; fni = (PFILE_NOTIFY_INFORMATION)p; info_size -= fni->NextEntryOffset; } } /* Free this notification set. */ free (ns->notifications); free (ns); } } return nevents; }