Subject: Drag&Drop support for emacs-19.33

From: Michael Illgner <[email-masked]>
Date: Fri, 29 Nov 1996 23:30:43 +0100

Dear Geoff,

Here is a small patchfile for adding drag and drop support to
emacs-19.33. This works both with NT4.0 and NT3.51, but i haven't
tested it with Win95. Maybe you want to include it in one of the
next official Emacs releases ? The idea was stolen from an acient
amiga port of Emacs 18.58.

				Have Fun
				Michael Illgner

--- Cut Here ---
diff -u --recursive --new-file emacs-19.33.orig/lisp/winnt.el emacs-19.33/lisp/winnt.el
--- emacs-19.33.orig/lisp/winnt.el	Tue Jul 23 18:16:40 1996
+++ emacs-19.33/lisp/winnt.el	Fri Nov 29 22:23:30 1996
@@ -194,4 +194,23 @@
 ;;; Set to a system sound if you want a fancy bell.
 (set-message-beep nil)
 
+;;; Some stuff for win32 message handling, stolen from acient amiga port
+(setq windows-map (make-keymap))
+(global-set-key "\C-x\C-a" windows-map)
+
+(defun windows-process ()
+  "Process all pending windows events, ie load all files requested"
+  (interactive)
+  (let (file)
+    (condition-case nil
+	(while (setq file (win32-get-filename t))
+	  (condition-case nil
+	      (find-file file)
+	    (error nil)))
+      (error nil))))
+
+(define-key windows-map "W" 'windows-process) 
+
+
 ;;; winnt.el ends here
+
diff -u --recursive --new-file emacs-19.33.orig/src/makefile.nt emacs-19.33/src/makefile.nt
--- emacs-19.33.orig/src/makefile.nt	Sat Jul 20 20:06:12 1996
+++ emacs-19.33/src/makefile.nt	Thu Nov 28 23:54:00 1996
@@ -137,6 +137,7 @@
 !IFDEF NTGUI
 	gdi32.lib       \
 	comdlg32.lib    \
+	shell32.lib	\
 !ENDIF
 #	libcmt.lib      \
 	$(BASE_LIBS)	\
@@ -1058,6 +1059,7 @@
 	$(SRC)\lisp.h \
 	$(SRC)\w32term.h \
 	$(SRC)\win32.h \
+	$(SRC)\w32drop.h \
 	$(SRC)\frame.h \
   	$(SRC)\window.h \
 	$(SRC)\buffer.h \
@@ -1090,6 +1092,7 @@
 	$(SRC)\blockinput.h \
 	$(SRC)\w32term.h \
 	$(SRC)\win32.h \
+	$(SRC)\w32drop.h \
 	$(SRC)\systty.h \
 	$(SRC)\systime.h \
 	$(SRC)\frame.h \
diff -u --recursive --new-file emacs-19.33.orig/src/w32drop.h emacs-19.33/src/w32drop.h
--- emacs-19.33.orig/src/w32drop.h	Thu Jan  1 01:00:00 1970
+++ emacs-19.33/src/w32drop.h	Thu Nov 28 23:59:32 1996
@@ -0,0 +1,33 @@
+/* Definitions and headers for drag and drop support with Win32 GUI.
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#ifndef __W32DROP_H__
+#define __W32DROP_H__
+
+struct win32_file_list
+{
+  struct win32_file_list *next;
+  char                   *file_name;
+};
+
+extern struct win32_file_list *win32_file_list;
+extern int win32_initialized;
+
+#endif
diff -u --recursive --new-file emacs-19.33.orig/src/w32fns.c emacs-19.33/src/w32fns.c
--- emacs-19.33.orig/src/w32fns.c	Tue Jul 16 07:10:12 1996
+++ emacs-19.33/src/w32fns.c	Fri Nov 29 00:14:08 1996
@@ -35,8 +35,10 @@
 #include "paths.h"
 #include "ntheap.h"
 #include "termhooks.h"
+#include "w32drop.h"
 
 #include <commdlg.h>
+#include <shellapi.h>
 
 extern void abort ();
 extern void free_frame_menubar ();
@@ -90,6 +92,10 @@
 /* Search path for bitmap files.  */
 Lisp_Object Vx_bitmap_file_path;
 
+/* True if lisp may process windows messages */
+int win32_initialized;
+
+
 /* Evaluate this expression to rebuild the section of syms_of_w32fns
    that initializes and staticpros the symbols declared below.  Note
    that Emacs 18 has a bug that keeps C-x C-e from being able to
@@ -2643,6 +2649,7 @@
 
       /* Do this to discard the default setting specified by our parent. */
       ShowWindow (hwnd, SW_HIDE);
+      DragAcceptFiles(hwnd, TRUE);
     }
 }
 
@@ -2949,6 +2956,10 @@
 
   switch (msg) 
     {
+    case WM_DROPFILES:
+      my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
+     
+      return 0;
     case WM_ERASEBKGND:
       f = x_window_to_frame (dpyinfo, hwnd);
       if (f)
@@ -3039,7 +3050,6 @@
     case WM_SYSCHAR:
     case WM_CHAR:
       wmsg.dwModifiers = construct_modifiers (wParam, lParam);
-
       enter_crit ();
       my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
 
@@ -4933,6 +4943,27 @@
   return build_string (buf);
 }
 
