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