diff options
Diffstat (limited to 'xorg-server/hw/xfree86/utils/xorgcfg/screen-cfg.c')
-rw-r--r-- | xorg-server/hw/xfree86/utils/xorgcfg/screen-cfg.c | 555 |
1 files changed, 555 insertions, 0 deletions
diff --git a/xorg-server/hw/xfree86/utils/xorgcfg/screen-cfg.c b/xorg-server/hw/xfree86/utils/xorgcfg/screen-cfg.c new file mode 100644 index 000000000..4c67d725a --- /dev/null +++ b/xorg-server/hw/xfree86/utils/xorgcfg/screen-cfg.c @@ -0,0 +1,555 @@ +/* + * 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; +} |