1 /*
2 * Motif
3 *
4 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
5 *
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
22 */
23 #ifdef REV_INFO
24 #ifndef lint
25 static char rcsid[] = "$XConsortium: DragUnder.c /main/12 1995/07/14 10:26:51 drk $"
26 #endif
27 #endif
28
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32
33
34 #include <Xm/DrawP.h>
35 #include "XmI.h"
36 #include "DragCI.h"
37 #include "DragICCI.h"
38 #include "DragOverSI.h"
39 #include "DragUnderI.h"
40 #include "DropSMgrI.h"
41 #include "GadgetUtiI.h"
42 #include "MessagesI.h"
43 #include "RegionI.h"
44 #include "ScreenI.h"
45
46 #define MESSAGE1 _XmMMsgDragUnder_0000
47 #define MESSAGE2 _XmMMsgDragUnder_0001
48
49 /******** Static Function Declarations ********/
50
51 static XmAnimationSaveData CreateAnimationSaveData(
52 XmDragContext dc,
53 XmAnimationData aData,
54 XmDragProcCallbackStruct *dpcb) ;
55 static void FreeAnimationData(
56 XmAnimationSaveData aSaveData) ;
57 static Boolean SaveAll(
58 XmAnimationSaveData aSaveData,
59 Position x,
60 Position y,
61 Dimension width,
62 Dimension height) ;
63 static Boolean SaveSegments(
64 XmAnimationSaveData aSaveData,
65 Position x,
66 Position y,
67 Dimension width,
68 Dimension height,
69 Dimension *thickness) ;
70 static void DrawHighlight(
71 XmAnimationSaveData aSaveData) ;
72 static void DrawShadow(
73 XmAnimationSaveData aSaveData) ;
74 static void DrawPixmap(
75 XmAnimationSaveData aSaveData) ;
76 static void AnimateExpose(Widget w, XmAnimationSaveData aSaveData,
77 XEvent *event,
78 Boolean *cont);
79 static void AnimateEnter(
80 XmDropSiteManagerObject dsm,
81 XmAnimationData aData,
82 XmDragProcCallbackStruct *dpcb) ;
83 static void AnimateLeave(
84 XmDropSiteManagerObject dsm,
85 XmAnimationData aData,
86 XmDragProcCallbackStruct *dpcb) ;
87
88 /******** End Static Function Declarations ********/
89
90
91 /*****************************************************************************
92 *
93 * CreateAnimationSaveData ()
94 *
95 * Create and fill an XmAnimationSaveData structure containing the data
96 * needed to animate the dropsite.
97 ***************************************************************************/
98
99 /*ARGSUSED*/
100 static XmAnimationSaveData
CreateAnimationSaveData(XmDragContext dc,XmAnimationData aData,XmDragProcCallbackStruct * dpcb)101 CreateAnimationSaveData(
102 XmDragContext dc,
103 XmAnimationData aData,
104 XmDragProcCallbackStruct *dpcb ) /* unused */
105 {
106 XmAnimationSaveData aSaveData;
107 XGCValues v;
108 unsigned long vmask;
109 XmDropSiteVisuals dsv;
110 int ac;
111 Arg al[5];
112 Window junkWin;
113 int junkInt;
114 unsigned int junkUInt;
115 unsigned char activeMode;
116
117 aSaveData = (XmAnimationSaveData)
118 XtMalloc (sizeof (XmAnimationSaveDataRec));
119
120 aSaveData->dragOver = aData->dragOver;
121 aSaveData->display = XtDisplay (dc);
122 aSaveData->xmScreen = (XmScreen) XmGetXmScreen (aData->screen);
123
124 aSaveData->window = aData->window;
125 aSaveData->windowX = aData->windowX;
126 aSaveData->windowY = aData->windowY;
127
128 if (aSaveData->dragOver) {
129 aSaveData->xmScreen = (XmScreen) XmGetXmScreen (XtScreen (aSaveData->dragOver));
130 }
131 else {
132 aSaveData->xmScreen = (XmScreen) XmGetXmScreen(XtScreen (dc));
133 }
134
135 /*
136 * Get the window depth.
137 */
138
139 if (!XGetGeometry (aSaveData->display, aSaveData->window,
140 &junkWin, &junkInt, &junkInt,
141 &junkUInt, &junkUInt, &junkUInt,
142 &(aSaveData->windowDepth))) {
143 XmeWarning ((Widget) dc, MESSAGE1);
144 aSaveData->windowDepth = 0;
145 }
146
147 aSaveData->clipRegion = aData->clipRegion;
148 aSaveData->dropSiteRegion = aData->dropSiteRegion;
149
150 dsv = XmDropSiteGetActiveVisuals ((Widget) dc);
151 aSaveData->background = dsv->background;
152 aSaveData->foreground = dsv->foreground;
153 aSaveData->topShadowColor = dsv->topShadowColor;
154 aSaveData->topShadowPixmap = dsv->topShadowPixmap;
155 aSaveData->bottomShadowColor = dsv->bottomShadowColor;
156 aSaveData->bottomShadowPixmap = dsv->bottomShadowPixmap;
157 aSaveData->shadowThickness = dsv->shadowThickness;
158 aSaveData->highlightThickness = dsv->highlightThickness;
159 aSaveData->highlightColor = dsv->highlightColor;
160 aSaveData->highlightPixmap = dsv->highlightPixmap;
161 aSaveData->borderWidth = dsv->borderWidth;
162 XtFree ((char *)dsv);
163
164 ac = 0;
165 XtSetArg (al[ac], XmNanimationStyle, &(aSaveData->animationStyle)); ac++;
166 XtSetArg (al[ac], XmNanimationMask, &(aSaveData->animationMask)); ac++;
167 XtSetArg (al[ac], XmNanimationPixmap, &(aSaveData->animationPixmap)); ac++;
168 XtSetArg (al[ac], XmNanimationPixmapDepth,
169 &(aSaveData->animationPixmapDepth)); ac++;
170 XmDropSiteRetrieve ((Widget) dc, al, ac);
171
172 if (aSaveData->animationStyle == XmDRAG_UNDER_PIXMAP &&
173 aSaveData->animationPixmap != None &&
174 aSaveData->animationPixmap != XmUNSPECIFIED_PIXMAP &&
175 aSaveData->animationPixmapDepth != 1 &&
176 aSaveData->animationPixmapDepth != aSaveData->windowDepth) {
177
178 XmeWarning ((Widget) dc, MESSAGE2);
179 aSaveData->animationPixmap = XmUNSPECIFIED_PIXMAP;
180 }
181
182 /*
183 * Create the draw GC.
184 */
185
186 v.foreground = aSaveData->foreground;
187 v.background = aSaveData->background;
188 v.graphics_exposures = False;
189 v.subwindow_mode = IncludeInferiors;
190 vmask = GCGraphicsExposures|GCSubwindowMode|GCForeground|GCBackground;
191 aSaveData->drawGC =
192 XCreateGC (aSaveData->display, aSaveData->window, vmask, &v);
193
194 if (aSaveData -> dragOver != (Widget) NULL) {
195 /* Save info on active drag over mode */
196 XtSetArg(al[0], XmNdragOverActiveMode, &activeMode);
197 XtGetValues((Widget) aSaveData -> dragOver, al, 1);
198 aSaveData->activeMode = activeMode;
199 } else {
200 /* XmCURSOR is as good as any other value for here. We only
201 check this against XmDRAG_WINDOW */
202 aSaveData->activeMode = XmCURSOR;
203 }
204
205 /* initialize savedPixmaps list */
206 aSaveData->savedPixmaps = NULL;
207 aSaveData->numSavedPixmaps = 0;
208
209 return (aSaveData);
210 }
211
212 /*****************************************************************************
213 *
214 * FreeAnimationData ()
215 *
216 * Free an XmAnimationSaveData structure.
217 ***************************************************************************/
218
219 static void
FreeAnimationData(XmAnimationSaveData aSaveData)220 FreeAnimationData(
221 XmAnimationSaveData aSaveData )
222 {
223 Cardinal i;
224
225 switch (aSaveData->animationStyle)
226 {
227 case XmDRAG_UNDER_SHADOW_IN:
228 case XmDRAG_UNDER_SHADOW_OUT:
229 XFreeGC (aSaveData->display, aSaveData->topShadowGC);
230 XFreeGC (aSaveData->display, aSaveData->bottomShadowGC);
231 XFreeGC (aSaveData->display, aSaveData->drawGC);
232 break;
233
234 case XmDRAG_UNDER_HIGHLIGHT:
235 XFreeGC (aSaveData->display, aSaveData->highlightGC);
236 XFreeGC (aSaveData->display, aSaveData->drawGC);
237 break;
238
239 case XmDRAG_UNDER_PIXMAP:
240 XFreeGC (aSaveData->display, aSaveData->drawGC);
241
242 case XmDRAG_UNDER_NONE:
243 default:
244 break;
245 }
246
247 if (aSaveData->numSavedPixmaps) {
248 for (i = 0; i < aSaveData->numSavedPixmaps; i++) {
249 _XmFreeScratchPixmap (aSaveData->xmScreen,
250 aSaveData->savedPixmaps[i].pixmap);
251 }
252 XtFree ((char *)aSaveData->savedPixmaps);
253 }
254
255 XtFree ((char *)aSaveData);
256 }
257
258 /*****************************************************************************
259 *
260 * SaveAll ()
261 *
262 * Save the original contents of a dropsite window that will be overwritten
263 * by dropsite animation into a rectangular backing store.
264 ***************************************************************************/
265
266 static Boolean
SaveAll(XmAnimationSaveData aSaveData,Position x,Position y,Dimension width,Dimension height)267 SaveAll(
268 XmAnimationSaveData aSaveData,
269 Position x,
270 Position y,
271 Dimension width,
272 Dimension height )
273 {
274 DragPixmapData *pData;
275
276 if (width <= 0 || height <= 0) {
277 return (False);
278 }
279
280 aSaveData->numSavedPixmaps = 1;
281 aSaveData->savedPixmaps = pData =
282 (DragPixmapData *) XtMalloc (sizeof(DragPixmapData));
283 if (!pData) {
284 return (False);
285 }
286
287 pData->x = x;
288 pData->y = y;
289 pData->width = width;
290 pData->height = height;
291 pData->pixmap =
292 _XmAllocScratchPixmap (aSaveData->xmScreen,
293 (Cardinal) aSaveData->windowDepth,
294 pData->width, pData->height);
295 XCopyArea (aSaveData->display, aSaveData->window,
296 pData->pixmap, aSaveData->drawGC,
297 pData->x, pData->y,
298 pData->width, pData->height, 0, 0);
299
300 return (True);
301 }
302
303 /*****************************************************************************
304 *
305 * SaveSegments ()
306 *
307 * Save the original contents of a dropsite window that will be overwritten
308 * by dropsite highlighting or shadowing of indicated thickness. This will
309 * save 0, 1, or 4 strips into backing store, depending on the dimensions
310 * of the dropsite and the animation thickness.
311 ***************************************************************************/
312
313 static Boolean
SaveSegments(XmAnimationSaveData aSaveData,Position x,Position y,Dimension width,Dimension height,Dimension * thickness)314 SaveSegments(
315 XmAnimationSaveData aSaveData,
316 Position x,
317 Position y,
318 Dimension width,
319 Dimension height,
320 Dimension *thickness )
321 {
322 DragPixmapData *pData;
323 Boolean save_all = False;
324
325 if (width <= 0 || height <= 0 || *thickness <= 0) {
326 return (False);
327 }
328 if (*thickness > (width >> 1)) {
329 *thickness = (width >> 1);
330 save_all = True;
331 }
332 if (*thickness > (height >> 1)) {
333 *thickness = (height >> 1);
334 save_all = True;
335 }
336
337 if (save_all) {
338 return (SaveAll (aSaveData, x, y, width, height));
339 }
340
341 aSaveData->numSavedPixmaps = 4;
342 aSaveData->savedPixmaps = pData =
343 (DragPixmapData *) XtMalloc (sizeof(DragPixmapData) * 4);
344 if (!pData) {
345 return (False);
346 }
347
348 pData->x = x;
349 pData->y = y;
350 pData->width = width;
351 pData->height = *thickness;
352 pData->pixmap =
353 _XmAllocScratchPixmap (aSaveData->xmScreen,
354 (Cardinal) aSaveData->windowDepth,
355 pData->width, pData->height);
356 XCopyArea (aSaveData->display, aSaveData->window,
357 pData->pixmap, aSaveData->drawGC,
358 pData->x, pData->y,
359 pData->width, pData->height, 0, 0);
360
361 pData++;
362 pData->x = x;
363 pData->y = y + *thickness;
364 pData->width = *thickness;
365 pData->height = height - (*thickness << 1);
366 pData->pixmap =
367 _XmAllocScratchPixmap (aSaveData->xmScreen,
368 (Cardinal) aSaveData->windowDepth,
369 pData->width, pData->height);
370 XCopyArea (aSaveData->display, aSaveData->window,
371 pData->pixmap, aSaveData->drawGC,
372 pData->x, pData->y,
373 pData->width, pData->height, 0, 0);
374
375 pData++;
376 pData->x = x;
377 pData->y = y + height - *thickness;
378 pData->width = width;
379 pData->height = *thickness;
380 pData->pixmap =
381 _XmAllocScratchPixmap (aSaveData->xmScreen,
382 (Cardinal) aSaveData->windowDepth,
383 pData->width, pData->height);
384 XCopyArea (aSaveData->display, aSaveData->window,
385 pData->pixmap, aSaveData->drawGC,
386 pData->x, pData->y,
387 pData->width, pData->height, 0, 0);
388
389 pData++;
390 pData->x = x + width - *thickness;
391 pData->y = y + *thickness;
392 pData->width = *thickness;
393 pData->height = height - (*thickness << 1);
394 pData->pixmap =
395 _XmAllocScratchPixmap (aSaveData->xmScreen,
396 (Cardinal) aSaveData->windowDepth,
397 pData->width, pData->height);
398 XCopyArea (aSaveData->display, aSaveData->window,
399 pData->pixmap, aSaveData->drawGC,
400 pData->x, pData->y,
401 pData->width, pData->height, 0, 0);
402
403 return (True);
404 }
405
406 /*****************************************************************************
407 *
408 * DrawHighlight ()
409 *
410 * Draws a highlight around the indicated region.
411 ***************************************************************************/
412
413 static void
DrawHighlight(XmAnimationSaveData aSaveData)414 DrawHighlight(
415 XmAnimationSaveData aSaveData )
416 {
417 XGCValues v;
418 unsigned long vmask;
419 Dimension offset;
420 Position x;
421 Position y;
422 Dimension width;
423 Dimension height;
424 XRectangle extents;
425
426 /*
427 * Create the highlightGC
428 */
429
430 v.foreground = aSaveData->highlightColor;
431 v.background = aSaveData->background;
432 v.graphics_exposures = False;
433 v.subwindow_mode = IncludeInferiors;
434 vmask = GCGraphicsExposures|GCSubwindowMode|GCForeground|GCBackground;
435
436 if (aSaveData->highlightPixmap != None &&
437 aSaveData->highlightPixmap != XmUNSPECIFIED_PIXMAP) {
438 int depth ;
439
440 XmeGetPixmapData(XtScreen(aSaveData->xmScreen),
441 aSaveData->highlightPixmap,
442 NULL,
443 &depth,
444 NULL, NULL, NULL, NULL, NULL, NULL);
445
446 if (depth == 1) {
447 v.fill_style = FillStippled;
448 v.stipple = aSaveData->highlightPixmap;
449 vmask |= GCStipple | GCFillStyle;
450 } else {
451 v.fill_style = FillTiled;
452 v.tile = aSaveData->highlightPixmap;
453 vmask |= GCTile | GCFillStyle;
454 }
455 }
456
457 aSaveData->highlightGC =
458 XCreateGC(aSaveData->display, aSaveData->window, vmask, &v);
459
460 _XmRegionSetGCRegion (aSaveData->display, aSaveData->highlightGC,
461 0, 0, aSaveData->clipRegion);
462
463 /* draw highlight */
464
465 _XmRegionGetExtents (aSaveData->dropSiteRegion, &extents);
466 offset = aSaveData->borderWidth;
467
468 if (_XmRegionGetNumRectangles(aSaveData->dropSiteRegion) == 1L) {
469
470 x = extents.x + offset;
471 y = extents.y + offset;
472 width = extents.width - (offset << 1);
473 height = extents.height - (offset << 1);
474
475 if (SaveSegments (aSaveData, x, y, width, height,
476 &aSaveData->highlightThickness)) {
477 XmeDrawHighlight (aSaveData->display, aSaveData->window,
478 aSaveData->highlightGC,
479 x, y, width, height,
480 aSaveData->highlightThickness);
481 }
482 }
483 else {
484 if (SaveAll (aSaveData, extents.x, extents.y, extents.width,
485 extents.height)) {
486 _XmRegionDrawShadow (aSaveData->display, aSaveData->window,
487 aSaveData->highlightGC, aSaveData->highlightGC,
488 aSaveData->dropSiteRegion,
489 offset, aSaveData->highlightThickness,
490 XmSHADOW_OUT);
491 }
492 }
493 }
494
495 /*****************************************************************************
496 *
497 * DrawShadow ()
498 *
499 * Draws a 3-D shadow around the indicated region.
500 ***************************************************************************/
501
502 static void
DrawShadow(XmAnimationSaveData aSaveData)503 DrawShadow(
504 XmAnimationSaveData aSaveData )
505 {
506 XGCValues v;
507 unsigned long vmask;
508 Dimension offset;
509 Position x;
510 Position y;
511 Dimension width;
512 Dimension height;
513 XRectangle extents;
514
515 /*
516 * Create the topShadowGC
517 */
518
519 v.foreground = aSaveData->topShadowColor;
520 v.background = aSaveData->foreground;
521 v.graphics_exposures = False;
522 v.subwindow_mode = IncludeInferiors;
523 vmask = GCGraphicsExposures|GCSubwindowMode|GCForeground|GCBackground;
524
525 if (aSaveData->topShadowPixmap != None &&
526 aSaveData->topShadowPixmap != XmUNSPECIFIED_PIXMAP) {
527 int depth ;
528
529 XmeGetPixmapData(XtScreen(aSaveData->xmScreen),
530 aSaveData->topShadowPixmap,
531 NULL,
532 &depth,
533 NULL, NULL, NULL, NULL, NULL, NULL);
534
535 if (depth == 1) {
536 v.fill_style = FillStippled;
537 v.stipple = aSaveData->topShadowPixmap;
538 vmask |= GCStipple | GCFillStyle;
539 } else {
540 v.fill_style = FillTiled;
541 v.tile = aSaveData->topShadowPixmap;
542 vmask |= GCTile | GCFillStyle;
543 }
544 }
545
546 aSaveData->topShadowGC =
547 XCreateGC(aSaveData->display, aSaveData->window, vmask, &v);
548
549 _XmRegionSetGCRegion (aSaveData->display, aSaveData->topShadowGC,
550 0, 0, aSaveData->clipRegion);
551
552 /*
553 * Create the bottomShadowGC
554 */
555
556 v.foreground = aSaveData->bottomShadowColor;
557 v.background = aSaveData->foreground;
558 v.graphics_exposures = False;
559 v.subwindow_mode = IncludeInferiors;
560 vmask = GCGraphicsExposures|GCSubwindowMode|GCForeground|GCBackground;
561
562 if (aSaveData->bottomShadowPixmap != None &&
563 aSaveData->bottomShadowPixmap != XmUNSPECIFIED_PIXMAP) {
564 int depth ;
565
566 XmeGetPixmapData(XtScreen(aSaveData->xmScreen),
567 aSaveData->bottomShadowPixmap,
568 NULL,
569 &depth,
570 NULL, NULL, NULL, NULL, NULL, NULL);
571
572 if (depth == 1) {
573 v.fill_style = FillStippled;
574 v.stipple = aSaveData->bottomShadowPixmap;
575 vmask |= GCStipple | GCFillStyle;
576 } else {
577 v.fill_style = FillTiled;
578 v.tile = aSaveData->bottomShadowPixmap;
579 vmask |= GCTile | GCFillStyle;
580 }
581 }
582
583
584 aSaveData->bottomShadowGC =
585 XCreateGC(aSaveData->display, aSaveData->window, vmask, &v);
586
587 _XmRegionSetGCRegion (aSaveData->display, aSaveData->bottomShadowGC,
588 0, 0, aSaveData->clipRegion);
589
590 /*
591 * Draw the shadows.
592 */
593
594 _XmRegionGetExtents (aSaveData->dropSiteRegion, &extents);
595 offset = aSaveData->borderWidth + aSaveData->highlightThickness;
596
597 if (_XmRegionGetNumRectangles(aSaveData->dropSiteRegion) == 1L) {
598
599 x = extents.x + offset;
600 y = extents.y + offset;
601 width = extents.width - (offset << 1);
602 height = extents.height - (offset << 1);
603
604 if (SaveSegments (aSaveData, x, y, width, height,
605 &aSaveData->shadowThickness)) {
606 XmeDrawShadows (aSaveData->display, aSaveData->window,
607 aSaveData->topShadowGC,
608 aSaveData->bottomShadowGC,
609 x, y, width, height,
610 aSaveData->shadowThickness,
611 (aSaveData->animationStyle ==
612 XmDRAG_UNDER_SHADOW_IN) ?
613 XmSHADOW_IN : XmSHADOW_OUT);
614 }
615 }
616 else {
617 if (SaveAll (aSaveData, extents.x, extents.y,
618 extents.width, extents.height)) {
619 _XmRegionDrawShadow (aSaveData->display, aSaveData->window,
620 aSaveData->topShadowGC,
621 aSaveData->bottomShadowGC,
622 aSaveData->dropSiteRegion,
623 offset, aSaveData->shadowThickness,
624 (aSaveData->animationStyle ==
625 XmDRAG_UNDER_SHADOW_IN) ?
626 XmSHADOW_IN : XmSHADOW_OUT);
627 }
628 }
629 }
630
631 /*****************************************************************************
632 *
633 * DrawPixmap ()
634 *
635 * Copy an animationPixmap, possibly masked, to the dropsite window.
636 ***************************************************************************/
637
638 static void
DrawPixmap(XmAnimationSaveData aSaveData)639 DrawPixmap(
640 XmAnimationSaveData aSaveData )
641 {
642 Position x;
643 Position y;
644 Dimension width;
645 Dimension height;
646 XRectangle extents;
647 XGCValues v;
648 unsigned long vmask;
649 Pixmap mask = XmUNSPECIFIED_PIXMAP;
650 GC maskGC = NULL;
651
652 if (aSaveData->animationPixmap == None ||
653 aSaveData->animationPixmap == XmUNSPECIFIED_PIXMAP) {
654 return;
655 }
656
657 /*
658 * Determine the destination location and dimensions -- the
659 * dropsite's bounding box.
660 */
661
662 _XmRegionGetExtents (aSaveData->dropSiteRegion, &extents);
663 x = extents.x;
664 y = extents.y;
665 width = extents.width;
666 height = extents.height;
667
668 /*
669 * Save the original window contents.
670 * Draw the DrawUnder pixmap into the window.
671 * Assume correct depth -- checked in CreateAnimationSaveData().
672 */
673
674 if (SaveAll (aSaveData, x, y, width, height)) {
675
676 if (aSaveData->animationMask != None &&
677 aSaveData->animationMask != XmUNSPECIFIED_PIXMAP) {
678
679 /*
680 * AnimationMask specified: create a composite mask consisting
681 * of both the clipping region and the animationMask to use for
682 * copying the animationPixmap into the dropSite.
683 *
684 * Create a mask and maskGC.
685 * Set the composite mask to 0's.
686 * Or the animationMask into it through the ClipRegion.
687 * Set the drawGC's ClipMask to the composite mask.
688 */
689
690 mask = _XmAllocScratchPixmap (aSaveData->xmScreen, 1,
691 width, height);
692
693 v.background = 0;
694 v.foreground = 1;
695 v.function = GXclear;
696 v.graphics_exposures = False;
697 v.subwindow_mode = IncludeInferiors;
698 vmask = GCGraphicsExposures|GCSubwindowMode|
699 GCBackground|GCForeground|GCFunction;
700 maskGC = XCreateGC (aSaveData->display, mask, vmask, &v);
701
702 XFillRectangle (aSaveData->display, mask, maskGC,
703 0, 0, width, height);
704
705 XSetFunction (aSaveData->display, maskGC, GXor);
706 _XmRegionSetGCRegion (aSaveData->display, maskGC,
707 -x, -y, aSaveData->clipRegion);
708 XCopyArea (aSaveData->display,
709 aSaveData->animationMask,
710 mask, maskGC,
711 0, 0, width, height, 0, 0);
712
713 XSetClipOrigin (aSaveData->display, aSaveData->drawGC, x, y);
714 XSetClipMask (aSaveData->display, aSaveData->drawGC, mask);
715
716 XFreeGC (aSaveData->display, maskGC);
717 }
718 else {
719 _XmRegionSetGCRegion (aSaveData->display, aSaveData->drawGC,
720 0, 0, aSaveData->clipRegion);
721 }
722
723 /*
724 * Copy the animationPixmap to the window.
725 * If the animationPixmapDepth is 1 we treat the animationPixmap
726 * as a bitmap and use XCopyPlane. For 1-deep dropsite windows,
727 * this may not be the same as treating the animationPixmap as a
728 * 1-deep pixmap and using XCopyArea.
729 */
730
731 if (aSaveData->animationPixmapDepth == 1) {
732 XCopyPlane (aSaveData->display,
733 aSaveData->animationPixmap,
734 aSaveData->window, aSaveData->drawGC,
735 0, 0, width, height, x, y, 1L);
736 }
737 else {
738 XCopyArea (aSaveData->display,
739 aSaveData->animationPixmap,
740 aSaveData->window, aSaveData->drawGC,
741 0, 0, width, height, x, y);
742 }
743 if (mask != XmUNSPECIFIED_PIXMAP) {
744 _XmFreeScratchPixmap (aSaveData->xmScreen, mask);
745 }
746 }
747 }
748
749 /*****************************************************************************
750 *
751 * AnimateExpose ()
752 *
753 ***************************************************************************/
754
755 /*ARGSUSED*/
756 static void
AnimateExpose(Widget w,XmAnimationSaveData aSaveData,XEvent * event,Boolean * cont)757 AnimateExpose(Widget w, /* unused */
758 XmAnimationSaveData aSaveData,
759 XEvent *event, /* unused */
760 Boolean *cont) /* unused */
761 {
762 /*
763 * If dragging a pixmap or window, hide it while drawing the
764 * animation.
765 */
766
767 if (aSaveData->dragOver && aSaveData->activeMode != XmDRAG_WINDOW) {
768 _XmDragOverHide (aSaveData->dragOver,
769 aSaveData->windowX, aSaveData->windowY,
770 aSaveData->clipRegion);
771 }
772
773 /* Draw the visuals. */
774 switch(aSaveData->animationStyle) {
775 default:
776 case XmDRAG_UNDER_HIGHLIGHT:
777 DrawHighlight (aSaveData);
778 break;
779
780 case XmDRAG_UNDER_SHADOW_IN:
781 case XmDRAG_UNDER_SHADOW_OUT:
782 DrawShadow (aSaveData);
783 break;
784
785 case XmDRAG_UNDER_PIXMAP:
786 DrawPixmap (aSaveData);
787 break;
788
789 case XmDRAG_UNDER_NONE:
790 break;
791 }
792
793 /*
794 * If dragging a pixmap or window, show it.
795 */
796
797 if (aSaveData->dragOver && aSaveData->activeMode != XmDRAG_WINDOW) {
798 _XmDragOverShow (aSaveData->dragOver,
799 aSaveData->windowX, aSaveData->windowY,
800 aSaveData->clipRegion);
801 }
802 }
803
804 /*****************************************************************************
805 *
806 * AnimateEnter ()
807 *
808 ***************************************************************************/
809
810 /*ARGSUSED*/
811 static void
AnimateEnter(XmDropSiteManagerObject dsm,XmAnimationData aData,XmDragProcCallbackStruct * dpcb)812 AnimateEnter(
813 XmDropSiteManagerObject dsm, /* unused */
814 XmAnimationData aData,
815 XmDragProcCallbackStruct *dpcb )
816 {
817 Widget dc = dpcb->dragContext;
818 XmAnimationSaveData aSaveData;
819 Widget dswidget = GetDSWidget((XmDSInfo) (dsm->dropManager.curInfo));
820 Boolean dummy;
821
822 /*
823 * Create and fill an XmAnimationSaveData structure containing the
824 * data needed to animate the dropsite. Save it for AnimateLeave().
825 */
826
827 aSaveData = CreateAnimationSaveData ((XmDragContext) dc, aData, dpcb);
828 *((XtPointer *) aData->saveAddr) = (XtPointer) aSaveData;
829
830 /* Show the visual */
831 AnimateExpose(dswidget, aSaveData, NULL, &dummy);
832
833 /* Save the dragunder widget */
834 aSaveData->dragUnder = dswidget;
835
836 if (aSaveData->activeMode == XmDRAG_WINDOW) {
837 /* Install the event handler to redo visual on Exposure */
838 Widget hwidget = dswidget;
839 if (XmIsGadget(hwidget))
840 hwidget = XtParent(hwidget);
841 XtInsertEventHandler(hwidget, ExposureMask, False,
842 (XtEventHandler) AnimateExpose,
843 (XtPointer) aSaveData, XtListTail);
844 }
845 }
846
847 /*****************************************************************************
848 *
849 * AnimateLeave ()
850 *
851 ***************************************************************************/
852
853 /*ARGSUSED*/
854 static void
AnimateLeave(XmDropSiteManagerObject dsm,XmAnimationData aData,XmDragProcCallbackStruct * dpcb)855 AnimateLeave(
856 XmDropSiteManagerObject dsm, /* unused */
857 XmAnimationData aData,
858 XmDragProcCallbackStruct *dpcb ) /* unused */
859 {
860 XmAnimationSaveData aSaveData =
861 (XmAnimationSaveData) *((XtPointer *) aData->saveAddr);
862
863 if (aSaveData) {
864 Cardinal i;
865 DragPixmapData *pData;
866
867 /* Move to here to avoid crashes when aSaveData already zeroed */
868 if (aSaveData->activeMode == XmDRAG_WINDOW) {
869 /* Remove the event handler to redo visual on Exposure */
870 Widget hwidget = aSaveData -> dragUnder;
871 if (XmIsGadget(hwidget))
872 hwidget = XtParent(hwidget);
873 XtRemoveEventHandler(hwidget, ExposureMask, False,
874 (XtEventHandler) AnimateExpose,
875 (XtPointer) aSaveData);
876 }
877
878 /*
879 * If dragging a pixmap or window, hide it while erasing the
880 * animation.
881 */
882
883 if (aSaveData->dragOver) {
884 _XmDragOverHide (aSaveData->dragOver,
885 aSaveData->windowX, aSaveData->windowY,
886 aSaveData->clipRegion);
887 }
888
889 /*
890 * Copy any saved segments back into the window.
891 * Be sure GCRegion is set properly here.
892 */
893
894 _XmRegionSetGCRegion (aSaveData->display, aSaveData->drawGC,
895 0, 0, aSaveData->clipRegion);
896 for (pData = aSaveData->savedPixmaps, i = aSaveData->numSavedPixmaps;
897 i; pData++, i--) {
898 XCopyArea (aSaveData->display,
899 pData->pixmap,
900 aSaveData->window,
901 aSaveData->drawGC,
902 0, 0,
903 pData->width,
904 pData->height,
905 pData->x,
906 pData->y);
907 }
908
909 /*
910 * If dragging a pixmap or window, show it.
911 * Free the XmAnimationSaveData structure created in AnimateEnter().
912 */
913
914 if (aSaveData->dragOver) {
915 _XmDragOverShow (aSaveData->dragOver,
916 aSaveData->windowX, aSaveData->windowY,
917 aSaveData->clipRegion);
918 }
919
920 FreeAnimationData (aSaveData);
921 *((XtPointer *) aData->saveAddr) = (XtPointer) NULL;
922 }
923 }
924
925 /*****************************************************************************
926 *
927 * _XmDragUnderAnimation ()
928 *
929 ***************************************************************************/
930
931 void
_XmDragUnderAnimation(Widget w,XtPointer clientData,XtPointer callData)932 _XmDragUnderAnimation(
933 Widget w,
934 XtPointer clientData,
935 XtPointer callData )
936 {
937 XmDropSiteManagerObject dsm = (XmDropSiteManagerObject) w;
938 XmDragProcCallbackStruct *dpcb = (XmDragProcCallbackStruct *) callData;
939 XmAnimationData aData = (XmAnimationData) clientData;
940
941 switch(dpcb->reason)
942 {
943 case XmCR_DROP_SITE_LEAVE_MESSAGE:
944 AnimateLeave(dsm, aData, dpcb);
945 break;
946
947 case XmCR_DROP_SITE_ENTER_MESSAGE:
948 AnimateEnter(dsm, aData, dpcb);
949 break;
950
951 default:
952 break;
953 }
954 }
955
956