6e7f1103289840b4bd5aa8075f1e2b1e3a673e22
[bertos.git] / mware / blanker.c
1 /**
2  * \file
3  * <!--
4  * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
5  * Copyright 2001 Bernardo Innocenti <bernie@codewiz.org>
6  * -->
7  *
8  * \brief Display Blanker (implementation).
9  *
10  * \version $Id$
11  *
12  * \author Bernardo Innocenti <bernie@develer.com>
13  */
14
15 #include "blanker.h"
16 #include <drv/kbd.h>
17 #include <drv/timer.h>
18
19 /* Time without input events before starting blanker */
20 #define BLK_BLANKTIMEOUT        (15 * 1000)     /* ms */
21
22 // TODO: move to blanker_hw.h
23 #include <drv/power.h>
24 #define BLK_LCDON       power_LcdOn()
25 #define BLK_LCDOFF      power_LcdOff()
26
27
28 /** Keyboard event handler to listen for key presses in blanker. */
29 static KbdHandler blk_KbdHandler;
30
31 /** Time since last key event. */
32 static ticks_t blk_lastevent;
33
34 /** Display blanking function is enabled. */
35 static bool blk_enabled;
36
37 /** Display blanker is engaged right now. */
38 static bool blk_active;
39
40
41 static bool blk_on(void)
42 {
43         if (!blk_active)
44         {
45                 blk_active = true;
46                 BLK_LCDOFF;
47         }
48         return true;
49 }
50
51
52 static void blk_off(void)
53 {
54         if (blk_active)
55         {
56                 blk_active = false;
57                 BLK_LCDON;
58         }
59 }
60
61
62 void blk_retrigger(void)
63 {
64         blk_lastevent = timer_clock();
65         blk_off();
66 }
67
68 #if 0
69 /**
70  * Matrix-like screen saver effect
71  */
72 static void blk_hack(void)
73 {
74         static signed char blk_colstart[LCD_COLS];
75         UBYTE row, col;
76
77
78         if (rand()%3 == 0)
79         {
80                 /* Modify one column */
81                 col = rand() % LCD_COLS;
82                 blk_colstart[col] += rand() % 12 - 5;
83         }
84
85         for (col = 0; col < LCD_COLS; ++col)
86         {
87                 if (blk_colstart[col] > 0)
88                 {
89                         --blk_colstart[col];
90
91                         /* Scroll down */
92                         for(row = LCD_ROWS-1; row; --row)
93                         {
94                                 lcd_SetAddr(blk_layer, LCD_POS(col,row));
95                                 lcd_PutChar(blk_layer->Buf[LCD_POS(col,row-1)], blk_layer);
96                         }
97
98                         /* Add new kanji */
99                         lcd_SetAddr(blk_layer, LCD_POS(col,0));
100                         lcd_PutChar((char)(rand() % 127 + 128), blk_layer);
101                 }
102                 else if (blk_colstart[col] < 0)
103                 {
104                         ++blk_colstart[col];
105
106                         /* Clear tail */
107                         for(row = 0; row < LCD_ROWS; ++row)
108                         {
109                                 if (blk_layer->Buf[LCD_POS(col,row)] != ' ')
110                                 {
111                                         lcd_SetAddr(blk_layer, LCD_POS(col,row));
112                                         lcd_PutChar(' ', blk_layer);
113                                         break;
114                                 }
115                         }
116                 }
117         }
118 }
119 #endif
120
121
122 static keymask_t blk_handlerFunc(keymask_t key)
123 {
124         /* key used to turn off blanker */
125         static keymask_t offkey;
126
127         ticks_t now = timer_clock();
128
129         /* If key pressed */
130         if (key != 0)
131         {
132                 blk_lastevent = now;
133                 if (blk_active)
134                 {
135                         blk_off();
136
137                         /* remember and eat key event */
138                         offkey = key;
139                         key = 0;
140                 }
141                 else if (key == offkey)
142                 {
143                         /* keep eating the key until released */
144                         key = 0;
145                 }
146
147                 /* pass key through */
148                 return key;
149         }
150
151         /* reset off key */
152         offkey = 0;
153
154         /* Blank timeout reached? */
155         if (now - blk_lastevent > ms_to_ticks(BLK_BLANKTIMEOUT))
156         {
157                 /* Enable blanker unless already done */
158                 if (!blk_active && !blk_on())
159                         return 0;
160
161 #if 0
162                 /* Do some nice visual effect */
163                 blk_hack();
164 #endif /* _DEBUG */
165         }
166
167         return 0;
168 }
169
170
171 void blk_enable(void)
172 {
173         if (!blk_enabled)
174         {
175                 blk_active = false;
176                 blk_lastevent = timer_clock();
177
178                 /* Add display blanker handler */
179                 blk_KbdHandler.hook = blk_handlerFunc;
180                 blk_KbdHandler.pri = 100; /* high priority */
181                 blk_KbdHandler.flags = KHF_RAWKEYS;
182                 kbd_addHandler(&blk_KbdHandler);
183
184                 blk_enabled = true;
185         }
186 }
187
188
189 void blk_disable(void)
190 {
191         if (blk_enabled)
192         {
193                 kbd_remHandler(&blk_KbdHandler);
194                 blk_off();
195                 blk_enabled = false;
196         }
197 }