📄 xmotif.cnu
字号:
/**********Copyright 1990 Regents of the University of California. All rights reserved.Author: 1988 Jeffrey M. Hsu, 1991 David A. Gates**********//* X11/MOTIF drivers for OSF/MOTIF 1.x (DEC only). Trial implementation, not compiled into final executable.*/#include "spice.h"#ifdef HAS_X11#include <sys/time.h>#include "ftegraph.h"#include "ftedbgra.h"#include "ftedev.h"#include "fteinput.h"#include "cpdefs.h"#include "ftedefs.h"#include <X11/Xlib.h>#include <X11/Xutil.h>#include <X11/Intrinsic.h>#include <X11/IntrinsicP.h>#include <X11/Shell.h>#include <X11/StringDefs.h>#include <X11/cursorfont.h>#include <Xm/Xm.h>#include <Xm/Form.h>#include <Xm/Frame.h>#include <Xm/DrawingA.h>#include <Xm/RowColumn.h>#include <Xm/PushB.h>#ifdef DEBUGextern int _Xdebug;#endif/* forward declarations */extern void handlebuttonev(), handlekeypressed(), killwin(), hardcopy(), redraw(), resize();int errorhandler();/* X dependent default parameters */#define DEF_FONT "6x10"#define NUMLINESTYLES 8#define NXPLANES 5 /* note: What is this used for? */#define BOXSIZE 30 /* initial size of bounding box for zoomin */typedef struct { Window window; int isopen; Widget shell, form, frame[2], view, buttonbox, buttons[2]; XFontStruct *font; GC gc; int lastx, lasty; /* used in X_DrawLine */ int lastlinestyle; /* used in X_DrawLine */} X11devdep;#define DEVDEP(g) (*((X11devdep *) (g)->devdep))static Display *display;static GC xorgc;static char *xlinestyles[NUMLINESTYLES] = { /* test patterns XXX */ "\001\001\001\001", /* solid */ "\001\003\001\003", /* spaced dots */ "\001\002\001\002", /* dots */ "\003\003\003\003", /* shortdash */ "\001\004\006\004", /* dots longdash */ "\007\007\007\007", /* longdash */ "\001\004\004\004", /* dots shortdash */ "\003\003\007\003", /* short/longdash */};static Widget toplevel;static Bool noclear = False;static GRAPH *lasthardcopy; /* graph user selected */X11_Init(){ char buf[512]; char *displayname; XGCValues gcvalues; /* grrr, Xtk forced contortions */ char *argv[2]; int argc = 2; if (cp_getvar("display", VT_STRING, buf)) { displayname = buf; } else if (!(displayname = getenv("DISPLAY"))) { internalerror("Can't open X display."); return (1); }#ifdef DEBUG _Xdebug = 1;#endif argv[0] = "nutmeg"; argv[1] = displayname;/* argv[2] = "-geometry"; argv[3] = "=1x1+2+2";*/ /* initialize X toolkit */ toplevel = XtInitialize("nutmeg", "Nutmeg", NULL, 0, &argc, argv); display = XtDisplay(toplevel); /* "invert" works better than "xor" for B&W */ /* xor gc should be a function of the pixels that are written on */ gcvalues.function = GXxor; gcvalues.line_width = 1; gcvalues.foreground = 1; gcvalues.background = 0; xorgc = XCreateGC(display, DefaultRootWindow(display), GCLineWidth | GCFunction | GCForeground | GCBackground, &gcvalues); /* set correct information */ dispdev->numlinestyles = NUMLINESTYLES; dispdev->numcolors = NUMCOLORS; dispdev->width = DisplayWidth(display, DefaultScreen(display)); dispdev->height = DisplayHeight(display, DefaultScreen(display)); /* we don't want non-fatal X errors to call exit */ XSetErrorHandler(errorhandler); return (0);}interrorhandler(display, errorev)Display *display;XErrorEvent *errorev;{ XGetErrorText(display, errorev->error_code, ErrorMessage, 1024); externalerror(ErrorMessage); return;}/* Recover from bad NewViewPort call. */#define RECOVERNEWVIEWPORT() free((char *) graph);\ graph = (GRAPH *) NULL; /* need to do this or else DestroyGraph will free it again *//* NewViewport is responsible for filling in graph->viewport */X11_NewViewport(graph)GRAPH *graph;{ char geometry[32], defaultgeometry[32]; char fontname[64]; Cursor cursor; XSetWindowAttributes w_attrs; XGCValues gcvalues; int numdispplanes = DisplayPlanes(display, DefaultScreen(display)); int trys; static Arg shellargs[] = { { XmNkeyboardFocusPolicy, (XtArgVal) XmPOINTER } }; static Arg frame0args[] = { { XmNmarginWidth, (XtArgVal) 2 }, { XmNmarginHeight, (XtArgVal) 2 }, { XmNshadowThickness, (XtArgVal) 2 }, { XmNshadowType, (XtArgVal) XmSHADOW_OUT } }; static Arg bboxargs[] = { { XmNnumColumns, (XtArgVal) 1 }, { XmNrightAttachment, (XtArgVal) XmATTACH_FORM } }; static Arg buttonargs[] = { { XmNresizable, (XtArgVal) TRUE }, { XmNhighlightOnEnter, (XtArgVal) TRUE } }; static Arg frame1args[] = { { XmNrightWidget, (XtArgVal) NULL }, { XmNresizable, (XtArgVal) TRUE }, { XmNshadowThickness, (XtArgVal) 2 }, { XmNshadowType, (XtArgVal) XmSHADOW_IN }, { XmNtopAttachment, (XtArgVal) XmATTACH_FORM }, { XmNbottomAttachment, (XtArgVal) XmATTACH_FORM }, { XmNleftAttachment, (XtArgVal) XmATTACH_FORM }, { XmNrightAttachment, (XtArgVal) XmATTACH_WIDGET }, }; static Arg viewargs[] = { { XmNresizable, (XtArgVal) TRUE }, { XmNwidth, (XtArgVal) 300 }, { XmNheight, (XtArgVal) 300 } }; graph->devdep = calloc(1, sizeof(X11devdep)); /* set up new shell */ DEVDEP(graph).shell = XtCreateApplicationShell("shell", topLevelShellWidgetClass, shellargs, XtNumber(shellargs)); /* set up outer frame widget */ DEVDEP(graph).frame[0] = XtCreateManagedWidget("frame", xmFrameWidgetClass, DEVDEP(graph).shell, frame0args, XtNumber(frame0args)); /* set up form widget inside frame */ DEVDEP(graph).form = XtCreateManagedWidget("form", xmFormWidgetClass, DEVDEP(graph).frame[0], NULL, 0 ); /* set up button box inside form */ DEVDEP(graph).buttonbox = XtCreateManagedWidget("buttonbox", xmRowColumnWidgetClass, DEVDEP(graph).form, bboxargs, XtNumber(bboxargs)); /* set up buttons */ DEVDEP(graph).buttons[0] = XtCreateManagedWidget("quit", xmPushButtonWidgetClass, DEVDEP(graph).buttonbox, buttonargs, 1); XtAddCallback(DEVDEP(graph).buttons[0], XmNactivateCallback, killwin, graph); DEVDEP(graph).buttons[1] = XtCreateManagedWidget("hardcopy", xmPushButtonWidgetClass, DEVDEP(graph).buttonbox, buttonargs, 1); XtAddCallback(DEVDEP(graph).buttons[1], XmNactivateCallback, hardcopy, graph); /* set up viewport frame widget */ XtSetArg( frame1args[0], XmNrightWidget, DEVDEP(graph).buttonbox ); DEVDEP(graph).frame[1] = XtCreateManagedWidget("frame", xmFrameWidgetClass, DEVDEP(graph).form, frame1args, XtNumber(frame1args)); /* set up viewport in frame */ DEVDEP(graph).view = XtCreateManagedWidget("viewport", xmDrawingAreaWidgetClass, DEVDEP(graph).frame[1], viewargs, XtNumber(viewargs)); XtAddEventHandler(DEVDEP(graph).view, ButtonPressMask, FALSE, handlebuttonev, graph); XtAddEventHandler(DEVDEP(graph).view, KeyPressMask, FALSE, handlekeypressed, graph); XtAddEventHandler(DEVDEP(graph).view, StructureNotifyMask, FALSE, resize, graph); XtAddEventHandler(DEVDEP(graph).view, ExposureMask, FALSE, redraw, graph); /* set up fonts */ if (!cp_getvar("font", VT_STRING, fontname)) { (void) strcpy(fontname, DEF_FONT); } trys = 1; while (!(DEVDEP(graph).font = XLoadQueryFont(display, fontname))) { sprintf(ErrorMessage, "can't open font %s", fontname); strcpy(fontname, "fixed"); if (trys > 1) { internalerror(ErrorMessage); RECOVERNEWVIEWPORT(); return(1); } trys += 1; } graph->fontwidth = DEVDEP(graph).font->max_bounds.rbearing - DEVDEP(graph).font->min_bounds.lbearing + 1; graph->fontheight = DEVDEP(graph).font->max_bounds.ascent + DEVDEP(graph).font->max_bounds.descent + 1; XtRealizeWidget(DEVDEP(graph).shell); DEVDEP(graph).window = XtWindow(DEVDEP(graph).view); w_attrs.bit_gravity = ForgetGravity; XChangeWindowAttributes(display, DEVDEP(graph).window, CWBitGravity, &w_attrs); gcvalues.line_width = 1; gcvalues.cap_style = CapNotLast; gcvalues.function = GXcopy; DEVDEP(graph).gc = XCreateGC(display, DEVDEP(graph).window, GCLineWidth | GCCapStyle | GCFunction, &gcvalues); /* should absolute.positions really be shell.pos? */ graph->absolute.xpos = DEVDEP(graph).view->core.x; graph->absolute.ypos = DEVDEP(graph).view->core.y; graph->absolute.width = DEVDEP(graph).view->core.width; graph->absolute.height = DEVDEP(graph).view->core.height; initlinestyles(); initcolors(graph); /* set up cursor */ cursor = XCreateFontCursor(display, XC_left_ptr); XDefineCursor(display, DEVDEP(graph).window, cursor); return (0);}staticinitlinestyles(){ int i; if (XDisplayPlanes(display, DefaultScreen(display)) > 1) { /* Dotted lines are a distraction when we have colors. */ for (i = 2; i < NUMLINESTYLES; i++) { xlinestyles[i] = xlinestyles[0]; } } return;}staticinitcolors(graph) GRAPH *graph;{ int numdispplanes = DisplayPlanes(display, DefaultScreen(display)); int i; static char *colornames[] = { "white", /* white */ "black", "red", "blue", "orange", "green", "pink", "brown", "khaki", "plum", "orchid", "violet", "maroon", "turquoise", "sienna", "coral", "cyan", "magenta", "gold", "yellow", "" }; XColor visualcolor, exactcolor; char buf[BSIZE_SP], colorstring[BSIZE_SP]; int xmaxcolors = NUMCOLORS; /* note: can we get rid of this? */ if (numdispplanes == 1) { /* black and white */ xmaxcolors = 2; graph->colors[0] = DEVDEP(graph).view->core.background_pixel; if (graph->colors[0] == WhitePixel(display, DefaultScreen(display))) graph->colors[1] = BlackPixel(display, DefaultScreen(display)); else graph->colors[1] = WhitePixel(display, DefaultScreen(display)); } else { if (numdispplanes < NXPLANES) { xmaxcolors = 1; while (numdispplanes-- > 1) xmaxcolors *= 2; } for (i = 0; i < xmaxcolors; i++) { (void) sprintf(buf, "color%d", i); if (!cp_getvar(buf, VT_STRING, colorstring)) (void) strcpy(colorstring, colornames[i]); if (!XAllocNamedColor(display, DefaultColormap(display, DefaultScreen(display)), colorstring, &visualcolor, &exactcolor)) { (void) sprintf(ErrorMessage, "can't get color %s\n", colorstring); externalerror(ErrorMessage); graph->colors[i] = i ? BlackPixel(display, DefaultScreen(display)) : WhitePixel(display, DefaultScreen(display)); continue; } graph->colors[i] = visualcolor.pixel; if (i > 0 && graph->colors[i] == DEVDEP(graph).view->core.background_pixel) { graph->colors[i] = graph->colors[0]; } } if (graph->colors[0] != DEVDEP(graph).view->core.background_pixel) { graph->colors[0] = DEVDEP(graph).view->core.background_pixel; } } for (i = xmaxcolors; i < NUMCOLORS; i++) { graph->colors[i] = graph->colors[i + 1 - xmaxcolors]; } return;}/* This routine closes the X connection. It is not to be called for finishing a graph. */X11_Close(){ XCloseDisplay(display);}X11_DrawLine(x1, y1, x2, y2)int x1, y1, x2, y2;{ if (DEVDEP(currentgraph).isopen) XDrawLine(display, DEVDEP(currentgraph).window, DEVDEP(currentgraph).gc, x1, currentgraph->absolute.height - y1, x2, currentgraph->absolute.height - y2);}/*ARGSUSED*/X11_Arc(x0, y0, radius, theta1, theta2)int x0, y0, radius;double theta1, theta2;{ int t1, t2; if (DEVDEP(currentgraph).isopen) { if (theta1 >= theta2) theta2 = 2 * M_PI + theta2; t1 = 64 * (180.0 / M_PI) * theta1; t2 = 64 * (180.0 / M_PI) * theta2 - t1; if (t2 == 0) return; XDrawArc(display, DEVDEP(currentgraph).window, DEVDEP(currentgraph).gc, x0 - radius, currentgraph->absolute.height - radius - y0, 2 * radius, 2 * radius, t1, t2);#ifdef notdef printf("at %d, %d, %g %g x %d :: (%d, %d)\n", x0, y0, theta1, theta2, radius, t1, t2); printf("skip\n"); XSync(display, 0); printf("XDrawArc(%d, %d, %d, %d, %d, %d)\n", x0 - radius, currentgraph->absolute.height - radius - y0, 2 * radius, 2 * radius, t1, t2);#endif }}/* note: x and y are the LOWER left corner of text */X11_Text(text, x, y)char *text;int x, y;{/* We specify text position by lower left corner, so have to adjust for X11's font nonsense. */ if (DEVDEP(currentgraph).isopen) XDrawString(display, DEVDEP(currentgraph).window, DEVDEP(currentgraph).gc, x, currentgraph->absolute.height - (y + DEVDEP(currentgraph).font->max_bounds.descent), text, strlen(text)); /* note: unlike before, we do not save any text here */}/*ARGSUSED*/X11_DefineColor(colorid, red, green, blue)int colorid;double red, green, blue;{ internalerror("X11_DefineColor not implemented."); return(0);}/*ARGSUSED*/X11_DefineLinestyle(linestyleid, mask)int linestyleid;int mask;{ internalerror("X11_DefineLinestyle not implemented.");}X11_SetLinestyle(linestyleid)int linestyleid;{ XGCValues values; if (currentgraph->linestyle != linestyleid) {#ifdef notdef switch (linestyleid %3) { case 0: values.line_style = LineSolid; break; case 1: values.line_style = LineOnOffDash; break; case 2: values.line_style = LineDoubleDash; break; }#endif if ((linestyleid == 0) || (DisplayPlanes(display, DefaultScreen(display)) > 1 && linestyleid != 1)) { /* solid if linestyle 0 or if has color, allow only one dashed linestyle */ values.line_style = LineSolid; } else { values.line_style = LineOnOffDash; } XChangeGC(display, DEVDEP(currentgraph).gc, GCLineStyle, &values); currentgraph->linestyle = linestyleid;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -