diff options
| author | Eli Zaretskii | 2012-10-06 20:02:31 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2012-10-06 20:02:31 +0200 |
| commit | 477f1e504482847a3b1209bc0a1dccfded649370 (patch) | |
| tree | 4c402149fa77ebada9340da6772157a2338a2bdd /src | |
| parent | d5acb99a199d83cde1a43482709c3e9d4ec34b2f (diff) | |
| download | emacs-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.c | 2 | ||||
| -rw-r--r-- | src/emacs.c | 1 | ||||
| -rw-r--r-- | src/keyboard.c | 15 | ||||
| -rw-r--r-- | src/lisp.h | 5 | ||||
| -rw-r--r-- | src/makefile.w32-in | 14 | ||||
| -rw-r--r-- | src/termhooks.h | 1 | ||||
| -rw-r--r-- | src/w32term.c | 127 | ||||
| -rw-r--r-- | src/w32term.h | 8 |
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 |
| 380 | static Lisp_Object *staticvec[NSTATICS] = {&Vpurify_flag}; | 380 | static 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; | |||
| 314 | static Lisp_Object Qfunction_key; | 314 | static Lisp_Object Qfunction_key; |
| 315 | Lisp_Object Qmouse_click; | 315 | Lisp_Object Qmouse_click; |
| 316 | #if defined (WINDOWSNT) | 316 | #if defined (WINDOWSNT) |
| 317 | Lisp_Object Qlanguage_change; | 317 | Lisp_Object Qlanguage_change, Qfile_notify; |
| 318 | #endif | 318 | #endif |
| 319 | static Lisp_Object Qdrag_n_drop; | 319 | static Lisp_Object Qdrag_n_drop; |
| 320 | static Lisp_Object Qsave_session; | 320 | static 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); | |||
| 3497 | extern Lisp_Object Qfont_param; | 3497 | extern Lisp_Object Qfont_param; |
| 3498 | #endif | 3498 | #endif |
| 3499 | 3499 | ||
| 3500 | #ifdef WINDOWSNT | ||
| 3501 | /* Defined on w32notify.c. */ | ||
| 3502 | extern void syms_of_w32notify (void); | ||
| 3503 | #endif | ||
| 3504 | |||
| 3500 | /* Defined in xfaces.c. */ | 3505 | /* Defined in xfaces.c. */ |
| 3501 | extern Lisp_Object Qdefault, Qtool_bar, Qfringe; | 3506 | extern Lisp_Object Qdefault, Qtool_bar, Qfringe; |
| 3502 | extern Lisp_Object Qheader_line, Qscroll_bar, Qcursor; | 3507 | extern 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 | ||
| 139 | LIBS = $(TLIB0) \ | 140 | LIBS = $(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 | ||
| 237 | static Lisp_Object Qvendor_specific_keysyms; | 237 | static Lisp_Object Qvendor_specific_keysyms; |
| 238 | static Lisp_Object Qadded, Qremoved, Qmodified; | ||
| 239 | static 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 | ||
| 3207 | static Lisp_Object | ||
| 3208 | lispy_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. */ | ||
| 3246 | static void | ||
| 3247 | queue_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 | ||
| 643 | extern void w32_sys_ring_bell (struct frame *f); | 644 | extern void w32_sys_ring_bell (struct frame *f); |
| 644 | extern void x_delete_display (struct w32_display_info *dpyinfo); | 645 | extern void x_delete_display (struct w32_display_info *dpyinfo); |
| 646 | extern int notification_buffer_in_use; | ||
| 647 | extern BYTE file_notifications[16384]; | ||
| 648 | extern DWORD notifications_size; | ||
| 649 | extern HANDLE notifications_desc; | ||
| 650 | extern 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 |