1 /* 2 * Copyright 2003-2014, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Michael Phipps 7 * Jérôme Duval, jerome.duval@free.fr 8 * Ryan Leavengood, leavengood@gmail.com 9 * Puck Meerburg, puck@puckipedia.nl 10 */ 11 12 13 #include "ScreenBlanker.h" 14 #include "ScreenSaverWindow.h" 15 16 #include <Application.h> 17 #include <View.h> 18 19 #include <WindowPrivate.h> 20 21 #include <syslog.h> 22 23 24 // #pragma mark - ScreenSaverFilter 25 26 27 /* This message filter is what will close the screensaver upon user activity. */ 28 filter_result 29 ScreenSaverFilter::Filter(BMessage* message, BHandler** target) 30 { 31 // This guard is used to avoid sending multiple B_QUIT_REQUESTED messages 32 if (fEnabled) { 33 switch (message->what) { 34 case B_MOUSE_MOVED: 35 { 36 // ignore the initial B_MOUSE_MOVED sent by the app_server 37 // in test mode, all mouse move events are ignored 38 bool transitOnly = false; 39 if (fTestMode 40 || (message->FindBool("be:transit_only", &transitOnly) 41 == B_OK && transitOnly)) 42 return B_DISPATCH_MESSAGE; 43 44 // Fall through 45 } 46 case B_KEY_DOWN: 47 { 48 // we ignore the Print-Screen key to make screen shots of 49 // screen savers possible 50 int32 key; 51 if (message->FindInt32("key", &key) == B_OK && key == 0xe) 52 return B_DISPATCH_MESSAGE; 53 54 // Fall through 55 } 56 case B_MODIFIERS_CHANGED: 57 case B_UNMAPPED_KEY_DOWN: 58 case B_MOUSE_DOWN: 59 fEnabled = false; 60 be_app->PostMessage(B_QUIT_REQUESTED); 61 break; 62 } 63 } else if (message->what == B_KEY_DOWN) { 64 ScreenBlanker* app = dynamic_cast<ScreenBlanker*>(be_app); 65 if (app != NULL && app->IsPasswordWindowShown()) { 66 // Handle the escape key when the password window is showing 67 const char* string = NULL; 68 if (message->FindString("bytes", &string) == B_OK 69 && string[0] == B_ESCAPE) { 70 be_app->PostMessage(kMsgResumeSaver); 71 } 72 } 73 } 74 75 return B_DISPATCH_MESSAGE; 76 } 77 78 79 // #pragma mark - ScreenSaverWindow 80 81 82 /*! 83 This is the BDirectWindow subclass that rendering occurs in. 84 A view is added to it so that BView based screensavers will work. 85 */ 86 ScreenSaverWindow::ScreenSaverWindow(BRect frame, bool test) 87 : 88 BDirectWindow(frame, "ScreenSaver Window", 89 B_NO_BORDER_WINDOW_LOOK, kWindowScreenFeel, 90 B_NOT_RESIZABLE | B_NOT_MOVABLE | B_NOT_MINIMIZABLE 91 | B_NOT_ZOOMABLE | B_NOT_CLOSABLE, B_ALL_WORKSPACES), 92 fTopView(NULL), 93 fSaverRunner(NULL), 94 fFilter(NULL) 95 { 96 frame.OffsetTo(0, 0); 97 fTopView = new BView(frame, "ScreenSaver View", B_FOLLOW_ALL, 98 B_WILL_DRAW); 99 fTopView->SetViewColor(B_TRANSPARENT_COLOR); 100 101 fFilter = new ScreenSaverFilter(test); 102 fTopView->AddFilter(fFilter); 103 104 AddChild(fTopView); 105 106 // Ensure that this view receives keyboard and mouse input 107 fTopView->MakeFocus(true); 108 fTopView->SetEventMask(B_KEYBOARD_EVENTS | B_POINTER_EVENTS, 109 B_NO_POINTER_HISTORY); 110 } 111 112 113 ScreenSaverWindow::~ScreenSaverWindow() 114 { 115 Hide(); 116 } 117 118 119 void 120 ScreenSaverWindow::MessageReceived(BMessage* message) 121 { 122 switch (message->what) { 123 case kMsgEnableFilter: 124 fFilter->SetEnabled(true); 125 break; 126 127 default: 128 BWindow::MessageReceived(message); 129 } 130 } 131 132 133 bool 134 ScreenSaverWindow::QuitRequested() 135 { 136 be_app->PostMessage(B_QUIT_REQUESTED); 137 return true; 138 } 139 140 141 void 142 ScreenSaverWindow::DirectConnected(direct_buffer_info* info) 143 { 144 BScreenSaver* saver = _ScreenSaver(); 145 if (saver != NULL) 146 saver->DirectConnected(info); 147 } 148 149 150 void 151 ScreenSaverWindow::SetSaverRunner(ScreenSaverRunner* runner) 152 { 153 fSaverRunner = runner; 154 } 155 156 157 BScreenSaver* 158 ScreenSaverWindow::_ScreenSaver() 159 { 160 if (fSaverRunner != NULL) 161 return fSaverRunner->ScreenSaver(); 162 163 return NULL; 164 } 165