int w32_console_read_socket (struct terminal *terminal, struct input_event *hold_quit) { int nev, add; int isdead; block_input (); for (;;) { int nfnotify = handle_file_notifications (hold_quit); nev = fill_queue (0); if (nev <= 0) { /* If nev == -1, there was some kind of error If nev == 0 then no events were available so return. */ if (nfnotify) nev = 0; break; } while (nev > 0) { struct input_event inev; EVENT_INIT (inev); inev.kind = NO_EVENT; inev.arg = Qnil; switch (queue_ptr->EventType) { case KEY_EVENT: add = key_event (&queue_ptr->Event.KeyEvent, &inev, &isdead); if (add == -1) /* 95.7.25 by himi */ { queue_ptr--; add = 1; } if (add) kbd_buffer_store_event_hold (&inev, hold_quit); break; case MOUSE_EVENT: add = do_mouse_event (&queue_ptr->Event.MouseEvent, &inev); if (add) kbd_buffer_store_event_hold (&inev, hold_quit); break; case WINDOW_BUFFER_SIZE_EVENT: if (w32_use_full_screen_buffer) resize_event (&queue_ptr->Event.WindowBufferSizeEvent); break; case MENU_EVENT: case FOCUS_EVENT: /* Internal event types, ignored. */ break; } queue_ptr++; nev--; } } /* We don't get told about changes in the window size (only the buffer size, which we no longer care about), so we have to check it periodically. */ if (!w32_use_full_screen_buffer) maybe_generate_resize_event (); unblock_input (); return nev; }
int w32_console_read_socket (struct terminal *terminal, int expected, struct input_event *hold_quit) { BOOL no_events = TRUE; int nev, ret = 0, add; int isdead; if (interrupt_input_blocked) { interrupt_input_pending = 1; return -1; } interrupt_input_pending = 0; BLOCK_INPUT; for (;;) { nev = fill_queue (0); if (nev <= 0) { /* If nev == -1, there was some kind of error If nev == 0 then waitp must be zero and no events were available so return. */ UNBLOCK_INPUT; return nev; } while (nev > 0) { struct input_event inev; EVENT_INIT (inev); inev.kind = NO_EVENT; inev.arg = Qnil; switch (queue_ptr->EventType) { case KEY_EVENT: add = key_event (&queue_ptr->Event.KeyEvent, &inev, &isdead); if (add == -1) /* 95.7.25 by himi */ { queue_ptr--; add = 1; } if (add) kbd_buffer_store_event_hold (&inev, hold_quit); break; case MOUSE_EVENT: add = do_mouse_event (&queue_ptr->Event.MouseEvent, &inev); if (add) kbd_buffer_store_event_hold (&inev, hold_quit); break; case WINDOW_BUFFER_SIZE_EVENT: if (w32_use_full_screen_buffer) resize_event (&queue_ptr->Event.WindowBufferSizeEvent); break; case MENU_EVENT: case FOCUS_EVENT: /* Internal event types, ignored. */ break; } queue_ptr++; nev--; } if (ret > 0 || expected == 0) break; } /* We don't get told about changes in the window size (only the buffer size, which we no longer care about), so we have to check it periodically. */ if (!w32_use_full_screen_buffer) maybe_generate_resize_event (); UNBLOCK_INPUT; return ret; }
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; }