dispswitch.c revision 649
6ae232055d4d8a97267517c5e50074c2c819941and * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc.
6ae232055d4d8a97267517c5e50074c2c819941and * Copyright © 2002 Hewlett Packard Company, Inc.
6ae232055d4d8a97267517c5e50074c2c819941and * Copyright © 2006 Intel Corporation
6ae232055d4d8a97267517c5e50074c2c819941and * Copyright © 2008 Sun Microsystems, Inc.
6ae232055d4d8a97267517c5e50074c2c819941and * Permission to use, copy, modify, distribute, and sell this software and its
6ae232055d4d8a97267517c5e50074c2c819941and * documentation for any purpose is hereby granted without fee, provided that
6ae232055d4d8a97267517c5e50074c2c819941and * the above copyright notice appear in all copies and that both that copyright
6ae232055d4d8a97267517c5e50074c2c819941and * notice and this permission notice appear in supporting documentation, and
6ae232055d4d8a97267517c5e50074c2c819941and * that the name of the copyright holders not be used in advertising or
6ae232055d4d8a97267517c5e50074c2c819941and * publicity pertaining to distribution of the software without specific,
6ae232055d4d8a97267517c5e50074c2c819941and * written prior permission. The copyright holders make no representations
6ae232055d4d8a97267517c5e50074c2c819941and * about the suitability of this software for any purpose. It is provided "as
6ae232055d4d8a97267517c5e50074c2c819941and * is" without express or implied warranty.
6ae232055d4d8a97267517c5e50074c2c819941and * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
6ae232055d4d8a97267517c5e50074c2c819941and * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
6ae232055d4d8a97267517c5e50074c2c819941and * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
6ae232055d4d8a97267517c5e50074c2c819941and * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
6ae232055d4d8a97267517c5e50074c2c819941and * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
6ae232055d4d8a97267517c5e50074c2c819941and * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
6ae232055d4d8a97267517c5e50074c2c819941and * OF THIS SOFTWARE.
6ae232055d4d8a97267517c5e50074c2c819941andstatic char *program_name;
6ae232055d4d8a97267517c5e50074c2c819941andstatic int screen;
6ae232055d4d8a97267517c5e50074c2c819941andstatic int had_error = 0;
6ae232055d4d8a97267517c5e50074c2c819941andstatic int init_x;
6ae232055d4d8a97267517c5e50074c2c819941andstatic int init_y;
6ae232055d4d8a97267517c5e50074c2c819941andstatic void
6ae232055d4d8a97267517c5e50074c2c819941and fprintf(stderr, " -display <display> or -d <display>\n");
6ae232055d4d8a97267517c5e50074c2c819941and /*NOTREACHED*/
6ae232055d4d8a97267517c5e50074c2c819941andstatic void
6ae232055d4d8a97267517c5e50074c2c819941and /*NOTREACHED*/
6ae232055d4d8a97267517c5e50074c2c819941and return (0);
6ae232055d4d8a97267517c5e50074c2c819941andtypedef enum _relation {
6ae232055d4d8a97267517c5e50074c2c819941andtypedef enum _changes {
6ae232055d4d8a97267517c5e50074c2c819941andtypedef enum _name_kind {
6ae232055d4d8a97267517c5e50074c2c819941andtypedef struct {
6ae232055d4d8a97267517c5e50074c2c819941and unsigned int mod;
4b3a8afbfcea8b265d179a122bf40dfedd1ce280takashistatic int start = 0;
6ae232055d4d8a97267517c5e50074c2c819941andstatic int ncon;
6ae232055d4d8a97267517c5e50074c2c819941and {"none", 0},
6ae232055d4d8a97267517c5e50074c2c819941and/* v refresh frequency in Hz */
6ae232055d4d8a97267517c5e50074c2c819941andstatic float
6ae232055d4d8a97267517c5e50074c2c819941and ((float) mode_info->hTotal * (float) mode_info->vTotal));
6ae232055d4d8a97267517c5e50074c2c819941andstatic void
6ae232055d4d8a97267517c5e50074c2c819941andstatic void
6ae232055d4d8a97267517c5e50074c2c819941andstatic void
6ae232055d4d8a97267517c5e50074c2c819941andstatic void
6ae232055d4d8a97267517c5e50074c2c819941andstatic void
6ae232055d4d8a97267517c5e50074c2c819941and if ((common & name_xid) && name->xid == output->output.xid)
6ae232055d4d8a97267517c5e50074c2c819941and if ((common & name_string) && !strcmp (name->string, output->output.string))
6ae232055d4d8a97267517c5e50074c2c819941and if ((common & name_index) && name->index == output->output.index)
6ae232055d4d8a97267517c5e50074c2c819941and for (c = 0; c < num_crtcs; c++)
6ae232055d4d8a97267517c5e50074c2c819941and if ((common & name_string) && !strcmp (name->string, crtc->crtc.string))
6ae232055d4d8a97267517c5e50074c2c819941and if ((common & name_index) && name->index == crtc->crtc.index)
6ae232055d4d8a97267517c5e50074c2c819941andstatic void
6ae232055d4d8a97267517c5e50074c2c819941andset_output_info (output_t *output, RROutput xid, XRROutputInfo *output_info)
6ae232055d4d8a97267517c5e50074c2c819941and /* sanity check output info */
6ae232055d4d8a97267517c5e50074c2c819941and if (output_info->connection != RR_Disconnected && !output_info->nmode)
6ae232055d4d8a97267517c5e50074c2c819941and fatal ("Output %s is not disconnected but has no modes\n",
6ae232055d4d8a97267517c5e50074c2c819941and /* set output name and info */
6ae232055d4d8a97267517c5e50074c2c819941and /* set position */
6ae232055d4d8a97267517c5e50074c2c819941and /* set rotation */
6ae232055d4d8a97267517c5e50074c2c819941andstatic void
6ae232055d4d8a97267517c5e50074c2c819941and XRRCrtcInfo *crtc_info = XRRGetCrtcInfo (dpy, res, res->crtcs[c]);
6ae232055d4d8a97267517c5e50074c2c819941and if (!crtc_info) fatal ("could not get crtc 0x%x information", res->crtcs[c]);
6ae232055d4d8a97267517c5e50074c2c819941andstatic void
6ae232055d4d8a97267517c5e50074c2c819941and crtc->outputs = realloc (crtc->outputs, (crtc->noutput + 1) * sizeof (output_t *));
6ae232055d4d8a97267517c5e50074c2c819941andstatic void
6ae232055d4d8a97267517c5e50074c2c819941and for (i = 0; i < ncon; i++) {
6ae232055d4d8a97267517c5e50074c2c819941andstatic void
6ae232055d4d8a97267517c5e50074c2c819941and if ((output->crtc_info) && (output->crtc_info->outputs)) {
6ae232055d4d8a97267517c5e50074c2c819941and fprintf (stderr, "crtc %d (%x) : disable\n", crtc->crtc.index, crtc->crtc.xid);
6ae232055d4d8a97267517c5e50074c2c819941and return XRRSetCrtcConfig (dpy, res, crtc->crtc.xid, CurrentTime,
6ae232055d4d8a97267517c5e50074c2c819941and return XRRSetCrtcConfig (dpy, res, crtc->crtc.xid, CurrentTime,
static Status
Status s;
return RRSetConfigSuccess;
if (!rr_outputs)
return BadAlloc;
if (verbose) {
if (dryrun)
s = RRSetConfigSuccess;
screen_revert (void)
if (verbose)
if (dryrun)
screen_apply (void)
if (verbose)
if (dryrun)
revert (void)
screen_revert ();
char *message;
revert ();
apply (void)
Status s;
if (!old_mode)
x = crtc_info->x;
y = crtc_info->y;
if (s != RRSetConfigSuccess)
screen_apply ();
if (s != RRSetConfigSuccess)
get_outputs (void)
if (!output)
static Bool
for (i = 0; i < ncon; i++)
return False;
return False;
return False;
return False;
return False;
return True;
static crtc_t *
return crtc;
return NULL;
set_positions (void)
for (i = 0; i < ncon; i++)
output->x = 0;
output->y = 0;
case left_of:
case right_of:
case above:
case below:
case same_as:
if (!keep_going)
if (!any_set)
for (i = 0; i < ncon; i++)
for (i = 0; i < ncon; i++)
static Bool
set_screen_size (void)
for (i = 0; i < ncon; i++)
if (!mode_info) continue;
x = output->x;
y = output->y;
if (verbose)
return False;
return True;
while (outputs)
int best_score;
int my_score;
int score;
if (!outputs)
return best_score;
if (!crtc)
my_score++;
return best_score;
static Bool
pick_crtcs (void)
for (i = 0; i < ncon; i++)
if (verbose)
if (i == ncon)
return True;
if (verbose)
return False;
return True;
static Bool
probe_and_check_output_changes (void) {
if (!new_res)
if (changed) {
if (res)
if (verbose)
return True;
if (verbose)
return False;
static Bool
need_probe (void) {
return True;
return False;
static Bool
return False;
x = output->x;
y = output->y;
return False;
x = output->x;
y = output->y;
return True;
static XRRModeInfo *
for (i = 0; i < c->nsmodes; i++) {
if (mode_info) {
x = output->x;
y = output->y;
if (i < c->nsmodes)
return c->smodes[i];
static Bool
return True;
return False;
do_init (void)
for (i = 0; i < MAX_OUTPUT; i++) {
ncon = 0;
dis_ncon = 0;
init_x = 0;
init_y = 0;
get_crtcs ();
get_outputs ();
(int (*) (const void *, const void *)) mode_sort);
if (verbose)
if (crtc)
ncon ++;
dis_ncon ++;
if (verbose) {
for (j = 0; j < ncon; j++) {
for (j = 0; j < dis_ncon; j++) {
start = i;
had_error = 0;
if (!testrun) {
if (had_error) {
if (verbose)
return keycode;
static Bool
do_switch (void)
int single;
for (i = 0; i < ncon; i++)
for (i = 0; i < ncon; i++) {
if (use_init_pos) {
output->x = 0;
output->y = 0;
if (!nosideview) {
if (verbose)
if (verbose)
single = 0;
if (single) {
for (i = 0; i < ncon; i++) {
if (new_mode[i]) {
if (verbose)
if (verbose)
if (!set_screen_size ())
return False;
if (!did_init)
get_crtcs();
if (!pick_crtcs()) {
if (verbose)
return True;
set_crtcs ();
apply();
return True;
unsigned int modifier = 0;
int keysym = 0;
usage();
int end = 0;
if (verbose)
for (j = 0; j < MAX_MODIFIERS; j++) {
if (j == MAX_MODIFIERS) {
usage();
if (end)
free (q);
usage();
if (!key_given)
if (!mod_given)
if (!res)
do_init();
if (testrun) {
if (verbose)
if (verbose)
if (probe_and_check_output_changes ()) {
while (output) {
for (i = 0; i < ncon; i++) {
do_init();
if (!do_not_switch)
if (!do_switch()) {
if (verbose)
(void) do_switch();