[Spice-devel] [PATCH 2/7] qxl: split user modesetting code and crtc code out.

airlied at gmail.com airlied at gmail.com
Sun Feb 24 21:31:10 PST 2013


From: Dave Airlie <airlied at gmail.com>

This splits the UMS modesetting and xf86Crtc code out into a separate file.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/Makefile.am    |   6 +-
 src/qxl.h          |  19 ++
 src/qxl_driver.c   | 965 +----------------------------------------------------
 src/qxl_ums_mode.c | 507 ++++++++++++++++++++++++++++
 src/qxl_uxa.c      |  53 +--
 5 files changed, 566 insertions(+), 984 deletions(-)
 create mode 100644 src/qxl_ums_mode.c

diff --git a/src/Makefile.am b/src/Makefile.am
index 6950ba5..c383514 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -51,7 +51,9 @@ qxl_drv_la_SOURCES =				\
 	qxl_option_helpers.c		\
 	qxl_option_helpers.h		\
 	qxl_edid.c			\
-	compat-api.h
+	qxl_uxa.c			\
+	qxl_ums_mode.c                     \
+	compat-api.h 
 endif
 
 if BUILD_XSPICE
@@ -91,5 +93,7 @@ spiceqxl_drv_la_SOURCES =				\
 	qxl_cursor.c				\
 	qxl_edid.c				\
 	dfps.c				        \
+	qxl_uxa.c                               \
+	qxl_ums_mode.c                     	\
 	compat-api.h
 endif
diff --git a/src/qxl.h b/src/qxl.h
index 8e2802a..09e9486 100644
--- a/src/qxl.h
+++ b/src/qxl.h
@@ -416,11 +416,14 @@ void		   qxl_surface_composite (qxl_surface_t *dest,
 					  int dst_x, int dst_y,
 					  int width, int height);
 
+/* UXA */
 #if HAS_DEVPRIVATEKEYREC
 extern DevPrivateKeyRec uxa_pixmap_index;
 #else
 extern int uxa_pixmap_index;
 #endif
+Bool
+qxl_uxa_init (qxl_screen_t *qxl, ScreenPtr screen);
 
 static inline qxl_surface_t *get_surface (PixmapPtr pixmap)
 {
@@ -445,6 +448,15 @@ get_ram_header (qxl_screen_t *qxl)
 
 void qxl_surface_upload_primary_regions(qxl_screen_t *qxl, PixmapPtr pixmap, RegionRec *r);
 
+/* ums randr code */
+void qxl_init_randr (ScrnInfoPtr pScrn, qxl_screen_t *qxl);
+void qxl_initialize_x_modes (qxl_screen_t *qxl, ScrnInfoPtr pScrn,
+                        unsigned int *max_x, unsigned int *max_y);
+void qxl_update_edid (qxl_screen_t *qxl);
+Bool qxl_create_desired_modes (qxl_screen_t *qxl);
+
+Bool qxl_resize_primary (qxl_screen_t *qxl, uint32_t width, uint32_t height);
+void qxl_io_monitors_config_async (qxl_screen_t *qxl);
 /*
  * Images
  */
@@ -538,4 +550,11 @@ SpiceServer *xspice_get_spice_server(void);
 
 #endif /* XSPICE */
 
+#ifdef WITH_CHECK_POINT
+#define CHECK_POINT() ErrorF ("%s: %d  (%s)\n", __FILE__, __LINE__, __FUNCTION__);
+#else
+#define CHECK_POINT()
+#endif
+
+
 #endif // QXL_H
diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index 5f70519..fdfee89 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -61,12 +61,6 @@
 
 extern void compat_init_scrn (ScrnInfoPtr);
 
-#ifdef WITH_CHECK_POINT
-#define CHECK_POINT() ErrorF ("%s: %d  (%s)\n", __FILE__, __LINE__, __FUNCTION__);
-#else
-#define CHECK_POINT()
-#endif
-
 #define BREAKPOINT()   do { __asm__ __volatile__ ("int $03"); } while (0)
 
 const OptionInfoRec DefaultOptions[] =
@@ -134,14 +128,6 @@ const OptionInfoRec DefaultOptions[] =
     { -1, NULL, OPTV_NONE, {0}, FALSE }
 };
 
