qxl_ums_mode.c revision d514b0f3
1d514b0f3Smrg/*
2d514b0f3Smrg * Copyright 2008 Red Hat, Inc.
3d514b0f3Smrg *
4d514b0f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5d514b0f3Smrg * copy of this software and associated documentation files (the "Software"),
6d514b0f3Smrg * to deal in the Software without restriction, including without limitation
7d514b0f3Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub
8d514b0f3Smrg * license, and/or sell copies of the Software, and to permit persons to whom
9d514b0f3Smrg * the Software is furnished to do so, subject to the following conditions:
10d514b0f3Smrg *
11d514b0f3Smrg * The above copyright notice and this permission notice (including the next
12d514b0f3Smrg * paragraph) shall be included in all copies or substantial portions of the
13d514b0f3Smrg * Software.
14d514b0f3Smrg *
15d514b0f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16d514b0f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17d514b0f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
18d514b0f3Smrg * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19d514b0f3Smrg * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20d514b0f3Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21d514b0f3Smrg */
22d514b0f3Smrg
23d514b0f3Smrg/* code to handle UMS modesetting */
24d514b0f3Smrg
25d514b0f3Smrg#ifdef HAVE_CONFIG_H
26d514b0f3Smrg#include <config.h>
27d514b0f3Smrg#endif
28d514b0f3Smrg#include "qxl.h"
29d514b0f3Smrg
30d514b0f3Smrg/* These constants govern which modes are reported to X as preferred */
31d514b0f3Smrg#define DEFAULT_WIDTH       1024
32d514b0f3Smrg#define DEFAULT_HEIGHT       768
33d514b0f3Smrg
34d514b0f3Smrgstatic void qxl_update_monitors_config (qxl_screen_t *qxl);
35d514b0f3Smrg
36d514b0f3Smrgstatic DisplayModePtr
37d514b0f3Smrgscreen_create_mode (ScrnInfoPtr pScrn, int width, int height, int type)
38d514b0f3Smrg{
39d514b0f3Smrg    DisplayModePtr mode;
40d514b0f3Smrg
41d514b0f3Smrg    mode = xnfcalloc (1, sizeof (DisplayModeRec));
42d514b0f3Smrg
43d514b0f3Smrg    mode->status = MODE_OK;
44d514b0f3Smrg    mode->type = type;
45d514b0f3Smrg    mode->HDisplay   = width;
46d514b0f3Smrg    mode->HSyncStart = (width * 105 / 100 + 7) & ~7;
47d514b0f3Smrg    mode->HSyncEnd   = (width * 115 / 100 + 7) & ~7;
48d514b0f3Smrg    mode->HTotal     = (width * 130 / 100 + 7) & ~7;
49d514b0f3Smrg    mode->VDisplay   = height;
50d514b0f3Smrg    mode->VSyncStart = height + 1;
51d514b0f3Smrg    mode->VSyncEnd   = height + 4;
52d514b0f3Smrg    mode->VTotal     = height * 1035 / 1000;
53d514b0f3Smrg    mode->Clock = mode->HTotal * mode->VTotal * 60 / 1000;
54d514b0f3Smrg    mode->Flags = V_NHSYNC | V_PVSYNC;
55d514b0f3Smrg
56d514b0f3Smrg    xf86SetModeDefaultName (mode);
57d514b0f3Smrg    xf86SetModeCrtc (mode, pScrn->adjustFlags); /* needed? xf86-video-modesetting does this */
58d514b0f3Smrg
59d514b0f3Smrg    return mode;
60d514b0f3Smrg}
61d514b0f3Smrg
62d514b0f3Smrgstatic DisplayModePtr
63d514b0f3Smrgqxl_add_mode (qxl_screen_t *qxl, ScrnInfoPtr pScrn, int width, int height, int type)
64d514b0f3Smrg{
65d514b0f3Smrg    DisplayModePtr mode;
66d514b0f3Smrg
67d514b0f3Smrg    mode = screen_create_mode (pScrn, width, height, type);
68d514b0f3Smrg    pScrn->modes = qxl->x_modes = xf86ModesAdd (qxl->x_modes, mode);
69d514b0f3Smrg
70d514b0f3Smrg    return mode;
71d514b0f3Smrg}
72d514b0f3Smrg
73d514b0f3Smrgstatic int
74d514b0f3Smrgcheck_crtc (qxl_screen_t *qxl)
75d514b0f3Smrg{
76d514b0f3Smrg    int i, count = 0;
77d514b0f3Smrg    xf86CrtcPtr crtc;
78d514b0f3Smrg
79d514b0f3Smrg    if (qxl->crtcs == NULL) {
80d514b0f3Smrg        return 0;
81d514b0f3Smrg    }
82d514b0f3Smrg
83d514b0f3Smrg    for (i = 0 ; i < qxl->num_heads; ++i)
84d514b0f3Smrg    {
85d514b0f3Smrg	crtc = qxl->crtcs[i];
86d514b0f3Smrg
87d514b0f3Smrg	if (!crtc->enabled || crtc->mode.CrtcHDisplay == 0 ||
88d514b0f3Smrg	    crtc->mode.CrtcVDisplay == 0)
89d514b0f3Smrg	{
90d514b0f3Smrg	    continue;
91d514b0f3Smrg	}
92d514b0f3Smrg	count++;
93d514b0f3Smrg    }
94d514b0f3Smrg
95d514b0f3Smrg#if 0
96d514b0f3Smrg    if (count == 0)
97d514b0f3Smrg    {
98d514b0f3Smrg	ErrorF ("check crtc failed, count == 0!!\n");
99d514b0f3Smrg	BREAKPOINT ();
100d514b0f3Smrg    }
101d514b0f3Smrg#endif
102d514b0f3Smrg
103d514b0f3Smrg    return count;
104d514b0f3Smrg}
105d514b0f3Smrg
106d514b0f3Smrgstatic void
107d514b0f3Smrgqxl_update_monitors_config (qxl_screen_t *qxl)
108d514b0f3Smrg{
109d514b0f3Smrg    int i;
110d514b0f3Smrg    QXLHead *head;
111d514b0f3Smrg    xf86CrtcPtr crtc;
112d514b0f3Smrg    qxl_output_private *qxl_output;
113d514b0f3Smrg    QXLRam * ram = get_ram_header (qxl);
114d514b0f3Smrg
115d514b0f3Smrg    if (check_crtc (qxl) == 0)
116d514b0f3Smrg        return;
117d514b0f3Smrg
118d514b0f3Smrg    qxl->monitors_config->count = 0;
119d514b0f3Smrg    qxl->monitors_config->max_allowed = qxl->num_heads;
120d514b0f3Smrg    for (i = 0 ; i < qxl->num_heads; ++i)
121d514b0f3Smrg    {
122d514b0f3Smrg	head = &qxl->monitors_config->heads[qxl->monitors_config->count];
123d514b0f3Smrg	crtc = qxl->crtcs[i];
124d514b0f3Smrg	qxl_output = qxl->outputs[i]->driver_private;
125d514b0f3Smrg	head->id = i;
126d514b0f3Smrg	head->surface_id = 0;
127d514b0f3Smrg	head->flags = 0;
128d514b0f3Smrg
129d514b0f3Smrg	if (!crtc->enabled || crtc->mode.CrtcHDisplay == 0 ||
130d514b0f3Smrg	    crtc->mode.CrtcVDisplay == 0)
131d514b0f3Smrg	{
132d514b0f3Smrg	    head->width = head->height = head->x = head->y = 0;
133d514b0f3Smrg	    qxl_output->status = XF86OutputStatusDisconnected;
134d514b0f3Smrg	}
135d514b0f3Smrg	else
136d514b0f3Smrg	{
137d514b0f3Smrg	    head->width = crtc->mode.CrtcHDisplay;
138d514b0f3Smrg	    head->height = crtc->mode.CrtcVDisplay;
139d514b0f3Smrg	    head->x = crtc->x;
140d514b0f3Smrg	    head->y = crtc->y;
141d514b0f3Smrg	    qxl->monitors_config->count++;
142d514b0f3Smrg	    qxl_output->status = XF86OutputStatusConnected;
143d514b0f3Smrg	}
144d514b0f3Smrg    }
145d514b0f3Smrg    /* initialize when actually used, memslots should be initialized by now */
146d514b0f3Smrg    if (ram->monitors_config == 0)
147d514b0f3Smrg    {
148d514b0f3Smrg	ram->monitors_config = physical_address (qxl, qxl->monitors_config,
149d514b0f3Smrg	                                         qxl->main_mem_slot);
150d514b0f3Smrg    }
151d514b0f3Smrg
152d514b0f3Smrg    qxl_io_monitors_config_async (qxl);
153d514b0f3Smrg}
154d514b0f3Smrg
155d514b0f3Smrgstatic Bool
156d514b0f3Smrgcrtc_set_mode_major (xf86CrtcPtr crtc, DisplayModePtr mode,
157d514b0f3Smrg                     Rotation rotation, int x, int y)
158d514b0f3Smrg{
159d514b0f3Smrg    qxl_crtc_private *crtc_private = crtc->driver_private;
160d514b0f3Smrg    qxl_screen_t *    qxl = crtc_private->qxl;
161d514b0f3Smrg
162d514b0f3Smrg    if (crtc == qxl->crtcs[0] && mode == NULL)
163d514b0f3Smrg    {
164d514b0f3Smrg	/* disallow disabling of monitor 0 mode */
165d514b0f3Smrg	ErrorF ("%s: not allowing crtc 0 disablement\n", __func__);
166d514b0f3Smrg	return FALSE;
167d514b0f3Smrg    }
168d514b0f3Smrg
169d514b0f3Smrg    crtc->mode = *mode;
170d514b0f3Smrg    crtc->x = x;
171d514b0f3Smrg    crtc->y = y;
172d514b0f3Smrg    crtc->rotation = rotation;
173d514b0f3Smrg#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC (1, 5, 99, 0, 0)
174d514b0f3Smrg    crtc->transformPresent = FALSE;
175d514b0f3Smrg#endif
176d514b0f3Smrg    /* TODO set EDID here */
177d514b0f3Smrg    return TRUE;
178d514b0f3Smrg}
179d514b0f3Smrg
180d514b0f3SmrgBool
181d514b0f3Smrgqxl_create_desired_modes (qxl_screen_t *qxl)
182d514b0f3Smrg{
183d514b0f3Smrg    int i;
184d514b0f3Smrg    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (qxl->pScrn);
185d514b0f3Smrg
186d514b0f3Smrg    CHECK_POINT ();
187d514b0f3Smrg
188d514b0f3Smrg    for (i = 0 ; i < config->num_crtc; ++i)
189d514b0f3Smrg    {
190d514b0f3Smrg	xf86CrtcPtr crtc = config->crtc[i];
191d514b0f3Smrg	if (!crtc->enabled)
192d514b0f3Smrg	    continue;
193d514b0f3Smrg
194d514b0f3Smrg	if (!crtc_set_mode_major (
195d514b0f3Smrg		crtc, &crtc->desiredMode, crtc->desiredRotation,
196d514b0f3Smrg		crtc->desiredX, crtc->desiredY))
197d514b0f3Smrg	{
198d514b0f3Smrg	    return FALSE;
199d514b0f3Smrg	}
200d514b0f3Smrg    }
201d514b0f3Smrg
202d514b0f3Smrg    qxl_update_monitors_config(qxl);
203d514b0f3Smrg    return TRUE;
204d514b0f3Smrg}
205d514b0f3Smrg
206d514b0f3Smrgvoid
207d514b0f3Smrgqxl_update_edid (qxl_screen_t *qxl)
208d514b0f3Smrg{
209d514b0f3Smrg    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (qxl->pScrn);
210d514b0f3Smrg    int i;
211d514b0f3Smrg
212d514b0f3Smrg    for (i = 0; i < config->num_crtc; ++i)
213d514b0f3Smrg    {
214d514b0f3Smrg	xf86CrtcPtr crtc = config->crtc[i];
215d514b0f3Smrg
216d514b0f3Smrg	if (!crtc->enabled)
217d514b0f3Smrg	    continue;
218d514b0f3Smrg
219d514b0f3Smrg	/* TODO set EDID here */
220d514b0f3Smrg    }
221d514b0f3Smrg}
222d514b0f3Smrg
223d514b0f3Smrg
224d514b0f3Smrgstatic DisplayModePtr
225d514b0f3Smrgqxl_output_get_modes (xf86OutputPtr output)
226d514b0f3Smrg{
227d514b0f3Smrg    qxl_output_private *qxl_output = output->driver_private;
228d514b0f3Smrg    DisplayModePtr      modes = xf86DuplicateModes (qxl_output->qxl->pScrn, qxl_output->qxl->x_modes);
229d514b0f3Smrg
230d514b0f3Smrg    /* xf86ProbeOutputModes owns this memory */
231d514b0f3Smrg    return modes;
232d514b0f3Smrg}
233d514b0f3Smrg
234d514b0f3Smrgstatic void
235d514b0f3Smrgqxl_output_destroy (xf86OutputPtr output)
236d514b0f3Smrg{
237d514b0f3Smrg    qxl_output_private *qxl_output = output->driver_private;
238d514b0f3Smrg
239d514b0f3Smrg    xf86DrvMsg (qxl_output->qxl->pScrn->scrnIndex, X_INFO,
240d514b0f3Smrg                "%s", __func__);
241d514b0f3Smrg}
242d514b0f3Smrg
243d514b0f3Smrgstatic void
244d514b0f3Smrgqxl_output_dpms (xf86OutputPtr output, int mode)
245d514b0f3Smrg{
246d514b0f3Smrg}
247d514b0f3Smrg
248d514b0f3Smrgstatic void
249d514b0f3Smrgqxl_output_create_resources (xf86OutputPtr output)
250d514b0f3Smrg{
251d514b0f3Smrg}
252d514b0f3Smrg
253d514b0f3Smrgstatic Bool
254d514b0f3Smrgqxl_output_set_property (xf86OutputPtr output, Atom property,
255d514b0f3Smrg                         RRPropertyValuePtr value)
256d514b0f3Smrg{
257d514b0f3Smrg    /* EDID data is stored in the "EDID" atom property, we must return
258d514b0f3Smrg     * TRUE here for that. No penalty to say ok to everything else. */
259d514b0f3Smrg    return TRUE;
260d514b0f3Smrg}
261d514b0f3Smrg
262d514b0f3Smrgstatic Bool
263d514b0f3Smrgqxl_output_get_property (xf86OutputPtr output, Atom property)
264d514b0f3Smrg{
265d514b0f3Smrg    return TRUE;
266d514b0f3Smrg}
267d514b0f3Smrg
268d514b0f3Smrgstatic xf86OutputStatus
269d514b0f3Smrgqxl_output_detect (xf86OutputPtr output)
270d514b0f3Smrg{
271d514b0f3Smrg    qxl_output_private *qxl_output = output->driver_private;
272d514b0f3Smrg
273d514b0f3Smrg    return qxl_output->status;
274d514b0f3Smrg}
275d514b0f3Smrg
276d514b0f3Smrgstatic Bool
277d514b0f3Smrgqxl_output_mode_valid (xf86OutputPtr output, DisplayModePtr pModes)
278d514b0f3Smrg{
279d514b0f3Smrg    return MODE_OK;
280d514b0f3Smrg}
281d514b0f3Smrg
282d514b0f3Smrgstatic const xf86OutputFuncsRec qxl_output_funcs = {
283d514b0f3Smrg    .dpms = qxl_output_dpms,
284d514b0f3Smrg    .create_resources = qxl_output_create_resources,
285d514b0f3Smrg#ifdef RANDR_12_INTERFACE
286d514b0f3Smrg    .set_property = qxl_output_set_property,
287d514b0f3Smrg    .get_property = qxl_output_get_property,
288d514b0f3Smrg#endif
289d514b0f3Smrg    .detect = qxl_output_detect,
290d514b0f3Smrg    .mode_valid = qxl_output_mode_valid,
291d514b0f3Smrg
292d514b0f3Smrg    .get_modes = qxl_output_get_modes,
293d514b0f3Smrg    .destroy = qxl_output_destroy
294d514b0f3Smrg};
295d514b0f3Smrg
296d514b0f3Smrg
297d514b0f3Smrgstatic void
298d514b0f3Smrgqxl_crtc_dpms (xf86CrtcPtr crtc, int mode)
299d514b0f3Smrg{
300d514b0f3Smrg}
301d514b0f3Smrg
302d514b0f3Smrgstatic Bool
303d514b0f3Smrgqxl_crtc_set_mode_major (xf86CrtcPtr crtc, DisplayModePtr mode,
304d514b0f3Smrg                         Rotation rotation, int x, int y)
305d514b0f3Smrg{
306d514b0f3Smrg    qxl_crtc_private *crtc_private = crtc->driver_private;
307d514b0f3Smrg    qxl_screen_t *    qxl = crtc_private->qxl;
308d514b0f3Smrg
309d514b0f3Smrg    CHECK_POINT ();
310d514b0f3Smrg
311d514b0f3Smrg    if (!crtc_set_mode_major (crtc, mode, rotation, x, y))
312d514b0f3Smrg	return FALSE;
313d514b0f3Smrg
314d514b0f3Smrg    qxl_update_monitors_config (qxl);
315d514b0f3Smrg
316d514b0f3Smrg    return TRUE;
317d514b0f3Smrg}
318d514b0f3Smrg
319d514b0f3Smrgstatic void
320d514b0f3Smrgqxl_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
321d514b0f3Smrg{
322d514b0f3Smrg}
323d514b0f3Smrg
324d514b0f3Smrgstatic void
325d514b0f3Smrgqxl_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
326d514b0f3Smrg{
327d514b0f3Smrg}
328d514b0f3Smrg
329d514b0f3Smrgstatic void
330d514b0f3Smrgqxl_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
331d514b0f3Smrg{
332d514b0f3Smrg}
333d514b0f3Smrg
334d514b0f3Smrgstatic void
335d514b0f3Smrgqxl_crtc_hide_cursor (xf86CrtcPtr crtc)
336d514b0f3Smrg{
337d514b0f3Smrg}
338d514b0f3Smrg
339d514b0f3Smrgstatic void
340d514b0f3Smrgqxl_crtc_show_cursor (xf86CrtcPtr crtc)
341d514b0f3Smrg{
342d514b0f3Smrg}
343d514b0f3Smrg
344d514b0f3Smrgstatic void
345d514b0f3Smrgqxl_crtc_gamma_set (xf86CrtcPtr crtc, uint16_t *red, uint16_t *green,
346d514b0f3Smrg                    uint16_t *blue, int size)
347d514b0f3Smrg{
348d514b0f3Smrg}
349d514b0f3Smrg
350d514b0f3Smrgstatic void
351d514b0f3Smrgqxl_crtc_destroy (xf86CrtcPtr crtc)
352d514b0f3Smrg{
353d514b0f3Smrg    qxl_crtc_private *crtc_private = crtc->driver_private;
354d514b0f3Smrg    qxl_screen_t *    qxl = crtc_private->qxl;
355d514b0f3Smrg
356d514b0f3Smrg    xf86DrvMsg (qxl->pScrn->scrnIndex, X_INFO, "%s\n", __func__);
357d514b0f3Smrg}
358d514b0f3Smrg
359d514b0f3Smrgstatic Bool
360d514b0f3Smrgqxl_crtc_lock (xf86CrtcPtr crtc)
361d514b0f3Smrg{
362d514b0f3Smrg    qxl_crtc_private *crtc_private = crtc->driver_private;
363d514b0f3Smrg    qxl_screen_t *    qxl = crtc_private->qxl;
364d514b0f3Smrg
365d514b0f3Smrg    xf86DrvMsg (qxl->pScrn->scrnIndex, X_INFO, "%s\n", __func__);
366d514b0f3Smrg    return TRUE;
367d514b0f3Smrg}
368d514b0f3Smrg
369d514b0f3Smrgstatic void
370d514b0f3Smrgqxl_crtc_unlock (xf86CrtcPtr crtc)
371d514b0f3Smrg{
372d514b0f3Smrg    qxl_crtc_private *crtc_private = crtc->driver_private;
373d514b0f3Smrg    qxl_screen_t *    qxl = crtc_private->qxl;
374d514b0f3Smrg
375d514b0f3Smrg    xf86DrvMsg (qxl->pScrn->scrnIndex, X_INFO, "%s\n", __func__);
376d514b0f3Smrg    qxl_update_monitors_config (qxl);
377d514b0f3Smrg}
378d514b0f3Smrg
379d514b0f3Smrgstatic const xf86CrtcFuncsRec qxl_crtc_funcs = {
380d514b0f3Smrg    .dpms = qxl_crtc_dpms,
381d514b0f3Smrg    .set_mode_major = qxl_crtc_set_mode_major,
382d514b0f3Smrg    .set_cursor_colors = qxl_crtc_set_cursor_colors,
383d514b0f3Smrg    .set_cursor_position = qxl_crtc_set_cursor_position,
384d514b0f3Smrg    .show_cursor = qxl_crtc_show_cursor,
385d514b0f3Smrg    .hide_cursor = qxl_crtc_hide_cursor,
386d514b0f3Smrg    .load_cursor_argb = qxl_crtc_load_cursor_argb,
387d514b0f3Smrg    .lock = qxl_crtc_lock,
388d514b0f3Smrg    .unlock = qxl_crtc_unlock,
389d514b0f3Smrg
390d514b0f3Smrg    .gamma_set = qxl_crtc_gamma_set,
391d514b0f3Smrg    .destroy = qxl_crtc_destroy,
392d514b0f3Smrg};
393d514b0f3Smrg
394d514b0f3Smrg
395d514b0f3Smrgstatic Bool
396d514b0f3Smrgqxl_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
397d514b0f3Smrg{
398d514b0f3Smrg    qxl_screen_t *qxl = scrn->driverPrivate;
399d514b0f3Smrg
400d514b0f3Smrg    xf86DrvMsg (scrn->scrnIndex, X_INFO, "%s: Placeholder resize %dx%d\n",
401d514b0f3Smrg                __func__, width, height);
402d514b0f3Smrg    if (!qxl_resize_primary (qxl, width, height))
403d514b0f3Smrg	return FALSE;
404d514b0f3Smrg
405d514b0f3Smrg    scrn->virtualX = width;
406d514b0f3Smrg    scrn->virtualY = height;
407d514b0f3Smrg
408d514b0f3Smrg    // when starting, no monitor is enabled, and count == 0
409d514b0f3Smrg    // we want to avoid server/client freaking out with temporary config
410d514b0f3Smrg    qxl_update_monitors_config (qxl);
411d514b0f3Smrg
412d514b0f3Smrg    return TRUE;
413d514b0f3Smrg}
414d514b0f3Smrg
415d514b0f3Smrgstatic const xf86CrtcConfigFuncsRec qxl_xf86crtc_config_funcs = {
416d514b0f3Smrg    qxl_xf86crtc_resize
417d514b0f3Smrg};
418d514b0f3Smrg
419d514b0f3Smrgvoid
420d514b0f3Smrgqxl_initialize_x_modes (qxl_screen_t *qxl, ScrnInfoPtr pScrn,
421d514b0f3Smrg                        unsigned int *max_x, unsigned int *max_y)
422d514b0f3Smrg{
423d514b0f3Smrg    int i;
424d514b0f3Smrg    int size;
425d514b0f3Smrg    int preferred_flag;
426d514b0f3Smrg
427d514b0f3Smrg    *max_x = *max_y = 0;
428d514b0f3Smrg    /* Create a list of modes used by the qxl_output_get_modes */
429d514b0f3Smrg    for (i = 0; i < qxl->num_modes; i++)
430d514b0f3Smrg    {
431d514b0f3Smrg	if (qxl->modes[i].orientation == 0)
432d514b0f3Smrg	{
433d514b0f3Smrg	    size = qxl->modes[i].y_res * qxl->modes[i].stride;
434d514b0f3Smrg	    if (size > qxl->surface0_size)
435d514b0f3Smrg	    {
436d514b0f3Smrg		ErrorF ("skipping mode %dx%d not fitting in surface0\n",
437d514b0f3Smrg		        qxl->modes[i].x_res, qxl->modes[i].y_res);
438d514b0f3Smrg		continue;
439d514b0f3Smrg	    }
440d514b0f3Smrg
441d514b0f3Smrg            if (qxl->modes[i].x_res == DEFAULT_WIDTH && qxl->modes[i].y_res == DEFAULT_HEIGHT)
442d514b0f3Smrg                preferred_flag = M_T_PREFERRED;
443d514b0f3Smrg            else
444d514b0f3Smrg                preferred_flag = 0;
445d514b0f3Smrg
446d514b0f3Smrg	    qxl_add_mode (qxl, pScrn, qxl->modes[i].x_res, qxl->modes[i].y_res,
447d514b0f3Smrg	                  M_T_DRIVER | preferred_flag);
448d514b0f3Smrg
449d514b0f3Smrg	    if (qxl->modes[i].x_res > *max_x)
450d514b0f3Smrg		*max_x = qxl->modes[i].x_res;
451d514b0f3Smrg	    if (qxl->modes[i].y_res > *max_y)
452d514b0f3Smrg		*max_y = qxl->modes[i].y_res;
453d514b0f3Smrg	}
454d514b0f3Smrg    }
455d514b0f3Smrg}
456d514b0f3Smrg
457d514b0f3Smrgvoid
458d514b0f3Smrgqxl_init_randr (ScrnInfoPtr pScrn, qxl_screen_t *qxl)
459d514b0f3Smrg{
460d514b0f3Smrg    char                name[32];
461d514b0f3Smrg    qxl_output_private *qxl_output;
462d514b0f3Smrg    qxl_crtc_private *  qxl_crtc;
463d514b0f3Smrg    int                 i;
464d514b0f3Smrg    xf86OutputPtr       output;
465d514b0f3Smrg
466d514b0f3Smrg    xf86CrtcConfigInit (pScrn, &qxl_xf86crtc_config_funcs);
467d514b0f3Smrg
468d514b0f3Smrg    /* CHECKME: This is actually redundant, it's overwritten by a later call via
469d514b0f3Smrg     * xf86InitialConfiguration */
470d514b0f3Smrg    xf86CrtcSetSizeRange (pScrn, 320, 200, 8192, 8192);
471d514b0f3Smrg
472d514b0f3Smrg    qxl->crtcs = xnfcalloc (sizeof (xf86CrtcPtr), qxl->num_heads);
473d514b0f3Smrg    qxl->outputs = xnfcalloc (sizeof (xf86OutputPtr), qxl->num_heads);
474d514b0f3Smrg
475d514b0f3Smrg    for (i = 0 ; i < qxl->num_heads; ++i)
476d514b0f3Smrg    {
477d514b0f3Smrg	qxl->crtcs[i] = xf86CrtcCreate (pScrn, &qxl_crtc_funcs);
478d514b0f3Smrg	if (!qxl->crtcs[i])
479d514b0f3Smrg	    xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "failed to create Crtc %d", i);
480d514b0f3Smrg
481d514b0f3Smrg	qxl_crtc = xnfcalloc (sizeof (qxl_crtc_private), 1);
482d514b0f3Smrg	qxl->crtcs[i]->driver_private = qxl_crtc;
483d514b0f3Smrg	qxl_crtc->head = i;
484d514b0f3Smrg	qxl_crtc->qxl = qxl;
485d514b0f3Smrg	snprintf (name, sizeof (name), "qxl-%d", i);
486d514b0f3Smrg	qxl->outputs[i] = output = xf86OutputCreate (pScrn, &qxl_output_funcs, name);
487d514b0f3Smrg	if (!output)
488d514b0f3Smrg	    xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "failed to create Output %d", i);
489d514b0f3Smrg
490d514b0f3Smrg	output->possible_crtcs = (1 << i); /* bitrange of allowed outputs - do a 1:1 */
491d514b0f3Smrg	output->possible_clones = 0; /* TODO: not? */
492d514b0f3Smrg	qxl_output = xnfcalloc (sizeof (qxl_output_private), 1);
493d514b0f3Smrg	output->driver_private = qxl_output;
494d514b0f3Smrg	qxl_output->head = i;
495d514b0f3Smrg	qxl_output->qxl = qxl;
496d514b0f3Smrg	qxl_output->status = i ? XF86OutputStatusDisconnected : XF86OutputStatusConnected;
497d514b0f3Smrg	qxl_crtc->output = output;
498d514b0f3Smrg    }
499d514b0f3Smrg
500d514b0f3Smrg    xf86InitialConfiguration (pScrn, TRUE);
501d514b0f3Smrg
502d514b0f3Smrg    qxl->virtual_x = pScrn->virtualX;
503d514b0f3Smrg    qxl->virtual_y = pScrn->virtualY;
504d514b0f3Smrg    /* all crtcs are enabled here, but their mode is 0,
505d514b0f3Smrg       resulting monitor config empty atm */
506d514b0f3Smrg}
507