changeset 59189:60ffced08532

* term/mac-win.el: Require x-dnd. (mac-drag-n-drop): Sync with W32 version. Use x-dnd.el functions. * macfns.c (install_window_handler): Modify extern to return OSErr value. (mac_window): Handle return value of install_window_handler. * macterm.c (reflect_byte): Remove function. (mac_create_bitmap_from_bitmap_data): Don't call it. Lookup table instead. (mac_do_font_lists): Simplify calculation of the longest nonspecial string. [TARGET_API_MAC_CARBON] (init_mac_drag_n_drop): Remove function and declaration. (mac_initialize) [TARGET_API_MAC_CARBON]: Don't call it. [TARGET_API_MAC_CARBON] (mac_do_track_drag): New function and declaration. (install_window_handler): Return OSErr value. (install_window_handler) [TARGET_API_MAC_CARBON]: Register handlers for tracking/receiving drag-and-drop items. (do_ae_open_documents): Generate unibyte strings for filenames. [TARGET_API_MAC_CARBON] (mac_do_receive_drag): Likewise. Reject only non-filename items. Set event modifiers. Set return value.
author Steven Tamm <steventamm@mac.com>
date Wed, 29 Dec 2004 17:25:02 +0000
parents 6b0648eec44c
children 6142d449ffb8
files lisp/ChangeLog lisp/term/mac-win.el src/ChangeLog src/macfns.c src/macterm.c
diffstat 5 files changed, 159 insertions(+), 75 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Wed Dec 29 16:01:49 2004 +0000
+++ b/lisp/ChangeLog	Wed Dec 29 17:25:02 2004 +0000
@@ -1,3 +1,9 @@
+2004-12-29  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
+
+	* term/mac-win.el: Require x-dnd.
+	(mac-drag-n-drop): Sync with W32 version.  Use x-dnd.el
+	functions.
+
 2004-12-29  David Kastrup  <dak@gnu.org>
 
 	* international/mule.el (decode-coding-inserted-region): Don't
