Doc fixes.
[bertos.git] / 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 #include <drv/kbd.h>
42 #include <drv/timer.h>
43
44 /* Time without input events before starting blanker */
45 #define BLK_BLANKTIMEOUT        (15 * 1000)     /* ms */
46
47 // TODO: move to blanker_hw.h
48 #include <drv/power.h>
49 #define BLK_LCDON       power_LcdOn()
50 #define BLK_LCDOFF      power_LcdOff()
51
52
53 /** Keyboard event handler to listen for key presses in blanker. */
54 static KbdHandler blk_KbdHandler;
55
56 /** Time since last key event. */
57 static ticks_t blk_lastevent;
58
59 /** Display blanking function is enabled. */
60 static bool blk_enabled;
61
62 /** Display blanker is engaged right now. */
63 static bool blk_active;
64
65
66 static bool blk_on(void)
67 {
68         if (!blk_active)
69         {
70                 blk_active = true;
71                 BLK_LCDOFF;
72         }
73         return true;
74 }
75
76
77 static void blk_off(void)
78 {
79         if (blk_active)
80         {
81                 blk_active = false;
82                 BLK_LCDON;
83         }
84 }
85
86
87 void blk_retrigger(void)
88 {
89         blk_lastevent = timer_clock();
90         blk_off();
91 }
92
93 #if 0
94 /**
95  * Matrix-like screen saver effect
96  */
97 static void blk_hack(void)
98 {
99         static signed char blk_colstart[LCD_COLS];
100         UBYTE row, col;
101
102
103         if (rand()%3 == 0)
104         {
105                 /* Modify one column */
106                 col = rand() % LCD_COLS;
107                 blk_colstart[col] += rand() % 12 - 5;
108         }
109
110         for (col = 0; col < LCD_COLS; ++col)
111         {
112                 if (blk_colstart[col] > 0)
113                 {
114                         --blk_colstart[col];
115
116                         /* Scroll down */
117                         for(row = LCD_ROWS-1; row; --row)
118                         {
119                                 lcd_SetAddr(blk_layer, LCD_POS(col,row));
120                                 lcd_PutChar(blk_layer->Buf[LCD_POS(col,row-1)], blk_layer);
121                         }
122
123                         /* Add new kanji */
124                         lcd_SetAddr(blk_layer, LCD_POS(col,0));
125                         lcd_PutChar((char)(rand() % 127 + 128), blk_layer);
126                 }
127                 else if (blk_colstart[col] < 0)
128                 {
129                         ++blk_colstart[col];
130
131                         /* Clear tail */
132                         for(row = 0; row < LCD_ROWS; ++row)
133                         {
134                                 if (blk_layer->Buf[LCD_POS(col,row)] != ' ')
135                                 {
136                                         lcd_SetAddr(blk_layer, LCD_POS(col,row));
137                                         lcd_PutChar(' ', blk_layer);
138                                         break;
139                                 }
140                         }
141                 }
142         }
143 }
144 #endif
145
146
147 static keymask_t blk_handlerFunc(keymask_t key)
148 {
149         /* key used to turn off blanker */
150         static keymask_t offkey;
151
152         ticks_t now = timer_clock();
153
154         /* If key pressed */
155         if (key != 0)
156         {
157                 blk_lastevent = now;
158                 if (blk_active)
159                 {
160                         blk_off();
161
162                         /* remember and eat key event */
163                         offkey = key;
164                         key = 0;
165                 }
166                 else if (key == offkey)
167                 {
168                         /* keep eating the key until released */
169                         key = 0;
170                 }
171
172                 /* pass key through */
173                 return key;
174         }
175
176         /* reset off key */
177         offkey = 0;
178
179         /* Blank timeout reached? */
180         if (now - blk_lastevent > ms_to_ticks(BLK_BLANKTIMEOUT))
181         {
182                 /* Enable blanker unless already done */
183                 if (!blk_active && !blk_on())
184                         return 0;
185
186 #if 0
187                 /* Do some nice visual effect */
188                 blk_hack();
189 #endif /* _DEBUG */
190         }
191
192         return 0;
193 }
194
195
196 void blk_enable(void)
197 {
198         if (!blk_enabled)
199         {
200                 blk_active = false;
201                 blk_lastevent = timer_clock();
202
203                 /* Add display blanker handler */
204                 blk_KbdHandler.hook = blk_handlerFunc;
205                 blk_KbdHandler.pri = 100; /* high priority */
206                 blk_KbdHandler.flags = KHF_RAWKEYS;
207                 kbd_addHandler(&blk_KbdHandler);
208
209                 blk_enabled = true;
210         }
211 }
212
213
214 void blk_disable(void)
215 {
216         if (blk_enabled)
217         {
218                 kbd_remHandler(&blk_KbdHandler);
219                 blk_off();
220                 blk_enabled = false;
221         }
222 }