#include #include #include #include #include #include #define ENABLE_X11_SHARED_MEMORY_PIXMAPS #ifdef ENABLE_X11_SHARED_MEMORY_PIXMAPS #include #include #include #include static int UsingSharedMemoryPixmaps = 0; #endif #include #include #include #include #include #include "Gfx.h" #include "Vector.h" #include "Movie.h" #define NIL (0) #define EVENT_MASK ( ExposureMask | \ KeyPressMask | \ ButtonPressMask | \ ButtonReleaseMask | \ ButtonMotionMask) /*** global data ***/ static Display * dpy; static Visual vis; static unsigned int blackColor; static unsigned int whiteColor; static Window win; static XEvent e; static GC gc; static XImage * image; static void * offscreen = (void*)0; static int mydepth; static signed int startx, starty; static int width = 400, height = 400; /*** End of global data ***/ void redraw(void) { #ifdef ENABLE_X11_SHARED_MEMORY_PIXMAPS if( UsingSharedMemoryPixmaps ) { XShmPutImage( dpy, win, gc, image, 0, 0, 0, 0, width, height, 0 ); } else { #endif XPutImage ( dpy, win, gc, image, 0, 0, 0, 0, width, height ); #ifdef ENABLE_X11_SHARED_MEMORY_PIXMAPS } #endif } #ifdef ENABLE_X11_SHARED_MEMORY_PIXMAPS XShmSegmentInfo * shminfo; #endif void handle_signal( int sig ) { if( sig == SIGINT ) { #ifdef ENABLE_X11_SHARED_MEMORY_PIXMAPS shmdt( shminfo->shmaddr ); shmctl( shminfo->shmid, IPC_RMID, 0); #endif fputs( "Exit\n", stderr); exit( 0 ); } if( sig == SIGALRM ) { if( !Movie_checkframe( ) ) { Vector_paint(); redraw(); } } } /*** main() ***/ int main(int argc, char **argv) { char x11_keychar; /* gedrueckte taste */ KeySym key; /* metadaten beim tastendruecken */ int shallredraw = 0; Cursor curs; struct itimerval ticks; signal( SIGINT, handle_signal ); signal( SIGALRM, handle_signal ); Vector_init( 5, 300); #ifdef ENABLE_X11_SHARED_MEMORY_PIXMAPS shminfo = malloc( sizeof( shminfo )); #endif if( (dpy = XOpenDisplay(NIL)) == NULL ) { fputs( "Can't XOpenDisplay\n", stderr ); exit( 0 ); } win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, height, 0, blackColor, blackColor); /*** We want to get MapNotify events ***/ XSelectInput(dpy, win, StructureNotifyMask); /*** "Map" the window (that is, make it appear on the screen) ***/ XMapWindow(dpy, win); /*** Create a "Graphics Context" ***/ gc = XCreateGC(dpy, win, 0, NIL); /*** Wait for the MapNotify event ***/ for(;;) { XNextEvent(dpy, &e); if (e.type == MapNotify) break; } curs = XCreateFontCursor(dpy, 39); XDefineCursor( dpy, win, curs ); switch ( mydepth = DefaultDepth(dpy, DefaultScreen(dpy)) ) { case 24: case 32: break; default: fputs( "Screen Resolution Aua\n", stderr ); exit( 0 ); break; } #ifdef ENABLE_X11_SHARED_MEMORY_PIXMAPS { int major, minor; Bool pixmaps; if( XShmQueryVersion( dpy, &major, &minor, &pixmaps) && pixmaps ) { UsingSharedMemoryPixmaps = 1; if((image = XShmCreateImage( dpy, CopyFromParent, DefaultDepth(dpy, DefaultScreen(dpy)), ZPixmap, NULL, shminfo, width, height )) == NULL ) { fputs( "Can't XShmCreateImage\n", stderr ); exit( 0 ); } shminfo->shmid = shmget( IPC_PRIVATE, image->bytes_per_line * image->height, IPC_CREAT | 0777 ); shminfo->shmaddr = offscreen = image->data = shmat( shminfo->shmid, 0, 0); shminfo->readOnly= 0; if( XShmAttach( dpy, shminfo ) == NULL ) { fputs( "Can't XShmAttach\n", stderr ); exit( 0 ); } } else { #endif if( ( image = XCreateImage( dpy, CopyFromParent, DefaultDepth(dpy, DefaultScreen(dpy)), ZPixmap, 0, offscreen, width, height, 32, 0 ) ) == NULL ) { fputs( "Can't XCreateImage\n", stderr ); exit( 0 ); } #ifdef ENABLE_X11_SHARED_MEMORY_PIXMAPS } } #endif Gfx_init(offscreen, width, height); Vector_paint(); /*** draw application***/ redraw(); /*** select events ***/ XSelectInput(dpy, win, EVENT_MASK); ticks.it_value.tv_sec = 0; ticks.it_value.tv_usec = 1000 * 40; ticks.it_interval.tv_sec = 0; ticks.it_interval.tv_usec = 1000 * 40; setitimer( ITIMER_REAL, &ticks, (struct itimerval*)0); while(1) { XNextEvent(dpy, &e); switch(e.type) { case ConfigureNotify: /* fprintf(stderr, "window resized\n"); */ break; case Expose: if(e.xexpose.count == 0) { redraw(); } break; case MotionNotify: Vector_move( startx - ((XButtonEvent*)&e)->x, starty - ((XButtonEvent*)&e)->y ); shallredraw = 1; /* Fall through */ case ButtonPress: startx = ((XButtonEvent*)&e)->x; starty = ((XButtonEvent*)&e)->y; break; case KeyPress: /* fprintf(stderr, "got keypress-event\n"); */ /*** klarheit verschaffen ***/ XLookupString((XKeyEvent *)&e, &x11_keychar, 1, &key, NULL); switch((int)key) { case 'q': Vector_angle( -0.01, 0, 0); shallredraw = 1; break; case 'w': Vector_angle( +0.01, 0, 0); shallredraw = 1; break; case 'a': Vector_angle( 0, -0.01, 0); shallredraw = 1; break; case 's': Vector_angle( 0, +0.01, 0); shallredraw = 1; break; case 'y': Vector_angle( 0, 0, -0.01); shallredraw = 1; break; case 'x': Vector_angle( 0, 0, +0.01); shallredraw = 1; break; case 'c': Vector_reset( ); shallredraw = 1; break; default: break; } default: break; } if( shallredraw == 1 ) { Vector_paint(); redraw(); shallredraw = 0; } } #ifdef ENABLE_X11_SHARED_MEMORY_PIXMAPS XShmDetach( dpy, shminfo); #endif XDestroyImage( image ); #ifdef ENABLE_X11_SHARED_MEMORY_PIXMAPS shmdt( shminfo->shmaddr ); shmctl( shminfo->shmid, IPC_RMID, 0); #endif }