-
-/* These constants govern which modes are reported to X as preferred */
-#define DEFAULT_WIDTH       1024
-#define DEFAULT_HEIGHT       768
-
-static void qxl_update_monitors_config (qxl_screen_t *qxl);
-
-
 static const OptionInfoRec *
 qxl_available_options (int chipid, int busid)
 {
@@ -301,7 +287,7 @@ qxl_io_flush_release (qxl_screen_t *qxl)
 
 #endif
 
-static void
+void
 qxl_io_monitors_config_async (qxl_screen_t *qxl)
 {
 #ifndef XSPICE
@@ -1011,7 +997,7 @@ qxl_resize_primary_to_virtual (qxl_screen_t *qxl)
     return TRUE;
 }
 
-static Bool
+Bool
 qxl_resize_primary (qxl_screen_t *qxl, uint32_t width, uint32_t height)
 {
     qxl->virtual_x = width;
@@ -1037,157 +1023,6 @@ qxl_switch_mode (SWITCH_MODE_ARGS_DECL)
     return qxl_resize_primary_to_virtual (qxl);
 }
 
-static int
-check_crtc (qxl_screen_t *qxl)
-{
-    int i, count = 0;
-    xf86CrtcPtr crtc;
-    
-    if (qxl->crtcs == NULL) {
-        return 0;
-    }
-
-    for (i = 0 ; i < qxl->num_heads; ++i)
-    {
-	crtc = qxl->crtcs[i];
-
-	if (!crtc->enabled || crtc->mode.CrtcHDisplay == 0 ||
-	    crtc->mode.CrtcVDisplay == 0)
-	{
-	    continue;
-	}
-	count++;
-    }
-    
-#if 0
-    if (count == 0)
-    {
-	ErrorF ("check crtc failed, count == 0!!\n");
-	BREAKPOINT ();
-    }
-#endif
-    
-    return count;
-}
-
-static void
-qxl_update_monitors_config (qxl_screen_t *qxl)
-{
-    int i;
-    QXLHead *head;
-    xf86CrtcPtr crtc;
-    qxl_output_private *qxl_output;
-    QXLRam * ram = get_ram_header (qxl);
-    
-    if (check_crtc (qxl) == 0)
-        return;
-    
-    qxl->monitors_config->count = 0;
-    qxl->monitors_config->max_allowed = qxl->num_heads;
-    for (i = 0 ; i < qxl->num_heads; ++i)
-    {
-	head = &qxl->monitors_config->heads[qxl->monitors_config->count];
-	crtc = qxl->crtcs[i];
-	qxl_output = qxl->outputs[i]->driver_private;
-	head->id = i;
-	head->surface_id = 0;
-	head->flags = 0;
-
-	if (!crtc->enabled || crtc->mode.CrtcHDisplay == 0 ||
-	    crtc->mode.CrtcVDisplay == 0)
-	{
-	    head->width = head->height = head->x = head->y = 0;
-	    qxl_output->status = XF86OutputStatusDisconnected;
-	}
-	else
-	{
-	    head->width = crtc->mode.CrtcHDisplay;
-	    head->height = crtc->mode.CrtcVDisplay;
-	    head->x = crtc->x;
-	    head->y = crtc->y;
-	    qxl->monitors_config->count++;
-	    qxl_output->status = XF86OutputStatusConnected;
-	}
-    }
-    /* initialize when actually used, memslots should be initialized by now */
-    if (ram->monitors_config == 0)
-    {
-	ram->monitors_config = physical_address (qxl, qxl->monitors_config,
-	                                         qxl->main_mem_slot);
-    }
-    
-    qxl_io_monitors_config_async (qxl);
-}
-
-static Bool
-crtc_set_mode_major (xf86CrtcPtr crtc, DisplayModePtr mode,
-                     Rotation rotation, int x, int y)
-{
-    qxl_crtc_private *crtc_private = crtc->driver_private;
-    qxl_screen_t *    qxl = crtc_private->qxl;
-    
-    if (crtc == qxl->crtcs[0] && mode == NULL)
-    {
-	/* disallow disabling of monitor 0 mode */
-	ErrorF ("%s: not allowing crtc 0 disablement\n", __func__);
-	return FALSE;
-    }
-    
-    crtc->mode = *mode;
-    crtc->x = x;
-    crtc->y = y;
-    crtc->rotation = rotation;
-#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC (1, 5, 99, 0, 0)
-    crtc->transformPresent = FALSE;
-#endif
-    qxl_output_edid_set (crtc_private->output, crtc_private->head, mode);
-    
-    return TRUE;
-}
-
-static Bool
-qxl_create_desired_modes (qxl_screen_t *qxl)
-{
-    int i;
-    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (qxl->pScrn);
-    
-    CHECK_POINT ();
-    
-    for (i = 0 ; i < config->num_crtc; ++i)
-    {
-	xf86CrtcPtr crtc = config->crtc[i];
-	if (!crtc->enabled)
-	    continue;
-	
-	if (!crtc_set_mode_major (
-		crtc, &crtc->desiredMode, crtc->desiredRotation,
-		crtc->desiredX, crtc->desiredY))
-	{
-	    return FALSE;
-	}
-    }
-    
-    qxl_update_monitors_config (qxl);
-    return TRUE;
-}
-
-static void
-qxl_update_edid (qxl_screen_t *qxl)
-{
-    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (qxl->pScrn); 
-    int i;
-   
-    for (i = 0; i < config->num_crtc; ++i)
-    {
-	xf86CrtcPtr crtc = config->crtc[i];
-
-	if (!crtc->enabled)
-	    continue;
-	
-	qxl_output_edid_set (qxl->outputs[i], i, &crtc->desiredMode);
-    }
-}
-
 static Bool
 qxl_create_screen_resources (ScreenPtr pScreen)
 {
@@ -1235,482 +1070,6 @@ qxl_create_screen_resources (ScreenPtr pScreen)
     return TRUE;
 }
 
-#if HAS_DEVPRIVATEKEYREC
-DevPrivateKeyRec uxa_pixmap_index;
-#else
-int uxa_pixmap_index;
-#endif
-
-static Bool
-qxl_prepare_access (PixmapPtr pixmap, RegionPtr region, uxa_access_t access)
-{
-    return qxl_surface_prepare_access (get_surface (pixmap),
-                                       pixmap, region, access);
-}
-
-static void
-qxl_finish_access (PixmapPtr pixmap)
-{
-    qxl_surface_finish_access (get_surface (pixmap), pixmap);
-}
-
-static Bool
-qxl_pixmap_is_offscreen (PixmapPtr pixmap)
-{
-    return !!get_surface (pixmap);
-}
-
-static Bool
-good_alu_and_pm (DrawablePtr drawable, int alu, Pixel planemask)
-{
-    if (!UXA_PM_IS_SOLID (drawable, planemask))
-	return FALSE;
-    
-    if (alu != GXcopy)
-	return FALSE;
-    
-    return TRUE;
-}
-
-/*
- * Solid fill
- */
-static Bool
-qxl_check_solid (DrawablePtr drawable, int alu, Pixel planemask)
-{
-    if (!good_alu_and_pm (drawable, alu, planemask))
-	return FALSE;
-    
-    return TRUE;
-}
-
-static Bool
-qxl_prepare_solid (PixmapPtr pixmap, int alu, Pixel planemask, Pixel fg)
-{
-    qxl_surface_t *surface;
-    
-    if (!(surface = get_surface (pixmap)))
-	return FALSE;
-    
-    return qxl_surface_prepare_solid (surface, fg);
-}
-
-static void
-qxl_solid (PixmapPtr pixmap, int x1, int y1, int x2, int y2)
-{
-    qxl_surface_solid (get_surface (pixmap), x1, y1, x2, y2);
-}
-
-static void
-qxl_done_solid (PixmapPtr pixmap)
-{
-}
-
-/*
- * Copy
- */
-static Bool
-qxl_check_copy (PixmapPtr source, PixmapPtr dest,
-                int alu, Pixel planemask)
-{
-    if (!good_alu_and_pm ((DrawablePtr)source, alu, planemask))
-	return FALSE;
-    
-    if (source->drawable.bitsPerPixel != dest->drawable.bitsPerPixel)
-    {
-	ErrorF ("differing bitsperpixel - this shouldn't happen\n");
-	return FALSE;
-    }
-    
-    return TRUE;
-}
-
-static Bool
-qxl_prepare_copy (PixmapPtr source, PixmapPtr dest,
-                  int xdir, int ydir, int alu,
-                  Pixel planemask)
-{
-    return qxl_surface_prepare_copy (get_surface (dest), get_surface (source));
-}
-
-static void
-qxl_copy (PixmapPtr dest,
-          int src_x1, int src_y1,
-          int dest_x1, int dest_y1,
-          int width, int height)
-{
-    qxl_surface_copy (get_surface (dest),
-                      src_x1, src_y1,
-                      dest_x1, dest_y1,
-                      width, height);
-}
-
-static void
-qxl_done_copy (PixmapPtr dest)
-{
-}
-
-/*
- * Composite
- */
-static Bool
-can_accelerate_picture (PicturePtr pict)
-{
-    if (!pict)
-	return TRUE;
-
-    if (pict->format != PICT_a8r8g8b8		&&
-	pict->format != PICT_x8r8g8b8		&&
-	pict->format != PICT_a8)
-    {
-	return FALSE;
-    }
-
-    if (!pict->pDrawable)
-	return FALSE;
-
-    if (pict->transform)
-    {
-	if (pict->transform->matrix[2][0] != 0	||
-	    pict->transform->matrix[2][1] != 0	||
-	    pict->transform->matrix[2][2] != pixman_int_to_fixed (1))
-	{
-	    return FALSE;
-	}
-    }
-
-    if (pict->filter != PictFilterBilinear	&&
-	pict->filter != PictFilterNearest)
-    {
-	return FALSE;
-    }
-    
-    return TRUE;
-}
-
-#define QXL_HAS_CAP(qxl, cap)						\
-    (((qxl)->rom->client_capabilities[(cap) / 8]) & (1 << ((cap) % 8)))
-
-static Bool
-qxl_has_composite (qxl_screen_t *qxl)
-{
-#ifndef XSPICE
-    return
-	qxl->pci->revision >= 4			&&
-	QXL_HAS_CAP (qxl, SPICE_DISPLAY_CAP_COMPOSITE);
-#else
-    /* FIXME */
-    return FALSE;
-#endif
-}
-
-static Bool
-qxl_has_a8_surfaces (qxl_screen_t *qxl)
-{
-#ifndef XSPICE
-    return
-	qxl->pci->revision >= 4			&&
-	QXL_HAS_CAP (qxl, SPICE_DISPLAY_CAP_A8_SURFACE);
-#else
-    /* FIXME */
-    return FALSE;
-#endif
-}
-
-static Bool
-qxl_check_composite (int op,
-		     PicturePtr pSrcPicture,
-		     PicturePtr pMaskPicture,
-		     PicturePtr pDstPicture,
-		     int width, int height)
-{
-    int i;
-    ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
-    ScrnInfoPtr pScrn = xf86ScreenToScrn (pScreen);
-    qxl_screen_t *qxl = pScrn->driverPrivate;
-    
-    static const int accelerated_ops[] =
-    {
-	PictOpClear, PictOpSrc, PictOpDst, PictOpOver, PictOpOverReverse,
-	PictOpIn, PictOpInReverse, PictOpOut, PictOpOutReverse,
-	PictOpAtop, PictOpAtopReverse, PictOpXor, PictOpAdd,
-	PictOpSaturate, PictOpMultiply, PictOpScreen, PictOpOverlay,
-	PictOpDarken, PictOpLighten, PictOpColorDodge, PictOpColorBurn,
-	PictOpHardLight, PictOpSoftLight, PictOpDifference, PictOpExclusion,
-	PictOpHSLHue, PictOpHSLSaturation, PictOpHSLColor, PictOpHSLLuminosity,
-    };
-
-    if (!qxl_has_composite (qxl))
-	return FALSE;
-    
-    if (!can_accelerate_picture (pSrcPicture)	||
-	!can_accelerate_picture (pMaskPicture)	||
-	!can_accelerate_picture (pDstPicture))
-    {
-	return FALSE;
-    }
-
-    for (i = 0; i < sizeof (accelerated_ops) / sizeof (accelerated_ops[0]); ++i)
-    {
-	if (accelerated_ops[i] == op)
-	    goto found;
-    }
-    return FALSE;
-
-found:
-    return TRUE;
-}
-
-static Bool
-qxl_check_composite_target (PixmapPtr pixmap)
-{
-    return TRUE;
-}
-
-static Bool
-qxl_check_composite_texture (ScreenPtr screen,
-			     PicturePtr pPicture)
-{
-    return TRUE;
-}
-
-static Bool
-qxl_prepare_composite (int op,
-		       PicturePtr pSrcPicture,
-		       PicturePtr pMaskPicture,
-		       PicturePtr pDstPicture,
-		       PixmapPtr pSrc,
-		       PixmapPtr pMask,
-		       PixmapPtr pDst)
-{
-    return qxl_surface_prepare_composite (
-	op, pSrcPicture, pMaskPicture, pDstPicture,
-	get_surface (pSrc),
-	pMask? get_surface (pMask) : NULL,
-	get_surface (pDst));
-}
-
-static void
-qxl_composite (PixmapPtr pDst,
-	       int src_x, int src_y,
-	       int mask_x, int mask_y,
-	       int dst_x, int dst_y,
-	       int width, int height)
-{
-    qxl_surface_composite (
-	get_surface (pDst),
-	src_x, src_y,
-	mask_x, mask_y,
-	dst_x, dst_y, width, height);
-}
-
-static void
-qxl_done_composite (PixmapPtr pDst)
-{
-    ;
-}
-
-static Bool
-qxl_put_image (PixmapPtr pDst, int x, int y, int w, int h,
-               char *src, int src_pitch)
-{
-    qxl_surface_t *surface = get_surface (pDst);
-    
-    if (surface)
-	return qxl_surface_put_image (surface, x, y, w, h, src, src_pitch);
-    
-    return FALSE;
-}
-
-static void
-qxl_set_screen_pixmap (PixmapPtr pixmap)
-{
-    pixmap->drawable.pScreen->devPrivate = pixmap;
-}
-
-static PixmapPtr
-qxl_create_pixmap (ScreenPtr screen, int w, int h, int depth, unsigned usage)
-{
-    ScrnInfoPtr    scrn = xf86ScreenToScrn (screen);
-    PixmapPtr      pixmap;
-    qxl_screen_t * qxl = scrn->driverPrivate;
-    qxl_surface_t *surface;
-    
-    if (w > 32767 || h > 32767)
-	return NULL;
-    
-    qxl_surface_cache_sanity_check (qxl->surface_cache);
-    
-#if 0
-    ErrorF ("Create pixmap: %d %d @ %d (usage: %d)\n", w, h, depth, usage);
-#endif
-    
-    if (uxa_swapped_out (screen))
-	goto fallback;
-
-    if (depth == 8 && !qxl_has_a8_surfaces (qxl))
-    {
-	/* FIXME: When we detect a _change_ in the property of having a8
-	 * surfaces, we should copy all existing a8 surface to host memory
-	 * and then destroy the ones on the device.
-	 */
-	goto fallback;
-    }
-    
-    surface = qxl_surface_create (qxl->surface_cache, w, h, depth);
-    
-    if (surface)
-    {
-	/* ErrorF ("   Successfully created surface in video memory\n"); */
-	
-	pixmap = fbCreatePixmap (screen, 0, 0, depth, usage);
-	
-	screen->ModifyPixmapHeader (pixmap, w, h,
-	                            -1, -1, -1,
-	                            NULL);
-	
-#if 0
-	ErrorF ("Create pixmap %p with surface %p\n", pixmap, surface);
-#endif
-	set_surface (pixmap, surface);
-	qxl_surface_set_pixmap (surface, pixmap);
-	
-	qxl_surface_cache_sanity_check (qxl->surface_cache);
-    }
-    else
-    {
-#if 0
-	ErrorF ("   Couldn't allocate %d x %d @ %d surface in video memory\n",
-	        w, h, depth);
-#endif
-    fallback:
-	pixmap = fbCreatePixmap (screen, w, h, depth, usage);
-	
-#if 0
-	ErrorF ("Create pixmap %p without surface\n", pixmap);
-#endif
-    }
-    
-    return pixmap;
-}
-
-static Bool
-qxl_destroy_pixmap (PixmapPtr pixmap)
-{
-    ScreenPtr      screen = pixmap->drawable.pScreen;
-    ScrnInfoPtr    scrn = xf86ScreenToScrn (screen);
-    qxl_screen_t * qxl = scrn->driverPrivate;
-    qxl_surface_t *surface = NULL;
-    
-    qxl_surface_cache_sanity_check (qxl->surface_cache);
-    
-    if (pixmap->refcnt == 1)
-    {
-	surface = get_surface (pixmap);
-	
-#if 0
-	ErrorF ("- Destroy %p (had surface %p)\n", pixmap, surface);
-#endif
-	
-	if (surface)
-	{
-	    qxl_surface_kill (surface);
-	    set_surface (pixmap, NULL);
-	    
-	    qxl_surface_cache_sanity_check (qxl->surface_cache);
-	}
-    }
-    
-    fbDestroyPixmap (pixmap);
-    return TRUE;
-}
-
-static void
-set_uxa_functions(qxl_screen_t *qxl, ScreenPtr screen)
-{
-    /* Solid fill */
-    qxl->uxa->check_solid = qxl_check_solid;
-    qxl->uxa->prepare_solid = qxl_prepare_solid;
-    qxl->uxa->solid = qxl_solid;
-    qxl->uxa->done_solid = qxl_done_solid;
-    
-    /* Copy */
-    qxl->uxa->check_copy = qxl_check_copy;
-    qxl->uxa->prepare_copy = qxl_prepare_copy;
-    qxl->uxa->copy = qxl_copy;
-    qxl->uxa->done_copy = qxl_done_copy;
-    
-    /* Composite */
-    qxl->uxa->check_composite = qxl_check_composite;
-    qxl->uxa->check_composite_target = qxl_check_composite_target;
-    qxl->uxa->check_composite_texture = qxl_check_composite_texture;
-    qxl->uxa->prepare_composite = qxl_prepare_composite;
-    qxl->uxa->composite = qxl_composite;
-    qxl->uxa->done_composite = qxl_done_composite;
-    
-    /* PutImage */
-    qxl->uxa->put_image = qxl_put_image;
-    
-    /* Prepare access */
-    qxl->uxa->prepare_access = qxl_prepare_access;
-    qxl->uxa->finish_access = qxl_finish_access;
-    
-    qxl->uxa->pixmap_is_offscreen = qxl_pixmap_is_offscreen;
-    
-    screen->SetScreenPixmap = qxl_set_screen_pixmap;
-    screen->CreatePixmap = qxl_create_pixmap;
-    screen->DestroyPixmap = qxl_destroy_pixmap;
-}
-
-static Bool
-setup_uxa (qxl_screen_t *qxl, ScreenPtr screen)
-{
-    ScrnInfoPtr scrn = xf86ScreenToScrn (screen);
-    
-#if HAS_DIXREGISTERPRIVATEKEY
-    if (!dixRegisterPrivateKey (&uxa_pixmap_index, PRIVATE_PIXMAP, 0))
-	return FALSE;
-#else
-    if (!dixRequestPrivate (&uxa_pixmap_index, 0))
-	return FALSE;
-#endif
-
-    qxl->uxa = uxa_driver_alloc ();
-    if (qxl->uxa == NULL)
-        return FALSE;
-
-    memset (qxl->uxa, 0, sizeof (*qxl->uxa));
-
-    qxl->uxa->uxa_major = 1;
-    qxl->uxa->uxa_minor = 0;
-
-#ifdef XSPICE
-    if (qxl->deferred_fps)
-        dfps_set_uxa_functions(qxl, screen);
-    else
-#endif
-        set_uxa_functions(qxl, screen);
-
-    if (!uxa_driver_init (screen, qxl->uxa))
-    {
-	xf86DrvMsg (scrn->scrnIndex, X_ERROR,
-	            "UXA initialization failed\n");
-	free (qxl->uxa);
-	return FALSE;
-    }
-    
-#if 0
-    uxa_set_fallback_debug (screen, FALSE);
-#endif
-    
-#if 0
-    if (!uxa_driver_init (screen, qxl->uxa))
-	return FALSE;
-#endif
-    
-    return TRUE;
-}
-
 #ifdef XSPICE
 
 static void
@@ -1834,7 +1193,7 @@ qxl_screen_init (SCREEN_INIT_ARGS_DECL)
     
     pScreen->SaveScreen = qxl_blank_screen;
     
-    setup_uxa (qxl, pScreen);
+    qxl_uxa_init (qxl, pScreen);
 
 #if 0
     uxa_set_fallback_debug(pScreen, TRUE);
@@ -2040,324 +1399,6 @@ qxl_check_device (ScrnInfoPtr pScrn, qxl_screen_t *qxl)
 
 #endif /* !XSPICE */
 
-static DisplayModePtr
-screen_create_mode (ScrnInfoPtr pScrn, int width, int height, int type)
-{
-    DisplayModePtr mode;
-    
-    mode = xnfcalloc (1, sizeof (DisplayModeRec));
-    
-    mode->status = MODE_OK;
-    mode->type = type;
-    mode->HDisplay   = width;
-    mode->HSyncStart = (width * 105 / 100 + 7) & ~7;
-    mode->HSyncEnd   = (width * 115 / 100 + 7) & ~7;
-    mode->HTotal     = (width * 130 / 100 + 7) & ~7;
-    mode->VDisplay   = height;
-    mode->VSyncStart = height + 1;
-    mode->VSyncEnd   = height + 4;
-    mode->VTotal     = height * 1035 / 1000;
-    mode->Clock = mode->HTotal * mode->VTotal * 60 / 1000;
-    mode->Flags = V_NHSYNC | V_PVSYNC;
-    
-    xf86SetModeDefaultName (mode);
-    xf86SetModeCrtc (mode, pScrn->adjustFlags); /* needed? xf86-video-modesetting does this */
-    
-    return mode;
-}
-
-static DisplayModePtr
-qxl_add_mode (qxl_screen_t *qxl, ScrnInfoPtr pScrn, int width, int height, int type)
-{
-    DisplayModePtr mode;
-    
-    mode = screen_create_mode (pScrn, width, height, type);
-    qxl->x_modes = xf86ModesAdd (qxl->x_modes, mode);
-    
-    return mode;
-}
-
-static DisplayModePtr
-qxl_output_get_modes (xf86OutputPtr output)
-{
-    qxl_output_private *qxl_output = output->driver_private;
-    DisplayModePtr      modes = xf86DuplicateModes (qxl_output->qxl->pScrn, qxl_output->qxl->x_modes);
-    
-    /* xf86ProbeOutputModes owns this memory */
-    return modes;
-}
-
-static void
-qxl_output_destroy (xf86OutputPtr output)
-{
-    qxl_output_private *qxl_output = output->driver_private;
-    
-    xf86DrvMsg (qxl_output->qxl->pScrn->scrnIndex, X_INFO,
-                "%s", __func__);
-}
-
-static void
-qxl_output_dpms (xf86OutputPtr output, int mode)
-{
-}
-
-static void
-qxl_output_create_resources (xf86OutputPtr output)
-{
-}
-
-static Bool
-qxl_output_set_property (xf86OutputPtr output, Atom property,
-                         RRPropertyValuePtr value)
-{
-    /* EDID data is stored in the "EDID" atom property, we must return
-     * TRUE here for that. No penalty to say ok to everything else. */
-    return TRUE;
-}
-
-static Bool
-qxl_output_get_property (xf86OutputPtr output, Atom property)
-{
-    return TRUE;
-}
-
-static xf86OutputStatus
-qxl_output_detect (xf86OutputPtr output)
-{
-    qxl_output_private *qxl_output = output->driver_private;
-    
-    return qxl_output->status;
-}
-
-static Bool
-qxl_output_mode_valid (xf86OutputPtr output, DisplayModePtr pModes)
-{
-    return MODE_OK;
-}
-
-static const xf86OutputFuncsRec qxl_output_funcs = {
-    .dpms = qxl_output_dpms,
-    .create_resources = qxl_output_create_resources,
-#ifdef RANDR_12_INTERFACE
-    .set_property = qxl_output_set_property,
-    .get_property = qxl_output_get_property,
-#endif
-    .detect = qxl_output_detect,
-    .mode_valid = qxl_output_mode_valid,
-    
-    .get_modes = qxl_output_get_modes,
-    .destroy = qxl_output_destroy
-};
-
-static void
-qxl_crtc_dpms (xf86CrtcPtr crtc, int mode)
-{
-}
-
-static Bool
-qxl_crtc_set_mode_major (xf86CrtcPtr crtc, DisplayModePtr mode,
-                         Rotation rotation, int x, int y)
-{
-    qxl_crtc_private *crtc_private = crtc->driver_private;
-    qxl_screen_t *    qxl = crtc_private->qxl;
-    
-    CHECK_POINT ();
-    
-    if (!crtc_set_mode_major (crtc, mode, rotation, x, y))
-	return FALSE;
-    
-    qxl_update_monitors_config (qxl);
-    
-    return TRUE;
-}
-
-static void
-qxl_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
-{
-}
-
-static void
-qxl_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
-{
-}
-
-static void
-qxl_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
-{
-}
-
-static void
-qxl_crtc_hide_cursor (xf86CrtcPtr crtc)
-{
-}
-
-static void
-qxl_crtc_show_cursor (xf86CrtcPtr crtc)
-{
-}
-
-static void
-qxl_crtc_gamma_set (xf86CrtcPtr crtc, uint16_t *red, uint16_t *green,
-                    uint16_t *blue, int size)
-{
-}
-
-static void
-qxl_crtc_destroy (xf86CrtcPtr crtc)
-{
-    qxl_crtc_private *crtc_private = crtc->driver_private;
-    qxl_screen_t *    qxl = crtc_private->qxl;
-    
-    xf86DrvMsg (qxl->pScrn->scrnIndex, X_INFO, "%s\n", __func__);
-}
-
-static Bool
-qxl_crtc_lock (xf86CrtcPtr crtc)
-{
-    qxl_crtc_private *crtc_private = crtc->driver_private;
-    qxl_screen_t *    qxl = crtc_private->qxl;
-    
-    xf86DrvMsg (qxl->pScrn->scrnIndex, X_INFO, "%s\n", __func__);
-    return TRUE;
-}
-
-static void
-qxl_crtc_unlock (xf86CrtcPtr crtc)
-{
-    qxl_crtc_private *crtc_private = crtc->driver_private;
-    qxl_screen_t *    qxl = crtc_private->qxl;
-    
-    xf86DrvMsg (qxl->pScrn->scrnIndex, X_INFO, "%s\n", __func__);
-    qxl_update_monitors_config (qxl);
-}
-
-static const xf86CrtcFuncsRec qxl_crtc_funcs = {
-    .dpms = qxl_crtc_dpms,
-    .set_mode_major = qxl_crtc_set_mode_major,
-    .set_cursor_colors = qxl_crtc_set_cursor_colors,
-    .set_cursor_position = qxl_crtc_set_cursor_position,
-    .show_cursor = qxl_crtc_show_cursor,
-    .hide_cursor = qxl_crtc_hide_cursor,
-    .load_cursor_argb = qxl_crtc_load_cursor_argb,
-    .lock = qxl_crtc_lock,
-    .unlock = qxl_crtc_unlock,
-    
-    .gamma_set = qxl_crtc_gamma_set,
-    .destroy = qxl_crtc_destroy,
-};
-
-static Bool
-qxl_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
-{
-    qxl_screen_t *qxl = scrn->driverPrivate;
-    
-    xf86DrvMsg (scrn->scrnIndex, X_INFO, "%s: Placeholder resize %dx%d\n",
-                __func__, width, height);
-    if (!qxl_resize_primary (qxl, width, height))
-	return FALSE;
-    
-    scrn->virtualX = width;
-    scrn->virtualY = height;
-    
-    // when starting, no monitor is enabled, and count == 0
-    // we want to avoid server/client freaking out with temporary config
-    qxl_update_monitors_config (qxl);
-    
-    return TRUE;
-}
-
-static const xf86CrtcConfigFuncsRec qxl_xf86crtc_config_funcs = {
-    qxl_xf86crtc_resize
-};
-
-static void
-qxl_init_randr (ScrnInfoPtr pScrn, qxl_screen_t *qxl)
-{
-    char                name[32];
-    qxl_output_private *qxl_output;
-    qxl_crtc_private *  qxl_crtc;
-    int                 i;
-    xf86OutputPtr       output;
-    
-    xf86CrtcConfigInit (pScrn, &qxl_xf86crtc_config_funcs);
-    
-    /* CHECKME: This is actually redundant, it's overwritten by a later call via
-     * xf86InitialConfiguration */
-    xf86CrtcSetSizeRange (pScrn, 320, 200, 8192, 8192);
-    
-    qxl->crtcs = xnfcalloc (sizeof (xf86CrtcPtr), qxl->num_heads);
-    qxl->outputs = xnfcalloc (sizeof (xf86OutputPtr), qxl->num_heads);
-    
-    for (i = 0 ; i < qxl->num_heads; ++i)
-    {
-	qxl->crtcs[i] = xf86CrtcCreate (pScrn, &qxl_crtc_funcs);
-	if (!qxl->crtcs[i])
-	    xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "failed to create Crtc %d", i);
-	
-	qxl_crtc = xnfcalloc (sizeof (qxl_crtc_private), 1);
-	qxl->crtcs[i]->driver_private = qxl_crtc;
-	qxl_crtc->head = i;
-	qxl_crtc->qxl = qxl;
-	snprintf (name, sizeof (name), "qxl-%d", i);
-	qxl->outputs[i] = output = xf86OutputCreate (pScrn, &qxl_output_funcs, name);
-	if (!output)
-	    xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "failed to create Output %d", i);
-	
-	output->possible_crtcs = (1 << i); /* bitrange of allowed outputs - do a 1:1 */
-	output->possible_clones = 0; /* TODO: not? */
-	qxl_output = xnfcalloc (sizeof (qxl_output_private), 1);
-	output->driver_private = qxl_output;
-	qxl_output->head = i;
-	qxl_output->qxl = qxl;
-	qxl_output->status = XF86OutputStatusConnected;
-	qxl_crtc->output = output;
-    }
-    
-    xf86InitialConfiguration (pScrn, TRUE);
-    /* all crtcs are enabled here, but their mode is 0,
-       resulting monitor config empty atm */
-
-    qxl->virtual_x = pScrn->virtualX;
-    qxl->virtual_y = pScrn->virtualY;
-}
-
-static void
-qxl_initialize_x_modes (qxl_screen_t *qxl, ScrnInfoPtr pScrn,
-                        unsigned int *max_x, unsigned int *max_y)
-{
-    int i;
-    int size;
-    int preferred_flag;
-    
-    *max_x = *max_y = 0;
-    /* Create a list of modes used by the qxl_output_get_modes */
-    for (i = 0; i < qxl->num_modes; i++)
-    {
-	if (qxl->modes[i].orientation == 0)
-	{
-	    size = qxl->modes[i].x_res * qxl->modes[i].y_res * 4;
-	    if (size > qxl->surface0_size)
-	    {
-		ErrorF ("skipping mode %dx%d not fitting in surface0",
-		        qxl->modes[i].x_res, qxl->modes[i].y_res);
-		continue;
-	    }
-
-            if (qxl->modes[i].x_res == DEFAULT_WIDTH && qxl->modes[i].y_res == DEFAULT_HEIGHT)
-                preferred_flag = M_T_PREFERRED;
-            else
-                preferred_flag = 0;
-
-	    qxl_add_mode (qxl, pScrn, qxl->modes[i].x_res, qxl->modes[i].y_res,
-	                  M_T_DRIVER | preferred_flag);
-	    if (qxl->modes[i].x_res > *max_x)
-		*max_x = qxl->modes[i].x_res;
-	    if (qxl->modes[i].y_res > *max_y)
-		*max_y = qxl->modes[i].y_res;
-	}
-    }
-}
-
 static Bool
 qxl_pre_init (ScrnInfoPtr pScrn, int flags)
 {
diff --git a/src/qxl_ums_mode.c b/src/qxl_ums_mode.c
new file mode 100644
index 0000000..56b570a
--- /dev/null
+++ b/src/qxl_ums_mode.c
@@ -0,0 +1,507 @@
+/*
+ * Copyright 2008 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* code to handle UMS modesetting */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "qxl.h"
+
+/* These constants govern which modes are reported to X as preferred */
+#define DEFAULT_WIDTH       1024
+#define DEFAULT_HEIGHT       768
+
+static void qxl_update_monitors_config (qxl_screen_t *qxl);
+
+static DisplayModePtr
+screen_create_mode (ScrnInfoPtr pScrn, int width, int height, int type)
+{
+    DisplayModePtr mode;
+    
+    mode = xnfcalloc (1, sizeof (DisplayModeRec));
+    
+    mode->status = MODE_OK;
+    mode->type = type;
+    mode->HDisplay   = width;
+    mode->HSyncStart = (width * 105 / 100 + 7) & ~7;
+    mode->HSyncEnd   = (width * 115 / 100 + 7) & ~7;
+    mode->HTotal     = (width * 130 / 100 + 7) & ~7;
+    mode->VDisplay   = height;
+    mode->VSyncStart = height + 1;
+    mode->VSyncEnd   = height + 4;
+    mode->VTotal     = height * 1035 / 1000;
+    mode->Clock = mode->HTotal * mode->VTotal * 60 / 1000;
+    mode->Flags = V_NHSYNC | V_PVSYNC;
+    
+    xf86SetModeDefaultName (mode);
+    xf86SetModeCrtc (mode, pScrn->adjustFlags); /* needed? xf86-video-modesetting does this */
+    
+    return mode;
+}
+
+static DisplayModePtr
+qxl_add_mode (qxl_screen_t *qxl, ScrnInfoPtr pScrn, int width, int height, int type)
+{
+    DisplayModePtr mode;
+    
+    mode = screen_create_mode (pScrn, width, height, type);
+    qxl->x_modes = xf86ModesAdd (qxl->x_modes, mode);
+    
+    return mode;
+}
+
+static int
+check_crtc (qxl_screen_t *qxl)
+{
+    int i, count = 0;
+    xf86CrtcPtr crtc;
+    
+    if (qxl->crtcs == NULL) {
+        return 0;
+    }
+
+    for (i = 0 ; i < qxl->num_heads; ++i)
+    {
+	crtc = qxl->crtcs[i];
+
+	if (!crtc->enabled || crtc->mode.CrtcHDisplay == 0 ||
+	    crtc->mode.CrtcVDisplay == 0)
+	{
+	    continue;
+	}
+	count++;
+    }
+    
+#if 0
+    if (count == 0)
+    {
+	ErrorF ("check crtc failed, count == 0!!\n");
+	BREAKPOINT ();
+    }
+#endif
+    
+    return count;
+}
+
+static void
+qxl_update_monitors_config (qxl_screen_t *qxl)
+{
+    int i;
+    QXLHead *head;
+    xf86CrtcPtr crtc;
+    qxl_output_private *qxl_output;
+    QXLRam * ram = get_ram_header (qxl);
+    
+    if (check_crtc (qxl) == 0)
+        return;
+        
+    qxl->monitors_config->count = 0;
+    qxl->monitors_config->max_allowed = qxl->num_heads;
+    for (i = 0 ; i < qxl->num_heads; ++i)
+    {
+	head = &qxl->monitors_config->heads[qxl->monitors_config->count];
+	crtc = qxl->crtcs[i];
+	qxl_output = qxl->outputs[i]->driver_private;
+	head->id = i;
+	head->surface_id = 0;
+	head->flags = 0;
+
+	if (!crtc->enabled || crtc->mode.CrtcHDisplay == 0 ||
+	    crtc->mode.CrtcVDisplay == 0)
+	{
+	    head->width = head->height = head->x = head->y = 0;
+	    qxl_output->status = XF86OutputStatusDisconnected;
+	}
+	else
+	{
+	    head->width = crtc->mode.CrtcHDisplay;
+	    head->height = crtc->mode.CrtcVDisplay;
+	    head->x = crtc->x;
+	    head->y = crtc->y;
+	    qxl->monitors_config->count++;
+	    qxl_output->status = XF86OutputStatusConnected;
+	}
+    }
+    /* initialize when actually used, memslots should be initialized by now */
+    if (ram->monitors_config == 0)
+    {
+	ram->monitors_config = physical_address (qxl, qxl->monitors_config,
+	                                         qxl->main_mem_slot);
+    }
+    
+    qxl_io_monitors_config_async (qxl);
+}
+
+static Bool
+crtc_set_mode_major (xf86CrtcPtr crtc, DisplayModePtr mode,
+                     Rotation rotation, int x, int y)
+{
+    qxl_crtc_private *crtc_private = crtc->driver_private;
+    qxl_screen_t *    qxl = crtc_private->qxl;
+    
+    if (crtc == qxl->crtcs[0] && mode == NULL)
+    {
+	/* disallow disabling of monitor 0 mode */
+	ErrorF ("%s: not allowing crtc 0 disablement\n", __func__);
+	return FALSE;
+    }
+    
+    crtc->mode = *mode;
+    crtc->x = x;
+    crtc->y = y;
+    crtc->rotation = rotation;
+#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC (1, 5, 99, 0, 0)
+    crtc->transformPresent = FALSE;
+#endif
+    qxl_output_edid_set (crtc_private->output, crtc_private->head, mode);
+    
+    return TRUE;
+}
+
+Bool
+qxl_create_desired_modes (qxl_screen_t *qxl)
+{
+    int i;
+    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (qxl->pScrn);
+    
+    CHECK_POINT ();
+    
+    for (i = 0 ; i < config->num_crtc; ++i)
+    {
+	xf86CrtcPtr crtc = config->crtc[i];
+	if (!crtc->enabled)
+	    continue;
+	
+	if (!crtc_set_mode_major (
+		crtc, &crtc->desiredMode, crtc->desiredRotation,
+		crtc->desiredX, crtc->desiredY))
+	{
+	    return FALSE;
+	}
+    }
+    
+    qxl_update_monitors_config(qxl);
+    return TRUE;
+}
+
+void
+qxl_update_edid (qxl_screen_t *qxl)
+{
+    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (qxl->pScrn); 
+    int i;
+   
+    for (i = 0; i < config->num_crtc; ++i)
+    {
+	xf86CrtcPtr crtc = config->crtc[i];
+
+	if (!crtc->enabled)
+	    continue;
+	
+	qxl_output_edid_set (qxl->outputs[i], i, &crtc->desiredMode);
+    }
+}
+
+
+static DisplayModePtr
+qxl_output_get_modes (xf86OutputPtr output)
+{
+    qxl_output_private *qxl_output = output->driver_private;
+    DisplayModePtr      modes = xf86DuplicateModes (qxl_output->qxl->pScrn, qxl_output->qxl->x_modes);
+    
+    /* xf86ProbeOutputModes owns this memory */
+    return modes;
+}
+
+static void
+qxl_output_destroy (xf86OutputPtr output)
+{
+    qxl_output_private *qxl_output = output->driver_private;
+    
+    xf86DrvMsg (qxl_output->qxl->pScrn->scrnIndex, X_INFO,
+                "%s", __func__);
+}
+
+static void
+qxl_output_dpms (xf86OutputPtr output, int mode)
+{
+}
+
+static void
+qxl_output_create_resources (xf86OutputPtr output)
+{
+}
+
+static Bool
+qxl_output_set_property (xf86OutputPtr output, Atom property,
+                         RRPropertyValuePtr value)
+{
+    /* EDID data is stored in the "EDID" atom property, we must return
+     * TRUE here for that. No penalty to say ok to everything else. */
+    return TRUE;
+}
+
+static Bool
+qxl_output_get_property (xf86OutputPtr output, Atom property)
+{
+    return TRUE;
+}
+
+static xf86OutputStatus
+qxl_output_detect (xf86OutputPtr output)
+{
+    qxl_output_private *qxl_output = output->driver_private;
+    
+    return qxl_output->status;
+}
+
+static Bool
+qxl_output_mode_valid (xf86OutputPtr output, DisplayModePtr pModes)
+{
+    return MODE_OK;
+}
+
+static const xf86OutputFuncsRec qxl_output_funcs = {
+    .dpms = qxl_output_dpms,
+    .create_resources = qxl_output_create_resources,
+#ifdef RANDR_12_INTERFACE
+    .set_property = qxl_output_set_property,
+    .get_property = qxl_output_get_property,
+#endif
+    .detect = qxl_output_detect,
+    .mode_valid = qxl_output_mode_valid,
+    
+    .get_modes = qxl_output_get_modes,
+    .destroy = qxl_output_destroy
+};
+
+
+static void
+qxl_crtc_dpms (xf86CrtcPtr crtc, int mode)
+{
+}
+
+static Bool
+qxl_crtc_set_mode_major (xf86CrtcPtr crtc, DisplayModePtr mode,
+                         Rotation rotation, int x, int y)
+{
+    qxl_crtc_private *crtc_private = crtc->driver_private;
+    qxl_screen_t *    qxl = crtc_private->qxl;
+    
+    CHECK_POINT ();
+    
+    if (!crtc_set_mode_major (crtc, mode, rotation, x, y))
+	return FALSE;
+    
+    qxl_update_monitors_config (qxl);
+    
+    return TRUE;
+}
+
+static void
+qxl_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
+{
+}
+
+static void
+qxl_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
+{
+}
+
+static void
+qxl_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
+{
+}
+
+static void
+qxl_crtc_hide_cursor (xf86CrtcPtr crtc)
+{
+}
+
+static void
+qxl_crtc_show_cursor (xf86CrtcPtr crtc)
+{
+}
+
+static void
+qxl_crtc_gamma_set (xf86CrtcPtr crtc, uint16_t *red, uint16_t *green,
+                    uint16_t *blue, int size)
+{
+}
+
+static void
+qxl_crtc_destroy (xf86CrtcPtr crtc)
+{
+    qxl_crtc_private *crtc_private = crtc->driver_private;
+    qxl_screen_t *    qxl = crtc_private->qxl;
+    
+    xf86DrvMsg (qxl->pScrn->scrnIndex, X_INFO, "%s\n", __func__);
+}
+
+static Bool
+qxl_crtc_lock (xf86CrtcPtr crtc)
+{
+    qxl_crtc_private *crtc_private = crtc->driver_private;
+    qxl_screen_t *    qxl = crtc_private->qxl;
+    
+    xf86DrvMsg (qxl->pScrn->scrnIndex, X_INFO, "%s\n", __func__);
+    return TRUE;
+}
+
+static void
+qxl_crtc_unlock (xf86CrtcPtr crtc)
+{
+    qxl_crtc_private *crtc_private = crtc->driver_private;
+    qxl_screen_t *    qxl = crtc_private->qxl;
+    
+    xf86DrvMsg (qxl->pScrn->scrnIndex, X_INFO, "%s\n", __func__);
+    qxl_update_monitors_config (qxl);
+}
+
+static const xf86CrtcFuncsRec qxl_crtc_funcs = {
+    .dpms = qxl_crtc_dpms,
+    .set_mode_major = qxl_crtc_set_mode_major,
+    .set_cursor_colors = qxl_crtc_set_cursor_colors,
+    .set_cursor_position = qxl_crtc_set_cursor_position,
+    .show_cursor = qxl_crtc_show_cursor,
+    .hide_cursor = qxl_crtc_hide_cursor,
+    .load_cursor_argb = qxl_crtc_load_cursor_argb,
+    .lock = qxl_crtc_lock,
+    .unlock = qxl_crtc_unlock,
+    
+    .gamma_set = qxl_crtc_gamma_set,
+    .destroy = qxl_crtc_destroy,
+};
+
+
+static Bool
+qxl_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
+{
+    qxl_screen_t *qxl = scrn->driverPrivate;
+    
+    xf86DrvMsg (scrn->scrnIndex, X_INFO, "%s: Placeholder resize %dx%d\n",
+                __func__, width, height);
+    if (!qxl_resize_primary (qxl, width, height))
+	return FALSE;
+    
+    scrn->virtualX = width;
+    scrn->virtualY = height;
+    
+    // when starting, no monitor is enabled, and count == 0
+    // we want to avoid server/client freaking out with temporary config
+    qxl_update_monitors_config (qxl);
+    
+    return TRUE;
+}
+
+static const xf86CrtcConfigFuncsRec qxl_xf86crtc_config_funcs = {
+    qxl_xf86crtc_resize
+};
+
+void
+qxl_initialize_x_modes (qxl_screen_t *qxl, ScrnInfoPtr pScrn,
+                        unsigned int *max_x, unsigned int *max_y)
+{
+    int i;
+    int size;
+    int preferred_flag;
+    
+    *max_x = *max_y = 0;
+    /* Create a list of modes used by the qxl_output_get_modes */
+    for (i = 0; i < qxl->num_modes; i++)
+    {
+	if (qxl->modes[i].orientation == 0)
+	{
+	    size = qxl->modes[i].x_res * qxl->modes[i].y_res * 4;
+	    if (size > qxl->surface0_size)
+	    {
+		ErrorF ("skipping mode %dx%d not fitting in surface0",
+		        qxl->modes[i].x_res, qxl->modes[i].y_res);
+		continue;
+	    }
+	    
+            if (qxl->modes[i].x_res == DEFAULT_WIDTH && qxl->modes[i].y_res == DEFAULT_HEIGHT)
+                preferred_flag = M_T_PREFERRED;
+            else
+                preferred_flag = 0;
+
+	    qxl_add_mode (qxl, pScrn, qxl->modes[i].x_res, qxl->modes[i].y_res,
+	                  M_T_DRIVER | preferred_flag);
+
+	    if (qxl->modes[i].x_res > *max_x)
+		*max_x = qxl->modes[i].x_res;
+	    if (qxl->modes[i].y_res > *max_y)
+		*max_y = qxl->modes[i].y_res;
+	}
+    }
+}
+
+void
+qxl_init_randr (ScrnInfoPtr pScrn, qxl_screen_t *qxl)
+{
+    char                name[32];
+    qxl_output_private *qxl_output;
+    qxl_crtc_private *  qxl_crtc;
+    int                 i;
+    xf86OutputPtr       output;
+    
+    xf86CrtcConfigInit (pScrn, &qxl_xf86crtc_config_funcs);
+    
+    /* CHECKME: This is actually redundant, it's overwritten by a later call via
+     * xf86InitialConfiguration */
+    xf86CrtcSetSizeRange (pScrn, 320, 200, 8192, 8192);
+    
+    qxl->crtcs = xnfcalloc (sizeof (xf86CrtcPtr), qxl->num_heads);
+    qxl->outputs = xnfcalloc (sizeof (xf86OutputPtr), qxl->num_heads);
+    
+    for (i = 0 ; i < qxl->num_heads; ++i)
+    {
+	qxl->crtcs[i] = xf86CrtcCreate (pScrn, &qxl_crtc_funcs);
+	if (!qxl->crtcs[i])
+	    xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "failed to create Crtc %d", i);
+	
+	qxl_crtc = xnfcalloc (sizeof (qxl_crtc_private), 1);
+	qxl->crtcs[i]->driver_private = qxl_crtc;
+	qxl_crtc->head = i;
+	qxl_crtc->qxl = qxl;
+	snprintf (name, sizeof (name), "qxl-%d", i);
+	qxl->outputs[i] = output = xf86OutputCreate (pScrn, &qxl_output_funcs, name);
+	if (!output)
+	    xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "failed to create Output %d", i);
+	
+	output->possible_crtcs = (1 << i); /* bitrange of allowed outputs - do a 1:1 */
+	output->possible_clones = 0; /* TODO: not? */
+	qxl_output = xnfcalloc (sizeof (qxl_output_private), 1);
+	output->driver_private = qxl_output;
+	qxl_output->head = i;
+	qxl_output->qxl = qxl;
+	qxl_output->status = XF86OutputStatusConnected;
+	qxl_crtc->output = output;
+    }
+    
+    xf86InitialConfiguration (pScrn, TRUE);
+
+    qxl->virtual_x = pScrn->virtualX;
+    qxl->virtual_y = pScrn->virtualY;
+    /* all crtcs are enabled here, but their mode is 0,
+       resulting monitor config empty atm */
+}
diff --git a/src/qxl_uxa.c b/src/qxl_uxa.c
index a6e528c..fa4a746 100644
--- a/src/qxl_uxa.c
+++ b/src/qxl_uxa.c
@@ -426,28 +426,9 @@ qxl_destroy_pixmap (PixmapPtr pixmap)
     return TRUE;
 }
 
