|
|
|
@ -1,4 +1,5 @@
|
|
|
|
|
/*
|
|
|
|
|
* Copyright © 2010 Raptor Engineering
|
|
|
|
|
* Copyright © 2007 Intel Corporation
|
|
|
|
|
*
|
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
@ -24,9 +25,9 @@
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
Status crtc_disable (struct CrtcInfo *crtc);
|
|
|
|
|
Status internal_crtc_disable (struct CrtcInfo *crtc);
|
|
|
|
|
|
|
|
|
|
char * get_output_name (struct ScreenInfo *screen_info, RROutput id)
|
|
|
|
|
char * internal_get_output_name (struct ScreenInfo *screen_info, RROutput id)
|
|
|
|
|
{
|
|
|
|
|
char *output_name = NULL;
|
|
|
|
|
int i;
|
|
|
|
@ -44,7 +45,7 @@ char * get_output_name (struct ScreenInfo *screen_info, RROutput id)
|
|
|
|
|
return output_name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XRRModeInfo * find_mode_by_xid (struct ScreenInfo *screen_info, RRMode mode_id)
|
|
|
|
|
XRRModeInfo * internal_find_mode_by_xid (struct ScreenInfo *screen_info, RRMode mode_id)
|
|
|
|
|
{
|
|
|
|
|
XRRModeInfo *mode_info = NULL;
|
|
|
|
|
XRRScreenResources *res;
|
|
|
|
@ -61,7 +62,7 @@ XRRModeInfo * find_mode_by_xid (struct ScreenInfo *screen_info, RRMode mode_id)
|
|
|
|
|
return mode_info;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static XRRCrtcInfo * find_crtc_by_xid (struct ScreenInfo *screen_info, RRCrtc crtc_id)
|
|
|
|
|
static XRRCrtcInfo * internal_find_crtc_by_xid (struct ScreenInfo *screen_info, RRCrtc crtc_id)
|
|
|
|
|
{
|
|
|
|
|
XRRCrtcInfo *crtc_info;
|
|
|
|
|
Display *dpy;
|
|
|
|
@ -75,7 +76,7 @@ static XRRCrtcInfo * find_crtc_by_xid (struct ScreenInfo *screen_info, RRCrtc cr
|
|
|
|
|
return crtc_info;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int get_width_by_output_id (struct ScreenInfo *screen_info, RROutput output_id)
|
|
|
|
|
int internal_get_width_by_output_id (struct ScreenInfo *screen_info, RROutput output_id)
|
|
|
|
|
{
|
|
|
|
|
struct OutputInfo *output_info;
|
|
|
|
|
struct CrtcInfo *crtc_info;
|
|
|
|
@ -92,9 +93,9 @@ int get_width_by_output_id (struct ScreenInfo *screen_info, RROutput output_id)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
mode_id = crtc_info->cur_mode_id;
|
|
|
|
|
mode_info = find_mode_by_xid (screen_info, mode_id);
|
|
|
|
|
mode_info = internal_find_mode_by_xid (screen_info, mode_id);
|
|
|
|
|
|
|
|
|
|
width = mode_width (mode_info, crtc_info->cur_rotation);
|
|
|
|
|
width = internal_mode_width (mode_info, crtc_info->cur_rotation);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
@ -103,7 +104,7 @@ int get_width_by_output_id (struct ScreenInfo *screen_info, RROutput output_id)
|
|
|
|
|
return width;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int get_height_by_output_id (struct ScreenInfo *screen_info, RROutput output_id)
|
|
|
|
|
int internal_get_height_by_output_id (struct ScreenInfo *screen_info, RROutput output_id)
|
|
|
|
|
{
|
|
|
|
|
struct OutputInfo *output_info;
|
|
|
|
|
struct CrtcInfo *crtc_info;
|
|
|
|
@ -120,9 +121,9 @@ int get_height_by_output_id (struct ScreenInfo *screen_info, RROutput output_id)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
mode_id = crtc_info->cur_mode_id;
|
|
|
|
|
mode_info = find_mode_by_xid (screen_info, mode_id);
|
|
|
|
|
mode_info = internal_find_mode_by_xid (screen_info, mode_id);
|
|
|
|
|
|
|
|
|
|
height = mode_height (mode_info, crtc_info->cur_rotation);
|
|
|
|
|
height = internal_mode_height (mode_info, crtc_info->cur_rotation);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
@ -131,7 +132,7 @@ int get_height_by_output_id (struct ScreenInfo *screen_info, RROutput output_id)
|
|
|
|
|
return height;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int mode_height (XRRModeInfo *mode_info, Rotation rotation)
|
|
|
|
|
int internal_mode_height (XRRModeInfo *mode_info, Rotation rotation)
|
|
|
|
|
{
|
|
|
|
|
switch (rotation & 0xf) {
|
|
|
|
|
case RR_Rotate_0:
|
|
|
|
@ -145,7 +146,7 @@ int mode_height (XRRModeInfo *mode_info, Rotation rotation)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int mode_width (XRRModeInfo *mode_info, Rotation rotation)
|
|
|
|
|
int internal_mode_width (XRRModeInfo *mode_info, Rotation rotation)
|
|
|
|
|
{
|
|
|
|
|
switch (rotation & 0xf) {
|
|
|
|
|
case RR_Rotate_0:
|
|
|
|
@ -160,7 +161,7 @@ int mode_width (XRRModeInfo *mode_info, Rotation rotation)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static struct CrtcInfo * find_crtc (struct ScreenInfo *screen_info, XRROutputInfo *output)
|
|
|
|
|
static struct CrtcInfo * internal_find_crtc (struct ScreenInfo *screen_info, XRROutputInfo *output)
|
|
|
|
|
{
|
|
|
|
|
struct CrtcInfo *crtc_info = NULL;
|
|
|
|
|
int i;
|
|
|
|
@ -175,7 +176,7 @@ static struct CrtcInfo * find_crtc (struct ScreenInfo *screen_info, XRROutputInf
|
|
|
|
|
return crtc_info;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct CrtcInfo * auto_find_crtc (struct ScreenInfo *screen_info, struct OutputInfo *output_info)
|
|
|
|
|
struct CrtcInfo * internal_auto_find_crtc (struct ScreenInfo *screen_info, struct OutputInfo *output_info)
|
|
|
|
|
{
|
|
|
|
|
struct CrtcInfo *crtc_info = NULL;
|
|
|
|
|
int i;
|
|
|
|
@ -194,7 +195,7 @@ struct CrtcInfo * auto_find_crtc (struct ScreenInfo *screen_info, struct OutputI
|
|
|
|
|
return crtc_info;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int set_screen_size (struct ScreenInfo *screen_info)
|
|
|
|
|
int internal_set_screen_size (struct ScreenInfo *screen_info)
|
|
|
|
|
{
|
|
|
|
|
Display *dpy;
|
|
|
|
|
int screen;
|
|
|
|
@ -214,12 +215,12 @@ int set_screen_size (struct ScreenInfo *screen_info)
|
|
|
|
|
if (!crtc->cur_mode_id) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
mode_info = find_mode_by_xid (screen_info, crtc->cur_mode_id);
|
|
|
|
|
mode_info = internal_find_mode_by_xid (screen_info, crtc->cur_mode_id);
|
|
|
|
|
cur_x = crtc->cur_x;
|
|
|
|
|
cur_y = crtc->cur_y;
|
|
|
|
|
|
|
|
|
|
w = mode_width (mode_info, crtc->cur_rotation);
|
|
|
|
|
h = mode_height (mode_info, crtc->cur_rotation);
|
|
|
|
|
w = internal_mode_width (mode_info, crtc->cur_rotation);
|
|
|
|
|
h = internal_mode_height (mode_info, crtc->cur_rotation);
|
|
|
|
|
|
|
|
|
|
if (cur_x + w > max_width) {
|
|
|
|
|
max_width = cur_x + w;
|
|
|
|
@ -272,7 +273,7 @@ int set_screen_size (struct ScreenInfo *screen_info)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void screen_apply (struct ScreenInfo *screen_info)
|
|
|
|
|
void internal_screen_apply (struct ScreenInfo *screen_info)
|
|
|
|
|
{
|
|
|
|
|
int width, height;
|
|
|
|
|
int mmWidth, mmHeight;
|
|
|
|
@ -301,7 +302,7 @@ void screen_apply (struct ScreenInfo *screen_info)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Status crtc_apply (struct CrtcInfo *crtc_info)
|
|
|
|
|
Status internal_crtc_apply (struct CrtcInfo *crtc_info)
|
|
|
|
|
{
|
|
|
|
|
struct ScreenInfo *screen_info;
|
|
|
|
|
XRRCrtcInfo *rr_crtc_info;
|
|
|
|
@ -333,7 +334,7 @@ Status crtc_apply (struct CrtcInfo *crtc_info)
|
|
|
|
|
noutput = crtc_info->cur_noutput;
|
|
|
|
|
|
|
|
|
|
if (0 == noutput) {
|
|
|
|
|
return crtc_disable (crtc_info);
|
|
|
|
|
return internal_crtc_disable (crtc_info);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
outputs = malloc (sizeof (RROutput) * noutput);
|
|
|
|
@ -360,7 +361,7 @@ Status crtc_apply (struct CrtcInfo *crtc_info)
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Status crtc_disable (struct CrtcInfo *crtc)
|
|
|
|
|
Status internal_crtc_disable (struct CrtcInfo *crtc)
|
|
|
|
|
{
|
|
|
|
|
struct ScreenInfo *screen_info;
|
|
|
|
|
|
|
|
|
@ -370,7 +371,7 @@ Status crtc_disable (struct CrtcInfo *crtc)
|
|
|
|
|
0, 0, None, RR_Rotate_0, NULL, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct ScreenInfo* read_screen_info (Display *display)
|
|
|
|
|
struct ScreenInfo* internal_read_screen_info (Display *display)
|
|
|
|
|
{
|
|
|
|
|
struct ScreenInfo *screen_info;
|
|
|
|
|
int screen_num;
|
|
|
|
@ -428,7 +429,7 @@ struct ScreenInfo* read_screen_info (Display *display)
|
|
|
|
|
|
|
|
|
|
output->id = sr->outputs[i];
|
|
|
|
|
output->info = XRRGetOutputInfo (display, sr, sr->outputs[i]);
|
|
|
|
|
output->cur_crtc = find_crtc (screen_info, output->info);
|
|
|
|
|
output->cur_crtc = internal_find_crtc (screen_info, output->info);
|
|
|
|
|
output->auto_set = 0;
|
|
|
|
|
if (output->cur_crtc) {
|
|
|
|
|
output->off_set = 0;
|
|
|
|
@ -446,7 +447,7 @@ struct ScreenInfo* read_screen_info (Display *display)
|
|
|
|
|
return screen_info;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void free_screen_info (struct ScreenInfo *screen_info)
|
|
|
|
|
void internal_free_screen_info (struct ScreenInfo *screen_info)
|
|
|
|
|
{
|
|
|
|
|
free (screen_info->outputs);
|
|
|
|
|
free (screen_info->crtcs);
|
|
|
|
@ -456,7 +457,7 @@ void free_screen_info (struct ScreenInfo *screen_info)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*check if other outputs that connected to the same crtc support this mode*/
|
|
|
|
|
static int check_mode (struct ScreenInfo *screen_info, struct OutputInfo *output, RRMode mode_id)
|
|
|
|
|
static int internal_check_mode (struct ScreenInfo *screen_info, struct OutputInfo *output, RRMode mode_id)
|
|
|
|
|
{
|
|
|
|
|
XRRCrtcInfo *crtc_info;
|
|
|
|
|
/* XRR */
|
|
|
|
@ -493,7 +494,7 @@ static int check_mode (struct ScreenInfo *screen_info, struct OutputInfo *output
|
|
|
|
|
return mode_ok;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static RRCrtc get_crtc_id_by_output_id (struct ScreenInfo *screen_info, RROutput output_id)
|
|
|
|
|
static RRCrtc internal_get_crtc_id_by_output_id (struct ScreenInfo *screen_info, RROutput output_id)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
RRCrtc crtc_id = -1;
|
|
|
|
@ -513,7 +514,7 @@ static RRCrtc get_crtc_id_by_output_id (struct ScreenInfo *screen_info, RROutput
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct CrtcInfo *
|
|
|
|
|
get_crtc_info_by_xid (struct ScreenInfo *screen_info, RRCrtc crtc_id)
|
|
|
|
|
internal_get_crtc_info_by_xid (struct ScreenInfo *screen_info, RRCrtc crtc_id)
|
|
|
|
|
{
|
|
|
|
|
struct CrtcInfo *crtc_info = NULL;
|
|
|
|
|
int i;
|
|
|
|
@ -529,7 +530,7 @@ get_crtc_info_by_xid (struct ScreenInfo *screen_info, RRCrtc crtc_id)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static XRRModeInfo *
|
|
|
|
|
preferred_mode (struct ScreenInfo *screen_info, struct OutputInfo *output)
|
|
|
|
|
internal_preferred_mode (struct ScreenInfo *screen_info, struct OutputInfo *output)
|
|
|
|
|
{
|
|
|
|
|
XRROutputInfo *output_info = output->info;
|
|
|
|
|
Display *dpy;
|
|
|
|
@ -543,7 +544,7 @@ preferred_mode (struct ScreenInfo *screen_info, struct OutputInfo *output)
|
|
|
|
|
best = NULL;
|
|
|
|
|
bestDist = 0;
|
|
|
|
|
for (m = 0; m < output_info->nmode; m++) {
|
|
|
|
|
XRRModeInfo *mode_info = find_mode_by_xid (screen_info, output_info->modes[m]);
|
|
|
|
|
XRRModeInfo *mode_info = internal_find_mode_by_xid (screen_info, output_info->modes[m]);
|
|
|
|
|
int dist;
|
|
|
|
|
|
|
|
|
|
if (m < output_info->npreferred)
|
|
|
|
@ -563,14 +564,14 @@ preferred_mode (struct ScreenInfo *screen_info, struct OutputInfo *output)
|
|
|
|
|
return best;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main_low_apply (struct ScreenInfo *screen_info)
|
|
|
|
|
int internal_main_low_apply (struct ScreenInfo *screen_info)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
struct CrtcInfo *crtc_info;
|
|
|
|
|
|
|
|
|
|
/* set_positions (screen_info); */
|
|
|
|
|
|
|
|
|
|
if (!set_screen_size (screen_info)) {
|
|
|
|
|
if (!internal_set_screen_size (screen_info)) {
|
|
|
|
|
printf("Screen Size FAILURE\n\r");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -579,7 +580,7 @@ int main_low_apply (struct ScreenInfo *screen_info)
|
|
|
|
|
int old_x, old_y, old_w, old_h;
|
|
|
|
|
|
|
|
|
|
XRRCrtcInfo *crtc_info = XRRGetCrtcInfo (screen_info->dpy, screen_info->res, screen_info->crtcs[i]->id);
|
|
|
|
|
XRRModeInfo *old_mode = find_mode_by_xid (screen_info, crtc_info->mode);
|
|
|
|
|
XRRModeInfo *old_mode = internal_find_mode_by_xid (screen_info, crtc_info->mode);
|
|
|
|
|
|
|
|
|
|
if (crtc_info->mode == None) {
|
|
|
|
|
continue;
|
|
|
|
@ -587,24 +588,24 @@ int main_low_apply (struct ScreenInfo *screen_info)
|
|
|
|
|
|
|
|
|
|
old_x = crtc_info->x;
|
|
|
|
|
old_y = crtc_info->y;
|
|
|
|
|
old_w = mode_width (old_mode, crtc_info->rotation);
|
|
|
|
|
old_h = mode_height (old_mode, crtc_info->rotation);
|
|
|
|
|
old_w = internal_mode_width (old_mode, crtc_info->rotation);
|
|
|
|
|
old_h = internal_mode_height (old_mode, crtc_info->rotation);
|
|
|
|
|
|
|
|
|
|
if (old_x + old_w <= screen_info->cur_width &&
|
|
|
|
|
old_y + old_h <= screen_info->cur_height ) {
|
|
|
|
|
continue;
|
|
|
|
|
} else {
|
|
|
|
|
crtc_disable (screen_info->crtcs[i]);
|
|
|
|
|
internal_crtc_disable (screen_info->crtcs[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
screen_apply (screen_info);
|
|
|
|
|
internal_screen_apply (screen_info);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < screen_info->n_crtc; i++) {
|
|
|
|
|
Status s;
|
|
|
|
|
crtc_info = screen_info->crtcs[i];
|
|
|
|
|
|
|
|
|
|
s = crtc_apply (crtc_info);
|
|
|
|
|
s = internal_crtc_apply (crtc_info);
|
|
|
|
|
if (RRSetConfigSuccess != s) {
|
|
|
|
|
fprintf (stderr, "crtc apply error\n");
|
|
|
|
|
}
|
|
|
|
@ -613,7 +614,7 @@ int main_low_apply (struct ScreenInfo *screen_info)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void output_auto (struct ScreenInfo *screen_info, struct OutputInfo *output_info)
|
|
|
|
|
void internal_output_auto (struct ScreenInfo *screen_info, struct OutputInfo *output_info)
|
|
|
|
|
{
|
|
|
|
|
XRRModeInfo *mode_info;
|
|
|
|
|
RRMode mode_id;
|
|
|
|
@ -627,11 +628,11 @@ void output_auto (struct ScreenInfo *screen_info, struct OutputInfo *output_info
|
|
|
|
|
probe_output_info = XRRGetOutputInfo (screen_info->dpy, cur_res, output_info->id);
|
|
|
|
|
if (RR_Disconnected != probe_output_info->connection) {
|
|
|
|
|
output_info->info = probe_output_info;
|
|
|
|
|
output_info->cur_crtc = auto_find_crtc (screen_info, output_info);
|
|
|
|
|
output_info->cur_crtc = internal_auto_find_crtc (screen_info, output_info);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mode_info = preferred_mode (screen_info, output_info);
|
|
|
|
|
mode_info = internal_preferred_mode (screen_info, output_info);
|
|
|
|
|
if (!mode_info) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@ -641,7 +642,7 @@ void output_auto (struct ScreenInfo *screen_info, struct OutputInfo *output_info
|
|
|
|
|
if (crtc_info) {
|
|
|
|
|
crtc_info->cur_mode_id = mode_id;
|
|
|
|
|
} else {
|
|
|
|
|
crtc_info = auto_find_crtc (screen_info, output_info);
|
|
|
|
|
crtc_info = internal_auto_find_crtc (screen_info, output_info);
|
|
|
|
|
if (!crtc_info) {
|
|
|
|
|
#if RANDR_GUI_DEBUG
|
|
|
|
|
fprintf (stderr, "Can not find usable CRTC\n");
|
|
|
|
@ -659,7 +660,7 @@ void output_auto (struct ScreenInfo *screen_info, struct OutputInfo *output_info
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void output_off (struct ScreenInfo *screen_info, struct OutputInfo *output)
|
|
|
|
|
void internal_output_off (struct ScreenInfo *screen_info, struct OutputInfo *output)
|
|
|
|
|
{
|
|
|
|
|
if (output->cur_crtc) {
|
|
|
|
|
output->cur_crtc->cur_noutput--;
|
|
|
|
|