diff --git a/src/add-ons/input_server/devices/keyboard/KeyboardInputDevice.cpp b/src/add-ons/input_server/devices/keyboard/KeyboardInputDevice.cpp index cca2263d67..d22ea4d19f 100644 --- a/src/add-ons/input_server/devices/keyboard/KeyboardInputDevice.cpp +++ b/src/add-ons/input_server/devices/keyboard/KeyboardInputDevice.cpp @@ -591,6 +591,7 @@ KeyboardInputDevice::_DeviceWatcher(void* arg) uint32 lastKeyCode = 0; uint32 repeatCount = 1; uint8 states[16]; + bool ctrlAltDelPressed = false; memset(states, 0, sizeof(states)); @@ -626,7 +627,7 @@ KeyboardInputDevice::_DeviceWatcher(void* arg) LOG(" %Ld, %02x, %02lx\n", timestamp, isKeyDown, keycode); if (isKeyDown && keycode == 0x68) { - // MENU KEY for OpenTracker 5.2.0+ + // MENU KEY for Tracker bool noOtherKeyPressed = true; for (int32 i = 0; i < 16; i++) { if (states[i] != 0) { @@ -649,23 +650,28 @@ KeyboardInputDevice::_DeviceWatcher(void* arg) states[(keycode) >> 3] &= (!(1 << (7 - (keycode & 0x7)))); } - if (isKeyDown - && keycode == 0x34 // DELETE KEY + if (isKeyDown && keycode == 0x34 // DELETE KEY && (states[0x5c >> 3] & (1 << (7 - (0x5c & 0x7)))) && (states[0x5d >> 3] & (1 << (7 - (0x5d & 0x7))))) { LOG("TeamMonitor called\n"); // show the team monitor if (owner->fTeamMonitorWindow == NULL) - owner->fTeamMonitorWindow = new (std::nothrow) TMWindow(); + owner->fTeamMonitorWindow = new(std::nothrow) TMWindow(); - if (owner->fTeamMonitorWindow != NULL) { + if (owner->fTeamMonitorWindow != NULL) owner->fTeamMonitorWindow->Enable(); - // cancel timer only for R5 - if (ioctl(device->fd, KB_CANCEL_CONTROL_ALT_DEL, NULL) == B_OK) - LOG("KB_CANCEL_CONTROL_ALT_DEL : OK\n"); + ctrlAltDelPressed = true; + } + if (ctrlAltDelPressed) { + if (owner->fTeamMonitorWindow != NULL) { + BMessage message(kMsgCtrlAltDelPressed); + message.AddBool("key down", isKeyDown); + owner->fTeamMonitorWindow->PostMessage(&message); } + if (!isKeyDown) + ctrlAltDelPressed = false; } BAutolock lock(owner->fKeymapLock); diff --git a/src/add-ons/input_server/devices/keyboard/TMWindow.cpp b/src/add-ons/input_server/devices/keyboard/TMWindow.cpp index e22b8e1316..d02acce51b 100644 --- a/src/add-ons/input_server/devices/keyboard/TMWindow.cpp +++ b/src/add-ons/input_server/devices/keyboard/TMWindow.cpp @@ -39,6 +39,8 @@ const uint32 TM_KILL_APPLICATION = 'TMka'; const uint32 TM_RESTART_DESKTOP = 'TMrd'; const uint32 TM_SELECTED_TEAM = 'TMst'; +static const uint32 kMsgRebootTick = 'TMrt'; + TMWindow::TMWindow() : BWindow(BRect(0, 0, 350, 300), "Team Monitor", @@ -136,6 +138,14 @@ TMWindow::MessageReceived(BMessage *msg) UpdateList(); break; + case kMsgCtrlAltDelPressed: + bool keyDown; + if (msg->FindBool("key down", &keyDown) != B_OK) + break; + + fDescriptionView->CtrlAltDelPressed(keyDown); + break; + case TM_FORCE_REBOOT: _kern_shutdown(true); break; @@ -250,10 +260,10 @@ void TMWindow::Enable() { if (Lock()) { - BMessage message(kMsgUpdate); - fUpdateRunner = new BMessageRunner(this, &message, 1000000LL); - if (IsHidden()) { + BMessage message(kMsgUpdate); + fUpdateRunner = new BMessageRunner(this, &message, 1000000LL); + UpdateList(); Show(); } @@ -277,7 +287,9 @@ TMWindow::Disable() TMDescView::TMDescView() : BBox("descview", B_WILL_DRAW | B_PULSE_NEEDED, B_NO_BORDER), - fItem(NULL) + fItem(NULL), + fSeconds(4), + fRebootRunner(NULL) { /* BTextView* textView = new BTextView("description"); @@ -295,9 +307,6 @@ TMDescView::TMDescView() fText[1] = "\"Kill Application\" button in order to close it."; fText[2] = "Hold CONTROL+ALT+DELETE for %ld seconds to reboot."; - fKeysPressed = false; - fSeconds = 4; - float width, height; GetPreferredSize(&width, &height); SetExplicitMinSize(BSize(width, -1)); @@ -306,18 +315,48 @@ TMDescView::TMDescView() } -void -TMDescView::Pulse() +TMDescView::~TMDescView() { - // TODO: connect this mechanism with the keyboard device - it can tell us - // if ctrl-alt-del is pressed - if (fKeysPressed) { - fSeconds--; - Invalidate(); + delete fRebootRunner; +} + + +void +TMDescView::MessageReceived(BMessage* message) +{ + switch (message->what) { + case kMsgRebootTick: + fSeconds--; + if (fSeconds == 0) + Window()->PostMessage(TM_FORCE_REBOOT); + else + Invalidate(); + break; + + default: + BBox::MessageReceived(message); } } +void +TMDescView::CtrlAltDelPressed(bool keyDown) +{ + if (!(keyDown ^ fRebootRunner != NULL)) + return; + + delete fRebootRunner; + fRebootRunner = NULL; + fSeconds = 4; + + if (keyDown) { + BMessage tick(kMsgRebootTick); + fRebootRunner = new BMessageRunner(this, &tick, 1000000LL); + } else + Invalidate(); +} + + void TMDescView::Draw(BRect rect) { diff --git a/src/add-ons/input_server/devices/keyboard/TMWindow.h b/src/add-ons/input_server/devices/keyboard/TMWindow.h index cfaa61e5a0..5e15add0ca 100644 --- a/src/add-ons/input_server/devices/keyboard/TMWindow.h +++ b/src/add-ons/input_server/devices/keyboard/TMWindow.h @@ -21,12 +21,14 @@ class TMDescView : public BBox { public: TMDescView(); + virtual ~TMDescView(); - virtual void Pulse(); - + virtual void MessageReceived(BMessage* message); virtual void Draw(BRect bounds); virtual void GetPreferredSize(float *_width, float *_height); + void CtrlAltDelPressed(bool keyDown); + void SetItem(TMListItem *item); TMListItem *Item() { return fItem; } @@ -34,7 +36,7 @@ class TMDescView : public BBox { const char* fText[3]; TMListItem* fItem; int32 fSeconds; - bool fKeysPressed; + BMessageRunner* fRebootRunner; }; class TMWindow : public BWindow { @@ -61,4 +63,6 @@ class TMWindow : public BWindow { TMDescView *fDescriptionView; }; +static const uint32 kMsgCtrlAltDelPressed = 'TMcp'; + #endif // TMWINDOW_H