summaryrefslogtreecommitdiffstats
path: root/kcontrol/randr/lowlevel_randr.c
diff options
context:
space:
mode:
Diffstat (limited to 'kcontrol/randr/lowlevel_randr.c')
-rw-r--r--kcontrol/randr/lowlevel_randr.c670
1 files changed, 0 insertions, 670 deletions
diff --git a/kcontrol/randr/lowlevel_randr.c b/kcontrol/randr/lowlevel_randr.c
deleted file mode 100644
index 7f3e890fd..000000000
--- a/kcontrol/randr/lowlevel_randr.c
+++ /dev/null
@@ -1,670 +0,0 @@
-/*
- * Copyright © 2007 Intel Corporation
- *
- * 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 the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, 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 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 NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS 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.
- */
-#include "lowlevel_randr.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-Status crtc_disable (struct CrtcInfo *crtc);
-
-char * get_output_name (struct ScreenInfo *screen_info, RROutput id)
-{
- char *output_name = NULL;
- int i;
-
- for (i = 0; i < screen_info->n_output; i++) {
- if (id == screen_info->outputs[i]->id) {
- output_name = screen_info->outputs[i]->info->name;
- }
- }
-
- if (!output_name) {
- output_name = "Unknown";
- }
-
- return output_name;
-}
-
-XRRModeInfo * find_mode_by_xid (struct ScreenInfo *screen_info, RRMode mode_id)
-{
- XRRModeInfo *mode_info = NULL;
- XRRScreenResources *res;
- int i;
-
- res = screen_info->res;
- for (i = 0; i < res->nmode; i++) {
- if (mode_id == res->modes[i].id) {
- mode_info = &res->modes[i];
- break;
- }
- }
-
- return mode_info;
-}
-
-static XRRCrtcInfo * find_crtc_by_xid (struct ScreenInfo *screen_info, RRCrtc crtc_id)
-{
- XRRCrtcInfo *crtc_info;
- Display *dpy;
- XRRScreenResources *res;
-
- dpy = screen_info->dpy;
- res = screen_info->res;
-
- crtc_info = XRRGetCrtcInfo (dpy, res, crtc_id);
-
- return crtc_info;
-}
-
-int get_width_by_output_id (struct ScreenInfo *screen_info, RROutput output_id)
-{
- struct OutputInfo *output_info;
- struct CrtcInfo *crtc_info;
- RRMode mode_id;
- XRRModeInfo *mode_info;
- int i;
- int width = -1;
-
- for (i = 0; i < screen_info->n_output; i++) {
- if (output_id == screen_info->outputs[i]->id) {
- crtc_info = screen_info->outputs[i]->cur_crtc;
- if (!crtc_info) {
- width = 0;
- break;
- }
- mode_id = crtc_info->cur_mode_id;
- mode_info = find_mode_by_xid (screen_info, mode_id);
-
- width = mode_width (mode_info, crtc_info->cur_rotation);
-
- break;
- }
- }
-
- return width;
-}
-
-int get_height_by_output_id (struct ScreenInfo *screen_info, RROutput output_id)
-{
- struct OutputInfo *output_info;
- struct CrtcInfo *crtc_info;
- RRMode mode_id;
- XRRModeInfo *mode_info;
- int i;
- int height = -1;
-
- for (i = 0; i < screen_info->n_output; i++) {
- if (output_id == screen_info->outputs[i]->id) {
- crtc_info = screen_info->outputs[i]->cur_crtc;
- if (!crtc_info) {
- height = 0;
- break;
- }
- mode_id = crtc_info->cur_mode_id;
- mode_info = find_mode_by_xid (screen_info, mode_id);
-
- height = mode_height (mode_info, crtc_info->cur_rotation);
-
- break;
- }
- }
-
- return height;
-}
-
-int mode_height (XRRModeInfo *mode_info, Rotation rotation)
-{
- switch (rotation & 0xf) {
- case RR_Rotate_0:
- case RR_Rotate_180:
- return mode_info->height;
- case RR_Rotate_90:
- case RR_Rotate_270:
- return mode_info->width;
- default:
- return 0;
- }
-}
-
-int mode_width (XRRModeInfo *mode_info, Rotation rotation)
-{
- switch (rotation & 0xf) {
- case RR_Rotate_0:
- case RR_Rotate_180:
- return mode_info->width;
- case RR_Rotate_90:
- case RR_Rotate_270:
- return mode_info->height;
- default:
- return 0;
- }
-}
-
-
-static struct CrtcInfo * find_crtc (struct ScreenInfo *screen_info, XRROutputInfo *output)
-{
- struct CrtcInfo *crtc_info = NULL;
- int i;
-
- for (i = 0; i < screen_info->n_crtc; i++) {
- if (screen_info->crtcs[i]->id == output->crtc) {
- crtc_info = screen_info->crtcs[i];
- break;
- }
- }
-
- return crtc_info;
-}
-
-struct CrtcInfo * auto_find_crtc (struct ScreenInfo *screen_info, struct OutputInfo *output_info)
-{
- struct CrtcInfo *crtc_info = NULL;
- int i;
-
- for (i = 0; i < screen_info->n_crtc; i++) {
- if (0 == screen_info->crtcs[i]->cur_noutput) {
- crtc_info = screen_info->crtcs[i];
- break;
- }
- }
-
- if (NULL == crtc_info) {
- crtc_info = screen_info->crtcs[0];
- }
-
- return crtc_info;
-}
-
-int set_screen_size (struct ScreenInfo *screen_info)
-{
- Display *dpy;
- int screen;
- struct CrtcInfo *crtc;
- XRRModeInfo *mode_info;
- int cur_x = 0, cur_y = 0;
- int w = 0, h = 0;
- int mmW, mmH;
- int max_width = 0, max_height = 0;
- int i;
-
- dpy = screen_info->dpy;
- screen = DefaultScreen (dpy);
-
- for (i = 0; i < screen_info->n_crtc; i++) {
- crtc = screen_info->crtcs[i];
- if (!crtc->cur_mode_id) {
- continue;
- }
- mode_info = 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);
-
- if (cur_x + w > max_width) {
- max_width = cur_x + w;
- }
- if (cur_y + h > max_height) {
- max_height = cur_y + h;
- }
- }
-
- if (max_width > screen_info->max_width) {
- #if RANDR_GUI_DEBUG
- fprintf (stderr, "user set screen width %d, larger than max width %d, set to max width\n",
- cur_x + w, screen_info->max_width);
- #endif
- return 0;
- } else if (max_width < screen_info->min_width) {
- screen_info->cur_width = screen_info->min_width;
- } else {
- screen_info->cur_width = max_width;
- }
-
- if (max_height > screen_info->max_height) {
- #if RANDR_GUI_DEBUG
- fprintf (stderr, "user set screen height %d, larger than max height %d, set to max height\n",
- cur_y + h, screen_info->max_height);
- #endif
- return 0;
- } else if (max_height < screen_info->min_height) {
- screen_info->cur_height = screen_info->min_height;
- } else {
- screen_info->cur_height = max_height;
- }
-
- /* calculate mmWidth, mmHeight */
- if (screen_info->cur_width != DisplayWidth (dpy, screen) ||
- screen_info->cur_height != DisplayHeight (dpy, screen) ) {
- double dpi;
-
- dpi = (25.4 * DisplayHeight (dpy, screen)) / DisplayHeightMM(dpy, screen);
- mmW = (25.4 * screen_info->cur_width) / dpi;
- mmH = (25.4 * screen_info->cur_height) / dpi;
- } else {
- mmW = DisplayWidthMM (dpy, screen);
- mmH = DisplayHeightMM (dpy, screen);
- }
-
- screen_info->cur_mmWidth = mmW;
- screen_info->cur_mmHeight = mmH;
-
- return 1;
-}
-
-void screen_apply (struct ScreenInfo *screen_info)
-{
- int width, height;
- int mmWidth, mmHeight;
- Display *dpy, *cur_dpy;
- Window window;
- int screen;
- static int first = 1;
-
- width = screen_info->cur_width;
- height = screen_info->cur_height;
- mmWidth = screen_info->cur_mmWidth;
- mmHeight = screen_info->cur_mmHeight;
- dpy = screen_info->dpy;
- window = screen_info->window;
- screen = DefaultScreen (dpy);
-
- cur_dpy = XOpenDisplay (NULL);
-
- if (width == DisplayWidth (cur_dpy, screen) &&
- height == DisplayHeight (cur_dpy, screen) &&
- mmWidth == DisplayWidthMM (cur_dpy, screen) &&
- mmHeight == DisplayHeightMM (cur_dpy, screen) ) {
- return;
- } else {
- XRRSetScreenSize (dpy, window, width, height, mmWidth, mmHeight);
- }
-}
-
-Status crtc_apply (struct CrtcInfo *crtc_info)
-{
- struct ScreenInfo *screen_info;
- XRRCrtcInfo *rr_crtc_info;
- Display *dpy;
- XRRScreenResources *res;
- RRCrtc crtc_id;
- int x, y;
- RRMode mode_id;
- Rotation rotation;
- RROutput *outputs;
- int noutput;
- Status s;
- int i;
-
- /*if (!crtc_info->changed) {
- return RRSetConfigSuccess;
- }*/
-
- screen_info = crtc_info->screen_info;
- dpy = screen_info->dpy;
- res = screen_info->res;
- crtc_id = crtc_info->id;
- x = crtc_info->cur_x;
- y = crtc_info->cur_y;
-
- mode_id = crtc_info->cur_mode_id;
- rotation = crtc_info->cur_rotation;
-
- noutput = crtc_info->cur_noutput;
-
- if (0 == noutput) {
- return crtc_disable (crtc_info);
- }
-
- outputs = malloc (sizeof (RROutput) * noutput);
- noutput = 0;
- for (i = 0; i < screen_info->n_output; i++) {
- struct OutputInfo *output_info = screen_info->outputs[i];
-
- if (output_info->cur_crtc && crtc_id == output_info->cur_crtc->id) {
- outputs[noutput++] = output_info->id;
- }
- }
-
-
- s = XRRSetCrtcConfig (dpy, res, crtc_id, CurrentTime,
- x, y, mode_id, rotation,
- outputs, noutput);
-
- if (RRSetConfigSuccess == s) {
- crtc_info->changed = 0;
- }
-
- free (outputs);
-
- return s;
-}
-
-Status crtc_disable (struct CrtcInfo *crtc)
-{
- struct ScreenInfo *screen_info;
-
- screen_info = crtc->screen_info;
-
- return XRRSetCrtcConfig (screen_info->dpy, screen_info->res, crtc->id, CurrentTime,
- 0, 0, None, RR_Rotate_0, NULL, 0);
-}
-
-struct ScreenInfo* read_screen_info (Display *display)
-{
- struct ScreenInfo *screen_info;
- int screen_num;
- Window root_window;
- XRRScreenResources *sr;
- int i;
-
- screen_num = DefaultScreen (display);
- root_window = RootWindow (display, screen_num);
-
- sr = XRRGetScreenResources (display, root_window);
-
- screen_info = malloc (sizeof (struct ScreenInfo));
- screen_info->dpy = display;
- screen_info->window = root_window;
- screen_info->res = sr;
- screen_info->cur_width = DisplayWidth (display, screen_num);
- screen_info->cur_height = DisplayHeight (display, screen_num);
- screen_info->cur_mmWidth = DisplayWidthMM (display, screen_num);
- screen_info->cur_mmHeight = DisplayHeightMM (display, screen_num);
- screen_info->n_output = sr->noutput;
- screen_info->n_crtc = sr->ncrtc;
- screen_info->outputs = malloc (sizeof (struct OutputInfo *) * sr->noutput);
- screen_info->crtcs = malloc (sizeof (struct CrtcInfo *) * sr->ncrtc);
- screen_info->clone = 0;
-
- XRRGetScreenSizeRange (display, root_window, &screen_info->min_width, &screen_info->min_height, &screen_info->max_width, &screen_info->max_height);
-
- /* get crtc */
- for (i = 0; i < sr->ncrtc; i++) {
- struct CrtcInfo *crtc_info;
- screen_info->crtcs[i] = malloc (sizeof (struct CrtcInfo));
- crtc_info = screen_info->crtcs[i];
- XRRCrtcInfo *xrr_crtc_info = XRRGetCrtcInfo (display, sr, sr->crtcs[i]);
-
- crtc_info->id = sr->crtcs[i];
- crtc_info->info = xrr_crtc_info;
- crtc_info->cur_x = xrr_crtc_info->x;
- crtc_info->cur_y = xrr_crtc_info->y;
- crtc_info->cur_mode_id = xrr_crtc_info->mode;
- crtc_info->cur_rotation = xrr_crtc_info->rotation;
- crtc_info->rotations = xrr_crtc_info->rotations;
- crtc_info->cur_noutput = xrr_crtc_info->noutput;
-
- crtc_info->changed = 0;
- crtc_info->screen_info = screen_info;
- }
-
-
- /* get output */
- for (i = 0; i < sr->noutput; i++) {
- struct OutputInfo *output;
- screen_info->outputs[i] = malloc (sizeof (struct OutputInfo));
- output = screen_info->outputs[i];
-
- output->id = sr->outputs[i];
- output->info = XRRGetOutputInfo (display, sr, sr->outputs[i]);
- output->cur_crtc = find_crtc (screen_info, output->info);
- output->auto_set = 0;
- if (output->cur_crtc) {
- output->off_set = 0;
- } else {
- output->off_set = 1;
- }
-
- }
-
- /* set current crtc */
- screen_info->cur_crtc = screen_info->outputs[0]->cur_crtc;
- screen_info->primary_crtc = screen_info->cur_crtc;
- screen_info->cur_output = screen_info->outputs[0];
-
- return screen_info;
-}
-
-void free_screen_info (struct ScreenInfo *screen_info)
-{
- free (screen_info->outputs);
- free (screen_info->crtcs);
- free (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)
-{
- XRRCrtcInfo *crtc_info;
- /* XRR */
- int i, j;
- int mode_ok = 1;
-
- if (!output->cur_crtc) {
- return 1;
- }
-
- crtc_info = output->cur_crtc->info;
- for (i = 0; i < crtc_info->noutput; i++) {
- XRROutputInfo *output_info;
- int nmode;
-
- if (output->id == crtc_info->outputs[i]) {
- continue;
- }
-
- mode_ok = 0;
- output_info = XRRGetOutputInfo (screen_info->dpy, screen_info->res, crtc_info->outputs[i]);
- nmode = output_info->nmode;
- for (j = 0; j < nmode; j++) {
- if (mode_id == output_info->modes[j]) {
- mode_ok = 1;
- break;
- }
- }
- if (!mode_ok) {
- break;
- }
- }
-
- return mode_ok;
-}
-
-static RRCrtc get_crtc_id_by_output_id (struct ScreenInfo *screen_info, RROutput output_id)
-{
- int i;
- RRCrtc crtc_id = -1;
-
- for (i = 0; i < screen_info->n_output; i++) {
- if (output_id == screen_info->outputs[i]->id) {
- if (screen_info->outputs[i]->cur_crtc) {
- crtc_id = screen_info->outputs[i]->cur_crtc->id;
- } else {
- crtc_id = 0; /* this output is off */
- }
- break;
- }
- }
-
- return crtc_id;
-}
-
-static struct CrtcInfo *
-get_crtc_info_by_xid (struct ScreenInfo *screen_info, RRCrtc crtc_id)
-{
- struct CrtcInfo *crtc_info = NULL;
- int i;
-
- for (i = 0; i < screen_info->n_crtc; i++) {
- if (crtc_id == screen_info->crtcs[i]->id) {
- crtc_info = screen_info->crtcs[i];
- break;
- }
- }
-
- return crtc_info;
-}
-
-static XRRModeInfo *
-preferred_mode (struct ScreenInfo *screen_info, struct OutputInfo *output)
-{
- XRROutputInfo *output_info = output->info;
- Display *dpy;
- int screen;
- int m;
- XRRModeInfo *best;
- int bestDist;
-
- dpy = screen_info->dpy;
- screen = DefaultScreen (dpy);
- 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]);
- int dist;
-
- if (m < output_info->npreferred)
- dist = 0;
- else if (output_info->mm_height)
- dist = (1000 * DisplayHeight(dpy, screen) / DisplayHeightMM(dpy, screen) -
- 1000 * mode_info->height / output_info->mm_height);
- else
- dist = DisplayHeight(dpy, screen) - mode_info->height;
-
- if (dist < 0) dist = -dist;
- if (!best || dist < bestDist) {
- best = mode_info;
- bestDist = dist;
- }
- }
- return best;
-}
-
-int main_low_apply (struct ScreenInfo *screen_info)
-{
- int i;
- struct CrtcInfo *crtc_info;
-
- /* set_positions (screen_info); */
-
- if (!set_screen_size (screen_info)) {
- printf("Screen Size FAILURE\n\r");
- return 0;
- }
-
- for (i = 0; i < screen_info->n_crtc; i++) {
- 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);
-
- if (crtc_info->mode == None) {
- continue;
- }
-
- 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);
-
- 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]);
- }
- }
-
- 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);
- if (RRSetConfigSuccess != s) {
- fprintf (stderr, "crtc apply error\n");
- }
- }
-
- return 1;
-}
-
-void output_auto (struct ScreenInfo *screen_info, struct OutputInfo *output_info)
-{
- XRRModeInfo *mode_info;
- RRMode mode_id;
- struct CrtcInfo *crtc_info;
- XRROutputInfo *probe_output_info;
-
- if (RR_Disconnected == output_info->info->connection) {
- XRRScreenResources *cur_res;
-
- cur_res = XRRGetScreenResources (screen_info->dpy, screen_info->window);
- 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);
- }
- }
-
- mode_info = preferred_mode (screen_info, output_info);
- if (!mode_info) {
- return;
- }
- mode_id = mode_info->id;
-
- crtc_info = output_info->cur_crtc;
- if (crtc_info) {
- crtc_info->cur_mode_id = mode_id;
- } else {
- crtc_info = auto_find_crtc (screen_info, output_info);
- if (!crtc_info) {
-#if RANDR_GUI_DEBUG
- fprintf (stderr, "Can not find usable CRTC\n");
-#endif
- return;
- } else {
- screen_info->cur_output->cur_crtc = crtc_info;
- screen_info->cur_crtc = crtc_info;
- screen_info->cur_crtc->cur_noutput++;
- fprintf (stderr, "n output: %d\n", screen_info->cur_crtc->cur_noutput);
- screen_info->cur_crtc->cur_mode_id = mode_id;
- screen_info->cur_crtc->changed = 1;
- }
- }
-
-}
-
-void output_off (struct ScreenInfo *screen_info, struct OutputInfo *output)
-{
- if (output->cur_crtc) {
- output->cur_crtc->cur_noutput--;
- }
- output->cur_crtc = NULL;
- screen_info->cur_crtc = NULL;
- output->off_set = 1;
-}