+DEFUN ("win32-get-filename", Fwin32_get_filename, Swin32_get_filename, 0, 1, 0,
+   "This will return a dropped filename")
+  (frame)
+     Lisp_Object frame;
+{
+  Lisp_Object file;
+  struct win32_file_list *list;
+
+  if (win32_file_list)
+    {
+      file = build_string(win32_file_list->file_name);
+      list = win32_file_list;
+      win32_file_list = win32_file_list->next;
+      free(list->file_name);
+      free(list);
+
+      return file;
+  }
+  return Qnil;
+}
+
 
 syms_of_win32fns ()
 {
@@ -5048,6 +5079,11 @@
 button down event is generated instead.");
   XSETINT (Vwin32_mouse_button_tolerance, GetDoubleClickTime () / 2);
 
+  DEFVAR_BOOL ("win32-initialized", &win32_initialized,
+	       "Set to true once lisp has been setup to process win32 messages.\n\
+No windows processing request (C-X C-a W) will be queued while this is nil.");
+  win32_initialized = 0;
+
   DEFVAR_INT ("win32-mouse-move-interval",
 	      &Vwin32_mouse_move_interval,
 	      "Minimum interval between mouse move events.\n\
@@ -5131,6 +5167,7 @@
   /* Win32 specific functions */
 
   defsubr (&Swin32_select_font);
+  defsubr (&Swin32_get_filename);
   defsubr (&Swin32_define_rgb_color);
   defsubr (&Swin32_default_color_map);
   defsubr (&Swin32_load_color_file);
diff -u --recursive --new-file emacs-19.33.orig/src/w32term.c emacs-19.33/src/w32term.c
--- emacs-19.33.orig/src/w32term.c	Sat Jul 20 20:04:02 1996
+++ emacs-19.33/src/w32term.c	Fri Nov 29 22:23:32 1996
@@ -47,6 +47,9 @@
 #include "window.h"
 #include "keyboard.h"
 #include "intervals.h"
+#include "w32drop.h"
+
+#include <shellapi.h>
 
 extern void free_frame_menubar ();
 
@@ -155,6 +158,8 @@
 
 static int win32_cursor_to ();
 static int win32_clear_end_of_line ();
+
+struct win32_file_list *win32_file_list = NULL;
 
 #if 0
 /* This is a function useful for recording debugging information
@@ -2365,6 +2370,7 @@
      register int numchars;
      int waitp;
      int expected;
+
 {
   int count = 0;
   int nbytes = 0;
@@ -2395,6 +2401,74 @@
     {
       switch (msg.msg.message)
 	{
+	case WM_DROPFILES:
+	    f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
+
+	    if (f && win32_initialized) 
+	      {
+		int add;
+		KEY_EVENT_RECORD key, *keyp = &key;
+	        WORD cFiles, a;
+		char lpszFile[255]; /* should be enough, even for large paths */ 
+
+		cFiles = DragQueryFile((HANDLE)msg.msg.wParam,
+				       0xFFFFFFFF, (LPSTR)NULL, 0);
+	  
+		for(a=0; a<cFiles; a++)
+		  {
+		    struct win32_file_list *new;
+
+		    DragQueryFile((HANDLE)msg.msg.wParam, a,
+				  lpszFile, sizeof(lpszFile));
+
+		    if (new = malloc(sizeof(struct win32_file_list)))
+		      {
+			new->file_name = _strdup(lpszFile);
+			new->next = win32_file_list;
+			win32_file_list = new;
+		      }
+		  }
+
+		/* Insert C-X into queue */
+		key.bKeyDown = TRUE;
+		key.wRepeatCount = 1;
+		key.wVirtualKeyCode = 88;
+		key.wVirtualScanCode = 45;
+		key.uChar.AsciiChar = 0;
+		key.dwControlKeyState = 8;
+	      
+		add = key_event (keyp, bufp);
+		bufp += add;
+		numchars -= add;
+		count += add;
+
+		/* Insert C-a into queue */
+		key.bKeyDown = TRUE;
+		key.wRepeatCount = 1;
+		key.wVirtualKeyCode = 65;
+		key.wVirtualScanCode = 30;
+		key.uChar.AsciiChar = 0;
+		key.dwControlKeyState = 8;
+		
+		add = key_event (keyp, bufp);
+		bufp += add;
+		numchars -= add;
+		count += add;
+
+		/* Insert W into queue */
+		key.bKeyDown = TRUE;
+		key.wRepeatCount = 1;
+		key.wVirtualKeyCode = 87;
+		key.wVirtualScanCode = 17;
+		key.uChar.AsciiChar = 0;
+		key.dwControlKeyState = 16;
+	      
+		add = key_event (keyp, bufp);
+		bufp += add;
+		numchars -= add;
+		count += add;
+	      }
+	  break;
 	case WM_PAINT:
 	  {
 	    f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
@@ -2455,6 +2529,7 @@
 		  
 		  convert_to_key_event (&msg, keyp);
 		  add = key_event (keyp, bufp);
+
 		  XSETFRAME (bufp->frame_or_window, f);
 		  if (add == -1)
 		    {
--- Cut Here ---

-- 
Michael Illgner
[email-masked]