home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / patches / 6.2.211 < prev    next >
Encoding:
Internet Message Format  |  2004-01-24  |  19.8 KB

  1. To: vim-dev@vim.org
  2. Subject: Patch 6.2.211 (extra)
  3. Fcc: outbox
  4. From: Bram Moolenaar <Bram@moolenaar.net>
  5. Mime-Version: 1.0
  6. Content-Type: text/plain; charset=ISO-8859-1
  7. Content-Transfer-Encoding: 8bit
  8. ------------
  9.  
  10. Patch 6.2.211 (extra)
  11. Problem:    Code for handling file dropped on Vim is duplicated.
  12. Solution:   Move the common code to gui_handle_drop().
  13.         Add code to drop the files in the window under the cursor.
  14.         Support drag&drop on the Macintosh.  (Taro Muraoka)
  15.         When dropping a directory name edit that directory (using the
  16.         explorer plugin)
  17.         Fix that changing directory with Shift pressed didn't work for
  18.         relative path names.
  19. Files:        src/fileio.c, src/gui.c, src/gui_gtk_x11.c, src/gui_mac.c,
  20.         src/gui_w48.c, src/proto/fileio.pro, src/proto/gui.pro
  21.  
  22.  
  23. *** ../vim-6.2.210/src/fileio.c    Sun Jan 18 21:31:56 2004
  24. --- src/fileio.c    Wed Jan 21 14:49:33 2004
  25. ***************
  26. *** 4834,4839 ****
  27. --- 4834,4840 ----
  28.   }
  29.   
  30.   /*
  31. +  * Shorten filenames for all buffers.
  32.    * When "force" is TRUE: Use full path from now on for files currently being
  33.    * edited, both for file name and swap file name.  Try to shorten the file
  34.    * names a bit, if safe to do so.
  35. ***************
  36. *** 4879,4884 ****
  37. --- 4880,4919 ----
  38.   #endif
  39.   }
  40.   
  41. + #if (defined(FEAT_DND) && defined(FEAT_GUI_GTK)) \
  42. +     || defined(FEAT_GUI_MSWIN) \
  43. +     || defined(FEAT_GUI_MAC) \
  44. +     || defined(PROTO)
  45. + /*
  46. +  * Shorten all filenames in "fnames[count]" by current directory.
  47. +  */
  48. +     void
  49. + shorten_filenames(fnames, count)
  50. +     char_u    **fnames;
  51. +     int        count;
  52. + {
  53. +     int        i;
  54. +     char_u    dirname[MAXPATHL];
  55. +     char_u    *p;
  56. +     if (fnames == NULL || count < 1)
  57. +     return;
  58. +     mch_dirname(dirname, sizeof(dirname));
  59. +     for (i = 0; i < count; ++i)
  60. +     {
  61. +     if ((p = shorten_fname(fnames[i], dirname)) != NULL)
  62. +     {
  63. +         /* shorten_fname() returns pointer in given "fnames[i]".  If free
  64. +          * "fnames[i]" first, "p" becomes invalid.  So we need to copy
  65. +          * "p" first then free fnames[i]. */
  66. +         p = vim_strsave(p);
  67. +         vim_free(fnames[i]);
  68. +         fnames[i] = p;
  69. +     }
  70. +     }
  71. + }
  72. + #endif
  73.   /*
  74.    * add extention to file name - change path/fo.o.h to path/fo.o.h.ext or
  75.    * fo_o_h.ext for MSDOS or when shortname option set.
  76. *** ../vim-6.2.210/src/gui.c    Thu Jan  8 20:54:45 2004
  77. --- src/gui.c    Thu Jan 22 16:53:48 2004
  78. ***************
  79. *** 4481,4483 ****
  80. --- 4481,4615 ----
  81.   }
  82.   
  83.   #endif
  84. + #if (defined(FEAT_DND) && defined(FEAT_GUI_GTK)) \
  85. +     || defined(FEAT_GUI_MSWIN) \
  86. +     || defined(FEAT_GUI_MAC) \
  87. +     || defined(PROTO)
  88. + #ifdef FEAT_WINDOWS
  89. + static void gui_wingoto_xy __ARGS((int x, int y));
  90. + /*
  91. +  * Jump to the window at specified point (x, y).
  92. +  */
  93. +     static void
  94. + gui_wingoto_xy(x, y)
  95. +     int x;
  96. +     int y;
  97. + {
  98. +     int        row = Y_2_ROW(y);
  99. +     int        col = X_2_COL(x);
  100. +     win_T    *wp;
  101. +     if (row >= 0 && col >= 0)
  102. +     {
  103. +     wp = mouse_find_win(&row, &col);
  104. +     if (wp != NULL && wp != curwin)
  105. +         win_goto(wp);
  106. +     }
  107. + }
  108. + #endif
  109. + /*
  110. +  * Process file drop.  Mouse cursor position, key modifiers, name of files
  111. +  * and count of files are given.  Argument "fnames[count]" has full pathnames
  112. +  * of dropped files, they will be freed in this function, and caller can't use
  113. +  * fnames after call this function.
  114. +  */
  115. + /*ARGSUSED*/
  116. +     void
  117. + gui_handle_drop(x, y, modifiers, fnames, count)
  118. +     int        x;
  119. +     int        y;
  120. +     int_u    modifiers;
  121. +     char_u    **fnames;
  122. +     int        count;
  123. + {
  124. +     int        i;
  125. +     char_u    *p;
  126. +     /*
  127. +      * When the cursor is at the command line, add the file names to the
  128. +      * command line, don't edit the files.
  129. +      */
  130. +     if (State & CMDLINE)
  131. +     {
  132. +     shorten_filenames(fnames, count);
  133. +     for (i = 0; i < count; ++i)
  134. +     {
  135. +         if (fnames[i] != NULL)
  136. +         {
  137. +         if (i > 0)
  138. +             add_to_input_buf((char_u*)" ", 1);
  139. +         /* We don't know what command is used thus we can't be sure
  140. +          * about which characters need to be escaped.  Only escape the
  141. +          * most common ones. */
  142. + # ifdef BACKSLASH_IN_FILENAME
  143. +         p = vim_strsave_escaped(fnames[i], (char_u *)" \t\"|");
  144. + # else
  145. +         p = vim_strsave_escaped(fnames[i], (char_u *)"\\ \t\"|");
  146. + # endif
  147. +         if (p != NULL)
  148. +             add_to_input_buf(p, (int)STRLEN(p));
  149. +         vim_free(p);
  150. +         vim_free(fnames[i]);
  151. +         }
  152. +     }
  153. +     vim_free(fnames);
  154. +     }
  155. +     else
  156. +     {
  157. +     /* Go to the window under mouse cursor, then shorten given "fnames" by
  158. +      * current window, because a window can have local current dir. */
  159. + # ifdef FEAT_WINDOWS
  160. +     gui_wingoto_xy(x, y);
  161. + # endif
  162. +     shorten_filenames(fnames, count);
  163. +     /* If Shift held down, remember the first item. */
  164. +     if ((modifiers & MOUSE_SHIFT) != 0)
  165. +         p = vim_strsave(fnames[0]);
  166. +     else
  167. +         p = NULL;
  168. +     /* Handle the drop, :edit or :split to get to the file.  This also
  169. +      * frees fnames[].  Skip this if there is only one item it's a
  170. +      * directory and Shift is held down. */
  171. +     if (count == 1 && (modifiers & MOUSE_SHIFT) != 0
  172. +                              && mch_isdir(fnames[0]))
  173. +     {
  174. +         vim_free(fnames[0]);
  175. +         vim_free(fnames);
  176. +     }
  177. +     else
  178. +         handle_drop(count, fnames, (modifiers & MOUSE_CTRL) != 0);
  179. +     /* If Shift held down, change to first file's directory.  If the first
  180. +      * item is a directory, change to that directory (and let the explorer
  181. +      * plugin show the contents). */
  182. +     if (p != NULL)
  183. +     {
  184. +         if (mch_isdir(p))
  185. +         {
  186. +         if (mch_chdir((char *)p) == 0)
  187. +             shorten_fnames(TRUE);
  188. +         }
  189. +         else if (vim_chdirfile(p) == OK)
  190. +         shorten_fnames(TRUE);
  191. +         vim_free(p);
  192. +     }
  193. +     /* Update the screen display */
  194. +     update_screen(NOT_VALID);
  195. + # ifdef FEAT_MENU
  196. +     gui_update_menus(0);
  197. + # endif
  198. +     setcursor();
  199. +     out_flush();
  200. +     gui_update_cursor(FALSE, FALSE);
  201. +     gui_mch_flush();
  202. +     }
  203. + }
  204. + #endif
  205. *** ../vim-6.2.210/src/gui_gtk_x11.c    Sun Jan 11 12:45:02 2004
  206. --- src/gui_gtk_x11.c    Wed Jan 21 16:07:00 2004
  207. ***************
  208. *** 1823,1981 ****
  209.    * Drag aNd Drop support handlers.
  210.    */
  211.   
  212. !     static void
  213. ! drag_handle_uri_list(GdkDragContext    *context,
  214. !              GtkSelectionData    *data,
  215. !              guint        time_,
  216. !              GdkModifierType    state)
  217.   {
  218. !     char_u  **fnames;
  219. !     int        redo_dirs = FALSE;
  220. !     int        i;
  221. !     int        n;
  222. !     char_u  *start;
  223. !     char_u  *copy;
  224. !     char_u  *names;
  225. !     int        nfiles = 0;
  226. !     int        url = FALSE;
  227.   
  228. !     names = data->data;
  229. !     copy = alloc((unsigned)(data->length + 1));
  230. !     if (copy == NULL)
  231. !     return;
  232. !     /*
  233. !      * Count how many items there may be and separate them with a NUL.
  234. !      * Apparently the items are separated with \r\n.  This is not documented,
  235. !      * thus be careful not to go past the end.    Also allow separation with NUL
  236. !      * characters.
  237. !      */
  238. !     start = copy;
  239. !     for (i = 0; i < data->length; ++i)
  240.       {
  241. !     if (names[i] == NUL || names[i] == '\n' || names[i] == '\r')
  242.       {
  243. !         if (start > copy && start[-1] != NUL)
  244.           {
  245. !         ++nfiles;
  246. !         *start++ = NUL;
  247.           }
  248.       }
  249. !     else if (names[i] == '%' && i + 2 < data->length
  250. !                           && hexhex2nr(names + i + 1) > 0)
  251.       {
  252. !         *start++ = hexhex2nr(names + i + 1);
  253.           i += 2;
  254.       }
  255.       else
  256. !         *start++ = names[i];
  257.       }
  258. !     if (start > copy && start[-1] != NUL)
  259.       {
  260. !     *start = NUL;    /* last item didn't have \r or \n */
  261. !     ++nfiles;
  262.       }
  263.   
  264. !     fnames = (char_u **)alloc((unsigned)(nfiles * sizeof(char_u *)));
  265. !     if (fnames == NULL)
  266. !     {
  267. !     vim_free(copy);
  268. !     return;
  269. !     }
  270. !     url = FALSE;    /* Set when a non-file URL was found. */
  271. !     start = copy;
  272. !     for (n = 0; n < nfiles; ++n)
  273.       {
  274. !     if (STRNCMP(start, "file://localhost", 16) == 0)
  275. !         start += 16;
  276. !     else
  277.       {
  278. !         if (STRNCMP(start, "file:", 5) != 0)
  279. !         url = TRUE;
  280. !         else
  281. !         {
  282. !         start += 5;
  283. !         while (start[0] == '/' && start[1] == '/')
  284. !             ++start;
  285. !         }
  286.       }
  287. !     fnames[n] = vim_strsave(start);
  288. !     start += STRLEN(start) + 1;
  289.       }
  290.   
  291. !     /* accept */
  292. !     gtk_drag_finish(context, TRUE, FALSE, time_);
  293.   
  294. !     /* Special handling when all items are real files. */
  295. !     if (url == FALSE)
  296. !     {
  297. !     if (nfiles == 1)
  298. !     {
  299. !         if (fnames[0] != NULL && mch_isdir(fnames[0]))
  300. !         {
  301. !         /* Handle dropping a directory on Vim. */
  302. !         if (mch_chdir((char *)fnames[0]) == 0)
  303. !         {
  304. !             vim_free(fnames[0]);
  305. !             fnames[0] = NULL;
  306. !             redo_dirs = TRUE;
  307. !         }
  308. !         }
  309. !     }
  310. !     else
  311. !     {
  312. !         /* Ignore any directories */
  313. !         for (i = 0; i < nfiles; ++i)
  314. !         {
  315. !         if (fnames[i] != NULL && mch_isdir(fnames[i]))
  316. !         {
  317. !             vim_free(fnames[i]);
  318. !             fnames[i] = NULL;
  319. !         }
  320. !         }
  321. !     }
  322.   
  323. !     if (state & GDK_SHIFT_MASK)
  324. !     {
  325. !         /* Shift held down, change to first file's directory */
  326. !         if (fnames[0] != NULL && vim_chdirfile(fnames[0]) == OK)
  327. !         redo_dirs = TRUE;
  328. !     }
  329. !     else
  330. !     {
  331. !         char_u    dirname[MAXPATHL];
  332. !         char_u    *s;
  333.   
  334. !         /* Shorten dropped file names. */
  335. !         if (mch_dirname(dirname, MAXPATHL) == OK)
  336. !         for (i = 0; i < nfiles; ++i)
  337. !             if (fnames[i] != NULL)
  338. !             {
  339. !             s = shorten_fname(fnames[i], dirname);
  340. !             if (s != NULL && (s = vim_strsave(s)) != NULL)
  341. !             {
  342. !                 vim_free(fnames[i]);
  343. !                 fnames[i] = s;
  344. !             }
  345. !             }
  346. !     }
  347. !     }
  348. !     vim_free(copy);
  349.   
  350. !     /* Handle the drop, :edit or :split to get to the file */
  351. !     handle_drop(nfiles, fnames, (state & GDK_CONTROL_MASK) != 0);
  352.   
  353. !     if (redo_dirs)
  354. !     shorten_fnames(TRUE);
  355.   
  356. !     /* Update the screen display */
  357. !     update_screen(NOT_VALID);
  358. ! # ifdef FEAT_MENU
  359. !     gui_update_menus(0);
  360. ! # endif
  361. !     setcursor();
  362. !     out_flush();
  363. !     gui_update_cursor(FALSE, FALSE);
  364. !     gui_mch_flush();
  365.   }
  366.   
  367.       static void
  368. --- 1823,1940 ----
  369.    * Drag aNd Drop support handlers.
  370.    */
  371.   
  372. ! /*
  373. !  * Count how many items there may be and separate them with a NUL.
  374. !  * Apparently the items are separated with \r\n.  This is not documented,
  375. !  * thus be careful not to go past the end.    Also allow separation with
  376. !  * NUL characters.
  377. !  */
  378. !     static int
  379. ! count_and_decode_uri_list(char_u *out, char_u *raw, int len)
  380.   {
  381. !     int        i;
  382. !     char_u    *p = out;
  383. !     int        count = 0;
  384.   
  385. !     for (i = 0; i < len; ++i)
  386.       {
  387. !     if (raw[i] == NUL || raw[i] == '\n' || raw[i] == '\r')
  388.       {
  389. !         if (p > out && p[-1] != NUL)
  390.           {
  391. !         ++count;
  392. !         *p++ = NUL;
  393.           }
  394.       }
  395. !     else if (raw[i] == '%' && i + 2 < len && hexhex2nr(raw + i + 1) > 0)
  396.       {
  397. !         *p++ = hexhex2nr(raw + i + 1);
  398.           i += 2;
  399.       }
  400.       else
  401. !         *p++ = raw[i];
  402.       }
  403. !     if (p > out && p[-1] != NUL)
  404.       {
  405. !     *p = NUL;    /* last item didn't have \r or \n */
  406. !     ++count;
  407.       }
  408. +     return count;
  409. + }
  410.   
  411. ! /*
  412. !  * Parse NUL separated "src" strings.  Make it an array "outlist" form.  On
  413. !  * this process, URI which protocol is not "file:" are removed.  Return
  414. !  * length of array (less than "max").
  415. !  */
  416. !     static int
  417. ! filter_uri_list(char_u **outlist, int max, char_u *src)
  418. ! {
  419. !     int    i, j;
  420. !     for (i = j = 0; i < max; ++i)
  421.       {
  422. !     outlist[i] = NULL;
  423. !     if (STRNCMP(src, "file:", 5) == 0)
  424.       {
  425. !         src += 5;
  426. !         if (STRNCMP(src, "//localhost", 11) == 0)
  427. !         src += 11;
  428. !         while (src[0] == '/' && src[1] == '/')
  429. !         ++src;
  430. !         outlist[j++] = vim_strsave(src);
  431.       }
  432. !     src += STRLEN(src) + 1;
  433.       }
  434. +     return j;
  435. + }
  436.   
  437. !     static char_u **
  438. ! parse_uri_list(int *count, char_u *data, int len)
  439. ! {
  440. !     int        n        = 0;
  441. !     char_u  *tmp    = NULL;
  442. !     char_u  **array = NULL;;
  443. !     if (data != NULL && len > 0 && (tmp = (char_u *)alloc(len + 1)) != NULL)
  444. !     {
  445. !     n = count_and_decode_uri_list(tmp, data, len);
  446. !     if (n > 0 && (array = (char_u **)alloc(n * sizeof(char_u *))) != NULL)
  447. !         n = filter_uri_list(array, n, tmp);
  448. !     }
  449. !     vim_free(tmp);
  450. !     *count = n;
  451. !     return array;
  452. ! }
  453.   
  454. !     static void
  455. ! drag_handle_uri_list(GdkDragContext    *context,
  456. !              GtkSelectionData    *data,
  457. !              guint        time_,
  458. !              GdkModifierType    state,
  459. !              gint        x,
  460. !              gint        y)
  461. ! {
  462. !     char_u  **fnames;
  463. !     int        nfiles = 0;
  464.   
  465. !     fnames = parse_uri_list(&nfiles, data->data, data->length);
  466.   
  467. !     if (fnames != NULL && nfiles > 0)
  468. !     {
  469. !     int_u   modifiers = 0;
  470.   
  471. !     gtk_drag_finish(context, TRUE, FALSE, time_); /* accept */
  472.   
  473. !     if (state & GDK_SHIFT_MASK)
  474. !         modifiers |= MOUSE_SHIFT;
  475. !     if (state & GDK_CONTROL_MASK)
  476. !         modifiers |= MOUSE_CTRL;
  477. !     if (state & GDK_MOD1_MASK)
  478. !         modifiers |= MOUSE_ALT;
  479.   
  480. !     gui_handle_drop(x, y, modifiers, fnames, nfiles);
  481. !     }
  482.   }
  483.   
  484.       static void
  485. ***************
  486. *** 2071,2077 ****
  487.   
  488.       /* Not sure about the role of "text/plain" here... */
  489.       if (info == (guint)TARGET_TEXT_URI_LIST)
  490. !     drag_handle_uri_list(context, data, time_, state);
  491.       else
  492.       drag_handle_text(context, data, time_, state);
  493.   
  494. --- 2030,2036 ----
  495.   
  496.       /* Not sure about the role of "text/plain" here... */
  497.       if (info == (guint)TARGET_TEXT_URI_LIST)
  498. !     drag_handle_uri_list(context, data, time_, state, x, y);
  499.       else
  500.       drag_handle_text(context, data, time_, state);
  501.   
  502. *** ../vim-6.2.210/src/gui_mac.c    Sun Jan 25 20:42:15 2004
  503. --- src/gui_mac.c    Thu Jan 22 10:44:31 2004
  504. ***************
  505. *** 2653,2658 ****
  506. --- 2653,2712 ----
  507.   }
  508.   #endif
  509.   
  510. +     static OSErr
  511. + receiveHandler(WindowRef theWindow, void* handlerRefCon, DragRef theDrag)
  512. + {
  513. +     int        x, y;
  514. +     int_u    modifiers;
  515. +     char_u    **fnames = NULL;
  516. +     int        count;
  517. +     int        i, j;
  518. +     /* Get drop position, modifiers and count of items */
  519. +     {
  520. +     Point    point;
  521. +     SInt16    mouseUpModifiers;
  522. +     UInt16    countItem;
  523. +     GetDragMouse(theDrag, &point, NULL);
  524. +     GlobalToLocal(&point);
  525. +     x = point.h;
  526. +     y = point.v;
  527. +     GetDragModifiers(theDrag, NULL, NULL, &mouseUpModifiers);
  528. +     modifiers = EventModifiers2VimMouseModifiers(mouseUpModifiers);
  529. +     CountDragItems(theDrag, &countItem);
  530. +     count = countItem;
  531. +     }
  532. +     fnames = (char_u **)alloc(count * sizeof(char_u *));
  533. +     if (fnames == NULL)
  534. +     return dragNotAcceptedErr;
  535. +     /* Get file names dropped */
  536. +     for (i = j = 0; i < count; ++i)
  537. +     {
  538. +     DragItemRef    item;
  539. +     OSErr        err;
  540. +     Size        size;
  541. +     FlavorType    type = flavorTypeHFS;
  542. +     HFSFlavor    hfsFlavor;
  543. +     fnames[i] = NULL;
  544. +     GetDragItemReferenceNumber(theDrag, i + 1, &item);
  545. +     err = GetFlavorDataSize(theDrag, item, type, &size);
  546. +     if (err != noErr || size > sizeof(hfsFlavor))
  547. +         continue;
  548. +     err = GetFlavorData(theDrag, item, type, &hfsFlavor, &size, 0);
  549. +     if (err != noErr)
  550. +         continue;
  551. +     fnames[j++] = FullPathFromFSSpec_save(hfsFlavor.fileSpec);
  552. +     }
  553. +     count = j;
  554. +     gui_handle_drop(x, y, modifiers, fnames, count);
  555. +     return noErr;
  556. + }
  557.   /*
  558.    * Initialise the GUI.  Create all the windows, set up all the call-backs
  559.    * etc.
  560. ***************
  561. *** 2721,2726 ****
  562. --- 2775,2782 ----
  563.   
  564.       gui.VimWindow = NewCWindow(nil, &windRect, "\pgVim on Macintosh", true, documentProc,
  565.               (WindowPtr) -1L, false, 0);
  566. +     InstallReceiveHandler((DragReceiveHandlerUPP)receiveHandler,
  567. +         gui.VimWindow, NULL);
  568.   #ifdef USE_CARBONIZED
  569.       SetPortWindowPort ( gui.VimWindow );
  570.   #else
  571. *** ../vim-6.2.210/src/gui_w48.c    Sun Jan 25 20:24:03 2004
  572. --- src/gui_w48.c    Wed Jan 21 16:11:49 2004
  573. ***************
  574. *** 2841,2924 ****
  575.       char    szFile[BUFPATHLEN];
  576.       UINT    cFiles = DragQueryFile(hDrop, DRAGQVAL, szFile, BUFPATHLEN);
  577.       UINT    i;
  578. -     char_u  *fname;
  579.       char_u  **fnames;
  580.       char_u  redo_dirs = FALSE;
  581.   
  582.       /* TRACE("_OnDropFiles: %d files dropped\n", cFiles); */
  583.   
  584.   # ifdef FEAT_VISUAL
  585.       reset_VIsual();
  586.   # endif
  587.   
  588.       fnames = (char_u **)alloc(cFiles * sizeof(char_u *));
  589.   
  590. !     for (i = 0; i < cFiles; ++i)
  591. !     {
  592. !     DragQueryFile(hDrop, i, szFile, BUFPATHLEN);
  593. !     mch_dirname(IObuff, IOSIZE);
  594. !     fname = shorten_fname(szFile, IObuff);
  595. !     if (fname == NULL)
  596. !         fname = szFile;
  597. !     fnames[i] = vim_strsave(fname);
  598. !     }
  599. !     DragFinish(hDrop);
  600. !     /*
  601. !      * When the cursor is at the command line, add the file names to the
  602. !      * command line, don't edit the files.
  603. !      */
  604. !     if (State & CMDLINE)
  605. !     {
  606.       for (i = 0; i < cFiles; ++i)
  607.       {
  608. !         if (fnames[i] != NULL)
  609. !         {
  610. !         if (i > 0)
  611. !             add_to_input_buf(" ", 1);
  612. !         add_to_input_buf(fnames[i], (int)STRLEN(fnames[i]));
  613. !         }
  614. !     }
  615. !     }
  616. !     else
  617. !     {
  618. !     /*
  619. !      * Handle dropping a directory on Vim.
  620. !      * Change to that directory and don't open any file.
  621. !      */
  622. !     if (cFiles == 1 && mch_isdir(fnames[0]))
  623. !     {
  624. !         if (mch_chdir(fnames[0]) == 0)
  625. !         {
  626. !         msg_str((char_u *)":cd %s", fnames[0]);
  627. !         vim_free(fnames[0]);
  628. !         fnames[0] = NULL;
  629. !         redo_dirs = TRUE;
  630. !         }
  631.       }
  632.   
  633. !     if (fnames[0] != NULL)
  634. !     {
  635. !         /* If Shift held down, change to first file's directory */
  636. !         if (GetKeyState(VK_SHIFT) & 0x8000)
  637. !         if (vim_chdirfile(fnames[0]) == OK)
  638. !             redo_dirs = TRUE;
  639. !         /* Handle the drop, :edit or :split to get to the file */
  640. !         handle_drop(cFiles, fnames,
  641. !                    ((GetKeyState(VK_CONTROL) & 0x8000) != 0));
  642. !     }
  643.   
  644. !     if (redo_dirs)
  645. !         shorten_fnames(TRUE);
  646.   
  647. !     /* Update the screen display */
  648. !     update_screen(NOT_VALID);
  649. !     setcursor();
  650. !     out_flush();
  651.       }
  652. -     s_need_activate = TRUE;
  653.   #endif
  654.   }
  655.   
  656. --- 2841,2885 ----
  657.       char    szFile[BUFPATHLEN];
  658.       UINT    cFiles = DragQueryFile(hDrop, DRAGQVAL, szFile, BUFPATHLEN);
  659.       UINT    i;
  660.       char_u  **fnames;
  661.       char_u  redo_dirs = FALSE;
  662. +     POINT   pt;
  663. +     int_u   modifiers = 0;
  664.   
  665.       /* TRACE("_OnDropFiles: %d files dropped\n", cFiles); */
  666.   
  667. +     /* Obtain dropped position */
  668. +     DragQueryPoint(hDrop, &pt);
  669. +     MapWindowPoints(s_hwnd, s_textArea, &pt, 1);
  670.   # ifdef FEAT_VISUAL
  671.       reset_VIsual();
  672.   # endif
  673.   
  674.       fnames = (char_u **)alloc(cFiles * sizeof(char_u *));
  675.   
  676. !     if (fnames != NULL)
  677.       for (i = 0; i < cFiles; ++i)
  678.       {
  679. !         DragQueryFile(hDrop, i, szFile, BUFPATHLEN);
  680. !         fnames[i] = vim_strsave(szFile);
  681.       }
  682.   
  683. !     DragFinish(hDrop);
  684. !     if (fnames != NULL)
  685. !     {
  686. !     if ((GetKeyState(VK_SHIFT) & 0x8000) != 0)
  687. !         modifiers |= MOUSE_SHIFT;
  688. !     if ((GetKeyState(VK_CONTROL) & 0x8000) != 0)
  689. !         modifiers |= MOUSE_CTRL;
  690. !     if ((GetKeyState(VK_MENU) & 0x8000) != 0)
  691. !         modifiers |= MOUSE_ALT;
  692.   
  693. !     gui_handle_drop(pt.x, pt.y, modifiers, fnames, cFiles);
  694.   
  695. !     s_need_activate = TRUE;
  696.       }
  697.   #endif
  698.   }
  699.   
  700. *** ../vim-6.2.210/src/proto/fileio.pro    Sun Jun  1 12:26:09 2003
  701. --- src/proto/fileio.pro    Wed Jan 21 15:32:29 2004
  702. ***************
  703. *** 5,10 ****
  704. --- 5,11 ----
  705.   int buf_write __ARGS((buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_T end, exarg_T *eap, int append, int forceit, int reset_changed, int filtering));
  706.   char_u *shorten_fname __ARGS((char_u *full_path, char_u *dir_name));
  707.   void shorten_fnames __ARGS((int force));
  708. + void shorten_filenames __ARGS((char_u **fnames, int count));
  709.   char_u *modname __ARGS((char_u *fname, char_u *ext, int prepend_dot));
  710.   char_u *buf_modname __ARGS((int shortname, char_u *fname, char_u *ext, int prepend_dot));
  711.   int vim_fgets __ARGS((char_u *buf, int size, FILE *fp));
  712. *** ../vim-6.2.210/src/proto/gui.pro    Sun Jun  1 12:26:24 2003
  713. --- src/proto/gui.pro    Wed Jan 21 15:32:24 2004
  714. ***************
  715. *** 57,60 ****
  716. --- 57,61 ----
  717.   void gui_update_screen __ARGS((void));
  718.   char_u *get_find_dialog_text __ARGS((char_u *arg, int *wwordp, int *mcasep));
  719.   int gui_do_findrepl __ARGS((int flags, char_u *find_text, char_u *repl_text, int down));
  720. + void gui_handle_drop __ARGS((int x, int y, int_u modifiers, char_u **fnames, int count));
  721.   /* vim: set ft=c : */
  722. *** ../vim-6.2.210/src/version.c    Sun Jan 25 20:42:15 2004
  723. --- src/version.c    Sun Jan 25 20:44:30 2004
  724. ***************
  725. *** 639,640 ****
  726. --- 639,642 ----
  727.   {   /* Add new patch number below this line */
  728. + /**/
  729. +     211,
  730.   /**/
  731.  
  732. -- 
  733. NEIL INNES PLAYED: THE FIRST SELF-DESTRUCTIVE MONK, ROBIN'S LEAST FAVORITE
  734.                    MINSTREL, THE PAGE CRUSHED BY A RABBIT, THE OWNER OF A DUCK
  735.                  "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
  736.  
  737.  /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
  738. ///        Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
  739. \\\              Project leader for A-A-P -- http://www.A-A-P.org        ///
  740.  \\\  Help AIDS victims, buy here: http://ICCF-Holland.org/click1.html  ///
  741.