/* * @OPENGROUP_COPYRIGHT@ * COPYRIGHT NOTICE * Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc. * Copyright (c) 1996, 1997, 1998, 1999, 2000 The Open Group * ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for * the full copyright text. * * This software is subject to an open license. It may only be * used on, with or for operating systems which are themselves open * source systems. You must contact The Open Group for a license * allowing distribution and sublicensing of this software on, with, * or for operating systems which are not Open Source programs. * * See http://www.opengroup.org/openmotif/license for full * details of the license agreement. Any use, reproduction, or * distribution of the program constitutes recipient's acceptance of * this agreement. * * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS * PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY * WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY * OR FITNESS FOR A PARTICULAR PURPOSE * * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT * NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE * EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. */ /* * HISTORY */ #ifdef REV_INFO #ifndef lint static char rcsid[] = "$XConsortium: DNDDrop3.c /main/8 1995/07/14 11:52:47 drk $" #endif #endif /* * (c) Copyright 1987, 1988, 1989 HEWLETT-PACKARD COMPANY */ /* * file: DNDDrop3.c * * This tests non-rectangular dropSites, i.e., dropSites that have to be * represented by more that one rectangle. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include static void StartMyDragProc(); static void RaiseProc(); static void LowerProc(); XRectangle rects0[] = { { 40, 0, 40, 40 }, { 0, 40, 120, 40 }, { 40, 80, 40, 40 }, }; XRectangle rects1[] = { { 0, 0, 40, 40 }, { 80, 0, 40, 40 }, { 0, 40, 120, 40 }, }; XRectangle rects2[] = { { 20, 0, 40, 40 }, { 0, 40, 80, 20 }, }; XRectangle rects3[] = { { 0, 0, 40, 60 }, { 40, 20, 40, 20 }, }; typedef struct _DropZoneRec { char *name; XRectangle *rects; int num_rects; Region region; Widget refW; Widget icon; } DropZoneRec, *DropZone; static DropZoneRec DropZones[] = { { "cross", rects0, XtNumber(rects0), NULL, NULL, NULL}, { "trough", rects1, XtNumber(rects1), NULL, NULL, NULL}, { "MwmIcon", rects2, XtNumber(rects2), NULL, NULL, NULL}, { "mallet", rects3, XtNumber(rects3), NULL, NULL, NULL}, }; static int numZones = XtNumber(DropZones); static String myDNDTranslations = " : StartMyDrag() \n\ m : Raise(1) \n\ : Raise(0) \n\ m : Lower(1) \n\ : Lower(0)"; static XtActionsRec myDNDActions[] = { { "StartMyDrag", StartMyDragProc }, { "Raise", RaiseProc }, { "Lower", LowerProc }, }; Widget shell1; Widget form1; Widget p0, p1, p2, p3; Widget text1; int n = 0; Arg args[30]; XtAppContext this_app; Display *display; int i; Pixel GetPixel(dpy, name) Display *dpy; char *name; { XColor color, exact_color; int scr = DefaultScreen(dpy); Colormap cmap = DefaultColormap(dpy, scr); XAllocNamedColor(dpy, cmap, name, &color, &exact_color); return(color.pixel); } void ExposeEventHandler(w, client_data, event, continue_to_dispatch) Widget w; XtPointer client_data; XEvent *event; Boolean *continue_to_dispatch; { static Boolean first_time = True; XGCValues values; unsigned long valueMask; static GC dzGC; Pixel zoneColor; int i, j; Region clipRegion = NULL; Region sibRegion = NULL; *continue_to_dispatch = True; if (first_time) { valueMask = GCGraphicsExposures; values.graphics_exposures = False; dzGC = XCreateGC(XtDisplay(w), XtWindow(w), valueMask, &values); clipRegion = XCreateRegion(); sibRegion = XCreateRegion(); } for (i=0; i < XtNumber(DropZones); i++) { valueMask = (GCForeground | GCBackground); values.background = DropZones[i].refW->core.background_pixel; values.foreground = DropZones[i].refW->core.background_pixel; XChangeGC(XtDisplay(w), dzGC, valueMask, &values); XUnionRegion(DropZones[i].region, DropZones[i].region, clipRegion); XOffsetRegion(clipRegion, XtX(w), XtY(w)); for (j=0; j < i ; j++) { XUnionRegion(DropZones[j].region, DropZones[j].region, sibRegion); XOffsetRegion(sibRegion, XtX(DropZones[j].refW), XtY(DropZones[j].refW)); XSubtractRegion(clipRegion, sibRegion, clipRegion); } XSetRegion(XtDisplay(w), dzGC, clipRegion); XFillRectangle(XtDisplay(w), XtWindow(w), dzGC, XtX(w), XtY(w), XtWidth(w), XtHeight(w)); } } static void RaiseProc(w, event, params, num_params) Widget w; XEvent *event; String *params; Cardinal *num_params; { int operation; if (*num_params) { /* We only expect one */ operation = atoi(params[0]); } switch(operation) { case 1: { /* Raise to top of stack */ } break; case 0: default: { /* Circulate the stack upwards */ } break; } } static void LowerProc(w, event, params, num_params) Widget w; XEvent *event; String *params; Cardinal *num_params; { } static void StartMyDragProc(w, event, params, num_params) Widget w; XEvent *event; String *params; Cardinal *num_params; { Arg args[30]; int n, i; XButtonEvent *myEvent = (XButtonEvent *) event; Widget dc; /* detect which, if any drop zone the drag started in */ for (i=0; i < numZones; i++) if (XPointInRegion(DropZones[i].region, myEvent->x, myEvent->y)) break; /* if in a drop zone, load the appropriate cursor */ if (i == numZones) return; n = 0; XtSetArg(args[n], XmNsourceCursorIcon, DropZones[i].icon); n++; dc = XmDragStart(w, event, args, n); } static void MyDropProc(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; { XmDropProcCallbackStruct *cb = (XmDropProcCallbackStruct *) call_data; Position newX = cb->x - XtX(w); Position newY = cb->y - XtY(w); Arg args[5]; int n; Boolean junk; n = 0; XtSetArg(args[n], XmNx, newX); n++; XtSetArg(args[n], XmNy, newY); n++; XtSetValues(w, args, n); ExposeEventHandler(w, NULL, NULL, &junk); } void CreateDropZone(w, targets, num_targets, dz) Widget w; Atom *targets; Cardinal num_targets; DropZone dz; { Display *display = XtDisplay(w); XRectangle clipBox; unsigned long vMask; XGCValues values; Pixmap iconMap, maskMap; GC clipGC; static Boolean first_time = True; static Region r1, r2; unsigned long valueMask; char buf[128]; if (first_time) { r1 = XCreateRegion(); r2 = XCreateRegion(); first_time = False; } dz->refW = w; /* Create and set the region from the rectangle data */ dz->region = XCreateRegion(); for (i=0; i < dz->num_rects; i++) XUnionRectWithRegion(&(dz->rects[i]), dz->region, dz->region); /* Get the bounding box of the region */ XClipBox(dz->region, &clipBox); n = 0; XtSetArg(args[n], XmNwidth, clipBox.width); n++; XtSetArg(args[n], XmNheight, clipBox.height); n++; XtSetValues(w, args, n); /* Create depth 1 pixmaps the size of bounding box */ iconMap = XCreatePixmap(display, DefaultRootWindow(display), clipBox.width, clipBox.height, 1); maskMap = XCreatePixmap(display, DefaultRootWindow(display), clipBox.width, clipBox.height, 1); /* Fill the bitmaps with 0's */ vMask = (GCForeground | GCBackground); values.background = 0; values.foreground = 0; clipGC = XCreateGC(display, iconMap, vMask, &values); XFillRectangle(display, iconMap, clipGC, 0, 0, clipBox.width, clipBox.height); XFillRectangle(display, maskMap, clipGC, 0, 0, clipBox.width, clipBox.height); /* Now we write with 1's */ valueMask = (GCForeground | GCBackground); values.background = 1; values.foreground = 1; XChangeGC(display, clipGC, valueMask, &values); /* Fill the shape of the icon with 1's */ XUnionRegion(dz->region, dz->region, r1); XOffsetRegion(r1, (-1 * clipBox.x), (-1 * clipBox.y)); XSetRegion(display, clipGC, r1); XFillRectangle(display, iconMap, clipGC, 0, 0, clipBox.width, clipBox.height); /* Create a clip region to shoot the 1's thru into the mask */ XUnionRegion(r1, r1, r2); XShrinkRegion(r2, 2, 2); XSubtractRegion(r1, r2, r1); XSetRegion(display, clipGC, r1); XFillRectangle(display, maskMap, clipGC, 0, 0, clipBox.width, clipBox.height); n = 0; XtSetArg(args[n], XmNpixmap, iconMap); n++; XtSetArg(args[n], XmNmask, maskMap); n++; XtSetArg(args[n], XmNdepth, 1); n++; XtSetArg(args[n], XmNwidth, clipBox.width); n++; XtSetArg(args[n], XmNheight, clipBox.height); n++; XtSetArg(args[n], XmNhotX, (clipBox.width / 2)); n++; XtSetArg(args[n], XmNhotY, (clipBox.height / 2)); n++; dz->icon = XmCreateDragIcon(w, dz->name, args, n); n = 0; XtSetArg(args[n], XmNimportTargets, targets); n++; XtSetArg(args[n], XmNnumImportTargets, num_targets); n++; XtSetArg(args[n], XmNdropRectangles, dz->rects); n++; XtSetArg(args[n], XmNnumDropRectangles, dz->num_rects); n++; XtSetArg(args[n], XmNdropProc, MyDropProc); n++; XmDropSiteRegister(w, args, n); } main(argc, argv) int argc; char **argv; { int i; Atom targets[1]; unsigned short *ID; XtTranslations myParsedTranslations; XtToolkitInitialize(); this_app = XtCreateApplicationContext(); display = XtOpenDisplay(this_app, NULL, NULL, "DNDNonRect", NULL, 0, &argc, argv); if (display == NULL) { fprintf(stderr, "%s: Can't open display\n", argv[0]); exit(1); } targets[0] = XmInternAtom(display, "COMPOUND_TEXT", False); XtAppAddActions(this_app, myDNDActions, XtNumber(myDNDActions)); myParsedTranslations = XtParseTranslationTable(myDNDTranslations); n = 0; XtSetArg(args[n], XmNallowShellResize, True); n++; XtSetArg(args[n], XmNwidth, 400); n++; XtSetArg(args[n], XmNheight, 300); n++; shell1 = XtAppCreateShell(NULL, "XMclient", applicationShellWidgetClass, display, args, n); n = 0; form1 = XmCreateForm(shell1, "form1", args, n); XtManageChild(form1); XtOverrideTranslations(form1, myParsedTranslations); XtAddEventHandler(form1, ExposureMask, True, ExposeEventHandler, NULL); n = 0; XtSetArg(args[n], XmNx, 10); n++; XtSetArg(args[n], XmNy, 10); n++; XtSetArg(args[n], XmNbackground, GetPixel(display, "DarkGreen")); n++; p0 = XtCreateWidget("p0", xmPrimitiveWidgetClass, form1, args, n); CreateDropZone(p0, targets, XtNumber(targets), &DropZones[0]); n = 0; XtSetArg(args[n], XmNx, 50); n++; XtSetArg(args[n], XmNy, 50); n++; XtSetArg(args[n], XmNbackground, GetPixel(display, "Blue")); n++; p1 = XtCreateWidget("p1", xmPrimitiveWidgetClass, form1, args, n); CreateDropZone(p1, targets, XtNumber(targets), &DropZones[1]); n = 0; XtSetArg(args[n], XmNbackground, GetPixel(display, "Cyan")); n++; p2 = XtCreateWidget("p2", xmPrimitiveWidgetClass, form1, args, n); CreateDropZone(p2, targets, XtNumber(targets), &DropZones[2]); n = 0; XtSetArg(args[n], XmNx, 150); n++; XtSetArg(args[n], XmNy, 150); n++; XtSetArg(args[n], XmNbackground, GetPixel(display, "Orange")); n++; p3 = XtCreateWidget("p3", xmPrimitiveWidgetClass, form1, args, n); CreateDropZone(p3, targets, XtNumber(targets), &DropZones[3]); n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; text1 = XmCreateTextField( form1, "text1", args, n); XtManageChild(text1); XtRealizeWidget(shell1); /* MainLoop */ XtAppMainLoop(this_app); }