#include #include #include #include extern const char *__progname; #include #include #include #include #include static const char *displayname = 0; typedef struct xy XY; typedef struct win WIN; struct xy { int x; int y; } ; struct win { Window w; XY loc; XY sz; } ; static Display *disp; static Screen *scr; static int rootwidth; static int rootheight; static int depth; static Window rootwin; static Colormap defcmap; static Visual *visual; static int (*preverr)(Display *, XErrorEvent *); static int (*prevIOerr)(Display *); static Colormap wincmap; static int borderwidth; static int bordermargin; static XColor bgcolour; static XColor fgcolour; static XColor bdcolour; static XColor pcbc_gr; static WIN win; static Window gridwin; static GC copygc; static GC gpgc; static XFontStruct *font; static GC fontgc; static int baselineskip; static int charwidth; static int ccell_font; static XTextProperty wn_prop; static XTextProperty in_prop; static XSizeHints *normal_hints; static XWMHints *wm_hints; static XClassHint *class_hints; static int zoom; /* PCB units per pixel */ static XY pan; /* PCB coordinate of window (0,0) */ #define UU __attribute__((__unused__)) #if 0 static int pcb_to_x_delta(int d) { return(rint(d/(double)zoom)); } #endif #if 0 static int pcb_to_x_x(int x) { return(rint((x-pan.x)/(double)zoom)); } #endif #if 0 static int pcb_to_x_y(int y) { return(rint((y-pan.y)/(double)zoom)); } #endif #if 0 static int x_to_pcb_delta(int d) { return(d*zoom); } #endif #if 0 static int x_to_pcb_x(int x) { return((x*zoom)+pan.x); } #endif #if 0 static int x_to_pcb_y(int y) { return((y*zoom)+pan.y); } #endif #if 0 static double pcb_to_x_delta_float(double d) { return(d/zoom); } #endif static double pcb_to_x_x_float(double x) { return((x-pan.x)/zoom); } static double pcb_to_x_y_float(double y) { return((y-pan.y)/zoom); } #if 0 static double x_to_pcb_delta_float(double d) { return(d*zoom); } #endif static double x_to_pcb_x_float(double x) { return((x*zoom)+pan.x); } static double x_to_pcb_y_float(double y) { return((y*zoom)+pan.y); } static void *dequal(volatile const void *in) { return( ( ((volatile const char *)in) - ((volatile const char *)0) ) + ((char *)0) ); } static int err(Display *d, XErrorEvent *ee) { return((*preverr)(d,ee)); } static int ioerr(Display *d) { return((*prevIOerr)(d)); } static void setup_numbers(void) { borderwidth = 1; bordermargin = 1; } static void setup_visual(void) { depth = XDefaultDepthOfScreen(scr); } static void setup_colour(const char *str, XColor *col) { if (XParseColor(disp,wincmap,str,col) == 0) { fprintf(stderr,"%s: bad colour `%s'\n",__progname,str); exit(1); } while (1) { if (XAllocColor(disp,wincmap,col) == 0) { if (wincmap != defcmap) { fprintf(stderr,"%s: can't allocate colourmap cell for color `%s'\n",__progname,str); exit(1); } wincmap = XCopyColormapAndFree(disp,wincmap); continue; } break; } } static void setup_colours(void) { wincmap = defcmap; setup_colour("black",&bgcolour); setup_colour("white",&fgcolour); setup_colour("white",&bdcolour); setup_colour("white",&pcbc_gr); } static void setup_font(void) { Pixmap pm; pm = XCreatePixmap(disp,rootwin,1,1,depth); fontgc = XCreateGC(disp,pm,0,0); XFreePixmap(disp,pm); font = XQueryFont(disp,XGContextFromGC(fontgc)); baselineskip = font->ascent + font->descent; charwidth = font->max_bounds.width; ccell_font = (font->min_bounds.width == charwidth); } static void setup_windows(void) { int x; int y; int w; int h; unsigned long int attrmask; XSetWindowAttributes attr; w = 853; h = 682; x = 0; y = 0; attrmask = 0; attr.background_pixel = bgcolour.pixel; attrmask |= CWBackPixel; attr.border_pixel = bdcolour.pixel; attrmask |= CWBorderPixel; attr.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask; attrmask |= CWEventMask; attr.do_not_propagate_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask; attrmask |= CWDontPropagate; attr.colormap = wincmap; attrmask |= CWColormap; w -= 2 * borderwidth; h -= 2 * borderwidth; win.sz.x = w; win.sz.y = h; win.w = XCreateWindow(disp,rootwin,x,y,w,h,borderwidth,depth, InputOutput,visual,attrmask,&attr); wn_prop.value = (unsigned char *) dequal("tst"); wn_prop.encoding = XA_STRING; wn_prop.format = 8; wn_prop.nitems = strlen(wn_prop.value); in_prop.value = (unsigned char *) dequal("tst"); in_prop.encoding = XA_STRING; in_prop.format = 8; in_prop.nitems = strlen(in_prop.value); normal_hints = XAllocSizeHints(); normal_hints->flags = PMinSize | PResizeInc; normal_hints->x = x; normal_hints->y = y; normal_hints->flags |= PPosition; normal_hints->width = w; normal_hints->height = h; normal_hints->flags |= PSize; normal_hints->min_width = 25; normal_hints->min_height = 25; normal_hints->width_inc = 1; normal_hints->height_inc = 1; wm_hints = XAllocWMHints(); wm_hints->flags = InputHint; wm_hints->input = True; class_hints = XAllocClassHint(); class_hints->res_name = dequal("xpcb"); class_hints->res_class = dequal("Editor"); XSetWMProperties(disp,win.w,&wn_prop,&in_prop,0,0,normal_hints,wm_hints,class_hints); attrmask = 0; attr.background_pixel = pcbc_gr.pixel; attrmask |= CWBackPixel; gridwin = XCreateWindow(disp,win.w,0,0,1,1,0,CopyFromParent, InputOutput,CopyFromParent,attrmask,&attr); XMapRaised(disp,win.w); } static void setup_gcs(void) { copygc = XCreateGC(disp,win.w,0,0); XCopyGC(disp,fontgc,GCFont,copygc); gpgc = XCreateGC(disp,win.w,0,0); XCopyGC(disp,fontgc,GCFont,gpgc); } /* * It seems that if we don't explicitly call XShapeQueryExtension, * calls to the SHAPE API routines simply don't work(!). (By my * reading of the doc, this is a bug....) */ static void setup_shape(void) { int ev; int er; XShapeQueryExtension(disp,&ev,&er); } static void setup_grid(void) { double bgrid; int boffx; int boffy; double grid; Pixmap mask; GC gc; XY wpcbsz; double gmul; double xmin; double xmax; double ymin; double ymax; double x0; double x1; double y0; double y1; double x; double y; int i; void draw_point_grid(double x0, double x1, double gx, double y0, double y1, double gy) { double x; double y; int i; int j; for (x=x0;x