00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "config.h"
00029
00030 #include <string.h>
00031
00032
00033
00034 #define INITGUID
00035
00036 #include "gdkdnd.h"
00037 #include "gdkproperty.h"
00038 #include "gdkprivate.h"
00039 #include "gdkwin32.h"
00040
00041 #ifdef OLE2_DND
00042 #include <ole2.h>
00043 #else
00044 #include <objbase.h>
00045 #endif
00046
00047 #include <shlobj.h>
00048 #include <shlguid.h>
00049
00050 #include <gdk/gdk.h>
00051
00052 typedef struct _GdkDragContextPrivate GdkDragContextPrivate;
00053
00054 typedef enum {
00055 GDK_DRAG_STATUS_DRAG,
00056 GDK_DRAG_STATUS_MOTION_WAIT,
00057 GDK_DRAG_STATUS_ACTION_WAIT,
00058 GDK_DRAG_STATUS_DROP
00059 } GtkDragStatus;
00060
00061 typedef enum {
00062 GDK_DRAG_SOURCE,
00063 GDK_DRAG_TARGET
00064 } GdkDragKind;
00065
00066 #ifdef OLE2_DND
00067
00068 #define PRINT_GUID(guid) \
00069 g_print ("guid = %.08x-%.04x-%.04x-%.02x%.02x-%.02x%.02x%.02x%.02x%.02x%.02x", \
00070 ((gulong *) guid)[0], \
00071 ((gushort *) guid)[2], \
00072 ((gushort *) guid)[3], \
00073 ((guchar *) guid)[8], \
00074 ((guchar *) guid)[9], \
00075 ((guchar *) guid)[10], \
00076 ((guchar *) guid)[11], \
00077 ((guchar *) guid)[12], \
00078 ((guchar *) guid)[13], \
00079 ((guchar *) guid)[14], \
00080 ((guchar *) guid)[15]);
00081
00082
00083 #endif
00084
00085
00086
00087
00088 struct _GdkDragContextPrivate {
00089 GdkDragContext context;
00090
00091 guint ref_count;
00092
00093 guint16 last_x;
00094 guint16 last_y;
00095 HWND dest_xid;
00096 guint drag_status;
00097 };
00098
00099 GdkDragContext *current_dest_drag = NULL;
00100
00101
00102
00103 static GList *contexts;
00104
00105 GdkDragContext *gdk_drag_context_new(void)
00106 {
00107 GdkDragContextPrivate *result;
00108
00109 result = g_new0(GdkDragContextPrivate, 1);
00110
00111 result->ref_count = 1;
00112
00113 contexts = g_list_prepend(contexts, result);
00114
00115 return (GdkDragContext *) result;
00116 }
00117
00118 void gdk_drag_context_ref(GdkDragContext * context)
00119 {
00120 g_return_if_fail(context != NULL);
00121
00122 ((GdkDragContextPrivate *) context)->ref_count++;
00123 }
00124
00125 void gdk_drag_context_unref(GdkDragContext * context)
00126 {
00127 GdkDragContextPrivate *private = (GdkDragContextPrivate *) context;
00128
00129 g_return_if_fail(context != NULL);
00130
00131 private->ref_count--;
00132
00133 GDK_NOTE(DND, g_print("gdk_drag_context_unref: %d%s\n",
00134 private->ref_count,
00135 (private->ref_count == 0 ? " freeing" : "")));
00136
00137 if (private->ref_count == 0) {
00138 g_dataset_destroy(private);
00139
00140 g_list_free(context->targets);
00141
00142 if (context->source_window)
00143 gdk_window_unref(context->source_window);
00144
00145 if (context->dest_window)
00146 gdk_window_unref(context->dest_window);
00147
00148 contexts = g_list_remove(contexts, private);
00149 g_free(private);
00150 }
00151 }
00152
00153 #if 0
00154
00155 static GdkDragContext *gdk_drag_context_find(gboolean is_source,
00156 HWND source_xid,
00157 HWND dest_xid)
00158 {
00159 GList *tmp_list = contexts;
00160 GdkDragContext *context;
00161
00162 while (tmp_list) {
00163 context = (GdkDragContext *) tmp_list->data;
00164
00165 if ((!context->is_source == !is_source) &&
00166 ((source_xid == None) || (context->source_window &&
00167 (GDK_WINDOW_XWINDOW
00168 (context->source_window) ==
00169 source_xid))) && ((dest_xid == None)
00170 || (context->
00171 dest_window
00172 &&
00173 (GDK_WINDOW_XWINDOW
00174 (context->
00175 dest_window)
00176 == dest_xid))))
00177 return context;
00178
00179 tmp_list = tmp_list->next;
00180 }
00181
00182 return NULL;
00183 }
00184
00185 #endif
00186
00187 typedef struct {
00188 #ifdef OLE2_DND
00189 IDropTarget idt;
00190 #endif
00191 GdkDragContext *context;
00192 } target_drag_context;
00193
00194 typedef struct {
00195 #ifdef OLE2_DND
00196 IDropSource ids;
00197 #endif
00198 GdkDragContext *context;
00199 } source_drag_context;
00200
00201 #ifdef OLE2_DND
00202
00203 static ULONG STDMETHODCALLTYPE
00204 m_add_ref_target(IDropTarget __RPC_FAR * This)
00205 {
00206 target_drag_context *ctx = (target_drag_context *) This;
00207 GdkDragContextPrivate *private = (GdkDragContextPrivate *) ctx->context;
00208
00209 GDK_NOTE(DND, g_print("m_add_ref_target\n"));
00210 gdk_drag_context_ref(ctx->context);
00211
00212 return private->ref_count;
00213 }
00214
00215 static HRESULT STDMETHODCALLTYPE
00216 m_query_interface_target(IDropTarget __RPC_FAR * This,
00217 REFIID riid,
00218 void __RPC_FAR * __RPC_FAR * ppvObject)
00219 {
00220 GDK_NOTE(DND, g_print("m_query_interface_target\n"));
00221
00222 *ppvObject = NULL;
00223
00224 PRINT_GUID(riid);
00225
00226 if (IsEqualGUID(riid, &IID_IUnknown)) {
00227 g_print("...IUnknown\n");
00228 m_add_ref_target(This);
00229 *ppvObject = This;
00230 return S_OK;
00231 } else if (IsEqualGUID(riid, &IID_IDropTarget)) {
00232 g_print("...IDropTarget\n");
00233 m_add_ref_target(This);
00234 *ppvObject = This;
00235 return S_OK;
00236 } else {
00237 g_print("...Huh?\n");
00238 return E_NOINTERFACE;
00239 }
00240 }
00241
00242 static ULONG STDMETHODCALLTYPE
00243 m_release_target(IDropTarget __RPC_FAR * This)
00244 {
00245 target_drag_context *ctx = (target_drag_context *) This;
00246 GdkDragContextPrivate *private = (GdkDragContextPrivate *) ctx->context;
00247
00248 GDK_NOTE(DND, g_print("m_release_target\n"));
00249 gdk_drag_context_unref(ctx->context);
00250
00251 if (private->ref_count == 1) {
00252 gdk_drag_context_unref(ctx->context);
00253 return 0;
00254 } else
00255 return private->ref_count - 1;
00256 }
00257
00258 static HRESULT STDMETHODCALLTYPE
00259 m_drag_enter(IDropTarget __RPC_FAR * This,
00260 IDataObject __RPC_FAR * pDataObj,
00261 DWORD grfKeyState, POINTL pt, DWORD __RPC_FAR * pdwEffect)
00262 {
00263 GDK_NOTE(DND, g_print("m_drag_enter\n"));
00264 return E_UNEXPECTED;
00265 }
00266
00267 static HRESULT STDMETHODCALLTYPE
00268 m_drag_over(IDropTarget __RPC_FAR * This,
00269 DWORD grfKeyState, POINTL pt, DWORD __RPC_FAR * pdwEffect)
00270 {
00271 GDK_NOTE(DND, g_print("m_drag_over\n"));
00272 return E_UNEXPECTED;
00273 }
00274
00275 static HRESULT STDMETHODCALLTYPE m_drag_leave(IDropTarget __RPC_FAR * This)
00276 {
00277 GDK_NOTE(DND, g_print("m_drag_leave\n"));
00278 return E_UNEXPECTED;
00279 }
00280
00281 static HRESULT STDMETHODCALLTYPE
00282 m_drop(IDropTarget __RPC_FAR * This,
00283 IDataObject __RPC_FAR * pDataObj,
00284 DWORD grfKeyState, POINTL pt, DWORD __RPC_FAR * pdwEffect)
00285 {
00286 GDK_NOTE(DND, g_print("m_drop\n"));
00287 return E_UNEXPECTED;
00288 }
00289
00290 static ULONG STDMETHODCALLTYPE
00291 m_add_ref_source(IDropSource __RPC_FAR * This)
00292 {
00293 source_drag_context *ctx = (source_drag_context *) This;
00294 GdkDragContextPrivate *private = (GdkDragContextPrivate *) ctx->context;
00295
00296 GDK_NOTE(DND, g_print("m_add_ref_source\n"));
00297 gdk_drag_context_ref(ctx->context);
00298
00299 return private->ref_count;
00300 }
00301
00302 static HRESULT STDMETHODCALLTYPE
00303 m_query_interface_source(IDropSource __RPC_FAR * This,
00304 REFIID riid,
00305 void __RPC_FAR * __RPC_FAR * ppvObject)
00306 {
00307 GDK_NOTE(DND, g_print("m_query_interface_source\n"));
00308
00309 *ppvObject = NULL;
00310
00311 PRINT_GUID(riid);
00312 if (IsEqualGUID(riid, &IID_IUnknown)) {
00313 g_print("...IUnknown\n");
00314 m_add_ref_source(This);
00315 *ppvObject = This;
00316 return S_OK;
00317 } else if (IsEqualGUID(riid, &IID_IDropSource)) {
00318 g_print("...IDropSource\n");
00319 m_add_ref_source(This);
00320 *ppvObject = This;
00321 return S_OK;
00322 } else {
00323 g_print("...Huh?\n");
00324 return E_NOINTERFACE;
00325 }
00326 }
00327
00328 static ULONG STDMETHODCALLTYPE
00329 m_release_source(IDropSource __RPC_FAR * This)
00330 {
00331 source_drag_context *ctx = (source_drag_context *) This;
00332 GdkDragContextPrivate *private = (GdkDragContextPrivate *) ctx->context;
00333
00334 GDK_NOTE(DND, g_print("m_release_source\n"));
00335 gdk_drag_context_unref(ctx->context);
00336
00337 if (private->ref_count == 1) {
00338 gdk_drag_context_unref(ctx->context);
00339 return 0;
00340 } else
00341 return private->ref_count - 1;
00342 }
00343
00344 static HRESULT STDMETHODCALLTYPE
00345 m_query_continue_drag(IDropSource __RPC_FAR * This,
00346 BOOL fEscapePressed, DWORD grfKeyState)
00347 {
00348 GDK_NOTE(DND, g_print("m_query_continue_drag\n"));
00349 return E_UNEXPECTED;
00350 }
00351
00352 static HRESULT STDMETHODCALLTYPE
00353 m_give_feedback(IDropSource __RPC_FAR * This, DWORD dwEffect)
00354 {
00355 GDK_NOTE(DND, g_print("m_give_feedback\n"));
00356 return E_UNEXPECTED;
00357 }
00358
00359 static HRESULT STDMETHODCALLTYPE
00360 m_query_interface_object(IDataObject __RPC_FAR * This,
00361 REFIID riid,
00362 void __RPC_FAR * __RPC_FAR * ppvObject)
00363 {
00364 return E_UNEXPECTED;
00365 }
00366
00367 static ULONG STDMETHODCALLTYPE
00368 m_add_ref_object(IDataObject __RPC_FAR * This)
00369 {
00370 return E_UNEXPECTED;
00371 }
00372
00373 static ULONG STDMETHODCALLTYPE
00374 m_release_object(IDataObject __RPC_FAR * This)
00375 {
00376 return E_UNEXPECTED;
00377 }
00378
00379 static HRESULT STDMETHODCALLTYPE
00380 m_get_data(IDataObject __RPC_FAR * This,
00381 FORMATETC * pFormatEtc, STGMEDIUM * pMedium)
00382 {
00383 return E_UNEXPECTED;
00384 }
00385
00386 static HRESULT STDMETHODCALLTYPE
00387 m_get_data_here(IDataObject __RPC_FAR * This,
00388 FORMATETC * pFormatEtc, STGMEDIUM * pMedium)
00389 {
00390 return E_UNEXPECTED;
00391 }
00392
00393 static HRESULT STDMETHODCALLTYPE
00394 m_query_get_data(IDataObject __RPC_FAR * This, FORMATETC * pFormatEtc)
00395 {
00396 return E_UNEXPECTED;
00397 }
00398
00399 static HRESULT STDMETHODCALLTYPE
00400 m_get_canonical_format_etc(IDataObject __RPC_FAR * This,
00401 FORMATETC * pFormatEtcIn,
00402 FORMATETC * pFormatEtcOut)
00403 {
00404 return E_UNEXPECTED;
00405 }
00406
00407 static HRESULT STDMETHODCALLTYPE
00408 m_set_data(IDataObject __RPC_FAR * This,
00409 FORMATETC * pFormatEtc, STGMEDIUM * pMedium, BOOL fRelease)
00410 {
00411 return E_UNEXPECTED;
00412 }
00413
00414 static HRESULT STDMETHODCALLTYPE
00415 m_enum_format_etc(IDataObject __RPC_FAR * This,
00416 DWORD dwDirection, IEnumFORMATETC ** ppEnumFormatEtc)
00417 {
00418 return E_UNEXPECTED;
00419 }
00420
00421 static HRESULT STDMETHODCALLTYPE
00422 m_d_advise(IDataObject __RPC_FAR * This,
00423 FORMATETC * pFormatetc,
00424 DWORD advf, IAdviseSink * pAdvSink, DWORD * pdwConnection)
00425 {
00426 return E_UNEXPECTED;
00427 }
00428
00429 static HRESULT STDMETHODCALLTYPE
00430 m_d_unadvise(IDataObject __RPC_FAR * This, DWORD dwConnection)
00431 {
00432 return E_UNEXPECTED;
00433 }
00434
00435 static HRESULT STDMETHODCALLTYPE
00436 m_enum_d_advise(IDataObject __RPC_FAR * This,
00437 IEnumSTATDATA ** ppenumAdvise)
00438 {
00439 return E_UNEXPECTED;
00440 }
00441
00442 static IDropTargetVtbl idt_vtbl = {
00443 m_query_interface_target,
00444 m_add_ref_target,
00445 m_release_target,
00446 m_drag_enter,
00447 m_drag_over,
00448 m_drag_leave,
00449 m_drop
00450 };
00451
00452 static IDropSourceVtbl ids_vtbl = {
00453 m_query_interface_source,
00454 m_add_ref_source,
00455 m_release_source,
00456 m_query_continue_drag,
00457 m_give_feedback
00458 };
00459
00460 static IDataObjectVtbl ido_vtbl = {
00461 m_query_interface_object,
00462 m_add_ref_object,
00463 m_release_object,
00464 m_get_data,
00465 m_get_data_here,
00466 m_query_get_data,
00467 m_get_canonical_format_etc,
00468 m_set_data,
00469 m_enum_format_etc,
00470 m_d_advise,
00471 m_d_unadvise,
00472 m_enum_d_advise
00473 };
00474
00475 #endif
00476
00477 static target_drag_context *target_context_new(void)
00478 {
00479 target_drag_context *result;
00480
00481 result = g_new0(target_drag_context, 1);
00482
00483 #ifdef OLE2_DND
00484 result->idt.lpVtbl = &idt_vtbl;
00485 #endif
00486
00487 result->context = gdk_drag_context_new();
00488
00489 return result;
00490 }
00491
00492 static source_drag_context *source_context_new(void)
00493 {
00494 source_drag_context *result;
00495
00496 result = g_new0(source_drag_context, 1);
00497
00498 #ifdef OLE2_DND
00499 result->ids.lpVtbl = &ids_vtbl;
00500 #endif
00501
00502 result->context = gdk_drag_context_new();
00503
00504 return result;
00505 }
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 static HRESULT
00519 resolve_link(HWND hWnd,
00520 LPCTSTR lpszLinkName, LPSTR lpszPath, LPSTR lpszDescription)
00521 {
00522 HRESULT hres;
00523 IShellLink *psl;
00524 WIN32_FIND_DATA wfd;
00525
00526
00527 *lpszPath = 0;
00528 if (lpszDescription)
00529 *lpszDescription = 0;
00530
00531
00532
00533
00534
00535
00536 hres = CoCreateInstance(&CLSID_ShellLink,
00537 NULL,
00538 CLSCTX_INPROC_SERVER,
00539 &IID_IShellLink, (LPVOID *) & psl);
00540 if (SUCCEEDED(hres)) {
00541 IPersistFile *ppf;
00542
00543
00544
00545
00546 hres = psl->lpVtbl->QueryInterface(psl,
00547 &IID_IPersistFile,
00548 (LPVOID *) & ppf);
00549 if (SUCCEEDED(hres)) {
00550 WORD wsz[MAX_PATH];
00551
00552
00553 MultiByteToWideChar(CP_ACP, 0, lpszLinkName, -1, wsz, MAX_PATH);
00554
00555 hres = ppf->lpVtbl->Load(ppf, wsz, STGM_READ);
00556 if (SUCCEEDED(hres)) {
00557
00558
00559
00560 hres = psl->lpVtbl->Resolve(psl, hWnd,
00561 SLR_ANY_MATCH | SLR_NO_UI);
00562 if (SUCCEEDED(hres)) {
00563 hres = psl->lpVtbl->GetPath(psl, lpszPath,
00564 MAX_PATH,
00565 (WIN32_FIND_DATA *) & wfd, 0);
00566
00567 if (SUCCEEDED(hres) && lpszDescription != NULL) {
00568 hres = psl->lpVtbl->GetDescription(psl,
00569 lpszDescription,
00570 MAX_PATH);
00571
00572 if (!SUCCEEDED(hres))
00573 return FALSE;
00574 }
00575 }
00576 }
00577 ppf->lpVtbl->Release(ppf);
00578 }
00579 psl->lpVtbl->Release(psl);
00580 }
00581 return SUCCEEDED(hres);
00582 }
00583
00584 static GdkFilterReturn
00585 gdk_dropfiles_filter(GdkXEvent * xev, GdkEvent * event, gpointer data)
00586 {
00587 GdkDragContext *context;
00588 GdkDragContextPrivate *private;
00589 static GdkAtom text_uri_list_atom = GDK_NONE;
00590 GString *result;
00591 MSG *msg = (MSG *) xev;
00592 HANDLE hdrop;
00593 POINT pt;
00594 gint nfiles, i, k;
00595 guchar fileName[MAX_PATH], linkedFile[MAX_PATH];
00596
00597 if (text_uri_list_atom == GDK_NONE)
00598 text_uri_list_atom = gdk_atom_intern("text/uri-list", FALSE);
00599
00600 if (msg->message == WM_DROPFILES) {
00601 GDK_NOTE(DND, g_print("WM_DROPFILES: %#x\n", msg->hwnd));
00602
00603 context = gdk_drag_context_new();
00604 private = (GdkDragContextPrivate *) context;
00605 context->protocol = GDK_DRAG_PROTO_WIN32_DROPFILES;
00606 context->is_source = FALSE;
00607 context->source_window = gdk_parent_root;
00608 context->dest_window = event->any.window;
00609 gdk_window_ref(context->dest_window);
00610
00611 context->targets =
00612 g_list_append(NULL, GUINT_TO_POINTER(text_uri_list_atom));
00613 current_dest_drag = context;
00614
00615 event->dnd.type = GDK_DROP_START;
00616 event->dnd.context = current_dest_drag;
00617 gdk_drag_context_ref(current_dest_drag);
00618
00619 hdrop = (HANDLE) msg->wParam;
00620 DragQueryPoint(hdrop, &pt);
00621 ClientToScreen(msg->hwnd, &pt);
00622
00623 event->dnd.x_root = pt.x;
00624 event->dnd.y_root = pt.y;
00625 event->dnd.time = msg->time;
00626
00627 nfiles = DragQueryFile(hdrop, 0xFFFFFFFF, NULL, 0);
00628
00629 result = g_string_new(NULL);
00630 for (i = 0; i < nfiles; i++) {
00631 g_string_append(result, "file:");
00632 DragQueryFile(hdrop, i, fileName, MAX_PATH);
00633
00634
00635 if (resolve_link(msg->hwnd, fileName, linkedFile, NULL)) {
00636 g_string_append(result, linkedFile);
00637 GDK_NOTE(DND, g_print("...%s link to %s\n",
00638 fileName, linkedFile));
00639 } else {
00640 g_string_append(result, fileName);
00641 GDK_NOTE(DND, g_print("...%s\n", fileName));
00642 }
00643 g_string_append(result, "\015\012");
00644 }
00645 gdk_sel_prop_store(gdk_parent_root, text_uri_list_atom, 8,
00646 result->str, result->len + 1);
00647
00648 DragFinish(hdrop);
00649
00650 return GDK_FILTER_TRANSLATE;
00651 } else
00652 return GDK_FILTER_CONTINUE;
00653 }
00654
00655
00656
00657
00658
00659 void gdk_dnd_init(void)
00660 {
00661 HRESULT hres;
00662 #ifdef OLE2_DND
00663 hres = OleInitialize(NULL);
00664
00665 if (!SUCCEEDED(hres))
00666 g_error("OleInitialize failed");
00667 #endif
00668 }
00669
00670 void gdk_win32_dnd_exit(void)
00671 {
00672 #ifdef OLE2_DND
00673 OleUninitialize();
00674 #endif
00675 }
00676
00677
00678
00679 static void gdk_drag_do_leave(GdkDragContext * context, guint32 time)
00680 {
00681 if (context->dest_window) {
00682 GDK_NOTE(DND, g_print("gdk_drag_do_leave\n"));
00683 gdk_window_unref(context->dest_window);
00684 context->dest_window = NULL;
00685 }
00686 }
00687
00688 GdkDragContext *gdk_drag_begin(GdkWindow * window, GList * targets)
00689 {
00690 GList *tmp_list;
00691 source_drag_context *ctx;
00692
00693 g_return_val_if_fail(window != NULL, NULL);
00694
00695 GDK_NOTE(DND, g_print("gdk_drag_begin\n"));
00696
00697 ctx = source_context_new();
00698 ctx->context->is_source = TRUE;
00699 ctx->context->source_window = window;
00700 gdk_window_ref(window);
00701
00702 tmp_list = g_list_last(targets);
00703 ctx->context->targets = NULL;
00704 while (tmp_list) {
00705 ctx->context->targets = g_list_prepend(ctx->context->targets,
00706 tmp_list->data);
00707 tmp_list = tmp_list->prev;
00708 }
00709
00710 ctx->context->actions = 0;
00711
00712 #if 0
00713 DoDragDrop(...);
00714 #endif
00715 return ctx->context;
00716 }
00717
00718 guint32 gdk_drag_get_protocol(guint32 xid, GdkDragProtocol * protocol)
00719 {
00720
00721 return 0;
00722 }
00723
00724 void
00725 gdk_drag_find_window(GdkDragContext * context,
00726 GdkWindow * drag_window,
00727 gint x_root,
00728 gint y_root,
00729 GdkWindow ** dest_window, GdkDragProtocol * protocol)
00730 {
00731 GdkDragContextPrivate *private = (GdkDragContextPrivate *) context;
00732 GdkDrawablePrivate *drag_window_private =
00733 (GdkDrawablePrivate *) drag_window;
00734 HWND recipient;
00735 POINT pt;
00736
00737 GDK_NOTE(DND, g_print("gdk_drag_find_window: %#x +%d+%d\n",
00738 (drag_window ? GDK_DRAWABLE_XID(drag_window) : 0),
00739 x_root, y_root));
00740
00741 pt.x = x_root;
00742 pt.y = y_root;
00743 recipient = WindowFromPoint(pt);
00744 if (recipient == NULL)
00745 *dest_window = NULL;
00746 else {
00747 *dest_window = gdk_window_lookup(recipient);
00748 if (*dest_window)
00749 gdk_window_ref(*dest_window);
00750 *protocol = GDK_DRAG_PROTO_WIN32_DROPFILES;
00751 }
00752 }
00753
00754 gboolean
00755 gdk_drag_motion(GdkDragContext * context,
00756 GdkWindow * dest_window,
00757 GdkDragProtocol protocol,
00758 gint x_root,
00759 gint y_root,
00760 GdkDragAction suggested_action,
00761 GdkDragAction possible_actions, guint32 time)
00762 {
00763 return FALSE;
00764 }
00765
00766 void gdk_drag_drop(GdkDragContext * context, guint32 time)
00767 {
00768 g_return_if_fail(context != NULL);
00769
00770 g_warning("gdk_drag_drop: not implemented\n");
00771 }
00772
00773 void gdk_drag_abort(GdkDragContext * context, guint32 time)
00774 {
00775 g_return_if_fail(context != NULL);
00776
00777 gdk_drag_do_leave(context, time);
00778 }
00779
00780
00781
00782 void
00783 gdk_drag_status(GdkDragContext * context,
00784 GdkDragAction action, guint32 time)
00785 {
00786 GDK_NOTE(DND, g_print("gdk_drag_status\n"));
00787 }
00788
00789 void gdk_drop_reply(GdkDragContext * context, gboolean ok, guint32 time)
00790 {
00791 }
00792
00793 void
00794 gdk_drop_finish(GdkDragContext * context, gboolean success, guint32 time)
00795 {
00796 }
00797
00798 static GdkFilterReturn
00799 gdk_destroy_filter(GdkXEvent * xev, GdkEvent * event, gpointer data)
00800 {
00801 #ifdef OLE2_DND
00802 MSG *msg = (MSG *) xev;
00803
00804 if (msg->message == WM_DESTROY) {
00805 IDropTarget *idtp = (IDropTarget *) data;
00806
00807 GDK_NOTE(DND,
00808 g_print("gdk_destroy_filter: WM_DESTROY: %#x\n",
00809 msg->hwnd));
00810 RevokeDragDrop(msg->hwnd);
00811 CoLockObjectExternal(idtp, FALSE, TRUE);
00812 }
00813 #endif
00814 return GDK_FILTER_CONTINUE;
00815 }
00816
00817 void gdk_window_register_dnd(GdkWindow * window)
00818 {
00819 #ifdef OLE2_DND
00820 target_drag_context *context;
00821 HRESULT hres;
00822 #endif
00823
00824 g_return_if_fail(window != NULL);
00825
00826 GDK_NOTE(DND, g_print("gdk_window_register_dnd: %#x\n",
00827 GDK_DRAWABLE_XID(window)));
00828
00829
00830
00831
00832
00833
00834 gdk_window_add_filter(window, gdk_dropfiles_filter, NULL);
00835 DragAcceptFiles(GDK_DRAWABLE_XID(window), TRUE);
00836
00837 #ifdef OLE2_DND
00838
00839 context = target_context_new();
00840 hres = CoLockObjectExternal((IUnknown *) & context->idt, TRUE, FALSE);
00841 if (!SUCCEEDED(hres))
00842 OTHER_API_FAILED("CoLockObjectExternal");
00843 else {
00844 hres = RegisterDragDrop(GDK_DRAWABLE_XID(window), &context->idt);
00845 if (hres == DRAGDROP_E_ALREADYREGISTERED) {
00846 g_print("DRAGDROP_E_ALREADYREGISTERED\n");
00847 CoLockObjectExternal((IUnknown *) & context->idt, FALSE, FALSE);
00848 } else if (!SUCCEEDED(hres))
00849 OTHER_API_FAILED("RegisterDragDrop");
00850 else {
00851 gdk_window_add_filter(window, gdk_destroy_filter, &context->idt);
00852 }
00853 }
00854 #endif
00855 }
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865 GdkAtom gdk_drag_get_selection(GdkDragContext * context)
00866 {
00867 if (context->protocol == GDK_DRAG_PROTO_WIN32_DROPFILES)
00868 return gdk_win32_dropfiles_atom;
00869 else if (context->protocol == GDK_DRAG_PROTO_OLE2)
00870 return gdk_ole2_dnd_atom;
00871 else
00872 return GDK_NONE;
00873 }