diff options
| author | Po Lu | 2024-06-30 23:12:09 +0800 |
|---|---|---|
| committer | Po Lu | 2024-06-30 23:12:09 +0800 |
| commit | 7c8d4e96ba6db19bdca20a87bafed024a84eb517 (patch) | |
| tree | fbab938bf8f25d5634912a58260f9d1c517d6737 /src | |
| parent | 7f89fe8a342d7b4e8800d0ef333fb6759b58ccb5 (diff) | |
| parent | 64851d101a854e00c68f3e9259d70777e7b26cb2 (diff) | |
| download | emacs-7c8d4e96ba6db19bdca20a87bafed024a84eb517.tar.gz emacs-7c8d4e96ba6db19bdca20a87bafed024a84eb517.zip | |
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.c | 8 | ||||
| -rw-r--r-- | src/w32.c | 2 | ||||
| -rw-r--r-- | src/w32.h | 1 | ||||
| -rw-r--r-- | src/w32fns.c | 79 | ||||
| -rw-r--r-- | src/w32notify.c | 42 | ||||
| -rw-r--r-- | src/w32uniscribe.c | 140 |
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) | |||
| 1395 | the additional call here is harmless.) */ | 1395 | the additional call here is harmless.) */ |
| 1396 | cache_system_info (); | 1396 | cache_system_info (); |
| 1397 | #ifdef WINDOWSNT | 1397 | #ifdef WINDOWSNT |
| 1398 | /* This must be called to initialize w32_unicode_filenames and | ||
| 1399 | is_windows_9x prior to w32_init_current_directory. */ | ||
| 1400 | globals_of_w32 (); | ||
| 1401 | |||
| 1398 | /* On Windows 9X, we have to load UNICOWS.DLL as early as possible, | 1402 | /* On Windows 9X, we have to load UNICOWS.DLL as early as possible, |
| 1399 | to have non-stub implementations of APIs we need to convert file | 1403 | to have non-stub implementations of APIs we need to convert file |
| 1400 | names between UTF-8 and the system's ANSI codepage. */ | 1404 | names between UTF-8 and the system's ANSI codepage. */ |
| @@ -1506,11 +1510,10 @@ main (int argc, char **argv) | |||
| 1506 | } | 1510 | } |
| 1507 | } | 1511 | } |
| 1508 | #endif | 1512 | #endif |
| 1509 | |||
| 1510 | emacs_wd = emacs_get_current_dir_name (); | 1513 | emacs_wd = emacs_get_current_dir_name (); |
| 1511 | #ifdef WINDOWSNT | 1514 | #ifdef WINDOWSNT |
| 1512 | initial_wd = emacs_wd; | 1515 | initial_wd = emacs_wd; |
| 1513 | #endif | 1516 | #endif /* WINDOWSNT */ |
| 1514 | #ifdef HAVE_PDUMPER | 1517 | #ifdef HAVE_PDUMPER |
| 1515 | if (dumped_with_pdumper_p ()) | 1518 | if (dumped_with_pdumper_p ()) |
| 1516 | pdumper_record_wd (emacs_wd); | 1519 | pdumper_record_wd (emacs_wd); |
| @@ -2165,7 +2168,6 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem | |||
| 2165 | init_atimer (); | 2168 | init_atimer (); |
| 2166 | 2169 | ||
| 2167 | #ifdef WINDOWSNT | 2170 | #ifdef WINDOWSNT |
| 2168 | globals_of_w32 (); | ||
| 2169 | #ifdef HAVE_W32NOTIFY | 2171 | #ifdef HAVE_W32NOTIFY |
| 2170 | globals_of_w32notify (); | 2172 | globals_of_w32notify (); |
| 2171 | #endif | 2173 | #endif |
| @@ -10624,6 +10624,7 @@ maybe_load_unicows_dll (void) | |||
| 10624 | pWideCharToMultiByte = (WideCharToMultiByte_Proc) | 10624 | pWideCharToMultiByte = (WideCharToMultiByte_Proc) |
| 10625 | get_proc_addr (ret, "WideCharToMultiByte"); | 10625 | get_proc_addr (ret, "WideCharToMultiByte"); |
| 10626 | multiByteToWideCharFlags = MB_ERR_INVALID_CHARS; | 10626 | multiByteToWideCharFlags = MB_ERR_INVALID_CHARS; |
| 10627 | load_unicows_dll_for_w32fns (ret); | ||
| 10627 | return ret; | 10628 | return ret; |
| 10628 | } | 10629 | } |
| 10629 | else | 10630 | else |
| @@ -10658,6 +10659,7 @@ maybe_load_unicows_dll (void) | |||
| 10658 | multiByteToWideCharFlags = 0; | 10659 | multiByteToWideCharFlags = 0; |
| 10659 | else | 10660 | else |
| 10660 | multiByteToWideCharFlags = MB_ERR_INVALID_CHARS; | 10661 | multiByteToWideCharFlags = MB_ERR_INVALID_CHARS; |
| 10662 | load_unicows_dll_for_w32fns (NULL); | ||
| 10661 | return LoadLibrary ("Gdi32.dll"); | 10663 | return LoadLibrary ("Gdi32.dll"); |
| 10662 | } | 10664 | } |
| 10663 | } | 10665 | } |
| @@ -170,6 +170,7 @@ extern void release_listen_threads (void); | |||
| 170 | extern void init_ntproc (int); | 170 | extern void init_ntproc (int); |
| 171 | extern void term_ntproc (int); | 171 | extern void term_ntproc (int); |
| 172 | extern HANDLE maybe_load_unicows_dll (void); | 172 | extern HANDLE maybe_load_unicows_dll (void); |
| 173 | extern void load_unicows_dll_for_w32fns (HMODULE); | ||
| 173 | extern void globals_of_w32 (void); | 174 | extern void globals_of_w32 (void); |
| 174 | 175 | ||
| 175 | extern void term_timers (void); | 176 | 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) | |||
| 2612 | } | 2612 | } |
| 2613 | 2613 | ||
| 2614 | #ifdef WINDOWSNT | 2614 | #ifdef WINDOWSNT |
| 2615 | |||
| 2615 | /* The Windows keyboard hook callback. */ | 2616 | /* The Windows keyboard hook callback. */ |
| 2616 | static LRESULT CALLBACK | 2617 | static LRESULT CALLBACK |
| 2617 | funhook (int code, WPARAM w, LPARAM l) | 2618 | funhook (int code, WPARAM w, LPARAM l) |
| @@ -2688,8 +2689,8 @@ funhook (int code, WPARAM w, LPARAM l) | |||
| 2688 | can prevent this by setting the | 2689 | can prevent this by setting the |
| 2689 | w32-pass-[lr]window-to-system variable to | 2690 | w32-pass-[lr]window-to-system variable to |
| 2690 | NIL. */ | 2691 | NIL. */ |
| 2691 | if ((hs->vkCode == VK_LWIN && !NILP (Vw32_pass_lwindow_to_system)) || | 2692 | if ((hs->vkCode == VK_LWIN && !NILP (Vw32_pass_lwindow_to_system)) |
| 2692 | (hs->vkCode == VK_RWIN && !NILP (Vw32_pass_rwindow_to_system))) | 2693 | || (hs->vkCode == VK_RWIN && !NILP (Vw32_pass_rwindow_to_system))) |
| 2693 | { | 2694 | { |
| 2694 | /* Not prevented - Simulate the keypress to the system. */ | 2695 | /* Not prevented - Simulate the keypress to the system. */ |
| 2695 | memset (inputs, 0, sizeof (inputs)); | 2696 | memset (inputs, 0, sizeof (inputs)); |
| @@ -2704,7 +2705,6 @@ funhook (int code, WPARAM w, LPARAM l) | |||
| 2704 | inputs[1].ki.dwFlags | 2705 | inputs[1].ki.dwFlags |
| 2705 | = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP; | 2706 | = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP; |
| 2706 | inputs[1].ki.time = 0; | 2707 | inputs[1].ki.time = 0; |
| 2707 | SendInput (2, inputs, sizeof (INPUT)); | ||
| 2708 | } | 2708 | } |
| 2709 | else if (focus != NULL) | 2709 | else if (focus != NULL) |
| 2710 | { | 2710 | { |
| @@ -6150,7 +6150,8 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, | |||
| 6150 | if (harfbuzz_available) | 6150 | if (harfbuzz_available) |
| 6151 | register_font_driver (&harfbuzz_font_driver, f); | 6151 | register_font_driver (&harfbuzz_font_driver, f); |
| 6152 | #endif | 6152 | #endif |
| 6153 | register_font_driver (&uniscribe_font_driver, f); | 6153 | if (uniscribe_available) |
| 6154 | register_font_driver (&uniscribe_font_driver, f); | ||
| 6154 | register_font_driver (&w32font_driver, f); | 6155 | register_font_driver (&w32font_driver, f); |
| 6155 | 6156 | ||
| 6156 | gui_default_parameter (f, parameters, Qfont_backend, Qnil, | 6157 | gui_default_parameter (f, parameters, Qfont_backend, Qnil, |
| @@ -7227,7 +7228,8 @@ w32_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms) | |||
| 7227 | if (harfbuzz_available) | 7228 | if (harfbuzz_available) |
| 7228 | register_font_driver (&harfbuzz_font_driver, f); | 7229 | register_font_driver (&harfbuzz_font_driver, f); |
| 7229 | #endif | 7230 | #endif |
| 7230 | register_font_driver (&uniscribe_font_driver, f); | 7231 | if (uniscribe_available) |
| 7232 | register_font_driver (&uniscribe_font_driver, f); | ||
| 7231 | register_font_driver (&w32font_driver, f); | 7233 | register_font_driver (&w32font_driver, f); |
| 7232 | 7234 | ||
| 7233 | gui_default_parameter (f, parms, Qfont_backend, Qnil, | 7235 | 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, | |||
| 8265 | 8267 | ||
| 8266 | 8268 | ||
| 8267 | #ifdef WINDOWSNT | 8269 | #ifdef WINDOWSNT |
| 8270 | static int (WINAPI *pfnSHFileOperationW) (LPSHFILEOPSTRUCTW); | ||
| 8271 | |||
| 8268 | /* Moving files to the system recycle bin. | 8272 | /* Moving files to the system recycle bin. |
| 8269 | Used by `move-file-to-trash' instead of the default moving to ~/.Trash */ | 8273 | Used by `move-file-to-trash' instead of the default moving to ~/.Trash */ |
| 8270 | DEFUN ("system-move-file-to-trash", Fsystem_move_file_to_trash, | 8274 | 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, | |||
| 8276 | Lisp_Object encoded_file; | 8280 | Lisp_Object encoded_file; |
| 8277 | Lisp_Object operation; | 8281 | Lisp_Object operation; |
| 8278 | 8282 | ||
| 8283 | /* Required on Windows 9X. */ | ||
| 8284 | maybe_load_unicows_dll (); | ||
| 8285 | |||
| 8279 | operation = Qdelete_file; | 8286 | operation = Qdelete_file; |
| 8280 | if (!NILP (Ffile_directory_p (filename)) | 8287 | if (!NILP (Ffile_directory_p (filename)) |
| 8281 | && NILP (Ffile_symlink_p (filename))) | 8288 | && NILP (Ffile_symlink_p (filename))) |
| @@ -8324,7 +8331,10 @@ DEFUN ("system-move-file-to-trash", Fsystem_move_file_to_trash, | |||
| 8324 | | FOF_NOERRORUI | FOF_NO_CONNECTED_ELEMENTS; | 8331 | | FOF_NOERRORUI | FOF_NO_CONNECTED_ELEMENTS; |
| 8325 | file_op_w.fAnyOperationsAborted = FALSE; | 8332 | file_op_w.fAnyOperationsAborted = FALSE; |
| 8326 | 8333 | ||
| 8327 | result = SHFileOperationW (&file_op_w); | 8334 | /* This is stated to exist on all versions of Windows NT Emacs |
| 8335 | supports. */ | ||
| 8336 | eassert (pfnSHFileOperationW); | ||
| 8337 | result = (*pfnSHFileOperationW) (&file_op_w); | ||
| 8328 | } | 8338 | } |
| 8329 | else | 8339 | else |
| 8330 | { | 8340 | { |
| @@ -8389,6 +8399,10 @@ If optional parameter FRAME is not specified, use selected frame. */) | |||
| 8389 | return Qnil; | 8399 | return Qnil; |
| 8390 | } | 8400 | } |
| 8391 | 8401 | ||
| 8402 | #ifndef CYGWIN | ||
| 8403 | static BOOL (WINAPI *pfnShellExecuteExW) (LPSHELLEXECUTEINFOW); | ||
| 8404 | #endif /* !CYGWIN */ | ||
| 8405 | |||
| 8392 | DEFUN ("w32-shell-execute", Fw32_shell_execute, Sw32_shell_execute, 2, 4, 0, | 8406 | DEFUN ("w32-shell-execute", Fw32_shell_execute, Sw32_shell_execute, 2, 4, 0, |
| 8393 | doc: /* Get Windows to perform OPERATION on DOCUMENT. | 8407 | doc: /* Get Windows to perform OPERATION on DOCUMENT. |
| 8394 | This is a wrapper around the ShellExecute system function, which | 8408 | This is a wrapper around the ShellExecute system function, which |
| @@ -8539,6 +8553,9 @@ a ShowWindow flag: | |||
| 8539 | const int file_url_len = sizeof (file_url_str) - 1; | 8553 | const int file_url_len = sizeof (file_url_str) - 1; |
| 8540 | int doclen; | 8554 | int doclen; |
| 8541 | 8555 | ||
| 8556 | /* Required on Windows 9X. */ | ||
| 8557 | maybe_load_unicows_dll (); | ||
| 8558 | |||
| 8542 | if (strncmp (SSDATA (document), file_url_str, file_url_len) == 0) | 8559 | if (strncmp (SSDATA (document), file_url_str, file_url_len) == 0) |
| 8543 | { | 8560 | { |
| 8544 | /* Passing "file:///" URLs to ShellExecute causes shlwapi.dll to | 8561 | /* Passing "file:///" URLs to ShellExecute causes shlwapi.dll to |
| @@ -8598,7 +8615,7 @@ a ShowWindow flag: | |||
| 8598 | doc_w = xmalloc (doclen * sizeof (wchar_t)); | 8615 | doc_w = xmalloc (doclen * sizeof (wchar_t)); |
| 8599 | pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags, | 8616 | pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags, |
| 8600 | SSDATA (document), -1, doc_w, doclen); | 8617 | SSDATA (document), -1, doc_w, doclen); |
| 8601 | if (use_unicode) | 8618 | if (use_unicode && pfnShellExecuteExW) |
| 8602 | { | 8619 | { |
| 8603 | wchar_t current_dir_w[MAX_PATH]; | 8620 | wchar_t current_dir_w[MAX_PATH]; |
| 8604 | SHELLEXECUTEINFOW shexinfo_w; | 8621 | SHELLEXECUTEINFOW shexinfo_w; |
| @@ -8650,7 +8667,7 @@ a ShowWindow flag: | |||
| 8650 | shexinfo_w.lpDirectory = current_dir_w; | 8667 | shexinfo_w.lpDirectory = current_dir_w; |
| 8651 | shexinfo_w.nShow = | 8668 | shexinfo_w.nShow = |
| 8652 | (FIXNUMP (show_flag) ? XFIXNUM (show_flag) : SW_SHOWDEFAULT); | 8669 | (FIXNUMP (show_flag) ? XFIXNUM (show_flag) : SW_SHOWDEFAULT); |
| 8653 | success = ShellExecuteExW (&shexinfo_w); | 8670 | success = (*pfnShellExecuteExW) (&shexinfo_w); |
| 8654 | xfree (doc_w); | 8671 | xfree (doc_w); |
| 8655 | } | 8672 | } |
| 8656 | else | 8673 | else |
| @@ -9121,6 +9138,7 @@ and width values are in pixels. | |||
| 9121 | menu_bar.cbSize = sizeof (menu_bar); | 9138 | menu_bar.cbSize = sizeof (menu_bar); |
| 9122 | menu_bar.rcBar.right = menu_bar.rcBar.left = 0; | 9139 | menu_bar.rcBar.right = menu_bar.rcBar.left = 0; |
| 9123 | menu_bar.rcBar.top = menu_bar.rcBar.bottom = 0; | 9140 | menu_bar.rcBar.top = menu_bar.rcBar.bottom = 0; |
| 9141 | |||
| 9124 | GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &menu_bar); | 9142 | GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &menu_bar); |
| 9125 | single_menu_bar_height = GetSystemMetrics (SM_CYMENU); | 9143 | single_menu_bar_height = GetSystemMetrics (SM_CYMENU); |
| 9126 | wrapped_menu_bar_height = GetSystemMetrics (SM_CYMENUSIZE); | 9144 | wrapped_menu_bar_height = GetSystemMetrics (SM_CYMENUSIZE); |
| @@ -10007,6 +10025,8 @@ Internal use only. */) | |||
| 10007 | 10025 | ||
| 10008 | #if defined WINDOWSNT && !defined HAVE_DBUS | 10026 | #if defined WINDOWSNT && !defined HAVE_DBUS |
| 10009 | 10027 | ||
| 10028 | static BOOL (WINAPI *pfnShell_NotifyIconW) (DWORD, PNOTIFYICONDATAW); | ||
| 10029 | |||
| 10010 | /*********************************************************************** | 10030 | /*********************************************************************** |
| 10011 | Tray notifications | 10031 | Tray notifications |
| 10012 | ***********************************************************************/ | 10032 | ***********************************************************************/ |
| @@ -10273,7 +10293,7 @@ add_tray_notification (struct frame *f, const char *icon, const char *tip, | |||
| 10273 | } | 10293 | } |
| 10274 | } | 10294 | } |
| 10275 | 10295 | ||
| 10276 | if (!Shell_NotifyIconW (NIM_ADD, (PNOTIFYICONDATAW)&nidw)) | 10296 | if (!(*pfnShell_NotifyIconW) (NIM_ADD, (PNOTIFYICONDATAW)&nidw)) |
| 10277 | { | 10297 | { |
| 10278 | /* GetLastError returns meaningless results when | 10298 | /* GetLastError returns meaningless results when |
| 10279 | Shell_NotifyIcon fails. */ | 10299 | Shell_NotifyIcon fails. */ |
| @@ -10305,7 +10325,7 @@ delete_tray_notification (struct frame *f, int id) | |||
| 10305 | nidw.hWnd = FRAME_W32_WINDOW (f); | 10325 | nidw.hWnd = FRAME_W32_WINDOW (f); |
| 10306 | nidw.uID = id; | 10326 | nidw.uID = id; |
| 10307 | 10327 | ||
| 10308 | if (!Shell_NotifyIconW (NIM_DELETE, (PNOTIFYICONDATAW)&nidw)) | 10328 | if (!(*pfnShell_NotifyIconW) (NIM_DELETE, (PNOTIFYICONDATAW)&nidw)) |
| 10309 | { | 10329 | { |
| 10310 | /* GetLastError returns meaningless results when | 10330 | /* GetLastError returns meaningless results when |
| 10311 | Shell_NotifyIcon fails. */ | 10331 | Shell_NotifyIcon fails. */ |
| @@ -10372,8 +10392,8 @@ The following parameters are supported: | |||
| 10372 | characters long, and will be truncated if it's longer. | 10392 | characters long, and will be truncated if it's longer. |
| 10373 | 10393 | ||
| 10374 | Note that versions of Windows before W2K support only `:icon' and `:tip'. | 10394 | Note that versions of Windows before W2K support only `:icon' and `:tip'. |
| 10375 | You can pass the other parameters, but they will be ignored on those | 10395 | You can pass the other parameters, but they will be ignored on |
| 10376 | old systems. | 10396 | those old systems. |
| 10377 | 10397 | ||
| 10378 | There can be at most one active notification at any given time. An | 10398 | There can be at most one active notification at any given time. An |
| 10379 | active notification must be removed by calling `w32-notification-close' | 10399 | active notification must be removed by calling `w32-notification-close' |
| @@ -10389,7 +10409,10 @@ usage: (w32-notification-notify &rest PARAMS) */) | |||
| 10389 | enum NI_Severity severity; | 10409 | enum NI_Severity severity; |
| 10390 | unsigned timeout = 0; | 10410 | unsigned timeout = 0; |
| 10391 | 10411 | ||
| 10392 | if (nargs == 0) | 10412 | /* Required on Windows 9X. */ |
| 10413 | maybe_load_unicows_dll (); | ||
| 10414 | |||
| 10415 | if (nargs == 0 || !pfnShell_NotifyIconW) | ||
| 10393 | return Qnil; | 10416 | return Qnil; |
| 10394 | 10417 | ||
| 10395 | arg_plist = Flist (nargs, args); | 10418 | arg_plist = Flist (nargs, args); |
| @@ -10448,7 +10471,7 @@ DEFUN ("w32-notification-close", | |||
| 10448 | { | 10471 | { |
| 10449 | struct frame *f = SELECTED_FRAME (); | 10472 | struct frame *f = SELECTED_FRAME (); |
| 10450 | 10473 | ||
| 10451 | if (FIXNUMP (id)) | 10474 | if (FIXNUMP (id) && !pfnShell_NotifyIconW) |
| 10452 | delete_tray_notification (f, XFIXNUM (id)); | 10475 | delete_tray_notification (f, XFIXNUM (id)); |
| 10453 | 10476 | ||
| 10454 | return Qnil; | 10477 | return Qnil; |
| @@ -11499,7 +11522,7 @@ globals_of_w32fns (void) | |||
| 11499 | get_proc_addr (wtsapi32_lib, "WTSRegisterSessionNotification"); | 11522 | get_proc_addr (wtsapi32_lib, "WTSRegisterSessionNotification"); |
| 11500 | WTSUnRegisterSessionNotification_fn = (WTSUnRegisterSessionNotification_Proc) | 11523 | WTSUnRegisterSessionNotification_fn = (WTSUnRegisterSessionNotification_Proc) |
| 11501 | get_proc_addr (wtsapi32_lib, "WTSUnRegisterSessionNotification"); | 11524 | get_proc_addr (wtsapi32_lib, "WTSUnRegisterSessionNotification"); |
| 11502 | #endif | 11525 | #endif /* WINDOWSNT */ |
| 11503 | 11526 | ||
| 11504 | /* Support OS dark mode on Windows 10 version 1809 and higher. | 11527 | /* Support OS dark mode on Windows 10 version 1809 and higher. |
| 11505 | See `w32_applytheme' which uses appropriate APIs per version of Windows. | 11528 | 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. */); | |||
| 11580 | syms_of_w32uniscribe (); | 11603 | syms_of_w32uniscribe (); |
| 11581 | } | 11604 | } |
| 11582 | 11605 | ||
| 11606 | #ifdef WINDOWSNT | ||
| 11607 | |||
| 11608 | /* Initialize pointers to functions whose real implementations exist in | ||
| 11609 | UNICOWS.DLL on Windows 9X. UNICOWS should be a pointer to a loaded | ||
| 11610 | handle referencing UNICOWS.DLL, or NULL on Windows NT systems. */ | ||
| 11611 | |||
| 11612 | void | ||
| 11613 | load_unicows_dll_for_w32fns (HMODULE unicows) | ||
| 11614 | { | ||
| 11615 | if (!unicows) | ||
| 11616 | /* The functions following are defined by SHELL32.DLL onw Windows | ||
| 11617 | NT. */ | ||
| 11618 | unicows = GetModuleHandle ("shell32"); | ||
| 11619 | |||
| 11620 | pfnSHFileOperationW | ||
| 11621 | = (void *) get_proc_addr (unicows, "SHFileOperationW"); | ||
| 11622 | pfnShellExecuteExW | ||
| 11623 | = (void *) get_proc_addr (unicows, "ShellExecuteExW"); | ||
| 11624 | #ifndef HAVE_DBUS | ||
| 11625 | pfnShell_NotifyIconW | ||
| 11626 | = (void *) get_proc_addr (unicows, "Shell_NotifyIconW"); | ||
| 11627 | #endif /* !HAVE_DBUS */ | ||
| 11628 | } | ||
| 11629 | |||
| 11630 | #endif /* WINDOWSNT */ | ||
| 11631 | |||
| 11583 | #ifdef NTGUI_UNICODE | 11632 | #ifdef NTGUI_UNICODE |
| 11584 | 11633 | ||
| 11585 | Lisp_Object | 11634 | 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 { | |||
| 120 | /* Used for communicating notifications to the main thread. */ | 120 | /* Used for communicating notifications to the main thread. */ |
| 121 | struct notifications_set *notifications_set_head; | 121 | struct notifications_set *notifications_set_head; |
| 122 | 122 | ||
| 123 | /* Function pointers. */ | ||
| 124 | static BOOL (WINAPI *pfnReadDirectoryChangesW) (HANDLE, PVOID, DWORD, BOOL, | ||
| 125 | DWORD, PDWORD, LPOVERLAPPED, | ||
| 126 | LPOVERLAPPED_COMPLETION_ROUTINE); | ||
| 123 | static Lisp_Object watch_list; | 127 | static 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. */) | |||
| 699 | void | 705 | void |
| 700 | globals_of_w32notify (void) | 706 | globals_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 | ||
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) | |||
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | 111 | ||
| 112 | /* Uniscribe function pointers. */ | ||
| 113 | static HRESULT (WINAPI * pfnScriptItemize) (const WCHAR *, | ||
| 114 | int, | ||
| 115 | int, | ||
| 116 | const SCRIPT_CONTROL *, | ||
| 117 | const SCRIPT_STATE *, | ||
| 118 | SCRIPT_ITEM *, int *); | ||
| 119 | static HRESULT (WINAPI * pfnScriptShape) (HDC, SCRIPT_CACHE *, | ||
| 120 | const WCHAR *, | ||
| 121 | int, int, SCRIPT_ANALYSIS *, | ||
| 122 | WORD *, WORD *, SCRIPT_VISATTR *, | ||
| 123 | int *); | ||
| 124 | static HRESULT (WINAPI * pfnScriptPlace) (HDC, SCRIPT_CACHE *, | ||
| 125 | const WORD *, int, | ||
| 126 | const SCRIPT_VISATTR *, | ||
| 127 | SCRIPT_ANALYSIS *, | ||
| 128 | int *, GOFFSET *, ABC *); | ||
| 129 | static HRESULT (WINAPI * pfnScriptGetGlyphABCWidth) (HDC, SCRIPT_CACHE *, | ||
| 130 | WORD, ABC *); | ||
| 131 | static HRESULT (WINAPI * pfnScriptFreeCache) (SCRIPT_CACHE *); | ||
| 132 | static HRESULT (WINAPI * pfnScriptGetCMap) (HDC, SCRIPT_CACHE *, | ||
| 133 | const WCHAR *, | ||
| 134 | int, DWORD, WORD *); | ||
| 135 | |||
| 136 | |||
| 112 | /* Font backend interface implementation. */ | 137 | /* Font backend interface implementation. */ |
| 113 | static Lisp_Object | 138 | static Lisp_Object |
| 114 | uniscribe_list (struct frame *f, Lisp_Object font_spec) | 139 | uniscribe_list (struct frame *f, Lisp_Object font_spec) |
| @@ -202,7 +227,7 @@ uniscribe_close (struct font *font) | |||
| 202 | else | 227 | else |
| 203 | #endif | 228 | #endif |
| 204 | if (uniscribe_font->cache) | 229 | if (uniscribe_font->cache) |
| 205 | ScriptFreeCache ((SCRIPT_CACHE) &(uniscribe_font->cache)); | 230 | (*pfnScriptFreeCache) ((SCRIPT_CACHE) &(uniscribe_font->cache)); |
| 206 | 231 | ||
| 207 | uniscribe_font->cache = NULL; | 232 | uniscribe_font->cache = NULL; |
| 208 | 233 | ||
| @@ -320,8 +345,8 @@ uniscribe_shape (Lisp_Object lgstring, Lisp_Object direction) | |||
| 320 | max_items = 2; | 345 | max_items = 2; |
| 321 | items = xmalloc (sizeof (SCRIPT_ITEM) * max_items + 1); | 346 | items = xmalloc (sizeof (SCRIPT_ITEM) * max_items + 1); |
| 322 | 347 | ||
| 323 | while ((result = ScriptItemize (chars, nchars, max_items, NULL, NULL, | 348 | while ((result = (*pfnScriptItemize) (chars, nchars, max_items, NULL, NULL, |
| 324 | items, &nitems)) == E_OUTOFMEMORY) | 349 | items, &nitems)) == E_OUTOFMEMORY) |
| 325 | { | 350 | { |
| 326 | /* If that wasn't enough, keep trying with one more run. */ | 351 | /* If that wasn't enough, keep trying with one more run. */ |
| 327 | max_items++; | 352 | max_items++; |
| @@ -344,17 +369,18 @@ uniscribe_shape (Lisp_Object lgstring, Lisp_Object direction) | |||
| 344 | { | 369 | { |
| 345 | int nglyphs, nchars_in_run; | 370 | int nglyphs, nchars_in_run; |
| 346 | nchars_in_run = items[i+1].iCharPos - items[i].iCharPos; | 371 | nchars_in_run = items[i+1].iCharPos - items[i].iCharPos; |
| 347 | /* Force ScriptShape to generate glyphs in the same order as | 372 | /* Force (*pfnScriptShape) to generate glyphs in the same order as |
| 348 | they are in the input LGSTRING, which is in the logical | 373 | they are in the input LGSTRING, which is in the logical |
| 349 | order. */ | 374 | order. */ |
| 350 | items[i].a.fLogicalOrder = 1; | 375 | items[i].a.fLogicalOrder = 1; |
| 351 | 376 | ||
| 352 | /* Context may be NULL here, in which case the cache should be | 377 | /* Context may be NULL here, in which case the cache should be |
| 353 | used without needing to select the font. */ | 378 | used without needing to select the font. */ |
| 354 | result = ScriptShape (context, (SCRIPT_CACHE) &(uniscribe_font->cache), | 379 | result |
| 355 | chars + items[i].iCharPos, nchars_in_run, | 380 | = (*pfnScriptShape) (context, (SCRIPT_CACHE) &(uniscribe_font->cache), |
| 356 | max_glyphs - done_glyphs, &(items[i].a), | 381 | chars + items[i].iCharPos, nchars_in_run, |
| 357 | glyphs, clusters, attributes, &nglyphs); | 382 | max_glyphs - done_glyphs, &(items[i].a), |
| 383 | glyphs, clusters, attributes, &nglyphs); | ||
| 358 | 384 | ||
| 359 | if (result == E_PENDING && !context) | 385 | if (result == E_PENDING && !context) |
| 360 | { | 386 | { |
| @@ -365,10 +391,12 @@ uniscribe_shape (Lisp_Object lgstring, Lisp_Object direction) | |||
| 365 | context = get_frame_dc (f); | 391 | context = get_frame_dc (f); |
| 366 | old_font = SelectObject (context, FONT_HANDLE (font)); | 392 | old_font = SelectObject (context, FONT_HANDLE (font)); |
| 367 | 393 | ||
| 368 | result = ScriptShape (context, (SCRIPT_CACHE) &(uniscribe_font->cache), | 394 | result |
| 369 | chars + items[i].iCharPos, nchars_in_run, | 395 | = (*pfnScriptShape) (context, |
| 370 | max_glyphs - done_glyphs, &(items[i].a), | 396 | (SCRIPT_CACHE) &(uniscribe_font->cache), |
| 371 | glyphs, clusters, attributes, &nglyphs); | 397 | chars + items[i].iCharPos, nchars_in_run, |
| 398 | max_glyphs - done_glyphs, &(items[i].a), | ||
| 399 | glyphs, clusters, attributes, &nglyphs); | ||
| 372 | } | 400 | } |
| 373 | 401 | ||
| 374 | if (result == E_OUTOFMEMORY) | 402 | if (result == E_OUTOFMEMORY) |
| @@ -390,9 +418,11 @@ uniscribe_shape (Lisp_Object lgstring, Lisp_Object direction) | |||
| 390 | } | 418 | } |
| 391 | else | 419 | else |
| 392 | { | 420 | { |
| 393 | result = ScriptPlace (context, (SCRIPT_CACHE) &(uniscribe_font->cache), | 421 | result |
| 394 | glyphs, nglyphs, attributes, &(items[i].a), | 422 | = (*pfnScriptPlace) (context, |
| 395 | advances, offsets, &overall_metrics); | 423 | (SCRIPT_CACHE) &(uniscribe_font->cache), |
| 424 | glyphs, nglyphs, attributes, &(items[i].a), | ||
| 425 | advances, offsets, &overall_metrics); | ||
| 396 | if (result == E_PENDING && !context) | 426 | if (result == E_PENDING && !context) |
| 397 | { | 427 | { |
| 398 | /* Cache not complete... */ | 428 | /* Cache not complete... */ |
| @@ -400,10 +430,11 @@ uniscribe_shape (Lisp_Object lgstring, Lisp_Object direction) | |||
| 400 | context = get_frame_dc (f); | 430 | context = get_frame_dc (f); |
| 401 | old_font = SelectObject (context, FONT_HANDLE (font)); | 431 | old_font = SelectObject (context, FONT_HANDLE (font)); |
| 402 | 432 | ||
| 403 | result = ScriptPlace (context, | 433 | result |
| 404 | (SCRIPT_CACHE) &(uniscribe_font->cache), | 434 | = (*pfnScriptPlace) (context, |
| 405 | glyphs, nglyphs, attributes, &(items[i].a), | 435 | (SCRIPT_CACHE) &(uniscribe_font->cache), |
| 406 | advances, offsets, &overall_metrics); | 436 | glyphs, nglyphs, attributes, &(items[i].a), |
| 437 | advances, offsets, &overall_metrics); | ||
| 407 | } | 438 | } |
| 408 | if (SUCCEEDED (result)) | 439 | if (SUCCEEDED (result)) |
| 409 | { | 440 | { |
| @@ -469,7 +500,7 @@ uniscribe_shape (Lisp_Object lgstring, Lisp_Object direction) | |||
| 469 | then updated for each successive glyph in the | 500 | then updated for each successive glyph in the |
| 470 | grapheme cluster. */ | 501 | grapheme cluster. */ |
| 471 | /* FIXME: Should we use DIRECTION here instead | 502 | /* FIXME: Should we use DIRECTION here instead |
| 472 | of what ScriptItemize guessed? */ | 503 | of what (*pfnScriptItemize) guessed? */ |
| 473 | if (items[i].a.fRTL) | 504 | if (items[i].a.fRTL) |
| 474 | { | 505 | { |
| 475 | int j1 = j; | 506 | int j1 = j; |
| @@ -496,7 +527,7 @@ uniscribe_shape (Lisp_Object lgstring, Lisp_Object direction) | |||
| 496 | LGLYPH_SET_ASCENT (lglyph, font->ascent); | 527 | LGLYPH_SET_ASCENT (lglyph, font->ascent); |
| 497 | LGLYPH_SET_DESCENT (lglyph, font->descent); | 528 | LGLYPH_SET_DESCENT (lglyph, font->descent); |
| 498 | 529 | ||
| 499 | result = ScriptGetGlyphABCWidth | 530 | result = (*pfnScriptGetGlyphABCWidth) |
| 500 | (context, (SCRIPT_CACHE) &(uniscribe_font->cache), | 531 | (context, (SCRIPT_CACHE) &(uniscribe_font->cache), |
| 501 | glyphs[j], &char_metric); | 532 | glyphs[j], &char_metric); |
| 502 | if (result == E_PENDING && !context) | 533 | if (result == E_PENDING && !context) |
| @@ -505,7 +536,7 @@ uniscribe_shape (Lisp_Object lgstring, Lisp_Object direction) | |||
| 505 | f = XFRAME (selected_frame); | 536 | f = XFRAME (selected_frame); |
| 506 | context = get_frame_dc (f); | 537 | context = get_frame_dc (f); |
| 507 | old_font = SelectObject (context, FONT_HANDLE (font)); | 538 | old_font = SelectObject (context, FONT_HANDLE (font)); |
| 508 | result = ScriptGetGlyphABCWidth | 539 | result = (*pfnScriptGetGlyphABCWidth) |
| 509 | (context, (SCRIPT_CACHE) &(uniscribe_font->cache), | 540 | (context, (SCRIPT_CACHE) &(uniscribe_font->cache), |
| 510 | glyphs[j], &char_metric); | 541 | glyphs[j], &char_metric); |
| 511 | } | 542 | } |
| @@ -624,7 +655,8 @@ uniscribe_encode_char (struct font *font, int c) | |||
| 624 | convert surrogate pairs to glyph indexes correctly. */ | 655 | convert surrogate pairs to glyph indexes correctly. */ |
| 625 | { | 656 | { |
| 626 | items = (SCRIPT_ITEM *) alloca (sizeof (SCRIPT_ITEM) * 2 + 1); | 657 | items = (SCRIPT_ITEM *) alloca (sizeof (SCRIPT_ITEM) * 2 + 1); |
| 627 | if (SUCCEEDED (ScriptItemize (ch, len, 2, NULL, NULL, items, &nitems))) | 658 | if (SUCCEEDED ((*pfnScriptItemize) (ch, len, 2, NULL, NULL, items, |
| 659 | &nitems))) | ||
| 628 | { | 660 | { |
| 629 | HRESULT result; | 661 | HRESULT result; |
| 630 | /* Surrogates seem to need 2 here, even though only one glyph is | 662 | /* Surrogates seem to need 2 here, even though only one glyph is |
| @@ -635,14 +667,14 @@ uniscribe_encode_char (struct font *font, int c) | |||
| 635 | SCRIPT_VISATTR attrs[2]; | 667 | SCRIPT_VISATTR attrs[2]; |
| 636 | int nglyphs; | 668 | int nglyphs; |
| 637 | 669 | ||
| 638 | /* Force ScriptShape to generate glyphs in the logical | 670 | /* Force (*pfnScriptShape) to generate glyphs in the logical |
| 639 | order. */ | 671 | order. */ |
| 640 | items[0].a.fLogicalOrder = 1; | 672 | items[0].a.fLogicalOrder = 1; |
| 641 | 673 | ||
| 642 | result = ScriptShape (context, | 674 | result = (*pfnScriptShape) (context, |
| 643 | (SCRIPT_CACHE) &(uniscribe_font->cache), | 675 | (SCRIPT_CACHE) &(uniscribe_font->cache), |
| 644 | ch, len, 2, &(items[0].a), | 676 | ch, len, 2, &(items[0].a), |
| 645 | glyphs, clusters, attrs, &nglyphs); | 677 | glyphs, clusters, attrs, &nglyphs); |
| 646 | 678 | ||
| 647 | if (result == E_PENDING) | 679 | if (result == E_PENDING) |
| 648 | { | 680 | { |
| @@ -651,10 +683,11 @@ uniscribe_encode_char (struct font *font, int c) | |||
| 651 | f = XFRAME (selected_frame); | 683 | f = XFRAME (selected_frame); |
| 652 | context = get_frame_dc (f); | 684 | context = get_frame_dc (f); |
| 653 | old_font = SelectObject (context, FONT_HANDLE (font)); | 685 | old_font = SelectObject (context, FONT_HANDLE (font)); |
| 654 | result = ScriptShape (context, | 686 | result |
| 655 | (SCRIPT_CACHE) &(uniscribe_font->cache), | 687 | = (*pfnScriptShape) (context, |
| 656 | ch, len, 2, &(items[0].a), | 688 | (SCRIPT_CACHE) &(uniscribe_font->cache), |
| 657 | glyphs, clusters, attrs, &nglyphs); | 689 | ch, len, 2, &(items[0].a), |
| 690 | glyphs, clusters, attrs, &nglyphs); | ||
| 658 | } | 691 | } |
| 659 | 692 | ||
| 660 | if (SUCCEEDED (result) && nglyphs == 1) | 693 | if (SUCCEEDED (result) && nglyphs == 1) |
| @@ -670,9 +703,10 @@ uniscribe_encode_char (struct font *font, int c) | |||
| 670 | when shaped. But we still need the return from here | 703 | when shaped. But we still need the return from here |
| 671 | to be valid for the shaping engine to be invoked | 704 | to be valid for the shaping engine to be invoked |
| 672 | later. */ | 705 | later. */ |
| 673 | result = ScriptGetCMap (context, | 706 | result |
| 674 | (SCRIPT_CACHE) &(uniscribe_font->cache), | 707 | = (*pfnScriptGetCMap) (context, |
| 675 | ch, len, 0, glyphs); | 708 | (SCRIPT_CACHE) &(uniscribe_font->cache), |
| 709 | ch, len, 0, glyphs); | ||
| 676 | if (SUCCEEDED (result) && glyphs[0]) | 710 | if (SUCCEEDED (result) && glyphs[0]) |
| 677 | code = glyphs[0]; | 711 | code = glyphs[0]; |
| 678 | } | 712 | } |
| @@ -942,7 +976,7 @@ uniscribe_check_otf_1 (HDC context, Lisp_Object script, Lisp_Object lang, | |||
| 942 | 976 | ||
| 943 | no_support: | 977 | no_support: |
| 944 | if (cache) | 978 | if (cache) |
| 945 | ScriptFreeCache (&cache); | 979 | (*pfnScriptFreeCache) (&cache); |
| 946 | return ret; | 980 | return ret; |
| 947 | } | 981 | } |
| 948 | 982 | ||
| @@ -1505,11 +1539,43 @@ syms_of_w32uniscribe_for_pdumper (void) | |||
| 1505 | return; | 1539 | return; |
| 1506 | 1540 | ||
| 1507 | /* Don't register if Uniscribe is not available. */ | 1541 | /* Don't register if Uniscribe is not available. */ |
| 1508 | HMODULE uniscribe = GetModuleHandle ("usp10"); | 1542 | HMODULE uniscribe; |
| 1543 | |||
| 1544 | #ifdef WINDOWSNT | ||
| 1545 | uniscribe = LoadLibrary ("usp10.dll"); | ||
| 1509 | if (!uniscribe) | 1546 | if (!uniscribe) |
| 1510 | return; | 1547 | return; |
| 1511 | 1548 | ||
| 1549 | pfnScriptItemize = (void *) get_proc_addr (uniscribe, "ScriptItemize"); | ||
| 1550 | pfnScriptShape = (void *) get_proc_addr (uniscribe, "ScriptShape"); | ||
| 1551 | pfnScriptPlace = (void *) get_proc_addr (uniscribe, "ScriptPlace"); | ||
| 1552 | pfnScriptGetGlyphABCWidth | ||
| 1553 | = (void *) get_proc_addr (uniscribe, "ScriptGetGlyphABCWidth"); | ||
| 1554 | pfnScriptFreeCache | ||
| 1555 | = (void *) get_proc_addr (uniscribe, "ScriptFreeCache"); | ||
| 1556 | pfnScriptGetCMap | ||
| 1557 | = (void *) get_proc_addr (uniscribe, "ScriptGetCMap"); | ||
| 1558 | if (!pfnScriptItemize || !pfnScriptShape || !pfnScriptPlace | ||
| 1559 | || !pfnScriptGetGlyphABCWidth || !pfnScriptFreeCache | ||
| 1560 | || !pfnScriptGetCMap) | ||
| 1561 | { | ||
| 1562 | FreeLibrary (uniscribe); | ||
| 1563 | return; | ||
| 1564 | } | ||
| 1565 | #else /* Cygwin */ | ||
| 1566 | uniscribe = GetModuleHandle ("usp10.dll"); | ||
| 1567 | if (!uniscribe) | ||
| 1568 | return; | ||
| 1569 | |||
| 1570 | pfnScriptItemize = &ScriptItemize; | ||
| 1571 | pfnScriptShape = &ScriptShape; | ||
| 1572 | pfnScriptPlace = &ScriptPlace; | ||
| 1573 | pfnScriptGetGlyphABCWidth = &ScriptGetGlyphABCWidth; | ||
| 1574 | pfnScriptFreeCache = &ScriptFreeCache; | ||
| 1575 | pfnScriptGetCMap = &ScriptGetCMap; | ||
| 1576 | |||
| 1512 | uniscribe_available = 1; | 1577 | uniscribe_available = 1; |
| 1578 | #endif /* Cygwin */ | ||
| 1513 | 1579 | ||
| 1514 | register_font_driver (&uniscribe_font_driver, NULL); | 1580 | register_font_driver (&uniscribe_font_driver, NULL); |
| 1515 | 1581 | ||