#include <config.h>
#include <signal.h>
#include <stdio.h>
-#include <setjmp.h>
#include "lisp.h"
#include "blockinput.h"
#include "w32term.h"
Lisp_Object w32_display_name_list;
-#ifndef GLYPHSET
+#if _WIN32_WINNT < 0x0500
/* Pre Windows 2000, this was not available, but define it here so
that Emacs compiled on such a platform will run on newer versions. */
void x_lower_frame (struct frame *);
void x_scroll_bar_clear (struct frame *);
-void x_wm_set_size_hint (struct frame *, long, int);
+void x_wm_set_size_hint (struct frame *, long, bool);
void x_raise_frame (struct frame *);
void x_set_window_size (struct frame *, int, int, int);
void x_wm_set_window_state (struct frame *, int);
#endif
static Lisp_Object Qvendor_specific_keysyms;
+static Lisp_Object Qadded, Qremoved, Qmodified;
+static Lisp_Object Qrenamed_from, Qrenamed_to;
\f
/***********************************************************************
/* Find and set clipping rectangle */
- wave_clip = (XRectangle){ x0, y0, width, wave_height };
+ wave_clip.x = x0;
+ wave_clip.y = y0;
+ wave_clip.width = width;
+ wave_clip.height = wave_height;
+
get_glyph_string_clip_rect (s, &w32_string_clip);
CONVERT_TO_XRECT (string_clip, w32_string_clip);
updated_window = w;
set_output_cursor (&w->cursor);
- BLOCK_INPUT;
+ block_input ();
if (f == hlinfo->mouse_face_mouse_frame)
{
#endif /* 0 */
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Draw a vertical window border from (x,y0) to (x,y1) */
if (!w->pseudo_window_p)
{
- BLOCK_INPUT;
+ block_input ();
if (cursor_on_p)
display_and_set_cursor (w, 1, output_cursor.hpos,
if (draw_window_fringes (w, 1))
x_draw_vertical_border (w);
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* If a row with mouse-face was overwritten, arrange for
if (hlinfo->mouse_face_deferred_gc
|| f == hlinfo->mouse_face_mouse_frame)
{
- BLOCK_INPUT;
+ block_input ();
if (hlinfo->mouse_face_mouse_frame)
note_mouse_highlight (hlinfo->mouse_face_mouse_frame,
hlinfo->mouse_face_mouse_x,
hlinfo->mouse_face_mouse_y);
hlinfo->mouse_face_deferred_gc = 0;
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
}
{
int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
- BLOCK_INPUT;
+ block_input ();
{
HDC hdc = get_frame_dc (f);
w32_clear_area (f, hdc, 0, y, width, height);
y, width, height);
release_frame_dc (f, hdc);
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
break;
default:
- abort ();
+ emacs_abort ();
}
if (!s->for_overlaps)
w32_set_clip_rectangle (next->hdc, NULL);
next->hl = save;
next->num_clips = 0;
+ next->clip_head = s->next;
}
}
}
if (! FRAME_W32_P (f))
return;
- abort ();
+ emacs_abort ();
}
/* We don't set the output cursor here because there will always
follow an explicit cursor_to. */
- BLOCK_INPUT;
+ block_input ();
w32_clear_window (f);
colors or something like that, then they should be notified. */
x_scroll_bar_clear (f);
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
static void
w32_ring_bell (struct frame *f)
{
- BLOCK_INPUT;
+ block_input ();
if (FRAME_W32_P (f) && visible_bell)
{
else
w32_sys_ring_bell (f);
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
if (! FRAME_W32_P (f))
return;
- abort ();
+ emacs_abort ();
}
expect_dirty = CreateRectRgn (x, y, x + width, to_y);
}
- BLOCK_INPUT;
+ block_input ();
/* Cursor off. Will be switched on again in x_update_window_end. */
updated_window = w;
DeleteObject (combined);
}
- UNBLOCK_INPUT;
+ unblock_input ();
DeleteObject (expect_dirty);
}
/* Make static so we can always return it */
static char value[100];
- BLOCK_INPUT;
+ block_input ();
GetKeyNameText (keysym, value, 100);
- UNBLOCK_INPUT;
+ unblock_input ();
return value;
}
return Qnil;
}
+static Lisp_Object
+lispy_file_action (DWORD action)
+{
+ static char unknown_fmt[] = "unknown-action(%d)";
+ Lisp_Object retval;
+
+ switch (action)
+ {
+ case FILE_ACTION_ADDED:
+ retval = Qadded;
+ break;
+ case FILE_ACTION_REMOVED:
+ retval = Qremoved;
+ break;
+ case FILE_ACTION_MODIFIED:
+ retval = Qmodified;
+ break;
+ case FILE_ACTION_RENAMED_OLD_NAME:
+ retval = Qrenamed_from;
+ break;
+ case FILE_ACTION_RENAMED_NEW_NAME:
+ retval = Qrenamed_to;
+ break;
+ default:
+ {
+ char buf[sizeof(unknown_fmt) - 1 + INT_STRLEN_BOUND (DWORD)];
+
+ sprintf (buf, unknown_fmt, action);
+ retval = intern (buf);
+ }
+ break;
+ }
+
+ return retval;
+}
+
+/* Put file notifications into the Emacs input event queue. This
+ function runs when the WM_EMACS_FILENOTIFY message arrives from a
+ watcher thread. */
+static void
+queue_notifications (struct input_event *event, W32Msg *msg, struct frame *f,
+ int *evcount)
+{
+ BYTE *p = file_notifications;
+ FILE_NOTIFY_INFORMATION *fni = (PFILE_NOTIFY_INFORMATION)p;
+ const DWORD min_size
+ = offsetof (FILE_NOTIFY_INFORMATION, FileName) + sizeof(wchar_t);
+ Lisp_Object frame;
+
+ /* 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;
+ }
+
+ XSETFRAME (frame, f);
+
+ enter_crit ();
+ if (notification_buffer_in_use)
+ {
+ DWORD info_size = notifications_size;
+
+ /* 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)
+ {
+ 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,
+ intern ("utf-16le"), 0);
+ Lisp_Object action = lispy_file_action (fni->Action);
+ Lisp_Object obj;
+
+ obj = get_watch_object (make_number (notifications_desc));
+ if (!NILP (obj) && CONSP (obj))
+ {
+ event->kind = FILE_NOTIFY_EVENT;
+ event->code = (ptrdiff_t)notifications_desc;
+ event->timestamp = msg->msg.time;
+ event->modifiers = 0;
+ event->frame_or_window = XCDR (obj);
+ event->arg = Fcons (action, fname);
+ kbd_buffer_store_event (event);
+ (*evcount)++;
+ }
+
+ if (!fni->NextEntryOffset)
+ break;
+ p += fni->NextEntryOffset;
+ fni = (PFILE_NOTIFY_INFORMATION)p;
+ info_size -= fni->NextEntryOffset;
+ }
+ }
+ notification_buffer_in_use = 0;
+ }
+ else
+ DebPrint (("We were promised notifications, but in-use flag is zero!\n"));
+ leave_crit ();
+
+ /* We've stuffed all the events ourselves, so w32_read_socket shouldn't. */
+ event->kind = NO_EVENT;
+}
+
\f
/* Function to report a mouse movement to the mainstream Emacs code.
The input handler calls this.
{
FRAME_PTR f1;
- BLOCK_INPUT;
+ block_input ();
if (! NILP (last_mouse_scroll_bar) && insist == 0)
x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
frame = XCAR (tail);
/* All elements of Vframe_list should be frames. */
if (! FRAMEP (frame))
- abort ();
+ emacs_abort ();
/* Scan this frame's scroll bar list for a scroll bar with the
right window ID. */
if (draggingp)
{
int near_bottom_p;
- BLOCK_INPUT;
+ block_input ();
si.cbSize = sizeof (si);
si.fMask = SIF_POS | SIF_PAGE;
GetScrollInfo (w, SB_CTL, &si);
near_bottom_p = si.nPos + si.nPage >= range;
- UNBLOCK_INPUT;
+ unblock_input ();
if (!near_bottom_p)
return;
}
sb_page = max (sb_page, VERTICAL_SCROLL_BAR_MIN_HANDLE);
- BLOCK_INPUT;
+ block_input ();
si.cbSize = sizeof (si);
si.fMask = SIF_PAGE | SIF_POS;
SetScrollInfo (w, SB_CTL, &si, TRUE);
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
= XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
Lisp_Object barobj;
- BLOCK_INPUT;
+ block_input ();
XSETWINDOW (bar->window, w);
XSETINT (bar->top, top);
if (! NILP (bar->next))
XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
- UNBLOCK_INPUT;
+ unblock_input ();
return bar;
}
{
FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
- BLOCK_INPUT;
+ block_input ();
/* Destroy the window. */
my_destroy_window (f, SCROLL_BAR_W32_WINDOW (bar));
/* Dissociate this scroll bar from its window. */
- WSET (XWINDOW (bar->window), vertical_scroll_bar, Qnil);
+ wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil);
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Set the handle of the vertical scroll bar for WINDOW to indicate
if (NILP (w->vertical_scroll_bar))
{
HDC hdc;
- BLOCK_INPUT;
+ block_input ();
if (width > 0 && height > 0)
{
hdc = get_frame_dc (f);
w32_clear_area (f, hdc, left, top, width, height);
release_frame_dc (f, hdc);
}
- UNBLOCK_INPUT;
+ unblock_input ();
bar = x_scroll_bar_create (w, top, sb_left, sb_width, height);
}
HDC hdc;
SCROLLINFO si;
- BLOCK_INPUT;
+ block_input ();
if (width && height)
{
hdc = get_frame_dc (f);
XSETINT (bar->width, sb_width);
XSETINT (bar->height, height);
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil;
w32_set_scroll_bar_thumb (bar, portion, position, whole);
XSETVECTOR (barobj, bar);
- WSET (w, vertical_scroll_bar, barobj);
+ wset_vertical_scroll_bar (w, barobj);
}
/* We can't redeem this window's scroll bar if it doesn't have one. */
if (NILP (window->vertical_scroll_bar))
- abort ();
+ emacs_abort ();
bar = XSCROLL_BAR (window->vertical_scroll_bar);
else
/* If its prev pointer is nil, it must be at the front of
one or the other! */
- abort ();
+ emacs_abort ();
}
else
XSCROLL_BAR (bar->prev)->next = bar->next;
struct input_event *emacs_event)
{
if (! WINDOWP (bar->window))
- abort ();
+ emacs_abort ();
emacs_event->kind = SCROLL_BAR_CLICK_EVENT;
emacs_event->code = 0;
int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
SCROLLINFO si;
- BLOCK_INPUT;
+ block_input ();
*fp = f;
*bar_window = bar->window;
*time = last_mouse_movement_time;
- UNBLOCK_INPUT;
+ unblock_input ();
}
We return the number of characters stored into the buffer,
thus pretending to be `read'.
- EXPECTED is nonzero if the caller knows input is available.
-
Some of these messages are reposted back to the message queue since the
system calls the windows proc directly in a context where we cannot return
the data nor can we guarantee the state we are in. So if we dispatch them
*/
static int
-w32_read_socket (struct terminal *terminal, int expected,
+w32_read_socket (struct terminal *terminal,
struct input_event *hold_quit)
{
int count = 0;
struct w32_display_info *dpyinfo = &one_w32_display_info;
Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
- if (interrupt_input_blocked)
- {
- interrupt_input_pending = 1;
- return -1;
- }
-
- interrupt_input_pending = 0;
- BLOCK_INPUT;
+ block_input ();
/* So people can tell when we have read the available input. */
input_signal_count++;
check_visibility = 1;
break;
+ case WM_EMACS_FILENOTIFY:
+ f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
+ if (f)
+ queue_notifications (&inev, &msg, f, &count);
+ break;
+
default:
/* Check for messages registered at runtime. */
if (msg.msg.message == msh_mousewheel)
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
return count;
}
break;
default:
- abort ();
+ emacs_abort ();
}
}
}
}
x_calc_absolute_position (f);
- BLOCK_INPUT;
+ block_input ();
x_wm_set_size_hint (f, (long) 0, 0);
modified_left = f->left_pos;
modified_left, modified_top,
0, 0,
SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
- UNBLOCK_INPUT;
+ unblock_input ();
}
{
int pixelwidth, pixelheight;
- BLOCK_INPUT;
+ block_input ();
check_frame_size (f, &rows, &cols);
f->scroll_bar_actual_width
cancel_mouse_face (f);
#endif
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
/* Mouse warping. */
RECT rect;
POINT pt;
- BLOCK_INPUT;
+ block_input ();
GetClientRect (FRAME_W32_WINDOW (f), &rect);
pt.x = rect.left + pix_x;
SetCursorPos (pt.x, pt.y);
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
struct w32_display_info *dpyinfo = &one_w32_display_info;
/* Give input focus to frame. */
- BLOCK_INPUT;
+ block_input ();
#if 0
/* Try not to change its Z-order if possible. */
if (x_window_to_frame (dpyinfo, GetForegroundWindow ()))
else
#endif
my_set_foreground_window (FRAME_W32_WINDOW (f));
- UNBLOCK_INPUT;
+ unblock_input ();
}
void
void
x_raise_frame (struct frame *f)
{
- BLOCK_INPUT;
+ block_input ();
/* Strictly speaking, raise-frame should only change the frame's Z
order, leaving input focus unchanged. This is reasonable behavior
my_bring_window_to_top (FRAME_W32_WINDOW (f));
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Lower frame F. */
void
x_lower_frame (struct frame *f)
{
- BLOCK_INPUT;
+ block_input ();
my_set_window_pos (FRAME_W32_WINDOW (f),
HWND_BOTTOM,
0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
- UNBLOCK_INPUT;
+ unblock_input ();
}
static void
{
Lisp_Object type;
- BLOCK_INPUT;
+ block_input ();
type = x_icon_type (f);
if (!NILP (type))
int count;
/* This must come after we set COUNT. */
- UNBLOCK_INPUT;
+ unblock_input ();
XSETFRAME (frame, f);
if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f)
FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame = 0;
- BLOCK_INPUT;
+ block_input ();
my_show_window (f, FRAME_W32_WINDOW (f), SW_HIDE);
f->async_visible = 0;
f->async_iconified = 0;
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Change window state from mapped to iconified. */
if (f->async_iconified)
return;
- BLOCK_INPUT;
+ block_input ();
type = x_icon_type (f);
if (!NILP (type))
/* Simulate the user minimizing the frame. */
SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0);
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
- BLOCK_INPUT;
+ block_input ();
/* We must free faces before destroying windows because some
font-driver (e.g. xft) access a window while finishing a
hlinfo->mouse_face_mouse_frame = 0;
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Set the normal size hints for the window manager, for frame F.
FLAGS is the flags word to use--or 0 meaning preserve the flags
that the window now has.
- If USER_POSITION is nonzero, we set the USPosition
+ If USER_POSITION, set the USPosition
flag (this is useful when FLAGS is 0). */
void
-x_wm_set_size_hint (struct frame *f, long flags, int user_position)
+x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
{
Window window = FRAME_W32_WINDOW (f);
terminal like X does. */
terminal->kboard = xmalloc (sizeof (KBOARD));
init_kboard (terminal->kboard);
- KSET (terminal->kboard, Vwindow_system, intern ("w32"));
+ kset_window_system (terminal->kboard, intern ("w32"));
terminal->kboard->next_kboard = all_kboards;
all_kboards = terminal->kboard;
/* Don't let the initial kboard remain current longer than necessary.
if (!terminal->name)
return;
- BLOCK_INPUT;
+ block_input ();
x_delete_display (dpyinfo);
- UNBLOCK_INPUT;
+ unblock_input ();
}
struct w32_display_info *
struct terminal *terminal;
HDC hdc;
- BLOCK_INPUT;
+ block_input ();
if (!w32_initialized)
{
init_sigio (connection);
#endif /* ! defined (SIGIO) */
- UNBLOCK_INPUT;
+ unblock_input ();
return dpyinfo;
}
DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
+ DEFSYM (Qadded, "added");
+ DEFSYM (Qremoved, "removed");
+ DEFSYM (Qmodified, "modified");
+ DEFSYM (Qrenamed_from, "renamed-from");
+ DEFSYM (Qrenamed_to, "renamed-to");
+
DEFVAR_INT ("w32-num-mouse-buttons",
w32_num_mouse_buttons,
doc: /* Number of physical mouse buttons. */);