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