--- a/lisp/term/mac-win.el	Wed Dec 29 16:01:49 2004 +0000
+++ b/lisp/term/mac-win.el	Wed Dec 29 17:25:02 2004 +0000
@@ -76,7 +76,7 @@
 ;;(require 'select)
 (require 'menu-bar)
 (require 'fontset)
-;;(require 'x-dnd)
+(require 'x-dnd)
 
 (defvar x-invocation-args)
 
@@ -1564,7 +1564,7 @@
 (mouse-wheel-mode 1)
 
 (defun mac-drag-n-drop (event)
-  "Edit the files listed in the drag-n-drop event.\n\
+  "Edit the files listed in the drag-n-drop EVENT.
 Switch to a buffer editing the last file dropped."
   (interactive "e")
   (save-excursion
@@ -1577,16 +1577,11 @@
 	   (y (cdr coords)))
       (if (and (> x 0) (> y 0))
 	  (set-frame-selected-window nil window))
-      (mapcar
-       '(lambda (file)
-	  (find-file
-	   (decode-coding-string
-	    file
-	    (or file-name-coding-system
-		default-file-name-coding-system))))
-       (car (cdr (cdr event)))))
-  (raise-frame)
-  (recenter)))
+      (mapcar (lambda (file-name) 
+		(x-dnd-handle-one-url window 'private 
+				      (concat "file:" file-name)))
+	      (car (cdr (cdr event)))))
+    (raise-frame)))
 
 (global-set-key [drag-n-drop] 'mac-drag-n-drop)
 
--- a/src/ChangeLog	Wed Dec 29 16:01:49 2004 +0000
+++ b/src/ChangeLog	Wed Dec 29 17:25:02 2004 +0000
@@ -1,3 +1,25 @@
+2004-12-29  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
+
+	* macfns.c (install_window_handler): Modify extern to return OSErr
+	value.
+	(mac_window): Handle return value of install_window_handler.
+
+	* macterm.c (reflect_byte): Remove function.
+	(mac_create_bitmap_from_bitmap_data): Don't call reflect_byte.
+	Lookup table instead.
+	(mac_do_font_lists): Simplify calculation of the longest
+	nonspecial string.
+	(init_mac_drag_n_drop): Remove function	and declaration.
+	(mac_initialize) [TARGET_API_MAC_CARBON]: Don't call
+	init_mac_drag_n_drop.
+	(mac_do_track_drag): New function and declaration.
+	(install_window_handler): Return OSErr value.
+	(install_window_handler) [TARGET_API_MAC_CARBON]: Register
+	handlers for tracking/receiving drag-and-drop items.
+	(do_ae_open_documents): Generate unibyte strings for filenames.
+	(mac_do_receive_drag) [TARGET_API_MAC_CARBON] : Likewise.  Reject
+	only non-filename items.  Set event modifiers.  Set return value.
+
 2004-12-28  Dan Nicolaescu  <dann@ics.uci.edu>
 
 	* coding.c (decode_coding): Fix previous change.
--- a/src/macfns.c	Wed Dec 29 16:01:49 2004 +0000
+++ b/src/macfns.c	Wed Dec 29 17:25:02 2004 +0000
@@ -158,7 +158,7 @@
 
 extern Lisp_Object Vwindow_system_version;
 
-#if 0 /* Use xstricmp instead. */
+#if 0 /* Use xstricmp instead.  */
 /* compare two strings ignoring case */
 
 static int
@@ -2261,7 +2261,7 @@
 
 /* Create and set up the Mac window for frame F.  */
 
-extern install_window_handler (WindowPtr);
+extern OSErr install_window_handler (WindowPtr);
 
 static void
 mac_window (f)
@@ -2282,7 +2282,11 @@
   if (FRAME_MAC_WINDOW (f))
     {
       SetWRefCon (FRAME_MAC_WINDOW (f), (long) f->output_data.mac);
-      install_window_handler (FRAME_MAC_WINDOW (f));
+      if (install_window_handler (FRAME_MAC_WINDOW (f)) != noErr)
+	{
+	  DisposeWindow (FRAME_MAC_WINDOW (f));
+	  FRAME_MAC_WINDOW (f) = NULL;
+	}
     }
 #else
   FRAME_MAC_WINDOW (f)
--- a/src/macterm.c	Wed Dec 29 16:01:49 2004 +0000
+++ b/src/macterm.c	Wed Dec 29 17:25:02 2004 +0000
@@ -511,23 +511,6 @@
 }
 
 
-/* XBM bits seem to be backward within bytes compared with how
-   Mac does things.  */
-static unsigned char
-reflect_byte (orig)
-     unsigned char orig;
-{
-  int i;
-  unsigned char reflected = 0x00;
-  for (i = 0; i < 8; i++)
-    {
-      if (orig & (0x01 << i))
-	reflected |= 0x80 >> i;
-    }
-  return reflected;
-}
-
-
 /* Mac replacement for XCreateBitmapFromBitmapData.  */
 
 static void
