--- app.h 2008-09-26 02:54:15.000000000 +0200 +++ app.h.new 2009-07-03 21:11:52.000000000 +0200 @@ -58,6 +58,10 @@ void UpdatePid(); bool AuthenticateUser(bool focuspass); + + void InitVirtualKeyboard(); + void OpenVirtualKeyboard(); + void CloseVirtualKeyboard(); static std::string findValidRandomTheme(const std::string& set); static void replaceVariables(std::string& input, @@ -98,6 +102,11 @@ // For testing themes char* testtheme; bool testing; + + // Virtual Keyboard stuff + pid_t KeyboardPID; + char** KeyboardCmd; + int KeyboardArgc; std::string themeName; std::string mcookie; --- app.cpp 2008-09-26 02:54:15.000000000 +0200 +++ app.cpp.new 2009-07-03 22:00:07.000000000 +0200 @@ -135,6 +135,8 @@ #endif int tmp; ServerPID = -1; + KeyboardPID = -1; + KeyboardArgc = -1; testing = false; mcookie = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; daemonmode = false; @@ -186,6 +188,107 @@ } +void App::InitVirtualKeyboard() { + static const int MAX_KEYBOARD_ARGS = 127; + static char* keyboard[MAX_KEYBOARD_ARGS+1] = { NULL }; + string command; + char *argptr; + char *args; + + cout << "Initialize virtual keyboard..." << endl; + + /* Disable virtual keyboard */ + KeyboardPID = -99; + KeyboardCmd = keyboard; + + /* Get the given command from the config file and check if it is empty. + If this is the case the keyboard should stay disabled. */ + command = cfg->getOption("keyboard_cmd"); + if (command == "") + return; + + args = new char[command.length()+1]; + strcpy(args, command.c_str()); + /* Make sure we find a \0 */ + args[command.length()] = '\0'; + + /* Parse the given string command into an array of strings */ + KeyboardArgc = 0; + argptr = args; + while (*argptr != '\0') { + /* Strip spaces and zero them */ + while (*argptr == ' ' || *argptr == '\t') { + *argptr = '\0'; + argptr++; + } + + /* We are at the end of the string */ + if (*argptr == '\0') + break; + + /* Ok we have a new string here, so set the next arg of the array. + If too many arguments are specified, remove them all to make + sure the keyboard starts. */ + keyboard[KeyboardArgc] = argptr; + KeyboardArgc++; + + if (KeyboardArgc >= MAX_KEYBOARD_ARGS) { + KeyboardArgc = 1; + break; + } + + /* Continue up to the next space */ + while (*argptr != ' ' && *argptr != '\t' && *argptr != '\0') { + argptr++; + } + } + + /* Enable virtual keyboard */ + if (KeyboardArgc > 0) { + cout << "Enabling virtual keyboard..." << endl; + KeyboardPID = -1; + } +} + +void App::OpenVirtualKeyboard() { + /* Initialize virtual keyboard command if requested */ + if (KeyboardArgc < 0) + InitVirtualKeyboard(); + + if(KeyboardPID == -1) { + cout << "Starting virtual keyboard..." << endl; + + KeyboardPID = fork (); + if(KeyboardPID == 0) { + /* This is the child process. Execute the shell command. */ + execvp(KeyboardCmd[0], KeyboardCmd); + cerr << APPNAME << "Executing the virtual keyboard failed!" << endl; + _exit (EXIT_FAILURE); + } else if (KeyboardPID < 0) { + cerr << APPNAME << "Spawning a new process for the virtual keyboard failed!" << endl; + } + cout << "DEBUG: Virtual keyboard is OK!" << endl; + } +} + +void App::CloseVirtualKeyboard() { + int status; + + if(KeyboardPID != -1) { + cout << "Terminating the virtual keyboard..." << endl; + status = kill(KeyboardPID, SIGTERM); + if(status != 0) { + cerr << APPNAME << "Terminating the virtual keyboard failed!" << endl; + return; + } + + /* This is the parent process. Wait for the child to complete. */ + if (waitpid (KeyboardPID, &status, 0) != KeyboardPID) { + cerr << APPNAME << "Waiting for virtual keyboard failed!" << endl; + } + } + KeyboardPID = -1; +} void App::Run() { DisplayName = DISPLAY; @@ -349,6 +452,9 @@ // Show panel LoginPanel->OpenPanel(); + + // Start virtual keyboard + OpenVirtualKeyboard(); } LoginPanel->Reset(); @@ -374,6 +480,10 @@ if (testing) { Action = Panel::Exit; } + + // Close the virtual keyboard + CloseVirtualKeyboard(); + panelclosed = 1; LoginPanel->ClosePanel();