From e1165632bdfbd720889ed1adf5f7ab338032c0ee Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 21 Dec 2009 15:56:35 +1000 Subject: [PATCH] xfree86: Add Option AutoServerLayout for input devices. Any input device with this option will be automatically added to whichever server layout is selected at startup. This removes the need to reference a device from the ServerLayout section. The two following configuration are identical: CONFIG 1: Section "ServerLayout" InputDevice "foo" EndSection Section "InputDevice" Identifier "foo" ... EndSection CONFIG 2: Section "InputDevice" Identifier "foo" Option "AutoServerLayout" "on" ... EndSection The selection of the server layout affects both explicitly specified layouts and the implicit layout. Signed-off-by: Peter Hutterer Reviewed-by: Keith Packard --- hw/xfree86/common/xf86Config.c | 97 +++++++++++++++++----------- hw/xfree86/doc/man/xorg.conf.man.pre | 5 ++ hw/xfree86/parser/Layout.c | 79 +++++++++++++++++----- hw/xfree86/parser/xf86Parser.h | 1 + 4 files changed, 129 insertions(+), 53 deletions(-) diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c index e4f0d2388..56ab2ee46 100644 --- a/hw/xfree86/common/xf86Config.c +++ b/hw/xfree86/common/xf86Config.c @@ -1488,6 +1488,45 @@ static OptionInfoRec LayoutOptions[] = { {0}, FALSE }, }; +static Bool +configInputDevices(XF86ConfLayoutPtr layout, serverLayoutPtr servlayoutp) +{ + XF86ConfInputrefPtr irp; + IDevPtr *indp; + int count = 0; + + /* + * Count the number of input devices. + */ + irp = layout->lay_input_lst; + while (irp) { + count++; + irp = (XF86ConfInputrefPtr)irp->list.next; + } + DebugF("Found %d input devices in the layout section %s\n", + count, layout.lay_identifier); + indp = xnfcalloc((count + 1), sizeof(IDevPtr)); + indp[count] = NULL; + irp = layout->lay_input_lst; + count = 0; + while (irp) { + indp[count] = xnfalloc(sizeof(IDevRec)); + if (!configInput(indp[count], irp->iref_inputdev, X_CONFIG)) { + while(count--) + xfree(indp[count]); + xfree(indp); + return FALSE; + } + indp[count]->extraOptions = irp->iref_option_lst; + count++; + irp = (XF86ConfInputrefPtr)irp->list.next; + } + servlayoutp->inputs = indp; + + return TRUE; +} + + /* * figure out which layout is active, which screens are used in that layout, * which drivers and monitors are used in these screens @@ -1498,14 +1537,12 @@ configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout, { XF86ConfAdjacencyPtr adjp; XF86ConfInactivePtr idp; - XF86ConfInputrefPtr irp; int count = 0; int scrnum; XF86ConfLayoutPtr l; MessageType from; screenLayoutPtr slp; GDevPtr gdp; - IDevPtr* indp; int i = 0, j; if (!servlayoutp) @@ -1679,37 +1716,13 @@ configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout, count++; idp = (XF86ConfInactivePtr)idp->list.next; } - /* - * Count the number of input devices. - */ - count = 0; - irp = conf_layout->lay_input_lst; - while (irp) { - count++; - irp = (XF86ConfInputrefPtr)irp->list.next; - } - DebugF("Found %d input devices in the layout section %s\n", - count, conf_layout->lay_identifier); - indp = xnfcalloc((count + 1), sizeof(IDevPtr)); - indp[count] = NULL; - irp = conf_layout->lay_input_lst; - count = 0; - while (irp) { - indp[count] = xnfalloc(sizeof(IDevRec)); - if (!configInput(indp[count], irp->iref_inputdev, X_CONFIG)) { - while(count--) - xfree(indp[count]); - xfree(indp); - return FALSE; - } - indp[count]->extraOptions = irp->iref_option_lst; - count++; - irp = (XF86ConfInputrefPtr)irp->list.next; - } + + if (!configInputDevices(conf_layout, servlayoutp)) + return FALSE; + servlayoutp->id = conf_layout->lay_identifier; servlayoutp->screens = slp; servlayoutp->inactives = gdp; - servlayoutp->inputs = indp; servlayoutp->options = conf_layout->lay_option_lst; from = X_DEFAULT; @@ -1721,12 +1734,14 @@ configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout, * the only active screen. */ static Bool -configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen) +configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen, + XF86ConfigPtr xf86configptr) { MessageType from; XF86ConfScreenPtr s; screenLayoutPtr slp; IDevPtr *indp; + XF86ConfLayoutRec layout; if (!servlayoutp) return FALSE; @@ -1762,10 +1777,19 @@ configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen) servlayoutp->screens = slp; servlayoutp->inactives = xnfcalloc(1, sizeof(GDevRec)); servlayoutp->options = NULL; - /* Set up an empty input device list, then look for some core devices. */ - indp = xnfalloc(sizeof(IDevPtr)); - *indp = NULL; - servlayoutp->inputs = indp; + + memset(&layout, 0, sizeof(layout)); + layout.lay_identifier = servlayoutp->id; + if (xf86layoutAddInputDevices(xf86configptr, &layout) > 0) { + if (!configInputDevices(&layout, servlayoutp)) + return FALSE; + from = X_DEFAULT; + } else { + /* Set up an empty input device list, then look for some core devices. */ + indp = xnfalloc(sizeof(IDevPtr)); + *indp = NULL; + servlayoutp->inputs = indp; + } return TRUE; } @@ -2478,7 +2502,8 @@ xf86HandleConfigFile(Bool autoconfig) "No Layout section. Using the first Screen section.\n"); } if (!configImpliedLayout(&xf86ConfigLayout, - xf86configptr->conf_screen_lst)) { + xf86configptr->conf_screen_lst, + xf86configptr)) { xf86Msg(X_ERROR, "Unable to determine the screen layout\n"); return CONFIG_PARSE_ERROR; } diff --git a/hw/xfree86/doc/man/xorg.conf.man.pre b/hw/xfree86/doc/man/xorg.conf.man.pre index 749eab068..7941a470a 100644 --- a/hw/xfree86/doc/man/xorg.conf.man.pre +++ b/hw/xfree86/doc/man/xorg.conf.man.pre @@ -880,6 +880,11 @@ which are described here. See the individual input driver manual pages for a description of the device\-specific options. .TP 7 +.BI "Option \*qAutoServerLayout\*q \*q" boolean \*q +Always add the device to the ServerLayout section used by this instance of +the server. This affects implied layouts as well as explicit layouts +specified in the configuration and/or on the command line. +.TP 7 .BI "Option \*qCorePointer\*q" Deprecated, use .B SendCoreEvents diff --git a/hw/xfree86/parser/Layout.c b/hw/xfree86/parser/Layout.c index beb008b35..00c1e7d09 100644 --- a/hw/xfree86/parser/Layout.c +++ b/hw/xfree86/parser/Layout.c @@ -64,6 +64,10 @@ #include "Configint.h" #include + +/* Needed for auto server layout */ +extern int xf86CheckBoolOption(void* optlist, const char *name, int deflt); + extern LexRec val; static xf86ConfigSymTabRec LayoutTab[] = @@ -435,16 +439,68 @@ xf86freeLayoutList (XF86ConfLayoutPtr ptr) } } +int +xf86layoutAddInputDevices(XF86ConfigPtr config, XF86ConfLayoutPtr layout) +{ + int count = 0; + XF86ConfInputPtr input = config->conf_input_lst; + XF86ConfInputrefPtr inptr; + + /* add all AutoServerLayout devices to the server layout */ + while (input) + { + if (xf86CheckBoolOption(input->inp_option_lst, "AutoServerLayout", FALSE)) + { + XF86ConfInputrefPtr iref = layout->lay_input_lst; + + /* avoid duplicates if referenced but lists AutoServerLayout too */ + while (iref) + { + if (strcmp(iref->iref_inputdev_str, input->inp_identifier) == 0) + break; + iref = iref->list.next; + } + + if (!iref) + { + XF86ConfInputrefPtr iptr; + iptr = calloc(1, sizeof(XF86ConfInputrefRec)); + iptr->iref_inputdev_str = input->inp_identifier; + layout->lay_input_lst = (XF86ConfInputrefPtr) + xf86addListItem((glp)layout->lay_input_lst, (glp)iptr); + count++; + } + } + input = input->list.next; + } + + inptr = layout->lay_input_lst; + while (inptr) + { + input = xf86findInput (inptr->iref_inputdev_str, + config->conf_input_lst); + if (!input) + { + xf86validationError (UNDEFINED_INPUT_MSG, + inptr->iref_inputdev_str, layout->lay_identifier); + return -1; + } + else + inptr->iref_inputdev = input; + inptr = inptr->list.next; + } + + return count; +} + int xf86validateLayout (XF86ConfigPtr p) { XF86ConfLayoutPtr layout = p->conf_layout_lst; XF86ConfAdjacencyPtr adj; XF86ConfInactivePtr iptr; - XF86ConfInputrefPtr inptr; XF86ConfScreenPtr screen; XF86ConfDevicePtr device; - XF86ConfInputPtr input; while (layout) { @@ -479,21 +535,10 @@ xf86validateLayout (XF86ConfigPtr p) iptr->inactive_device = device; iptr = iptr->list.next; } - inptr = layout->lay_input_lst; - while (inptr) - { - input = xf86findInput (inptr->iref_inputdev_str, - p->conf_input_lst); - if (!input) - { - xf86validationError (UNDEFINED_INPUT_MSG, - inptr->iref_inputdev_str, layout->lay_identifier); - return (FALSE); - } - else - inptr->iref_inputdev = input; - inptr = inptr->list.next; - } + + if (xf86layoutAddInputDevices(p, layout) == -1) + return FALSE; + layout = layout->list.next; } return (TRUE); diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h index 12bcd6e65..4675d02c7 100644 --- a/hw/xfree86/parser/xf86Parser.h +++ b/hw/xfree86/parser/xf86Parser.h @@ -476,6 +476,7 @@ extern _X_EXPORT XF86ConfInputPtr xf86findInput(const char *ident, XF86ConfInput extern _X_EXPORT XF86ConfInputPtr xf86findInputByDriver(const char *driver, XF86ConfInputPtr p); extern _X_EXPORT XF86ConfVideoAdaptorPtr xf86findVideoAdaptor(const char *ident, XF86ConfVideoAdaptorPtr p); +extern int xf86layoutAddInputDevices(XF86ConfigPtr config, XF86ConfLayoutPtr layout); extern _X_EXPORT GenericListPtr xf86addListItem(GenericListPtr head, GenericListPtr c_new); extern _X_EXPORT int xf86itemNotSublist(GenericListPtr list_1, GenericListPtr list_2);