/*
* Copyright (c) 2011-2013, The Bumblebee Project
* Author: Joaquín Ignacio Aramendía samsagax@gmail.com
* Author: Jaron Viëtor AKA "Thulinma" <jaron@vietors.com>
*
* This file is part of Bumblebee.
*
* Bumblebee is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Bumblebee is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Bumblebee. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* bbconfig.c: Bumblebee configuration file handler
*/
#include <errno.h>
#include <ctype.h>
#include <assert.h>
#include <unistd.h>
#include <getopt.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "bbconfig.h"
#include "bblogger.h"
#include "module.h"
/* config values for PM methods, edit bb_pm_method in bbconfig.h as well! */
const char *bb_pm_method_string[PM_METHODS_COUNT] = {
"none",
"auto",
/* the below names are used in switch/switching.c */
"bbswitch",
"switcheroo",
};
struct bb_status_struct bb_status;
struct bb_config_struct bb_config;
/**
* Returns a gboolean from true/false strings
* @return TRUE if str="true", FALSE otherwise
*/
gboolean bb_bool_from_string(char* str) {
if (strcmp(str, "true") == 0) {
return TRUE;
} else {
return FALSE;
}
}
/**
* Sets a value for configstring and free() existing values
* @param configstring A pointer to the destination
* @param newvalue A string to be set
*/
void free_and_set_value(char **configstring, char *newvalue) {
if (*configstring != NULL) {
free(*configstring);
}
*configstring = newvalue;
}
/**
* Takes a pointer to a char pointer, resizing and copying the string value to it.
*/
void set_string_value(char ** configstring, char * newvalue) {
//free the string if it already existed.
if (*configstring != 0) {
free(*configstring);
*configstring = 0;
}
//malloc a new buffer of strlen, plus one for the terminating null byte
*configstring = malloc(strlen(newvalue) + 1);
if (*configstring != 0) {
//copy the string if successful
strcpy(*configstring, newvalue);
} else {
//something, somewhere, went terribly wrong
bb_log(LOG_ERR, "Could not allocate %i bytes for new config value, setting to empty string!\n", strlen(newvalue) + 1);
*configstring = malloc(1);
if (*configstring == 0) {
bb_log(LOG_ERR, "FATAL: Could not allocate even 1 byte for config value!\n");
bb_log(LOG_ERR, "Aborting - cannot continue without stable config!\n");
exit(1);
}
(*configstring)[0] = 0;
}
}//set_string_value
/**
* Converts a string to the internal representation of a PM method
* @param value The string to be converted
* @return An index in the PM methods array
*/
enum bb_pm_method bb_pm_method_from_string(char *value) {
/* loop backwards through all possible values. If no valid value is found,
* assume the first element ("none") */
enum bb_pm_method method_index = PM_METHODS_COUNT;
while (method_index > 0) {
if (strcmp(value, bb_pm_method_string[--method_index]) == 0) {
break;
}
}
return method_index;
}
/**
* Prints a usage message and exits with given exit code
* @param exit_val The exit code to be passed to exit(). If non-zero, an hint is
* printed to use --help. Otherwise a help message is printed
*/
void print_usage(int exit_val) {
FILE *out = stdout;
int is_optirun = bb_status.runmode == BB_RUN_APP ||
bb_status.runmode == BB_RUN_STATUS;
if (exit_val != EXIT_SUCCESS) {
fprintf(stderr, "Try `%s --help' for more information.\n",
bb_status.program_name);
exit(exit_val);
}
if (is_optirun) {
printf("Usage: %s [OPTION]... command [command options...]\n",
bb_status.program_name);
fputs("Run an application using the discrete video card.\n", out);
} else {
printf("Usage: %s [OPTION]...\n", bb_status.program_name);
fputs("Daemon for controlling the discrete nVidia video card on Optimus"
" systems.\n", out);
}
printf("\n");
if (is_optirun) {
//client-only options
fputs("\
--failsafe run a program even if the nvidia card is unavailable\n\
--no-failsafe do not run a program if the nvidia card is unavailable\n\
--no-xorg do not start secondary X server (implies -b none)\n\
-b, --bridge METHOD acceleration/displaying bridge to use. Valid values\n\
are auto, virtualgl and primus. The --vgl-* options\n\
only make sense when using the virtualgl bridge,\n\
while the --primus-* options apply only when using\n\
the primus bridge.\n\
Additionally, value none is recognized, and its effect\n\
is to add paths to driver libraries to LD_LIBRARY_PATH\n\
(useful for nvidia-settings and CUDA applications)\n\
-c, --vgl-compress METHOD image compression or transport to use with \n\
VirtualGL. Valid values for METHOD are proxy,\n\
jpeg, rgb, xv and yuv. Changing this setting\n\
may affect performance, CPU usage and image\n\
quality\n\
--vgl-options OPTS a space-separated list of command options to be\n\
passed to vglrun. Useful for debugging virtualgl\n\
by passing options to it like +tr. These OPTS\n\
override the settings from optirun so be careful\n\
with setting it\n\
--primus-ldpath PATH a colon-separated list of paths which are searched\n\
for the primus libGL.so.1\n",
out);
} else {
//server-only options
fputs("\
-D, --daemon run daemonized (backgrounded). Implies --use-syslog\n\
-x, --xconf FILE xorg.conf file to use\n\
--xconfdir DIR xorg.conf.d directory to use\n\
-g, --group GROUP allow GROUP to communicate with the daemon\n\
--driver DRIVER the driver to use for the nvidia card. Valid values\n\
are nouveau and nvidia. This option also effects\n\
the driver section that will be used from the\n\
configuration file\n\
-m, --module-path PATH ModulePath to use for Xorg (only useful for nvidia)\n\
-k, --driver-module NAME Name of kernel module to be loaded if different\n\
from the driver\n\
--pm-method METHOD method to use for disabling the discrete video card,\n\
valid values are auto, bbswitch, switcheroo and\n\
none. auto selects a sensible method,\n\
bbswitch (kernel module) is available for nvidia\n\
and nouveau drivers,\n\
switcheroo (vga_switcheroo) is usually for\n\
nouveau and radeon drivers and none disables PM\n\
completely\n",
out);
#ifdef WITH_PIDFILE
fputs("\
--pidfile FILE file in which the process ID is written. An empty\n\
value disables cretion of a pidfile. Note that\n\
the file must not already exist\n\
--use-syslog redirect all messages to syslog\n", out);
#endif
}
/* common options */
fputs("\
-q, --quiet, --silent supresses all logging messages\n\
-v, --verbose increase the verbosity level of log messages. It\n\