Fix tsak not working on new libudev versions

Fix kicker Xinerama hiding
Fix potential displayconfig lockup
pull/2/head
Timothy Pearson 12 years ago
parent 3e5e79fb21
commit 167c4cbea6

@ -740,7 +740,7 @@ void KDisplayConfig::setRealResolutionSliderValue(int index) {
/**** KDisplayConfig ****/ /**** KDisplayConfig ****/
KDisplayConfig::KDisplayConfig(TQWidget *parent, const char *name, const TQStringList &) KDisplayConfig::KDisplayConfig(TQWidget *parent, const char *name, const TQStringList &)
: KCModule(KDisplayCFactory::instance(), parent, name), iccTab(0), m_randrsimple(0), activeProfileName(""), m_gammaApplyTimer(0) : KCModule(KDisplayCFactory::instance(), parent, name), iccTab(0), numberOfProfiles(0), numberOfScreens(0), m_randrsimple(0), activeProfileName(""), m_gammaApplyTimer(0)
{ {
TDEHardwareDevices *hwdevices = KGlobal::hardwareDevices(); TDEHardwareDevices *hwdevices = KGlobal::hardwareDevices();
connect(hwdevices, TQT_SIGNAL(hardwareUpdated(TDEGenericDevice*)), this, TQT_SLOT(deviceChanged(TDEGenericDevice*))); connect(hwdevices, TQT_SIGNAL(hardwareUpdated(TDEGenericDevice*)), this, TQT_SLOT(deviceChanged(TDEGenericDevice*)));
@ -1707,6 +1707,14 @@ void KDisplayConfig::createHotplugRulesGrid() {
connect(button, TQT_SIGNAL(clicked()), this, TQT_SLOT(changed())); connect(button, TQT_SIGNAL(clicked()), this, TQT_SLOT(changed()));
profileRulesGrid->addMultiCellWidget(button, i+2, i+2, 0, numberOfScreens+2); profileRulesGrid->addMultiCellWidget(button, i+2, i+2, 0, numberOfScreens+2);
button->show(); button->show();
if (getuid() == 0) {
// FIXME
label = new TQLabel(base->profileRulesGridWidget, "<ignore>");
label->setText(i18n("NOTE: Hotplug support for the graphical login manager is only partly implemented!"));
profileRulesGrid->addMultiCellWidget(label, i+3, i+3, 0, numberOfScreens+2);
label->show();
}
} }
void KDisplayConfig::addNewProfileRule() { void KDisplayConfig::addNewProfileRule() {
@ -1946,7 +1954,12 @@ void KDisplayConfig::load(bool useDefaults )
base->gammaTargetSelectDD->setCurrentItem(4); base->gammaTargetSelectDD->setCurrentItem(4);
gammaTargetChanged(4); gammaTargetChanged(4);
if (getuid() != 0) {
currentHotplugRules = m_randrsimple->getHotplugRules(locateLocal("config", "/", true)); currentHotplugRules = m_randrsimple->getHotplugRules(locateLocal("config", "/", true));
}
else {
currentHotplugRules = m_randrsimple->getHotplugRules(KDE_CONFDIR);
}
createHotplugRulesGrid(); createHotplugRulesGrid();
emit changed(useDefaults); emit changed(useDefaults);

@ -16,6 +16,10 @@
//crashes (e.g. because it's set to multiple wallpapers and //crashes (e.g. because it's set to multiple wallpapers and
//some image will be corrupted). //some image will be corrupted).
#define protected public
#include <tqwidget.h>
#undef protected
#include <config.h> #include <config.h>
#include <execinfo.h> #include <execinfo.h>
@ -220,7 +224,8 @@ LockProcess::LockProcess()
m_mousePrevX(0), m_mousePrevX(0),
m_mousePrevY(0), m_mousePrevY(0),
m_dialogPrevX(0), m_dialogPrevX(0),
m_dialogPrevY(0) m_dialogPrevY(0),
m_maskWidget(NULL)
{ {
#ifdef KEEP_MOUSE_UNGRABBED #ifdef KEEP_MOUSE_UNGRABBED
setNFlags(WX11DisableMove|WX11DisableClose|WX11DisableShade|WX11DisableMinimize|WX11DisableMaximize); setNFlags(WX11DisableMove|WX11DisableClose|WX11DisableShade|WX11DisableMinimize|WX11DisableMaximize);
@ -232,15 +237,8 @@ LockProcess::LockProcess()
kapp->installX11EventFilter(this); kapp->installX11EventFilter(this);
mForceContinualLockDisplayTimer = new TQTimer( this ); mForceContinualLockDisplayTimer = new TQTimer( this );
connect( mForceContinualLockDisplayTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(displayLockDialogIfNeeded()) );
mHackDelayStartupTimer = new TQTimer( this ); mHackDelayStartupTimer = new TQTimer( this );
connect( mHackDelayStartupTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(closeDialogAndStartHack()) );
mEnsureVRootWindowSecurityTimer = new TQTimer( this ); mEnsureVRootWindowSecurityTimer = new TQTimer( this );
connect( mEnsureVRootWindowSecurityTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(repaintRootWindowIfNeeded()) );
connect(tqApp, TQT_SIGNAL(mouseInteraction(XEvent *)), TQT_SLOT(slotMouseActivity(XEvent *)));
// Try to get the root pixmap // Try to get the root pixmap
if (!m_rootPixmap) m_rootPixmap = new KRootPixmap(this); if (!m_rootPixmap) m_rootPixmap = new KRootPixmap(this);
@ -248,18 +246,14 @@ LockProcess::LockProcess()
m_rootPixmap->setCustomPainting(true); m_rootPixmap->setCustomPainting(true);
m_rootPixmap->start(); m_rootPixmap->start();
// Get root window size // Get root window attributes
XWindowAttributes rootAttr; XWindowAttributes rootAttr;
XGetWindowAttributes(tqt_xdisplay(), RootWindow(tqt_xdisplay(), XGetWindowAttributes(tqt_xdisplay(), RootWindow(tqt_xdisplay(), tqt_xscreen()), &rootAttr);
tqt_xscreen()), &rootAttr);
mRootWidth = rootAttr.width;
mRootHeight = rootAttr.height;
{ // trigger creation of QToolTipManager, it does XSelectInput() on the root window { // trigger creation of QToolTipManager, it does XSelectInput() on the root window
TQWidget w; TQWidget w;
TQToolTip::add( &w, "foo" ); TQToolTip::add( &w, "foo" );
} }
XSelectInput( tqt_xdisplay(), tqt_xrootwin(), XSelectInput( tqt_xdisplay(), tqt_xrootwin(), SubstructureNotifyMask | rootAttr.your_event_mask );
SubstructureNotifyMask | rootAttr.your_event_mask );
// Add non-TDE path // Add non-TDE path
KGlobal::dirs()->addResourceType("scrsav", KGlobal::dirs()->addResourceType("scrsav",
@ -282,11 +276,6 @@ LockProcess::LockProcess()
gXA_VROOT = XInternAtom (tqt_xdisplay(), "__SWM_VROOT", False); gXA_VROOT = XInternAtom (tqt_xdisplay(), "__SWM_VROOT", False);
gXA_SCREENSAVER_VERSION = XInternAtom (tqt_xdisplay(), "_SCREENSAVER_VERSION", False); gXA_SCREENSAVER_VERSION = XInternAtom (tqt_xdisplay(), "_SCREENSAVER_VERSION", False);
connect(&mHackProc, TQT_SIGNAL(processExited(KProcess *)),
TQT_SLOT(hackExited(KProcess *)));
connect(&mSuspendTimer, TQT_SIGNAL(timeout()), TQT_SLOT(suspend()));
TQStringList dmopt = TQStringList dmopt =
TQStringList::split(TQChar(','), TQStringList::split(TQChar(','),
TQString::fromLatin1( ::getenv( "XDM_MANAGED" ))); TQString::fromLatin1( ::getenv( "XDM_MANAGED" )));
@ -294,25 +283,6 @@ LockProcess::LockProcess()
if ((*it).startsWith("method=")) if ((*it).startsWith("method="))
mMethod = (*it).mid(7); mMethod = (*it).mid(7);
#ifdef HAVE_DPMS
if (mDPMSDepend) {
BOOL on;
CARD16 state;
DPMSInfo(tqt_xdisplay(), &state, &on);
if (on)
{
connect(&mCheckDPMS, TQT_SIGNAL(timeout()), TQT_SLOT(checkDPMSActive()));
// we can save CPU if we stop it as quickly as possible
// but we waste CPU if we check too often -> so take 10s
mCheckDPMS.start(10000);
}
}
#endif
#if (TQT_VERSION-0 >= 0x030200) // XRANDR support
connect( kapp->desktop(), TQT_SIGNAL( resized( int )), TQT_SLOT( desktopResized()));
#endif
#ifdef KEEP_MOUSE_UNGRABBED #ifdef KEEP_MOUSE_UNGRABBED
setEnabled(false); setEnabled(false);
#endif #endif
@ -375,6 +345,39 @@ LockProcess::~LockProcess()
// //
void LockProcess::init(bool child, bool useBlankOnly) void LockProcess::init(bool child, bool useBlankOnly)
{ {
// Get root window size
XWindowAttributes rootAttr;
XGetWindowAttributes(tqt_xdisplay(), RootWindow(tqt_xdisplay(), tqt_xscreen()), &rootAttr);
mRootWidth = rootAttr.width;
mRootHeight = rootAttr.height;
// Connect all signals
connect( mForceContinualLockDisplayTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(displayLockDialogIfNeeded()) );
connect( mHackDelayStartupTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(closeDialogAndStartHack()) );
connect( mEnsureVRootWindowSecurityTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(repaintRootWindowIfNeeded()) );
connect(tqApp, TQT_SIGNAL(mouseInteraction(XEvent *)), TQT_SLOT(slotMouseActivity(XEvent *)));
connect(&mHackProc, TQT_SIGNAL(processExited(KProcess *)), TQT_SLOT(hackExited(KProcess *)));
connect(&mSuspendTimer, TQT_SIGNAL(timeout()), TQT_SLOT(suspend()));
#ifdef HAVE_DPMS
if (mDPMSDepend) {
BOOL on;
CARD16 state;
DPMSInfo(tqt_xdisplay(), &state, &on);
if (on)
{
connect(&mCheckDPMS, TQT_SIGNAL(timeout()), TQT_SLOT(checkDPMSActive()));
// we can save CPU if we stop it as quickly as possible
// but we waste CPU if we check too often -> so take 10s
mCheckDPMS.start(10000);
}
}
#endif
#if (TQT_VERSION-0 >= 0x030200) // XRANDR support
connect( kapp->desktop(), TQT_SIGNAL( resized( int )), TQT_SLOT( desktopResized()));
#endif
if (!trinity_desktop_lock_use_system_modal_dialogs) { if (!trinity_desktop_lock_use_system_modal_dialogs) {
setWFlags((WFlags)WX11BypassWM); setWFlags((WFlags)WX11BypassWM);
} }
@ -446,6 +449,11 @@ void LockProcess::timerEvent(TQTimerEvent *ev)
} }
} }
void LockProcess::resizeEvent(TQResizeEvent *)
{
//
}
void LockProcess::setupPipe() void LockProcess::setupPipe()
{ {
/* Create the FIFOs if they do not exist */ /* Create the FIFOs if they do not exist */
@ -1018,20 +1026,55 @@ void LockProcess::createSaverWindow()
void LockProcess::desktopResized() void LockProcess::desktopResized()
{ {
// Get root window size
XWindowAttributes rootAttr;
XGetWindowAttributes(tqt_xdisplay(), RootWindow(tqt_xdisplay(), tqt_xscreen()), &rootAttr);
if ((rootAttr.width == mRootWidth) && (rootAttr.height == mRootHeight)) {
return;
}
mRootWidth = rootAttr.width;
mRootHeight = rootAttr.height;
mBusy = true; mBusy = true;
mHackDelayStartupTimer->stop(); mHackDelayStartupTimer->stop();
stopHack(); stopHack();
DISABLE_CONTINUOUS_LOCKDLG_DISPLAY DISABLE_CONTINUOUS_LOCKDLG_DISPLAY
mResizingDesktopLock = true; mResizingDesktopLock = true;
// Get root window size backingPixmap = TQPixmap();
XWindowAttributes rootAttr;
XGetWindowAttributes(tqt_xdisplay(), RootWindow(tqt_xdisplay(), tqt_xscreen()), &rootAttr); if (trinity_desktop_lock_use_system_modal_dialogs) {
mRootWidth = rootAttr.width; // Temporarily hide the entire screen with a new override redirect window
mRootHeight = rootAttr.height; if (m_maskWidget) {
m_maskWidget->setGeometry(0, 0, mRootWidth, mRootHeight);
}
else {
int flags = CWOverrideRedirect;
Visual* visual = CopyFromParent;
XSetWindowAttributes attrs;
attrs.override_redirect = 1;
Window maskWindow = XCreateWindow(x11Display(), RootWindow( x11Display(), x11Screen()), 0, 0, mRootWidth, mRootHeight, 0, x11Depth(), InputOutput, visual, flags, &attrs);
m_maskWidget = new TQWidget();
m_maskWidget->create(maskWindow);
m_maskWidget->setBackgroundColor(TQt::black);
m_maskWidget->erase();
m_maskWidget->show();
}
XSync(tqt_xdisplay(), False);
if (mEnsureScreenHiddenTimer) {
mEnsureScreenHiddenTimer->stop();
}
else {
mEnsureScreenHiddenTimer = new TQTimer( this );
connect( mEnsureScreenHiddenTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotForcePaintBackground()) );
}
mEnsureScreenHiddenTimer->start(DESKTOP_WALLPAPER_OBTAIN_TIMEOUT_MS, true);
}
// Resize the background widget // Resize the background widget
setGeometry(0, 0, mRootWidth, mRootHeight); setGeometry(0, 0, mRootWidth, mRootHeight);
XSync(tqt_xdisplay(), False);
// Black out the background widget to hide ugly resize tiling artifacts // Black out the background widget to hide ugly resize tiling artifacts
setBackgroundColor(black); setBackgroundColor(black);
@ -1048,7 +1091,9 @@ void LockProcess::desktopResized()
void LockProcess::doDesktopResizeFinish() void LockProcess::doDesktopResizeFinish()
{ {
while (mDialogControlLock == true) usleep(100000); while (mDialogControlLock == true) {
usleep(100000);
}
mDialogControlLock = true; mDialogControlLock = true;
if (closeCurrentWindow()) { if (closeCurrentWindow()) {
TQTimer::singleShot( 0, this, SLOT(doDesktopResizeFinish()) ); TQTimer::singleShot( 0, this, SLOT(doDesktopResizeFinish()) );
@ -1058,7 +1103,7 @@ void LockProcess::doDesktopResizeFinish()
mDialogControlLock = false; mDialogControlLock = false;
// Restart the hack as the window size is now different // Restart the hack as the window size is now different
if (trinity_desktop_lock_delay_screensaver_start && trinity_desktop_lock_forced && trinity_desktop_lock_use_system_modal_dialogs) { if (trinity_desktop_lock_delay_screensaver_start && trinity_desktop_lock_use_system_modal_dialogs) {
ENABLE_CONTINUOUS_LOCKDLG_DISPLAY ENABLE_CONTINUOUS_LOCKDLG_DISPLAY
if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE); if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE);
} }
@ -1934,6 +1979,13 @@ void LockProcess::slotPaintBackground(const TQPixmap &rpm)
connect( mEnsureScreenHiddenTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotForcePaintBackground()) ); connect( mEnsureScreenHiddenTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotForcePaintBackground()) );
} }
// Only remove the mask widget once the resize is 100% complete!
if (m_maskWidget) {
delete m_maskWidget;
m_maskWidget = NULL;
XSync(tqt_xdisplay(), False);
}
TQPixmap pm = rpm; TQPixmap pm = rpm;
if (TQPaintDevice::x11AppDepth() == 32) { if (TQPaintDevice::x11AppDepth() == 32) {
@ -2107,8 +2159,9 @@ bool LockProcess::x11Event(XEvent *event)
break; break;
case ConfigureNotify: // from SubstructureNotifyMask on the root window case ConfigureNotify: // from SubstructureNotifyMask on the root window
if(event->xconfigure.event == tqt_xrootwin()) if(event->xconfigure.event == tqt_xrootwin()) {
stayOnTop(); stayOnTop();
}
for( TQValueList< VkbdWindow >::Iterator it = mVkbdWindows.begin(); for( TQValueList< VkbdWindow >::Iterator it = mVkbdWindows.begin();
it != mVkbdWindows.end(); it != mVkbdWindows.end();
++it ) { ++it ) {

@ -83,6 +83,7 @@ public slots:
protected: protected:
virtual bool x11Event(XEvent *); virtual bool x11Event(XEvent *);
virtual void timerEvent(TQTimerEvent *); virtual void timerEvent(TQTimerEvent *);
virtual void resizeEvent(TQResizeEvent *);
private slots: private slots:
void hackExited(KProcess *); void hackExited(KProcess *);
@ -209,6 +210,8 @@ private:
int m_mousePrevY; int m_mousePrevY;
int m_dialogPrevX; int m_dialogPrevX;
int m_dialogPrevY; int m_dialogPrevY;
TQWidget* m_maskWidget;
}; };
#endif #endif

@ -2034,7 +2034,6 @@ TQRect ExtensionContainer::initialGeometry(KPanelExtension::Position p,
// Forcibly hide // Forcibly hide
autoHidden = true; autoHidden = true;
userHidden = Unhidden; userHidden = Unhidden;
XineramaScreen = kapp->desktop()->screenNumber(const_cast<ExtensionContainer*>(this));
} }
/*kdDebug(1210) << "initialGeometry() Computing geometry for " << name() << /*kdDebug(1210) << "initialGeometry() Computing geometry for " << name() <<

@ -64,6 +64,7 @@ int main(int argc, char **argv)
// Load up user specific display settings // Load up user specific display settings
KRandrSimpleAPI *randrsimple = new KRandrSimpleAPI(); KRandrSimpleAPI *randrsimple = new KRandrSimpleAPI();
randrsimple->applyDisplayConfiguration("", locateLocal("config", "/", true)); randrsimple->applyDisplayConfiguration("", locateLocal("config", "/", true));
randrsimple->applyHotplugRules(locateLocal("config", "/", true));
delete randrsimple; delete randrsimple;
#endif #endif

@ -279,6 +279,7 @@ kg_main( const char *argv0 )
#ifdef WITH_XRANDR #ifdef WITH_XRANDR
KRandrSimpleAPI *randrsimple = new KRandrSimpleAPI(); KRandrSimpleAPI *randrsimple = new KRandrSimpleAPI();
TQPoint primaryScreenPosition = randrsimple->applyDisplayConfiguration("", KDE_CONFDIR); TQPoint primaryScreenPosition = randrsimple->applyDisplayConfiguration("", KDE_CONFDIR);
randrsimple->applyHotplugRules(KDE_CONFDIR);
delete randrsimple; delete randrsimple;
#endif #endif

@ -1,6 +1,6 @@
/* /*
Copyright 2010 Adam Marchetti Copyright 2010 Adam Marchetti
Copyright 2011-2012 Timothy Pearson <kb9vqf@pearsoncomputing.net> Copyright 2011-2013 Timothy Pearson <kb9vqf@pearsoncomputing.net>
This file is part of tsak, the TDE Secure Attention Key daemon This file is part of tsak, the TDE Secure Attention Key daemon
@ -132,7 +132,7 @@ void tsak_friendly_termination() {
// Wait for process termination // Wait for process termination
sleep(1); sleep(1);
fprintf(stderr, "tsak terminated by external request\n"); fprintf(stderr, "[tsak] tsak terminated by external request\n");
exit(17); exit(17);
} }
@ -359,7 +359,7 @@ void broadcast_sak()
int i; int i;
for (i=0;i<255;i++) { for (i=0;i<255;i++) {
if (write(mPipe_fd_out, "SAK\n\r", 6) < 0) { if (write(mPipe_fd_out, "SAK\n\r", 6) < 0) {
fprintf(stderr, "Unable to send SAK signal to clients\n"); fprintf(stderr, "[tsak] Unable to send SAK signal to clients\n");
} }
} }
} }
@ -368,7 +368,7 @@ void restart_tsak()
{ {
int i; int i;
fprintf(stderr, "Forcibly terminating...\n"); fprintf(stderr, "[tsak] Forcibly terminating...\n");
// Close down all child processes // Close down all child processes
for (i=0; i<MAX_KEYBOARDS; i++) { for (i=0; i<MAX_KEYBOARDS; i++) {
@ -386,7 +386,7 @@ void restart_tsak()
// Release all exclusive keyboard locks // Release all exclusive keyboard locks
for (int current_keyboard=0;current_keyboard<keyboard_fd_num;current_keyboard++) { for (int current_keyboard=0;current_keyboard<keyboard_fd_num;current_keyboard++) {
if(ioctl(keyboard_fds[current_keyboard], EVIOCGRAB, 0) < 0) { if(ioctl(keyboard_fds[current_keyboard], EVIOCGRAB, 0) < 0) {
fprintf(stderr, "Failed to release exclusive input device lock"); fprintf(stderr, "[tsak] Failed to release exclusive input device lock");
} }
close(keyboard_fds[current_keyboard]); close(keyboard_fds[current_keyboard]);
} }
@ -471,11 +471,11 @@ int main (int argc, char *argv[])
if (depcheck == false) { if (depcheck == false) {
// Check for existing file locks // Check for existing file locks
if (!checkFileLock()) { if (!checkFileLock()) {
fprintf(stderr, "Another instance of this program is already running [1]\n"); fprintf(stderr, "[tsak] Another instance of this program is already running [1]\n");
return 8; return 8;
} }
if (!setupLockingPipe(true)) { if (!setupLockingPipe(true)) {
fprintf(stderr, "Another instance of this program is already running [2]\n"); fprintf(stderr, "[tsak] Another instance of this program is already running [2]\n");
return 8; return 8;
} }
} }
@ -484,7 +484,7 @@ int main (int argc, char *argv[])
PipeHandler controlpipe; PipeHandler controlpipe;
if (depcheck == false) { if (depcheck == false) {
if (!setupPipe()) { if (!setupPipe()) {
fprintf(stderr, "Another instance of this program is already running\n"); fprintf(stderr, "[tsak] Another instance of this program is already running\n");
return 8; return 8;
} }
} }
@ -525,13 +525,13 @@ int main (int argc, char *argv[])
} }
} }
else { else {
fprintf(stderr, "Found %d keyboard(s)\n", keyboard_fd_num); fprintf(stderr, "[tsak] Found %d keyboard(s)\n", keyboard_fd_num);
can_proceed = true; can_proceed = true;
for (current_keyboard=0;current_keyboard<keyboard_fd_num;current_keyboard++) { for (current_keyboard=0;current_keyboard<keyboard_fd_num;current_keyboard++) {
// Print Device Name // Print Device Name
ioctl (keyboard_fds[current_keyboard], EVIOCGNAME (sizeof (name)), name); ioctl (keyboard_fds[current_keyboard], EVIOCGNAME (sizeof (name)), name);
fprintf(stderr, "Reading from keyboard: (%s)\n", name); fprintf(stderr, "[tsak] Reading from keyboard: (%s)\n", name);
// Create filtered virtual output device // Create filtered virtual output device
devout[current_keyboard]=open("/dev/misc/uinput",O_RDWR|O_NONBLOCK); devout[current_keyboard]=open("/dev/misc/uinput",O_RDWR|O_NONBLOCK);
@ -543,7 +543,7 @@ int main (int argc, char *argv[])
} }
if (devout[current_keyboard]<0) { if (devout[current_keyboard]<0) {
can_proceed = false; can_proceed = false;
fprintf(stderr, "Unable to open /dev/uinput or /dev/misc/uinput (char device 10:223).\nPossible causes:\n 1) Device node does not exist\n 2) Kernel not compiled with evdev [INPUT_EVDEV] and uinput [INPUT_UINPUT] user level driver support\n 3) Permission denied.\n"); fprintf(stderr, "[tsak] Unable to open /dev/uinput or /dev/misc/uinput (char device 10:223).\nPossible causes:\n 1) Device node does not exist\n 2) Kernel not compiled with evdev [INPUT_EVDEV] and uinput [INPUT_UINPUT] user level driver support\n 3) Permission denied.\n");
perror("open(\"/dev/uinput\")"); perror("open(\"/dev/uinput\")");
if (established) if (established)
sleep(1); sleep(1);
@ -560,7 +560,7 @@ int main (int argc, char *argv[])
for (current_keyboard=0;current_keyboard<keyboard_fd_num;current_keyboard++) { for (current_keyboard=0;current_keyboard<keyboard_fd_num;current_keyboard++) {
if(ioctl(keyboard_fds[current_keyboard], EVIOCGRAB, 2) < 0) { if(ioctl(keyboard_fds[current_keyboard], EVIOCGRAB, 2) < 0) {
close(keyboard_fds[current_keyboard]); close(keyboard_fds[current_keyboard]);
fprintf(stderr, "Failed to grab exclusive input device lock"); fprintf(stderr, "[tsak] Failed to grab exclusive input device lock");
if (established) { if (established) {
sleep(1); sleep(1);
} }
@ -571,22 +571,22 @@ int main (int argc, char *argv[])
else { else {
ioctl(keyboard_fds[current_keyboard], EVIOCGNAME(UINPUT_MAX_NAME_SIZE), devinfo.name); ioctl(keyboard_fds[current_keyboard], EVIOCGNAME(UINPUT_MAX_NAME_SIZE), devinfo.name);
strncat(devinfo.name, "+tsak", UINPUT_MAX_NAME_SIZE-1); strncat(devinfo.name, "+tsak", UINPUT_MAX_NAME_SIZE-1);
fprintf(stderr, "%s\n", devinfo.name); fprintf(stderr, "[tsak] %s\n", devinfo.name);
ioctl(keyboard_fds[current_keyboard], EVIOCGID, &devinfo.id); ioctl(keyboard_fds[current_keyboard], EVIOCGID, &devinfo.id);
copy_features(keyboard_fds[current_keyboard], devout[current_keyboard]); copy_features(keyboard_fds[current_keyboard], devout[current_keyboard]);
if (write(devout[current_keyboard],&devinfo,sizeof(devinfo)) < 0) { if (write(devout[current_keyboard],&devinfo,sizeof(devinfo)) < 0) {
fprintf(stderr, "Unable to write to output device\n"); fprintf(stderr, "[tsak] Unable to write to output device\n");
} }
if (ioctl(devout[current_keyboard],UI_DEV_CREATE)<0) { if (ioctl(devout[current_keyboard],UI_DEV_CREATE)<0) {
fprintf(stderr, "Unable to create input device with UI_DEV_CREATE\n"); fprintf(stderr, "[tsak] Unable to create input device with UI_DEV_CREATE\n");
if (established) if (established)
sleep(1); sleep(1);
else else
return 2; return 2;
} }
else { else {
fprintf(stderr, "Device created.\n"); fprintf(stderr, "[tsak] Device created.\n");
if (established == false) { if (established == false) {
int i=fork(); int i=fork();
@ -614,7 +614,7 @@ int main (int argc, char *argv[])
if (rrd >= size) { if (rrd >= size) {
if (revev.type == EV_LED) { if (revev.type == EV_LED) {
if (write(keyboard_fds[current_keyboard], &revev, sizeof(revev)) < 0) { if (write(keyboard_fds[current_keyboard], &revev, sizeof(revev)) < 0) {
fprintf(stderr, "Unable to replicate LED event\n"); fprintf(stderr, "[tsak] Unable to replicate LED event\n");
} }
} }
} }
@ -624,7 +624,7 @@ int main (int argc, char *argv[])
while (1) { while (1) {
if ((rd = read(keyboard_fds[current_keyboard], ev, size)) < size) { if ((rd = read(keyboard_fds[current_keyboard], ev, size)) < size) {
fprintf(stderr, "Read failed.\n"); fprintf(stderr, "[tsak] Read failed.\n");
break; break;
} }
@ -654,7 +654,7 @@ int main (int argc, char *argv[])
// Pass the event on... // Pass the event on...
event = ev[0]; event = ev[0];
if (write(devout[current_keyboard], &event, sizeof event) < 0) { if (write(devout[current_keyboard], &event, sizeof event) < 0) {
fprintf(stderr, "Unable to replicate keyboard event!\n"); fprintf(stderr, "[tsak] Unable to replicate keyboard event!\n");
} }
} }
if (hide_event == true) { if (hide_event == true) {
@ -683,7 +683,7 @@ int main (int argc, char *argv[])
// Wait a little bit so that udev hotplug can stabilize before we start monitoring // Wait a little bit so that udev hotplug can stabilize before we start monitoring
sleep(1); sleep(1);
fprintf(stderr, "Hotplug monitoring process started\n"); fprintf(stderr, "[tsak] Hotplug monitoring process started\n");
// Monitor for hotplugged keyboards // Monitor for hotplugged keyboards
int j; int j;
@ -696,7 +696,7 @@ int main (int argc, char *argv[])
// Create the udev object // Create the udev object
udev = udev_new(); udev = udev_new();
if (!udev) { if (!udev) {
fprintf(stderr, "Cannot connect to udev interface\n"); fprintf(stderr, "[tsak] Cannot connect to udev interface\n");
return 11; return 11;
} }
@ -707,6 +707,21 @@ int main (int argc, char *argv[])
while (1) { while (1) {
// Watch for input from the monitoring process // Watch for input from the monitoring process
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(udev_monitor_get_fd(mon), &readfds);
int fdcount = select(udev_monitor_get_fd(mon)+1, &readfds, NULL, NULL, NULL);
if (fdcount < 0) {
if (errno == EINTR) {
fprintf(stderr, "[tsak] Signal caught in hotplug monitoring process; ignoring\n");
}
else {
fprintf(stderr, "[tsak] Select failed on udev file descriptor in hotplug monitoring process\n");
}
usleep(1000);
continue;
}
dev = udev_monitor_receive_device(mon); dev = udev_monitor_receive_device(mon);
if (dev) { if (dev) {
// If a keyboard was removed we need to restart... // If a keyboard was removed we need to restart...
@ -741,20 +756,20 @@ int main (int argc, char *argv[])
// If a keyboard was added we need to restart... // If a keyboard was added we need to restart...
if (is_new_keyboard == true) { if (is_new_keyboard == true) {
fprintf(stderr, "Hotplugged new keyboard: (%s)\n", name); fprintf(stderr, "[tsak] Hotplugged new keyboard: (%s)\n", name);
udev_unref(udev); udev_unref(udev);
restart_tsak(); restart_tsak();
} }
} }
else { else {
fprintf(stderr, "No Device from receive_device(). A udev error has occurred; terminating hotplug monitoring process.\n"); fprintf(stderr, "[tsak] No device from receive_device(). A udev error has occurred; terminating hotplug monitoring process.\n");
return 11; return 12;
} }
} }
udev_unref(udev); udev_unref(udev);
fprintf(stderr, "Hotplug monitoring process terminated\n"); fprintf(stderr, "[tsak] Hotplug monitoring process terminated\n");
} }
} }
} }

Loading…
Cancel
Save