/**************************************************************************** * Michael Main -- Sept 25, 1991 * * This C module contains routines to simulate the Turbo C++ graphics * routines in a simple way, using X-windows. * * To use these routines in your C-program, follow these steps: * 1. Put this code in a file called Xturbo.c * 2. Compile this code with the command: * g++ -c Xturbo.c -I/usr/local/X11/include * 3. Put the include directive #include "Xturbo.h" in your program. * Documentation for the functions is also present in Xturbo.h. * 4. When you compile your program, include Xturbo.o on the g++ line, and * also include the X11 library, like this: * g++ myprogram.c Xturbo.o -L/usr/local/X11/lib -lX11 ****************************************************************************/ #include #include #include #include #include #include #include "Xturbo.h" static Display *mydisplay; static Window mywindow; static GC context[2]; static int screen; Colormap cmap; long unsigned int plane_masks[2]; long unsigned int colors[2]; XColor NeitherPlane, NotVisualPlaneOnly, VisualPlaneOnly, BothPlanes; unsigned long black_pix, white_pix; static int screenheight, screenwidth; // Height and width of screen in pixels static int monitortype; // Currently indicates the number of pages available static int lines, fills; // Line and fill colors static int visual, active; // Current visual and active page void clearviewport() { if (!monitortype) { XClearWindow(mydisplay, mywindow); XMapWindow(mydisplay, mywindow); /* XFlush(mydisplay); */ return; } int savelines = lines; int savefills = fills; lines = 1; fills = 1; short wholescreen[8] = { 0, 0, 0, screenheight, screenwidth, screenheight, screenwidth, 0 }; fillpoly(4, wholescreen); lines = savelines; fills = savefills; } void line(int x1, int y1, int x2, int y2) { if (lines) XSetForeground(mydisplay, context[active], white_pix); else XSetForeground(mydisplay, context[active], black_pix); XDrawLine(mydisplay, mywindow, context[active], x1, y1, x2, y2); XMapWindow(mydisplay, mywindow); /* XFlush(mydisplay); */ /* printf("Line %d %d %d %d\n", x1,y1,x2,y2); */ } void plot(int x, int y) { if (lines) XSetForeground(mydisplay, context[active], white_pix); else XSetForeground(mydisplay, context[active], black_pix); XDrawPoint(mydisplay, mywindow, context[active], x, y); XMapWindow(mydisplay, mywindow); /* XFlush(mydisplay); */ /* printf("Point %d %d\n", x,y); */ } void drawpoly(int numpoints, short polypoints[]) { /* Draws a polygon with numpoints vertices. The array ** polypoints contains the x,y coordinates of the first point of the polygon ** in polypoints[0] and polypoints[1]. The next point is in polypoints[2] ** and polypoints[3], and so on. */ char response; if (lines) XSetForeground(mydisplay, context[active], white_pix); else XSetForeground(mydisplay, context[active], black_pix); XDrawLines(mydisplay, mywindow, context[active], (XPoint *) polypoints, numpoints, CoordModeOrigin); if (numpoints >= 3) XDrawLine(mydisplay, mywindow, context[active], polypoints[2*numpoints-2], polypoints[2*numpoints-1], polypoints[0], polypoints[1]); XMapWindow(mydisplay, mywindow); /* scanf("%c", &response); */ /* XFlush(mydisplay); */ /* printf("Drawpoly has been called\n"); */ } void updateall() { XFlush(mydisplay); } void fillpoly(int numpoints, short polypoints[]) { /* Draws and fills a polygon with numpoints vertices. The array ** polypoints contains the x,y coordinates of the first point of the polygon ** in polypoints[0] and polypoints[1]. The next point is in polypoints[2] ** and polypoints[3], and so on. */ if (fills) XSetForeground(mydisplay, context[active], white_pix); else XSetForeground(mydisplay, context[active], black_pix); XFillPolygon(mydisplay, mywindow, context[active], (XPoint *) polypoints, numpoints, Complex, CoordModeOrigin); drawpoly(numpoints, polypoints); /* printf("Fillpoly has been called\n"); */ } void initgraphics() { unsigned int line_wid = 1; int line_style = LineSolid; int cap_style = CapRound; int join_style = JoinMiter; int dash_offset = 0; static char dash_list[] = { 12, 24 }; int list_len = 2; char response; /* First connect to a server -- page 53 Volume 1 of manual */ if ((mydisplay=XOpenDisplay(NULL)) == NULL ) { fprintf( stderr, "XOpenDisplay failure.\n"); fprintf( stderr, "Make sure the DISPLAY variable is set in environment."); exit( -1 ); } screen = DefaultScreen(mydisplay); /* Get the display dimensions -- page 56 Volume 1 of manual */ screenwidth = DisplayWidth(mydisplay, screen) >> 1; screenheight = screenwidth; /* Make it square */ /* Create a window -- page 57 Volume 1 of manual */ mywindow = XCreateSimpleWindow(mydisplay, RootWindow(mydisplay, screen), 0, 0, /* Coordinates of upper left corner of window */ screenwidth, screenheight, 4, /* Border width */ BlackPixel(mydisplay, screen), WhitePixel(mydisplay, screen) ); /* Select the events to handle */ (void) XSelectInput(mydisplay, mywindow, ExposureMask); /* Set the graphics context[active] -- page 270 Volume 1 of manual */ context[0] = XCreateGC(mydisplay, mywindow, 0, NULL); context[1] = XCreateGC(mydisplay, mywindow, 0, NULL); XSetWindowBackground(mydisplay, mywindow, WhitePixel(mydisplay,screen)); XSetForeground(mydisplay, context[active], BlackPixel(mydisplay,screen)); XSetLineAttributes(mydisplay,context[active],line_wid,line_style,cap_style,join_style); XSetDashes(mydisplay, context[active],dash_offset,dash_list,list_len); /* Make the window visible */ XMapWindow(mydisplay, mywindow); XFlush(mydisplay); /* Note: A scanf operation seems to be needed here, but I'm not sure why */ printf("Please press Return to complete initialization\n"); scanf("%c",&response); /* Set up the variables for pages and colors */ visual = active = 0; lines = 0; fills = 1; cmap = DefaultColormap(mydisplay, screen); if ((DisplayPlanes(mydisplay, screen) <= 1) || (!XAllocColorCells(mydisplay, cmap, False, plane_masks, 2, colors, 1))) { // Set up with just one page monitortype = 0; black_pix = BlackPixel(mydisplay, screen); white_pix = WhitePixel(mydisplay, screen); } else { // Set up with two pages using the planes and pixels allocated monitortype = 1; // Legal page numbers are 0 and 1 /* The following four pixels are now allocated, and will be displayed ** according to the current visual page, as shown in the table: ** colors[0] Always white ** colors[0] | plane_masks[0] Black if page 0 is visual, else white ** colors[0] | plane_masks[1] Black if page 1 is visual, else white ** colors[0] | both Always black */ // Set up four Xcolors to represent these four pixels XParseColor(mydisplay, cmap, "white", &NeitherPlane); XParseColor(mydisplay, cmap, "white", &NotVisualPlaneOnly); XParseColor(mydisplay, cmap, "black", &VisualPlaneOnly); XParseColor(mydisplay, cmap, "black", &BothPlanes); // Store the two non-changing pixels in the color map NeitherPlane.pixel = colors[0]; XStoreColor(mydisplay, cmap, &NeitherPlane); BothPlanes.pixel = colors[0] | plane_masks[0] | plane_masks[1]; XStoreColor(mydisplay, cmap, &BothPlanes); // Call setvisualpage to store the two changing pixels setvisualpage(0); // Call setactivepage to give initial values to black_pix. setactivepage(0); white_pix = colors[0]; XSetPlaneMask(mydisplay, context[0], colors[0] | plane_masks[0]); XSetPlaneMask(mydisplay, context[1], colors[0] | plane_masks[1]); } } void closegraph() { } int getmaxx() { return screenwidth-1; } int getmaxy() { return screenheight-1; } int maxpage() { return monitortype; } void setcolor(int linecolor) { lines = linecolor; } void setfill(int fillcolor) { fills = fillcolor; } void setactivepage(int pagenumber) { if ((pagenumber >= 0) && (pagenumber <= monitortype) && monitortype) { active = pagenumber; black_pix = colors[0] | plane_masks[active]; } } void setvisualpage(int pagenumber) { if ((pagenumber >= 0) && (pagenumber <= monitortype) && monitortype) { visual = pagenumber; VisualPlaneOnly.pixel = colors[0] | plane_masks[visual]; XStoreColor(mydisplay, cmap, &VisualPlaneOnly); NotVisualPlaneOnly.pixel = colors[0] | plane_masks[!visual]; XStoreColor(mydisplay, cmap, &NotVisualPlaneOnly); } }