void xf86_dga2_close_display(void)
{
	if(xf86ctx.device)
	{
		XFree(xf86ctx.device);
		xf86ctx.device = 0;
	}
	if(xf86ctx.modes)
	{
		XFree(xf86ctx.modes);
		xf86ctx.modes = 0;
	}
	if(xf86ctx.cmap)
	{
		XFreeColormap(display,xf86ctx.cmap);
		xf86ctx.cmap = 0;
	}
        sysdep_display_effect_close();
	xinput_close();
	if(xf86ctx.current_mode != -1)
	{
		/* HDG: is this really nescesarry ? */
		XDGASync(display,xf86ctx.screen);
#ifdef TDFX_DGA_WORKAROUND
		/* Restore the right video mode before leaving DGA  */
		/* The tdfx driver would have to do it, but it doesn't work ...*/
		XDGASetMode(display, xf86ctx.screen, xf86ctx.current_X11_mode);
#endif
		XDGASetMode(display, xf86ctx.screen, 0);
		xf86ctx.current_mode = -1;
	}
	XSync(display, True);
}
const char *xf86_dga2_update_display(mame_bitmap *bitmap,
	  rectangle *vis_area, rectangle *dirty_area,
	  struct sysdep_palette_struct *palette, int flags)
{
  rectangle my_dirty_area = *dirty_area;
  
  if (xf86ctx.max_page)
  {
    /* force a full screen update */
    if (xf86ctx.page_dirty)
    {
      my_dirty_area = *vis_area;
      xf86ctx.page_dirty--;
    }
    while(XDGAGetViewportStatus(display, xf86ctx.screen) & (0x01 <<
          (xf86ctx.max_page - 1)))
    {
    }
  }

  xf86ctx.page = (xf86ctx.page + 1) % (xf86ctx.max_page + 1);
  xf86ctx.update_display_func(bitmap, vis_area, &my_dirty_area,
        palette, xf86ctx.addr + xf86ctx.aligned_viewport_height *
	xf86ctx.page * xf86ctx.device->mode.bytesPerScanline, xf86ctx.width);

  if (xf86ctx.max_page)
  {
    XDGASetViewport(display, xf86ctx. screen, 0, xf86ctx.page *
      xf86ctx.aligned_viewport_height, XDGAFlipRetrace);

    /* If the dirty area has changed force a fullscreen update the next
       max_page updates, so that it gets updated in all pages */
    if (memcmp(&xf86ctx.old_dirty_area, dirty_area, sizeof(xf86ctx.old_dirty_area)))
    {
      xf86ctx.old_dirty_area = *dirty_area;
      xf86ctx.page_dirty = xf86ctx.max_page;
    }
  }

  XDGASync(display,xf86ctx.screen);
  
