1 /* This is the LCDproc driver for CrystalFontz 633 devices
2 (get yours from http://crystalfontz.com)
4 Copyright (C) 2002 David GLAUDE
6 This program 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
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.
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 Street, Fifth Floor, Boston, MA 02110-1301 */
23 * 04/04/2002: Working driver
24 * 05/06/2002: Reading of return value
25 * 02/09/2002: KeyPad handling and return string
26 * 03/09/2002: New icon incorporated
29 * + No checking if right hardware is connected (firmware/hardware)
30 * + No BigNum (but screen is too small ???)
31 * + No support for multiple instance (require private structure)
32 * + No cache of custom char usage (like in MtxOrb)
35 * + Stopping the live reporting (of temperature)
36 * + Stopping the reporting of temp and fan (is it necessary after reboot)
37 * + Use of library for hbar and vbar (good but library could be better)
38 * + Support for keypad (Using a KeyRing)
41 * + Make the caching at least for heartbeat icon
42 * + Create and use the library (for custom char handling)
60 #include "CFontz633.h"
61 #include "CFontz633io.h"
64 #include "adv_bignum.h"
66 #define CF633_KEY_UP 1
67 #define CF633_KEY_DOWN 2
68 #define CF633_KEY_LEFT 3
69 #define CF633_KEY_RIGHT 4
70 #define CF633_KEY_ENTER 5
71 #define CF633_KEY_ESCAPE 6
74 /* Constants for userdefchar_mode */
75 #define NUM_CCs 8 /* max. number of custom characters */
78 standard
, /* only char 0 is used for heartbeat */
79 vbar
, /* vertical bars */
80 hbar
, /* horizontal bars */
81 custom
, /* custom settings */
82 bignum
, /* big numbers */
83 bigchar
/* big characters */
87 typedef struct driver_private_data
{
99 int cellwidth
, cellheight
;
101 /* framebuffer and buffer for old LCD contents */
102 unsigned char *framebuf
;
103 unsigned char *backingstore
;
105 /* defineable characters */
114 /* Vars for the server core */
115 MODULE_EXPORT
char *api_version
= API_VERSION
;
116 MODULE_EXPORT
int stay_in_foreground
= 0;
117 MODULE_EXPORT
int supports_multiple
= 0;
118 MODULE_EXPORT
char *symbol_prefix
= "CFontz633_";
120 /* Internal functions */
121 /* static void CFontz633_linewrap (int on); */
122 /* static void CFontz633_autoscroll (int on); */
123 static void CFontz633_hidecursor (Driver
*drvthis
);
124 static void CFontz633_reboot (Driver
*drvthis
);
125 static void CFontz633_no_live_report (Driver
*drvthis
);
126 static void CFontz633_hardware_clear (Driver
*drvthis
);
130 * Initialize the driver.
131 * \param drvthis Pointer to driver structure.
136 CFontz633_init (Driver
*drvthis
)
138 struct termios portset
;
141 char size
[200] = DEFAULT_SIZE
;
145 /* Allocate and store private data */
146 p
= (PrivateData
*) calloc(1, sizeof(PrivateData
));
149 if (drvthis
->store_private_ptr(drvthis
, p
))
152 /* Initialize the PrivateData structure */
154 p
->cellwidth
= DEFAULT_CELL_WIDTH
;
155 p
->cellheight
= DEFAULT_CELL_HEIGHT
;
156 p
->ccmode
= standard
;
158 debug(RPT_INFO
, "%s(%p)", __FUNCTION__
, drvthis
);
160 EmptyKeyRing(&keyring
);
161 EmptyReceiveBuffer(&receivebuffer
);
163 /* Read config file */
164 /* Which device should be used */
165 strncpy(p
->device
, drvthis
->config_get_string(drvthis
->name
, "Device", 0, DEFAULT_DEVICE
), sizeof(p
->device
));
166 p
->device
[sizeof(p
->device
)-1] = '\0';
167 report(RPT_INFO
, "%s: using Device %s", drvthis
->name
, p
->device
);
170 strncpy(size
, drvthis
->config_get_string(drvthis
->name
, "Size", 0, DEFAULT_SIZE
), sizeof(size
));
171 size
[sizeof(size
)-1] = '\0';
172 if ((sscanf(size
, "%dx%d", &w
, &h
) != 2)
173 || (w
<= 0) || (w
> LCD_MAX_WIDTH
)
174 || (h
<= 0) || (h
> LCD_MAX_HEIGHT
)) {
175 report(RPT_WARNING
, "%s: cannot parse Size: %s; using default %s",
176 drvthis
->name
, size
, DEFAULT_SIZE
);
177 sscanf(DEFAULT_SIZE
, "%dx%d", &w
, &h
);
183 tmp
= drvthis
->config_get_int(drvthis
->name
, "Contrast", 0, DEFAULT_CONTRAST
);
184 if ((tmp
< 0) || (tmp
> 1000)) {
185 report(RPT_WARNING
, "%s: Contrast must be between 0 and 1000; using default %d",
186 drvthis
->name
, DEFAULT_CONTRAST
);
187 tmp
= DEFAULT_CONTRAST
;
191 /* Which backlight brightness */
192 tmp
= drvthis
->config_get_int(drvthis
->name
, "Brightness", 0, DEFAULT_BRIGHTNESS
);
193 if ((tmp
< 0) || (tmp
> 1000)) {
194 report(RPT_WARNING
, "%s: Brightness must be between 0 and 1000; using default %d",
195 drvthis
->name
, DEFAULT_BRIGHTNESS
);
196 tmp
= DEFAULT_BRIGHTNESS
;
200 /* Which backlight-off "brightness" */
201 tmp
= drvthis
->config_get_int(drvthis
->name
, "OffBrightness", 0, DEFAULT_OFFBRIGHTNESS
);
202 if ((tmp
< 0) || (tmp
> 1000)) {
203 report(RPT_WARNING
, "%s: OffBrightness must be between 0 and 1000; using default %d",
204 drvthis
->name
, DEFAULT_OFFBRIGHTNESS
);
205 tmp
= DEFAULT_OFFBRIGHTNESS
;
207 p
->offbrightness
= tmp
;
210 tmp
= drvthis
->config_get_int(drvthis
->name
, "Speed", 0, DEFAULT_SPEED
);
211 if ((tmp
!= 1200) && (tmp
!= 2400) && (tmp
!= 9600) && (tmp
!= 19200) && (tmp
!= 115200)) {
212 report(RPT_WARNING
, "%s: Speed must be 1200, 2400, 9600, 19200 or 115200; using default %d",
213 drvthis
->name
, DEFAULT_SPEED
);
216 if (tmp
== 1200) p
->speed
= B1200
;
217 else if (tmp
== 2400) p
->speed
= B2400
;
218 else if (tmp
== 9600) p
->speed
= B9600
;
219 else if (tmp
== 19200) p
->speed
= B19200
;
220 else if (tmp
== 115200) p
->speed
= B115200
;
222 /* New firmware version?
223 * I will try to behave differently for firmware 0.6 or above.
224 * Currently this is not in use.
226 p
->newfirmware
= drvthis
->config_get_bool(drvthis
->name
, "NewFirmware", 0, 0);
228 /* Reboot display? */
229 reboot
= drvthis
->config_get_bool(drvthis
->name
, "Reboot", 0, 0);
231 /* Am I USB or not? */
232 p
->usb
= drvthis
->config_get_bool(drvthis
->name
, "USB", 0, 0);
234 /* Set up io port correctly, and open it... */
235 debug(RPT_DEBUG
, "%s: Opening device: %s", __FUNCTION__
, p
->device
);
236 p
->fd
= open(p
->device
, (p
->usb
) ? (O_RDWR
| O_NOCTTY
) : (O_RDWR
| O_NOCTTY
| O_NDELAY
));
238 report(RPT_ERR
, "%s: open(%s) failed (%s)", drvthis
->name
, p
->device
, strerror(errno
));
242 tcgetattr(p
->fd
, &portset
);
244 /* We use RAW mode */
247 portset
.c_iflag
&= ~( IGNBRK
| BRKINT
| PARMRK
| ISTRIP
248 | INLCR
| IGNCR
| ICRNL
| IXON
);
249 portset
.c_oflag
&= ~OPOST
;
250 portset
.c_lflag
&= ~( ECHO
| ECHONL
| ICANON
| ISIG
| IEXTEN
);
251 portset
.c_cflag
&= ~( CSIZE
| PARENB
| CRTSCTS
);
252 portset
.c_cflag
|= CS8
| CREAD
| CLOCAL
;
253 portset
.c_cc
[VMIN
] = 0;
254 portset
.c_cc
[VTIME
] = 0;
256 #ifdef HAVE_CFMAKERAW
261 portset
.c_iflag
&= ~( IGNBRK
| BRKINT
| PARMRK
| ISTRIP
262 | INLCR
| IGNCR
| ICRNL
| IXON
);
263 portset
.c_oflag
&= ~OPOST
;
264 portset
.c_lflag
&= ~( ECHO
| ECHONL
| ICANON
| ISIG
| IEXTEN
);
265 portset
.c_cflag
&= ~( CSIZE
| PARENB
| CRTSCTS
);
266 portset
.c_cflag
|= CS8
| CREAD
| CLOCAL
;
271 cfsetospeed(&portset
, p
->speed
);
272 cfsetispeed(&portset
, B0
);
275 tcsetattr(p
->fd
, TCSANOW
, &portset
);
277 /* make sure the frame buffer is there... */
278 p
->framebuf
= (unsigned char *) malloc(p
->width
* p
->height
);
279 if (p
->framebuf
== NULL
) {
280 report(RPT_ERR
, "%s: unable to create framebuffer", drvthis
->name
);
283 memset(p
->framebuf
, ' ', p
->width
* p
->height
);
285 /* make sure the framebuffer backing store is there... */
286 p
->backingstore
= (unsigned char *) malloc(p
->width
* p
->height
);
287 if (p
->backingstore
== NULL
) {
288 report(RPT_ERR
, "%s: unable to create framebuffer backing store", drvthis
->name
);
291 memset(p
->backingstore
, ' ', p
->width
* p
->height
);
293 /* Set display-specific stuff.. */
295 report(RPT_INFO
, "%s: rebooting LCD...", drvthis
->name
);
296 CFontz633_reboot(drvthis
);
300 CFontz633_hidecursor(drvthis
);
302 CFontz633_set_contrast(drvthis
, p
->contrast
);
303 CFontz633_no_live_report(drvthis
);
304 CFontz633_hardware_clear(drvthis
);
306 report(RPT_DEBUG
, "%s: init() done", drvthis
->name
);
313 * Close the driver (do necessary clean-up).
314 * \param drvthis Pointer to driver structure.
317 CFontz633_close (Driver
*drvthis
)
319 PrivateData
*p
= drvthis
->private_data
;
330 free(p
->backingstore
);
331 p
->backingstore
= NULL
;
335 drvthis
->store_private_ptr(drvthis
, NULL
);
340 * Return the display width in characters.
341 * \param drvthis Pointer to driver structure.
342 * \return Number of characters the display is wide.
345 CFontz633_width (Driver
*drvthis
)
347 PrivateData
*p
= drvthis
->private_data
;
354 * Return the display height in characters.
355 * \param drvthis Pointer to driver structure.
356 * \return Number of characters the display is high.
359 CFontz633_height (Driver
*drvthis
)
361 PrivateData
*p
= drvthis
->private_data
;
368 * Return the width of a character in pixels.
369 * \param drvthis Pointer to driver structure.
370 * \return Number of pixel columns a character cell is wide.
373 CFontz633_cellwidth (Driver
*drvthis
)
375 PrivateData
*p
= drvthis
->private_data
;
382 * Return the height of a character in pixels.
383 * \param drvthis Pointer to driver structure.
384 * \return Number of pixel lines a character cell is high.
387 CFontz633_cellheight (Driver
*drvthis
)
389 PrivateData
*p
= drvthis
->private_data
;
391 return p
->cellheight
;
396 * Flush data on screen to the LCD.
397 * \param drvthis Pointer to driver structure.
400 CFontz633_flush (Driver
*drvthis
)
402 PrivateData
*p
= drvthis
->private_data
;
405 #if defined(CF635_FLUSH)
406 int len
= p
->width
* p
->height
;
407 unsigned char out
[3];
409 for (i
= 0; i
< len
; i
++) {
410 if (p
->framebuf
[i
] != p
->backingstore
[i
]) {
411 out
[0] = (unsigned char) (i
% p
->width
); // column
412 out
[1] = (unsigned char) (i
/ p
->width
); // line
413 out
[2] = p
->framebuf
[i
]; // character
414 send_bytes_message(p
->fd
, CF633_Send_Data_to_LCD
, 3, out
);
415 p
->backingstore
[i
] = p
->framebuf
[i
];
420 * We don't use delta update yet.
421 * It is possible but not easy, we can only update a line, full or begining.
423 unsigned char *xp
= p
->framebuf
;
424 unsigned char *xq
= p
->backingstore
;
426 for (i
= 0; i
< p
->width
; i
++) {
427 if (*xp
++ != *xq
++) {
428 send_bytes_message(p
->fd
, CF633_Set_LCD_Contents_Line_One
, 16, p
->framebuf
);
429 memcpy(p
->backingstore
, p
->framebuf
, p
->width
);
434 xp
= p
->framebuf
+ p
->width
;
435 xq
= p
->backingstore
+ p
->width
;
437 for (i
= 0; i
< p
->width
; i
++) {
438 if (*xp
++ != *xq
++) {
439 send_bytes_message(p
->fd
, CF633_Set_LCD_Contents_Line_Two
, 16, p
->framebuf
+ p
->width
);
440 memcpy(p
->backingstore
+ p
->width
, p
->framebuf
+ p
->width
, p
->width
);
444 #endif /* defined(CF635_FLUSH) */
449 * Get next key from the KeyRing.
450 * \param drvthis Pointer to driver structure.
451 * \return String representation of the key.
453 MODULE_EXPORT
const char *
454 CFontz633_get_key (Driver
*drvthis
)
456 // PrivateData *p = drvthis->private_data;
457 unsigned char key
= GetKeyFromKeyRing(&keyring
);
469 case CF633_KEY_RIGHT
:
472 case CF633_KEY_ENTER
:
473 return "Enter"; /* Is this correct ? */
475 case CF633_KEY_ESCAPE
:
480 report(RPT_INFO
, "%s: Untreated key 0x%02X", drvthis
->name
, key
);
489 * Print a character on the screen at position (x,y).
490 * The upper-left corner is (1,1), the lower-right corner is (p->width, p->height).
491 * \param drvthis Pointer to driver structure.
492 * \param x Horizontal character position (column).
493 * \param y Vertical character position (row).
494 * \param c Character that gets written.
497 CFontz633_chr (Driver
*drvthis
, int x
, int y
, char c
)
499 PrivateData
*p
= drvthis
->private_data
;
504 if ((x
>= 0) && (y
>= 0) && (x
< p
->width
) && (y
< p
->height
))
505 p
->framebuf
[(y
* p
->width
) + x
] = c
;
510 * Get current LCD contrast.
511 * This is only the locally stored contrast, the contrast value
512 * cannot be retrieved from the LCD.
513 * \param drvthis Pointer to driver structure.
514 * \return Stored contrast in promille.
517 CFontz633_get_contrast (Driver
*drvthis
)
519 PrivateData
*p
= drvthis
->private_data
;
526 * Change LCD contrast.
527 * \param drvthis Pointer to driver structure.
528 * \param promille New contrast value in promille.
531 CFontz633_set_contrast (Driver
*drvthis
, int promille
)
533 PrivateData
*p
= drvthis
->private_data
;
534 int hardware_contrast
;
537 if (promille
< 0 || promille
> 1000)
540 /* store the software value since there is not get */
541 p
->contrast
= promille
;
543 /* map range [0, 1000] -> [0, 50] that the hardware understands */
544 hardware_contrast
= p
->contrast
/ 20;
545 send_onebyte_message(p
->fd
, CF633_Set_LCD_Contrast
, hardware_contrast
);
550 * Retrieve brightness.
551 * \param drvthis Pointer to driver structure.
552 * \param state Brightness state (on/off) for which we want the value.
553 * \return Stored brightness in promille.
556 CFontz633_get_brightness(Driver
*drvthis
, int state
)
558 PrivateData
*p
= drvthis
->private_data
;
560 return (state
== BACKLIGHT_ON
) ? p
->brightness
: p
->offbrightness
;
565 * Set on/off brightness.
566 * \param drvthis Pointer to driver structure.
567 * \param state Brightness state (on/off) for which we want to store the value.
568 * \param promille New brightness in promille.
571 CFontz633_set_brightness(Driver
*drvthis
, int state
, int promille
)
573 PrivateData
*p
= drvthis
->private_data
;
576 if (promille
< 0 || promille
> 1000)
579 /* store the software value since there is not get */
580 if (state
== BACKLIGHT_ON
) {
581 p
->brightness
= promille
;
582 //CFontz633_backlight(drvthis, BACKLIGHT_ON);
585 p
->offbrightness
= promille
;
586 //CFontz633_backlight(drvthis, BACKLIGHT_OFF);
592 * Turn the LCD backlight on or off.
593 * \param drvthis Pointer to driver structure.
594 * \param on New backlight status.
597 CFontz633_backlight (Driver
*drvthis
, int on
)
599 PrivateData
*p
= drvthis
->private_data
;
600 int hardware_value
= (on
== BACKLIGHT_ON
)
604 /* map range [0, 1000] -> [0, 100] that the hardware understands */
605 hardware_value
/= 10;
606 send_onebyte_message(p
->fd
, CF633_Set_LCD_And_Keypad_Backlight
, hardware_value
);
611 * Get rid of the blinking cursor.
612 * \param drvthis Pointer to driver structure.
615 CFontz633_hidecursor (Driver
*drvthis
)
617 PrivateData
*p
= drvthis
->private_data
;
619 send_onebyte_message(p
->fd
, CF633_Set_LCD_Cursor_Style
, 0);
624 * Stop live reporting of temperature.
625 * \param drvthis Pointer to driver structure.
628 CFontz633_no_live_report (Driver
*drvthis
)
630 PrivateData
*p
= drvthis
->private_data
;
631 unsigned char out
[2] = { 0, 0 };
633 for (out
[0] = 0; out
[0] < 8; out
[0]++) {
634 send_bytes_message(p
->fd
, CF633_Set_Up_Live_Fan_or_Temperature_Display
, 2, out
);
640 * Stop the reporting of any fan.
641 * \param drvthis Pointer to driver structure.
644 CFontz633_no_fan_report (Driver
*drvthis
)
646 PrivateData
*p
= drvthis
->private_data
;
648 send_onebyte_message(p
->fd
, CF633_Set_Up_Fan_Reporting
, 0);
653 * Stop the reporting of any temperature.
654 * \param drvthis Pointer to driver structure.
657 CFontz633_no_temp_report (Driver
*drvthis
)
659 PrivateData
*p
= drvthis
->private_data
;
660 unsigned char out
[4] = { 0, 0, 0, 0 };
662 send_bytes_message(p
->fd
, CF633_Set_Up_Temperature_Reporting
, 4, out
);
667 * Reset the LCD display.
668 * \param drvthis Pointer to driver structure.
671 CFontz633_reboot (Driver
*drvthis
)
673 PrivateData
*p
= drvthis
->private_data
;
674 unsigned char out
[3] = { 8, 18, 99 };
676 send_bytes_message(p
->fd
, CF633_Reboot
, 3, out
);
682 * Draw a vertical bar bottom-up.
683 * \param drvthis Pointer to driver structure.
684 * \param x Horizontal character position (column) of the starting point.
685 * \param y Vertical character position (row) of the starting point.
686 * \param len Number of characters that the bar is high at 100%
687 * \param promille Current height level of the bar in promille.
688 * \param options Options (currently unused).
691 CFontz633_vbar (Driver
*drvthis
, int x
, int y
, int len
, int promille
, int options
)
693 PrivateData
*p
= drvthis
->private_data
;
695 if (p
->ccmode
!= vbar
) {
696 unsigned char vBar
[p
->cellheight
];
699 if (p
->ccmode
!= standard
) {
700 /* Not supported(yet) */
701 report(RPT_WARNING
, "%s: vbar: cannot combine two modes using user-defined characters",
707 memset(vBar
, 0x00, sizeof(vBar
));
709 for (i
= 1; i
< p
->cellheight
; i
++) {
710 // add pixel line per pixel line ...
711 vBar
[p
->cellheight
- i
] = 0xFF;
712 CFontz633_set_char(drvthis
, i
, vBar
);
716 lib_vbar_static(drvthis
, x
, y
, len
, promille
, options
, p
->cellheight
, 0);
721 * Draw a horizontal bar to the right.
722 * \param drvthis Pointer to driver structure.
723 * \param x Horizontal character position (column) of the starting point.
724 * \param y Vertical character position (row) of the starting point.
725 * \param len Number of characters that the bar is long at 100%
726 * \param promille Current length level of the bar in promille.
727 * \param options Options (currently unused).
730 CFontz633_hbar (Driver
*drvthis
, int x
, int y
, int len
, int promille
, int options
)
732 PrivateData
*p
= drvthis
->private_data
;
734 if (p
->ccmode
!= hbar
) {
735 unsigned char hBar
[p
->cellheight
];
738 if (p
->ccmode
!= standard
) {
739 /* Not supported(yet) */
740 report(RPT_WARNING
, "%s: hbar: cannot combine two modes using user-defined characters",
746 memset(hBar
, 0x00, sizeof(hBar
));
748 for (i
= 1; i
<= p
->cellwidth
; i
++) {
749 // fill pixel columns from left to right.
750 memset(hBar
, 0xFF & ~((1 << (p
->cellwidth
- i
)) - 1), sizeof(hBar
)-1);
751 CFontz633_set_char(drvthis
, i
, hBar
);
755 lib_hbar_static(drvthis
, x
, y
, len
, promille
, options
, p
->cellwidth
, 0);
760 * Write a big number to the screen.
761 * \param drvthis Pointer to driver structure.
762 * \param x Horizontal character position (column).
763 * \param num Character to write (0 - 10 with 10 representing ':')
766 CFontz633_num(Driver
*drvthis
, int x
, int num
)
768 PrivateData
*p
= drvthis
->private_data
;
771 if ((num
< 0) || (num
> 10))
774 if (p
->ccmode
!= bignum
) {
775 if (p
->ccmode
!= standard
) {
776 /* Not supported (yet) */
777 report(RPT_WARNING
, "%s: num: cannot combine two modes using user-defined characters",
787 // Lib_adv_bignum does everything needed to show the bignumbers.
788 lib_adv_bignum(drvthis
, x
, num
, 0, do_init
);
793 * Get total number of custom characters available.
794 * \param drvthis Pointer to driver structure.
795 * \return Number of custom characters (always NUM_CCs).
798 CFontz633_get_free_chars (Driver
*drvthis
)
800 //PrivateData *p = drvthis->private_data;
807 * Define a custom character and write it to the LCD.
808 * \param drvthis Pointer to driver structure.
809 * \param n Custom character to define [0 - (NUM_CCs-1)].
810 * \param dat Array of 8(=cellheight) bytes, each representing a pixel row
811 * starting from the top to bottom.
812 * The bits in each byte represent the pixels where the LSB
813 * (least significant bit) is the rightmost pixel in each pixel row.
816 CFontz633_set_char (Driver
*drvthis
, int n
, unsigned char *dat
)
818 PrivateData
*p
= drvthis
->private_data
;
819 unsigned char out
[9];
820 unsigned char mask
= (1 << p
->cellwidth
) - 1;
823 if ((n
< 0) || (n
>= NUM_CCs
))
828 out
[0] = n
; /* Custom char to define. xxx */
830 for (row
= 0; row
< p
->cellheight
; row
++) {
831 out
[row
+1] = dat
[row
] & mask
;
833 send_bytes_message(p
->fd
, CF633_Set_LCD_Special_Character_Data
, 9, out
);
838 * Place an icon on the screen.
839 * \param drvthis Pointer to driver structure.
840 * \param x Horizontal character position (column).
841 * \param y Vertical character position (row).
842 * \param icon synbolic value representing the icon.
843 * \return Information whether the icon is handled here or needs to be handled by the server core.
846 CFontz633_icon (Driver
*drvthis
, int x
, int y
, int icon
)
848 PrivateData
*p
= drvthis
->private_data
;
850 static unsigned char heart_open
[] =
859 static unsigned char heart_filled
[] =
868 static unsigned char arrow_up
[] =
877 static unsigned char arrow_down
[] =
887 static unsigned char arrow_left[] =
896 static unsigned char arrow_right[] =
906 static unsigned char checkbox_off
[] =
915 static unsigned char checkbox_on
[] =
924 static unsigned char checkbox_gray
[] =
934 static unsigned char selector_left[] =
943 static unsigned char selector_right[] =
952 static unsigned char ellipsis[] =
961 static unsigned char block_filled[] =
972 /* Yes we know, this is a VERY BAD implementation :-) */
974 case ICON_BLOCK_FILLED
:
975 CFontz633_chr(drvthis
, x
, y
, 255);
977 case ICON_HEART_FILLED
:
979 CFontz633_set_char(drvthis
, 0, heart_filled
);
980 CFontz633_chr(drvthis
, x
, y
, 0);
982 case ICON_HEART_OPEN
:
984 CFontz633_set_char(drvthis
, 0, heart_open
);
985 CFontz633_chr(drvthis
, x
, y
, 0);
989 CFontz633_set_char(drvthis
, 1, arrow_up
);
990 CFontz633_chr(drvthis
, x
, y
, 1);
992 case ICON_ARROW_DOWN
:
994 CFontz633_set_char(drvthis
, 2, arrow_down
);
995 CFontz633_chr(drvthis
, x
, y
, 2);
997 case ICON_ARROW_LEFT
:
998 CFontz633_chr(drvthis
, x
, y
, 0x7F);
1000 case ICON_ARROW_RIGHT
:
1001 CFontz633_chr(drvthis
, x
, y
, 0x7E);
1003 case ICON_CHECKBOX_OFF
:
1005 CFontz633_set_char(drvthis
, 3, checkbox_off
);
1006 CFontz633_chr(drvthis
, x
, y
, 3);
1008 case ICON_CHECKBOX_ON
:
1010 CFontz633_set_char(drvthis
, 4, checkbox_on
);
1011 CFontz633_chr(drvthis
, x
, y
, 4);
1013 case ICON_CHECKBOX_GRAY
:
1015 CFontz633_set_char(drvthis
, 5, checkbox_gray
);
1016 CFontz633_chr(drvthis
, x
, y
, 5);
1019 return -1; /* Let the core do other icons */
1027 * \param drvthis Pointer to driver structure.
1030 CFontz633_clear (Driver
*drvthis
)
1032 PrivateData
*p
= drvthis
->private_data
;
1034 memset(p
->framebuf
, ' ', p
->width
* p
->height
);
1035 p
->ccmode
= standard
;
1040 * Clear the LCD using hardware commands.
1041 * \param drvthis Pointer to driver structure.
1044 CFontz633_hardware_clear (Driver
*drvthis
)
1046 PrivateData
*p
= drvthis
->private_data
;
1048 send_zerobyte_message(p
->fd
, CF633_Clear_LCD_Screen
);
1053 * Print a string on the screen at position (x,y).
1054 * The upper-left corner is (1,1), the lower-right corner is (p->width, p->height).
1055 * \param drvthis Pointer to driver structure.
1056 * \param x Horizontal character position (column).
1057 * \param y Vertical character position (row).
1058 * \param string String that gets written.
1061 CFontz633_string (Driver
*drvthis
, int x
, int y
, const char string
[])
1063 PrivateData
*p
= drvthis
->private_data
;
1066 /* Convert 1-based coords to 0-based... */
1070 if ((y
< 0) || (y
>= p
->height
))
1073 for (i
= 0; (string
[i
] != '\0') && (x
< p
->width
); i
++, x
++) {
1074 /* Check for buffer overflows... */
1076 p
->framebuf
[(y
* p
->width
) + x
] = string
[i
];