@@ -536,6 +519,11 @@
      char *bits;
      int w, h;
 {
+  static unsigned char swap_nibble[16]
+    = { 0x0, 0x8, 0x4, 0xc,    /* 0000 1000 0100 1100 */
+	0x2, 0xa, 0x6, 0xe,    /* 0010 1010 0110 1110 */
+	0x1, 0x9, 0x5, 0xd,    /* 0001 1001 0101 1101 */
+	0x3, 0xb, 0x7, 0xf };  /* 0011 1011 0111 1111 */
   int i, j, w1;
   char *p;
 
@@ -547,7 +535,12 @@
     {
       p = bitmap->baseAddr + i * bitmap->rowBytes;
       for (j = 0; j < w1; j++)
-        *p++ = reflect_byte (*bits++);
+	{
+	  /* Bitswap XBM bytes to match how Mac does things.  */
+	  unsigned char c = *bits++;
+	  *p++ = (unsigned char)((swap_nibble[c & 0xf] << 4)
+				 | (swap_nibble[(c>>4) & 0xf]));;
+	}
     }
 
   SetRect (&(bitmap->bounds), 0, 0, w, h);
@@ -6256,7 +6249,7 @@
   char *ptr;
   int scl_val[XLFD_SCL_LAST], *field, *val;
   char *longest_start, *cur_start, *nonspecial;
-  int longest_len, cur_len, exact;
+  int longest_len, exact;
 
   if (font_name_table == NULL)  /* Initialize when first used.  */
     init_font_name_table ();
@@ -6318,7 +6311,7 @@
   *ptr++ = '^';
 
   longest_start = cur_start = ptr;
-  longest_len = cur_len = 0;
+  longest_len = 0;
   exact = 1;
 
   /* Turn pattern into a regexp and do a regexp match.  Also find the
@@ -6327,12 +6320,11 @@
     {
       if (*pattern == '?' || *pattern == '*')
 	{
-	  if (cur_len > longest_len)
+	  if (ptr - cur_start > longest_len)
 	    {
 	      longest_start = cur_start;
-	      longest_len = cur_len;
+	      longest_len = ptr - cur_start;
 	    }
-	  cur_len = 0;
 	  exact = 0;
 
 	  if (*pattern == '?')
@@ -6342,21 +6334,16 @@
 	      *ptr++ = '.';
 	      *ptr++ = '*';
 	    }
+	  cur_start = ptr;
 	}
       else
-	{
-	  if (cur_len == 0)
-	    cur_start = ptr;
-	  cur_len++;
-
-	  *ptr++ = tolower (*pattern);
-	}
-    }
-
-  if (cur_len > longest_len)
+	*ptr++ = tolower (*pattern);
+    }
+
+  if (ptr - cur_start > longest_len)
     {
       longest_start = cur_start;
-      longest_len = cur_len;
+      longest_len = ptr - cur_start;
     }
 
   *ptr = '$';
@@ -7086,7 +7073,7 @@
 
 #if TARGET_API_MAC_CARBON
 /* Drag and Drop */
-static OSErr init_mac_drag_n_drop ();
+static pascal OSErr mac_do_track_drag (DragTrackingMessage, WindowPtr, void*, DragReference);
 static pascal OSErr mac_do_receive_drag (WindowPtr, void*, DragReference);
 #endif
 
@@ -7098,7 +7085,7 @@
 static pascal OSStatus mac_handle_window_event (EventHandlerCallRef,
 						EventRef, void *);
 #endif
-void install_window_handler (WindowPtr);
+OSErr install_window_handler (WindowPtr);
 
 extern void init_emacs_passwd_dir ();
 extern int emacs_main (int, char **, char **);
@@ -7659,16 +7646,6 @@
   x_real_positions (f, &f->left_pos, &f->top_pos);
 }
 
-#if TARGET_API_MAC_CARBON
-/* Initialize Drag And Drop to allow files to be dropped onto emacs frames */
-static OSErr
-init_mac_drag_n_drop ()
-{
-  OSErr result = InstallReceiveHandler (mac_do_receive_drag, 0L, NULL);
-  return result;
-}
-#endif
-
 /* Intialize AppleEvent dispatcher table for the required events.  */
 void
 init_required_apple_events ()
@@ -7909,10 +7886,11 @@
 #endif	/* USE_CARBON_EVENTS */
 
 
-void
+OSErr
 install_window_handler (window)
      WindowPtr window;
 {
+  OSErr err = noErr;
 #if USE_CARBON_EVENTS
   EventTypeSpec specs[] = {{kEventClassWindow, kEventWindowBoundsChanging}};
   static EventHandlerUPP handle_window_event_UPP = NULL;
@@ -7920,9 +7898,17 @@
   if (handle_window_event_UPP == NULL)
     handle_window_event_UPP = NewEventHandlerUPP (mac_handle_window_event);
 
-  InstallWindowEventHandler (window, handle_window_event_UPP,
-			     GetEventTypeCount (specs), specs, NULL, NULL);
-#endif
+  err = InstallWindowEventHandler (window, handle_window_event_UPP,
+				   GetEventTypeCount (specs), specs,
+				   NULL, NULL);
+#endif
+#if TARGET_API_MAC_CARBON
+  if (err == noErr)
+    err = InstallTrackingHandler (mac_do_track_drag, window, NULL);
+  if (err == noErr)
+    err = InstallReceiveHandler (mac_do_receive_drag, window, NULL);
+#endif
+  return err;
 }
 
 
@@ -8004,8 +7990,11 @@
 					fs.name) &&
 		mac_to_posix_pathname (path_name, unix_path_name, 255))
 #endif
