comparison src/offix.c @ 272:c5d627a313b1 r21-0b34

Import from CVS: tag r21-0b34
author cvs
date Mon, 13 Aug 2007 10:28:48 +0200
parents 12579d965149
children 8626e4521993
comparison
equal deleted inserted replaced
271:c7b7086b0a39 272:c5d627a313b1
49 * Data for the standard Dnd cursors 49 * Data for the standard Dnd cursors
50 *=========================================================================*/ 50 *=========================================================================*/
51 #include "offix-cursors.h" 51 #include "offix-cursors.h"
52 52
53 /*=============================================================== CursorData 53 /*=============================================================== CursorData
54 * CursorData contains all the data for the cursors bitmaps 54 * CursorData contains all the data for the cursors bitmaps
55 *==========================================================================*/ 55 *==========================================================================*/
56 typedef struct 56 typedef struct
57 { 57 {
58 int Width,Height; 58 int Width,Height;
59 unsigned char *ImageData,*MaskData; 59 unsigned char *ImageData,*MaskData;
60 int HotSpotX,HotSpotY; 60 int HotSpotX,HotSpotY;
61 Pixmap ImagePixmap,MaskPixmap; 61 Pixmap ImagePixmap,MaskPixmap;
62 Cursor CursorID; 62 Cursor CursorID;
79 { app_width,app_height,app_bits,app_mask_bits, 79 { app_width,app_height,app_bits,app_mask_bits,
80 app_x_hot,app_y_hot }, 80 app_x_hot,app_y_hot },
81 { url_width,url_height,url_bits,url_mask_bits, 81 { url_width,url_height,url_bits,url_mask_bits,
82 url_x_hot,url_y_hot }, 82 url_x_hot,url_y_hot },
83 { mime_width,mime_height,mime_bits,mime_mask_bits, 83 { mime_width,mime_height,mime_bits,mime_mask_bits,
84 mime_x_hot,mime_y_hot } 84 mime_x_hot,mime_y_hot }
85 }; 85 };
86 86
87 /* Local prototypes */ 87 /* Local prototypes */
88 int DndIsDragging(void); 88 int DndIsDragging(void);
89 void DndStartAction(Widget widget, 89 void DndStartAction(Widget widget,
90 XtPointer data, 90 XtPointer data,
91 XEvent *event, 91 XEvent *event,
92 Boolean *p); 92 Boolean *p);
93 void DndPropertyHandler(Widget widget, 93 void DndPropertyHandler(Widget widget,
99 * Takes care of the drag and drop process. Wait until the pointer had moved 99 * Takes care of the drag and drop process. Wait until the pointer had moved
100 * a little. Then takes control over the pointer until the buttons are 100 * a little. Then takes control over the pointer until the buttons are
101 * released. After that send a Drag And Drop ClientMessage event. Returns 101 * released. After that send a Drag And Drop ClientMessage event. Returns
102 * non-zero if a drop did take place. 102 * non-zero if a drop did take place.
103 *===========================================================================*/ 103 *===========================================================================*/
104 int DndHandleDragging(Widget widget,XEvent *event) 104 int
105 DndHandleDragging(Widget widget,XEvent *event)
105 { 106 {
106 XEvent Event; 107 XEvent Event;
107 Window root = RootWindowOfScreen(XtScreenOfObject(widget)); 108 Window root = RootWindowOfScreen(XtScreenOfObject(widget));
108 XtAppContext app= XtWidgetToApplicationContext(widget); 109 XtAppContext app= XtWidgetToApplicationContext(widget);
109 Window DispatchWindow; 110 Window DispatchWindow;
116 XGrabPointer(dpy,root,False, 117 XGrabPointer(dpy,root,False,
117 ButtonMotionMask|ButtonPressMask|ButtonReleaseMask, 118 ButtonMotionMask|ButtonPressMask|ButtonReleaseMask,
118 GrabModeSync,GrabModeAsync,root, 119 GrabModeSync,GrabModeAsync,root,
119 DndCursor[DataType].CursorID, 120 DndCursor[DataType].CursorID,
120 CurrentTime); 121 CurrentTime);
121 122
122 /* Wait for button release */ 123 /* Wait for button release */
123 Dragging=1; RootFlag=0; 124 Dragging=1; RootFlag=0;
124 while(Dragging) 125 while(Dragging)
125 { 126 {
126 XAllowEvents(dpy,SyncPointer,CurrentTime); 127 XAllowEvents(dpy,SyncPointer,CurrentTime);
151 else 152 else
152 DispatchWindow=PointerWindow; 153 DispatchWindow=PointerWindow;
153 } 154 }
154 else 155 else
155 Target=DispatchWindow=XtWindow(MainWidget); 156 Target=DispatchWindow=XtWindow(MainWidget);
156 157
157 /* Now build the event structure */ 158 /* Now build the event structure */
158 DropX=Event.xbutton.x_root; 159 DropX=Event.xbutton.x_root;
159 DropY=Event.xbutton.y_root; 160 DropY=Event.xbutton.y_root;
160 Event.xclient.type = ClientMessage; 161 Event.xclient.type = ClientMessage;
161 Event.xclient.display = dpy; 162 Event.xclient.display = dpy;
165 Event.xclient.data.l[0] = DataType; 166 Event.xclient.data.l[0] = DataType;
166 Event.xclient.data.l[1] = (long)event->xbutton.state; 167 Event.xclient.data.l[1] = (long)event->xbutton.state;
167 Event.xclient.data.l[2] = (long)XtWindow(widget); 168 Event.xclient.data.l[2] = (long)XtWindow(widget);
168 Event.xclient.data.l[3] = DropX + 65536L*(long)DropY; 169 Event.xclient.data.l[3] = DropX + 65536L*(long)DropY;
169 Event.xclient.data.l[4] = 1; 170 Event.xclient.data.l[4] = 1;
170 171
171 /* Send the drop message */ 172 /* Send the drop message */
172 XSendEvent(dpy,DispatchWindow,True,NoEventMask,&Event); 173 XSendEvent(dpy,DispatchWindow,True,NoEventMask,&Event);
173 /* Send an old style version of the message just in case */ 174 /* Send an old style version of the message just in case */
174 Event.xclient.message_type = OldDndProtocol; 175 Event.xclient.message_type = OldDndProtocol;
175 XSendEvent(dpy,DispatchWindow,True,NoEventMask,&Event); 176 XSendEvent(dpy,DispatchWindow,True,NoEventMask,&Event);
176 177
177 #ifdef DEBUG 178 #ifdef DEBUG
178 fprintf(stderr,"ClientMessage sent to 0x%x(0x%x).\n", 179 fprintf(stderr,"ClientMessage sent to 0x%x(0x%x).\n",
179 DispatchWindow,Target); 180 DispatchWindow,Target);
180 fprintf(stderr,"The drop coordinates are (%d,%d).\n",DropX,DropY); 181 fprintf(stderr,"The drop coordinates are (%d,%d).\n",DropX,DropY);
181 #endif 182 #endif
191 { 192 {
192 Atom JunkAtom; 193 Atom JunkAtom;
193 int JunkInt; 194 int JunkInt;
194 unsigned long WinState,JunkLong; 195 unsigned long WinState,JunkLong;
195 unsigned char *Property; 196 unsigned char *Property;
196 197
197 XGetWindowProperty(dpy,XtWindow(widget),WM_STATE, 198 XGetWindowProperty(dpy,XtWindow(widget),WM_STATE,
198 0L,2L,False,AnyPropertyType, 199 0L,2L,False,AnyPropertyType,
199 &JunkAtom,&JunkInt,&WinState,&JunkLong, 200 &JunkAtom,&JunkInt,&WinState,&JunkLong,
200 &Property); 201 &Property);
201 WinState=(unsigned long)(*((long*)Property)); 202 WinState=(unsigned long)(*((long*)Property));
216 217
217 dpy = XtDisplayOfObject(shell); 218 dpy = XtDisplayOfObject(shell);
218 screen = DefaultScreen(dpy); 219 screen = DefaultScreen(dpy);
219 colormap= DefaultColormap(dpy,screen); 220 colormap= DefaultColormap(dpy,screen);
220 root = DefaultRootWindow(dpy); 221 root = DefaultRootWindow(dpy);
221 222
222 223
223 Black.pixel=BlackPixel(dpy,screen); 224 Black.pixel=BlackPixel(dpy,screen);
224 White.pixel=WhitePixel(dpy,screen); 225 White.pixel=WhitePixel(dpy,screen);
225 XQueryColor(dpy,colormap,&Black); 226 XQueryColor(dpy,colormap,&Black);
226 XQueryColor(dpy,colormap,&White); 227 XQueryColor(dpy,colormap,&White);
227 228
228 for(i=1;i!=DndEND;i++) 229 for(i=1;i!=DndEND;i++)
229 { 230 {
230 DndCursor[i].ImagePixmap= 231 DndCursor[i].ImagePixmap=
231 XCreateBitmapFromData(dpy,root, 232 XCreateBitmapFromData(dpy,root,
232 DndCursor[i].ImageData, 233 (char *) DndCursor[i].ImageData,
233 DndCursor[i].Width, 234 DndCursor[i].Width,
234 DndCursor[i].Height); 235 DndCursor[i].Height);
235 DndCursor[i].MaskPixmap= 236 DndCursor[i].MaskPixmap=
236 XCreateBitmapFromData(dpy,root, 237 XCreateBitmapFromData(dpy,root,
237 DndCursor[i].MaskData, 238 (char *) DndCursor[i].MaskData,
238 DndCursor[i].Width, 239 DndCursor[i].Width,
239 DndCursor[i].Height); 240 DndCursor[i].Height);
240 DndCursor[i].CursorID= 241 DndCursor[i].CursorID=
241 XCreatePixmapCursor(dpy,DndCursor[i].ImagePixmap, 242 XCreatePixmapCursor(dpy,DndCursor[i].ImagePixmap,
242 DndCursor[i].MaskPixmap, 243 DndCursor[i].MaskPixmap,
243 &Black,&White, 244 &Black,&White,
244 DndCursor[i].HotSpotX, 245 DndCursor[i].HotSpotX,
245 DndCursor[i].HotSpotY); 246 DndCursor[i].HotSpotY);
246 } 247 }
247 248
248 DndCursor[0].CursorID=XCreateFontCursor(dpy,XC_question_arrow); 249 DndCursor[0].CursorID=XCreateFontCursor(dpy,XC_question_arrow);
249 250
250 /* These two are for older versions */ 251 /* These two are for older versions */
251 OldDndProtocol=XInternAtom(dpy,"DndProtocol",FALSE); 252 OldDndProtocol=XInternAtom(dpy,"DndProtocol",FALSE);
252 OldDndSelection=XInternAtom(dpy,"DndSelection",FALSE); 253 OldDndSelection=XInternAtom(dpy,"DndSelection",FALSE);
253 /* Now the correct stuff */ 254 /* Now the correct stuff */
254 DndProtocol=XInternAtom(dpy,"_DND_PROTOCOL",FALSE); 255 DndProtocol=XInternAtom(dpy,"_DND_PROTOCOL",FALSE);
255 DndSelection=XInternAtom(dpy,"_DND_SELECTION",FALSE); 256 DndSelection=XInternAtom(dpy,"_DND_SELECTION",FALSE);
256 257
257 WM_STATE=XInternAtom(dpy,"WM_STATE",True); 258 WM_STATE=XInternAtom(dpy,"WM_STATE",True);
258 Dragging=0; 259 Dragging=0;
259 DragPrecision=10; 260 DragPrecision=10;
260 RootFlag=0; 261 RootFlag=0;
261 MainWidget=shell; 262 MainWidget=shell;
262 } 263 }
263 264
264 int DndIsDragging(void) { return Dragging; } 265 int
266 DndIsDragging(void)
267 {
268 return Dragging;
269 }
265 270
266 /*================================================================= DndSetData 271 /*================================================================= DndSetData
267 * Updates the selection data. 272 * Updates the selection data.
268 *===========================================================================*/ 273 *===========================================================================*/
269 void DndSetData(int Type,unsigned char *Data,unsigned long Size) 274 void
275 DndSetData(int Type,unsigned char *Data,unsigned long Size)
270 { 276 {
271 Window root = DefaultRootWindow(dpy); 277 Window root = DefaultRootWindow(dpy);
272 int AuxSize; 278 int AuxSize;
273 unsigned char *AuxData; 279 unsigned char *AuxData;
274 unsigned long BackSize=Size; 280 unsigned long BackSize=Size;
275 281
276 if (DataOK) return; 282 if (DataOK) return;
277 283
278 /* Set the data type -- allow any type */ 284 /* Set the data type -- allow any type */
279 DataType = Type; 285 DataType = Type;
280 286
281 /* Set the data */ 287 /* Set the data */
282 AuxData = Data; 288 AuxData = Data;
283 AuxSize = ( Size <= INT_MAX ? (int)Size : INT_MAX ); 289 AuxSize = ( Size <= INT_MAX ? (int)Size : INT_MAX );
284 XChangeProperty(dpy,root,DndSelection,XA_STRING,8, 290 XChangeProperty(dpy,root,DndSelection,XA_STRING,8,
285 PropModeReplace,Data,AuxSize); 291 PropModeReplace,Data,AuxSize);
286 for(Size-=(unsigned long)AuxSize;Size;Size-=(unsigned long)AuxSize) 292 for(Size-=(unsigned long)AuxSize;Size;Size-=(unsigned long)AuxSize)
287 { 293 {
288 Data+=AuxSize; 294 Data+=AuxSize;
289 AuxSize = ( (Size<=(INT_MAX)) ? (int)Size : (INT_MAX) ); 295 AuxSize = ( (Size<=(INT_MAX)) ? (int)Size : (INT_MAX) );
290 XChangeProperty(dpy,root,DndSelection,XA_STRING,8, 296 XChangeProperty(dpy,root,DndSelection,XA_STRING,8,
291 PropModeAppend,Data,AuxSize); 297 PropModeAppend,Data,AuxSize);
292 } 298 }
293 299
294 /* Set the data for old DND version */ 300 /* Set the data for old DND version */
295 Size = BackSize; 301 Size = BackSize;
296 AuxData = Data; 302 AuxData = Data;
297 AuxSize = ( Size <= INT_MAX ? (int)Size : INT_MAX ); 303 AuxSize = ( Size <= INT_MAX ? (int)Size : INT_MAX );
298 XChangeProperty(dpy,root,OldDndSelection,XA_STRING,8, 304 XChangeProperty(dpy,root,OldDndSelection,XA_STRING,8,
299 PropModeReplace,Data,AuxSize); 305 PropModeReplace,Data,AuxSize);
300 for(Size-=(unsigned long)AuxSize;Size;Size-=(unsigned long)AuxSize) 306 for(Size-=(unsigned long)AuxSize;Size;Size-=(unsigned long)AuxSize)
301 { 307 {
302 Data+=AuxSize; 308 Data+=AuxSize;
303 AuxSize = ( (Size<=(INT_MAX)) ? (int)Size : (INT_MAX) ); 309 AuxSize = ( (Size<=(INT_MAX)) ? (int)Size : (INT_MAX) );
304 XChangeProperty(dpy,root,OldDndSelection,XA_STRING,8, 310 XChangeProperty(dpy,root,OldDndSelection,XA_STRING,8,
305 PropModeAppend,Data,AuxSize); 311 PropModeAppend,Data,AuxSize);
306 } 312 }
307 313
308 /* Everything is now ok */ 314 /* Everything is now ok */
309 DataOK=1; 315 DataOK=1;
310 } 316 }
311 317
312 /*================================================================== DndGetData 318 /*================================================================== DndGetData
313 * Return a pointer to the current data. Se HOWTO for more details. 319 * Return a pointer to the current data. Se HOWTO for more details.
314 *===========================================================================*/ 320 *===========================================================================*/
315 void DndGetData(XEvent *event, unsigned char **Data,unsigned long *Size) 321 void
322 DndGetData(XEvent *event, unsigned char **Data,unsigned long *Size)
316 { 323 {
317 Window root = DefaultRootWindow(dpy); 324 Window root = DefaultRootWindow(dpy);
318 325
319 Atom ActualType,ActualDndSelection; 326 Atom ActualType,ActualDndSelection;
320 int ActualFormat; 327 int ActualFormat;
321 unsigned long RemainingBytes; 328 unsigned long RemainingBytes;
322 329
323 ActualDndSelection=(DndProtocolVersion(event) == 0L ? 330 ActualDndSelection=(DndProtocolVersion(event) == 0L ?
324 OldDndSelection : 331 OldDndSelection :
325 DndSelection ); 332 DndSelection );
326 333
327 XGetWindowProperty(dpy,root,ActualDndSelection, 334 XGetWindowProperty(dpy,root,ActualDndSelection,
328 0L,1000000L, 335 0L,1000000L,
329 FALSE,AnyPropertyType, 336 FALSE,AnyPropertyType,
330 &ActualType,&ActualFormat, 337 &ActualType,&ActualFormat,
331 Size,&RemainingBytes, 338 Size,&RemainingBytes,
332 Data); 339 Data);
333 } 340 }
334 341
335 /*================================== DndDataType DndDragButtons DndSourceWidget 342 /*================================== DndDataType DndDragButtons DndSourceWidget
336 * 343 *
337 * Return information about the Dnd event received. If a non-dnd event is 344 * Return information about the Dnd event received. If a non-dnd event is
338 * passed, the function DndDataType returns DndNotDnd, and the others 345 * passed, the function DndDataType returns DndNotDnd, and the others
339 * return zero. 346 * return zero.
340 *===========================================================================*/ 347 *===========================================================================*/
341 int DndDataType(XEvent *event) 348 int
349 DndDataType(XEvent *event)
342 { 350 {
343 int Type; 351 int Type;
344 352
345 if(!DndIsDropMessage(event)) return DndNotDnd; 353 if(!DndIsDropMessage(event)) return DndNotDnd;
346 Type=(int)(event->xclient.data.l[0]); 354 Type=(int)(event->xclient.data.l[0]);
347 if(Type>=DndEND) Type=DndUnknown; 355 if(Type>=DndEND) Type=DndUnknown;
348 return Type; 356 return Type;
349 } 357 }
350 358
351 unsigned int DndDragButtons(XEvent *event) 359 unsigned int
360 DndDragButtons(XEvent *event)
352 { 361 {
353 if(!DndIsDropMessage(event)) return 0; 362 if(!DndIsDropMessage(event)) return 0;
354 return (unsigned int)(event->xclient.data.l[1]); 363 return (unsigned int)(event->xclient.data.l[1]);
355 } 364 }
356 365
357 Window DndSourceWindow(XEvent *event) 366 Window
367 DndSourceWindow(XEvent *event)
358 { 368 {
359 if(!DndIsDropMessage(event)) return 0; 369 if(!DndIsDropMessage(event)) return 0;
360 if(DndProtocolVersion(event)<__DragAndDropH__) 370 if(DndProtocolVersion(event)<__DragAndDropH__)
361 /* We will try to do something about it, but nothing is certain */ 371 /* We will try to do something about it, but nothing is certain */
362 return XtWindow((Widget)(event->xclient.data.l[2])); 372 return XtWindow((Widget)(event->xclient.data.l[2]));
363 return (Window)(event->xclient.data.l[2]); 373 return (Window)(event->xclient.data.l[2]);
364 } 374 }
365 375
366 void DndDropRootCoordinates(XEvent *event,int *x,int *y) 376 void
377 DndDropRootCoordinates(XEvent *event,int *x,int *y)
367 { 378 {
368 if(!DndIsDropMessage(event)) 379 if(!DndIsDropMessage(event))
369 { 380 {
370 *x=0; *y=0; 381 *x=0; *y=0;
371 return; 382 return;
372 } 383 }
373 384
374 /* If it is an old protocol version we try to get the coordinates 385 /* If it is an old protocol version we try to get the coordinates
375 using the current pointer position. Of course, the pointer may have 386 using the current pointer position. Of course, the pointer may have
376 moved since the drop, but there's nothing we can do about it. 387 moved since the drop, but there's nothing we can do about it.
377 */ 388 */
378 if(DndProtocolVersion(event)<1L) 389 if(DndProtocolVersion(event)<1L)
379 { 390 {
380 Window root_return,child_return; 391 Window root_return,child_return;
381 int win_x_return,win_y_return; 392 int win_x_return,win_y_return;
382 unsigned int mask_return; 393 unsigned int mask_return;
383 394
384 XQueryPointer(dpy,DefaultRootWindow(dpy), 395 XQueryPointer(dpy,DefaultRootWindow(dpy),
385 &root_return,&child_return,x,y, 396 &root_return,&child_return,x,y,
386 &win_x_return,&win_y_return,&mask_return); 397 &win_x_return,&win_y_return,&mask_return);
387 return; 398 return;
388 } 399 }
389 /* Thanks god you are using a decent protocol version */ 400 /* Thanks god you are using a decent protocol version */
390 *x=(int)((long)(event->xclient.data.l[3]) & 0xffff); 401 *x=(int)((long)(event->xclient.data.l[3]) & 0xffff);
391 *y=(int)((long)(event->xclient.data.l[3])/65536); 402 *y=(int)((long)(event->xclient.data.l[3])/65536);
392 } 403 }
393 404
394 void DndDropCoordinates(Widget widget,XEvent *event,int *x,int *y) 405 void
406 DndDropCoordinates(Widget widget,XEvent *event,int *x,int *y)
395 { 407 {
396 int root_x,root_y; 408 int root_x,root_y;
397 Window child_return; 409 Window child_return;
398 410
399 DndDropRootCoordinates(event,&root_x,&root_y); 411 DndDropRootCoordinates(event,&root_x,&root_y);
400 XTranslateCoordinates(dpy,DefaultRootWindow(dpy), 412 XTranslateCoordinates(dpy,DefaultRootWindow(dpy),
401 XtWindow(widget), 413 XtWindow(widget),
402 root_x,root_y, 414 root_x,root_y,
403 x,y, 415 x,y,
404 &child_return); 416 &child_return);
405 } 417 }
406 418
407 long DndProtocolVersion(XEvent *event) 419 long
420 DndProtocolVersion(XEvent *event)
408 { 421 {
409 if(!DndIsDropMessage(event)) return -1L; 422 if(!DndIsDropMessage(event)) return -1L;
410 return event->xclient.data.l[4]; 423 return event->xclient.data.l[4];
411 } 424 }
412 425
413 int DndIsDropMessage(XEvent *event) 426 int
427 DndIsDropMessage(XEvent *event)
414 { 428 {
415 if(event->xclient.type != ClientMessage) return 0; 429 if(event->xclient.type != ClientMessage) return 0;
416 if(event->xclient.message_type == OldDndProtocol && 430 if(event->xclient.message_type == OldDndProtocol &&
417 event->xclient.data.l[4]==0) return 1; 431 event->xclient.data.l[4]==0) return 1;
418 if(event->xclient.message_type == DndProtocol) return 1; 432 if(event->xclient.message_type == DndProtocol) return 1;
419 return 0; 433 return 0;
420 } 434 }
421 435
422 void DndChangeCursor(int Type,int width,int height,char *image,char *mask, 436 void
423 int hot_x,int hot_y) 437 DndChangeCursor(int Type,int width,int height,char *image,char *mask,
438 int hot_x,int hot_y)
424 { 439 {
425 DndCursor[Type].ImagePixmap= 440 DndCursor[Type].ImagePixmap=
426 XCreateBitmapFromData(dpy,DefaultRootWindow(dpy), 441 XCreateBitmapFromData(dpy,DefaultRootWindow(dpy),
427 image,width,height); 442 image,width,height);
428 DndCursor[Type].MaskPixmap= 443 DndCursor[Type].MaskPixmap=