⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 x11.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1988 Jeffrey M. Hsu$Id: x11.c,v 1.16 2005/08/22 19:29:20 pnenzi Exp $**********//*    X11 drivers.*/#include <ngspice.h>#ifndef X_DISPLAY_MISSING#  include <sys/time.h>#  include <sys/types.h>  /* PN */#  include <unistd.h>     /* PN */#  include <graph.h>#  include <ftedbgra.h>#  include <ftedev.h>#  include <fteinput.h>#  include <cpdefs.h>#  include <ftedefs.h>#  include <variable.h>/* Added X11/ prefix to the next includes - ER */#  include <X11/IntrinsicP.h>#  include <X11/Xatom.h>#  include <X11/StringDefs.h>#  include <X11/Xutil.h>#  include <X11/cursorfont.h>#  include <X11/Xaw/Box.h>#  include <X11/Xaw/Command.h>#  include <X11/Xaw/Form.h>#  include <X11/Shell.h>#  ifdef DEBUG#     include <X11/Xlib.h> /* for _Xdebug */#  endif#include "x11.h"#include "graphdb.h"#include "display.h"#include "graf.h"#include "../error.h"#define RAD_TO_DEG	(180.0 / M_PI)/* X dependent default parameters */#define DEF_FONT "10x14"#define NUMLINESTYLES 8#define MW_LINEWIDTH 2  /* MW. I want larger lines */#define NXPLANES 5      /* note: What is this used for? */#define BOXSIZE 30      /* initial size of bounding box for zoomin */typedef struct x11info {    Window window;    int	isopen;    Widget shell, form, 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\002\001\002",	/* dots */    "\007\007\007\007",	/* longdash */    "\003\003\003\003",	/* shortdash */    "\007\002\002\002",	/* dots longdash */    "\003\002\001\002",	/* dots shortdash */    "\003\003\007\003",	/* short/longdash */};static Widget toplevel;static Bool noclear = False;static GRAPH *lasthardcopy; /* graph user selected */static int X11_Open = 0;static int numdispplanes;/* static functions */static void initlinestyles (void);static void initcolors (GRAPH *graph);static void X_ScreentoData (GRAPH *graph, int x, int y, double *fx, double *fy);static void linear_arc(int x0, int y0, int radius, double theta1, double theta2);interrorhandler(Display *display, XErrorEvent *errorev){    XGetErrorText(display, errorev->error_code, ErrorMessage, 1024);    externalerror(ErrorMessage);    return 0;}intX11_Init(void){    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] = "ngspice";    argv[1] = displayname;/*    argv[2] = "-geometry";    argv[3] = "=1x1+2+2";*/    /* initialize X toolkit */    toplevel = XtInitialize("ngspice", "Nutmeg", NULL, 0, &argc, argv);    display = XtDisplay(toplevel);    X11_Open = 1;    /* "invert" works better than "xor" for B&W */    /* xor gc should be a function of the pixels that are written on */    /* gcvalues.function = GXxor; */    /* this patch makes lines visible on true color displays    Guenther Roehrich 22-Jan-99 */    gcvalues.function = GXinvert;    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);    numdispplanes = DisplayPlanes(display, DefaultScreen(display));    return (0);}static voidinitlinestyles(void){    int i;    if (numdispplanes > 1) {      /* Dotted lines are a distraction when we have colors. */      for (i = 2; i < NUMLINESTYLES; i++) {	  xlinestyles[i] = xlinestyles[0];      }    }}static voidinitcolors(GRAPH *graph){    int i;    static char *colornames[] = {   "black",    /* white */	"white", "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 << numdispplanes;	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;	    	    	/* MW. I don't need this, everyone must know what he is doing	    if (i > 0 &&		graph->colors[i] == DEVDEP(graph).view->core.background_pixel) {		graph->colors[i] = graph->colors[0];	    } */	    	}	/* MW. Set Beackgroound here */	XSetWindowBackground(display, DEVDEP(graph).window, 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];    }}voidhandlekeypressed(Widget w, caddr_t clientdata, caddr_t calldata){    XKeyEvent *keyev = (XKeyPressedEvent *) calldata;    GRAPH *graph = (GRAPH *) clientdata;    char text[4];    int nbytes;    nbytes = XLookupString(keyev, text, 4, NULL, NULL);    if (!nbytes) return;    /* write it */    PushGraphContext(graph);    text[nbytes] = '\0';    SetColor(1);    Text(text, keyev->x, graph->absolute.height - keyev->y);    /* save it */    SaveText(graph, text, keyev->x, graph->absolute.height - keyev->y);    /* warp mouse so user can type in sequence */    XWarpPointer(display, None, DEVDEP(graph).window, 0, 0, 0, 0,	keyev->x + XTextWidth(DEVDEP(graph).font, text, nbytes),	keyev->y);    PopGraphContext();}voidhandlebuttonev(Widget w, caddr_t clientdata, caddr_t calldata){    XButtonEvent *buttonev = (XButtonEvent *) calldata;    switch (buttonev->button) {      case Button1:	slopelocation((GRAPH *) clientdata, buttonev->x, buttonev->y);	break;      case Button3:	zoomin((GRAPH *) clientdata);	break;    }}/* Recover from bad NewViewPort call. */#define RECOVERNEWVIEWPORT()    tfree(graph);\	            graph = (GRAPH *) NULL; 	    /* need to do this or else DestroyGraph will free it again *//* NewViewport is responsible for filling in graph->viewport */intX11_NewViewport(GRAPH *graph){    char fontname[513]; /* who knows . . . */    char *p, *q;    Cursor cursor;    XSetWindowAttributes	w_attrs;    XGCValues gcvalues;    static Arg formargs[ ] = {	{ XtNleft, (XtArgVal) XtChainLeft },	{ XtNresizable, (XtArgVal) TRUE }    };    static Arg bboxargs[ ] = {	{ XtNfromHoriz, (XtArgVal) NULL },	{ XtNbottom, (XtArgVal) XtChainTop },	{ XtNtop, (XtArgVal) XtChainTop },	{ XtNleft, (XtArgVal) XtChainRight },	{ XtNright, (XtArgVal) XtChainRight }    };    static Arg buttonargs[ ] = {	{ XtNlabel, (XtArgVal) NULL },	{ XtNfromVert, (XtArgVal) NULL },	{ XtNbottom, (XtArgVal) XtChainTop },	{ XtNtop, (XtArgVal) XtChainTop },	{ XtNleft, (XtArgVal) XtRubber },	{ XtNright, (XtArgVal) XtRubber },	{ XtNresizable, (XtArgVal) TRUE }    };    static Arg viewargs[] = {	{ XtNresizable, (XtArgVal) TRUE },	{ XtNwidth, (XtArgVal) 300 },	{ XtNheight, (XtArgVal) 300 },	{ XtNright, (XtArgVal) XtChainRight }    };    int	trys;    graph->devdep = tmalloc(sizeof(X11devdep));    /* set up new shell */    DEVDEP(graph).shell = XtCreateApplicationShell("shell",	    topLevelShellWidgetClass, NULL, 0);    /* set up form widget */    DEVDEP(graph).form = XtCreateManagedWidget("form",	formWidgetClass, DEVDEP(graph).shell, formargs, XtNumber(formargs));    /* set up viewport */    DEVDEP(graph).view = XtCreateManagedWidget("viewport", widgetClass,					       DEVDEP(graph).form,					       viewargs,					       XtNumber(viewargs));    XtAddEventHandler(DEVDEP(graph).view, ButtonPressMask, FALSE,		      (XtEventHandler) handlebuttonev, graph);    XtAddEventHandler(DEVDEP(graph).view, KeyPressMask, FALSE,		     (XtEventHandler) handlekeypressed, graph);    XtAddEventHandler(DEVDEP(graph).view, StructureNotifyMask, FALSE,		     (XtEventHandler) resize, graph);    XtAddEventHandler(DEVDEP(graph).view, ExposureMask, FALSE,	    (XtEventHandler) redraw, graph);    /* set up button box */    XtSetArg(bboxargs[1], XtNfromHoriz, DEVDEP(graph).view);    DEVDEP(graph).buttonbox = XtCreateManagedWidget("buttonbox",	boxWidgetClass, DEVDEP(graph).form, bboxargs, XtNumber(bboxargs));    /* set up buttons */    XtSetArg(buttonargs[0], XtNlabel, "quit");    XtSetArg(bboxargs[1], XtNfromVert, NULL);    DEVDEP(graph).buttons[0] = XtCreateManagedWidget("quit",	commandWidgetClass, DEVDEP(graph).buttonbox,	buttonargs, 1);    XtAddCallback(DEVDEP(graph).buttons[0], XtNcallback, (XtCallbackProc) killwin, graph);    XtSetArg(buttonargs[0], XtNlabel, "hardcopy");    XtSetArg(bboxargs[1], XtNfromVert, DEVDEP(graph).buttons[0]);    DEVDEP(graph).buttons[1] = XtCreateManagedWidget("hardcopy",	commandWidgetClass, DEVDEP(graph).buttonbox,	buttonargs, 1);    XtAddCallback(DEVDEP(graph).buttons[1], XtNcallback, (XtCallbackProc) hardcopy, graph);    /* set up fonts */    if (!cp_getvar("font", VT_STRING, fontname)) {	(void) strcpy(fontname, DEF_FONT);    }    for (p = fontname; *p && *p <= ' '; p++)	;    if (p != fontname) {	for (q = fontname; *p; *q++ = *p++)		;	*q = 0;    }    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);    DEVDEP(graph).isopen = 0;    w_attrs.bit_gravity = ForgetGravity;    XChangeWindowAttributes(display, DEVDEP(graph).window, CWBitGravity,	    &w_attrs);    /* have to note font and set mask GCFont in XCreateGC, p.w.h. */    gcvalues.font = DEVDEP(graph).font->fid;    gcvalues.line_width = MW_LINEWIDTH;    gcvalues.cap_style = CapNotLast;    gcvalues.function = GXcopy;    DEVDEP(graph).gc = XCreateGC(display, DEVDEP(graph).window,	    GCFont | 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);}/* This routine closes the X connection.	It is not to be called for finishing a graph. */intX11_Close(void){    XCloseDisplay(display);    return 0;}intX11_DrawLine(int x1, int y1, int x2, int y2){    if (DEVDEP(currentgraph).isopen)	XDrawLine(display, DEVDEP(currentgraph).window,		DEVDEP(currentgraph).gc,		x1, currentgraph->absolute.height - y1,		x2, currentgraph->absolute.height - y2);    return 0;}intX11_Arc(int x0, int y0, int radius, double theta1, double theta2){    int	t1, t2;    if (!cp_getvar("x11lineararcs", VT_BOOL, (char *) &t1)) {	linear_arc(x0, y0, radius, theta1, theta2);    }    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 0;	XDrawArc(display, DEVDEP(currentgraph).window, DEVDEP(currentgraph).gc,		x0 - radius,		currentgraph->absolute.height - radius - y0,		2 * radius, 2 * radius, t1, t2);		    }    return 0;}/* note: x and y are the LOWER left corner of text */intX11_Text(char *text, int x, int 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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -