xref: /haiku/src/bin/screen_blanker/ScreenSaverWindow.cpp (revision 1c09002cbee8e797a0f8bbfc5678dfadd39ee1a7)
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_ZOOMABLE, B_ALL_WORKSPACES),
83 	fSaver(NULL)
84 {
85 	frame.OffsetTo(0, 0);
86 	fTopView = new BView(frame, "ScreenSaver View", B_FOLLOW_ALL, B_WILL_DRAW);
87 	fTopView->SetViewColor(B_TRANSPARENT_COLOR);
88 
89 	fFilter = new ScreenSaverFilter();
90 	fTopView->AddFilter(fFilter);
91 
92 	AddChild(fTopView);
93 
94 	// Ensure that this view receives keyboard input
95 	fTopView->MakeFocus(true);
96 	fTopView->SetEventMask(B_KEYBOARD_EVENTS, 0);
97 }
98 
99 
100 ScreenSaverWindow::~ScreenSaverWindow()
101 {
102 	Hide();
103 }
104 
105 
106 void
107 ScreenSaverWindow::SetSaver(BScreenSaver *saver)
108 {
109 	fSaver = saver;
110 }
111 
112 
113 void
114 ScreenSaverWindow::MessageReceived(BMessage *message)
115 {
116 	switch (message->what) {
117 		case kMsgEnableFilter:
118 			fFilter->SetEnabled(true);
119 			break;
120 
121 		default:
122 			BWindow::MessageReceived(message);
123  			break;
124 	}
125 }
126 
127 
128 bool
129 ScreenSaverWindow::QuitRequested()
130 {
131 	be_app->PostMessage(B_QUIT_REQUESTED);
132 	return true;
133 }
134 
135 
136 void
137 ScreenSaverWindow::DirectConnected(direct_buffer_info *info)
138 {
139 	if (fSaver)
140 		fSaver->DirectConnected(info);
141 }
142 
143