#include #include /* includes and */ #include "pixels.h" #define OVERRIDE_WINDOW_MANAGER True #define BORDER_WIDTH 3 #define POSTSCRIPT_PAGE_WIDTH 2400 #define POSTSCRIPT_PAGE_HEIGHT 3150 Display *display; /* NULL => default to value of DISPLAY variable. */ static char *display_name = NULL; static int screen; static XWindowAttributes window_info; /* Where info on window goes. */ static XFontStruct *font_info; /* Font to be displayed. */ static char *font_name = "9x15"; static GC setGC, clrGC, xorGC; /* STRUCTURES*/ static GC setTxtGC, clrTxtGC, xorTxtGC; GC select_gc(); /* main( argc, argv ) int argc; char **argv; { test_graphics_x11(); test_graphics_simple(); } */ test_graphics_x11() { Window w1, w2; Window x_create_window(); unsigned int width; x_init_graphics(); printf( "Screen size: %d x %d (%dmm x %dmm)\n", DisplayWidth( display, screen ), DisplayHeight( display, screen ), DisplayWidthMM( display, screen ), DisplayHeightMM( display, screen ) ); w1 = x_create_window( "w1", 0, 0, 200, 200 ); w2 = x_create_window( "w2", 700, 0, 900, 1200 ); x_map_window( w1 ); x_map_window( w2 ); width = x_window_width(w1); printf("%d\n", width); x_draw_line(w1, 0, 0, 50, 50, SET, 0); x_draw_line(w1, 0, 0, 25, 25, CLEAR, 0); x_draw_line(w1, 20, 20, 35, 35, XOR, 0); x_draw_text(w2, 20, 20, "Test", SET, 0); x_draw_text(w2, 20, 50, "Test", CLEAR, 0); x_draw_text(w2, 20, 80, "Test", XOR, 0); x_draw_text(w2, 20, 80, "Te", XOR, 0); printf( "Press RETURN to continue.\n" ); getchar(); printf( "Goodbye, Joe.\n" ); x_kill_window(w1); x_kill_window(w2); x_kill_graphics(); } /****************************************************************************/ x_init_graphics() { XGCValues valuesset, valuesclr, valuesxor; printf( "Trying to open %s\n", XDisplayName( display_name ) ); /* connect to X server. */ if ( !( display = ( XOpenDisplay( display_name ) ) ) ) { fprintf( stderr, "GRAPHICS-X11: Cannot connect to X server %s\n", XDisplayName( display_name ) ); x_graphics_error( "Error while trying to open display." ); } screen = DefaultScreen(display); if ( !( font_info = XLoadQueryFont( display, font_name ) ) ) { fprintf( stderr, "Error while trying to open font %s\n", font_name ); x_graphics_error( "Can't find font. Try xlsfonts to find a new one." ); } /*CREATES GCs TO BE USED FOR DRAWABLE*/ valuesset.foreground = BlackPixel(display, screen); valuesset.background = WhitePixel(display, screen); valuesset.plane_mask = AllPlanes; valuesset.font = font_info->fid; /* valuesset.line_width = 5; */ setGC = XCreateGC(display, RootWindow(display, screen), GCForeground | GCBackground | GCPlaneMask /* | GCLineWidth */, &valuesset); setTxtGC = XCreateGC(display, RootWindow(display, screen), GCForeground | GCBackground | GCFont, &valuesset); valuesclr.background = BlackPixel(display, screen); valuesclr.foreground = WhitePixel(display, screen); valuesclr.plane_mask = AllPlanes; valuesclr.font = font_info->fid; /* valuesclr.line_width = 5; */ clrGC = XCreateGC(display, RootWindow(display, screen), GCForeground | GCBackground | GCPlaneMask /* | GCLineWidth */, &valuesclr); clrTxtGC = XCreateGC(display, RootWindow(display, screen), GCForeground | GCBackground | GCFont, &valuesclr); valuesxor.function = GXinvert; valuesxor.foreground = BlackPixel(display, screen); valuesxor.plane_mask = AllPlanes; valuesxor.font = font_info->fid; /* valuesxor.line_width = 5; */ xorGC = XCreateGC(display, RootWindow(display, screen), GCForeground | GCFunction | GCPlaneMask /* | GCLineWidth */, &valuesxor); xorTxtGC = XCreateGC(display, RootWindow(display, screen), GCForeground | GCFunction | GCFont, &valuesxor); } /****************************************************************************/ /* * Select a gc based on operation. */ GC select_gc (operation) int operation; { switch (operation) { case SET: return(setGC); break; case CLEAR: return(clrGC); break; case XOR: return(xorGC); break; default: fprintf( stderr, "X11-GRAPHICS: Can't handle operation %d\n", operation ); return(NULL); break; } } /****************************************************************************/ Window x_create_window( name, left, top, width, height ) char *name; int left, top, width, height; { Window w; XSetWindowAttributes attr; unsigned long set_mask; /* override redirect allows the window to be mapped under program control rather than user or window manager control. See attr stucture below (True in override_redirect position) and set_mask below. This is also why XCreateWindow() is used rather than XCreateSimpleWindow() */ if ( OVERRIDE_WINDOW_MANAGER ) set_mask = CWOverrideRedirect | CWBackPixel | CWBorderPixel; else set_mask = CWBackPixel | CWBorderPixel; attr.override_redirect = True; attr.background_pixel = WhitePixel(display, screen); attr.border_pixel = BlackPixel(display, screen); if ( !( w = XCreateWindow( display, RootWindow(display,screen), left, top, width, height, BORDER_WIDTH, CopyFromParent, CopyFromParent, CopyFromParent, set_mask, &attr))) x_graphics_error( "Error while creating window.\n" ); XStoreName( display, w, name ); XFlush( display ); return(w); } /* Old version: Window x_create_window (left, top, width, height) int left, top, width, height; { Window w; if ( !( w = XCreateSimpleWindow( display, RootWindow(display,screen), left, top, width, height, BORDER_WIDTH, BlackPixel(display, screen), WhitePixel(display, screen)) ) ) x_graphics_error( "Error while creating window.\n" ); XMapRaised( display,w ); XFlush(display); return(w); } */ /****************************************************************************/ x_map_window (window) Window window; { XEvent report; /* Make sure window gets exposed. */ /* Select event types wanted. */ XSelectInput( display, window, ExposureMask ); XMapRaised( display, window ); /* Put window up on screen. */ XFlush(display); /* And make server see it. */ XNextEvent( display, &report ); if ( report.type != Expose ) { fprintf( stderr, "GRAPHICS-X11: Expose not first event from window. %d\n", report.type ); x_graphics_error( "Error while mapping window.\n" ); } XSelectInput( display, window, 0 ); } /****************************************************************************/ x_unmap_window (window) Window window; { XUnmapWindow( display, window ); /* Take window off screen. */ XFlush(display); /* And make server see it. */ } /****************************************************************************/ x_flush() { XFlush(display); } /****************************************************************************/ x_kill_window (window) Window window; { XDestroyWindow( display,window ); /* Throw window away. */ XFlush(display); /* And make server see it. */ } /****************************************************************************/ x_kill_graphics() { XFreeFont( display, font_info ); XFreeGC( display, setGC ); XFreeGC( display, clrGC ); XFreeGC( display, xorGC ); XFreeGC( display, setTxtGC ); XFreeGC( display, clrTxtGC ); XFreeGC( display, xorTxtGC ); XFlush( display ); XCloseDisplay( display ); } /****************************************************************************/ x_clear_window(window) Window window; { XClearWindow( display,window ); XFlush(display); } /****************************************************************************/ x_draw_point( window, x, y, operation, flush ) Window window; int x, y, operation, flush; { GC gc; if ((gc = select_gc(operation))) { XDrawPoint( display, window, gc, x, y ); if (flush) XFlush(display); /* And make server see it. */ } } /****************************************************************************/ x_draw_line( window, x1, y1, x2, y2, operation, flush ) Window window; int x1, y1, x2, y2, operation, flush; { GC gc; if ((gc = select_gc(operation))) { XDrawLine( display, window, gc, x1, y1, x2, y2); if (flush) XFlush(display); /* And make server see it. */ } } /****************************************************************************/ x_draw_box( window, x, y, width, height, operation, flush ) Window window; int width, height, x, y, operation, flush; { GC gc; if ((gc = select_gc(operation))) { XDrawRectangle( display, window, gc, x, y, width, height); if (flush) XFlush(display); } } /****************************************************************************/ x_draw_filled_rectangle( window, x, y, width, height, operation, flush ) Window window; int width, height, x, y, operation, flush; { GC gc; if ((gc = select_gc(operation))) { XFillRectangle( display, window, gc, x, y, width, height); if (flush) XFlush(display); } } /****************************************************************************/ x_draw_circle( window, x, y, width, height, angle1, angle2, operation, flush ) Window window; int x, y, width, height, angle1, angle2, operation, flush; { GC gc; if ((gc = select_gc(operation))) { XDrawArc( display, window, gc, x, y, width, height, angle1, angle2 ); if (flush) XFlush(display); } } /****************************************************************************/ x_draw_filled_circle( window, x, y, width, height, angle1, angle2, operation, flush ) Window window; int x, y, width, height, angle1, angle2, operation, flush; { GC gc; if ((gc = select_gc(operation))) { XFillArc( display, window, gc, x, y, width, height, angle1, angle2 ); if (flush) XFlush(display); } } /****************************************************************************/ x_draw_text( window, x, y, text, operation, flush ) Window window; int x, y, operation, flush; char *text; { GC gc; switch( operation ) { case SET: gc = setTxtGC; break; case CLEAR: gc = clrTxtGC; break; case XOR: gc = xorTxtGC; break; default: fprintf( stderr, "X11-GRAPHICS: Can't handle text operation %d\n", operation ); break; } XDrawImageString( display, window, gc, x, y, text, strlen( text )); XFlush(display); /* And make server see it. */ } /****************************************************************************/ x_window_width(window) Window window; { if ( !XGetWindowAttributes(display, window, &window_info ) ) x_graphics_error( "Error while trying to query window." ); return( (int) window_info.width ); } /****************************************************************************/ x_window_height(window) Window window; { if ( !XGetWindowAttributes(display, window, &window_info ) ) x_graphics_error( "Error while trying to query window." ); return( (int) window_info.height ); } /****************************************************************************/ x_window_x(window) Window window; { if ( !XGetWindowAttributes(display, window, &window_info ) ) x_graphics_error( "Error while trying to query window." ); return( (int) window_info.x ); } /****************************************************************************/ x_window_y(window) Window window; { if ( !XGetWindowAttributes(display, window, &window_info ) ) x_graphics_error( "Error while trying to query window." ); return( (int) window_info.y ); } /****************************************************************************/ x_warp_mouse( window, x, y ) Window window; int x, y; { int mouse_x, mouse_y; XWarpPointer( display, None, window, 0, 0, 0, 0, mouse_x = x, mouse_y = y ); XFlush(display); /* And make server see it. */ } /****************************************************************************/ static int mouse_x, mouse_y, mouse_buttons; static Window trash1, trash2; int trash3, trash4; /* In order to return two variables I need to be given an array to fill. */ /* Returns the mouse buttons. */ x_read_mouse( window, position ) Window window; int position[]; { XQueryPointer( display, window, &trash1, &trash2, &trash3, &trash4, &mouse_x, &mouse_y, &mouse_buttons ); position[0] = mouse_x; position[1] = mouse_y; return( mouse_buttons ); } /****************************************************************************/ x_read_mouse_buttons( window ) Window window; { XQueryPointer( display, window, &trash1, &trash2, &trash3, &trash4, &mouse_x, &mouse_y, &mouse_buttons ); return( mouse_buttons ); } /****************************************************************************/ XEvent the_event; x_wait_button_click(window) Window window; { XSelectInput(display, window, ButtonPressMask); while (!XCheckTypedWindowEvent( display, window, ButtonPress, &the_event )) {} } /****************************************************************************/ /* * x_graphics_error - Fatal error. */ x_graphics_error( identifier ) char *identifier; { fprintf( stderr, "GRAPHICS-X11: %s\n", identifier ); exit(-1); } /****************************************************************************/ void x_plot_float_array (window, array, length, ring_start, time_step, time_offset, operation, display_left, display_bottom, display_right, display_top, user_left, user_bottom, user_right, user_top) float *array, time_step, time_offset; int length, ring_start, operation; int display_left, display_top, display_right, display_bottom; double user_left, user_top, user_right, user_bottom; { float x_conversion, y_conversion; register i, index; register int x, y; register int last_x, last_y; GC gc; x_conversion = (user_right - user_left) == 0 ? 0.0 : (display_right - display_left) / ( user_right - user_left); y_conversion = (user_bottom - user_top) == 0 ? 0.0 : (display_top - display_bottom) / (user_top - user_bottom); gc = select_gc(operation); index = (0 + ring_start) % length; last_x = display_left + (time_offset - user_left) * x_conversion; last_y = display_bottom + (array[index] - user_bottom) * y_conversion; XDrawPoint( display, window, gc, last_x, last_y ); for (i = 0; i < length; i++) { index = (i + ring_start) % length; x = display_left + (time_offset + i*time_step - user_left)*x_conversion; y = display_bottom + (array[index] - user_bottom)*y_conversion; XDrawLine( display, window, gc, last_x, last_y, x, y); last_x = x; last_y = y; } XFlush(display); /* And make server see it. */ } /****************************************************************************/ /****************************************************************************/ /****************************************************************************/ /****************************************************************************/ /* This is the really simple interface with just one window. */ test_graphics_simple() { int i; int mouse[2]; init_window( 0.5 ); printf( "Window width and height: %d %d\n", width_of_window(), height_of_window() ); /* Clear screen. */ clear_window(); draw_line( 0, 0, width_of_window(), height_of_window(), SET ); draw_line( 0, height_of_window(), width_of_window(), 0, SET ); /* draw top, bottom, left, right borders on box */ draw_line( 200, 200, 350, 200, SET ); draw_line( 350, 200, 350, 350, SET ); draw_line( 350, 350, 200, 350, SET ); draw_line( 200, 350, 200, 200, SET ); /* write text on canvas */ draw_text( 225, 250, "Hello World!", SET ); draw_text( 225, 275, "Hi Mom!", CLEAR ); /* for(;;) { i = read_mouse( mouse ); if ( i ) printf( "%d %d %d\n", i, mouse[0], mouse[1] ); } */ printf( "Press RETURN to continue.\n" ); getchar(); done_with_window(); } /****************************************************************************/ static Window w; /* window id of window to be used. */ /* Create a window in the top right corner of the screen with the given aspect-ratio (width/height) in pixels. */ init_window( aspect_ratio ) float aspect_ratio; { unsigned int width, height; /* window size. */ int left, top; /* window position. */ float screen_aspect_ratio; char *window_name = "Simple Graphics Window"; x_init_graphics(); screen_aspect_ratio = ((float) DisplayWidth( display, screen ))/ DisplayHeight( display, screen ); if ( aspect_ratio >= screen_aspect_ratio ) { /* width limited. */ width = DisplayWidth( display, screen ) - 2*BORDER_WIDTH; height = (int) (width/aspect_ratio); } else { /* height limited. */ height = DisplayHeight( display, screen ) - 2*BORDER_WIDTH; width = (int) (height*aspect_ratio); } w = x_create_window( "Graphics Window", DisplayWidth( display, screen ) - width - 2*BORDER_WIDTH, 0, width, height ); x_map_window( w ); } /****************************************************************************/ /* Create a window which can be printed in landscape mode. aspect_ratio is ignored. */ init_window_landscape( aspect_ratio ) float aspect_ratio; { unsigned int width, height; /* window size. */ int left, top; /* window position. */ float screen_aspect_ratio; char *window_name = "Simple Graphics Window"; x_init_graphics(); screen_aspect_ratio = ((float) DisplayWidth( display, screen ))/ DisplayHeight( display, screen ); /* SUN hi res display */ /* width = 1569; height = 1194; */ /* SUN low res display */ width = 1152-31; height = 900-6; w = x_create_window( "Graphics Window", DisplayWidth( display, screen ) - width - 2*BORDER_WIDTH, 0, width, height ); x_map_window( w ); } /****************************************************************************/ /* Create a window in the top right corner of the screen with the given size in pixels */ init_window_pixels( width, height ) unsigned int width, height; /* window size. */ { int left, top; /* window position. */ char *window_name = "Simple Graphics Window"; x_init_graphics(); w = x_create_window( "Graphics Window", DisplayWidth( display, screen ) - width - 2*BORDER_WIDTH, 0, width, height ); x_map_window( w ); } /****************************************************************************/ Window get_simple_window() { return w; } /****************************************************************************/ draw_line( x1, y1, x2, y2, operation ) int x1, y1, x2, y2, operation; { x_draw_line( w, x1, y1, x2, y2, operation, 0 ); } /****************************************************************************/ draw_text( x, y, text, operation ) int x, y, operation; char *text; { x_draw_text( w, x, y, text, operation, 0 ); } /****************************************************************************/ flush_graphics() { x_flush(); } /****************************************************************************/ done_with_window() { x_kill_window ( w ); x_kill_graphics( w ); } /****************************************************************************/ clear_window() { x_clear_window( w ); } /****************************************************************************/ width_of_window() { return( x_window_width( w ) ); } /****************************************************************************/ height_of_window() { return( x_window_height( w ) ); } /****************************************************************************/ warp_mouse( x, y ) int x, y; { return x_warp_mouse( w, x, y ); } /****************************************************************************/ read_mouse( position ) int position[]; { return x_read_mouse( w, position ); } /****************************************************************************/