summaryrefslogtreecommitdiff
path: root/vmwgfx/vmwgfx_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'vmwgfx/vmwgfx_output.c')
-rw-r--r--vmwgfx/vmwgfx_output.c393
1 files changed, 393 insertions, 0 deletions
diff --git a/vmwgfx/vmwgfx_output.c b/vmwgfx/vmwgfx_output.c
new file mode 100644
index 0000000..4f52f1d
--- /dev/null
+++ b/vmwgfx/vmwgfx_output.c
@@ -0,0 +1,393 @@
1/*
2 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 *
26 * Author: Alan Hourihane <alanh@tungstengraphics.com>
27 * Author: Jakob Bornecrantz <wallbraker@gmail.com>
28 *
29 */
30
31#include "xorg-server.h"
32#include <xf86.h>
33#include <xf86i2c.h>
34#include <xf86Crtc.h>
35#include <errno.h>
36#include <fcntl.h>
37#include <unistd.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <stdint.h>
41#include <string.h>
42#include <sys/stat.h>
43#include <sys/types.h>
44
45#ifdef HAVE_XEXTPROTO_71
46#include <X11/extensions/dpmsconst.h>
47#else
48#define DPMS_SERVER
49#include <X11/extensions/dpms.h>
50#endif
51
52#include "vmwgfx_driver.h"
53
54struct output_private
55{
56 drmModeConnectorPtr drm_connector;
57
58 int c;
59
60 Bool is_implicit;
61};
62
63static char *output_enum_list[] = {
64 "Unknown",
65 "VGA",
66 "DVI",
67 "DVI",
68 "DVI",
69 "Composite",
70 "SVIDEO",
71 "LVDS",
72 "CTV",
73 "DIN",
74 "DP",
75 "HDMI",
76 "HDMI",
77 "TV",
78 "EDP",
79 "Virtual",
80};
81
82static void
83output_create_resources(xf86OutputPtr output)
84{
85#ifdef RANDR_12_INTERFACE
86#endif /* RANDR_12_INTERFACE */
87}
88
89static void
90output_dpms(xf86OutputPtr output, int mode)
91{
92}
93
94static xf86OutputStatus
95output_detect(xf86OutputPtr output)
96{
97 modesettingPtr ms = modesettingPTR(output->scrn);
98 struct output_private *priv = output->driver_private;
99 drmModeConnectorPtr drm_connector;
100 xf86OutputStatus status;
101
102 drm_connector = drmModeGetConnector(ms->fd, priv->drm_connector->connector_id);
103 if (drm_connector) {
104 drmModeFreeConnector(priv->drm_connector);
105 priv->drm_connector = drm_connector;
106 } else {
107 drm_connector = priv->drm_connector;
108 }
109
110 switch (drm_connector->connection) {
111 case DRM_MODE_CONNECTED:
112 status = XF86OutputStatusConnected;
113 break;
114 case DRM_MODE_DISCONNECTED:
115 status = XF86OutputStatusDisconnected;
116 break;
117 default:
118 status = XF86OutputStatusUnknown;
119 }
120
121 return status;
122}
123
124static DisplayModePtr
125output_get_modes(xf86OutputPtr output)
126{
127 struct output_private *priv = output->driver_private;
128 drmModeConnectorPtr drm_connector = priv->drm_connector;
129 drmModeModeInfoPtr drm_mode = NULL;
130 DisplayModePtr modes = NULL, mode = NULL;
131 int i;
132
133 for (i = 0; i < drm_connector->count_modes; i++) {
134 drm_mode = &drm_connector->modes[i];
135 if (drm_mode) {
136 mode = calloc(1, sizeof(DisplayModeRec));
137 if (!mode)
138 continue;
139 mode->Clock = drm_mode->clock;
140 mode->HDisplay = drm_mode->hdisplay;
141 mode->HSyncStart = drm_mode->hsync_start;
142 mode->HSyncEnd = drm_mode->hsync_end;
143 mode->HTotal = drm_mode->htotal;
144 mode->VDisplay = drm_mode->vdisplay;
145 mode->VSyncStart = drm_mode->vsync_start;
146 mode->VSyncEnd = drm_mode->vsync_end;
147 mode->VTotal = drm_mode->vtotal;
148 mode->Flags = drm_mode->flags;
149 mode->HSkew = drm_mode->hskew;
150 mode->VScan = drm_mode->vscan;
151 mode->VRefresh = xf86ModeVRefresh(mode);
152 mode->Private = (void *)drm_mode;
153 mode->type = 0;
154 if (drm_mode->type & DRM_MODE_TYPE_PREFERRED)
155 mode->type |= M_T_PREFERRED;
156 if (drm_mode->type & DRM_MODE_TYPE_DRIVER)
157 mode->type |= M_T_DRIVER;
158 xf86SetModeDefaultName(mode);
159 modes = xf86ModesAdd(modes, mode);
160 xf86PrintModeline(0, mode);
161 }
162 }
163
164 return modes;
165}
166
167static int
168output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
169{
170 // modesettingPtr ms = modesettingPTR(output->scrn);
171 // CustomizerPtr cust = ms->cust;
172
173#if 0
174 if (cust && cust->winsys_check_fb_size &&
175 !cust->winsys_check_fb_size(cust, pMode->HDisplay *
176 output->scrn->bitsPerPixel / 8,
177 pMode->VDisplay))
178 return MODE_BAD;
179#endif
180 return MODE_OK;
181}
182
183#ifdef RANDR_12_INTERFACE
184static Bool
185output_set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value)
186{
187 return TRUE;
188}
189#endif /* RANDR_12_INTERFACE */
190
191#ifdef RANDR_13_INTERFACE
192static Bool
193output_get_property(xf86OutputPtr output, Atom property)
194{
195 return TRUE;
196}
197#endif /* RANDR_13_INTERFACE */
198
199static void
200output_destroy(xf86OutputPtr output)
201{
202 struct output_private *priv = output->driver_private;
203 drmModeFreeConnector(priv->drm_connector);
204 free(priv);
205 output->driver_private = NULL;
206}
207
208static const xf86OutputFuncsRec output_funcs = {
209 .create_resources = output_create_resources,
210#ifdef RANDR_12_INTERFACE
211 .set_property = output_set_property,
212#endif
213#ifdef RANDR_13_INTERFACE
214 .get_property = output_get_property,
215#endif
216 .dpms = output_dpms,
217 .detect = output_detect,
218
219 .get_modes = output_get_modes,
220 .mode_valid = output_mode_valid,
221 .destroy = output_destroy,
222};
223
224/**
225 * vmwgfx_output_explicit_overlap -- Check for explicit output overlaps
226 *
227 * This function returns TRUE iff the bounding box in screen space of an
228 * exlplicit output overlaps the bounding box in screen space of any other
229 * output.
230 */
231Bool
232vmwgfx_output_explicit_overlap(ScrnInfoPtr pScrn)
233{
234 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
235 xf86OutputPtr output;
236 ScreenPtr pScreen = pScrn->pScreen;
237 RegionRec output_union;
238 RegionRec cur_output;
239 RegionRec result;
240 struct output_private *priv;
241 xf86CrtcPtr crtc;
242 Bool overlap = FALSE;
243 int i;
244
245 (void) pScreen;
246 REGION_NULL(pScreen, &output_union);
247 REGION_NULL(pScreen, &cur_output);
248 REGION_NULL(pScreen, &result);
249
250 /*
251 * Collect a region of implicit outputs. These may overlap.
252 */
253 for (i = 0; i < config->num_output; i++) {
254 output = config->output[i];
255 priv = output->driver_private;
256 crtc = output->crtc;
257
258 if (!crtc || !crtc->enabled || !priv->is_implicit)
259 continue;
260
261 REGION_RESET(pScreen, &cur_output, &crtc->bounds);
262 REGION_UNION(pScreen, &output_union, &output_union, &cur_output);
263 }
264
265 /*
266 * Explicit outputs may not overlap any other output.
267 */
268 for (i = 0; i < config->num_output; i++) {
269 output = config->output[i];
270 priv = output->driver_private;
271 crtc = output->crtc;
272
273 if (!crtc || !crtc->enabled || priv->is_implicit)
274 continue;
275
276 REGION_RESET(pScreen, &cur_output, &crtc->bounds);
277 REGION_NULL(pScreen, &result);
278 REGION_INTERSECT(pScreen, &result, &output_union, &cur_output);
279 overlap = REGION_NOTEMPTY(vsaa->pScreen, &result);
280 if (overlap)
281 break;
282
283 REGION_UNION(pScreen, &output_union, &output_union, &cur_output);
284 }
285
286 REGION_UNINIT(pScreen, &output_union);
287 REGION_UNINIT(pScreen, &cur_output);
288 REGION_UNINIT(pScreen, &result);
289
290 return overlap;
291}
292
293void
294xorg_output_init(ScrnInfoPtr pScrn)
295{
296 modesettingPtr ms = modesettingPTR(pScrn);
297 xf86OutputPtr output;
298 drmModeResPtr res;
299 drmModeConnectorPtr drm_connector = NULL;
300 drmModeEncoderPtr drm_encoder = NULL;
301 struct output_private *priv;
302 char name[32];
303 int c, p;
304
305 res = drmModeGetResources(ms->fd);
306 if (res == 0) {
307 DRV_ERROR("Failed drmModeGetResources\n");
308 return;
309 }
310
311 for (c = 0; c < res->count_connectors; c++) {
312 Bool is_implicit = TRUE;
313
314 drm_connector = drmModeGetConnector(ms->fd, res->connectors[c]);
315 if (!drm_connector)
316 goto out;
317
318
319 for (p = 0; p < drm_connector->count_props; p++) {
320 drmModePropertyPtr prop;
321
322 prop = drmModeGetProperty(ms->fd, drm_connector->props[p]);
323
324 if (prop) {
325
326#if 0
327 /*
328 * Disabled until we sort out what the interface should
329 * look like.
330 */
331
332 if (strcmp(prop->name, "implicit placement") == 0) {
333 drmModeConnectorSetProperty(ms->fd,
334 drm_connector->connector_id,
335 prop->prop_id,
336 0);
337 is_implicit = FALSE;
338 }
339#endif
340 drmModeFreeProperty(prop);
341 }
342 }
343
344 if (drm_connector->connector_type >=
345 sizeof(output_enum_list) / sizeof(output_enum_list[0]))
346 drm_connector->connector_type = 0;
347
348 snprintf(name, 32, "%s%d",
349 output_enum_list[drm_connector->connector_type],
350 drm_connector->connector_type_id);
351
352
353 priv = calloc(sizeof(*priv), 1);
354 if (!priv) {
355 continue;
356 }
357
358 output = xf86OutputCreate(pScrn, &output_funcs, name);
359 if (!output) {
360 free(priv);
361 continue;
362 }
363
364 priv->is_implicit = is_implicit;
365
366 drm_encoder = drmModeGetEncoder(ms->fd, drm_connector->encoders[0]);
367 if (drm_encoder) {
368 output->possible_crtcs = drm_encoder->possible_crtcs;
369 output->possible_clones = drm_encoder->possible_clones;
370 } else {
371 output->possible_crtcs = 0;
372 output->possible_clones = 0;
373 }
374 priv->c = c;
375 priv->drm_connector = drm_connector;
376 output->driver_private = priv;
377 output->subpixel_order = SubPixelHorizontalRGB;
378 output->interlaceAllowed = FALSE;
379 output->doubleScanAllowed = FALSE;
380 }
381
382 out:
383 drmModeFreeResources(res);
384}
385
386unsigned
387xorg_output_get_id(xf86OutputPtr output)
388{
389 struct output_private *priv = output->driver_private;
390 return priv->drm_connector->connector_id;
391}
392
393/* vim: set sw=4 ts=8 sts=4: */