1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23 // MARKER(update_precomp.py): autogen include statement, do not remove
24 #include "precompiled_dtrans.hxx"
25
26 #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
27
28 #include "globals.hxx"
29 #include "DragSource.hxx"
30 #include "DropTarget.hxx"
31
32 using namespace com::sun::star::datatransfer::dnd::DNDConstants;
33
34 //
35 // Convert office drag actions as defined in
36 // <type>com::sun::star::datatransfer::dnd::DNDConstants</type>
37 // into system conform drag actions.
38 //
OfficeToSystemDragActions(sal_Int8 dragActions)39 MRESULT OfficeToSystemDragActions( sal_Int8 dragActions)
40 {
41 MRESULT actions = MRFROM2SHORT( DOR_NODROP, 0);
42
43 if (dragActions & ACTION_COPY)
44 {
45 actions = MRFROM2SHORT( DOR_DROP, DO_COPY);
46 }
47
48 if (dragActions & ACTION_MOVE)
49 {
50 actions = MRFROM2SHORT( DOR_DROP, DO_MOVE);
51 }
52
53 if (dragActions & ACTION_LINK)
54 {
55 actions = MRFROM2SHORT( DOR_DROP, DO_LINK);
56 }
57
58 debug_printf("OfficeToSystemDragActions %d->0x%x", dragActions, actions);
59 return actions;
60 }
61
62 //
63 // Convert system conform drag actions into office conform
64 // drag actions as defined in
65 // <type>com::sun::star::datatransfer::dnd::DNDConstants</type>.
66 //
SystemToOfficeDragActions(USHORT usOperation)67 sal_Int8 SystemToOfficeDragActions( USHORT usOperation)
68 {
69 sal_Int8 actions = ACTION_NONE;
70
71 switch( usOperation) {
72 case DO_UNKNOWN:
73 break;
74 case DO_DEFAULT:
75 actions |= ACTION_MOVE;
76 break;
77 case DO_MOVE:
78 actions |= ACTION_MOVE;
79 break;
80 case DO_COPY:
81 actions |= ACTION_COPY;
82 break;
83 case DO_LINK:
84 actions |= ACTION_LINK;
85 break;
86 }
87
88 debug_printf("SystemToOfficeDragActions 0x%x->%d", usOperation, actions);
89 return actions;
90 }
91
92
93 //
94 // functions used by dnd.dll to get access to Window class data fields
95 // in the subclassed window procedure
96 //
97
98 // Store DropTarget object reference
SetWindowDropTargetPtr(HWND hWnd,void * dropTarget)99 void SetWindowDropTargetPtr( HWND hWnd, void* dropTarget )
100 {
101 WinSetWindowULong( hWnd, SAL_FRAME_DROPTARGET, (ULONG)dropTarget);
102 }
103
104 // Get DropTarget object reference
GetWindowDropTargetPtr(HWND hWnd)105 void* GetWindowDropTargetPtr( HWND hWnd )
106 {
107 return (void*)WinQueryWindowULong( hWnd, SAL_FRAME_DROPTARGET);
108 }
109
110 // Store DragSource object reference
SetWindowDragSourcePtr(HWND hWnd,void * dragSource)111 void SetWindowDragSourcePtr( HWND hWnd, void* dragSource )
112 {
113 WinSetWindowULong( hWnd, SAL_FRAME_DRAGSOURCE, (ULONG)dragSource);
114 }
115
116 // Get DropTarget object reference
GetWindowDragSourcePtr(HWND hWnd)117 void* GetWindowDragSourcePtr( HWND hWnd )
118 {
119 return (void*)WinQueryWindowULong( hWnd, SAL_FRAME_DRAGSOURCE);
120 }
121
122 // map desktop coordinates of mouse pointer to local window
123 // inverting also the y axis
MapWindowPoint(HWND hwnd,PDRAGINFO dragInfo,PPOINTL ptlMouse)124 void MapWindowPoint( HWND hwnd, PDRAGINFO dragInfo, PPOINTL ptlMouse)
125 {
126 RECTL rclClient;
127 ptlMouse->x = dragInfo->xDrop;
128 ptlMouse->y = dragInfo->yDrop;
129 WinMapWindowPoints( HWND_DESKTOP, hwnd, ptlMouse, 1);
130 // invert y-coordinate
131 WinQueryWindowRect( hwnd, &rclClient);
132 ptlMouse->y = rclClient.yTop - ptlMouse->y;
133 }
134
135
136 //
137 // subclassed frame window procedure: used to intercept DM_* messages
138 // without accessing default window procedure inside VCL private code
139 //
dndFrameProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)140 extern "C" MRESULT EXPENTRY dndFrameProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
141 {
142 #if 0
143 debug_printf("dndFrameProc hwnd %x, msg %x", hwnd, msg);
144 #endif
145 DropTarget* dt = (DropTarget*) GetWindowDropTargetPtr( hwnd);
146 DragSource* ds = NULL;
147 MRESULT mr;
148
149 switch( msg) {
150
151 case DM_DRAGOVER:
152 debug_printf("dndFrameProc hwnd %x, dt %x, DM_DRAGOVER", hwnd, dt);
153 return dt->dragOver( (PDRAGINFO) mp1);
154 break;
155
156 case DM_DRAGLEAVE:
157 debug_printf("dndFrameProc hwnd %x, dt %x, DM_DRAGLEAVE", hwnd, dt);
158 return dt->dragLeave( (PDRAGINFO) mp1);
159 break;
160
161 case DM_DROP:
162 debug_printf("dndFrameProc hwnd %x, dt %x, DM_DROP", hwnd, dt);
163 mr = dt->drop( (PDRAGINFO) mp1);
164 debug_printf("dndFrameProc hwnd %x, dt %x, DM_DROP mr=%x", hwnd, dt, mr);
165 return mr;
166 break;
167
168 case DM_RENDERCOMPLETE:
169 debug_printf("dndFrameProc hwnd %x, dt %x, DM_RENDERCOMPLETE", hwnd, dt);
170 mr = dt->renderComplete( (PDRAGTRANSFER) mp1);
171 debug_printf("dndFrameProc hwnd %x, dt %x, DM_RENDERCOMPLETE mr=0x%x", hwnd, dt, mr);
172 return mr;
173 break;
174
175 case DM_RENDERPREPARE:
176 debug_printf("dndFrameProc hwnd %x, dt %x, DM_RENDERPREPARE", hwnd, dt);
177 break;
178
179 case DM_RENDER:
180 ds = (DragSource*) GetWindowDragSourcePtr( hwnd);
181 debug_printf("dndFrameProc hwnd %x, dt %x, DM_RENDER", hwnd, ds);
182 mr = ds->render( (PDRAGTRANSFER) mp1);
183 return mr;
184 break;
185
186 // sent from target window to source window after rendering
187 case DM_ENDCONVERSATION:
188 // sent from AOO to DropSource to notify end of dragging
189 case DM_AOO_ENDCONVERSATION:
190 ds = (DragSource*) GetWindowDragSourcePtr( hwnd);
191 debug_printf("dndFrameProc hwnd %x, dt %x, DM_ENDCONVERSATION", hwnd, ds);
192 mr = ds->endConversation( (ULONG) mp1, (ULONG) mp2);
193 return mr;
194 break;
195
196 }
197
198 // forward to VCL frame proc
199 return dt->defWndProc(hwnd, msg, mp1, mp2);
200 }
201