aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2012-10-06 20:02:31 +0200
committerEli Zaretskii2012-10-06 20:02:31 +0200
commit477f1e504482847a3b1209bc0a1dccfded649370 (patch)
tree4c402149fa77ebada9340da6772157a2338a2bdd /src
parentd5acb99a199d83cde1a43482709c3e9d4ec34b2f (diff)
downloademacs-477f1e504482847a3b1209bc0a1dccfded649370.tar.gz
emacs-477f1e504482847a3b1209bc0a1dccfded649370.zip
Initial version of the w32notify code.
Adding and removing a watch seems to work: a new thread is launched when a watch is added and exits when the watch is removed. But there are no notifications, so it seems. At least, the Lisp callback function passed to w32notify-add-watch is not called.
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c2
-rw-r--r--src/emacs.c1
-rw-r--r--src/keyboard.c15
-rw-r--r--src/lisp.h5
-rw-r--r--src/makefile.w32-in14
-rw-r--r--src/termhooks.h1
-rw-r--r--src/w32term.c127
-rw-r--r--src/w32term.h8
8 files changed, 169 insertions, 4 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 3ed8cc2d990..dd3a93ae019 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -376,7 +376,7 @@ struct gcpro *gcprolist;
376/* Addresses of staticpro'd variables. Initialize it to a nonzero 376/* Addresses of staticpro'd variables. Initialize it to a nonzero
377 value; otherwise some compilers put it into BSS. */ 377 value; otherwise some compilers put it into BSS. */
378 378
379#define NSTATICS 0x650 379#define NSTATICS 0x660
380static Lisp_Object *staticvec[NSTATICS] = {&Vpurify_flag}; 380static Lisp_Object *staticvec[NSTATICS] = {&Vpurify_flag};
381 381
382/* Index of next unused slot in staticvec. */ 382/* Index of next unused slot in staticvec. */
diff --git a/src/emacs.c b/src/emacs.c
index bc54f56b98a..65ee11fb261 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1417,6 +1417,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1417 1417
1418#ifdef WINDOWSNT 1418#ifdef WINDOWSNT
1419 syms_of_ntterm (); 1419 syms_of_ntterm ();
1420 syms_of_w32notify ();
1420#endif /* WINDOWSNT */ 1421#endif /* WINDOWSNT */
1421 1422
1422 syms_of_profiler (); 1423 syms_of_profiler ();
diff --git a/src/keyboard.c b/src/keyboard.c
index d06b02024c5..6597ebd884b 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -314,7 +314,7 @@ static Lisp_Object Qmouse_fixup_help_message;
314static Lisp_Object Qfunction_key; 314static Lisp_Object Qfunction_key;
315Lisp_Object Qmouse_click; 315Lisp_Object Qmouse_click;
316#if defined (WINDOWSNT) 316#if defined (WINDOWSNT)
317Lisp_Object Qlanguage_change; 317Lisp_Object Qlanguage_change, Qfile_notify;
318#endif 318#endif
319static Lisp_Object Qdrag_n_drop; 319static Lisp_Object Qdrag_n_drop;
320static Lisp_Object Qsave_session; 320static Lisp_Object Qsave_session;
@@ -3957,6 +3957,16 @@ kbd_buffer_get_event (KBOARD **kbp,
3957 make_number (event->modifiers))); 3957 make_number (event->modifiers)));
3958 kbd_fetch_ptr = event + 1; 3958 kbd_fetch_ptr = event + 1;
3959 } 3959 }
3960 else if (event->kind == FILE_NOTIFY_EVENT)
3961 {
3962 /* Make an event (file-notify (DESCRIPTOR ACTION FILE) CALLBACK). */
3963 obj = Fcons (Qfile_notify,
3964 list2 (list3 (event->code,
3965 XCAR (event->arg),
3966 CAR_SAFE (XCDR (event->arg))),
3967 event->frame_or_window));
3968 kbd_fetch_ptr = event + 1;
3969 }
3960#endif 3970#endif
3961 else if (event->kind == SAVE_SESSION_EVENT) 3971 else if (event->kind == SAVE_SESSION_EVENT)
3962 { 3972 {
@@ -11396,6 +11406,7 @@ syms_of_keyboard (void)
11396 11406
11397#if defined (WINDOWSNT) 11407#if defined (WINDOWSNT)
11398 DEFSYM (Qlanguage_change, "language-change"); 11408 DEFSYM (Qlanguage_change, "language-change");
11409 DEFSYM (Qfile_notify, "file-notify");
11399#endif 11410#endif
11400 11411
11401#ifdef HAVE_DBUS 11412#ifdef HAVE_DBUS
@@ -12167,6 +12178,8 @@ keys_of_keyboard (void)
12167#if defined (WINDOWSNT) 12178#if defined (WINDOWSNT)
12168 initial_define_lispy_key (Vspecial_event_map, "language-change", 12179 initial_define_lispy_key (Vspecial_event_map, "language-change",
12169 "ignore"); 12180 "ignore");
12181 initial_define_lispy_key (Vspecial_event_map, "file-notify",
12182 "w32notify-handlde-event");
12170#endif 12183#endif
12171} 12184}
12172 12185
diff --git a/src/lisp.h b/src/lisp.h
index 2a647e593a8..7812e58782b 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3497,6 +3497,11 @@ extern void syms_of_fontset (void);
3497extern Lisp_Object Qfont_param; 3497extern Lisp_Object Qfont_param;
3498#endif 3498#endif
3499 3499
3500#ifdef WINDOWSNT
3501/* Defined on w32notify.c. */
3502extern void syms_of_w32notify (void);
3503#endif
3504
3500/* Defined in xfaces.c. */ 3505/* Defined in xfaces.c. */
3501extern Lisp_Object Qdefault, Qtool_bar, Qfringe; 3506extern Lisp_Object Qdefault, Qtool_bar, Qfringe;
3502extern Lisp_Object Qheader_line, Qscroll_bar, Qcursor; 3507extern Lisp_Object Qheader_line, Qscroll_bar, Qcursor;
diff --git a/src/makefile.w32-in b/src/makefile.w32-in
index c6fbf59fb5a..f051ed6a8a9 100644
--- a/src/makefile.w32-in
+++ b/src/makefile.w32-in
@@ -134,6 +134,7 @@ OBJ2 = $(BLD)/sysdep.$(O) \
134 $(BLD)/w32menu.$(O) \ 134 $(BLD)/w32menu.$(O) \
135 $(BLD)/w32reg.$(O) \ 135 $(BLD)/w32reg.$(O) \
136 $(BLD)/w32font.$(O) \ 136 $(BLD)/w32font.$(O) \
137 $(BLD)/w32notify.$(O) \
137 $(BLD)/w32uniscribe.$(O) 138 $(BLD)/w32uniscribe.$(O)
138 139
139LIBS = $(TLIB0) \ 140LIBS = $(TLIB0) \
@@ -209,7 +210,7 @@ GLOBAL_SOURCES = dosfns.c msdos.c \
209 fontset.c menu.c dbusbind.c \ 210 fontset.c menu.c dbusbind.c \
210 w32.c w32console.c w32fns.c w32heap.c w32inevt.c \ 211 w32.c w32console.c w32fns.c w32heap.c w32inevt.c \
211 w32menu.c w32proc.c w32reg.c w32select.c w32term.c w32xfns.c \ 212 w32menu.c w32proc.c w32reg.c w32select.c w32term.c w32xfns.c \
212 font.c w32font.c w32uniscribe.c \ 213 font.c w32font.c w32uniscribe.c w32notify.c \
213 dispnew.c frame.c scroll.c xdisp.c window.c bidi.c \ 214 dispnew.c frame.c scroll.c xdisp.c window.c bidi.c \
214 charset.c coding.c category.c ccl.c character.c chartab.c \ 215 charset.c coding.c category.c ccl.c character.c chartab.c \
215 cm.c term.c terminal.c xfaces.c \ 216 cm.c term.c terminal.c xfaces.c \
@@ -1673,6 +1674,17 @@ $(BLD)/w32uniscribe.$(O) : \
1673 $(W32FONT_H) \ 1674 $(W32FONT_H) \
1674 $(W32TERM_H) 1675 $(W32TERM_H)
1675 1676
1677$(BLD)/w32notify.$(O) : \
1678 $(SRC)/w32notify.c \
1679 $(SRC)/w32heap.h \
1680 $(CODING_H) \
1681 $(CONFIG_H) \
1682 $(FRAME_H) \
1683 $(KEYBOARD_H) \
1684 $(LISP_H) \
1685 $(TERMHOOKS_H) \
1686 $(W32TERM_H)
1687
1676# Each object file depends on stamp_BLD, because in parallel builds we must 1688# Each object file depends on stamp_BLD, because in parallel builds we must
1677# make sure $(BLD) exists before starting compilations. 1689# make sure $(BLD) exists before starting compilations.
1678# 1690#
diff --git a/src/termhooks.h b/src/termhooks.h
index f35bd929af1..0afd7d97e7b 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -201,6 +201,7 @@ enum event_kind
201 On X, the window manager seems to grab the keys it wants 201 On X, the window manager seems to grab the keys it wants
202 first, so this is not a problem there. */ 202 first, so this is not a problem there. */
203 , MULTIMEDIA_KEY_EVENT 203 , MULTIMEDIA_KEY_EVENT
204 , FILE_NOTIFY_EVENT
204#endif 205#endif
205 206
206#ifdef HAVE_NS 207#ifdef HAVE_NS
diff --git a/src/w32term.c b/src/w32term.c
index 1cc8bd2adef..951ce9ef2df 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -235,6 +235,8 @@ static void x_check_font (struct frame *, struct font *);
235#endif 235#endif
236 236
237static Lisp_Object Qvendor_specific_keysyms; 237static Lisp_Object Qvendor_specific_keysyms;
238static Lisp_Object Qadded, Qremoved, Qmodified;
239static Lisp_Object Qrenamed_from, Qrenamed_to;
238 240
239 241
240/*********************************************************************** 242/***********************************************************************
@@ -3202,6 +3204,119 @@ construct_drag_n_drop (struct input_event *result, W32Msg *msg, struct frame *f)
3202 return Qnil; 3204 return Qnil;
3203} 3205}
3204 3206
3207static Lisp_Object
3208lispy_file_action (DWORD action)
3209{
3210 static char unknown_fmt[] = "unknown-action(%d)";
3211 Lisp_Object retval;
3212
3213 switch (action)
3214 {
3215 case FILE_ACTION_ADDED:
3216 retval = Qadded;
3217 break;
3218 case FILE_ACTION_REMOVED:
3219 retval = Qremoved;
3220 break;
3221 case FILE_ACTION_MODIFIED:
3222 retval = Qmodified;
3223 break;
3224 case FILE_ACTION_RENAMED_OLD_NAME:
3225 retval = Qrenamed_from;
3226 break;
3227 case FILE_ACTION_RENAMED_NEW_NAME:
3228 retval = Qrenamed_to;
3229 break;
3230 default:
3231 {
3232 char buf[sizeof(unknown_fmt) - 1 + INT_STRLEN_BOUND (DWORD)];
3233
3234 sprintf (buf, unknown_fmt, action);
3235 retval = intern (buf);
3236 }
3237 break;
3238 }
3239
3240 return retval;
3241}
3242
3243/* Put file notifications into the Emacs input event queue. This
3244 function runs when the WM_EMACS_FILENOTIFY message arrives from a
3245 watcher thread. */
3246static void
3247queue_notifications (struct input_event *event, W32Msg *msg, struct frame *f,
3248 int *evcount)
3249{
3250 BYTE *p = file_notifications;
3251 FILE_NOTIFY_INFORMATION *fni = (PFILE_NOTIFY_INFORMATION)p;
3252 const DWORD min_size
3253 = offsetof (FILE_NOTIFY_INFORMATION, FileName) + sizeof(wchar_t);
3254 Lisp_Object frame;
3255
3256 /* We cannot process notification before Emacs is fully initialized,
3257 since we need the UTF-16LE coding-system to be set up. */
3258 if (!initialized)
3259 {
3260 notification_buffer_in_use = 0;
3261 return;
3262 }
3263
3264 XSETFRAME (frame, f);
3265
3266 enter_crit ();
3267 if (notification_buffer_in_use)
3268 {
3269 DWORD info_size = notifications_size;
3270
3271 /* notifications_size could be zero when the buffer of
3272 notifications overflowed on the OS level, or when the
3273 directory being watched was itself deleted. Do nothing in
3274 that case. */
3275 if (info_size)
3276 {
3277 while (info_size >= min_size)
3278 {
3279 Lisp_Object utf_16_fn
3280 = make_unibyte_string ((char *)fni->FileName,
3281 fni->FileNameLength);
3282 /* Note: mule-conf is preloaded, so utf-16le must
3283 already be defined at this point. */
3284 Lisp_Object fname
3285 = code_convert_string_norecord (utf_16_fn,
3286 intern ("utf-16le"), 0);
3287 Lisp_Object action = lispy_file_action (fni->Action);
3288 Lisp_Object obj;
3289
3290 obj = get_watch_object (make_number (notifications_desc));
3291 if (!NILP (obj) && CONSP (obj))
3292 {
3293 event->kind = FILE_NOTIFY_EVENT;
3294 event->code = (ptrdiff_t)notifications_desc;
3295 event->timestamp = msg->msg.time;
3296 event->modifiers = 0;
3297 event->frame_or_window = XCDR (obj);
3298 event->arg = Fcons (action, fname);
3299 kbd_buffer_store_event (event);
3300 (*evcount)++;
3301 }
3302
3303 if (!fni->NextEntryOffset)
3304 break;
3305 p += fni->NextEntryOffset;
3306 fni = (PFILE_NOTIFY_INFORMATION)p;
3307 info_size -= fni->NextEntryOffset;
3308 }
3309 }
3310 notification_buffer_in_use = 0;
3311 }
3312 else
3313 DebPrint (("We were promised notifications, but in-use flag is zero!\n"));
3314 leave_crit ();
3315
3316 /* We've stuffed all the events ourselves, so w32_read_socket shouldn't. */
3317 event->kind = NO_EVENT;
3318}
3319
3205 3320
3206/* Function to report a mouse movement to the mainstream Emacs code. 3321/* Function to report a mouse movement to the mainstream Emacs code.
3207 The input handler calls this. 3322 The input handler calls this.
@@ -4829,6 +4944,12 @@ w32_read_socket (struct terminal *terminal,
4829 check_visibility = 1; 4944 check_visibility = 1;
4830 break; 4945 break;
4831 4946
4947 case WM_EMACS_FILENOTIFY:
4948 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4949 if (f)
4950 queue_notifications (&inev, &msg, f, &count);
4951 break;
4952
4832 default: 4953 default:
4833 /* Check for messages registered at runtime. */ 4954 /* Check for messages registered at runtime. */
4834 if (msg.msg.message == msh_mousewheel) 4955 if (msg.msg.message == msh_mousewheel)
@@ -6494,6 +6615,12 @@ syms_of_w32term (void)
6494 6615
6495 DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms"); 6616 DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
6496 6617
6618 DEFSYM (Qadded, "added");
6619 DEFSYM (Qremoved, "removed");
6620 DEFSYM (Qmodified, "modified");
6621 DEFSYM (Qrenamed_from, "renamed-from");
6622 DEFSYM (Qrenamed_to, "renamed-to");
6623
6497 DEFVAR_INT ("w32-num-mouse-buttons", 6624 DEFVAR_INT ("w32-num-mouse-buttons",
6498 w32_num_mouse_buttons, 6625 w32_num_mouse_buttons,
6499 doc: /* Number of physical mouse buttons. */); 6626 doc: /* Number of physical mouse buttons. */);
diff --git a/src/w32term.h b/src/w32term.h
index fcaccc4d624..75537458981 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -584,7 +584,8 @@ do { \
584#define WM_EMACS_SETCURSOR (WM_EMACS_START + 19) 584#define WM_EMACS_SETCURSOR (WM_EMACS_START + 19)
585#define WM_EMACS_PAINT (WM_EMACS_START + 20) 585#define WM_EMACS_PAINT (WM_EMACS_START + 20)
586#define WM_EMACS_BRINGTOTOP (WM_EMACS_START + 21) 586#define WM_EMACS_BRINGTOTOP (WM_EMACS_START + 21)
587#define WM_EMACS_END (WM_EMACS_START + 22) 587#define WM_EMACS_FILENOTIFY (WM_EMACS_START + 22)
588#define WM_EMACS_END (WM_EMACS_START + 23)
588 589
589#define WND_FONTWIDTH_INDEX (0) 590#define WND_FONTWIDTH_INDEX (0)
590#define WND_LINEHEIGHT_INDEX (4) 591#define WND_LINEHEIGHT_INDEX (4)
@@ -642,6 +643,11 @@ extern BOOL parse_button (int, int, int *, int *);
642 643
643extern void w32_sys_ring_bell (struct frame *f); 644extern void w32_sys_ring_bell (struct frame *f);
644extern void x_delete_display (struct w32_display_info *dpyinfo); 645extern void x_delete_display (struct w32_display_info *dpyinfo);
646extern int notification_buffer_in_use;
647extern BYTE file_notifications[16384];
648extern DWORD notifications_size;
649extern HANDLE notifications_desc;
650extern Lisp_Object get_watch_object (Lisp_Object);
645 651
646/* Keypad command key support. W32 doesn't have virtual keys defined 652/* Keypad command key support. W32 doesn't have virtual keys defined
647 for the function keys on the keypad (they are mapped to the standard 653 for the function keys on the keypad (they are mapped to the standard