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