556 lines
15 KiB
C
556 lines
15 KiB
C
/*
|
|
* Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com)
|
|
*
|
|
* 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
|
|
* CONECTIVA LINUX 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.
|
|
*
|
|
* Except as contained in this notice, the name of Conectiva Linux shall
|
|
* not be used in advertising or otherwise to promote the sale, use or other
|
|
* dealings in this Software without prior written authorization from
|
|
* Conectiva Linux.
|
|
*
|
|
* Author: Paulo César Pereira de Andrade <pcpa@conectiva.com.br>
|
|
*
|
|
*/
|
|
|
|
#include "xf86config.h"
|
|
#include "screen-cfg.h"
|
|
#include <X11/Xaw/Command.h>
|
|
#include <X11/Xaw/Form.h>
|
|
#include <X11/Xaw/Label.h>
|
|
#include <X11/Xaw/List.h>
|
|
#include <X11/Xaw/Toggle.h>
|
|
#include <X11/Xaw/Viewport.h>
|
|
#ifdef USE_MODULES
|
|
#include "loader.h"
|
|
#endif
|
|
|
|
#define CW 1
|
|
#define CCW -1
|
|
|
|
/*
|
|
* Prototypes
|
|
*/
|
|
static void DepthCallback(Widget, XtPointer, XtPointer);
|
|
static void SelectIndexCallback(Widget, XtPointer, XtPointer);
|
|
static void UnselectIndexCallback(Widget, XtPointer, XtPointer);
|
|
static void SelectCallback(Widget, XtPointer, XtPointer);
|
|
static void UnselectCallback(Widget, XtPointer, XtPointer);
|
|
static void MoveCallback(Widget, XtPointer, XtPointer);
|
|
static void RotateCallback(Widget, XtPointer, XtPointer);
|
|
|
|
/*
|
|
* Initialization
|
|
*/
|
|
static char *standard_modes[] = {
|
|
"640x400",
|
|
"640x480",
|
|
"800x600",
|
|
"1024x768",
|
|
"1280x960",
|
|
"1280x1024",
|
|
"320x200",
|
|
"320x240",
|
|
"400x300",
|
|
"1152x864",
|
|
"1600x1200",
|
|
"1800x1400",
|
|
"512x384",
|
|
"1400x1050",
|
|
"2048x1536",
|
|
"1920x1440",
|
|
};
|
|
|
|
static char **modes;
|
|
static int nmodes;
|
|
static int default_depth, sel_index, unsel_index;
|
|
static Widget listL, listR;
|
|
static char **defmodes;
|
|
static int ndefmodes;
|
|
static XF86ConfScreenPtr screen;
|
|
static int rotate;
|
|
|
|
/*
|
|
* Implementation
|
|
*/
|
|
XtPointer
|
|
ScreenConfig(XtPointer conf)
|
|
{
|
|
XF86ConfDisplayPtr disp;
|
|
Arg args[2];
|
|
int i, oldrotate;
|
|
|
|
screen = (XF86ConfScreenPtr)conf;
|
|
if (screen == NULL)
|
|
return (NULL);
|
|
|
|
XtSetArg(args[0], XtNstring, screen->scrn_identifier);
|
|
XtSetValues(ident_widget, args, 1);
|
|
if ((default_depth = screen->scrn_defaultdepth) <= 0)
|
|
default_depth = 8;
|
|
sel_index = unsel_index = -1;
|
|
for (i = 0; i < computer.num_screens; i++)
|
|
if (computer.screens[i]->screen == screen) {
|
|
SetScreenRotate(computer.screens[i]);
|
|
rotate = computer.screens[i]->rotate;
|
|
}
|
|
oldrotate = rotate;
|
|
|
|
ndefmodes = 0;
|
|
disp = screen->scrn_display_lst;
|
|
while (disp != NULL) {
|
|
if (disp->disp_depth == default_depth) {
|
|
XF86ModePtr mod = disp->disp_mode_lst;
|
|
|
|
while (mod != NULL) {
|
|
if (ndefmodes % 16 == 0)
|
|
defmodes = (char**)
|
|
XtRealloc((XtPointer)defmodes,
|
|
(ndefmodes + 16) * sizeof(char*));
|
|
defmodes[ndefmodes++] = XtNewString(mod->mode_name);
|
|
mod = (XF86ModePtr)(mod->list.next);
|
|
}
|
|
break;
|
|
}
|
|
disp = (XF86ConfDisplayPtr)(disp->list.next);
|
|
}
|
|
if (ndefmodes == 0) {
|
|
defmodes = (char**)XtMalloc(sizeof(char*));
|
|
defmodes[0] = XtNewString("640x480");
|
|
ndefmodes = 1;
|
|
}
|
|
|
|
if (listL != NULL) {
|
|
XawListUnhighlight(listL);
|
|
XawListUnhighlight(listR);
|
|
}
|
|
|
|
xf86info.cur_list = SCREEN;
|
|
XtSetSensitive(back, xf86info.lists[SCREEN].cur_function > 0);
|
|
XtSetSensitive(next, xf86info.lists[SCREEN].cur_function <
|
|
xf86info.lists[SCREEN].num_functions - 1);
|
|
(xf86info.lists[SCREEN].functions[xf86info.lists[SCREEN].cur_function])
|
|
(&xf86info);
|
|
|
|
if (ConfigLoop(NULL) == True) {
|
|
XF86ModePtr prev = NULL, mod;
|
|
|
|
/* user may have changed the default depth, read variables again */
|
|
disp = screen->scrn_display_lst;
|
|
while (disp != NULL) {
|
|
if (disp->disp_depth == default_depth)
|
|
break;
|
|
disp = (XF86ConfDisplayPtr)(disp->list.next);
|
|
}
|
|
|
|
if (disp == NULL) {
|
|
disp = (XF86ConfDisplayPtr)XtCalloc(1, sizeof(XF86ConfDisplayRec));
|
|
screen->scrn_display_lst = (XF86ConfDisplayPtr)
|
|
xf86addListItem((GenericListPtr)(screen->scrn_display_lst),
|
|
(GenericListPtr)(disp));
|
|
disp->disp_depth = default_depth;
|
|
}
|
|
|
|
if (strcasecmp(screen->scrn_identifier, ident_string))
|
|
xf86renameScreen(XF86Config, screen, ident_string);
|
|
|
|
screen->scrn_defaultdepth = default_depth;
|
|
|
|
XtSetArg(args[0], XtNlist, NULL);
|
|
XtSetArg(args[1], XtNnumberStrings, 0);
|
|
XtSetValues(listL, args, 2);
|
|
|
|
XtSetArg(args[0], XtNlist, NULL);
|
|
XtSetArg(args[1], XtNnumberStrings, 0);
|
|
XtSetValues(listR, args, 2);
|
|
|
|
mod = disp->disp_mode_lst;
|
|
/* free all modes */
|
|
while (mod != NULL) {
|
|
prev = mod;
|
|
mod = (XF86ModePtr)(mod->list.next);
|
|
XtFree(prev->mode_name);
|
|
XtFree((XtPointer)prev);
|
|
}
|
|
/* readd modes */
|
|
for (i = 0; i < ndefmodes; i++) {
|
|
mod = XtNew(XF86ModeRec);
|
|
mod->mode_name = XtNewString(defmodes[i]);
|
|
XtFree(defmodes[i]);
|
|
if (i == 0)
|
|
disp->disp_mode_lst = mod;
|
|
else
|
|
prev->list.next = mod;
|
|
prev = mod;
|
|
}
|
|
if (i == 0)
|
|
disp->disp_mode_lst = NULL;
|
|
else
|
|
mod->list.next = NULL;
|
|
|
|
XtFree((XtPointer)defmodes);
|
|
defmodes = NULL;
|
|
ndefmodes = 0;
|
|
|
|
for (i = 0; i < computer.num_screens; i++)
|
|
if (computer.screens[i]->screen == screen)
|
|
computer.screens[i]->rotate = rotate;
|
|
|
|
if (oldrotate != rotate) {
|
|
static char *Rotate = "Rotate";
|
|
|
|
if (screen->scrn_option_lst != NULL)
|
|
xf86removeOption(&screen->scrn_option_lst, Rotate);
|
|
if (rotate)
|
|
screen->scrn_option_lst =
|
|
xf86addNewOption(screen->scrn_option_lst,
|
|
XtNewString(Rotate),
|
|
XtNewString(rotate > 0 ? "CW" : "CCW"));
|
|
UpdateScreenUI();
|
|
AdjustScreenUI();
|
|
}
|
|
|
|
return ((XtPointer)screen);
|
|
}
|
|
|
|
XtSetArg(args[0], XtNlist, NULL);
|
|
XtSetArg(args[1], XtNnumberStrings, 0);
|
|
XtSetValues(listL, args, 2);
|
|
|
|
XtSetArg(args[0], XtNlist, NULL);
|
|
XtSetArg(args[1], XtNnumberStrings, 0);
|
|
XtSetValues(listR, args, 2);
|
|
|
|
for (i = 0; i < ndefmodes; i++)
|
|
XtFree(defmodes[i]);
|
|
XtFree((XtPointer)defmodes);
|
|
defmodes = NULL;
|
|
ndefmodes = 0;
|
|
|
|
return (NULL);
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
static void
|
|
DepthCallback(Widget w, XtPointer user_data, XtPointer call_data)
|
|
{
|
|
if (call_data != NULL)
|
|
default_depth = (long)user_data;
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
static void
|
|
SelectIndexCallback(Widget w, XtPointer user_data, XtPointer call_data)
|
|
{
|
|
XawListReturnStruct *info = (XawListReturnStruct *)call_data;
|
|
|
|
sel_index = info->list_index;
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
static void
|
|
UnselectIndexCallback(Widget w, XtPointer user_data, XtPointer call_data)
|
|
{
|
|
XawListReturnStruct *info = (XawListReturnStruct *)call_data;
|
|
|
|
unsel_index = info->list_index;
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
static void
|
|
SelectCallback(Widget w, XtPointer user_data, XtPointer call_data)
|
|
{
|
|
Arg args[2];
|
|
|
|
if (sel_index < 0 || sel_index >= nmodes)
|
|
return;
|
|
|
|
if (ndefmodes == 1 && *defmodes[0] == '\0') {
|
|
/* make sure tmp and defentries are not the same pointer */
|
|
char **tmp = defmodes;
|
|
|
|
XtFree(defmodes[0]);
|
|
defmodes = (char**)XtMalloc(sizeof(char*));
|
|
--ndefmodes;
|
|
XtFree((char*)tmp);
|
|
}
|
|
else
|
|
defmodes = (char**)XtRealloc((XtPointer)defmodes,
|
|
sizeof(char*) * (ndefmodes + 1));
|
|
defmodes[ndefmodes++] = XtNewString(modes[sel_index]);
|
|
|
|
XtSetArg(args[0], XtNlist, defmodes);
|
|
XtSetArg(args[1], XtNnumberStrings, ndefmodes);
|
|
XtSetValues(listR, args, 2);
|
|
|
|
XawListUnhighlight(listR);
|
|
if (ndefmodes > 1 || (ndefmodes == 1 && *defmodes[0] != '\0')) {
|
|
if (unsel_index >= ndefmodes)
|
|
unsel_index = ndefmodes - 1;
|
|
XawListHighlight(listR, unsel_index = ndefmodes - 1);
|
|
}
|
|
else
|
|
unsel_index = -1;
|
|
|
|
/* force realyout */
|
|
XtUnmanageChild(listR);
|
|
XtManageChild(listR);
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
static void
|
|
UnselectCallback(Widget w, XtPointer user_data, XtPointer call_data)
|
|
{
|
|
Arg args[2];
|
|
char **modes;
|
|
Cardinal num_modes;
|
|
|
|
if (unsel_index < 0 || unsel_index >= ndefmodes)
|
|
return;
|
|
|
|
XawListUnhighlight(listL);
|
|
XtSetArg(args[0], XtNlist, &modes);
|
|
XtSetArg(args[1], XtNnumberStrings, &num_modes);
|
|
XtGetValues(listL, args, 2);
|
|
if (modes) {
|
|
for (sel_index = 0; sel_index < num_modes; sel_index++)
|
|
if (strcmp(defmodes[unsel_index], modes[sel_index]) == 0)
|
|
break;
|
|
if (sel_index < num_modes)
|
|
XawListHighlight(listL, sel_index);
|
|
else
|
|
sel_index = -1;
|
|
}
|
|
|
|
XtFree(defmodes[unsel_index]);
|
|
if (--ndefmodes > unsel_index)
|
|
memmove(&defmodes[unsel_index], &defmodes[unsel_index + 1],
|
|
(ndefmodes - unsel_index) * sizeof(char*));
|
|
if (ndefmodes == 0) {
|
|
char **tmp = defmodes;
|
|
|
|
defmodes = (char**)XtMalloc(sizeof(char*));
|
|
defmodes[0] = XtNewString("");
|
|
ndefmodes = 1;
|
|
XtFree((char*)tmp);
|
|
}
|
|
|
|
XtSetArg(args[0], XtNlist, defmodes);
|
|
XtSetArg(args[1], XtNnumberStrings, ndefmodes);
|
|
XtSetValues(listR, args, 2);
|
|
|
|
XawListUnhighlight(listR);
|
|
if (ndefmodes > 1 || (ndefmodes == 1 && *defmodes[0] != '\0')) {
|
|
if (unsel_index >= ndefmodes)
|
|
unsel_index = ndefmodes - 1;
|
|
XawListHighlight(listR, unsel_index);
|
|
}
|
|
else
|
|
unsel_index = -1;
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
static void
|
|
MoveCallback(Widget w, XtPointer user_data, XtPointer call_data)
|
|
{
|
|
char *tmp;
|
|
Bool down = (long)user_data;
|
|
|
|
if (unsel_index < 0 || unsel_index >= ndefmodes)
|
|
return;
|
|
|
|
if ((down && unsel_index + 1 >= ndefmodes) ||
|
|
(!down && unsel_index - 1 < 0))
|
|
return;
|
|
|
|
tmp = defmodes[unsel_index];
|
|
if (down) {
|
|
defmodes[unsel_index] = defmodes[unsel_index + 1];
|
|
unsel_index++;
|
|
} else {
|
|
defmodes[unsel_index] = defmodes[unsel_index - 1];
|
|
unsel_index--;
|
|
}
|
|
defmodes[unsel_index] = tmp;
|
|
|
|
XawListUnhighlight(listR);
|
|
XawListHighlight(listR, unsel_index);
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
void
|
|
RotateCallback(Widget w, XtPointer user_data, XtPointer call_data)
|
|
{
|
|
if (call_data != NULL)
|
|
rotate = (long)user_data;
|
|
else
|
|
rotate = 0;
|
|
}
|
|
|
|
void
|
|
ScreenDialog(XF86SetupInfo *info)
|
|
{
|
|
static Widget dialog, d1, d4, d8, d16, d24, labelRotate, cw, ccw;
|
|
Arg args[2];
|
|
XF86ConfMonitorPtr mon = screen->scrn_monitor;
|
|
XF86ConfModeLinePtr mline = mon != NULL ? mon->mon_modeline_lst : NULL;
|
|
int i;
|
|
#ifdef USE_MODULES
|
|
xf86cfgModuleOptions *drv_opts = module_options;
|
|
Bool foundRotate = False;
|
|
#endif
|
|
|
|
while (nmodes > 0)
|
|
XtFree(modes[--nmodes]);
|
|
XtFree((XtPointer)modes);
|
|
modes = NULL;
|
|
while (mline) {
|
|
if (nmodes % 16 == 0)
|
|
modes = (char**)XtRealloc((XtPointer)modes,
|
|
sizeof(char*) * (nmodes + 16));
|
|
modes[nmodes++] = XtNewString(mline->ml_identifier);
|
|
mline = (XF86ConfModeLinePtr)(mline->list.next);
|
|
}
|
|
for (i = 0; i < sizeof(standard_modes) / sizeof(standard_modes[0]); i++) {
|
|
if (nmodes % 16 == 0)
|
|
modes = (char**)XtRealloc((XtPointer)modes,
|
|
sizeof(char*) * (nmodes + 16));
|
|
modes[nmodes++] = XtNewString(standard_modes[i]);
|
|
}
|
|
|
|
if (dialog == NULL) {
|
|
Widget command, viewport;
|
|
|
|
dialog = XtCreateWidget("screenD", formWidgetClass,
|
|
configp, NULL, 0);
|
|
XtCreateManagedWidget("depthL", labelWidgetClass,
|
|
dialog, NULL, 0);
|
|
d1 = XtCreateManagedWidget("1", toggleWidgetClass, dialog, NULL, 0);
|
|
XtAddCallback(d1, XtNcallback, DepthCallback, (XtPointer)1);
|
|
d4 = XtVaCreateManagedWidget("4", toggleWidgetClass, dialog,
|
|
XtNradioGroup, d1, NULL);
|
|
XtAddCallback(d4, XtNcallback, DepthCallback, (XtPointer)4);
|
|
d8 = XtVaCreateManagedWidget("8", toggleWidgetClass, dialog,
|
|
XtNradioGroup, d4, NULL);
|
|
XtAddCallback(d8, XtNcallback, DepthCallback, (XtPointer)8);
|
|
d16 = XtVaCreateManagedWidget("16", toggleWidgetClass, dialog,
|
|
XtNradioGroup, d8, NULL);
|
|
XtAddCallback(d16, XtNcallback, DepthCallback, (XtPointer)16);
|
|
d24 = XtVaCreateManagedWidget("24", toggleWidgetClass, dialog,
|
|
XtNradioGroup, d16, NULL);
|
|
XtAddCallback(d24, XtNcallback, DepthCallback, (XtPointer)24);
|
|
|
|
XtCreateManagedWidget("modeL", labelWidgetClass, dialog, NULL, 0);
|
|
viewport = XtCreateManagedWidget("viewL", viewportWidgetClass, dialog,
|
|
NULL, 0);
|
|
listL = XtCreateManagedWidget("listLeft", listWidgetClass, viewport,
|
|
NULL, 0);
|
|
XtAddCallback(listL, XtNcallback, SelectIndexCallback, NULL);
|
|
command = XtCreateManagedWidget("select", commandWidgetClass,
|
|
dialog, NULL, 0);
|
|
XtAddCallback(command, XtNcallback, SelectCallback, NULL);
|
|
command = XtCreateManagedWidget("unselect", commandWidgetClass,
|
|
dialog, NULL, 0);
|
|
XtAddCallback(command, XtNcallback, UnselectCallback, NULL);
|
|
command = XtCreateManagedWidget("up", commandWidgetClass,
|
|
dialog, NULL, 0);
|
|
XtAddCallback(command, XtNcallback, MoveCallback, (XtPointer)False);
|
|
command = XtCreateManagedWidget("down", commandWidgetClass,
|
|
dialog, NULL, 0);
|
|
XtAddCallback(command, XtNcallback, MoveCallback, (XtPointer)True);
|
|
viewport = XtCreateManagedWidget("viewR", viewportWidgetClass, dialog,
|
|
NULL, 0);
|
|
listR = XtCreateManagedWidget("listRight", listWidgetClass, viewport,
|
|
NULL, 0);
|
|
XtAddCallback(listR, XtNcallback, UnselectIndexCallback, NULL);
|
|
|
|
labelRotate = XtCreateManagedWidget("rotate", labelWidgetClass,
|
|
dialog, NULL, 0);
|
|
cw = XtCreateManagedWidget("CW", toggleWidgetClass, dialog, NULL, 0);
|
|
XtAddCallback(cw, XtNcallback, RotateCallback, (XtPointer)CW);
|
|
ccw = XtVaCreateManagedWidget("CCW", toggleWidgetClass, dialog,
|
|
XtNradioGroup, cw, NULL);
|
|
XtAddCallback(ccw, XtNcallback, RotateCallback, (XtPointer)CCW);
|
|
|
|
XtRealizeWidget(dialog);
|
|
}
|
|
|
|
#ifdef USE_MODULES
|
|
if (!nomodules) {
|
|
while (drv_opts) {
|
|
if (drv_opts->type == VideoModule &&
|
|
strcmp(drv_opts->name, screen->scrn_device->dev_driver) == 0) {
|
|
OptionInfoPtr opts = drv_opts->option;
|
|
|
|
while (opts->name) {
|
|
if (xf86nameCompare(opts->name, "Rotate") == 0) {
|
|
foundRotate = True;
|
|
break;
|
|
}
|
|
opts++;
|
|
}
|
|
break;
|
|
}
|
|
drv_opts = drv_opts->next;
|
|
}
|
|
|
|
if (!foundRotate) {
|
|
XtUnmapWidget(labelRotate);
|
|
XtUnmapWidget(cw);
|
|
XtUnmapWidget(ccw);
|
|
}
|
|
else {
|
|
XtMapWidget(labelRotate);
|
|
XtMapWidget(cw);
|
|
XtMapWidget(ccw);
|
|
}
|
|
}
|
|
#else
|
|
(void)labelRotate;
|
|
#endif
|
|
if (rotate == CW) {
|
|
XtVaSetValues(cw, XtNstate, True, NULL);
|
|
XtVaSetValues(ccw, XtNstate, False, NULL);
|
|
}
|
|
else if (rotate == CCW) {
|
|
XtVaSetValues(cw, XtNstate, False, NULL);
|
|
XtVaSetValues(ccw, XtNstate, True, NULL);
|
|
}
|
|
else {
|
|
XtVaSetValues(cw, XtNstate, False, NULL);
|
|
XtVaSetValues(ccw, XtNstate, False, NULL);
|
|
}
|
|
|
|
XtSetArg(args[0], XtNlist, modes);
|
|
XtSetArg(args[1], XtNnumberStrings, nmodes);
|
|
XtSetValues(listL, args, 2);
|
|
|
|
XtSetArg(args[0], XtNlist, defmodes);
|
|
XtSetArg(args[1], XtNnumberStrings, ndefmodes);
|
|
XtSetValues(listR, args, 2);
|
|
|
|
XtSetArg(args[0], XtNstate, True);
|
|
XtSetValues(default_depth == 1 ? d1 :
|
|
default_depth == 4 ? d4 :
|
|
default_depth == 16 ? d16 :
|
|
default_depth == 24 ? d24 : d8, args, 1);
|
|
|
|
XtChangeManagedSet(¤t, 1, NULL, NULL, &dialog, 1);
|
|
current = dialog;
|
|
}
|