static bool allocate_xvimage(struct vo *vo, int foo) { struct xvctx *ctx = vo->priv; struct vo_x11_state *x11 = vo->x11; // align it for faster OSD rendering (draw_bmp.c swscale usage) int aligned_w = FFALIGN(ctx->image_width, 32); #if HAVE_SHM if (x11->display_is_local && XShmQueryExtension(x11->display)) { ctx->Shmem_Flag = 1; x11->ShmCompletionEvent = XShmGetEventBase(x11->display) + ShmCompletion; } else { ctx->Shmem_Flag = 0; MP_INFO(vo, "Shared memory not supported\nReverting to normal Xv.\n"); } if (ctx->Shmem_Flag) { ctx->xvimage[foo] = (XvImage *) XvShmCreateImage(x11->display, ctx->xv_port, ctx->xv_format, NULL, aligned_w, ctx->image_height, &ctx->Shminfo[foo]); if (!ctx->xvimage[foo]) return false; ctx->Shminfo[foo].shmid = shmget(IPC_PRIVATE, ctx->xvimage[foo]->data_size, IPC_CREAT | 0777); ctx->Shminfo[foo].shmaddr = (char *) shmat(ctx->Shminfo[foo].shmid, 0, 0); if (ctx->Shminfo[foo].shmaddr == (void *)-1) return false; ctx->Shminfo[foo].readOnly = False; ctx->xvimage[foo]->data = ctx->Shminfo[foo].shmaddr; XShmAttach(x11->display, &ctx->Shminfo[foo]); XSync(x11->display, False); shmctl(ctx->Shminfo[foo].shmid, IPC_RMID, 0); } else #endif { ctx->xvimage[foo] = (XvImage *) XvCreateImage(x11->display, ctx->xv_port, ctx->xv_format, NULL, aligned_w, ctx->image_height); if (!ctx->xvimage[foo]) return false; ctx->xvimage[foo]->data = av_malloc(ctx->xvimage[foo]->data_size); if (!ctx->xvimage[foo]->data) return false; XSync(x11->display, False); } struct mp_image img = get_xv_buffer(vo, foo); img.w = aligned_w; mp_image_clear(&img, 0, 0, img.w, img.h); return true; }
void wsCreateImage( wsTWindow * win,int Width,int Height ) { int CompletionType = -1; if ( wsUseXShm ) { CompletionType=XShmGetEventBase( wsDisplay ) + ShmCompletion; win->xImage=XShmCreateImage( wsDisplay,win->VisualInfo.visual, win->VisualInfo.depth,ZPixmap,NULL,&win->Shminfo,Width,Height ); if ( win->xImage == NULL ) { mp_msg( MSGT_GPLAYER,MSGL_FATAL,MSGTR_WS_ShmError ); exit( 0 ); } win->Shminfo.shmid=shmget( IPC_PRIVATE,win->xImage->bytes_per_line * win->xImage->height,IPC_CREAT|0777 ); if ( win->Shminfo.shmid < 0 ) { XDestroyImage( win->xImage ); mp_msg( MSGT_GPLAYER,MSGL_FATAL,MSGTR_WS_ShmError ); exit( 0 ); } win->Shminfo.shmaddr=(char *)shmat( win->Shminfo.shmid,0,0 ); if ( win->Shminfo.shmaddr == ((char *) -1) ) { XDestroyImage( win->xImage ); if ( win->Shminfo.shmaddr != ((char *) -1) ) shmdt( win->Shminfo.shmaddr ); mp_msg( MSGT_GPLAYER,MSGL_FATAL,MSGTR_WS_ShmError ); exit( 0 ); } win->xImage->data=win->Shminfo.shmaddr; win->Shminfo.readOnly=0; XShmAttach( wsDisplay,&win->Shminfo ); XSync(wsDisplay, False); shmctl( win->Shminfo.shmid,IPC_RMID,0 ); } else { win->xImage=XCreateImage( wsDisplay,win->VisualInfo.visual,win->VisualInfo.depth, ZPixmap,0,0,Width,Height, (wsDepthOnScreen == 3) ? 32 : wsDepthOnScreen, 0 ); if ( ( win->xImage->data=malloc( win->xImage->bytes_per_line * win->xImage->height ) ) == NULL ) { mp_msg( MSGT_GPLAYER,MSGL_FATAL,MSGTR_WS_NotEnoughMemoryDrawBuffer ); exit( 0 ); } } win->ImageData=(unsigned char *)win->xImage->data; win->ImageDataw=(unsigned short int *)win->xImage->data; win->ImageDatadw=(unsigned int *)win->xImage->data; }
static int init_xshm_stuff(struct DriverInstance* sh, char* error_text, int text_len) { sh->completion_type = XShmGetEventBase(sh->display) + ShmCompletion; sh->event_pending = 0; /* allocate shared memory */ // changed flags from 0777 to 0666, see // http://lists.apple.com/archives/unix-porting/2004/Apr/msg00081.html sh->shminfo.shmid = shmget (IPC_PRIVATE, MAX_RES_X * MAX_RES_Y * 4, 0666 | IPC_CREAT); if (sh->shminfo.shmid == -1) { snprintf(error_text, text_len, "shmget() failed, errno=%i!", errno); return 0; } /* attach shared memory to our process */ sh->shminfo.shmaddr = shmat (sh->shminfo.shmid, 0, 0); if (sh->shminfo.shmaddr == (void*) -1) // TODO { shmctl (sh->shminfo.shmid, IPC_RMID, 0); snprintf(error_text, text_len, "shmat() failed!"); return 0; } /* the server is not allowed to write to the shared memory */ sh->shminfo.readOnly = True; /* tell the server to attach to the shared memory */ if (XShmAttach(sh->display, &sh->shminfo) != True) { shmdt (sh->shminfo.shmaddr); shmctl (sh->shminfo.shmid, IPC_RMID, 0); snprintf(error_text, text_len, "Server would not attach to shared memory!"); return 0; } return 1; }
int bg_x11_window_check_shm(Display * dpy, int * completion_type) { #if 0 return 0; #else int major; int minor; Bool pixmaps; int ret; if ((XShmQueryVersion (dpy, &major, &minor, &pixmaps) == 0) || (major < 1) || ((major == 1) && (minor < 1))) ret = 0; else ret = 1; if(ret) *completion_type = XShmGetEventBase(dpy) + ShmCompletion; return ret; #endif }
static void getMyXImage(void) { #ifdef HAVE_SHM if (mLocalDisplay && XShmQueryExtension(mDisplay)) Shmem_Flag = 1; else { Shmem_Flag = 0; mp_msg(MSGT_VO, MSGL_WARN, "Shared memory not supported\nReverting to normal Xlib\n"); } if (Shmem_Flag) CompletionType = XShmGetEventBase(mDisplay) + ShmCompletion; if (Shmem_Flag) { myximage = XShmCreateImage(mDisplay, vinfo.visual, depth, ZPixmap, NULL, &Shminfo[0], image_width, image_height); if (myximage == NULL) { mp_msg(MSGT_VO, MSGL_WARN, "Shared memory error,disabling ( Ximage error )\n"); goto shmemerror; } Shminfo[0].shmid = shmget(IPC_PRIVATE, myximage->bytes_per_line * myximage->height, IPC_CREAT | 0777); if (Shminfo[0].shmid < 0) { XDestroyImage(myximage); mp_msg(MSGT_VO, MSGL_V, "%s\n", strerror(errno)); //perror( strerror( errno ) ); mp_msg(MSGT_VO, MSGL_WARN, "Shared memory error,disabling ( seg id error )\n"); goto shmemerror; } Shminfo[0].shmaddr = (char *) shmat(Shminfo[0].shmid, 0, 0); if (Shminfo[0].shmaddr == ((char *) -1)) { XDestroyImage(myximage); if (Shminfo[0].shmaddr != ((char *) -1)) shmdt(Shminfo[0].shmaddr); mp_msg(MSGT_VO, MSGL_WARN, "Shared memory error,disabling ( address error )\n"); goto shmemerror; } myximage->data = Shminfo[0].shmaddr; ImageData = (unsigned char *) myximage->data; Shminfo[0].readOnly = False; XShmAttach(mDisplay, &Shminfo[0]); XSync(mDisplay, False); if (gXErrorFlag) { XDestroyImage(myximage); shmdt(Shminfo[0].shmaddr); mp_msg(MSGT_VO, MSGL_WARN, "Shared memory error,disabling.\n"); gXErrorFlag = 0; goto shmemerror; } else shmctl(Shminfo[0].shmid, IPC_RMID, 0); { static int firstTime = 1; if (firstTime) { mp_msg(MSGT_VO, MSGL_V, "Sharing memory.\n"); firstTime = 0; } } } else { shmemerror: Shmem_Flag = 0; #endif myximage = XCreateImage(mDisplay, vinfo.visual, depth, ZPixmap, 0, NULL, image_width, image_height, 8, 0); ImageDataOrig = malloc(myximage->bytes_per_line * image_height + 32); myximage->data = ImageDataOrig + 16 - ((long)ImageDataOrig & 15); memset(myximage->data, 0, myximage->bytes_per_line * image_height); ImageData = myximage->data; #ifdef HAVE_SHM } #endif }
static void getMyXImage(struct priv *p) { struct vo *vo = p->vo; #ifdef HAVE_SHM if (vo->x11->display_is_local && XShmQueryExtension(vo->x11->display)) p->Shmem_Flag = 1; else { p->Shmem_Flag = 0; mp_msg(MSGT_VO, MSGL_WARN, "Shared memory not supported\nReverting to normal Xlib\n"); } if (p->Shmem_Flag) p->CompletionType = XShmGetEventBase(vo->x11->display) + ShmCompletion; if (p->Shmem_Flag) { p->myximage = XShmCreateImage(vo->x11->display, p->vinfo.visual, p->depth, ZPixmap, NULL, &p->Shminfo[0], p->image_width, p->image_height); if (p->myximage == NULL) { mp_msg(MSGT_VO, MSGL_WARN, "Shared memory error,disabling ( Ximage error )\n"); goto shmemerror; } p->Shminfo[0].shmid = shmget(IPC_PRIVATE, p->myximage->bytes_per_line * p->myximage->height, IPC_CREAT | 0777); if (p->Shminfo[0].shmid < 0) { XDestroyImage(p->myximage); mp_msg(MSGT_VO, MSGL_V, "%s\n", strerror(errno)); //perror( strerror( errno ) ); mp_msg(MSGT_VO, MSGL_WARN, "Shared memory error,disabling ( seg id error )\n"); goto shmemerror; } p->Shminfo[0].shmaddr = (char *) shmat(p->Shminfo[0].shmid, 0, 0); if (p->Shminfo[0].shmaddr == ((char *) -1)) { XDestroyImage(p->myximage); if (p->Shminfo[0].shmaddr != ((char *) -1)) shmdt(p->Shminfo[0].shmaddr); mp_msg(MSGT_VO, MSGL_WARN, "Shared memory error,disabling ( address error )\n"); goto shmemerror; } p->myximage->data = p->Shminfo[0].shmaddr; p->ImageData = (unsigned char *) p->myximage->data; p->Shminfo[0].readOnly = False; XShmAttach(vo->x11->display, &p->Shminfo[0]); XSync(vo->x11->display, False); if (p->gXErrorFlag) { XDestroyImage(p->myximage); shmdt(p->Shminfo[0].shmaddr); mp_msg(MSGT_VO, MSGL_WARN, "Shared memory error,disabling.\n"); p->gXErrorFlag = 0; goto shmemerror; } else shmctl(p->Shminfo[0].shmid, IPC_RMID, 0); if (!p->firstTime) { mp_msg(MSGT_VO, MSGL_V, "Sharing memory.\n"); p->firstTime = 1; } } else { shmemerror: p->Shmem_Flag = 0; #endif p->myximage = XCreateImage(vo->x11->display, p->vinfo.visual, p->depth, ZPixmap, 0, NULL, p->image_width, p->image_height, 8, 0); p->ImageDataOrig = malloc(p->myximage->bytes_per_line * p->image_height + 32); p->myximage->data = p->ImageDataOrig + 16 - ((long)p->ImageDataOrig & 15); memset(p->myximage->data, 0, p->myximage->bytes_per_line * p->image_height); p->ImageData = p->myximage->data; #ifdef HAVE_SHM } #endif }
void I_InitGraphics(void) { const char* displayname = NULL; int n; int pnum; int x=0; int y=0; { static int firsttime=1; if (!firsttime) { return; } firsttime = 0; } { // Check for screen enlargement char str[3] = { '-', 0, 0 }; for (n=1; n<4; n++) { str[1] = n + '0'; if (M_CheckParm(str)) multiply = n; } } X_width = SCREENWIDTH * multiply; X_height = SCREENHEIGHT * multiply; // check for command-line geometry if ( (pnum=M_CheckParm("-geom")) ? 1 : (pnum=M_CheckParm("-geometry"))) if (pnum+1 < myargc) { // check parm given // warning: char format, different type arg char xsign=' '; char ysign=' '; const char* pg = myargv[pnum+1]; pg += strcspn(pg, "+-"); // warning: char format, different type arg 3,5 n = sscanf(pg, "%c%d%c%d", &xsign, &x, &ysign, &y); if (n==2) x = y = 0; else if (n==4) { if (xsign == '-') x = -x; if (ysign == '-') y = -y; } else fprintf(stderr, "I_InitGraphics: bad -geom offsets \"%s\"\n", pg); } // check for command-line display name if ( (pnum=M_CheckParm("-disp")) ) // suggest parentheses around assignment displayname = myargv[pnum+1]; // CPhipps - support more standard -display param if ( (pnum=M_CheckParm("-display")) ) // ditto displayname = myargv[pnum+1]; // CPhipps - and -displayname as for xterm if ( (pnum=M_CheckParm("-displayname")) ) // ditto displayname = myargv[pnum+1]; // open the display if (!(X_display = XOpenDisplay(displayname))) { if (displayname) I_Error("Could not open display [%s]", displayname); else I_Error("Could not open display (DISPLAY=[%s])", getenv("DISPLAY")); } // use the default visual X_screen = DefaultScreen(X_display); X_deletewin = XInternAtom(X_display, "WM_DELETE_WINDOW", False); // check for the MITSHM extension // even if it's available, make sure it's a local connection lprintf(LO_INFO,"I_InitGraphics:"); #ifdef HAVE_LIBXXF86DGA if ((doDga = (M_CheckParm("-dga") && XF86DGAQueryExtension(X_display, &n, &n)) )) { lprintf(LO_INFO,"I_InitGraphics: found DGA extension\n"); if (M_CheckParm("-noaccel") || (X_opt & 1)) doDga = false; else lprintf(LO_INFO, "(using DGA)"); } else #endif #ifdef HAVE_LIBXEXT if ((doShm = XShmQueryExtension(X_display))) { if (!displayname) displayname = getenv("DISPLAY"); if (displayname) { // CPhipps - don't modify the original string, please. // - oops my code here was totally wrong // I have no idea exactly what should go here. if (M_CheckParm("-noaccel") || (X_opt & 1)) doShm = false; else lprintf(LO_INFO, "(using MITShm)"); } } else #endif if (devparm) fprintf(stderr, "No MITShm extension in server"); if (devparm) fputc('\n', stderr); if ((X_visual = I_FindMode(X_screen)) == NULL) I_Error("Unsupported visual"); // create the colormap X_cmap = XCreateColormap(X_display, RootWindow(X_display, X_screen), X_visual, true_color ? AllocNone : AllocAll); #ifdef HAVE_LIBXXF86DGA /* setup for DGA */ if(doDga) { char *fb; X_mainWindow=RootWindow(X_display, X_screen); XF86DGAGetViewPortSize(X_display, X_screen, &DGA_width, &DGA_height); XF86DGAGetVideo(X_display, X_screen, &fb, &DGA_real_width, &DGA_pagelen, &DGA_memlen); fprintf(stderr, "I_InitGraphics: DGA reports %dx%d scan=%d page=%d mem=%d\n", DGA_width,DGA_height,DGA_real_width,DGA_pagelen,DGA_memlen); out_buffer=(void*)fb; XF86DGADirectVideo(X_display, X_screen, XF86DGADirectGraphics); XF86DGASetVidPage(X_display, X_screen, 0); XF86DGAForkApp(X_screen); XSelectInput(X_display, X_mainWindow, KeyPressMask | KeyReleaseMask); fprintf(stderr,"DGA framebuffer @%p\n",fb); memset(fb,0,102400); } #endif #ifdef HAVE_LIBXXF86DGA if(!doDga) #endif { // setup attributes for main window unsigned long attribmask; XSetWindowAttributes attribs; attribmask = CWEventMask | CWColormap | CWBorderPixel; attribs.event_mask = KeyPressMask | KeyReleaseMask #ifdef MONITOR_VISIBILITY | VisibilityChangeMask #endif | ExposureMask; attribs.colormap = X_cmap; attribs.border_pixel = 0; // create the main window X_mainWindow = XCreateWindow( X_display, RootWindow(X_display, X_screen), x, y, X_width, X_height, 0, // borderwidth X_bpp, // depth InputOutput, X_visual, attribmask, &attribs ); } #ifdef HAVE_LIBXXF86DGA if(!doDga) #endif { XClassHint c_hint; XTextProperty x_name; XSizeHints s_hint; XWMHints wm_hint; char lcase_buf[10], ucase_buf[10]; char* str; strcpy(str = lcase_buf, lcase_lxdoom); XStringListToTextProperty(&str, 1, &x_name); s_hint.flags = PSize | PMinSize | PMaxSize; s_hint.min_width = s_hint.max_width = s_hint.base_width = X_width; s_hint.min_height = s_hint.max_height = s_hint.base_height = X_height; wm_hint.input = True; wm_hint.window_group = X_mainWindow; wm_hint.flags = InputHint | WindowGroupHint; strcpy(c_hint.res_name = lcase_buf, lcase_lxdoom); strcpy(c_hint.res_class = ucase_buf, ucase_lxdoom); XSetWMProtocols(X_display, X_mainWindow, &X_deletewin, 1); XSetWMProperties(X_display, X_mainWindow, &x_name, &x_name, (char**)myargv, myargc, &s_hint, &wm_hint, &c_hint); XFlush(X_display); } #ifdef HAVE_LIBXXF86DGA if(!doDga) #endif // Hide pointer while over this window XDefineCursor(X_display, X_mainWindow, I_XCreateNullCursor( X_display, X_mainWindow ) ); { // create the GC XGCValues xgcvalues; int valuemask; valuemask = GCGraphicsExposures; xgcvalues.graphics_exposures = False; X_gc = XCreateGC(X_display, X_mainWindow, valuemask, &xgcvalues); } #ifdef HAVE_LIBXXF86DGA if(!doDga) #endif { // name the window XStoreName(X_display, X_mainWindow, "lxdoom"); // map the window XMapWindow(X_display, X_mainWindow); } // wait until it is OK to draw #ifdef HAVE_LIBXXF86DGA if(!doDga) #endif do { XNextEvent(X_display, &X_event); } while (!(X_event.type == Expose && !X_event.xexpose.count)); #ifdef HAVE_LIBXXF86DGA if(doDga) {} else #endif #ifdef HAVE_LIBXEXT if (doShm) { X_shmeventtype = XShmGetEventBase(X_display) + ShmCompletion; // create the image image = XShmCreateImage( X_display, X_visual, X_bpp, ZPixmap, 0, &X_shminfo, X_width, X_height ); I_XShmGrabSharedMemory(image->bytes_per_line * image->height); if (!(out_buffer = (pval*)image->data)) { perror(""); I_Error("shmat() failed in I_InitGraphics()"); } // get the X server to attach to it if (!XShmAttach(X_display, &X_shminfo)) I_Error("XShmAttach() failed in InitGraphics()"); if (!expand_buffer) { // Render directly into MitSHM memory Z_Free(screens[0]); screens[0] = (unsigned char *) (image->data); } } else #endif { if (!expand_buffer) { // Very efficient, render directly into image out_buffer = (pval*)screens[0]; } else { // Will have to enlarge from rendering buffer // into image buffer out_buffer = (pval*)malloc (X_width * X_height * BYTESPP); } { /* hack to enable 15 bpp usage */ int bpp=X_bpp; if(bpp==15)bpp=16; image=XCreateImage( X_display, X_visual, X_bpp, ZPixmap, 0, (char*)out_buffer, X_width, X_height, bpp, 0); #ifdef NOT_NOW image=XCreateImage( X_display, X_visual, X_bpp, ZPixmap, 0, (char*)out_buffer, X_width, X_height, X_bpp, 0); #endif } if (!image) I_Error("XCreateImage: failed to create image %dx%d %d bpp", X_width, X_height, X_bpp); } atexit(I_ShutdownGraphics); I_XInitInputs(); }
static PyObject * tkwin_ShmCompletionEventType(TkWinObject * self, PyObject *args) { return PyInt_FromLong(XShmGetEventBase(Tk_Display(self->tkwin)) + ShmCompletion); }
int main (int argc, char* argv[]) { int yuv_width = 1024; int yuv_height = 768; int xv_port = -1; int adaptor, encodings, attributes, formats; int i, j, ret, p, _d, _w, _h; long secsb, secsa, frames; XvAdaptorInfo *ai; XvEncodingInfo *ei; XvAttribute *at; XvImageFormatValues *fo; XvImage *yuv_image; #define GUID_YUV12_PLANAR 0x32315659 unsigned int p_version, p_release, p_request_base, p_event_base, p_error_base; int p_num_adaptors; Display *dpy; Window window, _dw; XSizeHints hint; XSetWindowAttributes xswa; XVisualInfo vinfo; int screen; unsigned long mask; XEvent event; GC gc; /** for shm */ int shmem_flag = 0; XShmSegmentInfo yuv_shminfo; int CompletionType; printf("starting up video testapp...\n\n"); adaptor = -1; dpy = XOpenDisplay(NULL); if (dpy == NULL) { printf("Cannot open Display.\n"); exit (-1); } screen = DefaultScreen(dpy); /** find best display */ if (XMatchVisualInfo(dpy, screen, 24, TrueColor, &vinfo)) { printf(" found 24bit TrueColor\n"); } else if (XMatchVisualInfo(dpy, screen, 16, TrueColor, &vinfo)) { printf(" found 16bit TrueColor\n"); } else if (XMatchVisualInfo(dpy, screen, 15, TrueColor, &vinfo)) { printf(" found 15bit TrueColor\n"); } else if (XMatchVisualInfo(dpy, screen, 8, PseudoColor, &vinfo)) { printf(" found 8bit PseudoColor\n"); } else if (XMatchVisualInfo(dpy, screen, 8, GrayScale, &vinfo)) { printf(" found 8bit GrayScale\n"); } else if (XMatchVisualInfo(dpy, screen, 8, StaticGray, &vinfo)) { printf(" found 8bit StaticGray\n"); } else if (XMatchVisualInfo(dpy, screen, 1, StaticGray, &vinfo)) { printf(" found 1bit StaticGray\n"); } else { printf("requires 16 bit display\n"); exit (-1); } CompletionType = -1; hint.x = 1; hint.y = 1; hint.width = yuv_width; hint.height = yuv_height; hint.flags = PPosition | PSize; xswa.colormap = XCreateColormap(dpy, DefaultRootWindow(dpy), vinfo.visual, AllocNone); xswa.event_mask = StructureNotifyMask | ExposureMask; xswa.background_pixel = 0; xswa.border_pixel = 0; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; window = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, yuv_width, yuv_height, 0, vinfo.depth, InputOutput, vinfo.visual, mask, &xswa); XStoreName(dpy, window, "XV"); XSetIconName(dpy, window, "XV"); XSelectInput(dpy, window, StructureNotifyMask); /** Map window */ XMapWindow(dpy, window); /** Wait for map. */ do { XNextEvent(dpy, &event); } while (event.type != MapNotify || event.xmap.event != window); if (XShmQueryExtension(dpy)) shmem_flag = 1; if (!shmem_flag) { printf("no shmem available.\n"); exit (-1); } if (shmem_flag==1) CompletionType = XShmGetEventBase(dpy) + ShmCompletion; /**--------------------------------- XV ------------------------------------*/ printf("beginning to parse the Xvideo extension...\n\n"); /** query and print Xvideo properties */ ret = XvQueryExtension(dpy, &p_version, &p_release, &p_request_base, &p_event_base, &p_error_base); if (ret != Success) { if (ret == XvBadExtension) printf("XvBadExtension returned at XvQueryExtension.\n"); else if (ret == XvBadAlloc) printf("XvBadAlloc returned at XvQueryExtension.\n"); else printf("other error happened at XvQueryExtension.\n"); } printf("========================================\n"); printf("XvQueryExtension returned the following:\n"); printf("p_version : %u\n", p_version); printf("p_release : %u\n", p_release); printf("p_request_base : %u\n", p_request_base); printf("p_event_base : %u\n", p_event_base); printf("p_error_base : %u\n", p_error_base); printf("========================================\n"); ret = XvQueryAdaptors(dpy, DefaultRootWindow(dpy), &p_num_adaptors, &ai); if (ret != Success) { if (ret == XvBadExtension) printf("XvBadExtension returned at XvQueryExtension.\n"); else if (ret == XvBadAlloc) printf("XvBadAlloc returned at XvQueryExtension.\n"); else printf("other error happaned at XvQueryAdaptors.\n"); } printf("=======================================\n"); printf("XvQueryAdaptors returned the following:\n"); printf("%d adaptors available.\n", p_num_adaptors); for (i = 0; i < p_num_adaptors; i++) { printf(" name: %s\n" " type: %s%s%s%s%s\n" " ports: %ld\n" " first port: %ld\n", ai[i].name, (ai[i].type & XvInputMask) ? "input | " : "", (ai[i].type & XvOutputMask) ? "output | " : "", (ai[i].type & XvVideoMask) ? "video | " : "", (ai[i].type & XvStillMask) ? "still | " : "", (ai[i].type & XvImageMask) ? "image | " : "", ai[i].num_ports, ai[i].base_id); xv_port = ai[i].base_id; printf("adaptor %d ; format list:\n", i); for (j = 0; j < ai[i].num_formats; j++) { printf(" depth=%d, visual=%ld\n", ai[i].formats[j].depth, ai[i].formats[j].visual_id); } for (p = ai[i].base_id; p < ai[i].base_id+ai[i].num_ports; p++) { printf(" encoding list for port %d\n", p); if (XvQueryEncodings(dpy, p, &encodings, &ei) != Success) { printf("XvQueryEncodings failed.\n"); continue; } for (j = 0; j < encodings; j++) { printf(" id=%ld, name=%s, size=%ldx%ld, numerator=%d, denominator=%d\n", ei[j].encoding_id, ei[j].name, ei[j].width, ei[j].height, ei[j].rate.numerator, ei[j].rate.denominator); } XvFreeEncodingInfo(ei); printf(" attribute list for port %d\n", p); at = XvQueryPortAttributes(dpy, p, &attributes); for (j = 0; j < attributes; j++) { printf(" name: %s\n" " flags: %s%s\n" " min_color: %i\n" " max_color: %i\n", at[j].name, (at[j].flags & XvGettable) ? " get" : "", (at[j].flags & XvSettable) ? " set" : "", at[j].min_value, at[j].max_value); } if (at) XFree(at); printf(" image format list for port %d\n", p); fo = XvListImageFormats(dpy, p, &formats); for (j = 0; j < formats; j++) { printf(" 0x%x (%4.4s) %s\n", fo[j].id, (char *)&fo[j].id, (fo[j].format == XvPacked) ? "packed" : "planar"); } if (fo) XFree(fo); } printf("\n"); } if (p_num_adaptors > 0) XvFreeAdaptorInfo(ai); if (xv_port == -1) exit (0); gc = XCreateGC(dpy, window, 0, 0); yuv_image = XvShmCreateImage(dpy, xv_port, GUID_YUV12_PLANAR, 0, yuv_width, yuv_height, &yuv_shminfo); yuv_shminfo.shmid = shmget(IPC_PRIVATE, yuv_image->data_size, IPC_CREAT | 0777); yuv_shminfo.shmaddr = yuv_image->data = shmat(yuv_shminfo.shmid, 0, 0); yuv_shminfo.readOnly = False; if (!XShmAttach(dpy, &yuv_shminfo)) { printf("XShmAttach failed !\n"); exit (-1); } for (i = 0; i < yuv_image->height; i++) { for (j = 0; j < yuv_image->width; j++) { yuv_image->data[yuv_image->width*i + j] = i*j; } } printf("%d\n", yuv_image->data_size); int joe = 0; while (1) { frames = secsa = secsb = 0; time(&secsa); while (frames < 200) { XGetGeometry(dpy, window, &_dw, &_d, &_d, &_w, &_h, &_d, &_d); for (i = 0; i < yuv_image->height * 1.5; i++) { for (j = 0; j < yuv_image->width; j++) { yuv_image->data[yuv_image->width*i + j] = (i + j + joe / 5); } } XvShmPutImage(dpy, xv_port, window, gc, yuv_image, 0, 0, yuv_image->width, yuv_image->height, 0, 0, _w, _h, True); /* XFlush(dpy); */ joe++; frames++; } time(&secsb); printf("%ld frames in %ld seconds; %.4f fps\n", frames, secsb-secsa, (double) frames/(secsb-secsa)); } return 0; }
/** The initialization function * This function opens the frame buffer device and allocates memory for display * also it finds the frame buffer supported display formats */ OMX_ERRORTYPE omx_xvideo_sink_component_Init(OMX_COMPONENTTYPE *openmaxStandComp) { omx_xvideo_sink_component_PrivateType* omx_xvideo_sink_component_Private = openmaxStandComp->pComponentPrivate; omx_xvideo_sink_component_PortType* pPort = (omx_xvideo_sink_component_PortType *) omx_xvideo_sink_component_Private->ports[OMX_BASE_SINK_INPUTPORT_INDEX]; int yuv_width = pPort->sPortParam.format.video.nFrameWidth; int yuv_height = pPort->sPortParam.format.video.nFrameHeight; unsigned int err,i; omx_xvideo_sink_component_Private->dpy = XOpenDisplay(NULL); omx_xvideo_sink_component_Private->screen = DefaultScreen(omx_xvideo_sink_component_Private->dpy); XGetWindowAttributes(omx_xvideo_sink_component_Private->dpy, DefaultRootWindow(omx_xvideo_sink_component_Private->dpy), &omx_xvideo_sink_component_Private->attribs); XMatchVisualInfo(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->screen, omx_xvideo_sink_component_Private->attribs.depth, TrueColor, & omx_xvideo_sink_component_Private->vinfo); omx_xvideo_sink_component_Private->wmDeleteWindow = XInternAtom(omx_xvideo_sink_component_Private->dpy, "WM_DELETE_WINDOW", False); omx_xvideo_sink_component_Private->hint.x = 1; omx_xvideo_sink_component_Private->hint.y = 1; omx_xvideo_sink_component_Private->hint.width = yuv_width; omx_xvideo_sink_component_Private->hint.height = yuv_height; omx_xvideo_sink_component_Private->hint.flags = PPosition | PSize; omx_xvideo_sink_component_Private->xswa.colormap = XCreateColormap(omx_xvideo_sink_component_Private->dpy, DefaultRootWindow(omx_xvideo_sink_component_Private->dpy), omx_xvideo_sink_component_Private->vinfo.visual, AllocNone); omx_xvideo_sink_component_Private->xswa.event_mask = StructureNotifyMask | ExposureMask; omx_xvideo_sink_component_Private->xswa.background_pixel = 0; omx_xvideo_sink_component_Private->xswa.border_pixel = 0; omx_xvideo_sink_component_Private->window = XCreateWindow(omx_xvideo_sink_component_Private->dpy, DefaultRootWindow(omx_xvideo_sink_component_Private->dpy), 0, 0, yuv_width, yuv_height, 0, omx_xvideo_sink_component_Private->vinfo.depth, InputOutput, omx_xvideo_sink_component_Private->vinfo.visual, CWBackPixel | CWBorderPixel | CWColormap | CWEventMask, &omx_xvideo_sink_component_Private->xswa); XSelectInput(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->window, StructureNotifyMask); XSetStandardProperties(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->window, "xvcam", "xvcam", None, NULL, 0, &omx_xvideo_sink_component_Private->hint); XSetWMProtocols(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->window, &omx_xvideo_sink_component_Private->wmDeleteWindow, 1); XMapWindow(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->window); if (XShmQueryExtension(omx_xvideo_sink_component_Private->dpy)) omx_xvideo_sink_component_Private->CompletionType = XShmGetEventBase(omx_xvideo_sink_component_Private->dpy) + ShmCompletion; else return OMX_ErrorUndefined; if (Success != XvQueryExtension(omx_xvideo_sink_component_Private->dpy, &omx_xvideo_sink_component_Private->ver, &omx_xvideo_sink_component_Private->rel, &omx_xvideo_sink_component_Private->req, &omx_xvideo_sink_component_Private->ev, &err)) fprintf(stderr, "Couldn't do Xv stuff\n"); if (Success != XvQueryAdaptors(omx_xvideo_sink_component_Private->dpy, DefaultRootWindow(omx_xvideo_sink_component_Private->dpy), &omx_xvideo_sink_component_Private->adapt, &omx_xvideo_sink_component_Private->ai)) fprintf(stderr, "Couldn't do Xv stuff\n"); for (i = 0; i < (int) omx_xvideo_sink_component_Private->adapt; i++) { omx_xvideo_sink_component_Private->xv_port = omx_xvideo_sink_component_Private->ai[i].base_id; } if (omx_xvideo_sink_component_Private->adapt > 0) XvFreeAdaptorInfo(omx_xvideo_sink_component_Private->ai); omx_xvideo_sink_component_Private->gc = XCreateGC(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->window, 0, 0); omx_xvideo_sink_component_Private->yuv_image = XvShmCreateImage(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->xv_port, GUID_I420_PLANAR, 0, yuv_width, yuv_height, &omx_xvideo_sink_component_Private->yuv_shminfo); omx_xvideo_sink_component_Private->yuv_shminfo.shmid = shmget(IPC_PRIVATE, omx_xvideo_sink_component_Private->yuv_image->data_size, IPC_CREAT | 0777); omx_xvideo_sink_component_Private->yuv_shminfo.shmaddr = (char *) shmat(omx_xvideo_sink_component_Private->yuv_shminfo.shmid, 0, 0); omx_xvideo_sink_component_Private->yuv_image->data = omx_xvideo_sink_component_Private->yuv_shminfo.shmaddr; omx_xvideo_sink_component_Private->yuv_shminfo.readOnly = False; if (!XShmAttach(omx_xvideo_sink_component_Private->dpy, &omx_xvideo_sink_component_Private->yuv_shminfo)) { printf("XShmAttach go boom boom!\n"); return OMX_ErrorUndefined; } omx_xvideo_sink_component_Private->old_time = 0; omx_xvideo_sink_component_Private->new_time = 0; omx_xvideo_sink_component_Private->bIsXVideoInit = OMX_TRUE; /*Signal XVideo Initialized*/ tsem_up(omx_xvideo_sink_component_Private->xvideoSyncSem); return OMX_ErrorNone; }
static bool getMyXImage(struct priv *p, int foo) { struct vo *vo = p->vo; #if HAVE_SHM && HAVE_XEXT if (vo->x11->display_is_local && XShmQueryExtension(vo->x11->display)) { p->Shmem_Flag = 1; vo->x11->ShmCompletionEvent = XShmGetEventBase(vo->x11->display) + ShmCompletion; } else { p->Shmem_Flag = 0; MP_WARN(vo, "Shared memory not supported\nReverting to normal Xlib\n"); } if (p->Shmem_Flag) { p->myximage[foo] = XShmCreateImage(vo->x11->display, p->vinfo.visual, p->depth, ZPixmap, NULL, &p->Shminfo[foo], p->image_width, p->image_height); if (p->myximage[foo] == NULL) { MP_WARN(vo, "Shared memory error,disabling ( Ximage error )\n"); goto shmemerror; } p->Shminfo[foo].shmid = shmget(IPC_PRIVATE, p->myximage[foo]->bytes_per_line * p->myximage[foo]->height, IPC_CREAT | 0777); if (p->Shminfo[foo].shmid < 0) { XDestroyImage(p->myximage[foo]); MP_WARN(vo, "Shared memory error,disabling ( seg id error )\n"); goto shmemerror; } p->Shminfo[foo].shmaddr = (char *) shmat(p->Shminfo[foo].shmid, 0, 0); if (p->Shminfo[foo].shmaddr == ((char *) -1)) { XDestroyImage(p->myximage[foo]); MP_WARN(vo, "Shared memory error,disabling ( address error )\n"); goto shmemerror; } p->myximage[foo]->data = p->Shminfo[foo].shmaddr; p->Shminfo[foo].readOnly = False; XShmAttach(vo->x11->display, &p->Shminfo[foo]); XSync(vo->x11->display, False); shmctl(p->Shminfo[foo].shmid, IPC_RMID, 0); } else { shmemerror: p->Shmem_Flag = 0; #endif MP_VERBOSE(vo, "Not using SHM.\n"); p->myximage[foo] = XCreateImage(vo->x11->display, p->vinfo.visual, p->depth, ZPixmap, 0, NULL, p->image_width, p->image_height, 8, 0); if (!p->myximage[foo]) { MP_WARN(vo, "could not allocate image"); return false; } p->myximage[foo]->data = calloc(1, p->myximage[foo]->bytes_per_line * p->image_height + 32); #if HAVE_SHM && HAVE_XEXT } #endif return true; }
static Bool init_x11( char * error_buf ) { /*XXX*/ /* Namely, support for -display host:0.0 etc. */ XrmQuark common_quarks_list[20]; /*XXX change number of elements if necessary */ XrmQuarkList ql = common_quarks_list; XGCValues gcv; char *common_quarks = "String." "Blinkinvisibletime.blinkinvisibletime." "Blinkvisibletime.blinkvisibletime." "Clicktimeframe.clicktimeframe." "Doubleclicktimeframe.doubleclicktimeframe." "Wheeldown.wheeldown." "Wheelup.wheelup." "Submenudelay.submenudelay." "Scrollfirst.scrollfirst." "Scrollnext.scrollnext"; char * atom_names[AI_count] = { "RESOLUTION_X", "RESOLUTION_Y", "PIXEL_SIZE", "SPACING", "RELATIVE_WEIGHT", "FOUNDRY", "AVERAGE_WIDTH", "CHARSET_REGISTRY", "CHARSET_ENCODING", "CREATE_EVENT", "WM_DELETE_WINDOW", "WM_PROTOCOLS", "WM_TAKE_FOCUS", "_NET_WM_STATE", "_NET_WM_STATE_SKIP_TASKBAR", "_NET_WM_STATE_MAXIMIZED_VERT", "_NET_WM_STATE_MAXIMIZED_HORZ", "_NET_WM_NAME", "_NET_WM_ICON_NAME", "UTF8_STRING", "TARGETS", "INCR", "PIXEL", "FOREGROUND", "BACKGROUND", "_MOTIF_WM_HINTS", "_NET_WM_STATE_MODAL", "_NET_SUPPORTED", "_NET_WM_STATE_MAXIMIZED_HORIZ", "text/plain;charset=UTF-8", "_NET_WM_STATE_STAYS_ON_TOP", "_NET_CURRENT_DESKTOP", "_NET_WORKAREA", "_NET_WM_STATE_ABOVE" }; char hostname_buf[256], *hostname = hostname_buf; guts. click_time_frame = 200; guts. double_click_time_frame = 200; guts. visible_timeout = 500; guts. invisible_timeout = 500; guts. insert = true; guts. last_time = CurrentTime; guts. ri_head = guts. ri_tail = 0; DISP = XOpenDisplay( do_display); if (!DISP) { char * disp = getenv("DISPLAY"); snprintf( error_buf, 256, "Error: Can't open display '%s'", do_display ? do_display : (disp ? disp : "")); free( do_display); do_display = nil; return false; } free( do_display); do_display = nil; XSetErrorHandler( x_error_handler); guts.main_error_handler = x_error_handler; (void)x_io_error_handler; XCHECKPOINT; guts.connection = ConnectionNumber( DISP); { struct sockaddr name; unsigned int l = sizeof( name); guts. local_connection = getsockname( guts.connection, &name, &l) >= 0 && l == 0; } #ifdef HAVE_X11_EXTENSIONS_SHAPE_H if ( XShapeQueryExtension( DISP, &guts.shape_event, &guts.shape_error)) { guts. shape_extension = true; } else { guts. shape_extension = false; } #else guts. shape_extension = false; #endif #ifdef USE_MITSHM if ( !do_no_shmem && XShmQueryExtension( DISP)) { guts. shared_image_extension = true; guts. shared_image_completion_event = XShmGetEventBase( DISP) + ShmCompletion; } else { guts. shared_image_extension = false; guts. shared_image_completion_event = -1; } #else guts. shared_image_extension = false; guts. shared_image_completion_event = -1; #endif guts. randr_extension = false; #ifdef HAVE_X11_EXTENSIONS_XRANDR_H { int dummy; if ( XRRQueryExtension( DISP, &dummy, &dummy)) guts. randr_extension = true; } #endif #ifdef HAVE_X11_EXTENSIONS_XRENDER_H { int dummy; if ( XRenderQueryExtension( DISP, &dummy, &dummy)) guts. render_extension = true; } #endif #ifdef HAVE_X11_EXTENSIONS_XCOMPOSITE_H { int dummy; if (XQueryExtension(DISP, COMPOSITE_NAME, &guts.composite_opcode, &dummy, &dummy)) guts. composite_extension = true; } #endif XrmInitialize(); guts.db = get_database(); XrmStringToQuarkList( common_quarks, common_quarks_list); guts.qString = *ql++; guts.qBlinkinvisibletime = *ql++; guts.qblinkinvisibletime = *ql++; guts.qBlinkvisibletime = *ql++; guts.qblinkvisibletime = *ql++; guts.qClicktimeframe = *ql++; guts.qclicktimeframe = *ql++; guts.qDoubleclicktimeframe = *ql++; guts.qdoubleclicktimeframe = *ql++; guts.qWheeldown = *ql++; guts.qwheeldown = *ql++; guts.qWheelup = *ql++; guts.qwheelup = *ql++; guts.qSubmenudelay = *ql++; guts.qsubmenudelay = *ql++; guts.qScrollfirst = *ql++; guts.qscrollfirst = *ql++; guts.qScrollnext = *ql++; guts.qscrollnext = *ql++; guts. mouse_buttons = XGetPointerMapping( DISP, guts. buttons_map, 256); XCHECKPOINT; guts. limits. request_length = XMaxRequestSize( DISP); guts. limits. XDrawLines = guts. limits. request_length - 3; guts. limits. XFillPolygon = guts. limits. request_length - 4; guts. limits. XDrawSegments = (guts. limits. request_length - 3) / 2; guts. limits. XDrawRectangles = (guts. limits. request_length - 3) / 2; guts. limits. XFillRectangles = (guts. limits. request_length - 3) / 2; guts. limits. XFillArcs = guts. limits. XDrawArcs = (guts. limits. request_length - 3) / 3; XCHECKPOINT; SCREEN = DefaultScreen( DISP); /* XXX - return code? */ guts. root = RootWindow( DISP, SCREEN); guts. displaySize. x = DisplayWidth( DISP, SCREEN); guts. displaySize. y = DisplayHeight( DISP, SCREEN); XQueryBestCursor( DISP, guts. root, guts. displaySize. x, /* :-) */ guts. displaySize. y, &guts. cursor_width, &guts. cursor_height); XCHECKPOINT; TAILQ_INIT( &guts.paintq); TAILQ_INIT( &guts.peventq); TAILQ_INIT( &guts.bitmap_gc_pool); TAILQ_INIT( &guts.screen_gc_pool); TAILQ_INIT( &guts.argb_gc_pool); guts. currentFocusTime = CurrentTime; guts. windows = hash_create(); guts. menu_windows = hash_create(); guts. ximages = hash_create(); gcv. graphics_exposures = false; guts. menugc = XCreateGC( DISP, guts. root, GCGraphicsExposures, &gcv); guts. resolution. x = 25.4 * guts. displaySize. x / DisplayWidthMM( DISP, SCREEN) + .5; guts. resolution. y = 25.4 * DisplayHeight( DISP, SCREEN) / DisplayHeightMM( DISP, SCREEN) + .5; guts. depth = DefaultDepth( DISP, SCREEN); guts. idepth = get_idepth(); if ( guts.depth == 1) guts. qdepth = 1; else if ( guts.depth <= 4) guts. qdepth = 4; else if ( guts.depth <= 8) guts. qdepth = 8; else guts. qdepth = 24; guts. byte_order = ImageByteOrder( DISP); guts. bit_order = BitmapBitOrder( DISP); if ( BYTEORDER == LSB32 || BYTEORDER == LSB64) guts. machine_byte_order = LSBFirst; else if ( BYTEORDER == MSB32 || BYTEORDER == MSB64) guts. machine_byte_order = MSBFirst; else { sprintf( error_buf, "UAA_001: weird machine byte order: %08x", BYTEORDER); return false; } XInternAtoms( DISP, atom_names, AI_count, 0, guts. atoms); guts. null_pointer = nilHandle; guts. pointer_invisible_count = 0; guts. files = plist_create( 16, 16); prima_rebuild_watchers(); guts. wm_event_timeout = 100; guts. menu_timeout = 200; guts. scroll_first = 200; guts. scroll_next = 50; apc_timer_create( CURSOR_TIMER); apc_timer_set_timeout(CURSOR_TIMER, 2); apc_timer_create( MENU_TIMER); apc_timer_set_timeout( MENU_TIMER, guts. menu_timeout); apc_timer_create( MENU_UNFOCUS_TIMER); apc_timer_set_timeout( MENU_UNFOCUS_TIMER, 50); if ( !prima_init_clipboard_subsystem( error_buf)) return false; if ( !prima_init_color_subsystem( error_buf)) return false; if ( !prima_init_font_subsystem( error_buf)) return false; #ifdef WITH_GTK2 if (!prima_gtk_init()) return false; #endif bzero( &guts. cursor_gcv, sizeof( guts. cursor_gcv)); guts. cursor_gcv. cap_style = CapButt; guts. cursor_gcv. function = GXcopy; gethostname( hostname, 256); hostname[255] = '\0'; XStringListToTextProperty((char **)&hostname, 1, &guts. hostname); guts. net_wm_maximization = prima_wm_net_state_read_maximization( guts. root, NET_SUPPORTED); if ( do_sync) XSynchronize( DISP, true); return true; }
/* * drawevents2 calls flush to display anything that was drawn. */ static Input * drawevents2(int block, int *ninp) { static int flushing; if(!flushing){ if(screen.dirty){ drawflush(screen.r); flushing = 1; screen.dirty = 0; } ninputs = 0; } while((block && (flushing || ninputs == 0)) || XPending(display)){ XEvent ev; XNextEvent(display, &ev); switch(ev.type){ case MapNotify: case ReparentNotify: addredraw(); continue; case Expose: addredraw(); continue; case KeyPress: case KeyRelease: { XKeyEvent *ep = &ev.xkey; if(0)fprintf( stderr, "key %s %d (%x) '%c' at (%d,%d) state %x\n", ev.type == KeyPress ? "pressed" : "released", ep->keycode, ep->keycode, isprint(ep->keycode) ? ep->keycode : '.', ep->x, ep->y, ep->state ); u64int mod; KeySym keysym; int code; char keystr[8] = {0}; keysym = XLookupKeysym(ep, ep->state & (ShiftMask|LockMask)); if((code = keysym2ucs(keysym)) != -1) utf8encode(keystr, sizeof keystr-1, code); else keystr[0] = '\0'; switch(keysym){ case XK_Return: case XK_KP_Enter: strncpy(keystr, "\n", sizeof keystr-1); mod = KeyStr; break; case XK_Tab: case XK_KP_Tab: case XK_ISO_Left_Tab: strncpy(keystr, "\t", sizeof keystr-1); mod = KeyStr; break; case XK_Break: mod = KeyBreak; break; case XK_BackSpace: mod = KeyBackSpace; break; case XK_Down: mod = KeyDown; break; case XK_End: mod = KeyEnd; break; case XK_Home: mod = KeyHome; break; case XK_Left: mod = KeyLeft; break; case XK_Page_Down: mod = KeyPageDown; break; case XK_Page_Up: mod = KeyPageUp; break; case XK_Right: mod = KeyRight; break; case XK_Up: mod = KeyUp; break; case XK_Shift_L: case XK_Shift_R: mod = KeyShift; break; case XK_Control_L: case XK_Control_R: mod = KeyControl; break; case XK_Meta_L: case XK_Meta_R: mod = KeyMeta; /* mac command key */ break; case XK_Alt_L: case XK_Alt_R: mod = KeyAlt; break; case XK_Super_L: case XK_Super_R: fprintf(stderr, "super\n"); mod = KeySuper; break; case XK_Hyper_L: case XK_Hyper_R: fprintf(stderr, "hyper\n"); mod = KeyHyper; break; case XK_KP_Insert: case XK_Insert: mod = KeyIns; break; case XK_KP_Delete: case XK_Delete: mod = KeyDel; break; case XK_Caps_Lock: mod = KeyCapsLock; break; default: mod = 0; break; } addinput( 0, 0, keystr, mod, ev.type == KeyPress, ev.type == KeyRelease ); } continue; case ButtonPress: case ButtonRelease: { XButtonEvent *ep = &ev.xbutton; u64int mod; switch(ep->button){ case 0:case 1:case 2:case 3:case 4: case 5:case 6:case 7:case 9:case 10: mod = Mouse0 << ep->button; break; default: fprintf(stderr, "unsupported mouse button %d\n", ep->button); mod = 0; break; } if(mod != 0){ addinput( ep->x, ep->y, NULL, mod, ev.type == ButtonPress, ev.type == ButtonRelease ); } } continue; case EnterNotify: case LeaveNotify: fprintf(stderr, "enter/leave\n"); continue; case MotionNotify: if(input_prevmod != 0){ XMotionEvent *ep = &ev.xmotion; u64int m; if(0)fprintf( stderr, "motion at (%d,%d) state %x\n", ep->x, ep->y, ep->state ); for(m = Mouse0; m <= LastMouse; m <<= 1){ addinput( ep->x, ep->y, NULL, m, 0,0 ); } } continue; case ConfigureNotify: { XConfigureEvent *ce = &ev.xconfigure; if(ce->width != width || ce->height != height){ shmfree(); width = ce->width; height = ce->height; if(shminit() == -1){ *ninp = 0; return NULL; } addredraw(); } continue; } } if(ev.type == XShmGetEventBase(display) + ShmCompletion){ flushing = 0; if(animating){ addredraw(); } continue; } fprintf(stderr, "unknown xevent %d\n", ev.type); } if(!flushing && ninputs > 0){ *ninp = ninputs; return inputs; } *ninp = 0; return NULL; }
int svlWindowManagerX11::DoModal(bool show, bool fullscreen) { Destroy(); DestroyFlag = false; unsigned int i, atom_count; int x, y, prevright, prevbottom; unsigned int lastimage = 0; unsigned long black, white; XSizeHints wsh; #if CISST_SVL_HAS_XV Atom atoms[3]; unsigned int xvadaptorcount; XvAdaptorInfo *xvai; XVisualInfo xvvinfo; bool xvupdateimage = true; #else // CISST_SVL_HAS_XV Atom atoms[2]; #endif // CISST_SVL_HAS_XV // setting decoration hints for borderless mode struct { unsigned long flags; unsigned long functions; unsigned long decorations; signed long input_mode; unsigned long status; } mwm; mwm.flags = MWM_HINTS_DECORATIONS; mwm.decorations = 0; mwm.functions = 0; mwm.input_mode = 0; mwm.status = 0; // resetting DestroyedSignal event if (DestroyedSignal) delete(DestroyedSignal); DestroyedSignal = new osaThreadSignal(); if (DestroyedSignal == 0) goto labError; // initialize display and pick default screen xDisplay = XOpenDisplay(reinterpret_cast<char*>(0)); xScreen = DefaultScreen(xDisplay); #if CISST_SVL_HAS_XV // check if 24bpp is suppoted by the display if (XMatchVisualInfo(xDisplay, xScreen, 24, TrueColor, &xvvinfo) == 0) goto labError; #endif // CISST_SVL_HAS_XV // pick colors black = BlackPixel(xDisplay, xScreen); white = WhitePixel(xDisplay, xScreen); // create windows xWindows = new Window[NumOfWins]; memset(xWindows, 0, NumOfWins * sizeof(Window)); xGCs = new GC[NumOfWins]; memset(xGCs, 0, NumOfWins * sizeof(GC)); // create atoms for overriding default window behaviours atoms[0] = XInternAtom(xDisplay, "WM_DELETE_WINDOW", False); atoms[1] = XInternAtom(xDisplay, "_MOTIF_WM_HINTS", False); #if CISST_SVL_HAS_XV atoms[2] = XInternAtom(xDisplay, "XV_SYNC_TO_VBLANK", False); #endif // CISST_SVL_HAS_XV // create title strings Titles = new std::string[NumOfWins]; CustomTitles = new std::string[NumOfWins]; CustomTitleEnabled = new int[NumOfWins]; #if CISST_SVL_HAS_XV xvImg = new XvImage*[NumOfWins]; xvShmInfo = new XShmSegmentInfo[NumOfWins]; xvPort = new XvPortID[NumOfWins]; if (xvImg == 0 || xvShmInfo == 0 || xvPort == 0) goto labError; memset(xvImg, 0, NumOfWins * sizeof(XvImage*)); memset(xvShmInfo, 0, NumOfWins * sizeof(XShmSegmentInfo)); memset(xvPort, 0, NumOfWins * sizeof(XvPortID)); #else // CISST_SVL_HAS_XV // create images xImageBuffers = new unsigned char*[NumOfWins]; for (i = 0; i < NumOfWins; i ++) { xImageBuffers[i] = new unsigned char[Width[i] * Height[i] * 4]; } xImg = new XImage*[NumOfWins]; memset(xImg, 0, NumOfWins * sizeof(XImage*)); if (xImg == 0) goto labError; for (i = 0; i < NumOfWins; i ++) { xImg[i] = XCreateImage(xDisplay, DefaultVisual(xDisplay, xScreen), 24, ZPixmap, 0, reinterpret_cast<char*>(xImageBuffers[i]), Width[i], Height[i], 32, 0); } #endif // CISST_SVL_HAS_XV prevright = prevbottom = 0; for (i = 0; i < NumOfWins; i ++) { if (PosX == 0 || PosY == 0) { if (fullscreen) { x = prevright; y = 0; prevright += Width[i]; } else { x = prevright; y = prevbottom; prevright += 50; prevbottom += 50; } } else { x = PosX[i]; y = PosY[i]; } xWindows[i] = XCreateSimpleWindow(xDisplay, DefaultRootWindow(xDisplay), x, y, Width[i], Height[i], 0, black, white); if (xWindows[i] == 0) goto labError; // overriding default behaviours: // - borderless mode // - closing window if (fullscreen) { XChangeProperty(xDisplay, xWindows[i], atoms[1], atoms[1], 32, PropModeReplace, reinterpret_cast<unsigned char*>(&mwm), 5); atom_count = 2; } else { atom_count = 1; } XSetWMProtocols(xDisplay, xWindows[i], atoms, atom_count); wsh.flags = PPosition|PSize; wsh.x = x; wsh.y = y; wsh.width = Width[i]; wsh.height = Height[i]; XSetNormalHints(xDisplay, xWindows[i], &wsh); // set window title CustomTitleEnabled[i] = 0; std::ostringstream ostring; if (Title.length() > 0) { if (NumOfWins > 0) ostring << Title << " #" << i; else ostring << Title; } else { if (NumOfWins > 0) ostring << Title << "svlImageWindow #" << i; else ostring << "svlImageWindow"; } Titles[i] = ostring.str(); XSetStandardProperties(xDisplay, xWindows[i], Titles[i].c_str(), Titles[i].c_str(), None, NULL, 0, NULL); // set even mask XSelectInput(xDisplay, xWindows[i], ExposureMask|PointerMotionMask|ButtonPressMask|KeyPressMask); // set window colormap XSetWindowColormap(xDisplay, xWindows[i], DefaultColormapOfScreen(DefaultScreenOfDisplay(xDisplay))); #if CISST_SVL_HAS_XV // query shared memory extension if (!XShmQueryExtension(xDisplay)) goto labError; // query video adaptors if (XvQueryAdaptors(xDisplay, DefaultRootWindow(xDisplay), &xvadaptorcount, &xvai) != Success) goto labError; xvPort[i] = xvai->base_id + i; XvFreeAdaptorInfo(xvai); // overriding default Xvideo vertical sync behavior XvSetPortAttribute (xDisplay, xvPort[i], atoms[2], 1); #endif // CISST_SVL_HAS_XV // create graphics context xGCs[i] = XCreateGC(xDisplay, xWindows[i], 0, 0); // set default colors XSetBackground(xDisplay, xGCs[i], white); XSetForeground(xDisplay, xGCs[i], black); #if CISST_SVL_HAS_XV // create image in shared memory xvImg[i] = XvShmCreateImage(xDisplay, xvPort[i], 0x32595559/*YUV2*/, 0, Width[i], Height[i], &(xvShmInfo[i])); if (xvImg[i]->width < static_cast<int>(Width[i]) || xvImg[i]->height < static_cast<int>(Height[i])) { CMN_LOG_INIT_ERROR << "DoModal - image too large for XV to display (requested=" << Width[i] << "x" << Height[i] << "; allowed=" << xvImg[i]->width << "x" << xvImg[i]->height << ")" << std::endl; goto labError; } xvShmInfo[i].shmid = shmget(IPC_PRIVATE, xvImg[i]->data_size, IPC_CREAT | 0777); xvShmInfo[i].shmaddr = xvImg[i]->data = reinterpret_cast<char*>(shmat(xvShmInfo[i].shmid, 0, 0)); xvShmInfo[i].readOnly = False; if (!XShmAttach(xDisplay, &(xvShmInfo[i]))) goto labError; #endif // CISST_SVL_HAS_XV // clear window XClearWindow(xDisplay, xWindows[i]); // show window if requested if (show) XMapRaised(xDisplay, xWindows[i]); } // signal that initialization is done if (InitReadySignal) InitReadySignal->Raise(); // main message loop XEvent event; KeySym code; unsigned int winid; while (1) { osaSleep(0.001); #if CISST_SVL_HAS_XV if (!xvupdateimage) { for (int events = XPending(xDisplay); events > 0; events --) { #else // CISST_SVL_HAS_XV if (XPending(xDisplay)) { #endif // CISST_SVL_HAS_XV XNextEvent(xDisplay, &event); // find recipient for (winid = 0; winid < NumOfWins; winid ++) { if (event.xany.window == xWindows[winid]) break; } if (winid == NumOfWins) continue; // override default window behaviour if (event.type == ClientMessage) { if (static_cast<unsigned long>(event.xclient.data.l[0]) == atoms[0]) { // X11 server wants to close window // Do nothing.... we will destroy it ourselves later } continue; } // window should be closed if (event.type == UnmapNotify) { printf("destroy\n"); if (xGCs[winid]) { XFreeGC(xDisplay, xGCs[winid]); xGCs[winid] = 0; } xWindows[winid] = 0; continue; } // window should be updated if (event.type == Expose && event.xexpose.count == 0) { XClearWindow(xDisplay, xWindows[winid]); continue; } if (event.type == KeyPress) { code = XLookupKeysym(&event.xkey, 0); if (code >= 48 && code <= 57) { // ascii numbers OnUserEvent(winid, true, code); continue; } if (code >= 97 && code <= 122) { // ascii letters OnUserEvent(winid, true, code); continue; } if (code == 13 || code == 32) { // special characters with correct ascii code OnUserEvent(winid, true, code); continue; } if (code >= 0xffbe && code <= 0xffc9) { // F1-F12 OnUserEvent(winid, false, winInput_KEY_F1 + (code - 0xffbe)); continue; } switch (code) { case 0xFF55: OnUserEvent(winid, false, winInput_KEY_PAGEUP); break; case 0xFF56: OnUserEvent(winid, false, winInput_KEY_PAGEDOWN); break; case 0xFF50: OnUserEvent(winid, false, winInput_KEY_HOME); break; case 0xFF57: OnUserEvent(winid, false, winInput_KEY_END); break; case 0xFF63: OnUserEvent(winid, false, winInput_KEY_INSERT); break; case 0xFFFF: OnUserEvent(winid, false, winInput_KEY_DELETE); break; case 0xFF51: OnUserEvent(winid, false, winInput_KEY_LEFT); break; case 0xFF53: OnUserEvent(winid, false, winInput_KEY_RIGHT); break; case 0xFF52: OnUserEvent(winid, false, winInput_KEY_UP); break; case 0xFF54: OnUserEvent(winid, false, winInput_KEY_DOWN); break; } continue; } if (event.type == ButtonPress) { if (event.xbutton.button == Button1) { if (!LButtonDown && !RButtonDown) { LButtonDown = true; XGrabPointer(xDisplay, xWindows[winid], false, PointerMotionMask|ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); } OnUserEvent(winid, false, winInput_LBUTTONDOWN); } else if (event.xbutton.button == Button3) { if (!LButtonDown && !RButtonDown) { RButtonDown = true; XGrabPointer(xDisplay, xWindows[winid], false, PointerMotionMask|ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); } OnUserEvent(winid, false, winInput_RBUTTONDOWN); } } if (event.type == ButtonRelease) { if (event.xbutton.button == Button1) { OnUserEvent(winid, false, winInput_LBUTTONUP); if (LButtonDown && !RButtonDown) { LButtonDown = false; XUngrabPointer(xDisplay, CurrentTime); } } else if (event.xbutton.button == Button3) { OnUserEvent(winid, false, winInput_RBUTTONUP); if (!LButtonDown && RButtonDown) { RButtonDown = false; XUngrabPointer(xDisplay, CurrentTime); } } } if (event.type == MotionNotify) { SetMousePos(static_cast<short>(event.xmotion.x), static_cast<short>(event.xmotion.y)); OnUserEvent(winid, false, winInput_MOUSEMOVE); } #if CISST_SVL_HAS_XV // image update complete if (event.type == XShmGetEventBase(xDisplay) + ShmCompletion) { xvupdateimage = true; continue; } } if (!xvupdateimage) signalImage.Wait(0.01); #endif // CISST_SVL_HAS_XV } else { if (DestroyFlag) break; if (ImageCounter > lastimage) { csImage.Enter(); lastimage = ImageCounter; #if CISST_SVL_HAS_XV for (i = 0; i < NumOfWins; i ++) { XvShmPutImage(xDisplay, xvPort[i], xWindows[i], xGCs[i], xvImg[i], 0, 0, Width[i], Height[i], 0, 0, Width[i], Height[i], True); } xvupdateimage = false; #else // CISST_SVL_HAS_XV for (i = 0; i < NumOfWins; i ++) { xImg[i]->data = reinterpret_cast<char*>(xImageBuffers[i]); XPutImage(xDisplay, xWindows[i], xGCs[i], xImg[i], 0, 0, 0, 0, Width[i], Height[i]); } #endif // CISST_SVL_HAS_XV /* for (i = 0; i < NumOfWins; i ++) { if (CustomTitleEnabled[i] < 0) { // Restore original timestamp XSetStandardProperties(xDisplay, xWindows[i], Titles[i].c_str(), Titles[i].c_str(), None, NULL, 0, NULL); } else if (CustomTitleEnabled[i] > 0) { // Set custom timestamp XSetStandardProperties(xDisplay, xWindows[i], CustomTitles[i].c_str(), CustomTitles[i].c_str(), None, NULL, 0, NULL); } } */ csImage.Leave(); } } } labError: #if CISST_SVL_HAS_XV if (xvShmInfo) { for (i = 0; i < NumOfWins; i ++) { XShmDetach(xDisplay, &(xvShmInfo[i])); shmdt(xvShmInfo[i].shmaddr); } delete [] xvShmInfo; xvShmInfo = 0; } #endif // CISST_SVL_HAS_XV XSync(xDisplay, 0); for (i = 0; i < NumOfWins; i ++) { if (xGCs[i]) XFreeGC(xDisplay, xGCs[i]); if (xWindows[i]) XDestroyWindow(xDisplay, xWindows[i]); } XCloseDisplay(xDisplay); #if CISST_SVL_HAS_XV if (xvImg) { for (i = 0; i < NumOfWins; i ++) { if (xvImg[i]) XFree(xvImg[i]); } delete [] xvImg; xvImg = 0; } if (xvPort) { delete [] xvPort; xvPort = 0; } #else // CISST_SVL_HAS_XV if (xImg) { for (i = 0; i < NumOfWins; i ++) { if (xImg[i]) XDestroyImage(xImg[i]); } delete [] xImg; xImg = 0; } if (xImageBuffers) { delete [] xImageBuffers; xImageBuffers = 0; } #endif // CISST_SVL_HAS_XV if (xGCs) { delete [] xGCs; xGCs = 0; } if (xWindows) { delete [] xWindows; xWindows = 0; } if (Titles) { delete [] Titles; Titles = 0; } if (CustomTitles) { delete [] CustomTitles; CustomTitles = 0; } if (CustomTitleEnabled) { delete [] CustomTitleEnabled; CustomTitleEnabled = 0; } xScreen = 0; xDisplay = 0; if (DestroyedSignal) DestroyedSignal->Raise(); return 0; }
int main(int argc, char **argv) { int num_queued; time_t start_time; double t; long num_frames, fast_skip = 200, fast_rewind = 200; unsigned int width, height; XEvent xevent; const char *prgname = argv[0]; const char *classname = "XLndmovie"; char *pixel_file_name = NULL; FILE *pixel_file; unsigned char *buffer = NULL, *huff = NULL; XImage *shm_image; XShmSegmentInfo shminfo; int shm_major, shm_minor; Bool shm_pixmaps; int ShmCompletionType; int shmtransfer_completed; int i, count, step_key = 0; char xkey[32]; KeySym keysym; XComposeStatus compose; int oc; extern int optind; extern char *optarg; init_signal_handling(); display = xwin_init(NULL, prgname, classname, argc, argv, &screen_no, &width, &height); fixed_font = XLoadQueryFont(display, "fixed"); mit_shm = XShmQueryVersion(display, &shm_major, &shm_minor, &shm_pixmaps); mit_shm = XShmQueryExtension(display); if (mit_shm == True) { /* printf("Shared memory extension used (found V %d.%d)\n", shm_major, shm_minor); */ ShmCompletionType = XShmGetEventBase(display) + ShmCompletion; } /* else printf("Standard Xlib used, no shared memory\n"); */ while ((oc = getopt(argc, argv, "c:f:r:h")) != -1) { switch (oc) { case 'c': cell_boxsize = strtol(optarg, NULL, 10); break; case 'f': fast_skip = strtol(optarg, NULL, 10); if (fast_skip < 1) fast_skip = 200; break; case 'r': fast_rewind = strtol(optarg, NULL, 10); if (fast_rewind < 1) fast_rewind = 200; break; default: fprintf(stderr, "Unknown option \'-%c\' -- ignored\n", oc); break; } } if (optind < argc) pixel_file_name = argv[optind++]; else { fprintf(stderr, "No pixel file specified -- exit\n"); exit (EXIT_FAILURE); } pixel_file = fopen(pixel_file_name, "rb"); if (pixel_file == NULL) { fprintf(stderr, "Failed to open pixel file \"%s\" -- exit\n", pixel_file_name); exit (EXIT_FAILURE); } read_pixheader(pixel_file); if ((cell_boxsize <= 0) || ((width / world_width) < cell_boxsize)) cell_boxsize = width / world_width; if ((height / world_height) < cell_boxsize) cell_boxsize = height / world_height; if (cell_boxsize <= 0) cell_boxsize = 1; if ((height / world_height) < cell_boxsize) cell_boxsize = height / world_height; window_width = world_width * cell_boxsize; pixmap_height = world_height * cell_boxsize; if (fixed_font) window_height = pixmap_height + fixed_font->ascent + fixed_font->descent + 5; else window_height = pixmap_height; buffer = (unsigned char *) malloc(world_width * world_height * sizeof(char)); if (buffer == NULL) { fprintf(stderr, "Failed to allocate internal buffer\n"); exit (EXIT_FAILURE); } huff = (unsigned char *) malloc(world_width * world_height * sizeof(char)); if (buffer == NULL) { fprintf(stderr, "Failed to allocate internal buffer\n"); free(buffer); exit (EXIT_FAILURE); } window = create_window(MOVER | FULLER | CLOSER | RTARROW | LFARROW | UPARROW | DNARROW, window_width, window_height, redraw_pixworld, close_pixwindow, 100, 100, window_width, window_height); XSelectInput(display, window, WH_EVENTMASK | WH_SELECTMASK); map_window(window); if (create_lndgcs(lnd_gc, lndx_gc, background_gc, &text_gc)) { fprintf(stderr, "Failed to create necessary GCs (insufficient colors?)\n"); free(buffer); free(huff); exit (EXIT_FAILURE); } if (mit_shm) { shm_image = XShmCreateImage(display, DefaultVisual(display, screen_no), DefaultDepth(display, screen_no), ZPixmap, NULL, &shminfo, window_width, pixmap_height); /* printf("XImage Structure:\n"); printf("width = %d, height = %d, depth = %d\n", shm_image->width, shm_image->height, shm_image->depth); printf("format: "); switch (shm_image->format) { case XYBitmap: printf("XYBitmap\n"); break; case XYPixmap: printf("XYPixmap\n"); break; case ZPixmap: printf("ZPixmap\n"); break; default: printf("UNKNOWN (%d)\n", shm_image->format); break; } printf("%d bytes per line, %d bits per pixel\n", shm_image->bytes_per_line, shm_image->bits_per_pixel); switch (shm_image->byte_order) { case MSBFirst: printf("byte order: MSBFirst\n"); break; case LSBFirst: printf("byte order: LSBFirst\n"); break; default: printf("byte order UNKNOWN (%d)\n", shm_image->byte_order); break; } switch (shm_image->bitmap_bit_order) { case MSBFirst: printf("bitmap bit order: MSBFirst\n"); break; case LSBFirst: printf("bitmap bit order: LSBFirst\n"); break; default: printf("bitmap bit order UNKNOWN (%d)\n", shm_image->bitmap_bit_order); break; } */ shminfo.shmid = shmget(IPC_PRIVATE, shm_image->bytes_per_line * shm_image->height, IPC_CREAT | 0777); if (shminfo.shmid == -1) { fprintf(stderr, "Failed to get shared memory segment, falling back to standard Xlib\n"); mit_shm = 0; } else { shminfo.shmaddr = shmat(shminfo.shmid, 0, 0); shm_image->data = shminfo.shmaddr; shminfo.readOnly = False; if (XShmAttach(display, &shminfo)) ; /* printf("Shared mem successfully attached to server\n"); */ else { mit_shm = 0; XDestroyImage(shm_image); shmdt(shminfo.shmaddr); shmctl(shminfo.shmid, IPC_RMID, 0); printf("Shared memory released\n"); } } } if (!mit_shm) { paint_pixmap = XCreatePixmap(display, window, window_width, pixmap_height, DefaultDepth(display, screen_no)); XFillRectangle(display, paint_pixmap, background_gc[15], 0, 0, window_width, pixmap_height); } redraw_pixmap = XCreatePixmap(display, window, window_width, pixmap_height, DefaultDepth(display, screen_no)); XFillRectangle(display, redraw_pixmap, background_gc[15], 0, 0, window_width, pixmap_height); /* for (i = 0; i < 6; i++) { XPutPixel(shm_image, 0, 0, lnd_pixel[i]); printf("lnd_pixel[%d]=%08lx -> data=%02x\n", i, lnd_pixel[i], shm_image->data[0]); XPutPixel(shm_image, 0, 0, lndx_pixel[i]); printf("lndx_pixel[%d]=%08lx -> data=%02x\n", i, lndx_pixel[i], shm_image->data[0]); } XPutPixel(shm_image, 0, 0, back_pixel); printf("back_pixel=%08lx -> data=%02x\n", back_pixel, shm_image->data[0]); */ do { XNextEvent(display, &xevent); num_queued = XEventsQueued(display, QueuedAfterFlush); process_xevent(&xevent); } while (!((xevent.type == Expose) && (xevent.xexpose.window == window))); shmtransfer_completed = 1; start_time = time(NULL); num_frames = 0; while (!game_over) { if(feof(pixel_file) || ferror(pixel_file)) { if (resume_fpos != -1) { mode = SINGLE_STEP; /* printf("switched to single step due to feof / ferror\n"); */ step_key = 0; /* printf("rewinding to resume pos %ld\n", resume_fpos); fseek(pixel_file, resume_fpos, SEEK_SET); */ } else { fprintf(stderr, "Encountered EOF without finding any entry point -- quitting\n"); game_over = 1; } } num_queued = XEventsQueued(display, QueuedAfterFlush); while ((num_queued) || ((mode == SINGLE_STEP) && !step_key)) { XNextEvent(display, &xevent); num_queued = XEventsQueued(display, QueuedAfterFlush); /* printf("received event: %s, window: %d\n", event_name[xevent.type], (int) xevent.xany.window); */ if (process_xevent(&xevent)) continue; if (xevent.type == ShmCompletionType) { /* printf("shm transfer completed\n"); */ shmtransfer_completed = 1; } if (xevent.type == KeyPress) { count = XLookupString(&(xevent.xkey), xkey, 32, &keysym, &compose); if (count) { switch(xkey[0]) { case 'f': /* printf("fast forward\n"); */ /* printf("rewind position: %ld\n", resume_fpos); */ mode = FAST_FORWARD; break; case 'r': /* printf("fast rewind\n"); */ /* printf("rewind position: %ld\n", resume_fpos); */ mode = FAST_REWIND; break; case 'b': /* printf("backward play\n"); */ /* printf("rewind position: %ld\n", resume_fpos); */ mode = BACKWARD_PLAY; rewind_generation(pixel_file); break; case 's': /* printf("single step\n"); */ mode = SINGLE_STEP; step_key = 0; break; case 'n': /* printf("normal play\n"); */ /* printf("rewind position: %ld\n", resume_fpos); */ mode = NORMAL_PLAY; break; case 'q': case 'Q': /* printf("game over, bye bye\n"); */ mode = NORMAL_PLAY; step_key = 1; game_over = 1; break; default: step_key = 1; break; } } } } if ((mode == NORMAL_PLAY) || (mode == BACKWARD_PLAY) || ((mode == SINGLE_STEP) && step_key) || ((mode == FAST_FORWARD) && ((generation % fast_skip) == (fast_skip - 1))) || ((mode == FAST_REWIND) && ((generation % fast_rewind) == 1))) { if (mit_shm && shmtransfer_completed) { if (shm_draw_generation(pixel_file, shm_image, buffer, huff)) { mode = SINGLE_STEP; /* printf("switched to single step after shm_draw_generation\n"); */ step_key = 0; } else { if (window != BadValue) XShmPutImage(display, window, background_gc[15], shm_image, 0, 0, 0, window_height - pixmap_height, window_width, pixmap_height, True); if (redraw_pixmap != BadValue) XShmPutImage(display, redraw_pixmap, background_gc[15], shm_image, 0, 0, 0, 0, window_width, pixmap_height, True); shmtransfer_completed = 0; num_frames++; } } else { if (draw_generation(pixel_file, paint_pixmap, buffer, huff)) { mode = SINGLE_STEP; /* printf("switched to single step after draw_generation\n"); */ step_key = 0; } else { if (window != BadValue) XCopyArea(display, paint_pixmap, window, background_gc[15], 0, 0, window_width, pixmap_height, 0, window_height - pixmap_height); if (redraw_pixmap != BadValue) XCopyArea(display, paint_pixmap, redraw_pixmap, background_gc[15], 0, 0, window_width, pixmap_height, 0, 0); num_frames++; } } redraw_text(); if (mode == FAST_REWIND) { if (rewind_generation(pixel_file)) { mode = SINGLE_STEP; /* printf("switched to single step after rewind_generation\n"); */ step_key = 0; } } step_key = 0; } switch (mode) { case BACKWARD_PLAY: if (rewind_generation(pixel_file)) { mode = SINGLE_STEP; /* printf("switched to single step after rewind_generation\n"); */ step_key = 0; } /* fall through */ case FAST_REWIND: if (rewind_generation(pixel_file)) { mode = SINGLE_STEP; /* printf("switched to single step after rewind_generation\n"); */ step_key = 0; } redraw_text(); break; case FAST_FORWARD: if (skip_frame(pixel_file)) { mode = SINGLE_STEP; /* printf("switched to single step after skip_frame\n"); */ step_key = 0; } redraw_text(); break; } } t = difftime(time(NULL), start_time); /* printf("%ld frames in %f seconds (%f frames/sec)\n", num_frames, t, num_frames / t); */ if (mit_shm) { XShmDetach(display, &shminfo); XDestroyImage(shm_image); shmdt(shminfo.shmaddr); shmctl(shminfo.shmid, IPC_RMID, 0); printf("Shared memory released\n"); } free_lndgcs(); if (window != BadValue) remove_window(window); if (redraw_pixmap != BadValue) XFreePixmap(display, redraw_pixmap); if (paint_pixmap != BadValue) XFreePixmap(display, paint_pixmap); free(buffer); free(huff); return (EXIT_SUCCESS); }