xref: /haiku/src/servers/power/power_daemon.cpp (revision 60b39cd7416028e61e3d30bb3ba28bd3526e6001)
1 /*
2  * Copyright 2013, Jérôme Duval, korli@users.berlios.de.
3  * Copyright 2005, Nathan Whitehorn.
4  *
5  * Distributed under the terms of the MIT License.
6  */
7 
8 
9 #include "lid_monitor.h"
10 #include "power_button_monitor.h"
11 
12 #include <Application.h>
13 
14 
15 class PowerManagementDaemon : public BApplication {
16 public:
17 								PowerManagementDaemon();
18 	virtual 					~PowerManagementDaemon();
19 private:
20 			void				_EventLoop();
21 	static	status_t			_EventLooper(void *arg);
22 
23 			thread_id			fEventThread;
24 			PowerMonitor*		fPowerMonitors[2];
25 			uint32				fMonitorCount;
26 
27 			bool				fQuitRequested;
28 };
29 
30 
31 int
32 main(void)
33 {
34 	new PowerManagementDaemon();
35 	be_app->Run();
36 	delete be_app;
37 	return 0;
38 }
39 
40 
41 PowerManagementDaemon::PowerManagementDaemon()
42 	:
43 	BApplication("application/x-vnd.Haiku-powermanagement"),
44 	fMonitorCount(0),
45 	fQuitRequested(false)
46 {
47 	PowerMonitor* powerButtonMonitor = new PowerButtonMonitor;
48 	if (powerButtonMonitor->FD() > 0)
49 		fPowerMonitors[fMonitorCount++] = powerButtonMonitor;
50 	else
51 		delete powerButtonMonitor;
52 
53 	PowerMonitor* lidMonitor = new LidMonitor;
54 	if (lidMonitor->FD() > 0)
55 		fPowerMonitors[fMonitorCount++] = lidMonitor;
56 	else
57 		delete lidMonitor;
58 
59 	fEventThread = spawn_thread(_EventLooper, "_power_daemon_event_loop_",
60 		B_NORMAL_PRIORITY, this);
61 	if (fEventThread < B_OK)
62 		return;
63 	if (resume_thread(fEventThread) < B_OK) {
64 		kill_thread(fEventThread);
65 		fEventThread = -1;
66 		return;
67 	}
68 }
69 
70 
71 PowerManagementDaemon::~PowerManagementDaemon()
72 {
73 	fQuitRequested = true;
74 	for (uint32 i = 0; i < fMonitorCount; i++)
75 		delete fPowerMonitors[i];
76 	status_t status;
77 	wait_for_thread(fEventThread, &status);
78 }
79 
80 
81 status_t
82 PowerManagementDaemon::_EventLooper(void* arg)
83 {
84 	PowerManagementDaemon* self = (PowerManagementDaemon*)arg;
85 	self->_EventLoop();
86 	return B_OK;
87 }
88 
89 
90 void
91 PowerManagementDaemon::_EventLoop()
92 {
93 	if (fMonitorCount == 0)
94 		return;
95 	object_wait_info info[fMonitorCount];
96 	for (uint32 i = 0; i < fMonitorCount; i++) {
97 		info[i].object = fPowerMonitors[i]->FD();
98 		info[i].type = B_OBJECT_TYPE_FD;
99 		info[i].events = B_EVENT_READ;
100 	}
101 	while (!fQuitRequested) {
102 		if (wait_for_objects(info, fMonitorCount) < B_OK)
103 			continue;
104 		// handle events and reset events
105 		for (uint32 i = 0; i < fMonitorCount; i++) {
106 			if (info[i].events & B_EVENT_READ)
107 				fPowerMonitors[i]->HandleEvent();
108 			else
109 				info[i].events = B_EVENT_READ;
110 		}
111 	}
112 }
113