diff options
| author | Cecilio Pardo | 2024-09-27 23:58:02 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2024-10-08 16:13:24 +0300 |
| commit | 9af36e70f83d00eaef2255929e8aed7e1d3ed5b9 (patch) | |
| tree | 1262465c5a08b767e9e96f8498f2a583d0c13222 /src | |
| parent | 339ffd79862c322f5b75fed1b55d61efe90bc7a1 (diff) | |
| download | emacs-9af36e70f83d00eaef2255929e8aed7e1d3ed5b9.tar.gz emacs-9af36e70f83d00eaef2255929e8aed7e1d3ed5b9.zip | |
Implement drag-n-drop for w32 with support for files and text
Implement drag-n-drop with IDropTarget for MS-Windows. This
allows for dropping files or text.
* lisp/term/w32-win.el (w32-drag-n-drop): Change to handle
files or strings.
* src/w32fns.c (process_dropfiles): New function to convert
DROPFILES struct to array of strings.
(w32_process_dnd_data): New function to process drop data.
(w32_try_get_data): Extract data from IDataObject.
(w32_createwindow): Assign an IDropTarget to each new frame.
(w32_name_of_message): New message.
(w32_msg_pump): Changed CoInitialize to OleInitialize, needed
by the drag-n-drop functions.
(w32_wnd_proc): New struct w32_drop_target, and
w32_drop_target_* functions to implement the IDropTarget
interface.
* src/w32term.c (w32_read_socket): Handle WM_EMACS_DROP and
remove WM_EMACS_DROPFILES.
* src/w32term.h: New message WM_EMACS_DROP.
(Bug#3468)
* etc/NEWS: Announce the new feature.
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32fns.c | 221 | ||||
| -rw-r--r-- | src/w32term.c | 98 | ||||
| -rw-r--r-- | src/w32term.h | 4 |
3 files changed, 237 insertions, 86 deletions
diff --git a/src/w32fns.c b/src/w32fns.c index 0a3f5c38a58..b3d26b841e4 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -34,6 +34,12 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 34 | 34 | ||
| 35 | #include <c-ctype.h> | 35 | #include <c-ctype.h> |
| 36 | 36 | ||
| 37 | #define COBJMACROS /* Ask for C definitions for COM. */ | ||
| 38 | #include <shlobj.h> | ||
| 39 | #include <oleidl.h> | ||
| 40 | #include <objidl.h> | ||
| 41 | #include <ole2.h> | ||
| 42 | |||
| 37 | #include "lisp.h" | 43 | #include "lisp.h" |
| 38 | #include "w32term.h" | 44 | #include "w32term.h" |
| 39 | #include "frame.h" | 45 | #include "frame.h" |
| @@ -359,6 +365,9 @@ extern HANDLE keyboard_handle; | |||
| 359 | 365 | ||
| 360 | static struct w32_display_info *w32_display_info_for_name (Lisp_Object); | 366 | static struct w32_display_info *w32_display_info_for_name (Lisp_Object); |
| 361 | 367 | ||
| 368 | static void my_post_msg (W32Msg*, HWND, UINT, WPARAM, LPARAM); | ||
| 369 | static unsigned int w32_get_modifiers (void); | ||
| 370 | |||
| 362 | /* Let the user specify a display with a frame. | 371 | /* Let the user specify a display with a frame. |
| 363 | nil stands for the selected frame--or, if that is not a w32 frame, | 372 | nil stands for the selected frame--or, if that is not a w32 frame, |
| 364 | the first display on the list. */ | 373 | the first display on the list. */ |
| @@ -2464,6 +2473,182 @@ w32_createhscrollbar (struct frame *f, struct scroll_bar * bar) | |||
| 2464 | return hwnd; | 2473 | return hwnd; |
| 2465 | } | 2474 | } |
| 2466 | 2475 | ||
| 2476 | /* From the DROPFILES struct, extract the filenames and return as a list | ||
| 2477 | of strings. */ | ||
| 2478 | static Lisp_Object | ||
| 2479 | process_dropfiles (DROPFILES *files) | ||
| 2480 | { | ||
| 2481 | char *start_of_files = (char *) files + files->pFiles; | ||
| 2482 | char filename[MAX_UTF8_PATH]; | ||
| 2483 | Lisp_Object lisp_files = Qnil; | ||
| 2484 | |||
| 2485 | if (files->fWide) | ||
| 2486 | { | ||
| 2487 | WCHAR *p = (WCHAR *) start_of_files; | ||
| 2488 | for (; *p; p += wcslen (p) + 1) | ||
| 2489 | { | ||
| 2490 | filename_from_utf16(p, filename); | ||
| 2491 | lisp_files = Fcons (DECODE_FILE (build_unibyte_string (filename)), | ||
| 2492 | lisp_files ); | ||
| 2493 | } | ||
| 2494 | } | ||
| 2495 | else | ||
| 2496 | { | ||
| 2497 | char *p = start_of_files; | ||
| 2498 | for (; *p; p += strlen(p) + 1) | ||
| 2499 | { | ||
| 2500 | filename_from_ansi (p, filename); | ||
| 2501 | lisp_files = Fcons (DECODE_FILE (build_unibyte_string (filename)), | ||
| 2502 | lisp_files ); | ||
| 2503 | } | ||
| 2504 | } | ||
| 2505 | return lisp_files; | ||
| 2506 | } | ||
| 2507 | |||
| 2508 | |||
| 2509 | /* This function can be called ONLY between calls to | ||
| 2510 | block_input/unblock_input. It is used in w32_read_socket. */ | ||
| 2511 | Lisp_Object | ||
| 2512 | w32_process_dnd_data (int format, void *hGlobal) | ||
| 2513 | { | ||
| 2514 | Lisp_Object result = Qnil; | ||
| 2515 | HGLOBAL hg = (HGLOBAL) hGlobal; | ||
| 2516 | |||
| 2517 | switch (format) | ||
| 2518 | { | ||
| 2519 | case CF_HDROP: | ||
| 2520 | { | ||
| 2521 | DROPFILES *files = (DROPFILES *) GlobalLock (hg); | ||
| 2522 | if (files) | ||
| 2523 | result = process_dropfiles (files); | ||
| 2524 | GlobalUnlock (hg); | ||
| 2525 | break; | ||
| 2526 | } | ||
| 2527 | case CF_UNICODETEXT: | ||
| 2528 | { | ||
| 2529 | WCHAR *text = (WCHAR *) GlobalLock (hg); | ||
| 2530 | result = from_unicode_buffer (text); | ||
| 2531 | GlobalUnlock (hg); | ||
| 2532 | break; | ||
| 2533 | } | ||
| 2534 | case CF_TEXT: | ||
| 2535 | { | ||
| 2536 | char *text = (char *) GlobalLock (hg); | ||
| 2537 | result = DECODE_SYSTEM (build_unibyte_string (text)); | ||
| 2538 | GlobalUnlock (hg); | ||
| 2539 | break; | ||
| 2540 | } | ||
| 2541 | } | ||
| 2542 | |||
| 2543 | GlobalFree (hg); | ||
| 2544 | |||
| 2545 | return result; | ||
| 2546 | } | ||
| 2547 | |||
| 2548 | struct w32_drop_target { | ||
| 2549 | /* i_drop_target must be the first member. */ | ||
| 2550 | IDropTarget i_drop_target; | ||
| 2551 | HWND hwnd; | ||
| 2552 | }; | ||
| 2553 | |||
| 2554 | static HRESULT STDMETHODCALLTYPE | ||
| 2555 | w32_drop_target_QueryInterface (IDropTarget *t, REFIID ri, void **r) | ||
| 2556 | { | ||
| 2557 | return E_NOINTERFACE; | ||
| 2558 | } | ||
| 2559 | |||
| 2560 | static ULONG STDMETHODCALLTYPE | ||
| 2561 | w32_drop_target_AddRef (IDropTarget *This) | ||
| 2562 | { | ||
| 2563 | return 1; | ||
| 2564 | } | ||
| 2565 | |||
| 2566 | static ULONG STDMETHODCALLTYPE | ||
| 2567 | w32_drop_target_Release (IDropTarget *This) | ||
| 2568 | { | ||
| 2569 | struct w32_drop_target *target = (struct w32_drop_target * ) This; | ||
| 2570 | free (target->i_drop_target.lpVtbl); | ||
| 2571 | free (target); | ||
| 2572 | return 0; | ||
| 2573 | } | ||
| 2574 | |||
| 2575 | static HRESULT STDMETHODCALLTYPE | ||
| 2576 | w32_drop_target_DragEnter (IDropTarget *This, IDataObject *pDataObj, | ||
| 2577 | DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) | ||
| 2578 | { | ||
| 2579 | /* Possible 'effect' values are COPY, MOVE, LINK or NONE. This choice | ||
| 2580 | changes the mouse pointer shape to inform the user of what will | ||
| 2581 | happen on drop. We send COPY because our use cases don't modify | ||
| 2582 | or link to the original data. */ | ||
| 2583 | *pdwEffect = DROPEFFECT_COPY; | ||
| 2584 | return S_OK; | ||
| 2585 | } | ||
| 2586 | |||
| 2587 | static HRESULT STDMETHODCALLTYPE | ||
| 2588 | w32_drop_target_DragOver (IDropTarget *This, DWORD grfKeyState, POINTL pt, | ||
| 2589 | DWORD *pdwEffect) | ||
| 2590 | { | ||
| 2591 | /* See comment in w32_drop_target_DragEnter. */ | ||
| 2592 | *pdwEffect = DROPEFFECT_COPY; | ||
| 2593 | return S_OK; | ||
| 2594 | } | ||
| 2595 | |||
| 2596 | static HRESULT STDMETHODCALLTYPE | ||
| 2597 | w32_drop_target_DragLeave (IDropTarget *This) | ||
| 2598 | { | ||
| 2599 | return S_OK; | ||
| 2600 | } | ||
| 2601 | |||
| 2602 | static HGLOBAL w32_try_get_data (IDataObject *pDataObj, int format) | ||
| 2603 | { | ||
| 2604 | FORMATETC formatetc = { format, NULL, DVASPECT_CONTENT, -1, | ||
| 2605 | TYMED_HGLOBAL }; | ||
| 2606 | STGMEDIUM stgmedium; | ||
| 2607 | HRESULT r = IDataObject_GetData (pDataObj, &formatetc, &stgmedium); | ||
| 2608 | if (SUCCEEDED (r)) | ||
| 2609 | { | ||
| 2610 | if (stgmedium.tymed == TYMED_HGLOBAL) | ||
| 2611 | return stgmedium.hGlobal; | ||
| 2612 | ReleaseStgMedium (&stgmedium); | ||
| 2613 | } | ||
| 2614 | return NULL; | ||
| 2615 | } | ||
| 2616 | |||
| 2617 | static HRESULT STDMETHODCALLTYPE | ||
| 2618 | w32_drop_target_Drop (IDropTarget *This, IDataObject *pDataObj, | ||
| 2619 | DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) | ||
| 2620 | { | ||
| 2621 | struct w32_drop_target *target = (struct w32_drop_target *)This; | ||
| 2622 | *pdwEffect = DROPEFFECT_COPY; | ||
| 2623 | |||
| 2624 | W32Msg msg = {0}; | ||
| 2625 | msg.dwModifiers = w32_get_modifiers(); | ||
| 2626 | msg.msg.time = GetMessageTime (); | ||
| 2627 | msg.msg.pt.x = pt.x; | ||
| 2628 | msg.msg.pt.y = pt.y; | ||
| 2629 | |||
| 2630 | int format = CF_HDROP; | ||
| 2631 | HGLOBAL hGlobal = w32_try_get_data (pDataObj, format); | ||
| 2632 | |||
| 2633 | if (!hGlobal) | ||
| 2634 | { | ||
| 2635 | format = CF_UNICODETEXT; | ||
| 2636 | hGlobal = w32_try_get_data (pDataObj, format); | ||
| 2637 | } | ||
| 2638 | |||
| 2639 | if (!hGlobal) | ||
| 2640 | { | ||
| 2641 | format = CF_TEXT; | ||
| 2642 | hGlobal = w32_try_get_data (pDataObj, format); | ||
| 2643 | } | ||
| 2644 | |||
| 2645 | if (hGlobal) | ||
| 2646 | my_post_msg (&msg, target->hwnd, WM_EMACS_DROP, format, | ||
| 2647 | (LPARAM) hGlobal); | ||
| 2648 | |||
| 2649 | return S_OK; | ||
| 2650 | } | ||
| 2651 | |||
| 2467 | static void | 2652 | static void |
| 2468 | w32_createwindow (struct frame *f, int *coords) | 2653 | w32_createwindow (struct frame *f, int *coords) |
| 2469 | { | 2654 | { |
| @@ -2548,7 +2733,30 @@ w32_createwindow (struct frame *f, int *coords) | |||
| 2548 | SetWindowLong (hwnd, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f)); | 2733 | SetWindowLong (hwnd, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f)); |
| 2549 | 2734 | ||
| 2550 | /* Enable drag-n-drop. */ | 2735 | /* Enable drag-n-drop. */ |
| 2551 | DragAcceptFiles (hwnd, TRUE); | 2736 | struct w32_drop_target *drop_target = |
| 2737 | malloc (sizeof (struct w32_drop_target)); | ||
| 2738 | |||
| 2739 | if (drop_target != NULL) | ||
| 2740 | { | ||
| 2741 | IDropTargetVtbl *vtbl = malloc (sizeof (IDropTargetVtbl)); | ||
| 2742 | if (vtbl != NULL) | ||
| 2743 | { | ||
| 2744 | drop_target->hwnd = hwnd; | ||
| 2745 | drop_target->i_drop_target.lpVtbl = vtbl; | ||
| 2746 | vtbl->QueryInterface = w32_drop_target_QueryInterface; | ||
| 2747 | vtbl->AddRef = w32_drop_target_AddRef; | ||
| 2748 | vtbl->Release = w32_drop_target_Release; | ||
| 2749 | vtbl->DragEnter = w32_drop_target_DragEnter; | ||
| 2750 | vtbl->DragOver = w32_drop_target_DragOver; | ||
| 2751 | vtbl->DragLeave = w32_drop_target_DragLeave; | ||
| 2752 | vtbl->Drop = w32_drop_target_Drop; | ||
| 2753 | RegisterDragDrop (hwnd, &drop_target->i_drop_target); | ||
| 2754 | } | ||
| 2755 | else | ||
| 2756 | { | ||
| 2757 | free (drop_target); | ||
| 2758 | } | ||
| 2759 | } | ||
| 2552 | 2760 | ||
| 2553 | /* Enable system light/dark theme. */ | 2761 | /* Enable system light/dark theme. */ |
| 2554 | w32_applytheme (hwnd); | 2762 | w32_applytheme (hwnd); |
| @@ -3399,6 +3607,7 @@ w32_name_of_message (UINT msg) | |||
| 3399 | M (WM_EMACS_PAINT), | 3607 | M (WM_EMACS_PAINT), |
| 3400 | M (WM_EMACS_IME_STATUS), | 3608 | M (WM_EMACS_IME_STATUS), |
| 3401 | M (WM_CHAR), | 3609 | M (WM_CHAR), |
| 3610 | M (WM_EMACS_DROP), | ||
| 3402 | #undef M | 3611 | #undef M |
| 3403 | { 0, 0 } | 3612 | { 0, 0 } |
| 3404 | }; | 3613 | }; |
| @@ -3465,13 +3674,14 @@ w32_msg_pump (deferred_msg * msg_buf) | |||
| 3465 | /* Produced by complete_deferred_msg; just ignore. */ | 3674 | /* Produced by complete_deferred_msg; just ignore. */ |
| 3466 | break; | 3675 | break; |
| 3467 | case WM_EMACS_CREATEWINDOW: | 3676 | case WM_EMACS_CREATEWINDOW: |
| 3468 | /* Initialize COM for this window. Even though we don't use it, | 3677 | /* Initialize COM for this window. Needed for RegisterDragDrop. |
| 3469 | some third party shell extensions can cause it to be used in | 3678 | Some third party shell extensions can cause it to be used in |
| 3470 | system dialogs, which causes a crash if it is not initialized. | 3679 | system dialogs, which causes a crash if it is not initialized. |
| 3471 | This is a known bug in Windows, which was fixed long ago, but | 3680 | This is a known bug in Windows, which was fixed long ago, but |
| 3472 | the patch for XP is not publicly available until XP SP3, | 3681 | the patch for XP is not publicly available until XP SP3, |
| 3473 | and older versions will never be patched. */ | 3682 | and older versions will never be patched. */ |
| 3474 | CoInitialize (NULL); | 3683 | OleInitialize (NULL); |
| 3684 | |||
| 3475 | w32_createwindow ((struct frame *) msg.wParam, | 3685 | w32_createwindow ((struct frame *) msg.wParam, |
| 3476 | (int *) msg.lParam); | 3686 | (int *) msg.lParam); |
| 3477 | if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0)) | 3687 | if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0)) |
| @@ -5106,7 +5316,6 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) | |||
| 5106 | return 0; | 5316 | return 0; |
| 5107 | 5317 | ||
| 5108 | case WM_MOUSEWHEEL: | 5318 | case WM_MOUSEWHEEL: |
| 5109 | case WM_DROPFILES: | ||
| 5110 | wmsg.dwModifiers = w32_get_modifiers (); | 5319 | wmsg.dwModifiers = w32_get_modifiers (); |
| 5111 | my_post_msg (&wmsg, hwnd, msg, wParam, lParam); | 5320 | my_post_msg (&wmsg, hwnd, msg, wParam, lParam); |
| 5112 | signal_user_input (); | 5321 | signal_user_input (); |
| @@ -5597,7 +5806,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) | |||
| 5597 | } | 5806 | } |
| 5598 | 5807 | ||
| 5599 | case WM_EMACS_DESTROYWINDOW: | 5808 | case WM_EMACS_DESTROYWINDOW: |
| 5600 | DragAcceptFiles ((HWND) wParam, FALSE); | 5809 | RevokeDragDrop ((HWND) wParam); |
| 5601 | return DestroyWindow ((HWND) wParam); | 5810 | return DestroyWindow ((HWND) wParam); |
| 5602 | 5811 | ||
| 5603 | case WM_EMACS_HIDE_CARET: | 5812 | case WM_EMACS_HIDE_CARET: |
diff --git a/src/w32term.c b/src/w32term.c index 62037e3b2cd..3a627308137 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -3576,81 +3576,6 @@ w32_construct_mouse_wheel (struct input_event *result, W32Msg *msg, | |||
| 3576 | return Qnil; | 3576 | return Qnil; |
| 3577 | } | 3577 | } |
| 3578 | 3578 | ||
| 3579 | static Lisp_Object | ||
| 3580 | w32_construct_drag_n_drop (struct input_event *result, W32Msg *msg, | ||
| 3581 | struct frame *f) | ||
| 3582 | { | ||
| 3583 | Lisp_Object files; | ||
| 3584 | Lisp_Object frame; | ||
| 3585 | HDROP hdrop; | ||
| 3586 | POINT p; | ||
| 3587 | WORD num_files; | ||
| 3588 | wchar_t name_w[MAX_PATH]; | ||
| 3589 | #ifdef NTGUI_UNICODE | ||
| 3590 | const int use_unicode = 1; | ||
| 3591 | #else | ||
| 3592 | int use_unicode = w32_unicode_filenames; | ||
| 3593 | char name_a[MAX_PATH]; | ||
| 3594 | char file[MAX_UTF8_PATH]; | ||
| 3595 | #endif | ||
| 3596 | int i; | ||
| 3597 | |||
| 3598 | result->kind = DRAG_N_DROP_EVENT; | ||
| 3599 | result->code = 0; | ||
| 3600 | result->timestamp = msg->msg.time; | ||
| 3601 | result->modifiers = msg->dwModifiers; | ||
| 3602 | |||
| 3603 | hdrop = (HDROP) msg->msg.wParam; | ||
| 3604 | DragQueryPoint (hdrop, &p); | ||
| 3605 | |||
| 3606 | #if 0 | ||
| 3607 | p.x = LOWORD (msg->msg.lParam); | ||
| 3608 | p.y = HIWORD (msg->msg.lParam); | ||
| 3609 | ScreenToClient (msg->msg.hwnd, &p); | ||
| 3610 | #endif | ||
| 3611 | |||
| 3612 | XSETINT (result->x, p.x); | ||
| 3613 | XSETINT (result->y, p.y); | ||
| 3614 | |||
| 3615 | num_files = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0); | ||
| 3616 | files = Qnil; | ||
| 3617 | |||
| 3618 | for (i = 0; i < num_files; i++) | ||
| 3619 | { | ||
| 3620 | if (use_unicode) | ||
| 3621 | { | ||
| 3622 | eassert (DragQueryFileW (hdrop, i, NULL, 0) < MAX_PATH); | ||
| 3623 | /* If DragQueryFile returns zero, it failed to fetch a file | ||
| 3624 | name. */ | ||
| 3625 | if (DragQueryFileW (hdrop, i, name_w, MAX_PATH) == 0) | ||
| 3626 | continue; | ||
| 3627 | #ifdef NTGUI_UNICODE | ||
| 3628 | files = Fcons (from_unicode_buffer (name_w), files); | ||
| 3629 | #else | ||
| 3630 | filename_from_utf16 (name_w, file); | ||
| 3631 | files = Fcons (DECODE_FILE (build_unibyte_string (file)), files); | ||
| 3632 | #endif /* NTGUI_UNICODE */ | ||
| 3633 | } | ||
| 3634 | #ifndef NTGUI_UNICODE | ||
| 3635 | else | ||
| 3636 | { | ||
| 3637 | eassert (DragQueryFileA (hdrop, i, NULL, 0) < MAX_PATH); | ||
| 3638 | if (DragQueryFileA (hdrop, i, name_a, MAX_PATH) == 0) | ||
| 3639 | continue; | ||
| 3640 | filename_from_ansi (name_a, file); | ||
| 3641 | files = Fcons (DECODE_FILE (build_unibyte_string (file)), files); | ||
| 3642 | } | ||
| 3643 | #endif | ||
| 3644 | } | ||
| 3645 | |||
| 3646 | DragFinish (hdrop); | ||
| 3647 | |||
| 3648 | XSETFRAME (frame, f); | ||
| 3649 | result->frame_or_window = frame; | ||
| 3650 | result->arg = files; | ||
| 3651 | return Qnil; | ||
| 3652 | } | ||
| 3653 | |||
| 3654 | 3579 | ||
| 3655 | #if HAVE_W32NOTIFY | 3580 | #if HAVE_W32NOTIFY |
| 3656 | 3581 | ||
| @@ -5682,11 +5607,26 @@ w32_read_socket (struct terminal *terminal, | |||
| 5682 | } | 5607 | } |
| 5683 | break; | 5608 | break; |
| 5684 | 5609 | ||
| 5685 | case WM_DROPFILES: | 5610 | case WM_EMACS_DROP: |
| 5686 | f = w32_window_to_frame (dpyinfo, msg.msg.hwnd); | 5611 | { |
| 5612 | int format = msg.msg.wParam; | ||
| 5613 | Lisp_Object drop_object = | ||
| 5614 | w32_process_dnd_data (format, (void *) msg.msg.lParam); | ||
| 5687 | 5615 | ||
| 5688 | if (f) | 5616 | f = w32_window_to_frame (dpyinfo, msg.msg.hwnd); |
| 5689 | w32_construct_drag_n_drop (&inev, &msg, f); | 5617 | if (!f || NILP (drop_object)) |
| 5618 | break; | ||
| 5619 | |||
| 5620 | XSETFRAME (inev.frame_or_window, f); | ||
| 5621 | inev.kind = DRAG_N_DROP_EVENT; | ||
| 5622 | inev.code = 0; | ||
| 5623 | inev.timestamp = msg.msg.time; | ||
| 5624 | inev.modifiers = msg.dwModifiers; | ||
| 5625 | ScreenToClient (msg.msg.hwnd, &msg.msg.pt); | ||
| 5626 | XSETINT (inev.x, msg.msg.pt.x); | ||
| 5627 | XSETINT (inev.y, msg.msg.pt.y); | ||
| 5628 | inev.arg = drop_object; | ||
| 5629 | } | ||
| 5690 | break; | 5630 | break; |
| 5691 | 5631 | ||
| 5692 | case WM_HSCROLL: | 5632 | case WM_HSCROLL: |
diff --git a/src/w32term.h b/src/w32term.h index 47be542f570..39e2262e2a8 100644 --- a/src/w32term.h +++ b/src/w32term.h | |||
| @@ -272,6 +272,7 @@ extern const char *w32_get_string_resource (void *v_rdb, | |||
| 272 | 272 | ||
| 273 | /* w32fns.c */ | 273 | /* w32fns.c */ |
| 274 | extern void w32_default_font_parameter (struct frame* f, Lisp_Object parms); | 274 | extern void w32_default_font_parameter (struct frame* f, Lisp_Object parms); |
| 275 | extern Lisp_Object w32_process_dnd_data (int format, void *pDataObj); | ||
| 275 | 276 | ||
| 276 | 277 | ||
| 277 | #define PIX_TYPE COLORREF | 278 | #define PIX_TYPE COLORREF |
| @@ -710,7 +711,8 @@ do { \ | |||
| 710 | #define WM_EMACS_INPUT_READY (WM_EMACS_START + 24) | 711 | #define WM_EMACS_INPUT_READY (WM_EMACS_START + 24) |
| 711 | #define WM_EMACS_FILENOTIFY (WM_EMACS_START + 25) | 712 | #define WM_EMACS_FILENOTIFY (WM_EMACS_START + 25) |
| 712 | #define WM_EMACS_IME_STATUS (WM_EMACS_START + 26) | 713 | #define WM_EMACS_IME_STATUS (WM_EMACS_START + 26) |
| 713 | #define WM_EMACS_END (WM_EMACS_START + 27) | 714 | #define WM_EMACS_DROP (WM_EMACS_START + 27) |
| 715 | #define WM_EMACS_END (WM_EMACS_START + 28) | ||
| 714 | 716 | ||
| 715 | #define WND_FONTWIDTH_INDEX (0) | 717 | #define WND_FONTWIDTH_INDEX (0) |
| 716 | #define WND_LINEHEIGHT_INDEX (4) | 718 | #define WND_LINEHEIGHT_INDEX (4) |