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. */
24filter_result
25ScreenSaverFilter::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
68void
69ScreenSaverFilter::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*/
79ScreenSaverWindow::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
101ScreenSaverWindow::~ScreenSaverWindow()
102{
103	Hide();
104}
105
106
107void
108ScreenSaverWindow::SetSaver(BScreenSaver *saver)
109{
110	fSaver = saver;
111}
112
113
114void
115ScreenSaverWindow::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
129bool
130ScreenSaverWindow::QuitRequested()
131{
132	be_app->PostMessage(B_QUIT_REQUESTED);
133	return true;
134}
135
136
137void
138ScreenSaverWindow::DirectConnected(direct_buffer_info *info)
139{
140	if (fSaver)
141		fSaver->DirectConnected(info);
142}
143
144