ckb-next  v0.2.8 at branch master
ckb-next driver for corsair devices
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
main.cpp File Reference
#include "mainwindow.h"
#include <QApplication>
#include <QDateTime>
#include <QSharedMemory>
#include <QCommandLineParser>
#include <cstring>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
+ Include dependency graph for main.cpp:

Go to the source code of this file.

Macros

#define SHMEM_SIZE   128 * 1024
 
#define SHMEM_SIZE_V015   16
 

Enumerations

enum  CommandLineParseResults {
  CommandLineOK, CommandLineError, CommandLineVersionRequested, CommandLineHelpRequested,
  CommandLineClose, CommandLineBackground
}
 

Functions

QSharedMemory appShare ("ckb")
 
CommandLineParseResults parseCommandLine (QCommandLineParser &parser, QString *errorMessage)
 parseCommandLine - Setup options and parse command line arguments. More...
 
static bool pidActive (const QStringList &lines)
 
static bool isRunning (const char *command)
 
int main (int argc, char *argv[])
 

Macro Definition Documentation

#define SHMEM_SIZE   128 * 1024

Definition at line 20 of file main.cpp.

Referenced by isRunning().

#define SHMEM_SIZE_V015   16

Definition at line 21 of file main.cpp.

Referenced by isRunning().

Enumeration Type Documentation

Enumerator
CommandLineOK 
CommandLineError 
CommandLineVersionRequested 
CommandLineHelpRequested 
CommandLineClose 
CommandLineBackground 

Definition at line 24 of file main.cpp.

Function Documentation

QSharedMemory appShare ( "ckb"  )

Referenced by isRunning().

+ Here is the caller graph for this function:

static bool isRunning ( const char *  command)
static

Definition at line 109 of file main.cpp.

References appShare(), pidActive(), SHMEM_SIZE, and SHMEM_SIZE_V015.

Referenced by main().

109  {
110  // Try to create shared memory (if successful, application was not already running)
111  if(!appShare.create(SHMEM_SIZE) || !appShare.lock()){
112  // Lock existing shared memory
113  if(!appShare.attach() || !appShare.lock())
114  return true;
115  bool running = false;
116  if(appShare.size() == SHMEM_SIZE_V015){
117  // Old shmem - no PID listed so assume the process is running, and print the command directly to the buffer
118  if(command){
119  void* data = appShare.data();
120  snprintf((char*)data, SHMEM_SIZE_V015, "%s", command);
121  }
122  running = true;
123  } else {
124  // New shmem. Scan the contents of the shared memory for a PID
125  QStringList lines = QString((const char*)appShare.constData()).split("\n");
126  if(pidActive(lines)){
127  running = true;
128  // Append the command
129  if(command){
130  lines.append(QString("Option ") + command);
131  QByteArray newMem = lines.join("\n").left(SHMEM_SIZE).toLatin1();
132  // Copy the NUL byte as well as the string
133  memcpy(appShare.data(), newMem.constData(), newMem.length() + 1);
134  }
135  }
136  }
137  if(running){
138  appShare.unlock();
139  return true;
140  }
141  }
142  // Not already running. Initialize the shared memory with our PID
143  snprintf((char*)appShare.data(), appShare.size(), "PID %ld", (long)getpid());
144  appShare.unlock();
145  return false;
146 }
QSharedMemory appShare("ckb")
#define SHMEM_SIZE_V015
Definition: main.cpp:21
#define SHMEM_SIZE
Definition: main.cpp:20
static bool pidActive(const QStringList &lines)
Definition: main.cpp:92

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int main ( int  argc,
char *  argv[] 
)

Definition at line 148 of file main.cpp.

References CommandLineBackground, CommandLineClose, CommandLineError, CommandLineHelpRequested, CommandLineOK, CommandLineVersionRequested, disableAppNap(), isRunning(), and parseCommandLine().

