git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1119942 283d02a7-25f6-0310-bc7c-ecb5cbfe19dav3.5.13-sru
parent
0a9caa3b37
commit
42980db88e
@ -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;
|
|
||||||
}
|
|
@ -1,102 +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 <X11/Xlib.h>
|
|
||||||
#include <X11/extensions/Xrandr.h>
|
|
||||||
|
|
||||||
struct ScreenInfo;
|
|
||||||
|
|
||||||
struct CrtcInfo {
|
|
||||||
RRCrtc id;
|
|
||||||
XRRCrtcInfo *info;
|
|
||||||
int cur_x;
|
|
||||||
int cur_y;
|
|
||||||
RRMode cur_mode_id;
|
|
||||||
Rotation cur_rotation;
|
|
||||||
Rotation rotations;
|
|
||||||
int cur_noutput;
|
|
||||||
|
|
||||||
int changed;
|
|
||||||
|
|
||||||
struct ScreenInfo *screen_info;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct OutputInfo {
|
|
||||||
RROutput id;
|
|
||||||
XRROutputInfo *info;
|
|
||||||
struct CrtcInfo *cur_crtc;
|
|
||||||
|
|
||||||
int auto_set;
|
|
||||||
int off_set;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ScreenInfo {
|
|
||||||
Display *dpy;
|
|
||||||
Window window;
|
|
||||||
XRRScreenResources *res;
|
|
||||||
int min_width, min_height;
|
|
||||||
int max_width, max_height;
|
|
||||||
int cur_width;
|
|
||||||
int cur_height;
|
|
||||||
int cur_mmWidth;
|
|
||||||
int cur_mmHeight;
|
|
||||||
|
|
||||||
int n_output;
|
|
||||||
int n_crtc;
|
|
||||||
struct OutputInfo **outputs;
|
|
||||||
struct CrtcInfo **crtcs;
|
|
||||||
|
|
||||||
int clone;
|
|
||||||
struct CrtcInfo *primary_crtc;
|
|
||||||
|
|
||||||
struct CrtcInfo *cur_crtc;
|
|
||||||
struct OutputInfo *cur_output;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct ScreenInfo *screen_info;
|
|
||||||
extern const uint big_pixbuf[], small_pixbuf[];
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
void free_screen_info (struct ScreenInfo *screen_info);
|
|
||||||
|
|
||||||
struct ScreenInfo* read_screen_info (Display *);
|
|
||||||
|
|
||||||
int set_screen_size (struct ScreenInfo *screen_info);
|
|
||||||
void output_auto (struct ScreenInfo *screen_info, struct OutputInfo *output_info);
|
|
||||||
void output_off (struct ScreenInfo *screen_info, struct OutputInfo *output);
|
|
||||||
struct CrtcInfo* auto_find_crtc (struct ScreenInfo *screen_info, struct OutputInfo *output_info);
|
|
||||||
|
|
||||||
XRRModeInfo *find_mode_by_xid (struct ScreenInfo *screen_info, RRMode mode_id);
|
|
||||||
int mode_height (XRRModeInfo *mode_info, Rotation rotation);
|
|
||||||
int mode_width (XRRModeInfo *mode_info, Rotation rotation);
|
|
||||||
int get_width_by_output_id (struct ScreenInfo *screen_info, RROutput output_id);
|
|
||||||
int get_height_by_output_id (struct ScreenInfo *screen_info, RROutput output_id);
|
|
||||||
char *get_output_name (struct ScreenInfo *screen_info, RROutput id);
|
|
||||||
Status crtc_apply (struct CrtcInfo *crtc_info);
|
|
||||||
Status crtc_disable (struct CrtcInfo *crtc);
|
|
||||||
int main_low_apply (struct ScreenInfo *screen_info);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,703 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2002,2003 Hamish Rodda <rodda@kde.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "randr.h"
|
|
||||||
|
|
||||||
#include <qtimer.h>
|
|
||||||
|
|
||||||
#include <kdebug.h>
|
|
||||||
#include <klocale.h>
|
|
||||||
#include <kglobal.h>
|
|
||||||
#include <kapplication.h>
|
|
||||||
#include <kiconloader.h>
|
|
||||||
#include <dcopclient.h>
|
|
||||||
#include <kipc.h>
|
|
||||||
#include <kactivelabel.h>
|
|
||||||
|
|
||||||
#include "ktimerdialog.h"
|
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#define INT8 _X11INT8
|
|
||||||
#define INT32 _X11INT32
|
|
||||||
#include <X11/Xproto.h>
|
|
||||||
#undef INT8
|
|
||||||
#undef INT32
|
|
||||||
#include <X11/extensions/Xrandr.h>
|
|
||||||
|
|
||||||
class RandRScreenPrivate
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RandRScreenPrivate() : config(0L) {};
|
|
||||||
~RandRScreenPrivate()
|
|
||||||
{
|
|
||||||
if (config)
|
|
||||||
XRRFreeScreenConfigInfo(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
XRRScreenConfiguration* config;
|
|
||||||
};
|
|
||||||
|
|
||||||
RandRScreen::RandRScreen(int screenIndex)
|
|
||||||
: d(new RandRScreenPrivate())
|
|
||||||
, m_screen(screenIndex)
|
|
||||||
, m_shownDialog(NULL)
|
|
||||||
{
|
|
||||||
loadSettings();
|
|
||||||
setOriginal();
|
|
||||||
}
|
|
||||||
|
|
||||||
RandRScreen::~RandRScreen()
|
|
||||||
{
|
|
||||||
delete d;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RandRScreen::loadSettings()
|
|
||||||
{
|
|
||||||
if (d->config)
|
|
||||||
XRRFreeScreenConfigInfo(d->config);
|
|
||||||
|
|
||||||
d->config = XRRGetScreenInfo(qt_xdisplay(), RootWindow(qt_xdisplay(), m_screen));
|
|
||||||
Q_ASSERT(d->config);
|
|
||||||
|
|
||||||
Rotation rotation;
|
|
||||||
m_currentSize = m_proposedSize = XRRConfigCurrentConfiguration(d->config, &rotation);
|
|
||||||
m_currentRotation = m_proposedRotation = rotation;
|
|
||||||
|
|
||||||
m_pixelSizes.clear();
|
|
||||||
m_mmSizes.clear();
|
|
||||||
int numSizes;
|
|
||||||
XRRScreenSize* sizes = XRRSizes(qt_xdisplay(), m_screen, &numSizes);
|
|
||||||
for (int i = 0; i < numSizes; i++) {
|
|
||||||
m_pixelSizes.append(QSize(sizes[i].width, sizes[i].height));
|
|
||||||
m_mmSizes.append(QSize(sizes[i].mwidth, sizes[i].mheight));
|
|
||||||
}
|
|
||||||
|
|
||||||
m_rotations = XRRRotations(qt_xdisplay(), m_screen, &rotation);
|
|
||||||
|
|
||||||
m_currentRefreshRate = m_proposedRefreshRate = refreshRateHzToIndex(m_currentSize, XRRConfigCurrentRate(d->config));
|
|
||||||
}
|
|
||||||
|
|
||||||
void RandRScreen::setOriginal()
|
|
||||||
{
|
|
||||||
m_originalSize = m_currentSize;
|
|
||||||
m_originalRotation = m_currentRotation;
|
|
||||||
m_originalRefreshRate = m_currentRefreshRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RandRScreen::applyProposed()
|
|
||||||
{
|
|
||||||
//kdDebug() << k_funcinfo << " size " << (SizeID)proposedSize() << ", rotation " << proposedRotation() << ", refresh " << refreshRateIndexToHz(proposedSize(), proposedRefreshRate()) << endl;
|
|
||||||
|
|
||||||
Status status;
|
|
||||||
|
|
||||||
if (proposedRefreshRate() < 0)
|
|
||||||
status = XRRSetScreenConfig(qt_xdisplay(), d->config, DefaultRootWindow(qt_xdisplay()), (SizeID)proposedSize(), (Rotation)proposedRotation(), CurrentTime);
|
|
||||||
else {
|
|
||||||
if( refreshRateIndexToHz(proposedSize(), proposedRefreshRate()) <= 0 ) {
|
|
||||||
m_proposedRefreshRate = 0;
|
|
||||||
}
|
|
||||||
status = XRRSetScreenConfigAndRate(qt_xdisplay(), d->config, DefaultRootWindow(qt_xdisplay()), (SizeID)proposedSize(), (Rotation)proposedRotation(), refreshRateIndexToHz(proposedSize(), proposedRefreshRate()), CurrentTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
//kdDebug() << "New size: " << WidthOfScreen(ScreenOfDisplay(QPaintDevice::x11AppDisplay(), screen)) << ", " << HeightOfScreen(ScreenOfDisplay(QPaintDevice::x11AppDisplay(), screen)) << endl;
|
|
||||||
|
|
||||||
if (status == RRSetConfigSuccess) {
|
|
||||||
m_currentSize = m_proposedSize;
|
|
||||||
m_currentRotation = m_proposedRotation;
|
|
||||||
m_currentRefreshRate = m_proposedRefreshRate;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RandRScreen::applyProposedAndConfirm()
|
|
||||||
{
|
|
||||||
if (proposedChanged()) {
|
|
||||||
setOriginal();
|
|
||||||
|
|
||||||
if (applyProposed()) {
|
|
||||||
if (!confirm()) {
|
|
||||||
proposeOriginal();
|
|
||||||
applyProposed();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RandRScreen::confirm()
|
|
||||||
{
|
|
||||||
// uncomment the line below and edit out the KTimerDialog stuff to get
|
|
||||||
// a version which works on today's kdelibs (no accept dialog is presented)
|
|
||||||
|
|
||||||
// FIXME remember to put the dialog on the right screen
|
|
||||||
|
|
||||||
KTimerDialog acceptDialog ( 15000, KTimerDialog::CountDown,
|
|
||||||
KApplication::kApplication()->mainWidget(),
|
|
||||||
"mainKTimerDialog",
|
|
||||||
true,
|
|
||||||
i18n("Confirm Display Setting Change"),
|
|
||||||
KTimerDialog::Ok|KTimerDialog::Cancel,
|
|
||||||
KTimerDialog::Cancel);
|
|
||||||
|
|
||||||
acceptDialog.setButtonOK(KGuiItem(i18n("&Accept Configuration"), "button_ok"));
|
|
||||||
acceptDialog.setButtonCancel(KGuiItem(i18n("&Return to Previous Configuration"), "button_cancel"));
|
|
||||||
|
|
||||||
KActiveLabel *label = new KActiveLabel(i18n("Your screen orientation, size and refresh rate "
|
|
||||||
"have been changed to the requested settings. Please indicate whether you wish to "
|
|
||||||
"keep this configuration. In 15 seconds the display will revert to your previous "
|
|
||||||
"settings."), &acceptDialog, "userSpecifiedLabel");
|
|
||||||
|
|
||||||
acceptDialog.setMainWidget(label);
|
|
||||||
|
|
||||||
KDialog::centerOnScreen(&acceptDialog, m_screen);
|
|
||||||
|
|
||||||
m_shownDialog = &acceptDialog;
|
|
||||||
connect( m_shownDialog, SIGNAL( destroyed()), this, SLOT( shownDialogDestroyed()));
|
|
||||||
connect( kapp->desktop(), SIGNAL( resized(int)), this, SLOT( desktopResized()));
|
|
||||||
|
|
||||||
return acceptDialog.exec();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RandRScreen::shownDialogDestroyed()
|
|
||||||
{
|
|
||||||
m_shownDialog = NULL;
|
|
||||||
disconnect( kapp->desktop(), SIGNAL( resized(int)), this, SLOT( desktopResized()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void RandRScreen::desktopResized()
|
|
||||||
{
|
|
||||||
if( m_shownDialog != NULL )
|
|
||||||
KDialog::centerOnScreen(m_shownDialog, m_screen);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString RandRScreen::changedMessage() const
|
|
||||||
{
|
|
||||||
if (currentRefreshRate() == -1)
|
|
||||||
return i18n("New configuration:\nResolution: %1 x %2\nOrientation: %3")
|
|
||||||
.arg(currentPixelWidth())
|
|
||||||
.arg(currentPixelHeight())
|
|
||||||
.arg(currentRotationDescription());
|
|
||||||
else
|
|
||||||
return i18n("New configuration:\nResolution: %1 x %2\nOrientation: %3\nRefresh rate: %4")
|
|
||||||
.arg(currentPixelWidth())
|
|
||||||
.arg(currentPixelHeight())
|
|
||||||
.arg(currentRotationDescription())
|
|
||||||
.arg(currentRefreshRateDescription());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RandRScreen::changedFromOriginal() const
|
|
||||||
{
|
|
||||||
return m_currentSize != m_originalSize || m_currentRotation != m_originalRotation || m_currentRefreshRate != m_originalRefreshRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RandRScreen::proposeOriginal()
|
|
||||||
{
|
|
||||||
m_proposedSize = m_originalSize;
|
|
||||||
m_proposedRotation = m_originalRotation;
|
|
||||||
m_proposedRefreshRate = m_originalRefreshRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RandRScreen::proposedChanged() const
|
|
||||||
{
|
|
||||||
return m_currentSize != m_proposedSize || m_currentRotation != m_proposedRotation || m_currentRefreshRate != m_proposedRefreshRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString RandRScreen::rotationName(int rotation, bool pastTense, bool capitalised)
|
|
||||||
{
|
|
||||||
if (!pastTense)
|
|
||||||
switch (rotation) {
|
|
||||||
case RR_Rotate_0:
|
|
||||||
return i18n("Normal");
|
|
||||||
case RR_Rotate_90:
|
|
||||||
return i18n("Left (90 degrees)");
|
|
||||||
case RR_Rotate_180:
|
|
||||||
return i18n("Upside-down (180 degrees)");
|
|
||||||
case RR_Rotate_270:
|
|
||||||
return i18n("Right (270 degrees)");
|
|
||||||
case RR_Reflect_X:
|
|
||||||
return i18n("Mirror horizontally");
|
|
||||||
case RR_Reflect_Y:
|
|
||||||
return i18n("Mirror vertically");
|
|
||||||
default:
|
|
||||||
return i18n("Unknown orientation");
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (rotation) {
|
|
||||||
case RR_Rotate_0:
|
|
||||||
return i18n("Normal");
|
|
||||||
case RR_Rotate_90:
|
|
||||||
return i18n("Rotated 90 degrees counterclockwise");
|
|
||||||
case RR_Rotate_180:
|
|
||||||
return i18n("Rotated 180 degrees counterclockwise");
|
|
||||||
case RR_Rotate_270:
|
|
||||||
return i18n("Rotated 270 degrees counterclockwise");
|
|
||||||
default:
|
|
||||||
if (rotation & RR_Reflect_X)
|
|
||||||
if (rotation & RR_Reflect_Y)
|
|
||||||
if (capitalised)
|
|
||||||
return i18n("Mirrored horizontally and vertically");
|
|
||||||
else
|
|
||||||
return i18n("mirrored horizontally and vertically");
|
|
||||||
else
|
|
||||||
if (capitalised)
|
|
||||||
return i18n("Mirrored horizontally");
|
|
||||||
else
|
|
||||||
return i18n("mirrored horizontally");
|
|
||||||
else if (rotation & RR_Reflect_Y)
|
|
||||||
if (capitalised)
|
|
||||||
return i18n("Mirrored vertically");
|
|
||||||
else
|
|
||||||
return i18n("mirrored vertically");
|
|
||||||
else
|
|
||||||
if (capitalised)
|
|
||||||
return i18n("Unknown orientation");
|
|
||||||
else
|
|
||||||
return i18n("unknown orientation");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QPixmap RandRScreen::rotationIcon(int rotation) const
|
|
||||||
{
|
|
||||||
// Adjust icons for current screen orientation
|
|
||||||
if (!(m_currentRotation & RR_Rotate_0) && rotation & (RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270)) {
|
|
||||||
int currentAngle = m_currentRotation & (RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
|
|
||||||
switch (currentAngle) {
|
|
||||||
case RR_Rotate_90:
|
|
||||||
rotation <<= 3;
|
|
||||||
break;
|
|
||||||
case RR_Rotate_180:
|
|
||||||
rotation <<= 2;
|
|
||||||
break;
|
|
||||||
case RR_Rotate_270:
|
|
||||||
rotation <<= 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fix overflow
|
|
||||||
if (rotation > RR_Rotate_270) {
|
|
||||||
rotation >>= 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (rotation) {
|
|
||||||
case RR_Rotate_0:
|
|
||||||
return SmallIcon("up");
|
|
||||||
case RR_Rotate_90:
|
|
||||||
return SmallIcon("back");
|
|
||||||
case RR_Rotate_180:
|
|
||||||
return SmallIcon("down");
|
|
||||||
case RR_Rotate_270:
|
|
||||||
return SmallIcon("forward");
|
|
||||||
case RR_Reflect_X:
|
|
||||||
case RR_Reflect_Y:
|
|
||||||
default:
|
|
||||||
return SmallIcon("stop");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString RandRScreen::currentRotationDescription() const
|
|
||||||
{
|
|
||||||
QString ret = rotationName(m_currentRotation & RotateMask);
|
|
||||||
|
|
||||||
if (m_currentRotation != m_currentRotation & RotateMask)
|
|
||||||
if (m_currentRotation & RR_Rotate_0)
|
|
||||||
ret = rotationName(m_currentRotation & (RR_Reflect_X + RR_Reflect_X), true, true);
|
|
||||||
else
|
|
||||||
ret += ", " + rotationName(m_currentRotation & (RR_Reflect_X + RR_Reflect_X), true, false);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRScreen::rotationIndexToDegree(int rotation) const
|
|
||||||
{
|
|
||||||
switch (rotation & RotateMask) {
|
|
||||||
case RR_Rotate_90:
|
|
||||||
return 90;
|
|
||||||
|
|
||||||
case RR_Rotate_180:
|
|
||||||
return 180;
|
|
||||||
|
|
||||||
case RR_Rotate_270:
|
|
||||||
return 270;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRScreen::rotationDegreeToIndex(int degree) const
|
|
||||||
{
|
|
||||||
switch (degree) {
|
|
||||||
case 90:
|
|
||||||
return RR_Rotate_90;
|
|
||||||
|
|
||||||
case 180:
|
|
||||||
return RR_Rotate_180;
|
|
||||||
|
|
||||||
case 270:
|
|
||||||
return RR_Rotate_270;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return RR_Rotate_0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRScreen::currentPixelWidth() const
|
|
||||||
{
|
|
||||||
return m_pixelSizes[m_currentSize].width();
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRScreen::currentPixelHeight() const
|
|
||||||
{
|
|
||||||
return m_pixelSizes[m_currentSize].height();
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRScreen::currentMMWidth() const
|
|
||||||
{
|
|
||||||
return m_pixelSizes[m_currentSize].width();
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRScreen::currentMMHeight() const
|
|
||||||
{
|
|
||||||
return m_pixelSizes[m_currentSize].height();
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList RandRScreen::refreshRates(int size) const
|
|
||||||
{
|
|
||||||
int nrates;
|
|
||||||
short* rates = XRRRates(qt_xdisplay(), m_screen, (SizeID)size, &nrates);
|
|
||||||
|
|
||||||
QStringList ret;
|
|
||||||
for (int i = 0; i < nrates; i++)
|
|
||||||
ret << refreshRateDirectDescription(rates[i]);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString RandRScreen::refreshRateDirectDescription(int rate) const
|
|
||||||
{
|
|
||||||
return i18n("Refresh rate in Hertz (Hz)", "%1 Hz").arg(rate);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString RandRScreen::refreshRateIndirectDescription(int size, int index) const
|
|
||||||
{
|
|
||||||
return i18n("Refresh rate in Hertz (Hz)", "%1 Hz").arg(refreshRateIndexToHz(size, index));
|
|
||||||
}
|
|
||||||
|
|
||||||
QString RandRScreen::refreshRateDescription(int size, int index) const
|
|
||||||
{
|
|
||||||
return refreshRates(size)[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RandRScreen::proposeRefreshRate(int index)
|
|
||||||
{
|
|
||||||
if (index >= 0 && (int)refreshRates(proposedSize()).count() > index) {
|
|
||||||
m_proposedRefreshRate = index;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRScreen::currentRefreshRate() const
|
|
||||||
{
|
|
||||||
return m_currentRefreshRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString RandRScreen::currentRefreshRateDescription() const
|
|
||||||
{
|
|
||||||
return refreshRateIndirectDescription(m_currentSize, m_currentRefreshRate);
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRScreen::proposedRefreshRate() const
|
|
||||||
{
|
|
||||||
return m_proposedRefreshRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRScreen::refreshRateHzToIndex(int size, int hz) const
|
|
||||||
{
|
|
||||||
int nrates;
|
|
||||||
short* rates = XRRRates(qt_xdisplay(), m_screen, (SizeID)size, &nrates);
|
|
||||||
|
|
||||||
for (int i = 0; i < nrates; i++)
|
|
||||||
if (hz == rates[i])
|
|
||||||
return i;
|
|
||||||
|
|
||||||
if (nrates != 0)
|
|
||||||
// Wrong input Hz!
|
|
||||||
Q_ASSERT(false);
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRScreen::refreshRateIndexToHz(int size, int index) const
|
|
||||||
{
|
|
||||||
int nrates;
|
|
||||||
short* rates = XRRRates(qt_xdisplay(), m_screen, (SizeID)size, &nrates);
|
|
||||||
|
|
||||||
if (nrates == 0 || index < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Wrong input Hz!
|
|
||||||
if(index >= nrates)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return rates[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRScreen::numSizes() const
|
|
||||||
{
|
|
||||||
return m_pixelSizes.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
const QSize& RandRScreen::pixelSize(int index) const
|
|
||||||
{
|
|
||||||
return m_pixelSizes[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
const QSize& RandRScreen::mmSize(int index) const
|
|
||||||
{
|
|
||||||
return m_mmSizes[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRScreen::sizeIndex(QSize pixelSize) const
|
|
||||||
{
|
|
||||||
for (uint i = 0; i < m_pixelSizes.count(); i++)
|
|
||||||
if (m_pixelSizes[i] == pixelSize)
|
|
||||||
return i;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRScreen::rotations() const
|
|
||||||
{
|
|
||||||
return m_rotations;
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRScreen::currentRotation() const
|
|
||||||
{
|
|
||||||
return m_currentRotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRScreen::currentSize() const
|
|
||||||
{
|
|
||||||
return m_currentSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRScreen::proposedRotation() const
|
|
||||||
{
|
|
||||||
return m_proposedRotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RandRScreen::proposeRotation(int newRotation)
|
|
||||||
{
|
|
||||||
m_proposedRotation = newRotation & OrientationMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRScreen::proposedSize() const
|
|
||||||
{
|
|
||||||
return m_proposedSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RandRScreen::proposeSize(int newSize)
|
|
||||||
{
|
|
||||||
if ((int)m_pixelSizes.count() > newSize) {
|
|
||||||
m_proposedSize = newSize;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RandRScreen::load(KConfig& config)
|
|
||||||
{
|
|
||||||
config.setGroup(QString("Screen%1").arg(m_screen));
|
|
||||||
|
|
||||||
if (proposeSize(sizeIndex(QSize(config.readNumEntry("width", currentPixelWidth()), config.readNumEntry("height", currentPixelHeight())))))
|
|
||||||
proposeRefreshRate(refreshRateHzToIndex(proposedSize(), config.readNumEntry("refresh", currentRefreshRate())));
|
|
||||||
|
|
||||||
proposeRotation(rotationDegreeToIndex(config.readNumEntry("rotation", 0)) + (config.readBoolEntry("reflectX") ? ReflectX : 0) + (config.readBoolEntry("reflectY") ? ReflectY : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
void RandRScreen::save(KConfig& config) const
|
|
||||||
{
|
|
||||||
config.setGroup(QString("Screen%1").arg(m_screen));
|
|
||||||
config.writeEntry("width", currentPixelWidth());
|
|
||||||
config.writeEntry("height", currentPixelHeight());
|
|
||||||
config.writeEntry("refresh", refreshRateIndexToHz(currentSize(), currentRefreshRate()));
|
|
||||||
config.writeEntry("rotation", rotationIndexToDegree(currentRotation()));
|
|
||||||
config.writeEntry("reflectX", (bool)(currentRotation() & ReflectMask) == ReflectX);
|
|
||||||
config.writeEntry("reflectY", (bool)(currentRotation() & ReflectMask) == ReflectY);
|
|
||||||
}
|
|
||||||
|
|
||||||
RandRDisplay::RandRDisplay()
|
|
||||||
: m_valid(true)
|
|
||||||
{
|
|
||||||
// Check extension
|
|
||||||
Status s = XRRQueryExtension(qt_xdisplay(), &m_eventBase, &m_errorBase);
|
|
||||||
if (!s) {
|
|
||||||
m_errorCode = QString("%1, base %1").arg(s).arg(m_errorBase);
|
|
||||||
m_valid = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int major_version, minor_version;
|
|
||||||
XRRQueryVersion(qt_xdisplay(), &major_version, &minor_version);
|
|
||||||
|
|
||||||
m_version = QString("X Resize and Rotate extension version %1.%1").arg(major_version).arg(minor_version);
|
|
||||||
|
|
||||||
m_numScreens = ScreenCount(qt_xdisplay());
|
|
||||||
|
|
||||||
// This assumption is WRONG with Xinerama
|
|
||||||
// Q_ASSERT(QApplication::desktop()->numScreens() == ScreenCount(qt_xdisplay()));
|
|
||||||
|
|
||||||
m_screens.setAutoDelete(true);
|
|
||||||
for (int i = 0; i < m_numScreens; i++) {
|
|
||||||
m_screens.append(new RandRScreen(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
setCurrentScreen(QApplication::desktop()->primaryScreen());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RandRDisplay::isValid() const
|
|
||||||
{
|
|
||||||
return m_valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString& RandRDisplay::errorCode() const
|
|
||||||
{
|
|
||||||
return m_errorCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRDisplay::eventBase() const
|
|
||||||
{
|
|
||||||
return m_eventBase;
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRDisplay::screenChangeNotifyEvent() const
|
|
||||||
{
|
|
||||||
return m_eventBase + RRScreenChangeNotify;
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRDisplay::errorBase() const
|
|
||||||
{
|
|
||||||
return m_errorBase;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString& RandRDisplay::version() const
|
|
||||||
{
|
|
||||||
return m_version;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RandRDisplay::setCurrentScreen(int index)
|
|
||||||
{
|
|
||||||
m_currentScreenIndex = index;
|
|
||||||
m_currentScreen = m_screens.at(m_currentScreenIndex);
|
|
||||||
Q_ASSERT(m_currentScreen);
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRDisplay::screenIndexOfWidget(QWidget* widget)
|
|
||||||
{
|
|
||||||
int ret = QApplication::desktop()->screenNumber(widget);
|
|
||||||
return ret != -1 ? ret : QApplication::desktop()->primaryScreen();
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRDisplay::currentScreenIndex() const
|
|
||||||
{
|
|
||||||
return m_currentScreenIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RandRDisplay::refresh()
|
|
||||||
{
|
|
||||||
for (RandRScreen* s = m_screens.first(); s; s = m_screens.next())
|
|
||||||
s->loadSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRDisplay::numScreens() const
|
|
||||||
{
|
|
||||||
return m_numScreens;
|
|
||||||
}
|
|
||||||
|
|
||||||
RandRScreen* RandRDisplay::screen(int index)
|
|
||||||
{
|
|
||||||
return m_screens.at(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
RandRScreen* RandRDisplay::currentScreen()
|
|
||||||
{
|
|
||||||
return m_currentScreen;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RandRDisplay::loadDisplay(KConfig& config, bool loadScreens)
|
|
||||||
{
|
|
||||||
if (loadScreens)
|
|
||||||
for (RandRScreen* s = m_screens.first(); s; s = m_screens.next())
|
|
||||||
s->load(config);
|
|
||||||
|
|
||||||
return applyOnStartup(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RandRDisplay::applyOnStartup(KConfig& config)
|
|
||||||
{
|
|
||||||
config.setGroup("Display");
|
|
||||||
return config.readBoolEntry("ApplyOnStartup", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RandRDisplay::syncTrayApp(KConfig& config)
|
|
||||||
{
|
|
||||||
config.setGroup("Display");
|
|
||||||
return config.readBoolEntry("SyncTrayApp", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RandRDisplay::saveDisplay(KConfig& config, bool applyOnStartup, bool syncTrayApp)
|
|
||||||
{
|
|
||||||
Q_ASSERT(!config.isReadOnly());
|
|
||||||
|
|
||||||
config.setGroup("Display");
|
|
||||||
config.writeEntry("ApplyOnStartup", applyOnStartup);
|
|
||||||
config.writeEntry("SyncTrayApp", syncTrayApp);
|
|
||||||
|
|
||||||
for (RandRScreen* s = m_screens.first(); s; s = m_screens.next())
|
|
||||||
s->save(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RandRDisplay::applyProposed(bool confirm)
|
|
||||||
{
|
|
||||||
for (int screenIndex = 0; screenIndex < numScreens(); screenIndex++) {
|
|
||||||
if (screen(screenIndex)->proposedChanged()) {
|
|
||||||
if (confirm)
|
|
||||||
screen(screenIndex)->applyProposedAndConfirm();
|
|
||||||
else
|
|
||||||
screen(screenIndex)->applyProposed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int RandRScreen::pixelCount( int index ) const
|
|
||||||
{
|
|
||||||
QSize sz = pixelSize(index);
|
|
||||||
return sz.width() * sz.height();
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "randr.moc"
|
|
@ -1,235 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2002,2003 Hamish Rodda <rodda@kde.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __RANDR_H__
|
|
||||||
#define __RANDR_H__
|
|
||||||
|
|
||||||
#include <qobject.h>
|
|
||||||
#include <qstringlist.h>
|
|
||||||
#include <qptrlist.h>
|
|
||||||
|
|
||||||
#include <kcmodule.h>
|
|
||||||
#include <kconfig.h>
|
|
||||||
|
|
||||||
class KTimerDialog;
|
|
||||||
class RandRScreenPrivate;
|
|
||||||
|
|
||||||
class RandRScreen : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum orientations {
|
|
||||||
Rotate0 = 0x1,
|
|
||||||
Rotate90 = 0x2,
|
|
||||||
Rotate180 = 0x4,
|
|
||||||
Rotate270 = 0x8,
|
|
||||||
RotateMask = 15,
|
|
||||||
RotationCount = 4,
|
|
||||||
ReflectX = 0x10,
|
|
||||||
ReflectY = 0x20,
|
|
||||||
ReflectMask = 48,
|
|
||||||
OrientationMask = 63,
|
|
||||||
OrientationCount = 6
|
|
||||||
};
|
|
||||||
|
|
||||||
RandRScreen(int screenIndex);
|
|
||||||
~RandRScreen();
|
|
||||||
|
|
||||||
void loadSettings();
|
|
||||||
void setOriginal();
|
|
||||||
|
|
||||||
bool applyProposed();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns false if the user did not confirm in time, or cancelled, or the change failed
|
|
||||||
*/
|
|
||||||
bool applyProposedAndConfirm();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
bool confirm();
|
|
||||||
|
|
||||||
public:
|
|
||||||
QString changedMessage() const;
|
|
||||||
|
|
||||||
bool changedFromOriginal() const;
|
|
||||||
void proposeOriginal();
|
|
||||||
|
|
||||||
bool proposedChanged() const;
|
|
||||||
|
|
||||||
static QString rotationName(int rotation, bool pastTense = false, bool capitalised = true);
|
|
||||||
QPixmap rotationIcon(int rotation) const;
|
|
||||||
QString currentRotationDescription() const;
|
|
||||||
|
|
||||||
int rotationIndexToDegree(int rotation) const;
|
|
||||||
int rotationDegreeToIndex(int degree) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Refresh rate functions.
|
|
||||||
*/
|
|
||||||
QStringList refreshRates(int size) const;
|
|
||||||
|
|
||||||
QString refreshRateDirectDescription(int rate) const;
|
|
||||||
QString refreshRateIndirectDescription(int size, int index) const;
|
|
||||||
QString refreshRateDescription(int size, int index) const;
|
|
||||||
|
|
||||||
int currentRefreshRate() const;
|
|
||||||
QString currentRefreshRateDescription() const;
|
|
||||||
|
|
||||||
// Refresh rate hz <==> index conversion
|
|
||||||
int refreshRateHzToIndex(int size, int hz) const;
|
|
||||||
int refreshRateIndexToHz(int size, int index) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Screen size functions.
|
|
||||||
*/
|
|
||||||
int numSizes() const;
|
|
||||||
const QSize& pixelSize(int index) const;
|
|
||||||
const QSize& mmSize(int index) const;
|
|
||||||
int pixelCount(int index) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the index of a screen size with a specified pixel size.
|
|
||||||
*
|
|
||||||
* @param pixelSize dimensions of the screen in pixels
|
|
||||||
* @returns the index of the requested screen size
|
|
||||||
*/
|
|
||||||
int sizeIndex(QSize pixelSize) const;
|
|
||||||
|
|
||||||
int rotations() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Current setting functions.
|
|
||||||
*/
|
|
||||||
int currentPixelWidth() const;
|
|
||||||
int currentPixelHeight() const;
|
|
||||||
int currentMMWidth() const;
|
|
||||||
int currentMMHeight() const;
|
|
||||||
|
|
||||||
int currentRotation() const;
|
|
||||||
int currentSize() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Proposed setting functions.
|
|
||||||
*/
|
|
||||||
int proposedSize() const;
|
|
||||||
bool proposeSize(int newSize);
|
|
||||||
|
|
||||||
int proposedRotation() const;
|
|
||||||
void proposeRotation(int newRotation);
|
|
||||||
|
|
||||||
int proposedRefreshRate() const;
|
|
||||||
/**
|
|
||||||
* Propose a refresh rate.
|
|
||||||
* Please note that you must propose the target size first for this to work.
|
|
||||||
*
|
|
||||||
* @param index the index of the refresh rate (not a refresh rate in hz!)
|
|
||||||
* @returns true if successful, false otherwise.
|
|
||||||
*/
|
|
||||||
bool proposeRefreshRate(int index);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuration functions.
|
|
||||||
*/
|
|
||||||
void load(KConfig& config);
|
|
||||||
void save(KConfig& config) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
RandRScreenPrivate* d;
|
|
||||||
|
|
||||||
int m_screen;
|
|
||||||
|
|
||||||
QValueList<QSize> m_pixelSizes;
|
|
||||||
QValueList<QSize> m_mmSizes;
|
|
||||||
int m_rotations;
|
|
||||||
|
|
||||||
int m_originalRotation;
|
|
||||||
int m_originalSize;
|
|
||||||
int m_originalRefreshRate;
|
|
||||||
|
|
||||||
int m_currentRotation;
|
|
||||||
int m_currentSize;
|
|
||||||
int m_currentRefreshRate;
|
|
||||||
|
|
||||||
int m_proposedRotation;
|
|
||||||
int m_proposedSize;
|
|
||||||
int m_proposedRefreshRate;
|
|
||||||
|
|
||||||
KTimerDialog* m_shownDialog;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void desktopResized();
|
|
||||||
void shownDialogDestroyed();
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef QPtrList<RandRScreen> ScreenList;
|
|
||||||
|
|
||||||
class RandRDisplay
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RandRDisplay();
|
|
||||||
|
|
||||||
bool isValid() const;
|
|
||||||
const QString& errorCode() const;
|
|
||||||
const QString& version() const;
|
|
||||||
|
|
||||||
int eventBase() const;
|
|
||||||
int screenChangeNotifyEvent() const;
|
|
||||||
int errorBase() const;
|
|
||||||
|
|
||||||
int screenIndexOfWidget(QWidget* widget);
|
|
||||||
|
|
||||||
int numScreens() const;
|
|
||||||
RandRScreen* screen(int index);
|
|
||||||
|
|
||||||
void setCurrentScreen(int index);
|
|
||||||
int currentScreenIndex() const;
|
|
||||||
RandRScreen* currentScreen();
|
|
||||||
|
|
||||||
void refresh();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads saved settings.
|
|
||||||
*
|
|
||||||
* @param config the KConfig object to load from
|
|
||||||
* @param loadScreens whether to call RandRScreen::load() for each screen
|
|
||||||
* @retuns true if the settings should be applied on KDE startup.
|
|
||||||
*/
|
|
||||||
bool loadDisplay(KConfig& config, bool loadScreens = true);
|
|
||||||
void saveDisplay(KConfig& config, bool applyOnStartup, bool syncTrayApp);
|
|
||||||
|
|
||||||
static bool applyOnStartup(KConfig& config);
|
|
||||||
static bool syncTrayApp(KConfig& config);
|
|
||||||
|
|
||||||
void applyProposed(bool confirm = true);
|
|
||||||
|
|
||||||
private:
|
|
||||||
int m_numScreens;
|
|
||||||
int m_currentScreenIndex;
|
|
||||||
RandRScreen* m_currentScreen;
|
|
||||||
ScreenList m_screens;
|
|
||||||
|
|
||||||
bool m_valid;
|
|
||||||
QString m_errorCode;
|
|
||||||
QString m_version;
|
|
||||||
|
|
||||||
int m_eventBase;
|
|
||||||
int m_errorBase;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
Loading…
Reference in new issue