/* Signal to the main thread that we have file notifications for it to process. */ static void send_notifications (BYTE *info, DWORD info_size, void *desc, volatile int *terminate) { int done = 0; struct frame *f = SELECTED_FRAME (); /* A single buffer is used to communicate all notifications to the main thread. Since both the main thread and several watcher threads could be active at the same time, we use a critical area and an "in-use" flag to synchronize them. A watcher thread can only put its notifications in the buffer if it acquires the critical area and finds the "in-use" flag reset. The main thread resets the flag after it is done processing notifications. FIXME: is there a better way of dealing with this? */ while (!done && !*terminate) { enter_crit (); if (!notification_buffer_in_use) { if (info_size) memcpy (file_notifications, info, min (info_size, sizeof (file_notifications))); notifications_size = min (info_size, sizeof (file_notifications)); notifications_desc = desc; /* If PostMessage fails, the message queue is full. If that happens, the last thing they will worry about is file notifications. So we effectively discard the notification in that case. */ if ((FRAME_TERMCAP_P (f) /* We send the message to the main (a.k.a. "Lisp") thread, where it will wake up MsgWaitForMultipleObjects inside sys_select, causing it to report that there's some keyboard input available. This will in turn cause w32_console_read_socket to be called, which will pick up the file notifications. */ && PostThreadMessage (dwMainThreadId, WM_EMACS_FILENOTIFY, 0, 0)) || (FRAME_W32_P (f) && PostMessage (FRAME_W32_WINDOW (f), WM_EMACS_FILENOTIFY, 0, 0)) /* When we are running in batch mode, there's no one to send a message, so we just signal the data is available and hope sys_select will be called soon and will read the data. */ || (FRAME_INITIAL_P (f) && noninteractive)) notification_buffer_in_use = 1; done = 1; } leave_crit (); if (!done) Sleep (5); } }
/* Remember mouse motion and notify emacs. */ static void mouse_moved_to (int x, int y) { /* If we're in the same place, ignore it. */ if (x != movement_pos.X || y != movement_pos.Y) { SELECTED_FRAME ()->mouse_moved = 1; movement_pos.X = x; movement_pos.Y = y; movement_time = GetTickCount (); } }
static void destroy_fringe_bitmap (int n) { struct fringe_bitmap **fbp; fringe_faces[n] = Qnil; fbp = &fringe_bitmaps[n]; if (*fbp && (*fbp)->dynamic) { /* XXX Is SELECTED_FRAME OK here? */ struct redisplay_interface *rif = FRAME_RIF (SELECTED_FRAME ()); if (rif && rif->destroy_fringe_bitmap) rif->destroy_fringe_bitmap (n); xfree (*fbp); *fbp = NULL; } while (max_used_fringe_bitmap > MAX_STANDARD_FRINGE_BITMAPS && fringe_bitmaps[max_used_fringe_bitmap - 1] == NULL) max_used_fringe_bitmap--; }
/* Signal to the main thread that we have file notifications for it to process. */ static void send_notifications (struct notifications_set *ns) { struct frame *f = SELECTED_FRAME (); /* We add the current notification set to the linked list. Use the critical section to make sure only one thread will access the linked list. */ enter_crit (); ns->next = notifications_set_head; ns->prev = notifications_set_head->prev; ns->prev->next = ns; notifications_set_head->prev = ns; leave_crit(); /* If PostMessage fails, the message queue is full. If that happens, the last thing they will worry about is file notifications. So we effectively discard the notification in that case. */ if (FRAME_TERMCAP_P (f)) /* We send the message to the main (a.k.a. "Lisp") thread, where it will wake up MsgWaitForMultipleObjects inside sys_select, causing it to report that there's some keyboard input available. This will in turn cause w32_console_read_socket to be called, which will pick up the file notifications. */ PostThreadMessage (dwMainThreadId, WM_EMACS_FILENOTIFY, 0, 0); else if (FRAME_W32_P (f)) PostMessage (FRAME_W32_WINDOW (f), WM_EMACS_FILENOTIFY, 0, 0); /* When we are running in batch mode, there's no one to send a message, so we just signal the data is available and hope sys_select will be called soon and will read the data. */ #if 0 else if (FRAME_INITIAL_P (f) && noninteractive) ; #endif }
/* Mouse position hook. */ void w32_console_mouse_position (FRAME_PTR *f, int insist, Lisp_Object *bar_window, enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y, Time *time) { block_input (); insist = insist; *f = get_frame (); *bar_window = Qnil; *part = 0; SELECTED_FRAME ()->mouse_moved = 0; XSETINT (*x, movement_pos.X); XSETINT (*y, movement_pos.Y); *time = movement_time; unblock_input (); }
/* Mouse position hook. */ void w32_console_mouse_position (FRAME_PTR *f, int insist, Lisp_Object *bar_window, enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y, unsigned long *time) { BLOCK_INPUT; insist = insist; *f = get_frame (); *bar_window = Qnil; *part = 0; SELECTED_FRAME ()->mouse_moved = 0; XSETINT (*x, movement_pos.X); XSETINT (*y, movement_pos.Y); *time = movement_time; UNBLOCK_INPUT; }
static int do_mouse_event (MOUSE_EVENT_RECORD *event, struct input_event *emacs_ev) { static DWORD button_state = 0; static Lisp_Object last_mouse_window; DWORD but_change, mask; int i; if (event->dwEventFlags == MOUSE_MOVED) { FRAME_PTR f = SELECTED_FRAME (); Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); int mx = event->dwMousePosition.X, my = event->dwMousePosition.Y; mouse_moved_to (mx, my); if (f->mouse_moved) { if (hlinfo->mouse_face_hidden) { hlinfo->mouse_face_hidden = 0; clear_mouse_face (hlinfo); } /* Generate SELECT_WINDOW_EVENTs when needed. */ if (!NILP (Vmouse_autoselect_window)) { Lisp_Object mouse_window = window_from_coordinates (f, mx, my, 0, 0); /* A window will be selected only when it is not selected now, and the last mouse movement event was not in it. A minibuffer window will be selected iff it is active. */ if (WINDOWP (mouse_window) && !EQ (mouse_window, last_mouse_window) && !EQ (mouse_window, selected_window)) { struct input_event event; EVENT_INIT (event); event.kind = SELECT_WINDOW_EVENT; event.frame_or_window = mouse_window; event.arg = Qnil; event.timestamp = movement_time; kbd_buffer_store_event (&event); } last_mouse_window = mouse_window; } else last_mouse_window = Qnil; previous_help_echo_string = help_echo_string; help_echo_string = help_echo_object = help_echo_window = Qnil; help_echo_pos = -1; note_mouse_highlight (f, mx, my); /* If the contents of the global variable help_echo has changed (inside note_mouse_highlight), generate a HELP_EVENT. */ if (!NILP (help_echo_string) || !NILP (previous_help_echo_string)) gen_help_event (help_echo_string, selected_frame, help_echo_window, help_echo_object, help_echo_pos); } return 0; } /* It looks like the console code sends us a mouse event with dwButtonState == 0 when a window is activated. Ignore this case. */ if (event->dwButtonState == button_state) return 0; emacs_ev->kind = MOUSE_CLICK_EVENT; /* Find out what button has changed state since the last button event. */ but_change = button_state ^ event->dwButtonState; mask = 1; for (i = 0; mask; i++, mask <<= 1) if (but_change & mask) { if (i < NUM_TRANSLATED_MOUSE_BUTTONS) emacs_ev->code = emacs_button_translation[i]; else emacs_ev->code = i; break; } button_state = event->dwButtonState; emacs_ev->timestamp = GetTickCount (); emacs_ev->modifiers = w32_kbd_mods_to_emacs (event->dwControlKeyState, 0) | ((event->dwButtonState & mask) ? down_modifier : up_modifier); XSETFASTINT (emacs_ev->x, event->dwMousePosition.X); XSETFASTINT (emacs_ev->y, event->dwMousePosition.Y); /* for Mule 2.2 (Based on Emacs 19.28 */ #ifdef MULE XSET (emacs_ev->frame_or_window, Lisp_Frame, get_frame ()); #else XSETFRAME (emacs_ev->frame_or_window, get_frame ()); #endif return 1; }
/* In a generic, multi-frame world this should take a console handle and return the frame for it Right now, there's only one frame so return it. */ static FRAME_PTR get_frame (void) { return SELECTED_FRAME (); }
/* In a generic, multi-frame world this should take a console handle and return the frame for it. Right now, there's only one frame so return it. */ static struct frame * get_frame (void) { return SELECTED_FRAME (); }
if (menu) w32_free_submenu_strings (menu); } current_popup_menu = NULL; } /* The following is used by delayed window autoselection. */ DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p, 0, 0, 0, doc: /* Return t if a menu or popup dialog is active on selected frame. */) (void) { struct frame *f; f = SELECTED_FRAME (); return (f->output_data.w32->menubar_active > 0) ? Qt : Qnil; } void syms_of_w32menu (void) { globals_of_w32menu (); current_popup_menu = NULL; DEFSYM (Qdebug_on_next_call, "debug-on-next-call"); DEFSYM (Qunsupported__w32_dialog, "unsupported--w32-dialog"); defsubr (&Smenu_or_popup_active_p); }