148  {
149  // Setup main application
150  QApplication a(argc, argv);
151 
152  // Setup names and versions
153  QCoreApplication::setOrganizationName("ckb");
154  QCoreApplication::setApplicationVersion(CKB_VERSION_STR);
155  QCoreApplication::setApplicationName("ckb");
156 
157  // Setup argument parser
158  QCommandLineParser parser;
159  QString errorMessage;
160  parser.setApplicationDescription("Open Source Corsair Input Device Driver for Linux and OSX.");
161  bool background = 0;
162 
163  // Although the daemon runs as root, the GUI needn't and shouldn't be, as it has the potential to corrupt settings data.
164  if(getuid() == 0){
165  printf("The ckb GUI should not be run as root.\n");
166  return 0;
167  }
168 
169  // Seed the RNG for UsbIds
170  qsrand(QDateTime::currentMSecsSinceEpoch());
171 #ifdef Q_OS_MACX
172  disableAppNap();
173 
174  FILE *fp = fopen("/tmp/ckb", "w");
175  fprintf(fp, "%d", getpid());
176  fclose(fp);
177 #endif
178 #if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0)
179  // Enable HiDPI support
180  qApp->setAttribute(Qt::AA_UseHighDpiPixmaps);
181 #endif
182 
183  // Parse arguments
184  switch (parseCommandLine(parser, &errorMessage)) {
185  case CommandLineOK:
186  // If launched with no argument
187  break;
188  case CommandLineError:
189  fputs(qPrintable(errorMessage), stderr);
190  fputs("\n\n", stderr);
191  fputs(qPrintable(parser.helpText()), stderr);
192  return 1;
194  // If launched with --version, print version info and then quit
195  printf("%s %s\n", qPrintable(QCoreApplication::applicationName()),
196  qPrintable(QCoreApplication::applicationVersion()));
197  return 0;
199  // If launched with --help, print help and then quit
200  parser.showHelp();
201  return 0;
202  case CommandLineClose:
203  // If launched with --close, kill existing app
204  if (isRunning("Close"))
205  printf("Asking existing instance to close.\n");
206  else
207  printf("ckb is not running.\n");
208  return 0;
210  // If launched with --background, launch in background
211  background = 1;
212  break;
213  }
214 
215  // Launch in background if requested, or if re-launching a previous session
216  if(qApp->isSessionRestored())
217  background = 1;
218  if(isRunning(background ? 0 : "Open")){
219  printf("ckb is already running. Exiting.\n");
220  return 0;
221  }
222  MainWindow w;
223  if(!background)
224  w.show();
225 
226  return a.exec();
227 }
void disableAppNap()
Definition: media_mac.m:34
static bool isRunning(const char *command)
Definition: main.cpp:109
CommandLineParseResults parseCommandLine(QCommandLineParser &parser, QString *errorMessage)
parseCommandLine - Setup options and parse command line arguments.
Definition: main.cpp:41

+ Here is the call graph for this function:

CommandLineParseResults parseCommandLine ( QCommandLineParser &  parser,
QString *  errorMessage 
)
Parameters
parserparser instance to use for parse the arguments
errorMessageargument parse error message
Returns
integer, representing the requested argument

Definition at line 41 of file main.cpp.

References CommandLineBackground, CommandLineClose, CommandLineError, CommandLineHelpRequested, CommandLineOK, and CommandLineVersionRequested.

Referenced by main().

41  {
42  // setup parser to interpret -abc as -a -b -c
43  parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsCompactedShortOptions);
44 
45  /* add command line options */
46  // add -v, --version
47  const QCommandLineOption versionOption = parser.addVersionOption();
48  // add -h, --help (/? on windows)
49  const QCommandLineOption helpOption = parser.addHelpOption();
50  // add -b, --background
51  const QCommandLineOption backgroundOption(QStringList() << "b" << "background",
52  "Starts in background, without displaying the main window.");
53  parser.addOption(backgroundOption);
54  // add -c, --close
55  const QCommandLineOption closeOption(QStringList() << "c" << "close",
56  "Causes already running instance (if any) to exit.");
57  parser.addOption(closeOption);
58 
59  /* parse arguments */
60  if (!parser.parse(QCoreApplication::arguments())) {
61  // set error, if there already are some
62  *errorMessage = parser.errorText();
63  return CommandLineError;
64  }
65 
66  /* return requested operation/setup */
67  if (parser.isSet(versionOption)) {
68  // print version and exit
70  }
71 
72  if (parser.isSet(helpOption)) {
73  // print help and exit
75  }
76 
77  if (parser.isSet(backgroundOption)) {
78  // open application in background
79  return CommandLineBackground;
80  }
81 
82  if (parser.isSet(closeOption)) {
83  // close already running application instances, if any
84  return CommandLineClose;
85  }
86 
87  /* no explicit argument was passed */
88  return CommandLineOK;
89 };

+ Here is the caller graph for this function:

static bool pidActive ( const QStringList &  lines)
static

Definition at line 92 of file main.cpp.

Referenced by isRunning().

92  {
93  foreach(const QString& line, lines){
94  if(line.startsWith("PID ")){
95  bool ok;
96  pid_t pid;
97  // Valid PID found?
98  if((pid = line.split(" ")[1].toLong(&ok)) > 0 && ok){
99  // kill -0 does nothing to the application, but checks if it's running
100  return (kill(pid, 0) == 0 || errno != ESRCH);
101  }
102  }
103  }
104  // If the PID wasn't listed in the shmem, assume it is running
105  return true;
106 }

+ Here is the caller graph for this function: