summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2024-06-30 23:12:09 +0800
committerPo Lu <luangruo@yahoo.com>2024-06-30 23:12:09 +0800
commit7c8d4e96ba6db19bdca20a87bafed024a84eb517 (patch)
treefbab938bf8f25d5634912a58260f9d1c517d6737 /src
parent7f89fe8a342d7b4e8800d0ef333fb6759b58ccb5 (diff)
parent64851d101a854e00c68f3e9259d70777e7b26cb2 (diff)
Merge from savannah/emacs-30
64851d101a8 Improve Android "adaptive icon" 9b294059d71 Fix documentation for Emacs 30 f50167ab95e ; Update NEWS and corresponding manuals 4e22ef870c4 Add D-Bus test f784d946d44 ; Repair corruption in etc/DEBUG c750fbb539e ; * etc/DEBUG: Advice for debugging Emacs on OpenBSD (bug... 38179f85f8f Merge remote-tracking branch 'savannah/scratch/windows-98... 72cf9964f3c Inaccuracy in efaq.texi fc48e9e8ed5 ; Fix typos in DOS Makefile scripts 9b8d754579f ; * etc/NEWS: Explain Nextstep. 8819e5a45d5 Fix treesit crash (bug#71681) eaf2dc96c1f ; Fix SHR test on MS-Windows 57880f597c5 Delete redundant mention of `with-eval-after-load' ea8ce984342 * doc/misc/efaq.texi (New in Emacs 30): Fix typos. 45a20d781a9 ; Fix typos in symbols d95f039af43 Document security fixes in FAQ d063af203c8 Add "New in Emacs 30" to FAQ ca6b484162b ; * etc/NEWS: Move "Minibuffer and Completions" 35c46663e49 ; * etc/NEWS: Move item to "Lisp Changes". 0515b38d289 ; * etc/NEWS: Move keyboard macro items closer together. 22af3a71039 ; * etc/NEWS: More copy-edits. 000ef8876ae ; * etc/NEWS: Move items to "Incompatible Lisp Changes". 4088dc8e4ce ; * etc/NEWS: Rearrange "Incompatible Lisp Changes". 179800f36bb ; * lisp/epg.el (epg--start): Add commentary about encoding. 73898f0214c Fix non-ASCII filename operatiion on EasyPG (bug#71500) a65b6aac6b5 Silence warning with global minor mode :predicate f5f7343ac41 ; * etc/NEWS: Move an item to "Startup Changes" c95066bf188 ; * etc/NEWS: Move some Lisp items to better place. bf7db88ce1f ; * etc/NEWS: Rearrange "Editing Changes in Emacs 30.1" 000424eb9eb ; * etc/NEWS: Make touch screen support more prominent. 5b5671587fb ; * etc/NEWS: Rearrange "Changes in Emacs 30.1". 31124abdefe ; * lisp/thingatpt.el (sexp-at-point): Doc fix (bug#71777). 44f269d6e60 Fix: make 'xwidget-webkit-scroll-backward' scroll backwards 358085997c6 Merge branch 'emacs-30' of git.savannah.gnu.org:/srv/git/... 736b7cad406 Add jsdoc support to php-ts-mode in <script> element 5f3d964e397 Update to Transient v0.7.2-4-gf75bc48d 2d8881d5267 Fix typo incurring leaks of face structures 219501dd629 ; Fix use of @footnote in cc-mode.texi c7be2dcac44 Merge branch 'emacs-30' of git.sv.gnu.org:/srv/git/emacs ... f0a48799756 Sync with Tramp 2.7.1 53dcf2b9492 ; * etc/NEWS: Move the mwheel entry to a better place. a5726782d03 ; Sort tree-sitter modes in NEWS daa89dc939e ; * etc/NEWS: Rearrange "New Modes and Packages in Emacs ... 4ddbf4f70ef ; * etc/NEWS: Move many items. 437b1ced268 ; * etc/NEWS: Copy-edits. 7372b2eb302 Expand docstring of which-key-mode df0eb5be1ea Improve documentation of 'remove-overlays' in ELisp manual 73c1252bb6b Fix link to major mode variable in docstring c4ad54812ac Make `shell-mode' more robust c4ec905c9a9 Correct ommissions in rmc.el bf862fc2770 * lisp/hi-lock.el: More fixes related to revert-buffer. 6cc8ffae9a6 Update to Org 9.7.5-9-ga091ca c477443ab80 ; Fix typo in lua-ts-mode.el 6e5e4d61939 ; Add 'eglot-ensure' option to 'lua-ts-mode-hook' 58a2f36a8b9 ; * etc/NEWS: Copy edit. df53ef176ac Merge branch 'emacs-30' of git.savannah.gnu.org:/srv/git/... 039e6ffd866 Write Antinews for Emacs 30 ELisp Reference bf8c9f702ba (eval-last-sexp): Fix bug#71774 6d94090cadc * lisp/hi-lock.el: More fixes for revert-buffer (bug#57534) 280c91782af * lisp/hi-lock.el (hi-lock-revert-buffer-rehighlight): Im... 339310d0205 * lisp/tab-bar.el (tab-bar-select-restore-windows): Impro... c1e7569a925 Write Antinews for Emacs 30 user manual 233f683da8f ; * lisp/erc/erc-backend.el (erc-server-reconnect-timeout... 20a672b3b2b Change ERC version for Emacs 30 to 5.6.0.30.1 cbede3d43df * src/w32uniscribe.c (syms_of_w32uniscribe_for_pdumper): ... 6f9f9a21555 Fix two tests for --without-all build 98daa10f065 ; * etc/PROBLEMS (PGTK): Remove redundant 2nd PGTK section. ced33bc2397 Fix handling of non-nil 'dired-movement-style' b1e9b6fd67d ; * lisp/gnus/message.el (message-idna-to-ascii-rhs): Doc... 5eb9a0d2c79 ; * etc/NEWS: Fix last change (bug#71720). 6ec77f580dd Do not prematurely truncate python eldoc string f475a1a2544 ; Fix simple-tests as fallout of last change aa10d0c5ac1 Add tests for `kill-whole-line' (bug#65734) 058bb4ca25a kill-whole-line: Honor visibility; fix kill-ring when rea... e45173d114e * lisp/hi-lock.el (hi-lock-file-patterns-policy): Add val... d6afb017deb * lisp/progmodes/xref.el (xref-revert-buffer-restore-poin... 8d55b38e2a1 Fix Cygwin build 82125b1a661 Use 'revert-function' in *xref* buffer 860840621a1 Prevent crashes and related issues if initial activity is... d5c6eb1f964 Doc fix in 'php-ts-mode' fb15affde8c Avoid compiler warnings in the Cygwin-w32 build 8d354925ddb Add new face 'widget-unselected' to wid-edit.el 1809f6a93ef Always perform Eshell process cleanup runs in the Eshell ... 8b1841021c0 Avert crash in store_mode_line_string on Android 5.0 and ... e7c85f9235a Use HarfBuzz in Cygwin-w32 build 8e3e206bd32 ; * src/buffer.c (syms_of_buffer) <mode-line-format>: ASC... fe0d9dfb3b1 ; * lisp/treesit.el (treesit--syntax-propertize-start): F... 2f18929319a Fix tabbing between widgets (bug#70594) 6ad6507532b ; * lisp/which-key.el (which-key-dont-use-unicode): Add :... 60b38c317bb * lisp/touch-screen.el (touch-screen-inhibit-drag): Anoth... a4ca30ac2e0 Fix rescaling of images via 'text-scale-mode' in EWW 0e43606b20d * lisp/touch-screen.el (touch-screen-inhibit-drag): Fix t... 1b4c5627211 Fix latent side-effects of respecting field boundaries in... e4046f33ab8 ; * lisp/simple.el (undo-auto--boundaries): Doc fix (bug#... 008eeb21fdb ; * lisp/language/cyrillic.el: Delete obsolete commentary... 680155d3f03 Add missing builtin package declarations ce4f56caf71 Extend treesitter tests on emba 7e8a97ac788 Show entries from key-translation-map in which-key mode 4a0958642d9 * lisp/tab-bar.el (tab-bar-tab-group-face-function): Impr... a769f171e7e ; Fix flymake tests with GCC 14. 96e27c2ecf9 Don't show char name for multi-char translations 0715abfa86a Reset ls-lisp-use-string-collate when ls-lisp-emulation c... 4fcc38966bf Update to Transient v0.7.2-1-gf273c0c8 b7d5ca3a8fb * doc/misc/calc.texi (Musical Notes): Fix typo. 164f75822b2 ; Fix typos 768e92b9c02 Update options that depend on 'which-key-dont-use-unicode' 4b2682b17cd ; Remove debugging message in Completion Preview test 73a58329a69 Fix omission of updates to child frames on Android 0edacf2aa7e Add jsdoc support to js-ts-mode cace0cbee93 ; Restore inadvertently removed line. 2b04effb13d ; * test/lisp/net/shr-tests.el (shr-test--rendering-check... 6619aec6bca ; Don't run new 'shr-test/zoom-image' when built without ... 5d19bfda321 ; * admin/release-branch.txt: Update and fix typo. fb11294d415 ; Fix typos d9bd1718f9a Backport: Minor changes in tramp-tests.el 1728de5a776 Backport: Tramp: Fix bug#71709, and other minor changes dd0fc6aff60 New branch emacs-30 bc72c33ac38 * admin/admin.el: (set-version): Fix regexp for configure... 60475a73d17 Disable Ffile_system_info for Android special directories 18e7a9f3d0c Restore functionality on Windows 98 5f8a9cd4b6f Fix a bug in 'switch-to-buffer' 5f9b5803bea Fix zooming images in SHR 6f2036243f2 ; Doc fix in 'php-ts-mode'. 2f1c882a16e Colorize CSS property value like `css--fontify-region' dd0994aa36c Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs 486ea8ef5ac * configure.ac: Disable kqueue on Haiku. 737fa7c5292 Fix 'Customize' menu entry for 'php-ts-mode' cb7be6035ee Fix compilation on prerelease versions of Haiku 2b848a4e504 Fix FIXME in comment 77e3a56507d Update SKK-JISYO.L from upstream e5bae788614 Update publicsuffix.txt from upstream bf5f74288b7 Add assignment form as `etc/copyright-assign.txt` fcd37988048 ; Merge from origin/emacs-29 0f01cb0ebd1 Bump Emacs version to 29.4.50 014aab9847a Fix for grammar change of keyword "virtual" in tree-sitte... fa364a0d469 Revert "; * etc/HISTORY: Delete never-released Emacs 28.3." a81417e5766 Update Tramp version (don't merge to master) ff389163ee8 Manually merge NEWS.29 from emacs-29 ea057131220 ; * etc/HISTORY: Delete never-released Emacs 28.3. d3469978b89 Merge from origin/emacs-29 3739342a4e9 ; Merge from origin/emacs-29 38e738a35eb Merge from origin/emacs-29 4c4c94fa105 ; Merge from origin/emacs-29 1313b8966ae Merge from origin/emacs-29 4a76af51bb6 Replace literal whitespace with `\s` e41dd2241f7 ; Merge from origin/emacs-29 8520ec829d3 ; * lisp/editorconfig.el (editorconfig-indentation-alist)... 99161fb7140 Fix non-existing `editorconfig-set-indentation-python-mode` fd15d89ec51 Merge remote-tracking branch 'origin/emacs-29' into emacs-29 6a299b3cace Release Emacs 29.4 3f3c08bcc76 Add before-save-hook to man page files 7b0e6cb3ffa Use UTC when generating man page timestamps a7cb642a9fc Merge from origin/emacs-29 6491d11b53a ; Merge from origin/emacs-29 2f39a4b28a9 Merge from origin/emacs-29 150e2b979c1 ; * src/xfns.c (unwind_create_frame): Add missing definit... 75fdeef7b49 Allow to expand truncated long lines in *Compilation* buf... fb1b188e1ad Eglot: Fix command execution (bug#71642) 155cc89de02 Support for indentation of PHP alternative syntax control... 7f7b28a2500 ; Wayland SECONDARY selection problem 11fb3510f48 Prevent auto-revert when deleting entry (bug#71264) a4fe4ca93cf Fix font lock regex for user defined constant in PHP e1ba4ebb495 Make Compilation mode recognize non-legacy Kotlin/Gradle ... 4f030834994 ; Improve documentation of EditorConfig support c0bfe429485 List Andrea Corallo as co-maintainer in ack.texi b3d6880512f * admin/MAINTAINERS: Add myself in (co-)maintainers. 7cc939bf27e ; * lisp/ldefs-boot.el: Regenerated for Emacs 29.4 959eacc2a70 Bump Emacs version to 29.4 9a02fce714c Update files for Emacs 29.4 d96c54d3883 * admin/authors.el: Update for Emacs 29.4 fd207432e50 * etc/NEWS: Update for Emacs 29.4 c645e1d8205 org-link-expand-abbrev: Do not evaluate arbitrary unsafe ... 50a237c4689 Update Tramp version (don't merge to master) f3e80dd0f70 * admin/emacs-shell-lib: Backport to Bash 4.4 or older. ce85d3811da Fix bug#49289 also for other auth-source backends # Conflicts: # etc/NEWS
Diffstat (limited to 'src')
-rw-r--r--src/emacs.c8
-rw-r--r--src/w32.c2
-rw-r--r--src/w32.h1
-rw-r--r--src/w32fns.c79
-rw-r--r--src/w32notify.c42
-rw-r--r--src/w32uniscribe.c140
6 files changed, 204 insertions, 68 deletions
diff --git a/src/emacs.c b/src/emacs.c
index 77929817447..22b7a4f1038 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1395,6 +1395,10 @@ main (int argc, char **argv)
the additional call here is harmless.) */
cache_system_info ();
#ifdef WINDOWSNT
+ /* This must be called to initialize w32_unicode_filenames and
+ is_windows_9x prior to w32_init_current_directory. */
+ globals_of_w32 ();
+
/* On Windows 9X, we have to load UNICOWS.DLL as early as possible,
to have non-stub implementations of APIs we need to convert file
names between UTF-8 and the system's ANSI codepage. */
@@ -1506,11 +1510,10 @@ main (int argc, char **argv)
}
}
#endif
-
emacs_wd = emacs_get_current_dir_name ();
#ifdef WINDOWSNT
initial_wd = emacs_wd;
-#endif
+#endif /* WINDOWSNT */
#ifdef HAVE_PDUMPER
if (dumped_with_pdumper_p ())
pdumper_record_wd (emacs_wd);
@@ -2165,7 +2168,6 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
init_atimer ();
#ifdef WINDOWSNT
- globals_of_w32 ();
#ifdef HAVE_W32NOTIFY
globals_of_w32notify ();
#endif
diff --git a/src/w32.c b/src/w32.c
index 1c6a56bcbd9..4986d4c6676 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -10624,6 +10624,7 @@ maybe_load_unicows_dll (void)
pWideCharToMultiByte = (WideCharToMultiByte_Proc)
get_proc_addr (ret, "WideCharToMultiByte");
multiByteToWideCharFlags = MB_ERR_INVALID_CHARS;
+ load_unicows_dll_for_w32fns (ret);
return ret;
}
else
@@ -10658,6 +10659,7 @@ maybe_load_unicows_dll (void)
multiByteToWideCharFlags = 0;
else
multiByteToWideCharFlags = MB_ERR_INVALID_CHARS;
+ load_unicows_dll_for_w32fns (NULL);
return LoadLibrary ("Gdi32.dll");
}
}
diff --git a/src/w32.h b/src/w32.h
index cf470ae9901..3dc79dabf4b 100644
--- a/src/w32.h
+++ b/src/w32.h
@@ -170,6 +170,7 @@ extern void release_listen_threads (void);
extern void init_ntproc (int);
extern void term_ntproc (int);
extern HANDLE maybe_load_unicows_dll (void);
+extern void load_unicows_dll_for_w32fns (HMODULE);
extern void globals_of_w32 (void);
extern void term_timers (void);
diff --git a/src/w32fns.c b/src/w32fns.c
index 4c2f18abd08..6090eb34e82 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -2612,6 +2612,7 @@ my_post_msg (W32Msg * wmsg, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
}
#ifdef WINDOWSNT
+
/* The Windows keyboard hook callback. */
static LRESULT CALLBACK
funhook (int code, WPARAM w, LPARAM l)
@@ -2688,8 +2689,8 @@ funhook (int code, WPARAM w, LPARAM l)
can prevent this by setting the
w32-pass-[lr]window-to-system variable to
NIL. */
- if ((hs->vkCode == VK_LWIN && !NILP (Vw32_pass_lwindow_to_system)) ||
- (hs->vkCode == VK_RWIN && !NILP (Vw32_pass_rwindow_to_system)))
+ if ((hs->vkCode == VK_LWIN && !NILP (Vw32_pass_lwindow_to_system))
+ || (hs->vkCode == VK_RWIN && !NILP (Vw32_pass_rwindow_to_system)))
{
/* Not prevented - Simulate the keypress to the system. */
memset (inputs, 0, sizeof (inputs));
@@ -2704,7 +2705,6 @@ funhook (int code, WPARAM w, LPARAM l)
inputs[1].ki.dwFlags
= KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP;
inputs[1].ki.time = 0;
- SendInput (2, inputs, sizeof (INPUT));
}
else if (focus != NULL)
{
@@ -6150,7 +6150,8 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
if (harfbuzz_available)
register_font_driver (&harfbuzz_font_driver, f);
#endif
- register_font_driver (&uniscribe_font_driver, f);
+ if (uniscribe_available)
+ register_font_driver (&uniscribe_font_driver, f);
register_font_driver (&w32font_driver, f);
gui_default_parameter (f, parameters, Qfont_backend, Qnil,
@@ -7227,7 +7228,8 @@ w32_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms)
if (harfbuzz_available)
register_font_driver (&harfbuzz_font_driver, f);
#endif
- register_font_driver (&uniscribe_font_driver, f);
+ if (uniscribe_available)
+ register_font_driver (&uniscribe_font_driver, f);
register_font_driver (&w32font_driver, f);
gui_default_parameter (f, parms, Qfont_backend, Qnil,
@@ -8265,6 +8267,8 @@ DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
#ifdef WINDOWSNT
+static int (WINAPI *pfnSHFileOperationW) (LPSHFILEOPSTRUCTW);
+
/* Moving files to the system recycle bin.
Used by `move-file-to-trash' instead of the default moving to ~/.Trash */
DEFUN ("system-move-file-to-trash", Fsystem_move_file_to_trash,
@@ -8276,6 +8280,9 @@ DEFUN ("system-move-file-to-trash", Fsystem_move_file_to_trash,
Lisp_Object encoded_file;
Lisp_Object operation;
+ /* Required on Windows 9X. */
+ maybe_load_unicows_dll ();
+
operation = Qdelete_file;
if (!NILP (Ffile_directory_p (filename))
&& NILP (Ffile_symlink_p (filename)))
@@ -8324,7 +8331,10 @@ DEFUN ("system-move-file-to-trash", Fsystem_move_file_to_trash,
| FOF_NOERRORUI | FOF_NO_CONNECTED_ELEMENTS;
file_op_w.fAnyOperationsAborted = FALSE;
- result = SHFileOperationW (&file_op_w);
+ /* This is stated to exist on all versions of Windows NT Emacs
+ supports. */
+ eassert (pfnSHFileOperationW);
+ result = (*pfnSHFileOperationW) (&file_op_w);
}
else
{
@@ -8389,6 +8399,10 @@ If optional parameter FRAME is not specified, use selected frame. */)
return Qnil;
}
+#ifndef CYGWIN
+static BOOL (WINAPI *pfnShellExecuteExW) (LPSHELLEXECUTEINFOW);
+#endif /* !CYGWIN */
+
DEFUN ("w32-shell-execute", Fw32_shell_execute, Sw32_shell_execute, 2, 4, 0,
doc: /* Get Windows to perform OPERATION on DOCUMENT.
This is a wrapper around the ShellExecute system function, which
@@ -8539,6 +8553,9 @@ a ShowWindow flag:
const int file_url_len = sizeof (file_url_str) - 1;
int doclen;
+ /* Required on Windows 9X. */
+ maybe_load_unicows_dll ();
+
if (strncmp (SSDATA (document), file_url_str, file_url_len) == 0)
{
/* Passing "file:///" URLs to ShellExecute causes shlwapi.dll to
@@ -8598,7 +8615,7 @@ a ShowWindow flag:
doc_w = xmalloc (doclen * sizeof (wchar_t));
pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
SSDATA (document), -1, doc_w, doclen);
- if (use_unicode)
+ if (use_unicode && pfnShellExecuteExW)
{
wchar_t current_dir_w[MAX_PATH];
SHELLEXECUTEINFOW shexinfo_w;
@@ -8650,7 +8667,7 @@ a ShowWindow flag:
shexinfo_w.lpDirectory = current_dir_w;
shexinfo_w.nShow =
(FIXNUMP (show_flag) ? XFIXNUM (show_flag) : SW_SHOWDEFAULT);
- success = ShellExecuteExW (&shexinfo_w);
+ success = (*pfnShellExecuteExW) (&shexinfo_w);
xfree (doc_w);
}
else
@@ -9121,6 +9138,7 @@ and width values are in pixels.
menu_bar.cbSize = sizeof (menu_bar);
menu_bar.rcBar.right = menu_bar.rcBar.left = 0;
menu_bar.rcBar.top = menu_bar.rcBar.bottom = 0;
+
GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &menu_bar);
single_menu_bar_height = GetSystemMetrics (SM_CYMENU);
wrapped_menu_bar_height = GetSystemMetrics (SM_CYMENUSIZE);
@@ -10007,6 +10025,8 @@ Internal use only. */)
#if defined WINDOWSNT && !defined HAVE_DBUS
+static BOOL (WINAPI *pfnShell_NotifyIconW) (DWORD, PNOTIFYICONDATAW);
+
/***********************************************************************
Tray notifications
***********************************************************************/
@@ -10273,7 +10293,7 @@ add_tray_notification (struct frame *f, const char *icon, const char *tip,
}
}
- if (!Shell_NotifyIconW (NIM_ADD, (PNOTIFYICONDATAW)&nidw))
+ if (!(*pfnShell_NotifyIconW) (NIM_ADD, (PNOTIFYICONDATAW)&nidw))
{
/* GetLastError returns meaningless results when
Shell_NotifyIcon fails. */
@@ -10305,7 +10325,7 @@ delete_tray_notification (struct frame *f, int id)
nidw.hWnd = FRAME_W32_WINDOW (f);
nidw.uID = id;
- if (!Shell_NotifyIconW (NIM_DELETE, (PNOTIFYICONDATAW)&nidw))
+ if (!(*pfnShell_NotifyIconW) (NIM_DELETE, (PNOTIFYICONDATAW)&nidw))
{
/* GetLastError returns meaningless results when
Shell_NotifyIcon fails. */
@@ -10372,8 +10392,8 @@ The following parameters are supported:
characters long, and will be truncated if it's longer.
Note that versions of Windows before W2K support only `:icon' and `:tip'.
-You can pass the other parameters, but they will be ignored on those
-old systems.
+You can pass the other parameters, but they will be ignored on
+those old systems.
There can be at most one active notification at any given time. An
active notification must be removed by calling `w32-notification-close'
@@ -10389,7 +10409,10 @@ usage: (w32-notification-notify &rest PARAMS) */)
enum NI_Severity severity;
unsigned timeout = 0;
- if (nargs == 0)
+ /* Required on Windows 9X. */
+ maybe_load_unicows_dll ();
+
+ if (nargs == 0 || !pfnShell_NotifyIconW)
return Qnil;
arg_plist = Flist (nargs, args);
@@ -10448,7 +10471,7 @@ DEFUN ("w32-notification-close",
{
struct frame *f = SELECTED_FRAME ();
- if (FIXNUMP (id))
+ if (FIXNUMP (id) && !pfnShell_NotifyIconW)
delete_tray_notification (f, XFIXNUM (id));
return Qnil;
@@ -11499,7 +11522,7 @@ globals_of_w32fns (void)
get_proc_addr (wtsapi32_lib, "WTSRegisterSessionNotification");
WTSUnRegisterSessionNotification_fn = (WTSUnRegisterSessionNotification_Proc)
get_proc_addr (wtsapi32_lib, "WTSUnRegisterSessionNotification");
-#endif
+#endif /* WINDOWSNT */
/* Support OS dark mode on Windows 10 version 1809 and higher.
See `w32_applytheme' which uses appropriate APIs per version of Windows.
@@ -11580,6 +11603,32 @@ Changing the value takes effect only for frames created after the change. */);
syms_of_w32uniscribe ();
}
+#ifdef WINDOWSNT
+
+/* Initialize pointers to functions whose real implementations exist in
+ UNICOWS.DLL on Windows 9X. UNICOWS should be a pointer to a loaded
+ handle referencing UNICOWS.DLL, or NULL on Windows NT systems. */
+
+void
+load_unicows_dll_for_w32fns (HMODULE unicows)
+{
+ if (!unicows)
+ /* The functions following are defined by SHELL32.DLL onw Windows
+ NT. */
+ unicows = GetModuleHandle ("shell32");
+
+ pfnSHFileOperationW
+ = (void *) get_proc_addr (unicows, "SHFileOperationW");
+ pfnShellExecuteExW
+ = (void *) get_proc_addr (unicows, "ShellExecuteExW");
+#ifndef HAVE_DBUS
+ pfnShell_NotifyIconW
+ = (void *) get_proc_addr (unicows, "Shell_NotifyIconW");
+#endif /* !HAVE_DBUS */
+}
+
+#endif /* WINDOWSNT */
+
#ifdef NTGUI_UNICODE
Lisp_Object
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 {
/* Used for communicating notifications to the main thread. */
struct notifications_set *notifications_set_head;
+/* Function pointers. */
+static BOOL (WINAPI *pfnReadDirectoryChangesW) (HANDLE, PVOID, DWORD, BOOL,
+ DWORD, PDWORD, LPOVERLAPPED,
+ LPOVERLAPPED_COMPLETION_ROUTINE);
static Lisp_Object watch_list;
/* 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)
/* Calling ReadDirectoryChangesW quickly to watch again for new
notifications. */
- if (!ReadDirectoryChangesW (dirwatch->dir, dirwatch->buf,
- DIRWATCH_BUFFER_SIZE, dirwatch->subtree,
- dirwatch->filter, &_bytes, dirwatch->io_info,
- watch_completion))
+ if (!(*pfnReadDirectoryChangesW) (dirwatch->dir, dirwatch->buf,
+ DIRWATCH_BUFFER_SIZE, dirwatch->subtree,
+ dirwatch->filter, &_bytes,
+ dirwatch->io_info, watch_completion))
{
DebPrint (("ReadDirectoryChangesW error: %lu\n", GetLastError ()));
/* 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)
/* If we were asked to terminate the thread, then fire the event. */
if (terminate)
- SetEvent(dirwatch->terminate);
+ SetEvent (dirwatch->terminate);
}
/* Worker routine for the watch thread. */
@@ -284,10 +288,10 @@ watch_worker (LPVOID arg)
if (dirwatch->dir)
{
- bErr = ReadDirectoryChangesW (dirwatch->dir, dirwatch->buf,
- DIRWATCH_BUFFER_SIZE, dirwatch->subtree,
- dirwatch->filter, &_bytes,
- dirwatch->io_info, watch_completion);
+ bErr = (*pfnReadDirectoryChangesW) (dirwatch->dir, dirwatch->buf,
+ DIRWATCH_BUFFER_SIZE, dirwatch->subtree,
+ dirwatch->filter, &_bytes,
+ dirwatch->io_info, watch_completion);
if (!bErr)
{
DebPrint (("ReadDirectoryChangesW: %lu\n", GetLastError ()));
@@ -436,7 +440,7 @@ remove_watch (struct notification *dirwatch)
DebPrint (("QueueUserAPC failed (%lu)!\n", GetLastError ()));
/* We also signal the thread that it can terminate. */
- SetEvent(dirwatch->terminate);
+ SetEvent (dirwatch->terminate);
/* Wait for the thread to exit. FIXME: is there a better method
that is not overly complex? */
@@ -466,7 +470,7 @@ remove_watch (struct notification *dirwatch)
CloseHandle (dirwatch->thr);
dirwatch->thr = NULL;
}
- CloseHandle(dirwatch->terminate);
+ CloseHandle (dirwatch->terminate);
xfree (dirwatch->buf);
xfree (dirwatch->io_info);
xfree (dirwatch->watchee);
@@ -575,6 +579,8 @@ generate notifications correctly, though. */)
report_file_notify_error ("Watching filesystem events is not supported",
Qnil);
}
+ else
+ eassert (pfnReadDirectoryChangesW);
/* filenotify.el always passes us a directory, either the parent
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'. */)
if (!NILP (watch_object))
{
watch_list = Fdelete (watch_object, watch_list);
- dirwatch = (struct notification *)xmint_pointer (watch_descriptor);
+ dirwatch = (struct notification *) xmint_pointer (watch_descriptor);
if (w32_valid_pointer_p (dirwatch, sizeof(struct notification)))
status = remove_watch (dirwatch);
}
@@ -687,7 +693,7 @@ watch by calling `w32notify-rm-watch' also makes it invalid. */)
if (!NILP (watch_object))
{
struct notification *dirwatch =
- (struct notification *)xmint_pointer (watch_descriptor);
+ (struct notification *) xmint_pointer (watch_descriptor);
if (w32_valid_pointer_p (dirwatch, sizeof(struct notification))
&& dirwatch->dir != NULL)
return Qt;
@@ -699,6 +705,16 @@ watch by calling `w32notify-rm-watch' also makes it invalid. */)
void
globals_of_w32notify (void)
{
+ HANDLE kernel32 = GetModuleHandle ("kernel32");
+
+ /* Initialize pointers to IO functions that provide file
+ notifications. In the event that these are absent, no harm will be
+ done, since their absence indicates that Emacs is running on
+ Windows 9X, where file notifications are unavailable at the
+ outset. */
+ pfnReadDirectoryChangesW
+ = (void *) get_proc_addr (kernel32, "ReadDirectoryChangesW");
+
watch_list = Qnil;
}
diff --git a/src/w32uniscribe.c b/src/w32uniscribe.c
index dacd6dd766e..471bdf544d8 100644
--- a/src/w32uniscribe.c
+++ b/src/w32uniscribe.c
@@ -109,6 +109,31 @@ memq_no_quit (Lisp_Object elt, Lisp_Object list)
}
+/* Uniscribe function pointers. */
+static HRESULT (WINAPI * pfnScriptItemize) (const WCHAR *,
+ int,
+ int,
+ const SCRIPT_CONTROL *,
+ const SCRIPT_STATE *,
+ SCRIPT_ITEM *, int *);
+static HRESULT (WINAPI * pfnScriptShape) (HDC, SCRIPT_CACHE *,
+ const WCHAR *,
+ int, int, SCRIPT_ANALYSIS *,
+ WORD *, WORD *, SCRIPT_VISATTR *,
+ int *);
+static HRESULT (WINAPI * pfnScriptPlace) (HDC, SCRIPT_CACHE *,
+ const WORD *, int,
+ const SCRIPT_VISATTR *,
+ SCRIPT_ANALYSIS *,
+ int *, GOFFSET *, ABC *);
+static HRESULT (WINAPI * pfnScriptGetGlyphABCWidth) (HDC, SCRIPT_CACHE *,
+ WORD, ABC *);
+static HRESULT (WINAPI * pfnScriptFreeCache) (SCRIPT_CACHE *);
+static HRESULT (WINAPI * pfnScriptGetCMap) (HDC, SCRIPT_CACHE *,
+ const WCHAR *,
+ int, DWORD, WORD *);
+
+
/* Font backend interface implementation. */
static Lisp_Object
uniscribe_list (struct frame *f, Lisp_Object font_spec)
@@ -202,7 +227,7 @@ uniscribe_close (struct font *font)
else
#endif
if (uniscribe_font->cache)
- ScriptFreeCache ((SCRIPT_CACHE) &(uniscribe_font->cache));
+ (*pfnScriptFreeCache) ((SCRIPT_CACHE) &(uniscribe_font->cache));
uniscribe_font->cache = NULL;
@@ -320,8 +345,8 @@ uniscribe_shape (Lisp_Object lgstring, Lisp_Object direction)
max_items = 2;
items = xmalloc (sizeof (SCRIPT_ITEM) * max_items + 1);
- while ((result = ScriptItemize (chars, nchars, max_items, NULL, NULL,
- items, &nitems)) == E_OUTOFMEMORY)
+ while ((result = (*pfnScriptItemize) (chars, nchars, max_items, NULL, NULL,
+ items, &nitems)) == E_OUTOFMEMORY)
{
/* If that wasn't enough, keep trying with one more run. */
max_items++;
@@ -344,17 +369,18 @@ uniscribe_shape (Lisp_Object lgstring, Lisp_Object direction)
{
int nglyphs, nchars_in_run;
nchars_in_run = items[i+1].iCharPos - items[i].iCharPos;
- /* Force ScriptShape to generate glyphs in the same order as
+ /* Force (*pfnScriptShape) to generate glyphs in the same order as
they are in the input LGSTRING, which is in the logical
order. */
items[i].a.fLogicalOrder = 1;
/* Context may be NULL here, in which case the cache should be
used without needing to select the font. */
- result = ScriptShape (context, (SCRIPT_CACHE) &(uniscribe_font->cache),
- chars + items[i].iCharPos, nchars_in_run,
- max_glyphs - done_glyphs, &(items[i].a),
- glyphs, clusters, attributes, &nglyphs);
+ result
+ = (*pfnScriptShape) (context, (SCRIPT_CACHE) &(uniscribe_font->cache),
+ chars + items[i].iCharPos, nchars_in_run,
+ max_glyphs - done_glyphs, &(items[i].a),
+ glyphs, clusters, attributes, &nglyphs);
if (result == E_PENDING && !context)
{
@@ -365,10 +391,12 @@ uniscribe_shape (Lisp_Object lgstring, Lisp_Object direction)
context = get_frame_dc (f);
old_font = SelectObject (context, FONT_HANDLE (font));
- result = ScriptShape (context, (SCRIPT_CACHE) &(uniscribe_font->cache),
- chars + items[i].iCharPos, nchars_in_run,
- max_glyphs - done_glyphs, &(items[i].a),
- glyphs, clusters, attributes, &nglyphs);
+ result
+ = (*pfnScriptShape) (context,
+ (SCRIPT_CACHE) &(uniscribe_font->cache),
+ chars + items[i].iCharPos, nchars_in_run,
+ max_glyphs - done_glyphs, &(items[i].a),
+ glyphs, clusters, attributes, &nglyphs);
}
if (result == E_OUTOFMEMORY)
@@ -390,9 +418,11 @@ uniscribe_shape (Lisp_Object lgstring, Lisp_Object direction)
}
else
{
- result = ScriptPlace (context, (SCRIPT_CACHE) &(uniscribe_font->cache),
- glyphs, nglyphs, attributes, &(items[i].a),
- advances, offsets, &overall_metrics);
+ result
+ = (*pfnScriptPlace) (context,
+ (SCRIPT_CACHE) &(uniscribe_font->cache),
+ glyphs, nglyphs, attributes, &(items[i].a),
+ advances, offsets, &overall_metrics);
if (result == E_PENDING && !context)
{
/* Cache not complete... */
@@ -400,10 +430,11 @@ uniscribe_shape (Lisp_Object lgstring, Lisp_Object direction)
context = get_frame_dc (f);
old_font = SelectObject (context, FONT_HANDLE (font));
- result = ScriptPlace (context,
- (SCRIPT_CACHE) &(uniscribe_font->cache),
- glyphs, nglyphs, attributes, &(items[i].a),
- advances, offsets, &overall_metrics);
+ result
+ = (*pfnScriptPlace) (context,
+ (SCRIPT_CACHE) &(uniscribe_font->cache),
+ glyphs, nglyphs, attributes, &(items[i].a),
+ advances, offsets, &overall_metrics);
}
if (SUCCEEDED (result))
{
@@ -469,7 +500,7 @@ uniscribe_shape (Lisp_Object lgstring, Lisp_Object direction)
then updated for each successive glyph in the
grapheme cluster. */
/* FIXME: Should we use DIRECTION here instead
- of what ScriptItemize guessed? */
+ of what (*pfnScriptItemize) guessed? */
if (items[i].a.fRTL)
{
int j1 = j;
@@ -496,7 +527,7 @@ uniscribe_shape (Lisp_Object lgstring, Lisp_Object direction)
LGLYPH_SET_ASCENT (lglyph, font->ascent);
LGLYPH_SET_DESCENT (lglyph, font->descent);
- result = ScriptGetGlyphABCWidth
+ result = (*pfnScriptGetGlyphABCWidth)
(context, (SCRIPT_CACHE) &(uniscribe_font->cache),
glyphs[j], &char_metric);
if (result == E_PENDING && !context)
@@ -505,7 +536,7 @@ uniscribe_shape (Lisp_Object lgstring, Lisp_Object direction)
f = XFRAME (selected_frame);
context = get_frame_dc (f);
old_font = SelectObject (context, FONT_HANDLE (font));
- result = ScriptGetGlyphABCWidth
+ result = (*pfnScriptGetGlyphABCWidth)
(context, (SCRIPT_CACHE) &(uniscribe_font->cache),
glyphs[j], &char_metric);
}
@@ -624,7 +655,8 @@ uniscribe_encode_char (struct font *font, int c)
convert surrogate pairs to glyph indexes correctly. */
{
items = (SCRIPT_ITEM *) alloca (sizeof (SCRIPT_ITEM) * 2 + 1);
- if (SUCCEEDED (ScriptItemize (ch, len, 2, NULL, NULL, items, &nitems)))
+ if (SUCCEEDED ((*pfnScriptItemize) (ch, len, 2, NULL, NULL, items,
+ &nitems)))
{
HRESULT result;
/* Surrogates seem to need 2 here, even though only one glyph is
@@ -635,14 +667,14 @@ uniscribe_encode_char (struct font *font, int c)
SCRIPT_VISATTR attrs[2];
int nglyphs;
- /* Force ScriptShape to generate glyphs in the logical
+ /* Force (*pfnScriptShape) to generate glyphs in the logical
order. */
items[0].a.fLogicalOrder = 1;
- result = ScriptShape (context,
- (SCRIPT_CACHE) &(uniscribe_font->cache),
- ch, len, 2, &(items[0].a),
- glyphs, clusters, attrs, &nglyphs);
+ result = (*pfnScriptShape) (context,
+ (SCRIPT_CACHE) &(uniscribe_font->cache),
+ ch, len, 2, &(items[0].a),
+ glyphs, clusters, attrs, &nglyphs);
if (result == E_PENDING)
{
@@ -651,10 +683,11 @@ uniscribe_encode_char (struct font *font, int c)
f = XFRAME (selected_frame);
context = get_frame_dc (f);
old_font = SelectObject (context, FONT_HANDLE (font));
- result = ScriptShape (context,
- (SCRIPT_CACHE) &(uniscribe_font->cache),
- ch, len, 2, &(items[0].a),
- glyphs, clusters, attrs, &nglyphs);
+ result
+ = (*pfnScriptShape) (context,
+ (SCRIPT_CACHE) &(uniscribe_font->cache),
+ ch, len, 2, &(items[0].a),
+ glyphs, clusters, attrs, &nglyphs);
}
if (SUCCEEDED (result) && nglyphs == 1)
@@ -670,9 +703,10 @@ uniscribe_encode_char (struct font *font, int c)
when shaped. But we still need the return from here
to be valid for the shaping engine to be invoked
later. */
- result = ScriptGetCMap (context,
- (SCRIPT_CACHE) &(uniscribe_font->cache),
- ch, len, 0, glyphs);
+ result
+ = (*pfnScriptGetCMap) (context,
+ (SCRIPT_CACHE) &(uniscribe_font->cache),
+ ch, len, 0, glyphs);
if (SUCCEEDED (result) && glyphs[0])
code = glyphs[0];
}
@@ -942,7 +976,7 @@ uniscribe_check_otf_1 (HDC context, Lisp_Object script, Lisp_Object lang,
no_support:
if (cache)
- ScriptFreeCache (&cache);
+ (*pfnScriptFreeCache) (&cache);
return ret;
}
@@ -1505,11 +1539,43 @@ syms_of_w32uniscribe_for_pdumper (void)
return;
/* Don't register if Uniscribe is not available. */
- HMODULE uniscribe = GetModuleHandle ("usp10");
+ HMODULE uniscribe;
+
+#ifdef WINDOWSNT
+ uniscribe = LoadLibrary ("usp10.dll");
if (!uniscribe)
return;
+ pfnScriptItemize = (void *) get_proc_addr (uniscribe, "ScriptItemize");
+ pfnScriptShape = (void *) get_proc_addr (uniscribe, "ScriptShape");
+ pfnScriptPlace = (void *) get_proc_addr (uniscribe, "ScriptPlace");
+ pfnScriptGetGlyphABCWidth
+ = (void *) get_proc_addr (uniscribe, "ScriptGetGlyphABCWidth");
+ pfnScriptFreeCache
+ = (void *) get_proc_addr (uniscribe, "ScriptFreeCache");
+ pfnScriptGetCMap
+ = (void *) get_proc_addr (uniscribe, "ScriptGetCMap");
+ if (!pfnScriptItemize || !pfnScriptShape || !pfnScriptPlace
+ || !pfnScriptGetGlyphABCWidth || !pfnScriptFreeCache
+ || !pfnScriptGetCMap)
+ {
+ FreeLibrary (uniscribe);
+ return;
+ }
+#else /* Cygwin */
+ uniscribe = GetModuleHandle ("usp10.dll");
+ if (!uniscribe)
+ return;
+
+ pfnScriptItemize = &ScriptItemize;
+ pfnScriptShape = &ScriptShape;
+ pfnScriptPlace = &ScriptPlace;
+ pfnScriptGetGlyphABCWidth = &ScriptGetGlyphABCWidth;
+ pfnScriptFreeCache = &ScriptFreeCache;
+ pfnScriptGetCMap = &ScriptGetCMap;
+
uniscribe_available = 1;
+#endif /* Cygwin */
register_font_driver (&uniscribe_font_driver, NULL);