Widget CreateDragSourceIcon( Widget widget, Pixmap pixmap, Pixmap mask) { Widget dragIcon; Window rootWindow; int pixmapX, pixmapY; unsigned int pixmapWidth, pixmapHeight, pixmapBorder, pixmapDepth; Arg args[20]; Cardinal nn = 0; XGetGeometry (XtDisplayOfObject(widget), pixmap, &rootWindow, &pixmapX, &pixmapY, &pixmapWidth, &pixmapHeight, &pixmapBorder, &pixmapDepth); XtSetArg(args[nn], XmNwidth, pixmapWidth); nn++; XtSetArg(args[nn], XmNheight, pixmapHeight); nn++; XtSetArg(args[nn], XmNmaxWidth, pixmapWidth); nn++; XtSetArg(args[nn], XmNmaxHeight, pixmapHeight); nn++; XtSetArg(args[nn], XmNpixmap, pixmap); nn++; XtSetArg(args[nn], XmNmask, mask); nn++; XtSetArg(args[nn], XmNdepth, pixmapDepth); nn++; dragIcon = XmCreateDragIcon(widget, "sourceIcon", args, nn); return(dragIcon); }
int main(int argc, char *argv[]) { #define MAIN_CHILDREN 3 #define FORM_CHILDREN 3 #define PLANE_CHILDREN 6 #define TRAFFIC_CHILDREN 3 #define SetMenuEntry(k,l,p,d) labels[k]=l;procs[k]=p;private[k]=d; Pixmap flying; Pixmap parked; Pixmap mask; Widget theWidgetRoot; Widget main_tab[MAIN_CHILDREN]; Widget from_tab[PLANE_CHILDREN]; Widget to_tab[TRAFFIC_CHILDREN]; Widget form_tab[FORM_CHILDREN]; Widget framed[2]; Widget entry; static char myClass[] = "XmdAirport"; Arg args[10]; int n ; String labels[4]; XtCallbackProc procs[4]; XtPointer private[4]; XGCValues gcv; Airport this; /* * Initialize */ this = (Airport) XtCalloc(sizeof(AirportRec), 1); XtSetLanguageProc(NULL, (XtLanguageProc) NULL, NULL); theWidgetRoot = XtVaOpenApplication( &this->context, myClass, NULL, 0, &argc, argv, NULL, sessionShellWidgetClass, XmNallowShellResize, True, NULL); this->display = XtDisplay(theWidgetRoot); FlightAtom = XmInternAtom(this->display, "FLIGHT", False); DeleteAtom = XmInternAtom(this->display, "DELETE", False); XtGetApplicationResources(theWidgetRoot, &AirportResources, AirportResourcesSpecs, XtNumber(AirportResourcesSpecs), (ArgList) NULL, 0); /* * Create the Main Window, the menubar and the pulldown menus */ n = 0; this->main = XmCreateMainWindow(theWidgetRoot, "main", args, n); n = 0; main_tab[0] = XmCreateMenuBar(this->main, "menubar", args, n); n = 0; SetMenuEntry(n, "Exit", (XtCallbackProc) ExitCallback, (XtPointer) this ); n++; entry = MenuBarEntry(main_tab[0], "File", labels, procs, private, n); n = 0; SetMenuEntry(0, "Tutorial", (XtCallbackProc) HelpCallback, (XtPointer) this); n++; entry = MenuBarEntry(main_tab[0], "Help", labels, procs, private, n); n = 0; XtSetArg(args[n], XmNmenuHelpWidget, entry); n++; XtSetValues(main_tab[0], args, n); /* * Create the Airport widget structure. * Two framed radio boxes show state. * A drawing area in the middle show track and planes */ n = 0; this->screen_width = WidthOfScreen(XtScreenOfObject(this->main)); this->screen_height = HeightOfScreen(XtScreenOfObject(this->main)); XtSetArg(args[n], XmNwidth, this->screen_width*3/7); n++; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_NONE); n++; main_tab[1] = XmCreateForm(this->main, "airport", args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment,XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM) ; n++; form_tab[0] = XmCreateFrame(main_tab[1], "flight", args, n); n = 0; XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++; framed[0] = XmCreateLabel(form_tab[0], "title", args, n); n = 0; XtSetArg(args[n], XmNchildType, XmFRAME_WORKAREA_CHILD); n++; XtSetArg(args[n], XmNresizePolicy, XmRESIZE_GROW); n++; XtSetArg(args[n], XmNradioBehavior, True); n++; framed[1] = XmCreateRadioBox(form_tab[0], "panel", args, n); n = 0; XtSetArg(args[n], XmNset, True); n++; XtSetArg(args[n], XmNvisibleWhenOff, False); n++; this->from.departure = from_tab[0] = XmCreateToggleButton(framed[1], "departure", args, n); n = 0; XtSetArg(args[n], XmNvisibleWhenOff, False); n++; this->from.over_ocean = from_tab[1] = XmCreateToggleButton(framed[1], "over_ocean", args, n); n = 0; XtSetArg(args[n], XmNvisibleWhenOff, False); n++; this->from.over_land = from_tab[2] = XmCreateToggleButton(framed[1], "over_land", args, n); n = 0; XtSetArg(args[n], XmNvisibleWhenOff, False); n++; this->from.over_site = from_tab[3] = XmCreateToggleButton(framed[1], "radar", args, n); n = 0; XtSetArg(args[n], XmNvisibleWhenOff, False); n++; this->from.landing = from_tab[4] = XmCreateToggleButton(framed[1], "landing", args, n); n = 0; XtSetArg(args[n], XmNvisibleWhenOff, False); n++; this->from.landed = from_tab[5] = XmCreateToggleButton(framed[1], "landed", args, n); XtManageChildren(from_tab, PLANE_CHILDREN); XtManageChildren(framed, 2); /* * Create the Airport Traffic control state */ n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment,XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM) ; n++; form_tab[1] = XmCreateFrame(main_tab[1], "traffic", args, n); n = 0; XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++; framed[0] = XmCreateLabel(form_tab[1], "title", args, n); n = 0; XtSetArg(args[n], XmNchildType, XmFRAME_WORKAREA_CHILD); n++; XtSetArg(args[n], XmNradioBehavior, True); n++; framed[1] = XmCreateRadioBox(form_tab[1], "traffic_box", args, n); n = 0; XtSetArg(args[n], XmNset, True); n++; XtSetArg(args[n], XmNvisibleWhenOff, False); n++; this->to.leave = to_tab[1] = XmCreateToggleButton(framed[1], "no_traffic", args, n); n = 0; XtSetArg(args[n], XmNvisibleWhenOff, False); n++; this->to.enter = to_tab[0] = XmCreateToggleButton(framed[1], "radar_echo", args, n); n = 0; XtSetArg(args[n], XmNvisibleWhenOff, False); n++; this->to.landing = to_tab[2] = XmCreateToggleButton(framed[1], "landing", args, n); XtManageChildren(to_tab, TRAFFIC_CHILDREN); XtManageChildren(framed, 2); /* * Create the Airport picture */ n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment,XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET) ; n++; XtSetArg(args[n], XmNleftWidget, form_tab[0]) ; n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET) ; n++; XtSetArg(args[n], XmNrightWidget, form_tab[1]) ; n++; this->airport = form_tab[2] = XmCreateDrawingArea(main_tab[1], "da", args, n); XtAddCallback(this->airport, XmNexposeCallback, (XtCallbackProc) ShowAirport, (XtPointer) this); XtAddCallback(this->airport, XmNresizeCallback, (XtCallbackProc) ResizeAirport, (XtPointer) this); XtAddCallback(this->airport, XmNinputCallback, (XtCallbackProc) AirportInput, (XtPointer) this); /* * Create the Airport Message area */ n = 0; main_tab[2] = XmCreateFrame(this->main, "message", args, n); n = 0; XtSetArg(args[n], XmNchildType, XmFRAME_TITLE_CHILD); n++; framed[0] = XmCreateLabel(main_tab[2], "title", args, n); n = 0; XtSetArg(args[n], XmNchildType, XmFRAME_WORKAREA_CHILD); n++; XtSetArg(args[n], XmNvisibleItemCount, 4); n++; this->msg_area = XmCreateScrolledList(main_tab[2], "msg_list", args, n); XtManageChild(this->msg_area); framed[1] = XtParent(this->msg_area); XtManageChildren(framed, 2); n = 0; XtSetArg(args[n], XmNmenuBar, main_tab[0]); n++; XtSetArg(args[n], XmNworkWindow, main_tab[1]); n++; XtSetArg(args[n], XmNmessageWindow, main_tab[2]); n++; XtSetValues(this->main, args, n); XtManageChildren(form_tab, FORM_CHILDREN); XtManageChildren(main_tab, MAIN_CHILDREN); XtManageChild(this->main); XtRealizeWidget(theWidgetRoot); /* * Create the drag icon */ parked = XCreateBitmapFromData(this->display, XtWindow(this->main), (char*)plane_bits, plane_width, plane_height); flying = XCreateBitmapFromData(this->display, XtWindow(this->main), (char*)flying_bits, flying_icon_width, flying_icon_height); mask = XCreateBitmapFromData(this->display, XtWindow(this->main), (char*)flying_mask_bits, flying_mask_width, flying_mask_height); n = 0; XtSetArg(args[n], XmNpixmap, flying); n++; XtSetArg(args[n], XmNdepth, 1); n++; XtSetArg(args[n], XmNmask, mask); n++; XtSetArg(args[n], XmNwidth, flying_icon_width); n++; XtSetArg(args[n], XmNheight, flying_icon_height) ; n++; this->dragIcon = XmCreateDragIcon(form_tab[2], "drag", args, n); if (this->dragIcon == NULL) { printf("cannot create drag icon\n"); exit(0); } /* Create GC for drawing planes */ gcv.function = GXcopy; gcv.fill_style = FillOpaqueStippled; gcv.stipple = parked; gcv.foreground = AirportResources.spot_foreground; gcv.background = AirportResources.spot_background; this->park.gc = XCreateGC(this->display, XtWindow(this->main), GCFunction|GCStipple|GCFillStyle |GCForeground|GCBackground, &gcv); gcv.line_style = LineDoubleDash; gcv.line_width = AirportResources.track_border_width; gcv.fill_style = FillSolid; gcv.foreground = AirportResources.track_foreground; gcv.background = AirportResources.track_background; this->track.gc = XCreateGC(this->display, XtWindow(this->main), GCFunction|GCLineWidth|GCLineStyle |GCFillStyle|GCForeground|GCBackground, &gcv); XtAppMainLoop(this->context); return 0; /* make compiler happy */ }
Widget XmCreateDragIcon_TNK(Widget parent, String name, ArgList arglist,Cardinal argcount) { return XmCreateDragIcon(parent, name, arglist, argcount);}
void StartDrag(Widget searchWidget, XEvent *event) { Arg args[8]; Cardinal n; Atom exportList[1]; Widget sourceIcon; UpdateTask * pt; int textWidth, maxWidth, maxHeight, fontHeight, ascent; unsigned long fg, bg; XButtonEvent * xbutton; XGCValues gcValues; unsigned long gcValueMask; DisplayInfo * displayInfo; static char *channelNames[MAX(MAX_PENS,MAX_TRACES)][2]; Pixmap sourcePixmap = (Pixmap)NULL; static GC gc = NULL; /* a nice sized font */ #define FONT_TABLE_INDEX 6 /* move the text over... */ #define X_SHIFT 8 #define MARGIN 2 /* (MDA) since widget doing drag could be toggleButton or optionMenu button * (which has more than just flat, single parent), * find the widget that has a parent that is the drawing area and * search based on that * (since that is what is rooted in the display) * - NB if drawing areas as children of the main drawing area are allowed * as parents of controllers/monitors, this logic must change... */ if (XtClass(searchWidget) == xmDrawingAreaWidgetClass && strcmp(XtName(searchWidget),stripChartWidgetName) !=0 ) { /* starting search from a DrawingArea which is not a StripChart * (i.e., DL_Display) therefore lookup "graphic" (non-widget) elements ; * get UpdateTask data from position knowledge */ displayInfo = dmGetDisplayInfoFromWidget(searchWidget); xbutton = (XButtonEvent *)event; pt = getUpdateTaskFromPosition(displayInfo, xbutton->x,xbutton->y); } else { WidgetUserData * userData; /* get UpdateTask data from widget's userData resource */ while (XtClass(XtParent(searchWidget)) != xmDrawingAreaWidgetClass) searchWidget = XtParent(searchWidget); XtVaGetValues (searchWidget, XmNuserData, &userData, NULL); if (userData) pt = userData->updateTask; else { pt = getUpdateTaskFromWidget(searchWidget); INFORM_INTERNAL_ERROR(); } } #define MAX_COL 4 if (pt) { char * name[MAX_PENS*MAX_COL]; short severity[MAX_PENS*MAX_COL]; int count = 1; int column; int row; if (pt->name == NULL) return; else (*pt->name)(pt->clientData, name, severity, &count); /* T. Straumann: copy the names to the clipboard * * NOTE: we must copy the name strings, because we * cannot be 100% sure the updateTask still * exists at the time the PRIMARY selection * is requested. */ if ( count > 0 ) { int i; clipbdStart(); clipbdAdd(name[0]); /* count > 100 means count/100 columns (see dm2kCartesianPlot.c !?!) */ for ( i=1; i < (count%100); i++) { clipbdAdd("\n"); clipbdAdd(name[i]); } clipbdHold(); } column = count / 100; if (column == 0) column = 1; if (column > MAX_COL) column = MAX_COL; count = count % 100; row = 0; bg = BlackPixel(display,screenNum); fg = WhitePixel(display,screenNum); ascent = fontTable[FONT_TABLE_INDEX]->ascent; fontHeight = ascent + fontTable[FONT_TABLE_INDEX]->descent; if (count == 0) { channelName = NULL; return; } else { int i, j; int x, y; i = 0; j = 0; textWidth = 0; while (i < count) { if (name[i]) { register int tmp = XTextWidth(fontTable[FONT_TABLE_INDEX],name[i],STRLEN(name[i])); textWidth = MAX(textWidth,tmp); } j++; if (j >= column) { j = 0; row++; } i++; } maxWidth = X_SHIFT + (textWidth + MARGIN) * column; maxHeight = row*fontHeight + 2*MARGIN; sourcePixmap = XCreatePixmap(display, RootWindow(display, screenNum), maxWidth,maxHeight, DefaultDepth(display,screenNum)); if (gc == NULL) gc = XCreateGC(display,sourcePixmap,0,NULL); gcValueMask = GCForeground|GCBackground|GCFunction|GCFont; gcValues.foreground = bg; gcValues.background = bg; gcValues.function = GXcopy; gcValues.font = fontTable[FONT_TABLE_INDEX]->fid; XChangeGC(display,gc,gcValueMask,&gcValues); XFillRectangle(display,sourcePixmap,gc,0,0,maxWidth,maxHeight); i = j = 0; x = X_SHIFT; y = ascent + MARGIN; while (i < count) { if (name[i]) { XSetForeground(display,gc,alarmColorPixel[severity[i]]); XDrawString(display,sourcePixmap,gc,x,y,name[i],STRLEN(name[i])); channelName = name[i]; } j++; if (j < column) { x += textWidth + MARGIN; } else { j = 0; x = X_SHIFT; y += fontHeight; } i++; } } } if (sourcePixmap != (Pixmap)NULL) { /* use source widget as parent - can inherit visual attributes that way */ n = 0; XtSetArg(args[n],XmNpixmap,sourcePixmap); n++; XtSetArg(args[n],XmNwidth,maxWidth); n++; XtSetArg(args[n],XmNheight,maxHeight); n++; XtSetArg(args[n],XmNdepth,DefaultDepth(display,screenNum)); n++; sourceIcon = XmCreateDragIcon(XtParent(searchWidget),"sourceIcon",args,n); /* establish list of valid target types */ exportList[0] = COMPOUND_TEXT; n = 0; XtSetArg(args[n],XmNexportTargets, exportList); n++; XtSetArg(args[n],XmNnumExportTargets, 1); n++; XtSetArg(args[n],XmNdragOperations, XmDROP_COPY); n++; XtSetArg(args[n],XmNconvertProc, DragConvertProc); n++; XtSetArg(args[n],XmNsourcePixmapIcon, sourceIcon); n++; XtSetArg(args[n],XmNcursorForeground, fg); n++; XtSetArg(args[n],XmNcursorBackground, bg); n++; XtSetArg(args[n],XmNdragDropFinishCallback, dragDropFinishCB); n++; XmDragStart(searchWidget,event,args,n); } }