Clean up. Add copyright notice. Mark as FIXME.
[bertos.git] / bertos / mware / blanker.c
1 /**
2  * \file
3  * <!--
4  * This file is part of BeRTOS.
5  *
6  * Bertos is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  *
29  * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
30  * Copyright 2001 Bernardo Innocenti <bernie@codewiz.org>
31  * -->
32  *
33  * \brief Display Blanker (implementation).
34  *
35  * \version $Id$
36  *
37  * \author Bernardo Innocenti <bernie@develer.com>
38  */
39
40 #include "blanker.h"
41
42 #include <drv/kbd.h>
43 #include <drv/timer.h>
44
45 /* Time without input events before starting blanker */
46 #define BLK_BLANKTIMEOUT        (15 * 1000)     /* ms */
47
48 // TODO: move to blanker_hw.h
49 #include <drv/power.h>
50 #define BLK_LCDON       power_LcdOn()
51 #define BLK_LCDOFF      power_LcdOff()
52
53 #warning FIXME:Revise me!
54
55 /** Keyboard event handler to listen for key presses in blanker. */
56 static KbdHandler blk_KbdHandler;
57
58 /** Time since last key event. */
59 static ticks_t blk_lastevent;
60
61 /** Display blanking function is enabled. */
62 static bool blk_enabled;
63
64 /** Display blanker is engaged right now. */
65 static bool blk_active;
66
67
68 static bool blk_on(void)
69 {
70         if (!blk_active)
71         {
72                 blk_active = true;
73                 BLK_LCDOFF;
74         }
75         return true;
76 }
77
78
79 static void blk_off(void)
80 {
81         if (blk_active)
82         {
83                 blk_active = false;
84                 BLK_LCDON;
85         }
86 }
87
88
89 void blk_retrigger(void)
90 {
91         blk_lastevent = timer_clock();
92         blk_off();
93 }
94
95 #if 0
96 /**
97  * Matrix-like screen saver effect
98  */
99 static void blk_hack(void)
100 {
101         static signed char blk_colstart[LCD_COLS];
102         UBYTE row, col;
103
104
105         if (rand()%3 == 0)
106         {
107                 /* Modify one column */
108                 col = rand() % LCD_COLS;
109                 blk_colstart[col] += rand() % 12 - 5;
110         }
111
112         for (col = 0; col < LCD_COLS; ++col)
113         {
114                 if (blk_colstart[col] > 0)
115                 {
116                         --blk_colstart[col];
117
118                         /* Scroll down */
119                         for(row = LCD_ROWS-1; row; --row)
120                         {
121                                 lcd_SetAddr(blk_layer, LCD_POS(col,row));
122                                 lcd_PutChar(blk_layer->Buf[LCD_POS(col,row-1)], blk_layer);
123                         }
124
125                         /* Add new kanji */
126                         lcd_SetAddr(blk_layer, LCD_POS(col,0));
127                         lcd_PutChar((char)(rand() % 127 + 128), blk_layer);
128                 }
129                 else if (blk_colstart[col] < 0)
130                 {
131                         ++blk_colstart[col];
132
133                         /* Clear tail */
134                         for(row = 0; row < LCD_ROWS; ++row)
135                         {
136                                 if (blk_layer->Buf[LCD_POS(col,row)] != ' ')
137                                 {
138                                         lcd_SetAddr(blk_layer, LCD_POS(col,row));
139                                         lcd_PutChar(' ', blk_layer);
140                                         break;
141                                 }
142                         }
143                 }
144         }
145 }
146 #endif
147
148
149 static keymask_t blk_handlerFunc(keymask_t key)
150 {
151         /* key used to turn off blanker */
152         static keymask_t offkey;
153
154         ticks_t now = timer_clock();
155
156         /* If key pressed */
157         if (key != 0)
158         {
159                 blk_lastevent = now;
160                 if (blk_active)
161                 {
162                         blk_off();
163
164                         /* remember and eat key event */
165                         offkey = key;
166                         key = 0;
167                 }
168                 else if (key == offkey)
169                 {
170                         /* keep eating the key until released */
171                         key = 0;
172                 }
173
174                 /* pass key through */
175                 return key;
176         }
177
178         /* reset off key */
179         offkey = 0;
180
181         /* Blank timeout reached? */
182         if (now - blk_lastevent > ms_to_ticks(BLK_BLANKTIMEOUT))
183         {
184                 /* Enable blanker unless already done */
185                 if (!blk_active && !blk_on())
186                         return 0;
187
188 #if 0
189                 /* Do some nice visual effect */
190                 blk_hack();
191 #endif /* _DEBUG */
192         }
193
194         return 0;
195 }
196
197
198 void blk_enable(void)
199 {
200         if (!blk_enabled)
201         {
202                 blk_active = false;
203                 blk_lastevent = timer_clock();
204
205                 /* Add display blanker handler */
206                 blk_KbdHandler.hook = blk_handlerFunc;
207                 blk_KbdHandler.pri = 100; /* high priority */
208                 blk_KbdHandler.flags = KHF_RAWKEYS;
209                 kbd_addHandler(&blk_KbdHandler);
210
211                 blk_enabled = true;
212         }
213 }
214
215
216 void blk_disable(void)
217 {
218         if (blk_enabled)
219         {
220                 kbd_remHandler(&blk_KbdHandler);
221                 blk_off();
222                 blk_enabled = false;
223         }
224 }