xref: /haiku/src/bin/screen_blanker/ScreenSaverWindow.cpp (revision 8a6724a0ee3803f1e9f487d8111bb3f6cb8d16db)
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