/*
*
* 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,
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) 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
* THE AUTHORS OR COPYRIGHT HOLDERS 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.
*/
#include <libscf.h> /* Service Configuration Facility */
#include <stdarg.h> /* va_end(), va_start(), vfprintf() */
#include <stdio.h> /* fprintf(), printf() */
#include <stdlib.h> /* exit(), free(), malloc() */
#include <string.h> /* strerror(), str[l]cpy(), strstr(), ... */
#include <unistd.h> /* close(), ioctl() */
#include <dirent.h> /* opendir(), readdir(), closedir() */
#include <fcntl.h> /* open() */
#include <nl_types.h>
#include <errno.h> /* errno */
#include "gfx_common.h" /* Frame buffer model name */
/*
*/
/*
* Frame buffer configuration software directory
*/
/*
* fbconfig invokes the dcmtool script (which in turn invokes java)
*/
/* globals */
/*
* PrintError()
*
* Write a variable format error message to stderr, prefixed by the
* program name.
*/
static
void
{
} /* PrintError() */
/*
* IdentifyXServer()
*
* Determine what X server is currently configured (Xsun, Xorg, ...).
*
* Note that this is not necessarily the X server that is currently
* running.
*
* Related svccfg(1M) "set" and "list" commands:
*
* svccfg -s svc:/application/x11/x11-server \
* svccfg -s svc:/application/x11/x11-server \
*
* svccfg -s svc:/application/x11/x11-server listprop 'options/server'
*/
typedef enum {
} xserv_t;
#if OSVER==510
#else
#endif
static
IdentifyXServer(void)
{
/*
* X, the unknown
*/
/*
* Allocate and initialize the necessary SCF data structures
*/
(prop_group == NULL) ||
(scf_handle == NULL)) {
#ifdef DEBUG_FB
PrintError("SCF resource creation, %s",
scf_strerror(scf_error()));
#endif
goto clean_up;
}
/*
* Retrieve the Nul-terminated X server pathname string
*/
== -1) ||
#ifdef DEBUG_FB
PrintError("SCF value retrieval, %s",
scf_strerror(scf_error()));
#endif
goto clean_up;
}
/*
* Evaluate the simple filename
*/
} else {
filename += 1;
}
} else
}
/*
* Destroy our resources
*/
}
}
if (prop_group != NULL) {
}
}
}
if (scf_handle != NULL) {
}
/*
* Return the identity of the X server
*/
return (x_server);
} /* IdentifyXServer() */
/*
* CallConfigProgram()
*
* Become the actual device configuration program, executing it with
* the caller-provided argument vector. This function does not
* return.
*/
static
void
{
#ifdef DEBUG_FB
printf("CallConfigProgram(argv is NULL)\n");
exit(1);
}
{
int i;
}
}
#endif
"No configuration program pathname"));
} else {
}
exit(1);
} /* CallConfigProgram() */
/*
* get_device_model()
*
* Return the frame buffer model name, else an empty string, in the
* caller-supplied device_model[GFX_MAX_MODELNAME_LEN] name buffer.
*
* Note that ioctl(GFX_IOCTL_GET_IDENTIFIER) might not be supported
* by older drivers (e.g., Xsun drivers).
*/
static
void
int device_fd, /* Device file descriptor number */
char *device_model) /* Returned device model name */
{
/*
* Get the frame buffer model name w/o any leading "SUNW," substring
*/
model_name = "";
}
}
}
/*
* Return the frame buffer model name, else an empty string
*/
} /* get_device_model() */
/*
* get_device_identification()
*
* character special file. If the caller has provided the necessary
* pointer, return the (struct stat).st_rdev value. Open the file
* and return the VISUAL environment device identifier name. For
* "SUNWjfb". If the caller has provided the necessary
* device_model[GFX_MAX_MODELNAME_LEN] name buffer, get and return
* the frame buffer model name.
*
* In the event of an error, return an errno-style error code. An
* EACCES code may be of special interest to the caller.
*/
/*
* Mask for stat_buf.st_rdev member
*/
static
int
const char *device_path, /* Device pathname */
int *st_rdev, /* Optionally returned st_rdev value */
char *device_model) /* Optionally returned model name */
{
/*
* Make sure this is a character special file
*/
return (errno);
}
return (ENODEV); /* "No such device" almost says it */
}
/*
* Return the st_rdev value if the caller wants it
*/
}
/*
* Open the existing device file
*/
if (device_fd == -1) {
return (errno); /* Error code, e.g. EACCES */
}
/*
* Get the VISUAL environment device identifier name
*/
error_code = 0;
error_code = errno;
}
/*
* If the caller wants it, return the frame buffer model name
*/
if (device_model != NULL) {
}
return (error_code);
} /* get_device_identification() */
typedef struct {
} path_file_t;
};
/*
* GetDefaultDevicePathname()
*
* This function looks for a default device and returns the pathname
* of the first default frame buffer device that is found and can be
* opened and provide a VISUAL environment device identifier. The
* possible return values are:
* Zero - Success; a default device exists and can be accessed
* ENOENT - No frame buffer device was found
* EACCES - Something was found, but the user can't access it
*/
static
int
char **device_path) /* Returned default device pathname */
{
*device_path = NULL;
error_code = ENOENT;
/*
* See whether any default device will open and identify itself
*/
for (default_dev = &default_device[0];
default_dev += 1) {
if (err_code == 0) {
return (0); /* At least one FB device exists */
}
if (*device_path == NULL) {
}
}
}
return (error_code);
} /* GetDefaultDevicePathname() */
/*
* GetDevicePathname()
*
* Given the pathname or simple filename of a real or default frame
* buffer device, return the fully qualified pathname.
*
* Partial pathnames will be treated arbitrarily in nonsense-in,
* nonsense-out fashion.
*
* The caller-supplied buffer will be used if it is necessary to
* construct a fully qualified pathname from path components.
*/
static
char *
char *device_name, /* Free-form device name */
char *device_path_buf, /* Ptr to device pathname buffer */
{
#if (0) /* Currently unused */
/*
* If there's no device name, return the most likely default pathname
*/
if (device_name == NULL) {
(void) GetDefaultDevicePathname(&device_name);
if (device_name == NULL) {
}
return (device_name);
}
#endif /* Currently unused */
/*
* Convert a default device name to a full pathname
*/
for (default_dev = &default_device[0];
default_dev += 1) {
return (default_dev->pathname);
}
}
/*
* Try to convert a real device filename to a full pathname
*/
if (*device_name != '/') {
< device_path_buflen) {
}
}
/*
* Return the full pathname or whatever
*/
return (device_name);
} /* GetDevicePathname() */
/*
* GetConfigProgramPath()
*
* Given the current X server and the identifier for the frame buffer
* device, construct the full pathname of the relevant configuration
* program. Return the program pathname and a sense of whether it
* exists (ENOENT), is accessible (EACCES), etc.
*
* The caller is responsible for freeing the returned pathname
* string.
*/
static
int
const char *vis_ident_name, /* VISUAL env device identifier */
char **config_prog_path) /* Returned config program path */
{
*config_prog_path = NULL;
error_code = 0;
/*
* Build server-specific pathnames of config programs
*/
switch (x_server) {
default:
/*
* Commandeer EINVAL to indicate that the X server is unknown
*/
return (EINVAL); /* Invalid x_server argument */
case XSERVER_XSUN:
if (*config_prog_path == NULL) {
return (ENOMEM);
}
break;
case XSERVER_XORG:
/*
* Allocate memory to contain any one of the pathnames:
* * any device-specific config program
* * the device-specific library used by fbconf_xorg
* * the multi-device config program, fbconf_xorg
*
* Note that the two-character "%s" conversion spec
* in the sprintf() format string is replaced by the
* vis_ident_name string. Its trifling length could
* be ignored but we'll count it against the length
* of the Nul terminator.
*/
}
}
if (*config_prog_path == NULL) {
return (ENOMEM);
}
/*
* See if a config program exists, accessible or not
*/
return (0); /* Have a device-specific program */
}
return (errno); /* Have a program w/ encumbrances */
}
/*
* Make a note of whether a device-specific library exists
*
* We'll return the multi-device config program path
* in any case. The caller can decide, based on the
* error code, whether and how it could be useful.
*/
error_code = errno;
}
/*
* Construct the multi-device config program pathname
*
* It's assumed that the states of existence and
* accessibility of the config program, fbconf_xorg,
* also hold true for its common library,
* libfbconf_xorg.so.
*/
break;
}
/*
* See if the config program exists and allows the user to execute it
*/
if (error_code != ENOENT) {
}
}
return (error_code);
} /* GetConfigProgramPath() */
/*
* FindConfigProgram()
*
* Return the full pathname of the configuration program associated
* with this X server and fully qualified device pathname.
*
* In the event of an error, an error code from errno.h space will be
* returned, along with a NULL pathname pointer.
*
* The caller is responsible for freeing the returned pathname
* string.
*/
static
int
const char *device_path, /* Device pathname */
char **config_prog_path) /* Returned config program path */
{
*config_prog_path = NULL;
/*
* Validate the device and get its VISUAL environment identifier
*/
if (error_code != 0) {
if (error_code != EACCES) {
"Not a configurable device. "
" Use -list to show valid devices."));
}
return (error_code);
}
/*
* Get the config program to use with this X server and device type
*/
if (error_code != 0) {
(*config_prog_path == NULL) ?
"config program" : *config_prog_path);
*config_prog_path = NULL;
}
return (error_code);
} /* FindConfigProgram() */
/*
* PathToGUI()
*
* Return the pathname of the DCM Tool GUI script and an errno-style
* error code indicating whether the pathname is useable.
*/
static
int
const char **gui_path) /* Returned GUI script pathname */
{
error_code = 0;
error_code = errno;
#ifdef DEBUG_FB
#endif
}
return (error_code);
} /* PathToGUI() */
/*
* PrintHelp()
*
* Display this program's command line syntax. Include the -gui
* option only if PathToGUI() returns a non-zero error code,
* indicating that the returned GUI pathname is useable. Then invoke
* the actual device configuration program, iff known, to display its
* own -help text. (The device configuration program must implement
* the -dev and the -help option.)
*/
static
void
char *device_path) /* Device pathname */
{
/*
* Decide whether to show the -gui option synopsis and description
*/
gui_synopsis = "";
#if (1) /* ??? Cover for temporarily absent functionality ??? */
error_code = EINVAL;
if (x_server == XSERVER_XSUN) {
#endif
if (error_code == 0) {
}
#if (1) /* ??? Cover for temporarily absent functionality ??? */
}
#endif
/*
* Display synopsis (usage) and description text
*/
"Usage:\n"
"\tfbconfig [-dev devname] [-help] [-list]%s\n"
"\t [device-specific-options]\n"
"\t-dev\t\tSpecify the frame buffer device file name.\n"
"\t-help\t\tDisplay this help text.\n"
"\t-list\t\tList installed and configurable frame buffers.\n"
"\t-xserver [Xorg | Xsun]\tConfigure the Xserver to the specified program.\n"),
if (error_code == 0) {
"\t-gui\t\tInvoke Graphical User Interface (SUNWdcm)\n"
"\t\t\tto configure devices and update Xservers file.\n"));
}
printf("\n"
"\tdevice-specific-options are implemented by the device\n"
"\t\t\tconfiguration program.\n"
"\n");
/*
* Invoke the device config program to display its own -help text
*/
if (device_path != NULL) {
(void) FindConfigProgram(
if (config_prog_path != NULL) {
argv[0] = config_prog_path;
}
}
} /* PrintHelp() */
/*
* ListDevices_StreamCheck()
*
* See whether the specified "device" name and "stream" name are in
* fact a device file and a stream file for the same device. (It is
* possible that the device file is actually a stream for a previous
* device. The stream file could be any frame buffer entity.) If a
* character. Return a Nul character otherwise.
*/
static
char
const char *device_name, /* Device file name */
int device_rdev, /* st_rdev value returned by stat() */
const char *stream_name) /* Potential stream file name */
{
/*
* See if the potential stream name is the device name w/ a stream char
*/
== NULL)) {
return ('\0'); /* The name strings are unrelated */
}
/*
* See if the potential stream has the same device identifiers
*
* Note that our caller, ListDevices(), has compared
* this pathname length to the buffer length. Oversized
* names were rejected.
*/
return ('\0'); /* Decline to pursue this */
}
return ('\0'); /* Device identifiers don't match */
}
/*
* Return with the stream suffix character
*/
return (*(stream_name + device_len));
} /* ListDevices_StreamCheck() */
/*
* ListDevices()
*
* In response to the -list option, display the frame buffer device
* buffer configuration program appropriate for the type of device.
* If there is some obvious problem with the device or the config
* program, a diagnostic message may be displayed instead of the
* program file name.
*
* Illustrative -list output, assuming Xorg is configured:
*
* Device File Name Device Model Config Program
* ---------------- ------------ --------------
*
* This and the FindConfigurableDevices() function are similar and
* can be maintained together.
*/
/* Entry in a sorted, singly-linked list of potential device names */
typedef struct devent_st {
} dev_ent_t;
static
unsigned int
{
return GFX_DEV_AST;
return GFX_DEV_NFB;
return GFX_DEV_PFB;
return GFX_DEV_KFB;
return GFX_DEV_IFB;
return GFX_DEV_JFB;
return GFX_DEV_FFB;
return GFX_DEV_M64;
} else {
return 0;
}
}
static
void
unsigned int *device_mask) /* bit set for each listed device */
{
/*
*/
exit(1);
}
/*
*/
for (;;) {
/*
* Read the next directory entry
*/
}
break;
}
/*
* Ignore anything that clearly isn't a device name
*/
continue; /* Directories aren't devices */
}
continue; /* Too long for a device pathname */
}
/*
* Create a list entry for this potential device name
*/
PrintError("Insufficient memory, %s",
exit(1);
}
/*
* Insert the new name into the sorted list of names
*/
for (dev_ent_pptr = &dev_list;
;
dev_next = *dev_ent_pptr;
break;
}
}
}
/*
* Display information for each list entry that looks like a device
*/
/*
* Construct the full pathname for this potential device
*
* Note that this pathname length was compared to the
* buffer length in the previous loop. Oversized
* names were rejected.
*/
/*
* Discard this list entry
*/
/*
* See if this file is a device and get its identifications
*/
device_model[0] = '\0';
if (error_code == 0) {
}
if (probe_only == B_TRUE)
continue;
/*
* Determine the "Config Program" field contents
*/
if (error_code != 0) {
if (error_code != EACCES) {
continue; /* Not a convincing device */
}
/* No VISUAL env identifier with which to proceed */
program_field = "device access denied";
} else {
/*
* Get the config program pathname for this device
*/
if (error_code != 0) {
/*
* Provide a diagnostic message
*/
switch (error_code) {
case EINVAL: /* Invalid x_server value */
"X server not known");
break;
case ENOENT: /* Config program not found */
"program not available");
break;
case EACCES: /* User can't access program */
"program access denied";
break;
default: /* Some other mischief */
break;
}
} else {
/*
* Find the simple filename of the config prog
*/
if (program_field == NULL) {
} else {
program_field += 1;
}
}
}
/*
* Check for streams that can be consolidated with this device
*
* It is assumed that the device name list is sorted
* such that all names for a given device are
* adjacent, with the plain device name first and any
* stream-suffixed names following. It's also
* assumed that a stream name is the device name with
* a one-character suffix from the set,
* STREAM_SUFFIX_CHARS.
*/
suffix_punct = '[';
/*
* See if the next list entry has a related stream name
*/
if (suffix_char == '\0') {
break; /* Not a related stream name */
}
/*
* Append this stream suffix character to the substring
*/
suffix_ptr += 2;
suffix_punct = '|';
/*
* Free this now-consolidated stream entry
*/
}
if (suffix_punct != '[') {
/*
* Terminate the non-empty stream suffix char substring
*/
/*
* Append the stream suffix character substring
*/
}
/*
* Display the file & any streams, model, and config prog field
*/
if (!found) {
#ifdef DEBUG_FB /* Show VISUAL environment identifier also */
printf(" -------");
#endif
" Device File Name Device Model Config Program\n"
" ---------------- ------------ --------------\n"));
}
#ifdef DEBUG_FB /* Show VISUAL environment identifier also */
#endif
printf(" %-27.27s %-16.16s %s\n",
}
/*
* If nothing was found then say so (before returning and terminating)
*/
if (!probe_only && !found) {
"No configurable devices found in "
DEVICE_DIR " directory\n"));
}
} /* ListDevices() */
/*
* FindConfigurableDevices()
*
* frame buffer device is found that can be opened and provide a
* VISUAL environment device identifier. The possible return values
* are:
* Zero - Success; at least one device exists and can be accessed
* ENOENT - No frame buffer device was found
* EACCES - Something was found, but the user can't access it
*
* The -gui option will not launch the DCM Tool if this function
* returns a non-zero value.
*
* This and the ListDevices() function are similar and can be
* maintained together.
*/
static
int
FindConfigurableDevices(void)
{
error_code = ENOENT;
/*
* See whether any default device will open and identify itself
*/
if (err_code == 0) {
return (0); /* At least one FB device exists */
}
}
/*
*/
exit(1);
}
/*
*/
for (;;) {
/*
* Read the next directory entry
*/
}
break;
}
/*
* Ignore anything that clearly isn't a device
*/
continue; /* Directories aren't devices */
}
continue; /* Too long for a device pathname */
}
/*
* Construct the full pathname for the device
*/
/*
* See if this file is a frame buffer device
*/
if (err_code == 0) {
error_code = 0;
break; /* At least one FB device exists */
}
}
}
return (error_code);
} /* FindConfigurableDevices() */
/*
* InvokeGUI()
*
* Implement the -gui option:
* -gui Executes the Graphics User Interface program DCMTool
* if it is available.
*
* This is done by invoking:
* (RBAC's exec_attr entry makes that program setuid root.)
*
* If successful, this function does not return. A non-zero exit
* code is returned otherwise.
*/
static
int
InvokeGUI(void)
{
/*
* Make sure the GUI will have at least one device
*
* The error_code returned by FindConfigurableDevices()
* will be EACCES, ENOENT, or zero.
*/
if (error_code != 0) {
if (error_code == EACCES) {
"You do not have access to configure"
" graphics devices on this system.\n"
"You will have access if you log in"
" to the console or you are superuser (root)."));
return (2);
}
"No configurable devices found in "
DEVICE_DIR " directory\n"));
return (1);
}
/*
* Get the pathname of the DCM Tool GUI script
*/
if (error_code != 0) {
if (error_code == ENOENT) {
"GUI not present. Install SUNWdcm package."));
} else {
}
return (1);
}
/* execl() should not return; if it did, it failed */
#ifdef DEBUG_FB
#endif
return (2);
} /* InvokeGUI() */
static
int
{
return 0;
}
printf("Fails to configure xserver to %s, not all graphics devices in the system can be configured to run with this xserver\n",
return 0;
}
return 1;
}
static
void
{
if (xserver_arg == XSERVER_XORG) {
/*
* First check if all the listed devices supports Xorg.
* If not, setting to Xorg will be denied.
*/
return;
}
/*
* If there is a XVR-50, XVR-100, XVR-300, check if efb driver exists
*/
printf("Fails to configure xserver to %s, efb driver is not installed\n",
return;
}
}
system("svccfg -s svc:/application/x11/x11-server setprop options/server=/usr/bin/Xorg");
system("add_drv -n -m '* 0666 root sys' -i \"SUNW,XVR-50 SUNW,XVR-100 SUNW,XVR-300\" efb 2>/dev/null&");
printf("A reboot needs to be performed to complete the reconfiguration to run Xorg\n");
} else {
printf("Fails to switch to efb driver. Please check to see if SUNWefb is installed.\n");
}
} else if (xserver_arg == XSERVER_XSUN) {
int pfb_exists = 0;
/*
* First check if all the listed devices supports Xsun.
* If not, setting to Xsun will be denied.
*/
return;
}
#if OSVER==510
pfb_exists = 1;
}
#else
pfb_exists = 1;
}
#endif
/*
* If there is a XVR-300, check if nfb driver exists
*/
if (device_mask & GFX_DEV_NFB) {
printf("Fails to configure xserver to %s, nfb driver is not installed\n",
return;
}
}
/*
* If there is a XVR-50, XVR-100, check if pfb driver exists
*/
if (device_mask & GFX_DEV_PFB) {
if (pfb_exists == 0) {
printf("Fails to configure xserver to %s, pfb driver is not installed\n",
return;
}
}
system("svccfg -s svc:/application/x11/x11-server setprop options/server=/usr/openwin/bin/Xsun");
}
}
if (pfb_exists) {
}
printf("A reboot needs to be performed to complete the reconfiguration to run Xsun\n");
} else {
}
} /* SetXServer() */
/*
* main() for fbconfig(1M)
*
* Do exactly one of the following, in order of precedence, depending
* on options in the program command line (argv[]):
* * Display fbconfig(1M) help text (-help) along with any
* configuration program help text (-dev, -help) and then
* terminate.
* * Display the installed frame buffer devices and the
* corresponding configuration program for each (-list) and then
* terminate.
* * Become the dcmtool GUI (-gui).
* * Repackage the program argument vector and become the
* appropriate device configuration program (-dev).
* * Report a fatal error and terminate.
*/
int
main(
int argc, /* Program argument count */
char *argv[]) /* Program argument vector */
{
int i; /* argv[] argument vector index */
int n; /* cfg_argv[] argument vector index */
unsigned int device_mask = 0;
/*
* Allocate an argument vector to pass to the device config program
*
* The config program (child) argument vector must be large
* enough to hold:
* * The config program pathname ( 1 pointer )
* * The fbconfig(1M) arguments (argc-1 pointers)
* * A NULL terminator ( 1 pointer )
*/
PrintError("Insufficient memory for new argument vector");
return (1);
}
/*
* Process the fbconfig(1M) program command line arguments
*
* Leave room in the child's argument vector to prepend these
* three (CFG_ARG_1) strings:
* * The pathname of the child config program
* * A -dev option and a default frame buffer name
*/
n = CFG_ARG_1;
/* Look for -help (for which -dev can be a modifier) */
continue; /* Option isn't passed to child */
}
/* Look for a -list option and don't copy it */
continue; /* Option isn't passed to child */
}
/* Look for a -list option and don't copy it */
i++;
if (i < argc) {
}
}
continue; /* Option isn't passed to child */
}
/* Look for a -gui option and don't copy it */
continue; /* Option isn't passed to child */
}
/* Look for -dev and save the full device pathname */
/*
* Check for -dev option errors
*/
i += 1;
if (i >= argc) {
"Option requires a value, -dev"));
return (1);
}
if (dev_opt) {
"Duplicate option, -dev %s"),
argv[i]);
return (1);
}
/*
* Get the fully qualified device pathname
*/
argv[i],
sizeof (device_path_buf));
/*
* Copy the -dev option to the new argument vector
*/
n += 2;
continue;
}
/*
* Copy this string to the arg vector for the config program
*/
n += 1;
}
/*
* Find out which X server is configured (Xsun, Xorg, ...)
*
* If the X server isn't known, the GetConfigProgramPath()
* function can't return a configuration program pathname.
* Options such as -help and -list might still be useful,
* however (and someday -gui will work too).
*/
x_server = IdentifyXServer();
if (x_server == XSERVER_UNKNOWN) {
PrintError("Unable to identify the configured X server");
}
/*
* Try to make sure the frame buffer device pathname is known
*/
if (!dev_opt) {
(void) GetDefaultDevicePathname(&device_path);
}
/*
* If -help was specified or implied, display help text and exit
*
* The -help option is implied iff there is no -list or -gui
* option and no option or argument intended for a device
* configuration program (n > CFG_ARG_1). The -dev option is
* either a modifier for the explicit -help option or is an
* option for the device configuration program.
*/
return (0);
}
/*
* If -list was specified, display the frame buffer devices and exit
*/
if (list_opt) {
return (0);
}
/*
*
*/
if (xserver_opt) {
return (0);
}
/*
* If -gui was specified, try to become the GUI (else exit)
*/
if (gui_opt) {
/*
* Invoke the GUI (w/o returning), else exit unsuccessfully
*/
#if (1) /* ??? Cover for temporarily absent functionality ??? */
if (x_server != XSERVER_XSUN) {
"A GUI interface is available only with the Xsun server");
return (1);
}
#endif
return (InvokeGUI());
}
/*
* Identify and invoke the device configuration program
*
* The default -dev option, if any, should be prepended
* rather than appended to the argument vector. If the
* user-supplied argument vector ends badly (e.g. the last
* option's argument is missing), the child config program
* should be able to diagnose and report the problem
* correctly, without tripping over an appended -dev option.
*/
if ((device_path != NULL) &&
) {
n = 2; /* Index for config program pathname */
if (!dev_opt) {
n = 0; /* Index for config program pathname */
}
cfg_argv[n] = config_prog_path;
CallConfigProgram(&cfg_argv[n]);
} else {
PrintError("Unable to find a default device");
}
return (1); /* Exit unsuccessfully */
} /* main() */
/* End of fbconfig.c */