-Bool
-qxl_uxa_init (qxl_screen_t *qxl, ScreenPtr screen)
+static void
+set_uxa_functions(qxl_screen_t *qxl, ScreenPtr screen)
 {
-    ScrnInfoPtr scrn = xf86ScreenToScrn (screen);
-    
-#if HAS_DIXREGISTERPRIVATEKEY
-    if (!dixRegisterPrivateKey (&uxa_pixmap_index, PRIVATE_PIXMAP, 0))
-	return FALSE;
-#else
-    if (!dixRequestPrivate (&uxa_pixmap_index, 0))
-	return FALSE;
-#endif
-    
-    qxl->uxa = uxa_driver_alloc ();
-    if (qxl->uxa == NULL)
-	return FALSE;
-    
-    memset (qxl->uxa, 0, sizeof (*qxl->uxa));
-    
-    qxl->uxa->uxa_major = 1;
-    qxl->uxa->uxa_minor = 0;
-    
     /* Solid fill */
     qxl->uxa->check_solid = qxl_check_solid;
     qxl->uxa->prepare_solid = qxl_prepare_solid;
@@ -480,6 +461,36 @@ qxl_uxa_init (qxl_screen_t *qxl, ScreenPtr screen)
     screen->SetScreenPixmap = qxl_set_screen_pixmap;
     screen->CreatePixmap = qxl_create_pixmap;
     screen->DestroyPixmap = qxl_destroy_pixmap;
+}
+
+Bool
+qxl_uxa_init (qxl_screen_t *qxl, ScreenPtr screen)
+{
+    ScrnInfoPtr scrn = xf86ScreenToScrn (screen);
+    
+#if HAS_DIXREGISTERPRIVATEKEY
+    if (!dixRegisterPrivateKey (&uxa_pixmap_index, PRIVATE_PIXMAP, 0))
+	return FALSE;
+#else
+    if (!dixRequestPrivate (&uxa_pixmap_index, 0))
+	return FALSE;
+#endif
+    
+    qxl->uxa = uxa_driver_alloc ();
+    if (qxl->uxa == NULL)
+	return FALSE;
+    
+    memset (qxl->uxa, 0, sizeof (*qxl->uxa));
+    
+    qxl->uxa->uxa_major = 1;
+    qxl->uxa->uxa_minor = 0;
+
+#ifdef XSPICE
+    if (qxl->deferred_fps)
+        dfps_set_uxa_functions(qxl, screen);
+    else
+#endif
+        set_uxa_functions(qxl, screen);
     
     if (!uxa_driver_init (screen, qxl->uxa))
     {
-- 
1.8.1.2



More information about the Spice-devel mailing list