-	      drag_and_drop_file_list = Fcons (build_string (unix_path_name),
-					       drag_and_drop_file_list);
+	      /* x-dnd functions expect undecoded filenames.  */
+	      drag_and_drop_file_list =
+		Fcons (make_unibyte_string (unix_path_name,
+					    strlen (unix_path_name)),
+		       drag_and_drop_file_list);
 	  }
       }
   }
@@ -8022,6 +8011,67 @@
 
 #if TARGET_API_MAC_CARBON
 static pascal OSErr
+mac_do_track_drag (DragTrackingMessage message, WindowPtr window,
+		   void *handlerRefCon, DragReference theDrag)
+{
+  static int can_accept;
+  short items;
+  short index;
+  ItemReference theItem;
+  FlavorFlags theFlags;
+  OSErr result;
+
+  switch (message)
+    {
+    case kDragTrackingEnterHandler:
+      CountDragItems (theDrag, &items);
+      can_accept = 1;
+      for (index = 1; index <= items; index++)
+	{
+	  GetDragItemReferenceNumber (theDrag, index, &theItem);
+	  result = GetFlavorFlags (theDrag, theItem, flavorTypeHFS, &theFlags);
+	  if (result != noErr)
+	    {
+	      can_accept = 0;
+	      break;
+	    }
+	}
+      break;
+
+    case kDragTrackingEnterWindow:
+      if (can_accept)
+	{
+	  RgnHandle hilite_rgn = NewRgn ();
+	  Rect r;
+
+	  GetWindowPortBounds (window, &r);
+	  OffsetRect (&r, -r.left, -r.top);
+	  RectRgn (hilite_rgn, &r);
+	  ShowDragHilite (theDrag, hilite_rgn, true);
+	  DisposeRgn (hilite_rgn);
+	  SetThemeCursor (kThemeCopyArrowCursor);
+	}
+      break;
+
+    case kDragTrackingInWindow:
+      break;
+
+    case kDragTrackingLeaveWindow:
+      if (can_accept)
+	{
+	  HideDragHilite (theDrag);
+	  SetThemeCursor (kThemeArrowCursor);
+	}
+      break;
+
+    case kDragTrackingLeaveHandler:
+      break;
+    }
+
+  return noErr;
+}
+
+static pascal OSErr
 mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
 		     DragReference theDrag)
 {
@@ -8062,11 +8112,14 @@
 				      data.fileSpec.parID, data.fileSpec.name) &&
 	      mac_to_posix_pathname (path_name, unix_path_name, 255))
 #endif
-            drag_and_drop_file_list = Fcons (build_string (unix_path_name),
-					     drag_and_drop_file_list);
+	    /* x-dnd functions expect undecoded filenames.  */
+            drag_and_drop_file_list =
+	      Fcons (make_unibyte_string (unix_path_name,
+					  strlen (unix_path_name)),
+		     drag_and_drop_file_list);
 	}
       else
-	return;
+	continue;
     }
   /* If there are items in the list, construct an event and post it to
      the queue like an interrupt using kbd_buffer_store_event.  */
@@ -8075,12 +8128,14 @@
       struct input_event event;
       Lisp_Object frame;
       struct frame *f = mac_window_to_frame (window);
-      SetPortWindowPort (window);
+      SInt16 modifiers;
+
       GlobalToLocal (&mouse);
+      GetDragModifiers (theDrag, NULL, NULL, &modifiers);
 
       event.kind = DRAG_N_DROP_EVENT;
       event.code = 0;
-      event.modifiers = 0;
+      event.modifiers = mac_to_emacs_modifiers (modifiers);
       event.timestamp = TickCount () * (1000 / 60);
       XSETINT (event.x, mouse.h);
       XSETINT (event.y, mouse.v);
@@ -8095,7 +8150,11 @@
 	GetCurrentProcess (&psn);
 	SetFrontProcess (&psn);
       }
-    }
+
+      return noErr;
+    }
+  else
+    return dragNotAcceptedErr;
 }
 #endif
 
@@ -9580,8 +9639,6 @@
 #if TARGET_API_MAC_CARBON
   init_required_apple_events ();
 
-  init_mac_drag_n_drop ();
-
 #if USE_CARBON_EVENTS
   init_service_handler ();