197
compare_outputs (CoglOutput *a,
200
return strcmp (a->name, b->name);
203
#define CSO(X) COGL_SUBPIXEL_ORDER_ ## X
204
static CoglSubpixelOrder subpixel_map[6][6] = {
205
{ CSO(UNKNOWN), CSO(NONE), CSO(HORIZONTAL_RGB), CSO(HORIZONTAL_BGR),
206
CSO(VERTICAL_RGB), CSO(VERTICAL_BGR) }, /* 0 */
207
{ CSO(UNKNOWN), CSO(NONE), CSO(VERTICAL_RGB), CSO(VERTICAL_BGR),
208
CSO(HORIZONTAL_BGR), CSO(HORIZONTAL_RGB) }, /* 90 */
209
{ CSO(UNKNOWN), CSO(NONE), CSO(HORIZONTAL_BGR), CSO(HORIZONTAL_RGB),
210
CSO(VERTICAL_BGR), CSO(VERTICAL_RGB) }, /* 180 */
211
{ CSO(UNKNOWN), CSO(NONE), CSO(VERTICAL_BGR), CSO(VERTICAL_RGB),
212
CSO(HORIZONTAL_RGB), CSO(HORIZONTAL_BGR) }, /* 270 */
213
{ CSO(UNKNOWN), CSO(NONE), CSO(HORIZONTAL_BGR), CSO(HORIZONTAL_RGB),
214
CSO(VERTICAL_RGB), CSO(VERTICAL_BGR) }, /* Reflect_X */
215
{ CSO(UNKNOWN), CSO(NONE), CSO(HORIZONTAL_RGB), CSO(HORIZONTAL_BGR),
216
CSO(VERTICAL_BGR), CSO(VERTICAL_RGB) }, /* Reflect_Y */
221
update_outputs (CoglRenderer *renderer,
224
CoglXlibRenderer *xlib_renderer =
225
_cogl_xlib_renderer_get_data (renderer);
226
XRRScreenResources *resources;
227
CoglXlibTrapState state;
228
CoglBool error = FALSE;
229
GList *new_outputs = NULL;
231
CoglBool changed = FALSE;
234
xlib_renderer->outputs_update_serial = XNextRequest (xlib_renderer->xdpy);
236
resources = XRRGetScreenResources (xlib_renderer->xdpy,
237
DefaultRootWindow (xlib_renderer->xdpy));
239
_cogl_xlib_renderer_trap_errors (renderer, &state);
241
for (i = 0; i < resources->ncrtc && !error; i++)
243
XRRCrtcInfo *crtc_info = NULL;
244
XRROutputInfo *output_info = NULL;
246
float refresh_rate = 0;
249
crtc_info = XRRGetCrtcInfo (xlib_renderer->xdpy,
250
resources, resources->crtcs[i]);
251
if (crtc_info == NULL)
257
if (crtc_info->mode == None)
260
for (j = 0; j < resources->nmode; j++)
262
if (resources->modes[j].id == crtc_info->mode)
263
refresh_rate = (resources->modes[j].dotClock /
264
((float)resources->modes[j].hTotal *
265
resources->modes[j].vTotal));
268
output_info = XRRGetOutputInfo (xlib_renderer->xdpy,
270
crtc_info->outputs[0]);
271
if (output_info == NULL)
277
output = _cogl_output_new (output_info->name);
278
output->x = crtc_info->x;
279
output->y = crtc_info->y;
280
output->width = crtc_info->width;
281
output->height = crtc_info->height;
282
if ((crtc_info->rotation & (RR_Rotate_90 | RR_Rotate_270)) != 0)
284
output->mm_width = output_info->mm_height;
285
output->mm_height = output_info->mm_width;
289
output->mm_width = output_info->mm_width;
290
output->mm_height = output_info->mm_height;
293
output->refresh_rate = refresh_rate;
295
switch (output_info->subpixel_order)
297
case SubPixelUnknown:
299
output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
302
output->subpixel_order = COGL_SUBPIXEL_ORDER_NONE;
304
case SubPixelHorizontalRGB:
305
output->subpixel_order = COGL_SUBPIXEL_ORDER_HORIZONTAL_RGB;
307
case SubPixelHorizontalBGR:
308
output->subpixel_order = COGL_SUBPIXEL_ORDER_HORIZONTAL_BGR;
310
case SubPixelVerticalRGB:
311
output->subpixel_order = COGL_SUBPIXEL_ORDER_VERTICAL_RGB;
313
case SubPixelVerticalBGR:
314
output->subpixel_order = COGL_SUBPIXEL_ORDER_VERTICAL_BGR;
318
output->subpixel_order = COGL_SUBPIXEL_ORDER_HORIZONTAL_RGB;
320
/* Handle the effect of rotation and reflection on subpixel order (ugh) */
321
for (j = 0; j < 6; j++)
323
if ((crtc_info->rotation & (1 << j)) != 0)
324
output->subpixel_order = subpixel_map[j][output->subpixel_order];
327
new_outputs = g_list_prepend (new_outputs, output);
330
if (crtc_info != NULL)
333
if (output_info != NULL)
341
new_outputs = g_list_sort (new_outputs, (GCompareFunc)compare_outputs);
344
m = renderer->outputs;
349
CoglOutput *output_l = l ? (CoglOutput *)l->data : NULL;
350
CoglOutput *output_m = m ? (CoglOutput *)m->data : NULL;
353
cmp = compare_outputs (output_l, output_m);
361
GList *m_next = m->next;
363
if (!_cogl_output_values_equal (output_l, output_m))
365
renderer->outputs = g_list_remove_link (renderer->outputs, m);
366
renderer->outputs = g_list_insert_before (renderer->outputs,
368
cogl_object_ref (output_l);
379
g_list_insert_before (renderer->outputs, m, output_l);
380
cogl_object_ref (output_l);
386
GList *m_next = m->next;
387
renderer->outputs = g_list_remove_link (renderer->outputs, m);
394
g_list_free_full (new_outputs, (GDestroyNotify)cogl_object_unref);
395
_cogl_xlib_renderer_untrap_errors (renderer, &state);
399
const CoglWinsysVtable *winsys = renderer->winsys_vtable;
402
COGL_NOTE (WINSYS, "Outputs changed:");
404
COGL_NOTE (WINSYS, "Outputs:");
406
for (l = renderer->outputs; l; l = l->next)
408
CoglOutput *output = l->data;
409
const char *subpixel_string;
411
switch (output->subpixel_order)
413
case COGL_SUBPIXEL_ORDER_UNKNOWN:
415
subpixel_string = "unknown";
417
case COGL_SUBPIXEL_ORDER_NONE:
418
subpixel_string = "none";
420
case COGL_SUBPIXEL_ORDER_HORIZONTAL_RGB:
421
subpixel_string = "horizontal_rgb";
423
case COGL_SUBPIXEL_ORDER_HORIZONTAL_BGR:
424
subpixel_string = "horizontal_bgr";
426
case COGL_SUBPIXEL_ORDER_VERTICAL_RGB:
427
subpixel_string = "vertical_rgb";
429
case COGL_SUBPIXEL_ORDER_VERTICAL_BGR:
430
subpixel_string = "vertical_bgr";
435
" %10s: +%d+%dx%dx%d mm=%dx%d dpi=%.1fx%.1f "
436
"subpixel_order=%s refresh_rate=%.3f",
438
output->x, output->y, output->width, output->height,
439
output->mm_width, output->mm_height,
440
output->width / (output->mm_width / 25.4),
441
output->height / (output->mm_height / 25.4),
443
output->refresh_rate);
446
if (notify && winsys->renderer_outputs_changed != NULL)
447
winsys->renderer_outputs_changed (renderer);
451
static CoglFilterReturn
452
randr_filter (XEvent *event,
455
CoglRenderer *renderer = data;
456
CoglXlibRenderer *xlib_renderer =
457
_cogl_xlib_renderer_get_data (renderer);
458
CoglX11Renderer *x11_renderer =
459
(CoglX11Renderer *) xlib_renderer;
461
if (x11_renderer->randr_base != -1 &&
462
(event->xany.type == x11_renderer->randr_base + RRScreenChangeNotify ||
463
event->xany.type == x11_renderer->randr_base + RRNotify) &&
464
event->xany.serial >= xlib_renderer->outputs_update_serial)
465
update_outputs (renderer, TRUE);
467
return COGL_FILTER_CONTINUE;
194
_cogl_xlib_renderer_connect (CoglRenderer *renderer, GError **error)
471
_cogl_xlib_renderer_connect (CoglRenderer *renderer, CoglError **error)
196
473
CoglXlibRenderer *xlib_renderer =
197
474
_cogl_xlib_renderer_get_data (renderer);
198
475
CoglX11Renderer *x11_renderer =
199
476
(CoglX11Renderer *) xlib_renderer;
200
477
int damage_error;
202
480
if (!assert_xlib_display (renderer, error))