Index: macterm.c =================================================================== RCS file: /cvsroot/emacs/emacs/src/macterm.c,v retrieving revision 1.106 diff -p -u -w -u -r1.106 macterm.c --- macterm.c 16 Mar 2005 08:08:06 -0000 1.106 +++ macterm.c 5 Apr 2005 20:23:29 -0000 @@ -7155,7 +7159,8 @@ int current_mac_keyboard_text_encoding = drag and drop events. */ Lisp_Object Qmac_ready_for_drag_n_drop; -Lisp_Object drag_and_drop_file_list; +/* List of objects for a pending drag-n-drop event. */ +Lisp_Object drag_and_drop_list; Point saved_menu_event_location; @@ -8078,10 +8083,10 @@ do_ae_open_documents(AppleEvent *message err = AEGetParamPtr (message, keyAEPosition, typeChar, &actual_type, &position, sizeof(SelectionRange), &actual_size); if (err == noErr) - drag_and_drop_file_list = Fcons (list3 (make_number (position.lineNum + 1), + drag_and_drop_list = Fcons (list3 (make_number (position.lineNum + 1), make_number (position.startRange + 1), make_number (position.endRange + 1)), - drag_and_drop_file_list); + drag_and_drop_list); /* Check to see that we got all of the required parameters from the event descriptor. For an 'odoc' event this should just be the @@ -8135,10 +8140,11 @@ do_ae_open_documents(AppleEvent *message sizeof (unix_path_name) - 1) == noErr) #endif /* 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); + drag_and_drop_list = + Fcons (Fcons (intern("file"), + make_unibyte_string (unix_path_name, + strlen (unix_path_name))), + drag_and_drop_list); } } } @@ -8152,8 +8158,27 @@ descriptor_error_exit: return err; } - #if TARGET_API_MAC_CARBON + +static FlavorType +mac_favorite_flavor (DragReference theDrag, ItemReference theItem, + FlavorFlags* theFlags) +{ + const FlavorType accepted_flavors[] = { + flavorTypeHFS, + flavorTypeDirectory, + 'url ', + 'utxt', + 0 + }; + int j; + for (j = 0; accepted_flavors[j]; j++) + if (GetFlavorFlags (theDrag, theItem, accepted_flavors[j], &theFlags) + == noErr) + return accepted_flavors[j]; + return 0; +} + static pascal OSErr mac_do_track_drag (DragTrackingMessage message, WindowPtr window, void *handlerRefCon, DragReference theDrag) @@ -8176,8 +8201,7 @@ mac_do_track_drag (DragTrackingMessage m for (index = 1; index <= items; index++) { GetDragItemReferenceNumber (theDrag, index, &theItem); - result = GetFlavorFlags (theDrag, theItem, flavorTypeHFS, &theFlags); - if (result == noErr) + if (mac_favorite_flavor (theDrag, theItem, &theFlags) != 0) { can_accept = 1; break; @@ -8231,28 +8255,33 @@ mac_do_receive_drag (WindowPtr window, v Point mouse; OSErr result; ItemReference theItem; - HFSFlavor data; - Size size = sizeof (HFSFlavor); if (GetFrontWindowOfClass (kMovableModalWindowClass, false)) return dragNotAcceptedErr; - drag_and_drop_file_list = Qnil; + drag_and_drop_list = Qnil; GetDragMouse (theDrag, &mouse, 0L); CountDragItems (theDrag, &items); for (index = 1; index <= items; index++) { - /* Only handle file references. */ + FlavorType flavor; + GetDragItemReferenceNumber (theDrag, index, &theItem); - result = GetFlavorFlags (theDrag, theItem, flavorTypeHFS, &theFlags); - if (result == noErr) + flavor = mac_favorite_flavor (theDrag, theItem, &theFlags); + switch (flavor) + { + case flavorTypeHFS: + case flavorTypeDirectory: + /* Handle file/directory references. */ { + HFSFlavor data; + Size size = sizeof (HFSFlavor); #ifdef MAC_OSX FSRef fref; #endif char unix_path_name[MAXPATHLEN]; - GetFlavorData (theDrag, theItem, flavorTypeHFS, &data, &size, 0L); + GetFlavorData (theDrag, theItem, flavor, &data, &size, 0L); #ifdef MAC_OSX /* Use Carbon routines, otherwise it converts the file name to /Macintosh HD/..., which is not correct. */ @@ -8262,16 +8291,52 @@ mac_do_receive_drag (WindowPtr window, v if (fsspec_to_posix_pathname (&data.fileSpec, unix_path_name, sizeof (unix_path_name) - 1) == noErr) #endif - /* x-dnd functions expect undecoded filenames. */ - drag_and_drop_file_list = - Fcons (make_unibyte_string (unix_path_name, + /* x-dnd functions expect undecoded filenames, but we + don't have to follow that. */ + drag_and_drop_list = + Fcons (Fcons + (intern ("file"), + Fdecode_coding_string + (make_unibyte_string (unix_path_name, strlen (unix_path_name)), - drag_and_drop_file_list); + NILP (Vfile_name_coding_system) + ? Vdefault_file_name_coding_system + : Vfile_name_coding_system, + Qnil)), + drag_and_drop_list); + } + break; + + case 'url ': + case 'utxt': + { + Size size; + char * data; + if (GetFlavorDataSize (theDrag, theItem, flavor, &size) != noErr) + break; + data = xmalloc (size + 1); + GetFlavorData (theDrag, theItem, flavor, data, &size, 0L); + if (flavor == 'url ') + drag_and_drop_list = + Fcons (Fcons (intern ("url"), + make_unibyte_string (data, size)), + drag_and_drop_list); + else + drag_and_drop_list = + Fcons (Fcons (intern ("text"), + Fdecode_coding_string + (make_unibyte_string (data, size), + intern ("utf-16"), + Qnil)), + drag_and_drop_list); + free (data); } + break; + }; } /* If there are items in the list, construct an event and post it to the queue like an interrupt using kbd_buffer_store_event. */ - if (!NILP (drag_and_drop_file_list)) + if (!NILP (drag_and_drop_list)) { struct input_event event; Lisp_Object frame; @@ -8288,7 +8353,7 @@ mac_do_receive_drag (WindowPtr window, v XSETINT (event.x, mouse.h); XSETINT (event.y, mouse.v); XSETFRAME (frame, f); - event.frame_or_window = Fcons (frame, drag_and_drop_file_list); + event.frame_or_window = Fcons (frame, drag_and_drop_list); event.arg = Qnil; /* Post to the interrupt queue */ kbd_buffer_store_event (&event); @@ -8298,12 +8363,13 @@ mac_do_receive_drag (WindowPtr window, v GetCurrentProcess (&psn); SetFrontProcess (&psn); } - return noErr; } else + { return dragNotAcceptedErr; } +} #endif @@ -9091,13 +9157,13 @@ XTread_socket (sd, expected, hold_quit) break; case kHighLevelEvent: - drag_and_drop_file_list = Qnil; + drag_and_drop_list = Qnil; AEProcessAppleEvent(&er); /* Build a DRAG_N_DROP_EVENT type event as is done in constuct_drag_n_drop in w32term.c. */ - if (!NILP (drag_and_drop_file_list)) + if (!NILP (drag_and_drop_list)) { struct frame *f = NULL; WindowPtr wp; @@ -9129,7 +9195,7 @@ XTread_socket (sd, expected, hold_quit) XSETINT (inev.y, 0); XSETFRAME (frame, f); - inev.frame_or_window = Fcons (frame, drag_and_drop_file_list); + inev.frame_or_window = Fcons (frame, drag_and_drop_list); /* Regardless of whether Emacs was suspended or in the foreground, ask it to redraw its entire screen.