/* Free an allocated frame buffer. */ static void video_arch_frame_buffer_free(video_canvas_t *canvas) { Display *display; if (canvas == NULL) { return; } #ifdef HAVE_XVIDEO if (canvas->xv_image) { #if defined(__QNX__) || defined(MINIX_SUPPORT) XShmSegmentInfo* shminfo = NULL; #else XShmSegmentInfo* shminfo = canvas->using_mitshm ? &canvas->xshm_info : NULL; #endif display = x11ui_get_display_ptr(); destroy_yuv_image(display, canvas->xv_image, shminfo); return; } #endif #ifdef HAVE_FULLSCREEN if (fullscreen_is_enabled) { return; } #endif display = x11ui_get_display_ptr(); #ifdef USE_MITSHM if (canvas->using_mitshm) { XShmDetach(display, &(canvas->xshm_info)); if (canvas->x_image) { XDestroyImage(canvas->x_image); } if (shmdt(canvas->xshm_info.shmaddr)) { log_error(x11video_log, "Cannot release shared memory!"); } } else if (canvas->x_image) { XDestroyImage(canvas->x_image); } #else if (canvas->x_image) { XDestroyImage(canvas->x_image); } #endif }
int uicolor_alloc_color(unsigned int red, unsigned int green, unsigned int blue, unsigned long *color_pixel, BYTE *pixel_return) { XColor color; XImage *im; BYTE *data = (BYTE *)malloc(4); /* XDestroyImage will free data. */ Display *display = x11ui_get_display_ptr(); /* This is a kludge to map pixels to zimage values. Is there a better way to do this? //tvr */ im = XCreateImage(display, visual, x11ui_get_display_depth(), ZPixmap, 0, (char *)data, 1, 1, 8, 0); if (!im) { log_error(LOG_DEFAULT, "XCreateImage failed."); free(data); return -1; } color.flags = DoRed | DoGreen | DoBlue; color.red = red << 8; color.green = green << 8; color.blue = blue << 8; if (!XAllocColor(display, colormap, &color)) { log_error(LOG_DEFAULT, "Cannot allocate color \"#%04X%04X%04X\".", color.red, color.green, color.blue); XDestroyImage(im); return -1; } XPutPixel(im, 0, 0, color.pixel); *pixel_return = *data; *color_pixel = color.pixel; XDestroyImage(im); return 0; }
static void init_xv_settings(video_canvas_t *canvas) { /* Find XVideo color setting limits. */ if (canvas->videoconfig->hwscale && canvas->xv_image) { int i, j; int numattr = 0; Display *dpy = x11ui_get_display_ptr(); XvAttribute *attr = XvQueryPortAttributes(dpy, canvas->xv_port, &numattr); for (i = 0; i < (int)(sizeof(xv_settings)/sizeof(xv_settings[0])); i++) { xv_settings[i].atom = 0; for (j = 0; j < numattr; j++) { if (strcmp(xv_settings[i].name, attr[j].name) == 0) { xv_settings[i].atom = XInternAtom(dpy, xv_settings[i].name, False); xv_settings[i].min = attr[j].min_value; xv_settings[i].max = attr[j].max_value; break; } } } if (attr) { XFree(attr); } /* Apply color settings to XVideo. */ video_canvas_set_palette(canvas, canvas->palette); } }
void init_openGL(void) { XVisualInfo *vi; Display *dpy; /*get the deepest buffer with 1 red bit*/ static int attributeListSgl[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None }; dpy = x11ui_get_display_ptr(); vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributeListSgl); if (vi == NULL) { log_error(openGL_log, "glXChooseVisual() failed"); no_sync = 1; return; } if (cx) glXDestroyContext(dpy, cx); cx = glXCreateContext(dpy, vi, 0, GL_TRUE); if (!cx) { log_error(openGL_log, "glXCreateContext() failed"); no_sync = 1; return; } glXMakeCurrent(dpy, x11ui_get_X11_window(), cx); openGL_initialized = 1; }
int video_canvas_set_palette(video_canvas_t *c, struct palette_s *palette) { #ifdef HAVE_XVIDEO /* Apply color settings to XVideo. */ if (c->videoconfig->hwscale && c->xv_image) { int i; Display *dpy = x11ui_get_display_ptr(); for (i = 0; i < (int)(sizeof(xv_settings) / sizeof(xv_settings[0])); i++) { /* Map from VICE [0,2000] to XVideo [xv_min, xv_max]. */ int v_min = 0, v_max = 2000; int v_zero = (v_min + v_max) / 2; int v_range = v_max - v_min; int xv_zero = (xv_settings[i].min + xv_settings[i].max) / 2; int xv_range = xv_settings[i].max - xv_settings[i].min; int xv_val = (*xv_settings[i].value - v_zero) * xv_range / v_range + xv_zero; if (!xv_settings[i].atom) { continue; } XvSetPortAttribute(dpy, c->xv_port, xv_settings[i].atom, xv_val); } } #endif c->palette = palette; return uicolor_set_palette(c, palette); }
static GC video_get_gc(XGCValues *gc_values) { Display *display; display = x11ui_get_display_ptr(); return XCreateGC(display, XtWindow(_ui_top_level), 0, gc_values); }
/* Make the canvas not visible. */ void video_canvas_unmap(video_canvas_t *s) { Display *display; display = x11ui_get_display_ptr(); XUnmapWindow(display, s->drawable); XFlush(display); }
void openGL_sync_shutdown(void) { if (openGL_sync) set_openGL_sync(0, NULL); if (cx) { glXDestroyContext(x11ui_get_display_ptr(), cx); cx = NULL; } }
int vidmode_enable(struct video_canvas_s *canvas, int enable) { #ifdef HAVE_FULLSCREEN Display *vm_display; Window shellwin; if (vm_available == 0) { return 0; } vm_display = x11ui_get_display_ptr(); if (enable) { vm_is_enabled = 0; log_message(vidmode_log, "Enabling Vidmode with%s", vm_bestmodes[vidmode_selected_mode].name); vm = vm_modes[vm_bestmodes[vidmode_selected_mode].modeindex]; saved_w = canvas->draw_buffer->canvas_width; saved_h = canvas->draw_buffer->canvas_height; vidmode_resize_canvas(canvas, canvas->fullscreenconfig->ui_border_top > 0); XF86VidModeSwitchToMode(vm_display, screen, vm); vidmode_center_canvas(canvas); XWarpPointer(vm_display, None, DefaultRootWindow(vm_display), 0, 0, vm->hdisplay, vm->vdisplay, x + vm->hdisplay / 2, y + vm->vdisplay / 2); /* grab the pointer */ shellwin = x11ui_get_X11_window(); XGrabPointer(vm_display, shellwin, 1, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, shellwin, None, CurrentTime); active_canvas = canvas; vm_is_enabled = 1; vm_is_suspended = 0; } else { if (!vm_is_enabled) { return 0; } log_message(vidmode_log, "Disabling Vidmode"); /* FIXME: don't ungrab if either mouse or lightpen emulation is enabled */ XUngrabPointer(vm_display, CurrentTime); XUngrabKeyboard(vm_display, CurrentTime); XF86VidModeSwitchToMode(vm_display, screen, vm_modes[0]); /* restore canvas size for windowed mode */ canvas->draw_buffer->canvas_width = saved_w; canvas->draw_buffer->canvas_height = saved_h; video_viewport_resize(canvas); vm_is_enabled = 0; } #endif return 0; }
int uicolor_alloc_colors(video_canvas_t *c) { if (uicolor_alloc_system_colors() < 0 || color_alloc_colors(c, c->palette, NULL) < 0) { Display *display = x11ui_get_display_ptr(); if (colormap == DefaultColormap(display, screen)) { log_warning(LOG_DEFAULT, "Automatically using a private colormap."); colormap = XCreateColormap(display, RootWindow(display, screen), visual, AllocNone); XtVaSetValues(_ui_top_level, XtNcolormap, colormap, NULL); return color_alloc_colors(c, c->palette, NULL); } } return 0; }
static void vidmode_resize_canvas(struct video_canvas_s *canvas, int uienable) { int status_h = 0; int fs_h, fs_w; Display *vm_display; if (vm_available == 0) { return; } vm_display = x11ui_get_display_ptr(); #ifdef HAVE_FULLSCREEN if (uienable) { status_h = canvas->fullscreenconfig->ui_border_top + canvas->fullscreenconfig->ui_border_bottom; } #endif /* fs_w = ((float)vm->hdisplay * get_aspect(canvas)); */ fs_h = vm->vdisplay; fs_w = vm->hdisplay; if (canvas->videoconfig->doublesizex) { xoffs = ((fs_w) - (vm->hdisplay)); fs_w /= 2; } else { xoffs = (fs_w / 2) - (vm->hdisplay / 2); } if (canvas->videoconfig->doublesizey) { yoffs = ((fs_h) - (vm->vdisplay)); fs_h -= status_h; fs_h /= 2; } else { yoffs = (fs_h / 2) - (vm->vdisplay / 2); fs_h -= status_h; } fs_w += (EXTRA_BORDER * 2); fs_h += (EXTRA_BORDER * 2); xoffs += EXTRA_BORDER; yoffs += EXTRA_BORDER; canvas->draw_buffer->canvas_width = fs_w; canvas->draw_buffer->canvas_height = fs_h; video_viewport_resize(canvas); ui_dispatch_events(); }
void openGL_sync_init(void) { Display *dpy; if (openGL_log == LOG_ERR) openGL_log = log_open("openGL"); else return; /* we've been initializied already */ dpy = x11ui_get_display_ptr(); if (check_openGL(dpy)) no_sync = 1; else init_openGL(); }
static void init_xv_settings(video_canvas_t *canvas) { /* Find XVideo color setting limits. */ if (canvas->videoconfig->hwscale && canvas->xv_image) { int i, j; int numattr = 0; Display *dpy = x11ui_get_display_ptr(); XvAttribute *attr = XvQueryPortAttributes(dpy, canvas->xv_port, &numattr); xv_settings[0].value = &(canvas->videoconfig->video_resources.color_saturation); xv_settings[1].value = &(canvas->videoconfig->video_resources.color_contrast); xv_settings[2].value = &(canvas->videoconfig->video_resources.color_brightness); xv_settings[3].value = &(canvas->videoconfig->video_resources.color_gamma); for (i = 0; i < (int)util_arraysize(xv_settings); i++) { xv_settings[i].atom = 0; for (j = 0; j < numattr; j++) { if (!(attr[j].flags & XvSettable)) { continue; /* useless, can't be set */ } if (strcmp(xv_settings[i].name, attr[j].name) == 0) { xv_settings[i].atom = XInternAtom(dpy, xv_settings[i].name, False); xv_settings[i].min = attr[j].min_value; xv_settings[i].max = attr[j].max_value; if ((attr[j].flags & XvGettable) && !xv_settings[i].restore) { xv_settings[i].restore = (XvGetPortAttribute(dpy, canvas->xv_port, xv_settings[i].atom, &xv_settings[i].xv_default) == Success); if (!xv_settings[i].restore) { xv_settings[i].restore = 2; } } break; } } } if (attr) { XFree(attr); } /* Apply color settings to XVideo. */ video_canvas_set_palette(canvas, canvas->palette); } }
void vidmode_shutdown(void) { unsigned int i; if (vm_is_enabled > 0 && vm_is_suspended == 0) { log_message(vidmode_log, "Disabling Vidmode"); XF86VidModeSwitchToMode(x11ui_get_display_ptr(), screen, vm_modes[0]); } if (vm_available == 0) { return; } for (i = 0; i < vm_index; i++) { lib_free(vm_bestmodes[i].name); } lib_free(vm_bestmodes); }
static void vidmode_center_canvas(struct video_canvas_s *canvas) { Display *vm_display; if (vm_available == 0) { return; } if (active_canvas != canvas) { return; } vm_display = x11ui_get_display_ptr(); x11ui_move_canvas_window(canvas->emuwindow, 0, 0); ui_dispatch_events(); x11ui_canvas_position(canvas->emuwindow, &x, &y); XF86VidModeSetViewPort(vm_display, screen, x + xoffs, y + yoffs); ui_dispatch_events(); }
int vidmode_init(void) { unsigned int hz; int i; Display *display; vidmode_log = log_open("VidMode"); display = x11ui_get_display_ptr(); if (!XF86VidModeGetAllModeLines(display, screen, &vm_mode_count, &vm_modes)) { log_error(vidmode_log, "Error getting video mode information - disabling vidmode extension."); vm_available = 0; return 0; } for (i = 0; i < vm_mode_count; i++) { if (vm_modes[i]->hdisplay <= 800 && vm_modes[i]->hdisplay >= 320 && vm_modes[i]->vdisplay <= 600 && vm_modes[i]->vdisplay >= 200) { vm_bestmodes = (vm_bestvideomode_t *)lib_realloc(vm_bestmodes, (vm_index + 1) * sizeof(vm_bestvideomode_t)); vm_bestmodes[vm_index].modeindex = i; if (vm_modes[i]->vtotal * vm_modes[i]->htotal) { hz = vm_modes[i]->dotclock * 1000 / (vm_modes[i]->vtotal * vm_modes[i]->htotal); } else { hz = 0; } vm_bestmodes[vm_index].name = lib_msprintf(" %ix%i-%iHz", vm_modes[i]->hdisplay, vm_modes[i]->vdisplay, hz); if (++vm_index > 29) { break; } } } if (vm_index == 0) { return 0; } vm_available = 1; return 0; }
int video_init(void) { XGCValues gc_values; Display *display; _video_gc = video_get_gc(&gc_values); display = x11ui_get_display_ptr(); x11video_log = log_open("X11Video"); color_init(); #ifdef USE_MITSHM if (!try_mitshm) { use_mitshm = 0; } else { /* This checks if the server has MITSHM extensions available If try_mitshm is true and we are on a different machine, frame_buffer_alloc will fall back to non shared memory calls. */ int major_version, minor_version, pixmap_flag; /* Check whether the server supports the Shared Memory Extension. */ if (!XShmQueryVersion(display, &major_version, &minor_version, &pixmap_flag)) { log_warning(x11video_log, "The MITSHM extension is not supported on this display."); use_mitshm = 0; } else { DEBUG_MITSHM((_("MITSHM extensions version %d.%d detected."), major_version, minor_version)); if (!pixmap_flag) { DEBUG_MITSHM(("The MITSHM extension is supported on this display, but shared pixmaps are not available.")); } use_mitshm = 1; } } #else use_mitshm = 0; #endif return 0; }
void uicolor_init_video_colors() { short i; XColor colorr, colorg, colorb; Display *display; display = x11ui_get_display_ptr(); for (i = 0; i < 256; i++) { colorr.flags = DoRed | DoGreen | DoBlue; colorr.red = i << 8; colorr.green = 0; colorr.blue = 0; colorg.flags = DoRed | DoGreen | DoBlue; colorg.red = 0; colorg.green = i << 8; colorg.blue = 0; colorb.flags = DoRed | DoGreen | DoBlue; colorb.red = 0; colorb.green = 0; colorb.blue = i << 8; if (!XAllocColor(display, colormap, &colorr)) { log_error(LOG_DEFAULT, "Cannot allocate color \"#%04X%04X%04X\".", colorr.red, colorr.green, colorr.blue); } if (!XAllocColor(display, colormap, &colorg)) { log_error(LOG_DEFAULT, "Cannot allocate color \"#%04X%04X%04X\".", colorg.red, colorg.green, colorg.blue); } if (!XAllocColor(display, colormap, &colorb)) { log_error(LOG_DEFAULT, "Cannot allocate color \"#%04X%04X%04X\".", colorb.red, colorb.green, colorb.blue); } video_render_setrawrgb(i, (DWORD)colorr.pixel, (DWORD)colorg.pixel, (DWORD)colorb.pixel); } video_render_initraw(); }
static int video_arch_frame_buffer_alloc(video_canvas_t *canvas, unsigned int width, unsigned int height) { int sizeofpixel = sizeof(BYTE); Display *display; #ifdef USE_MITSHM int (*olderrorhandler)(Display *, XErrorEvent *); #endif #ifdef USE_MITSHM canvas->using_mitshm = use_mitshm; #endif display = x11ui_get_display_ptr(); /* sizeof(PIXEL) is not always what we are using. I guess this should be checked from the XImage but I'm lazy... */ if (canvas->depth > 8) { sizeofpixel *= 2; } if (canvas->depth > 16) { sizeofpixel *= 2; } canvas->videoconfig->readable = 1; /* it's not direct rendering */ #ifdef HAVE_XVIDEO canvas->xv_image = NULL; if (canvas->videoconfig->hwscale) { #if defined(__QNX__) || defined(MINIX_SUPPORT) XShmSegmentInfo* shminfo = NULL; #else XShmSegmentInfo* shminfo = canvas->using_mitshm ? &canvas->xshm_info : NULL; #endif for (;;) { canvas->xv_image = create_yuv_image(display, canvas->xv_port, canvas->xv_format, width, height, shminfo); if (canvas->xv_image) { break; } if (shminfo) { #ifndef __QNX__ canvas->using_mitshm = 0; #endif shminfo = NULL; continue; } return -1; } XSync(display, False); /* Copy data for architecture independent rendering. */ canvas->yuv_image.width = canvas->xv_image->width; canvas->yuv_image.height = canvas->xv_image->height; canvas->yuv_image.data_size = canvas->xv_image->data_size; canvas->yuv_image.num_planes = canvas->xv_image->num_planes; canvas->yuv_image.pitches = canvas->xv_image->pitches; canvas->yuv_image.offsets = canvas->xv_image->offsets; canvas->yuv_image.data = (unsigned char *)canvas->xv_image->data; log_message(x11video_log, "Successfully initialized using XVideo (%dx%d %.4s)%s shared memory.", width, height, canvas->xv_format.label, #ifndef __QNX__ canvas->using_mitshm ? ", using" : " without"); #else " without"); #endif return 0; }
void vidmode_mouse_moved(struct video_canvas_s *canvas, int x, int y, int leave) { static int lastx, lasty; int winx, winy; int menu_h = 0; int status_h = 0; int wrap; Display *vm_display; Window shellwin; if (vm_available == 0) { return; } if (canvas->emuwindow == NULL) { return; } vm_display = x11ui_get_display_ptr(); if (vm_display == NULL) { return; } if (leave) { shellwin = x11ui_get_X11_window(); if (shellwin == 0) { return; } } if (leave == 1) { /* pointer left canvas */ #ifdef HAVE_FULLSCREEN menu_h = canvas->fullscreenconfig->ui_border_top; status_h = canvas->fullscreenconfig->ui_border_bottom; #endif x11ui_canvas_position(canvas->emuwindow, &winx, &winy); if (lastx < 20) { lastx = (vm->hdisplay + xoffs) - 2; } else if (lastx > ((vm->hdisplay + xoffs) - 20)) { lastx = 2; } /* only wrap around at y if menu/status is disabled */ wrap = 1; if (menu_h == 0) { if (lasty < 20) { lasty = (vm->vdisplay + yoffs) - 2; } else if (lasty > ((vm->vdisplay + yoffs) - 20)) { lasty = 2; } } else { if (lasty < 20) { wrap = 0; } else if (lasty > ((vm->vdisplay + yoffs) - (menu_h + status_h + 20))) { /* FIXME */ wrap = 0; } } lastx += (winx + xoffs); lasty += (winy + yoffs + menu_h); if (wrap) { XWarpPointer(vm_display, None, DefaultRootWindow(vm_display), 0, 0, vm->hdisplay, vm->vdisplay, lastx, lasty); /* grab the pointer and keyboard */ XGrabPointer(vm_display, shellwin, 1, PointerMotionMask, GrabModeAsync, GrabModeAsync, shellwin, None, CurrentTime); vidmode_center_canvas(canvas); /* ui_dispatch_events(); */ } } else if (leave == 2) { /* enter the canvas */ /* grab the pointer and keyboard */ XGrabPointer(vm_display, shellwin, 1, PointerMotionMask, GrabModeAsync, GrabModeAsync, shellwin, None, CurrentTime); /* vidmode_center_canvas(canvas); */ /* this crashes ? */ delayed_center = 1; } else { lastx = x; lasty = y; #ifdef HAVE_FULLSCREEN menu_h = canvas->fullscreenconfig->ui_border_top; #endif y -= (menu_h + yoffs); x -= (xoffs); wrap = 0; if (x < 1) { x = vm->hdisplay - 10; wrap = 1; } else if (x >= (vm->hdisplay-1)) { x = xoffs + 10; wrap = 1; } /* only wrap around at y if menu/status is disabled */ if (menu_h == 0) { if (y < 1) { y = vm->vdisplay - 10; wrap = 1; } else if (y >= (vm->vdisplay-1)) { y = ((menu_h + yoffs) * 2) + 50; /* FIXME */ wrap = 1; } } if (wrap) { XWarpPointer(vm_display, None, DefaultRootWindow(vm_display), 0, 0, vm->hdisplay, vm->vdisplay, x, y); vidmode_center_canvas(canvas); } else if (delayed_center) { delayed_center = 0; vidmode_center_canvas(canvas); } } }
static int video_arch_frame_buffer_alloc(video_canvas_t *canvas, unsigned int width, unsigned int height) { int sizeofpixel = sizeof(BYTE); Display *display; #ifdef USE_MITSHM int (*olderrorhandler)(Display *, XErrorEvent *); int dummy; #endif #ifdef USE_MITSHM canvas->using_mitshm = use_mitshm; #endif display = x11ui_get_display_ptr(); /* sizeof(PIXEL) is not always what we are using. I guess this should be checked from the XImage but I'm lazy... */ if (canvas->depth > 8) { sizeofpixel *= 2; } if (canvas->depth > 16) { sizeofpixel *= 2; } #ifdef HAVE_XVIDEO canvas->xv_image = NULL; if (canvas->videoconfig->hwscale) { #if defined(__QNX__) || defined(MINIX_SUPPORT) XShmSegmentInfo* shminfo = NULL; #else XShmSegmentInfo* shminfo = use_mitshm ? &canvas->xshm_info : NULL; #endif canvas->xv_image = create_yuv_image(display, canvas->xv_port, canvas->xv_format, width, height, shminfo); if (!(canvas->xv_image)) { return -1; } /* Copy data for architecture independent rendering. */ canvas->yuv_image.width = canvas->xv_image->width; canvas->yuv_image.height = canvas->xv_image->height; canvas->yuv_image.data_size = canvas->xv_image->data_size; canvas->yuv_image.num_planes = canvas->xv_image->num_planes; canvas->yuv_image.pitches = canvas->xv_image->pitches; canvas->yuv_image.offsets = canvas->xv_image->offsets; canvas->yuv_image.data = (unsigned char *)canvas->xv_image->data; log_message(x11video_log, "Successfully initialized using XVideo (%dx%d %.4s).", width, height, canvas->xv_format.label); return 0; } #endif /* HAVE_XVIDEO */ /* Round up to 32-bit boundary (used in XCreateImage). */ width = (width + 3) & ~0x3; #ifdef USE_MITSHM tryagain: if (canvas->using_mitshm) { DEBUG_MITSHM(("frame_buffer_alloc(): allocating XImage with MITSHM, %d x %d pixels...", width, height)); canvas->x_image = XShmCreateImage(display, visual, canvas->depth, ZPixmap, NULL, &(canvas->xshm_info), width, height); if (!canvas->x_image) { log_warning(x11video_log, "Cannot allocate XImage with XShm; falling back to non MITSHM extension mode."); canvas->using_mitshm = 0; goto tryagain; } DEBUG_MITSHM(("Done.")); DEBUG_MITSHM(("frame_buffer_alloc(): shmgetting %ld bytes...", (long)canvas->x_image->bytes_per_line * canvas->x_image->height)); canvas->xshm_info.shmid = shmget(IPC_PRIVATE, canvas->x_image->bytes_per_line * canvas->x_image->height, IPC_CREAT | 0604); if (canvas->xshm_info.shmid == -1) { log_warning(x11video_log, "Cannot get shared memory; falling back to non MITSHM extension mode."); XDestroyImage(canvas->x_image); canvas->using_mitshm = 0; goto tryagain; } DEBUG_MITSHM(("Done, id = 0x%x.", i->xshm_info.shmid)); DEBUG_MITSHM(("frame_buffer_alloc(): getting address... ")); canvas->xshm_info.shmaddr = shmat(canvas->xshm_info.shmid, 0, 0); canvas->x_image->data = canvas->xshm_info.shmaddr; if (canvas->xshm_info.shmaddr == (char *)-1) { log_warning(x11video_log, "Cannot get shared memory address; falling back to non MITSHM extension mode."); shmctl(canvas->xshm_info.shmid,IPC_RMID,0); XDestroyImage(canvas->x_image); canvas->using_mitshm = 0; goto tryagain; } DEBUG_MITSHM(("0x%lx OK.", (unsigned long) i->xshm_info.shmaddr)); canvas->xshm_info.readOnly = True; mitshm_failed = 0; XQueryExtension(display,"MIT-SHM",&shmmajor,&dummy,&dummy); olderrorhandler = XSetErrorHandler(shmhandler); if (!XShmAttach(display, &(canvas->xshm_info))) { log_warning(x11video_log, "Cannot attach shared memory; falling back to non MITSHM extension mode."); shmdt(canvas->xshm_info.shmaddr); shmctl(canvas->xshm_info.shmid,IPC_RMID,0); XDestroyImage(canvas->x_image); canvas->using_mitshm = 0; goto tryagain; } /* Wait for XShmAttach to fail or to succede. */ XSync(display,False); XSetErrorHandler(olderrorhandler); /* Mark memory segment for automatic deletion. */ shmctl(canvas->xshm_info.shmid, IPC_RMID, 0); if (mitshm_failed) { log_warning(x11video_log, "Cannot attach shared memory; falling back to non MITSHM extension mode."); shmdt(canvas->xshm_info.shmaddr); XDestroyImage(canvas->x_image); canvas->using_mitshm = 0; goto tryagain; } DEBUG_MITSHM((_("MITSHM initialization succeed.\n"))); video_refresh_func((void (*)(void))XShmPutImage); } else #endif { /* !i->using_mitshm */ char *data; data = lib_malloc(width * height * sizeofpixel); if (data == NULL) { return -1; } canvas->x_image = XCreateImage(display, visual, canvas->depth, ZPixmap, 0, data, width, height, 32, 0); if (!canvas->x_image) { return -1; } video_refresh_func((void (*)(void))XPutImage); } #ifdef USE_MITSHM log_message(x11video_log, "Successfully initialized%s shared memory.", (canvas->using_mitshm) ? ", using" : " without"); if (!(canvas->using_mitshm)) { log_warning(x11video_log, "Performance will be poor."); } #else log_message(x11video_log, "Successfully initialized without shared memory."); #endif return 0; }
void uicolor_free_color(unsigned int red, unsigned int green, unsigned int blue, unsigned long color_pixel) { if (!XFreeColors(x11ui_get_display_ptr(), colormap, &color_pixel, 1, 0)) { log_error(LOG_DEFAULT, "XFreeColors failed."); } }
video_canvas_t *video_canvas_create(video_canvas_t *canvas, unsigned int *width, unsigned int *height, int mapped) { int res; unsigned int new_width, new_height; XGCValues gc_values; canvas->depth = x11ui_get_display_depth(); new_width = *width; new_height = *height; if (canvas->videoconfig->doublesizex) { new_width *= 2; } if (canvas->videoconfig->doublesizey) { new_height *= 2; } #ifdef HAVE_XVIDEO /* Request specified video format. */ canvas->xv_format.id = fourcc; if (!find_yuv_port(x11ui_get_display_ptr(), &canvas->xv_port, &canvas->xv_format)) { if (canvas->videoconfig->hwscale) { log_message(x11video_log, "HW scaling not available"); canvas->videoconfig->hwscale = 0; } resources_set_int("HwScalePossible", 0); } #else resources_set_int("HwScalePossible", 0); #endif if (video_arch_frame_buffer_alloc(canvas, new_width, new_height) < 0) { return NULL; } res = ui_open_canvas_window(canvas, canvas->viewport->title, new_width, new_height, 1); if (res < 0) { return NULL; } if (!_video_gc) { _video_gc = video_get_gc(&gc_values); } canvas->width = new_width; canvas->height = new_height; ui_finish_canvas(canvas); if (canvas->depth > 8) { uicolor_init_video_colors(); } #ifdef HAVE_XVIDEO init_xv_settings(canvas); #endif #ifdef HAVE_OPENGL_SYNC openGL_sync_init(canvas); #endif return canvas; }
/* Refresh a canvas. */ void video_canvas_refresh(video_canvas_t *canvas, unsigned int xs, unsigned int ys, unsigned int xi, unsigned int yi, unsigned int w, unsigned int h) { Display *display; if (console_mode || vsid_mode) { return; } #ifdef HAVE_XVIDEO if (canvas->videoconfig->hwscale && canvas->xv_image) { int doublesize = canvas->videoconfig->doublesizex && canvas->videoconfig->doublesizey; #if defined(__QNX__) || defined(MINIX_SUPPORT) XShmSegmentInfo* shminfo = NULL; #else XShmSegmentInfo* shminfo = use_mitshm ? &canvas->xshm_info : NULL; #endif Window root; int x, y; unsigned int border_width, depth; unsigned int canvas_height; double local_aspect_ratio; display = x11ui_get_display_ptr(); render_yuv_image(doublesize, canvas->viewport, video_resources.delayloop_emulation, video_resources.pal_blur * 64 / 1000, video_resources.pal_scanlineshade * 1024 / 1000, canvas->xv_format, &canvas->yuv_image, canvas->draw_buffer->draw_buffer, canvas->draw_buffer->draw_buffer_width, canvas->videoconfig, xs, ys, w, h, xi, yi); /* * render_yuv_image() doesn't handle 1x2 drawing modes. * So it mistakenly fills only half the canvas vertically. * However, that is what we can use the hardware scaling for! */ canvas_height = canvas->height; if (trueaspect) { local_aspect_ratio = canvas->geometry->pixel_aspect_ratio; } else if (keepaspect) { local_aspect_ratio = aspect_ratio; } else { local_aspect_ratio = 0.0; } if (!doublesize && canvas->videoconfig->doublesizey) { canvas_height /= 2; local_aspect_ratio /= 2; } XGetGeometry(display, canvas->drawable, &root, &x, &y, &canvas->xv_geometry.w, &canvas->xv_geometry.h, &border_width, &depth); /* Xv does subpixel scaling. Since coordinates are in integers we refresh the entire image to get it right. */ display_yuv_image(display, canvas->xv_port, canvas->drawable, _video_gc, canvas->xv_image, shminfo, 0, 0, canvas->width, canvas_height, &canvas->xv_geometry, local_aspect_ratio); if (_video_use_xsync) { XSync(display, False); } return; } #endif if (canvas->videoconfig->doublesizex) { xi *= 2; w *= 2; } if (canvas->videoconfig->doublesizey) { yi *= 2; h *= 2; } #ifdef HAVE_FULLSCREEN if (canvas->video_fullscreen_refresh_func) { canvas->video_fullscreen_refresh_func(canvas, xs, ys, xi, yi, w, h); return; } #endif if (xi + w > canvas->width || yi + h > canvas->height) { log_debug("Attempt to draw outside canvas!\nXI%i YI%i W%i H%i CW%i CH%i\n", xi, yi, w, h, canvas->width, canvas->height); return; /* this makes `-fullscreen -80col' work XXX fix me some day */ } if ((int)xs >= 0) { /* some render routines don't like negative xs */ video_canvas_render(canvas, (BYTE *)canvas->x_image->data, w, h, xs, ys, xi, yi, canvas->x_image->bytes_per_line, canvas->x_image->bits_per_pixel); } /* This could be optimized away. */ display = x11ui_get_display_ptr(); _refresh_func(display, canvas->drawable, _video_gc, canvas->x_image, xi, yi, xi, yi, w, h, False, NULL, canvas); if (_video_use_xsync) { XSync(display, False); } }