aboutsummaryrefslogtreecommitdiffstats
path: root/src/w32notify.c
diff options
context:
space:
mode:
authorPo Lu2024-06-23 16:28:22 +0800
committerPo Lu2024-06-23 16:28:22 +0800
commit18e7a9f3d0c27385f8efeb2b1ef80b3446dca288 (patch)
tree65501bcc78c32cb1b0972b36ddd344d044faa83e /src/w32notify.c
parent60070d0d749ecd711949683108305fe50bf39d1a (diff)
downloademacs-18e7a9f3d0c27385f8efeb2b1ef80b3446dca288.tar.gz
emacs-18e7a9f3d0c27385f8efeb2b1ef80b3446dca288.zip
Restore functionality on Windows 98
* configure.ac (W32_LIBS): Don't link with -lusp10 on non-Cygwin systems. * src/emacs.c (main): Call globals_of_w32 before the startup directory is initialized. * src/w32.c (maybe_load_unicows_dll): Call load_unicows_dll_for_w32fns. * src/w32.h: Update prototypes. * src/w32fns.c (Fx_create_frame, w32_create_tip_frame): Do not register the Uniscribe font driver when unavailable. (pfnSHFileOperationW): New function pointer. (Fsystem_move_file_to_trash): Load UNICOWS.DLL if not yet loaded. Call SHFileOperationW through said function pointer. (pfnShellExecuteExW): New function pointer. (Fw32_shell_execute) [!CYGWIN]: Load UNICOWS.DLL if not yet loaded. Call ShellExecuteExW through said function pointer. (pfnShell_NotifyIconW): New function pointer. (add_tray_notification, delete_tray_notification): Call Shell_NotifyIconW through said function pointer. (Fw32_notification_notify): Load UNICOWS.DLL. (Fw32_notification_close): Return if Shell_NotifyIconW is unavailable, as when UNICOWS.DLL has yet to be loaded. (load_unicows_dll_for_w32fns): New function. * src/w32notify.c (pfnReadDirectoryChangesW): New function pointer. (watch_completion, remove_watch, Fw32notify_add_watch) (Fw32notify_rm_watch, Fw32notify_valid_p): Call ReadDirectoryChangesW through said function pointer, and assert its presence. (globals_of_w32notify): Load ReadDirectoryChangesW from KERNEL32.DLL. * src/w32uniscribe.c (pfnScriptItemize, pfnScriptShape) (pfnScriptPlace, pfnScriptGetGlyphABCWidth, pfnScriptFreeCache) (pfnScriptGetCMap): New function pointers. (uniscribe_close, uniscribe_shape, uniscribe_encode_char) (uniscribe_check_otf_1): Call Uniscribe functions through the same. (syms_of_w32uniscribe_for_pdumper): Load Uniscribe library and required functions from the same, and if unavailable, return while leaving uniscribe_available intact. On Cygwin, simply assign USP10.DLL functions to the said new function pointers.
Diffstat (limited to 'src/w32notify.c')
-rw-r--r--src/w32notify.c42
1 files changed, 29 insertions, 13 deletions
diff --git a/src/w32notify.c b/src/w32notify.c
index c93e8796fe2..1001c85fdbe 100644
--- a/src/w32notify.c
+++ b/src/w32notify.c
@@ -120,6 +120,10 @@ struct notification {
120/* Used for communicating notifications to the main thread. */ 120/* Used for communicating notifications to the main thread. */
121struct notifications_set *notifications_set_head; 121struct notifications_set *notifications_set_head;
122 122
123/* Function pointers. */
124static BOOL (WINAPI *pfnReadDirectoryChangesW) (HANDLE, PVOID, DWORD, BOOL,
125 DWORD, PDWORD, LPOVERLAPPED,
126 LPOVERLAPPED_COMPLETION_ROUTINE);
123static Lisp_Object watch_list; 127static Lisp_Object watch_list;
124 128
125/* Signal to the main thread that we have file notifications for it to 129/* Signal to the main thread that we have file notifications for it to
@@ -252,10 +256,10 @@ watch_completion (DWORD status, DWORD bytes_ret, OVERLAPPED *io_info)
252 256
253 /* Calling ReadDirectoryChangesW quickly to watch again for new 257 /* Calling ReadDirectoryChangesW quickly to watch again for new
254 notifications. */ 258 notifications. */
255 if (!ReadDirectoryChangesW (dirwatch->dir, dirwatch->buf, 259 if (!(*pfnReadDirectoryChangesW) (dirwatch->dir, dirwatch->buf,
256 DIRWATCH_BUFFER_SIZE, dirwatch->subtree, 260 DIRWATCH_BUFFER_SIZE, dirwatch->subtree,
257 dirwatch->filter, &_bytes, dirwatch->io_info, 261 dirwatch->filter, &_bytes,
258 watch_completion)) 262 dirwatch->io_info, watch_completion))
259 { 263 {
260 DebPrint (("ReadDirectoryChangesW error: %lu\n", GetLastError ())); 264 DebPrint (("ReadDirectoryChangesW error: %lu\n", GetLastError ()));
261 /* If this call fails, it means that the directory is not 265 /* If this call fails, it means that the directory is not
@@ -270,7 +274,7 @@ watch_completion (DWORD status, DWORD bytes_ret, OVERLAPPED *io_info)
270 274
271 /* If we were asked to terminate the thread, then fire the event. */ 275 /* If we were asked to terminate the thread, then fire the event. */
272 if (terminate) 276 if (terminate)
273 SetEvent(dirwatch->terminate); 277 SetEvent (dirwatch->terminate);
274} 278}
275 279
276/* Worker routine for the watch thread. */ 280/* Worker routine for the watch thread. */
@@ -284,10 +288,10 @@ watch_worker (LPVOID arg)
284 288
285 if (dirwatch->dir) 289 if (dirwatch->dir)
286 { 290 {
287 bErr = ReadDirectoryChangesW (dirwatch->dir, dirwatch->buf, 291 bErr = (*pfnReadDirectoryChangesW) (dirwatch->dir, dirwatch->buf,
288 DIRWATCH_BUFFER_SIZE, dirwatch->subtree, 292 DIRWATCH_BUFFER_SIZE, dirwatch->subtree,
289 dirwatch->filter, &_bytes, 293 dirwatch->filter, &_bytes,
290 dirwatch->io_info, watch_completion); 294 dirwatch->io_info, watch_completion);
291 if (!bErr) 295 if (!bErr)
292 { 296 {
293 DebPrint (("ReadDirectoryChangesW: %lu\n", GetLastError ())); 297 DebPrint (("ReadDirectoryChangesW: %lu\n", GetLastError ()));
@@ -436,7 +440,7 @@ remove_watch (struct notification *dirwatch)
436 DebPrint (("QueueUserAPC failed (%lu)!\n", GetLastError ())); 440 DebPrint (("QueueUserAPC failed (%lu)!\n", GetLastError ()));
437 441
438 /* We also signal the thread that it can terminate. */ 442 /* We also signal the thread that it can terminate. */
439 SetEvent(dirwatch->terminate); 443 SetEvent (dirwatch->terminate);
440 444
441 /* Wait for the thread to exit. FIXME: is there a better method 445 /* Wait for the thread to exit. FIXME: is there a better method
442 that is not overly complex? */ 446 that is not overly complex? */
@@ -466,7 +470,7 @@ remove_watch (struct notification *dirwatch)
466 CloseHandle (dirwatch->thr); 470 CloseHandle (dirwatch->thr);
467 dirwatch->thr = NULL; 471 dirwatch->thr = NULL;
468 } 472 }
469 CloseHandle(dirwatch->terminate); 473 CloseHandle (dirwatch->terminate);
470 xfree (dirwatch->buf); 474 xfree (dirwatch->buf);
471 xfree (dirwatch->io_info); 475 xfree (dirwatch->io_info);
472 xfree (dirwatch->watchee); 476 xfree (dirwatch->watchee);
@@ -575,6 +579,8 @@ generate notifications correctly, though. */)
575 report_file_notify_error ("Watching filesystem events is not supported", 579 report_file_notify_error ("Watching filesystem events is not supported",
576 Qnil); 580 Qnil);
577 } 581 }
582 else
583 eassert (pfnReadDirectoryChangesW);
578 584
579 /* filenotify.el always passes us a directory, either the parent 585 /* filenotify.el always passes us a directory, either the parent
580 directory of a file to be watched, or the directory to be 586 directory of a file to be watched, or the directory to be
@@ -649,7 +655,7 @@ WATCH-DESCRIPTOR should be an object returned by `w32notify-add-watch'. */)
649 if (!NILP (watch_object)) 655 if (!NILP (watch_object))
650 { 656 {
651 watch_list = Fdelete (watch_object, watch_list); 657 watch_list = Fdelete (watch_object, watch_list);
652 dirwatch = (struct notification *)xmint_pointer (watch_descriptor); 658 dirwatch = (struct notification *) xmint_pointer (watch_descriptor);
653 if (w32_valid_pointer_p (dirwatch, sizeof(struct notification))) 659 if (w32_valid_pointer_p (dirwatch, sizeof(struct notification)))
654 status = remove_watch (dirwatch); 660 status = remove_watch (dirwatch);
655 } 661 }
@@ -687,7 +693,7 @@ watch by calling `w32notify-rm-watch' also makes it invalid. */)
687 if (!NILP (watch_object)) 693 if (!NILP (watch_object))
688 { 694 {
689 struct notification *dirwatch = 695 struct notification *dirwatch =
690 (struct notification *)xmint_pointer (watch_descriptor); 696 (struct notification *) xmint_pointer (watch_descriptor);
691 if (w32_valid_pointer_p (dirwatch, sizeof(struct notification)) 697 if (w32_valid_pointer_p (dirwatch, sizeof(struct notification))
692 && dirwatch->dir != NULL) 698 && dirwatch->dir != NULL)
693 return Qt; 699 return Qt;
@@ -699,6 +705,16 @@ watch by calling `w32notify-rm-watch' also makes it invalid. */)
699void 705void
700globals_of_w32notify (void) 706globals_of_w32notify (void)
701{ 707{
708 HANDLE kernel32 = GetModuleHandle ("kernel32");
709
710 /* Initialize pointers to IO functions that provide file
711 notifications. In the event that these are absent, no harm will be
712 done, since their absence indicates that Emacs is running on
713 Windows 9X, where file notifications are unavailable at the
714 outset. */
715 pfnReadDirectoryChangesW
716 = (void *) get_proc_addr (kernel32, "ReadDirectoryChangesW");
717
702 watch_list = Qnil; 718 watch_list = Qnil;
703} 719}
704 720