Exemple #1
0
/* 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
}
Exemple #2
0
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;
}
Exemple #3
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);
    }
}
Exemple #4
0
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;
}
Exemple #5
0
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);
}
Exemple #6
0
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);
}
Exemple #7
0
/* 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);
}
Exemple #8
0
void
openGL_sync_shutdown(void)
{
    if (openGL_sync)
	set_openGL_sync(0, NULL);
    if (cx)
    {
	glXDestroyContext(x11ui_get_display_ptr(), cx);
	cx = NULL;
    }
}
Exemple #9
0
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;
}
Exemple #10
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;
}
Exemple #11
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();
}
Exemple #12
0
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();
}
Exemple #13
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);

        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);
    }
}
Exemple #14
0
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);
}
Exemple #15
0
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();
}
Exemple #16
0
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;
}
Exemple #17
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;
}
Exemple #18
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();
}
Exemple #19
0
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;
    }
Exemple #20
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);
        }
    }
}
Exemple #21
0
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;
}
Exemple #22
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.");
    }
}
Exemple #23
0
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;
}
Exemple #24
0
/* 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);
    }
}