2
* Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com)
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
11
* The above copyright notice and this permission notice shall be included in
12
* all copies or substantial portions of the Software.
14
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17
* CONECTIVA LINUX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
* Except as contained in this notice, the name of Conectiva Linux shall
23
* not be used in advertising or otherwise to promote the sale, use or other
24
* dealings in this Software without prior written authorization from
27
* Author: Paulo C�sar Pereira de Andrade <pcpa@conectiva.com.br>
29
* $XFree86: xc/programs/Xserver/hw/xfree86/xf86cfg/screen.c,v 1.9 2002/06/06 21:03:32 paulo Exp $
32
#include <X11/IntrinsicP.h>
33
#include <X11/extensions/shape.h>
34
#include <X11/Xaw/Simple.h>
43
void ReshapeScreenWidget(xf86cfgScreen*);
44
static int qcmp_screen(_Xconst void*, _Xconst void*);
51
static int rows, columns; /* number of rows/columns of monitors */
53
static int mon_width, mon_height;
54
static int *mon_widths, *mon_heights;
60
SetScreenRotate(xf86cfgScreen *screen)
62
static char *Rotate = "Rotate", *_CW = "CW", *_CCW = "CCW";
64
XF86OptionPtr option, options;
66
/* This is the only place where xf86cfg is intrusive, and deletes options
67
* added by the user directly in the config file. The "Rotate" option
68
* will be kept in the screen section.
70
if (screen->monitor != NULL) {
71
options = ((XF86ConfMonitorPtr)(screen->monitor->config))->mon_option_lst;
72
if ((option = xf86findOption(options, Rotate)) != NULL) {
73
if (option->opt_val != NULL)
74
rotate = strcasecmp(option->opt_val, _CW) == 0 ? CW :
75
strcasecmp(option->opt_val, _CCW) == 0 ? CCW : 0;
76
xf86removeOption(&((XF86ConfMonitorPtr)(screen->monitor->config))
77
->mon_option_lst, Rotate);
80
if (screen->card != NULL) {
81
options = ((XF86ConfDevicePtr)(screen->card->config))->dev_option_lst;
82
if ((option = xf86findOption(options, Rotate)) != NULL) {
83
if (option->opt_val != NULL)
84
rotate += strcasecmp(option->opt_val, _CW) == 0 ? CW :
85
strcasecmp(option->opt_val, _CCW) == 0 ? CCW : 0;
86
xf86removeOption(&((XF86ConfDevicePtr)(screen->card->config))
87
->dev_option_lst, Rotate);
91
options = screen->screen->scrn_option_lst;
92
if ((option = xf86findOption(options, Rotate)) != NULL) {
93
if (option->opt_val != NULL)
94
rotate += strcasecmp(option->opt_val, _CW) == 0 ? CW :
95
strcasecmp(option->opt_val, _CCW) == 0 ? CCW : 0;
96
xf86removeOption(&screen->screen->scrn_option_lst, Rotate);
99
rotate = rotate > 0 ? CW : rotate < 0 ? CCW : 0;
101
screen->screen->scrn_option_lst =
102
xf86addNewOption(screen->screen->scrn_option_lst,
104
XtNewString(rotate > 0 ? _CW : _CCW));
105
screen->rotate = rotate;
109
CreateScreenWidget(xf86cfgScreen *screen)
111
Widget w = XtCreateWidget("screen", simpleWidgetClass,
112
XtParent(computer.cpu), NULL, 0);
114
SetScreenRotate(screen);
117
screen->column = screen->row = -1;
119
ReshapeScreenWidget(screen);
123
ReshapeScreenWidget(xf86cfgScreen *screen)
128
int x = 0, y = 0, width = screen->rect.width, height = screen->rect.height;
129
Widget w = screen->widget;
131
if (screen->state == USED && screen->row >= 0) {
132
if (screen->column == 0)
133
x = w->core.width - width;
134
else if (screen->column == columns - 1)
135
x = w->core.width - mon_widths[screen->column];
137
x = (w->core.width - mon_widths[screen->column]) +
138
((mon_widths[screen->column] - width) >> 1);
140
if (screen->row == 0)
141
y = w->core.height - height;
142
else if (screen->row == rows - 1)
143
y = w->core.height - mon_heights[screen->row];
145
y = (w->core.height - mon_heights[screen->row]) +
146
((mon_heights[screen->row] - height) >> 1);
148
else if (screen->rect.width == 0) {
149
width = w->core.width;
150
height = w->core.height;
155
screen->rect.width = width;
156
screen->rect.height = height;
157
pixmap = XCreatePixmap(XtDisplay(w), XtWindow(w),
158
w->core.width, w->core.height, 1);
159
values.foreground = 0;
160
values.background = 1;
161
gc = XCreateGC(XtDisplay(w), pixmap, GCForeground | GCBackground, &values);
162
XFillRectangle(XtDisplay(w), pixmap, gc, 0, 0, w->core.width, w->core.height);
163
XSetForeground(XtDisplay(w), gc, 1);
165
DrawScreenMask(XtDisplay(w), pixmap, gc, x, y, x + width, y + height,
167
XShapeCombineMask(XtDisplay(w), XtWindow(w), ShapeBounding,
168
0, 0, pixmap, ShapeSet);
170
/* Do not call XtSetValues, to avoid all extra code for caching pixmaps */
171
XFreePixmap(XtDisplay(w), pixmap);
172
if (XtIsRealized(w)) {
173
pixmap = XCreatePixmap(XtDisplay(w), XtWindow(w),
174
w->core.width, w->core.height,
175
DefaultDepthOfScreen(XtScreen(w)));
176
DrawScreen(XtDisplay(w), pixmap, x, y, x + width, y + height,
177
screen->state == USED ? True : False, screen->rotate);
178
XSetWindowBackgroundPixmap(XtDisplay(w), XtWindow(w), pixmap);
179
XClearWindow(XtDisplay(w), XtWindow(w));
180
XFreePixmap(XtDisplay(w), pixmap);
182
XFreeGC(XtDisplay(w), gc);
186
AddScreen(xf86cfgDevice *mon, xf86cfgDevice *dev)
189
char screen_name[48];
190
XF86ConfScreenPtr screen = XF86Config->conf_screen_lst;
191
XF86ConfAdjacencyPtr adj;
193
while (screen != NULL) {
195
screen = (XF86ConfScreenPtr)(screen->list.next);
198
XmuSnprintf(screen_name, sizeof(screen_name), "Screen%d",
201
} while (xf86findScreen(screen_name,
202
XF86Config->conf_screen_lst) != NULL);
204
screen = (XF86ConfScreenPtr)XtCalloc(1, sizeof(XF86ConfScreenRec));
205
screen->scrn_identifier = XtNewString(screen_name);
206
screen->scrn_device_str = XtNewString(((XF86ConfDevicePtr)(dev->config))->dev_identifier);
207
screen->scrn_device = (XF86ConfDevicePtr)(dev->config);
208
screen->scrn_monitor_str = XtNewString(((XF86ConfMonitorPtr)(mon->config))->mon_identifier);
209
screen->scrn_monitor = (XF86ConfMonitorPtr)(mon->config);
210
XF86Config->conf_screen_lst =
211
xf86addScreen(XF86Config->conf_screen_lst, screen);
213
adj = (XF86ConfAdjacencyPtr)XtCalloc(1, sizeof(XF86ConfAdjacencyRec));
214
adj->adj_screen = screen;
215
adj->adj_screen_str = XtNewString(screen_name);
216
if (computer.layout == NULL)
217
computer.layout = XF86Config->conf_layout_lst = (XF86ConfLayoutPtr)
218
XtCalloc(1, sizeof(XF86ConfLayoutRec));
219
computer.layout->lay_adjacency_lst = (XF86ConfAdjacencyPtr)
220
xf86addListItem((GenericListPtr)computer.layout->lay_adjacency_lst,
221
(GenericListPtr)adj);
223
computer.screens = (xf86cfgScreen**)
224
XtRealloc((XtPointer)computer.screens, sizeof(xf86cfgScreen*) *
225
(computer.num_screens + 1));
226
computer.screens[computer.num_screens] =
227
(xf86cfgScreen*)XtCalloc(1, sizeof(xf86cfgScreen));
228
computer.screens[computer.num_screens]->screen = screen;
229
computer.screens[computer.num_screens]->card = dev;
230
computer.screens[computer.num_screens]->monitor = mon;
235
CreateScreenWidget(computer.screens[computer.num_screens]);
236
computer.screens[computer.num_screens]->type = SCREEN;
237
SetTip((xf86cfgDevice*)computer.screens[computer.num_screens]);
239
++computer.num_screens;
243
RemoveScreen(xf86cfgDevice *mon, xf86cfgDevice *dev)
245
XF86ConfScreenPtr screen = XF86Config->conf_screen_lst;
248
mon->state = dev->state = UNUSED;
249
while (screen != NULL) {
250
if ((XtPointer)screen->scrn_monitor == mon->config &&
251
(XtPointer)screen->scrn_device == dev->config)
254
screen = (XF86ConfScreenPtr)(screen->list.next);
259
for (i = 0; i < computer.num_screens; i++) {
260
if (computer.screens[i]->screen == screen) {
261
XtDestroyWidget(computer.screens[i]->widget);
262
if (i < --computer.num_screens)
263
memmove(&computer.screens[i], &computer.screens[i + 1],
264
(computer.num_screens - i) * sizeof(xf86cfgScreen*));
269
xf86removeScreen(XF86Config, screen);
273
ChangeScreen(XF86ConfMonitorPtr mon, XF86ConfMonitorPtr oldmon,
274
XF86ConfDevicePtr dev, XF86ConfDevicePtr olddev)
276
int ioldm, im, ioldc, ic;
278
if (mon == oldmon && dev == olddev)
282
for (im = 0; im < computer.num_devices; im++)
283
if (computer.devices[im]->config == (XtPointer)mon)
288
if (oldmon != NULL) {
289
for (ioldm = 0; ioldm < computer.num_devices; ioldm++)
290
if (computer.devices[ioldm]->config == (XtPointer)oldmon)
297
for (ic = 0; ic < computer.num_devices; ic++)
298
if (computer.devices[ic]->config == (XtPointer)dev)
303
if (olddev != NULL) {
304
for (ioldc = 0; ioldc < computer.num_devices; ioldc++)
305
if (computer.devices[ioldc]->config == (XtPointer)olddev)
311
if (ioldm >= 0 && ioldc >= 0) {
312
RemoveScreen(computer.devices[ioldm], computer.devices[ioldc]);
313
computer.devices[ioldm]->state = UNUSED;
314
/* computer.devices[ioldc]->state = UNUSED;*/
317
if (im >= 0 && ic >= 0) {
318
AddScreen(computer.devices[im], computer.devices[ic]);
319
computer.devices[im]->state = USED;
320
/* computer.devices[ic]->state = USED;*/
326
+------------------------------------------------+
328
| +------------------------------------------+ |
343
| +------------------------------------------+ |
345
+------------------------------------------------+
349
+----------------------------------------+
352
static double oxs = 0.0, oys = 0.0, oxe = 100.0, oye = 70.0;
353
static double ixs = 7.0, iys = 7.0, ixe = 93.0, iye = 63.0;
354
static double lin[] = { 25.0, 70.0, 25.0, 75.0, 5.0, 75.0, 5.0, 80.0,
355
95.0, 80.0, 95.0, 75.0, 75.0, 75.0, 75.0, 70.0 };
358
DrawScreen(Display *dpy, Drawable win, int xs, int ys, int xe, int ye,
359
Bool active, int rotate)
362
XPoint points[(sizeof(lin) / sizeof(lin[0])) >> 1];
364
static GC gray0, gray1, gray2, black, red;
370
XAllocNamedColor(XtDisplay(toplevel), toplevel->core.colormap, "gray95",
372
values.foreground = color.pixel;
373
gray0 = XCreateGC(XtDisplay(toplevel), win, GCForeground, &values);
374
XAllocNamedColor(XtDisplay(toplevel), toplevel->core.colormap, "gray75",
376
values.foreground = color.pixel;
377
gray1 = XCreateGC(XtDisplay(toplevel), win, GCForeground, &values);
379
XAllocNamedColor(XtDisplay(toplevel), toplevel->core.colormap, "gray60",
381
values.foreground = color.pixel;
382
gray2 = XCreateGC(XtDisplay(toplevel), win, GCForeground, &values);
384
XAllocNamedColor(XtDisplay(toplevel), toplevel->core.colormap, "gray20",
386
values.foreground = color.pixel;
387
black = XCreateGC(XtDisplay(toplevel), win, GCForeground, &values);
389
XAllocNamedColor(XtDisplay(toplevel), toplevel->core.colormap, "red",
391
values.foreground = color.pixel;
392
values.line_width = 4;
393
values.cap_style = CapButt;
394
red = XCreateGC(XtDisplay(toplevel), win,
395
GCForeground | GCLineWidth | GCCapStyle, &values);
399
xfact = (xe - xs) / 80.0;
400
yfact = (ye - ys) / 100.0;
402
/* outer rectangle */
403
XFillRectangle(dpy, win, gray1,
404
oxs * xfact + xs + .5,
405
oys * yfact + ys + .5,
406
(oye - oys) * xfact + .5,
407
(oxe - oxs) * yfact + .5);
408
XDrawLine(dpy, win, gray2,
410
70 * xfact + xs - 1 + .5, ye - 1);
411
XDrawLine(dpy, win, gray2,
412
70 * xfact + xs - 1 + .5, ye - 1,
413
70 * xfact + xs - 1 + .5, ys);
414
/* inner rectangle */
415
XFillRectangle(dpy, win, black,
416
ixs * xfact + xs + .5,
417
iys * yfact + ys + .5,
418
(iye - iys) * xfact + .5,
419
(ixe - ixs) * yfact + .5);
420
for (i = 0; i < sizeof(points) / sizeof(points[0]); i++) {
421
points[i].x = lin[(i<<1) + 1] * xfact + xs + .5;
422
points[i].y = lin[(i<<1)] * yfact + ys + .5;
424
XFillPolygon(dpy, win, gray2, points, i, Convex, CoordModeOrigin);
425
XDrawLine(dpy, win, gray0,
426
(oxe - 10) * xfact + xs + .5, oys * yfact + ys + .5,
427
xs, oys * yfact + ys + .5);
428
XDrawLine(dpy, win, gray0,
431
XDrawLine(dpy, win, black,
432
lin[7] * xfact + xs - 1 + .5, lin[6] * yfact + ys + .5,
433
lin[9] * xfact + xs - 1 + .5, lin[8] * yfact + ys - 1 + .5);
434
XDrawLine(dpy, win, black,
435
lin[9] * xfact + xs - 1 + .5, lin[8] * yfact + ys - 1 + .5,
436
lin[11] * xfact + xs + .5, lin[10] * yfact + ys - 1 + .5);
437
XDrawLine(dpy, win, black,
438
lin[13] * xfact + xs + .5, lin[12] * yfact + ys - 1 + .5,
439
lin[15] * xfact + xs + .5, lin[14] * yfact + ys - 1 + .5);
442
XDrawLine(dpy, win, red,
443
iys * xfact, ixs * yfact, iye * xfact, ixe * yfact);
444
XDrawLine(dpy, win, red,
445
iye * xfact, ixs * yfact, iys * xfact, ixe * yfact);
448
else if (rotate == CCW) {
449
/* outer rectangle */
450
XFillRectangle(dpy, win, gray1,
451
10 * xfact + xs + .5,
452
oys * yfact + ys + .5,
453
(oye - oys) * xfact + .5,
454
(oxe - oxs) * yfact + .5);
456
XDrawLine(dpy, win, gray2,
457
10 * xfact + xs + .5, ye - 1,
458
oxe * xfact + xs - 1 + .5, ye - 1);
459
XDrawLine(dpy, win, gray2,
462
/* inner rectangle */
463
XFillRectangle(dpy, win, black,
464
(ixs + 10) * xfact + xs + .5,
465
iys * yfact + ys + .5,
466
(iye - iys) * xfact + .5,
467
(ixe - ixs) * yfact + .5);
468
for (i = 0; i < sizeof(points) / sizeof(points[0]); i++) {
469
points[i].x = (-lin[(i<<1) + 1] + 80.0) * xfact + xs + .5;
470
points[i].y = lin[(i<<1)] * yfact + ys + .5;
472
XFillPolygon(dpy, win, gray2, points, i, Convex, CoordModeOrigin);
473
XDrawLine(dpy, win, gray0,
474
oxe * xfact + xs + .5, oys * yfact + ys + .5,
475
(oxs - 10) * xfact + xs + .5, oys * yfact + ys + .5);
476
XDrawLine(dpy, win, gray0,
477
(oxs + 10) * xfact + xs + .5, ys,
478
(oxs + 10) * xfact + xs + .5, xe);
480
XDrawLine(dpy, win, black,
481
xs, lin[8] * yfact - 1 + ys + .5,
482
4 * xfact + xs + .5, lin[8] * yfact - 1 + ys + .5);
483
XDrawLine(dpy, win, black,
484
4 * xfact + xs, lin[8] * yfact - 1 + ys + .5,
485
4 * xfact + xs, lin[3] * yfact - 1 + ys + .5);
486
XDrawLine(dpy, win, black,
487
4 * xfact + xs + .5, lin[3] * yfact - 1 + ys + .5,
488
10 * xfact + xs + .5 - 1, lin[3] * yfact - 1 + ys + .5);
489
XDrawLine(dpy, win, black,
490
4 * xfact + xs, lin[0] * yfact - 1 + ys + .5,
491
4 * xfact + xs, lin[4] * yfact - 1 + ys + .5);
494
XDrawLine(dpy, win, red,
495
(iys + 10) * xfact, ixs * yfact,
496
(iye + 10) * xfact, ixe * yfact);
497
XDrawLine(dpy, win, red,
498
(iye + 10) * xfact, ixs * yfact,
499
(iys + 10) * xfact, ixe * yfact);
504
xfact = (xe - xs) / 100.0;
505
yfact = (ye - ys) / 80.0;
507
/* outer rectangle */
508
XFillRectangle(dpy, win, gray1,
509
oxs * xfact + xs + .5,
510
oys * yfact + ys + .5,
511
(oxe - oxs) * xfact + .5,
512
(oye - oys) * yfact + .5);
514
XDrawLine(dpy, win, gray2,
515
oxs * xfact + xs + .5, oye * yfact + ys - 1 + .5,
516
oxe * xfact + xs - 1 + .5, oye * yfact + ys - 1 + .5);
517
XDrawLine(dpy, win, gray2,
518
oxe * xfact + xs - 1 + .5, oys * yfact + ys + .5,
519
oxe * xfact + xs - 1 + .5, oye * yfact + ys - 1 + .5);
521
/* inner rectangle */
522
XFillRectangle(dpy, win, black,
523
ixs * xfact + xs + .5,
524
iys * yfact + ys + .5,
525
(ixe - ixs) * xfact + .5,
526
(iye - iys) * yfact + .5);
528
for (i = 0; i < sizeof(points) / sizeof(points[0]); i++) {
529
points[i].x = lin[i<<1] * xfact + xs + .5;
530
points[i].y = lin[(i<<1) + 1] * yfact + ys + .5;
533
XFillPolygon(dpy, win, gray2, points, i, Convex, CoordModeOrigin);
535
XDrawLine(dpy, win, black,
536
lin[6] * xfact + xs + .5, lin[7] * yfact + ys - 1 + .5,
537
lin[8] * xfact + xs - 1 + .5, lin[9] * yfact + ys - 1 + .5);
538
XDrawLine(dpy, win, black,
539
lin[8] * xfact + xs - 1 + .5, lin[9] * yfact + ys - 1 + .5,
540
lin[10] * xfact + xs - 1 + .5, lin[11] * yfact + ys + .5);
541
XDrawLine(dpy, win, black,
542
lin[12] * xfact + xs - 1 + .5, lin[13] * yfact + ys + .5,
543
lin[14] * xfact + xs - 1 + .5, lin[15] * yfact + ys + .5);
545
XDrawLine(dpy, win, gray0,
546
oxe * xfact + xs + .5, oys * yfact + ys + .5,
547
oxs * xfact + xs + .5, oys * yfact + ys + .5);
548
XDrawLine(dpy, win, gray0,
549
oxs * xfact + xs + .5, oys * yfact + ys + .5,
550
oxs * xfact + xs + .5, lin[1] * yfact + ys + .5);
553
XDrawLine(dpy, win, red,
554
ixs * xfact, iys * yfact, ixe * xfact, iye * yfact);
555
XDrawLine(dpy, win, red,
556
ixe * xfact, iys * yfact, ixs * xfact, iye * yfact);
562
DrawScreenMask(Display *dpy, Drawable win, GC gc, int xs, int ys, int xe, int ye,
566
XPoint points[(sizeof(lin) / sizeof(lin[0])) >> 1];
567
int i = 0, x = 0, y = 0, width, height;
570
xfact = (xe - xs) / 80.0;
571
yfact = (ye - ys) / 100.0;
572
width = (oye - oys) * xfact + .5;
573
height = (oxe - oxs) * yfact + .5;
575
x = oxs * xfact + xs + .5;
576
y = oys * yfact + ys + .5;
577
for (i = 0; i < sizeof(points) / sizeof(points[0]); i++) {
578
points[i].x = lin[(i<<1) + 1] * xfact + xs + .5;
579
points[i].y = lin[(i<<1)] * yfact + ys + .5;
582
else if (rotate == CCW) {
583
x = 10 * xfact + xs + .5;
584
y = oys * yfact + ys + .5;
585
for (i = 0; i < sizeof(points) / sizeof(points[0]); i++) {
586
points[i].x = (-lin[(i<<1) + 1] + 80.0) * xfact + xs + .5;
587
points[i].y = lin[(i<<1)] * yfact + ys + .5;
592
xfact = (xe - xs) / 100.0;
593
yfact = (ye - ys) / 80.0;
594
x = oxs * xfact + xs + .5;
595
y = oys * yfact + ys + .5;
596
width = (oxe - oxs) * xfact + .5;
597
height = (oye - oys) * yfact + .5;
598
for (i = 0; i < sizeof(points) / sizeof(points[0]); i++) {
599
points[i].x = lin[(i<<1)] * xfact + xs + .5;
600
points[i].y = lin[(i<<1) + 1] * yfact + ys + .5;
605
XFillRectangle(dpy, win, gc, x, y, width, height);
608
XFillPolygon(dpy, win, gc, points, i, Convex, CoordModeOrigin);
614
XF86ConfLayoutPtr lay = computer.layout;
615
XF86ConfAdjacencyPtr adj;
616
int i, dx, dy, x, y, w, h, base = -1;
622
adj = lay->lay_adjacency_lst;
626
XtFree((XtPointer)mon_widths);
627
XtFree((XtPointer)mon_heights);
628
mon_widths = (int*)XtCalloc(1, sizeof(int) * columns);
629
mon_heights = (int*)XtCalloc(1, sizeof(int) * rows);
631
mon_width = mon_height = 0;
632
for (i = 0; i < computer.num_screens; i++) {
633
if (base == -1 && computer.screens[i]->state == USED)
635
if (computer.screens[i]->screen->scrn_monitor->mon_width > mon_width)
636
mon_width = computer.screens[i]->screen->scrn_monitor->mon_width;
637
if (computer.screens[i]->screen->scrn_monitor->mon_height > mon_height)
638
mon_height = computer.screens[i]->screen->scrn_monitor->mon_height;
641
for (i = 0; i < computer.num_screens; i++)
642
ReshapeScreenWidget(computer.screens[i]);
646
if (mon_width == 0) {
654
xf86cfgScreen *scr = NULL,
655
*topscr = NULL, *botscr = NULL, *lefscr = NULL, *rigscr = NULL;
657
for (i = 0; i < computer.num_screens; i++)
658
if (computer.screens[i]->screen == adj->adj_screen)
660
if (i < computer.num_screens)
661
scr = computer.screens[i];
663
if (adj->adj_top != NULL) {
664
for (i = 0; i < computer.num_screens; i++)
665
if (computer.screens[i]->screen == adj->adj_top)
667
if (i < computer.num_screens)
668
topscr = computer.screens[i];
671
if (adj->adj_bottom != NULL) {
672
for (i = 0; i < computer.num_screens; i++)
673
if (computer.screens[i]->screen == adj->adj_bottom)
675
if (i < computer.num_screens)
676
botscr = computer.screens[i];
679
if (adj->adj_left != NULL) {
680
for (i = 0; i < computer.num_screens; i++)
681
if (computer.screens[i]->screen == adj->adj_left)
683
if (i < computer.num_screens)
684
lefscr = computer.screens[i];
687
if (adj->adj_right != NULL) {
688
for (i = 0; i < computer.num_screens; i++)
689
if (computer.screens[i]->screen == adj->adj_right)
691
if (i < computer.num_screens)
692
rigscr = computer.screens[i];
695
if (lefscr == NULL && rigscr == NULL && topscr == NULL && lefscr == NULL) {
698
if (adj->adj_where >= CONF_ADJ_RIGHTOF < adj->adj_where <= CONF_ADJ_BELOW) {
699
s = xf86findScreen(adj->adj_refscreen, XF86Config->conf_screen_lst);
700
for (i = 0; i < computer.num_screens; i++)
701
if (computer.screens[i]->screen == s)
703
if (i < computer.num_screens) {
704
switch (adj->adj_where) {
705
case CONF_ADJ_RIGHTOF:
706
lefscr = computer.screens[i];
708
case CONF_ADJ_LEFTOF:
709
rigscr = computer.screens[i];
712
botscr = computer.screens[i];
715
topscr = computer.screens[i];
722
XtMoveWidget(scr->widget, 0, 0);
724
if (lefscr != NULL) {
725
if (lefscr->state == USED1)
726
XtMoveWidget(scr->widget,
727
lefscr->widget->core.x + lefscr->widget->core.width,
728
lefscr->widget->core.y);
730
XtMoveWidget(lefscr->widget,
731
-(int)(lefscr->widget->core.width),
732
scr->widget->core.y);
735
if (rigscr != NULL) {
736
if (rigscr->state == USED1) {
737
dx = rigscr->widget->core.x - scr->widget->core.width - scr->widget->core.x;
738
dy = rigscr->widget->core.y - scr->widget->core.y;
740
XtMoveWidget(scr->widget, scr->widget->core.x + dx,
741
scr->widget->core.y + dy);
742
if (lefscr != NULL && lefscr->state != USED1)
743
XtMoveWidget(lefscr->widget, lefscr->widget->core.x + dx,
744
lefscr->widget->core.y + dy);
747
XtMoveWidget(rigscr->widget, scr->widget->core.width,
748
scr->widget->core.y);
751
if (topscr != NULL) {
752
if (topscr->state == USED1) {
753
dx = topscr->widget->core.x - scr->widget->core.x;
754
dy = topscr->widget->core.y + topscr->widget->core.height -
757
XtMoveWidget(scr->widget, scr->widget->core.x + dx,
758
scr->widget->core.y + dy);
759
if (lefscr != NULL && lefscr->state != USED1)
760
XtMoveWidget(lefscr->widget, lefscr->widget->core.x + dx,
761
lefscr->widget->core.y + dy);
762
if (rigscr != NULL && rigscr->state != USED1)
763
XtMoveWidget(rigscr->widget, rigscr->widget->core.x + dx,
764
rigscr->widget->core.y + dy);
767
XtMoveWidget(topscr->widget, scr->widget->core.x,
768
scr->widget->core.y - topscr->widget->core.height);
771
if (botscr != NULL) {
772
if (botscr->state == USED1) {
773
dx = botscr->widget->core.x - scr->widget->core.x;
774
dy = botscr->widget->core.y - scr->widget->core.height - scr->widget->core.y;
776
XtMoveWidget(scr->widget, scr->widget->core.x + dx,
777
scr->widget->core.y + dy);
778
if (lefscr != NULL && lefscr->state != USED1)
779
XtMoveWidget(lefscr->widget, lefscr->widget->core.x + dx,
780
lefscr->widget->core.y + dy);
781
if (rigscr != NULL && rigscr->state != USED1)
782
XtMoveWidget(rigscr->widget, rigscr->widget->core.x + dx,
783
rigscr->widget->core.y + dy);
784
if (botscr != NULL && botscr->state != USED1)
785
XtMoveWidget(botscr->widget, botscr->widget->core.x + dx,
786
botscr->widget->core.y + dy);
789
XtMoveWidget(botscr->widget, scr->widget->core.x,
790
scr->widget->core.y + scr->widget->core.height);
793
adj = (XF86ConfAdjacencyPtr)(adj->list.next);
796
for (i = 0; i < computer.num_screens; i++)
797
if (computer.screens[i]->state == USED1)
798
computer.screens[i]->state = USED;
800
XLowerWindow(XtDisplay(computer.screens[i]->widget),
801
XtWindow(computer.screens[i]->widget));
803
w = work->core.width / (columns + 1) - 5;
804
h = work->core.height / (rows + 1) - 5;
811
dx = (work->core.width - (columns * w)) >> 1;
812
dy = (work->core.height - (rows * h)) >> 1;
814
xf = (double)w / (double)computer.screens[0]->widget->core.width;
815
yf = (double)h / (double)computer.screens[0]->widget->core.height;
817
for (i = 0; i < computer.num_screens; i++) {
818
Widget z = computer.screens[i]->widget;
820
if (computer.screens[i]->state == USED)
821
XtConfigureWidget(z, z->core.x * xf + dx,
822
z->core.y * yf + dy, w, h, 0);
824
XtConfigureWidget(z, z->core.x, z->core.y, w, h, 0);
827
if (computer.screens[base]->row >= 0) {
831
for (i = 0; i < computer.num_screens; i++) {
832
width = computer.screens[i]->screen->scrn_monitor->mon_width;
833
height = computer.screens[i]->screen->scrn_monitor->mon_height;
839
if (computer.screens[i]->rotate) {
840
xf = (double)width / (double)mon_width * 8. / 10.;
841
yf = (double)height / (double)mon_height;
844
xf = (double)width / (double)mon_width;
845
yf = (double)height / (double)mon_height * 8. / 10.;
847
width = computer.screens[i]->widget->core.width * xf;
848
height = computer.screens[i]->widget->core.height * yf;
849
if (computer.screens[i]->state == USED) {
850
if (mon_widths[computer.screens[i]->column] < width)
851
mon_widths[computer.screens[i]->column] = width;
852
if (mon_heights[computer.screens[i]->row] < height)
853
mon_heights[computer.screens[i]->row] = height;
856
/* do it here to avoid recalculation */
857
computer.screens[i]->rect.width = width;
858
computer.screens[i]->rect.height = height;
862
for (i = 0; i < computer.num_screens; i++)
863
ReshapeScreenWidget(computer.screens[i]);
865
/* do a new pass, to avoid gaps if the monitors have different
868
if (computer.screens[base]->row >= 0) {
869
x = computer.screens[base]->widget->core.x;
870
y = computer.screens[base]->widget->core.y;
872
/* screens representations are already ordered */
873
for (i = base; i < computer.num_screens; i++) {
874
if (computer.screens[i]->state == UNUSED)
876
if (computer.screens[i]->column != 0)
877
x += mon_widths[computer.screens[i]->column];
879
x = computer.screens[base]->widget->core.x;
881
y += mon_heights[computer.screens[i]->row];
883
XtMoveWidget(computer.screens[i]->widget, x, y);
890
qcmp_screen(_Xconst void *a, _Xconst void *b)
892
xf86cfgScreen *s1, *s2;
894
s1 = *(xf86cfgScreen**)a;
895
s2 = *(xf86cfgScreen**)b;
897
if (s1->widget->core.x > s2->widget->core.x) {
898
if (s2->widget->core.y >=
899
s1->widget->core.y + (s1->widget->core.height >> 1))
904
if (s1->widget->core.y >=
905
s2->widget->core.y + (s2->widget->core.height >> 1))
915
XF86ConfLayoutPtr lay = computer.layout;
916
XF86ConfAdjacencyPtr adj, prev, left, base;
917
int i, p, cols, scrno;
922
rows = columns = cols = 1;
924
qsort(computer.screens, computer.num_screens, sizeof(xf86cfgScreen*),
927
adj = prev = left = base = NULL;
928
for (i = p = scrno = 0; i < computer.num_screens; i++) {
929
XF86ConfScreenPtr scr = computer.screens[i]->screen;
931
if (computer.screens[i]->state == UNUSED)
934
adj = (XF86ConfAdjacencyPtr)XtCalloc(1, sizeof(XF86ConfAdjacencyRec));
935
adj->adj_scrnum = scrno++;
936
adj->adj_screen = scr;
937
adj->adj_screen_str = XtNewString(scr->scrn_identifier);
940
computer.screens[i]->row = computer.screens[i]->column = 0;
943
int dy = computer.screens[i]->widget->core.y -
944
computer.screens[p]->widget->core.y;
946
prev->list.next = adj;
947
if (dy > (computer.screens[i]->widget->core.height >> 1)) {
948
adj->adj_where = CONF_ADJ_BELOW;
949
adj->adj_refscreen = XtNewString(left->adj_screen_str);
951
computer.screens[i]->row = rows;
952
computer.screens[i]->column = 0;
957
computer.screens[i]->row = rows - 1;
958
computer.screens[i]->column = cols;
959
adj->adj_where = CONF_ADJ_RIGHTOF;
960
if (++cols > columns)
962
adj->adj_refscreen = XtNewString(prev->adj_screen_str);
969
adj = lay->lay_adjacency_lst;
971
while (adj != NULL) {
973
adj = (XF86ConfAdjacencyPtr)(adj->list.next);
974
XtFree(prev->adj_screen_str);
975
XtFree(prev->adj_right_str);
976
XtFree(prev->adj_left_str);
977
XtFree(prev->adj_top_str);
978
XtFree(prev->adj_bottom_str);
979
XtFree(prev->adj_refscreen);
983
lay->lay_adjacency_lst = base;