Add copy of .ttf font with .eot extension for testing
[wine-gecko.git] / widget / src / photon / nsDragService.cpp
blobbbe2bfc3afc85ae77fdfeffb2c22053eabb88e0e
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include "nsDragService.h"
39 #include "nsITransferable.h"
40 #include "nsString.h"
41 #include "nsClipboard.h"
42 #include "nsIRegion.h"
43 #include "nsISupportsPrimitives.h"
44 #include "nsPrimitiveHelpers.h"
45 #include "nsCOMPtr.h"
46 #include "nsXPIDLString.h"
48 #include "nsWidgetsCID.h"
50 char *nsDragService::mDndEvent = NULL;
51 int nsDragService::mDndEventLen;
53 #define kMimeCustom "text/_moz_htmlcontext"
55 nsDragService::nsDragService()
57 mDndWidget = nsnull;
58 mDndEvent = nsnull;
59 mNativeCtrl = nsnull;
60 mRawData = nsnull;
61 mFlavourStr = nsnull;
62 mTransportFile = nsnull;
65 nsDragService::~nsDragService()
67 if( mNativeCtrl ) PtReleaseTransportCtrl( mNativeCtrl );
68 if( mFlavourStr ) free( mFlavourStr );
69 if( mTransportFile ) {
70 unlink( mTransportFile );
71 free( mTransportFile );
75 NS_IMETHODIMP nsDragService::SetNativeDndData( PtWidget_t *widget, PhEvent_t *event ) {
76 mDndWidget = widget;
77 if( !mDndEvent ) {
78 mDndEventLen = sizeof( PhEvent_t ) + event->num_rects * sizeof( PhRect_t ) + event->data_len;
79 mDndEvent = ( char * ) malloc( mDndEventLen );
81 memcpy( mDndEvent, (char*)event, mDndEventLen );
82 return NS_OK;
85 NS_IMETHODIMP nsDragService::SetDropData( char *data ) {
87 if( mRawData ) free( mRawData );
89 /* data is the filename used for passing the data */
90 FILE *fp = fopen( data, "r" );
91 PRUint32 n;
92 fread( &n, sizeof( PRUint32 ), 1, fp );
93 mRawData = ( char * ) malloc( n );
94 if( !mRawData ) { fclose( fp ); return NS_ERROR_FAILURE; }
96 fseek( fp, 0, SEEK_SET );
97 fread( mRawData, 1, n, fp );
98 fclose( fp );
100 return NS_OK;
104 /* remove this function with the one from libph.so, when it becomes available */
105 int CancelDrag( PhRid_t rid, unsigned input_group )
107 struct dragevent {
108 PhEvent_t hdr;
109 PhDragEvent_t drag;
110 } ev;
111 memset( &ev, 0, sizeof(ev) );
112 ev.hdr.type = Ph_EV_DRAG;
113 ev.hdr.emitter.rid = Ph_DEV_RID;
114 ev.hdr.flags = Ph_EVENT_INCLUSIVE | Ph_EMIT_TOWARD;
115 ev.hdr.data_len = sizeof( ev.drag );
116 ev.hdr.subtype = Ph_EV_DRAG_COMPLETE;
117 ev.hdr.input_group = input_group;
118 ev.drag.rid = rid;
119 return PhEmit( &ev.hdr, NULL, &ev.drag );
123 //-------------------------------------------------------------------------
124 NS_IMETHODIMP
125 nsDragService::InvokeDragSession (nsIDOMNode *aDOMNode,
126 nsISupportsArray * aArrayTransferables,
127 nsIScriptableRegion * aRegion,
128 PRUint32 aActionType)
130 #ifdef DEBUG
131 printf( "nsDragService::InvokeDragSession\n" );
132 #endif
133 nsresult rv = nsBaseDragService::InvokeDragSession(aDOMNode,
134 aArrayTransferables,
135 aRegion, aActionType);
136 NS_ENSURE_SUCCESS(rv, rv);
138 if(!aArrayTransferables) return NS_ERROR_INVALID_ARG;
140 /* this will also addref the transferables since we're going to hang onto this beyond the length of this call */
141 mSourceDataItems = aArrayTransferables;
143 PRUint32 numDragItems = 0;
144 mSourceDataItems->Count(&numDragItems);
145 if ( ! numDragItems ) return NS_ERROR_FAILURE;
147 /* cancel a previous drag ( PhInitDrag ) if one is in place */
148 CancelDrag( PtWidgetRid( mDndWidget ), ((PhEvent_t*)mDndEvent)->input_group );
150 mActionType = aActionType;
152 PRUint32 pDataLen = sizeof( PRUint32 ) + sizeof( PRUint32 ), totalItems = 0;
153 char *pdata = ( char * ) malloc( pDataLen ); /* we reserve space for a total size and totalItems */
154 if( !pdata ) return NS_ERROR_FAILURE;
157 for(PRUint32 itemIndex = 0; itemIndex < numDragItems; ++itemIndex) {
158 nsCOMPtr<nsISupports> genericItem;
159 mSourceDataItems->GetElementAt(itemIndex, getter_AddRefs(genericItem));
160 nsCOMPtr<nsITransferable> currItem (do_QueryInterface(genericItem));
161 if(currItem) {
162 nsCOMPtr <nsISupportsArray> flavorList;
163 currItem->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
164 if(flavorList) {
165 PRUint32 numFlavors;
166 flavorList->Count( &numFlavors );
167 for( PRUint32 flavorIndex = 0; flavorIndex < numFlavors ; ++flavorIndex ) {
168 nsCOMPtr<nsISupports> genericWrapper;
169 flavorList->GetElementAt (flavorIndex, getter_AddRefs(genericWrapper));
170 nsCOMPtr<nsISupportsCString> currentFlavor;
171 currentFlavor = do_QueryInterface(genericWrapper);
172 if(currentFlavor) {
173 nsXPIDLCString flavorStr;
174 currentFlavor->ToString ( getter_Copies(flavorStr) );
175 const char *FlavourStr = ( const char * ) flavorStr;
176 nsCOMPtr<nsISupports> data;
177 PRUint32 tmpDataLen = 0;
178 rv = currItem->GetTransferData( FlavourStr, getter_AddRefs(data), &tmpDataLen );
179 if( NS_SUCCEEDED( rv ) ) {
180 /* insert FlavourStr, data into the PtTransportCtrl_t */
181 int len = sizeof( PRUint32 ) + sizeof( PRUint32 ) + strlen( FlavourStr ) + 1 + tmpDataLen;
182 /* we reserve space for itemIndex|tmpDataLen|flavorStr|data */
183 len = ( ( len + 3 ) / 4 ) * 4;
184 pdata = ( char * ) realloc( pdata, len + pDataLen );
185 if( pdata ) {
186 char *p = pdata + pDataLen;
187 PRUint32 *d = ( PRUint32 * ) p;
188 d[0] = itemIndex; /* copy itemIndex*/
189 d[1] = tmpDataLen; /* copy PRUint32 tmpDataLen */
190 strcpy( p + sizeof( PRUint32 ) + sizeof( PRUint32 ), FlavourStr ); /* copy flavorStr */
192 void *mem_data;
193 nsPrimitiveHelpers::CreateDataFromPrimitive ( FlavourStr, data, &mem_data, tmpDataLen );
195 memcpy( p + sizeof( PRUint32 ) + sizeof( PRUint32 ) + strlen( FlavourStr ) + 1, mem_data, tmpDataLen ); /* copy the data */
196 pDataLen += len;
197 totalItems++;
206 if( totalItems ) {
207 PRUint32 *p = ( PRUint32 * ) pdata;
208 p[0] = pDataLen;
209 p[1] = totalItems;
210 mNativeCtrl = PtCreateTransportCtrl( );
212 if( !mTransportFile ) mTransportFile = strdup( (char*) tmpnam( NULL ) );
214 FILE *fp = fopen( mTransportFile, "w" );
215 fwrite( pdata, 1, pDataLen, fp );
216 fclose( fp );
217 free( pdata );
219 PtTransportType( mNativeCtrl, "Mozilla", "dnddata", 1, Ph_TRANSPORT_INLINE, "string", (void*)mTransportFile, 0, 0 );
220 PtInitDnd( mNativeCtrl, mDndWidget, (PhEvent_t*)mDndEvent, NULL, 0 );
223 return NS_OK;
228 //-------------------------------------------------------------------------
229 NS_IMETHODIMP nsDragService::GetNumDropItems (PRUint32 * aNumItems)
231 *aNumItems = 1;
232 return NS_OK;
236 //-------------------------------------------------------------------------
237 NS_IMETHODIMP nsDragService::GetData (nsITransferable * aTransferable, PRUint32 aItemIndex ) {
238 nsresult rv = NS_ERROR_FAILURE;
239 nsCOMPtr<nsISupports> genericDataWrapper;
241 if( mRawData ) {
242 PRUint32 *d = ( PRUint32 * ) mRawData, totalItems = d[1];
243 PRUint32 i, pdataLen = sizeof( PRUint32 ) + sizeof( PRUint32 );
245 /* search for aItemIndex */
246 for( i=0; i<totalItems; i++ ) {
247 char *p = mRawData + pdataLen;
248 PRUint32 *d = ( PRUint32 * ) p;
250 char *flavorStr = p + sizeof( PRUint32 ) + sizeof( PRUint32 );
251 PRUint32 this_len = sizeof( PRUint32 ) + sizeof( PRUint32 ) + strlen( flavorStr ) + 1 + d[1];
252 this_len = ( ( this_len + 3 ) / 4 ) * 4;
253 char *raw_data = flavorStr + strlen( flavorStr ) + 1;
255 if( d[0] == aItemIndex && !strcmp( mFlavourStr, flavorStr ) ) {
256 nsPrimitiveHelpers::CreatePrimitiveForData( flavorStr, raw_data, d[1], getter_AddRefs( genericDataWrapper ) );
257 rv = aTransferable->SetTransferData( flavorStr, genericDataWrapper, d[1] );
258 break;
261 pdataLen += this_len;
264 return rv;
267 //-------------------------------------------------------------------------
268 NS_IMETHODIMP nsDragService::IsDataFlavorSupported(const char *aDataFlavor, PRBool *_retval)
270 if (!aDataFlavor || !_retval)
271 return NS_ERROR_FAILURE;
273 // set this to no by default
274 *_retval = PR_FALSE;
276 const char *ask;
277 if( !strcmp( aDataFlavor, kMimeCustom ) ) ask = kHTMLMime;
278 else ask = aDataFlavor;
280 if(!mSourceDataItems) return NS_OK;
281 PRUint32 numDragItems = 0;
282 mSourceDataItems->Count(&numDragItems);
283 for(PRUint32 itemIndex = 0; itemIndex < numDragItems; ++itemIndex) {
284 nsCOMPtr<nsISupports> genericItem;
285 mSourceDataItems->GetElementAt(itemIndex, getter_AddRefs(genericItem));
286 nsCOMPtr<nsITransferable> currItem (do_QueryInterface(genericItem));
287 if(currItem) {
288 nsCOMPtr <nsISupportsArray> flavorList;
289 currItem->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
290 if(flavorList) {
291 PRUint32 numFlavors;
292 flavorList->Count( &numFlavors );
293 for( PRUint32 flavorIndex = 0; flavorIndex < numFlavors ; ++flavorIndex ) {
294 nsCOMPtr<nsISupports> genericWrapper;
295 flavorList->GetElementAt (flavorIndex, getter_AddRefs(genericWrapper));
296 nsCOMPtr<nsISupportsCString> currentFlavor;
297 currentFlavor = do_QueryInterface(genericWrapper);
298 if(currentFlavor) {
299 nsXPIDLCString flavorStr;
300 currentFlavor->ToString ( getter_Copies(flavorStr) );
301 if(strcmp(flavorStr, ask) == 0) {
302 *_retval = PR_TRUE;
303 if( mFlavourStr ) free( mFlavourStr );
304 mFlavourStr = strdup( ask );
312 return NS_OK;
315 void
316 nsDragService::SourceEndDrag(void)
318 // this just releases the list of data items that we provide
319 mSourceDataItems = 0;