  return NULL;
}
Beispiel #3
0
static int config(uint32_t width, uint32_t height,
                       uint32_t d_width, uint32_t d_height,
                       uint32_t flags, char *title, uint32_t format)
{

    int x_off, y_off;
    int wanted_width, wanted_height;

    static unsigned char *vo_dga_base;
    static int prev_width, prev_height;

#ifdef HAVE_DGA2
    // needed to change DGA video mode
    int mX = VO_DGA_INVALID_RES, mY = VO_DGA_INVALID_RES, mVBI =
        100000, mMaxY = 0, i, j = 0;
    int dga_modenum;
    XDGAMode *modeline;
    XDGADevice *dgadevice;
#else
#ifdef HAVE_XF86VM
    unsigned int vm_event, vm_error;
    unsigned int vm_ver, vm_rev;
    int i, j = 0, have_vm = 0;
    int mX = VO_DGA_INVALID_RES, mY = VO_DGA_INVALID_RES, mVBI =
        100000, mMaxY = 0, dga_modenum;
#endif
    int bank, ram;
#endif

    vo_dga_src_format = format;

    wanted_width = d_width;
    wanted_height = d_height;

    if (!wanted_height)
        wanted_height = height;
    if (!wanted_width)
        wanted_width = width;

    if (!vo_dbpp)
    {
        if ((format & IMGFMT_BGR_MASK) == IMGFMT_BGR)
        {
            vo_dga_src_mode = vd_ModeValid(format & 0xff);
        }
    } else
    {
        vo_dga_src_mode = vd_ModeValid(vo_dbpp);
    }
    vo_dga_hw_mode = SRC_MODE.vdm_hw_mode;

    if (!vo_dga_src_mode)
    {
        mp_msg(MSGT_VO, MSGL_ERR, "vo_dga: unsupported video format!\n");
        return 1;
    }

    vo_dga_vp_width = vo_screenwidth;
    vo_dga_vp_height = vo_screenheight;

    mp_msg(MSGT_VO, MSGL_V, "vo_dga: XServer res: %dx%d\n",
           vo_dga_vp_width, vo_dga_vp_height);

// choose a suitable mode ...

#ifdef HAVE_DGA2
// Code to change the video mode added by Michael Graffam
// [email protected]

    mp_msg(MSGT_VO, MSGL_V, "vo_dga: vo_modelines=%p, vo_modecount=%d\n",
           vo_modelines, vo_modecount);

    if (vo_modelines == NULL)
    {
        mp_msg(MSGT_VO, MSGL_ERR, "vo_dga: can't get modelines\n");
        return 1;
    }

    mp_msg(MSGT_VO, MSGL_INFO,
           "vo_dga: DGA 2.0 available :-) Can switch resolution AND depth!\n");
    for (i = 0; i < vo_modecount; i++)
    {
        if (vd_ModeEqual(vo_modelines[i].depth,
                         vo_modelines[i].bitsPerPixel,
                         vo_modelines[i].redMask,
                         vo_modelines[i].greenMask,
                         vo_modelines[i].blueMask, vo_dga_hw_mode))
        {

            mp_msg(MSGT_VO, MSGL_V, "maxy: %4d, depth: %2d, %4dx%4d, ",
                   vo_modelines[i].maxViewportY, vo_modelines[i].depth,
                   vo_modelines[i].imageWidth,
                   vo_modelines[i].imageHeight);
            if (check_res
                (i, wanted_width, wanted_height, vo_modelines[i].depth,
                 vo_modelines[i].viewportWidth,
                 vo_modelines[i].viewportHeight,
                 (unsigned) vo_modelines[i].verticalRefresh,
                 vo_modelines[i].maxViewportY, &mX, &mY, &mVBI, &mMaxY))
                j = i;
        }
    }
    mp_msg(MSGT_VO, MSGL_INFO,
           "vo_dga: Selected hardware mode %4d x %4d @ %3d Hz @ depth %2d, bitspp %2d.\n",
           mX, mY, mVBI, HW_MODE.vdm_depth, HW_MODE.vdm_bitspp);
    mp_msg(MSGT_VO, MSGL_INFO,
           "vo_dga: Video parameters by codec: %3d x %3d, depth %2d, bitspp %2d.\n",
           width, height, SRC_MODE.vdm_depth, SRC_MODE.vdm_bitspp);
    vo_dga_vp_width = mX;
    vo_dga_vp_height = mY;

    if ((flags & VOFLAG_SWSCALE) || (flags & VOFLAG_FULLSCREEN))
    {                           /* -zoom or -fs */
        scale_dstW = (d_width + 7) & ~7;
        scale_dstH = d_height;
        scale_srcW = width;
        scale_srcH = height;
        aspect_save_screenres(mX, mY);
        aspect_save_orig(scale_srcW, scale_srcH);
        aspect_save_prescale(scale_dstW, scale_dstH);
        if (flags & VOFLAG_FULLSCREEN)       /* -fs */
            aspect(&scale_dstW, &scale_dstH, A_ZOOM);
        else if (flags & VOFLAG_SWSCALE)  /* -fs */
            aspect(&scale_dstW, &scale_dstH, A_NOZOOM);
        mp_msg(MSGT_VO, MSGL_INFO,
               "vo_dga: Aspect corrected size for SwScaler: %4d x %4d.\n",
               scale_dstW, scale_dstH);
        /* XXX this is a hack, but I'm lazy ;-) :: atmos */
        width = scale_dstW;
        height = scale_dstH;
    }

    vo_dga_width = vo_modelines[j].bytesPerScanline / HW_MODE.vdm_bytespp;
    dga_modenum = vo_modelines[j].num;
    modeline = vo_modelines + j;

#else

#ifdef HAVE_XF86VM

    mp_msg(MSGT_VO, MSGL_INFO,
           "vo_dga: DGA 1.0 compatibility code: Using XF86VidMode for mode switching!\n");

    if (XF86VidModeQueryExtension(mDisplay, &vm_event, &vm_error))
    {
        XF86VidModeQueryVersion(mDisplay, &vm_ver, &vm_rev);
        mp_msg(MSGT_VO, MSGL_INFO,
               "vo_dga: XF86VidMode Extension v%i.%i\n", vm_ver, vm_rev);
        have_vm = 1;
    } else
    {
        mp_msg(MSGT_VO, MSGL_ERR,
               "vo_dga: XF86VidMode Extension not available.\n");
    }

#define GET_VREFRESH(dotclk, x, y)( (((dotclk)/(x))*1000)/(y) )

    if (have_vm)
    {
        int modecount;

        XF86VidModeGetAllModeLines(mDisplay, mScreen, &modecount,
                                   &vo_dga_vidmodes);

        if (vo_dga_vidmodes != NULL)
        {
            for (i = 0; i < modecount; i++)
            {
                if (check_res(i, wanted_width, wanted_height,
                              vo_dga_modes[vo_dga_hw_mode].vdm_depth,
                              vo_dga_vidmodes[i]->hdisplay,
                              vo_dga_vidmodes[i]->vdisplay,
                              GET_VREFRESH(vo_dga_vidmodes[i]->dotclock,
                                           vo_dga_vidmodes[i]->htotal,
                                           vo_dga_vidmodes[i]->vtotal),
                              0, &mX, &mY, &mVBI, &mMaxY))
                    j = i;
            }

            mp_msg(MSGT_VO, MSGL_INFO,
                   "vo_dga: Selected video mode %4d x %4d @ %3d Hz @ depth %2d, bitspp %2d, video %3d x %3d.\n",
                   mX, mY, mVBI,
                   vo_dga_modes[vo_dga_hw_mode].vdm_depth,
                   vo_dga_modes[vo_dga_hw_mode].vdm_bitspp, width, height);
        } else
        {
            mp_msg(MSGT_VO, MSGL_INFO,
                   "vo_dga: XF86VidMode returned no screens - using current resolution.\n");
        }
        dga_modenum = j;
        vo_dga_vp_width = mX;
        vo_dga_vp_height = mY;
    }

#else
    mp_msg(MSGT_VO, MSGL_INFO,
           "vo_dga: Only have DGA 1.0 extension and no XF86VidMode :-(\n");
    mp_msg(MSGT_VO, MSGL_INFO,
           "        Thus, resolution switching is NOT possible.\n");

#endif
#endif

    vo_dga_src_width = width;
    vo_dga_src_height = height;

    if (vo_dga_src_width > vo_dga_vp_width ||
        vo_dga_src_height > vo_dga_vp_height)
    {
        mp_msg(MSGT_VO, MSGL_ERR,
               "vo_dga: Sorry, video larger than viewport is not yet supported!\n");
        // ugly, do something nicer in the future ...
#ifndef HAVE_DGA2
#ifdef HAVE_XF86VM
        if (vo_dga_vidmodes)
        {
            XFree(vo_dga_vidmodes);
            vo_dga_vidmodes = NULL;
        }
#endif
#endif
        return 1;
    }

    if (vo_dga_vp_width == VO_DGA_INVALID_RES)
    {
        mp_msg(MSGT_VO, MSGL_ERR,
               "vo_dga: Something is wrong with your DGA. There doesn't seem to be a\n"
               "         single suitable mode!\n"
               "         Please file a bug report (see DOCS/HTML/en/bugreports.html)\n");
#ifndef HAVE_DGA2
#ifdef HAVE_XF86VM
        if (vo_dga_vidmodes)
        {
            XFree(vo_dga_vidmodes);
            vo_dga_vidmodes = NULL;
        }
#endif
#endif
        return 1;
    }
// now let's start the DGA thing 

    if (!vo_config_count || width != prev_width || height != prev_height)
    {
#ifdef HAVE_DGA2

        if (!XDGAOpenFramebuffer(mDisplay, mScreen))
        {
            mp_msg(MSGT_VO, MSGL_ERR,
                   "vo_dga: Framebuffer mapping failed!!!\n");
            return 1;
        }

        dgadevice = XDGASetMode(mDisplay, mScreen, dga_modenum);
        XDGASync(mDisplay, mScreen);

        vo_dga_base = dgadevice->data;
        XFree(dgadevice);

        XDGASetViewport(mDisplay, mScreen, 0, 0, XDGAFlipRetrace);

#else

#ifdef HAVE_XF86VM
        if (have_vm)
        {
            XF86VidModeLockModeSwitch(mDisplay, mScreen, 0);
            // Two calls are needed to switch modes on my ATI Rage 128. Why?
            // for riva128 one call is enough!
            XF86VidModeSwitchToMode(mDisplay, mScreen,
                                    vo_dga_vidmodes[dga_modenum]);
            XF86VidModeSwitchToMode(mDisplay, mScreen,
                                    vo_dga_vidmodes[dga_modenum]);
        }
#endif

        XF86DGAGetViewPortSize(mDisplay, mScreen,
                               &vo_dga_vp_width, &vo_dga_vp_height);

        XF86DGAGetVideo(mDisplay, mScreen,
                        (char **) &vo_dga_base, &vo_dga_width, &bank,
                        &ram);

        XF86DGADirectVideo(mDisplay, mScreen,
                           XF86DGADirectGraphics | XF86DGADirectMouse |
                           XF86DGADirectKeyb);

        XF86DGASetViewPort(mDisplay, mScreen, 0, 0);

#endif
    }
    // do some more checkings here ...

    mp_msg(MSGT_VO, MSGL_V,
           "vo_dga: bytes/line: %d, screen res: %dx%d, depth: %d, base: %p, bpp: %d\n",
           vo_dga_width, vo_dga_vp_width, vo_dga_vp_height,
           HW_MODE.vdm_bytespp, vo_dga_base, HW_MODE.vdm_bitspp);

    x_off = (vo_dga_vp_width - vo_dga_src_width) >> 1;
    y_off = (vo_dga_vp_height - vo_dga_src_height) >> 1;

    vo_dga_bytes_per_line = vo_dga_src_width * HW_MODE.vdm_bytespp;
    vo_dga_lines = vo_dga_src_height;

    vo_dga_src_offset = 0;
    vo_dga_vp_offset =
        (y_off * vo_dga_width + x_off) * HW_MODE.vdm_bytespp;

    vo_dga_vp_skip = (vo_dga_width - vo_dga_src_width) * HW_MODE.vdm_bytespp;   // todo

    mp_msg(MSGT_VO, MSGL_V, "vo_dga: vp_off=%d, vp_skip=%d, bpl=%d\n",
           vo_dga_vp_offset, vo_dga_vp_skip, vo_dga_bytes_per_line);


    XGrabKeyboard(mDisplay, DefaultRootWindow(mDisplay), True,
                  GrabModeAsync, GrabModeAsync, CurrentTime);
    if (vo_grabpointer)
        XGrabPointer(mDisplay, DefaultRootWindow(mDisplay), True,
                     ButtonPressMask, GrabModeAsync, GrabModeAsync,
                     None, None, CurrentTime);

    if (!vo_config_count || width != prev_width || height != prev_height)
    {
        init_video_buffers(vo_dga_base,
                           vo_dga_vp_height,
                           vo_dga_width * HW_MODE.vdm_bytespp,
#ifdef HAVE_DGA2
                           modeline->maxViewportY,
#else
                           vo_dga_vp_height,
#endif
                           vo_doublebuffering);
        prev_width = width;
        prev_height = height;
    }

    mp_msg(MSGT_VO, MSGL_V, "vo_dga: Using %d frame buffer%s.\n",
           vo_dga_nr_video_buffers,
           vo_dga_nr_video_buffers == 1 ? "" : "s");

    vo_dga_is_running = 1;
    return 0;
}