4 * This file is part of BeRTOS.
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.
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 St, Fifth Floor, Boston, MA 02110-1301 USA
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.
29 * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
30 * Copyright 2000,2001 Bernie Innocenti <bernie@codewiz.org>
35 * \author Bernie Innocenti <bernie@codewiz.org>
37 * \brief Custom Qt widget for emulating a graphics LCD display (implementation)
42 *#* Revision 1.1 2006/01/16 03:51:35 bernie
43 *#* Add LCD Qt emulator.
49 #include <qsizepolicy.h>
56 #define LCD_FG_COLOR 0x0, 0x0, 0x0
57 #define LCD_BG_COLOR 0xBB, 0xCC, 0xBB
60 EmulLCD::EmulLCD(QWidget *parent, const char *name) :
61 QFrame(parent, name, WRepaintNoErase | WResizeNoErase),
62 lcd_font("courier", 18),
63 fg_color(LCD_FG_COLOR),
64 bg_color(LCD_BG_COLOR),
72 "01234567890123456789"
73 "abcdefghijhlmnopqrst"
74 "ABCDEFGHIJKLMNOPQRST"
75 "!@#$%^&*()_+|{}':?><",
79 lcd_font.setFixedPitch(true);
82 // get exact font size
83 QFontMetrics fm(lcd_font);
84 font_width = fm.width(QChar(' '));
85 font_height = fm.height();
88 setFrameStyle(QFrame::Panel | QFrame::Sunken);
90 frame_width = frameWidth();
100 QSizePolicy EmulLCD::sizePolicy() const
102 return QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed, false);
106 QSize EmulLCD::sizeHint() const
109 font_width * COLS + frame_width * 2,
110 font_height * ROWS + frame_width * 2);
114 void EmulLCD::drawContents(QPainter *p)
120 void EmulLCD::SetPainter(QPainter & p)
122 p.setBackgroundMode(OpaqueMode);
124 p.setBackgroundColor(bg_color);
128 void EmulLCD::RedrawText(QPainter & p)
134 for (r = 0; r < ROWS; r++)
135 for (c = 0; c < COLS; c++)
140 void EmulLCD::PrintChar(QPainter & p, int row, int col)
142 // Fetch char from DD RAM
143 unsigned char c = ddram[row][col];
145 // Map some Hitachi characters to ISO Latin1
149 c = 0xBA; // "degrees" glyph
153 c = 0xB5; // "micro" glyph
156 default: // all others
160 // Draw char on display
161 int x = col * font_width + frame_width;
162 int y = row * font_height + frame_width;
163 bool restore_colors = false;
165 if (show_cursor && (row == cr_row) && (col == cr_col))
167 // Exchange FG/BG colors
169 p.setBackgroundColor(fg_color);
170 restore_colors = true;
173 p.drawText(x, y, x + font_width, y + font_height, 0 /*tf*/,
174 QString(QChar(c)), 1);
178 // Restore FG/BG colors
180 p.setBackgroundColor(bg_color);
185 void EmulLCD::MoveCursor(int r, int c)
187 // Save old cursor position
188 int old_row = cr_row;
189 int old_col = cr_col;
196 if (show_cursor && (old_col != cr_col || old_row != cr_row))
202 PrintChar(p, cr_row, cr_col);
205 PrintChar(p, old_row, old_col);
210 void EmulLCD::ShowCursor(bool show)
214 // Draw (or erase) cursor
217 PrintChar(p, cr_row, cr_col);
221 void EmulLCD::AdvanceCursor()
224 if (cr_col == COLS - 1)
226 if (cr_row == ROWS - 1)
229 MoveCursor(cr_row + 1, 0);
232 MoveCursor(cr_row, cr_col + 1);
236 void EmulLCD::PutChar(unsigned char c)
240 // Write data in CGRAM
241 cgram[cgramaddr] = c;
243 // Auto increment CGRAM address
244 cgramaddr = (cgramaddr + 1) & 0x3F;
249 ddram[cr_row][cr_col] = c;
255 PrintChar(p, cr_row, cr_col);
262 char EmulLCD::GetChar()
264 char c = ddram[cr_row][cr_col];
270 void EmulLCD::Clear()
272 memset(ddram, ' ', sizeof(ddram));
280 void EmulLCD::SetCGRamAddr(unsigned char addr)
282 cgramaddr = addr & (sizeof(cgram) - 1);
286 // Hitachi LM044L register-level emulation
288 #define INI_DISPLAY 0x30
289 #define INI_OP_DISP 0x38 /* 8 bits, 2 lines, 5x7 dots */
290 #define ON_DISPLAY 0x0F /* Switch on display */
291 #define OFF_DISPLAY 0x08 /* Switch off display */
292 #define CLR_DISPLAY 0x01 /* Clear display */
293 #define CURSOR_BLOCK 0x0D /* Show cursor (block) */
294 #define CURSOR_LINE 0x0F /* Show cursor (line) */
295 #define CURSOR_OFF 0x0C /* Hide cursor */
296 #define MODE_DISPL 0x06
297 #define SHIFT_DISPLAY 0x18
298 #define MOVESHIFT_LEFT 0x00
299 #define MOVESHIFT_RIGHT 0x04
300 #define LCD_CGRAMADDR (1<<6)
301 #define LCD_DDRAMADDR (1<<7)
304 extern "C" void Emul_LCDWriteReg(unsigned char d)
306 static const unsigned char lcd_rowaddress[EmulLCD::ROWS] = { 0x80, 0xC0, 0x94, 0xD4 };
311 emul->emulLCD->Clear();
316 emul->emulLCD->ShowCursor(true);
320 emul->emulLCD->ShowCursor(false);
324 // Set DDRAM address?
325 if (d & LCD_DDRAMADDR)
327 for (int i = 0; i < EmulLCD::ROWS; i++)
329 if ((d >= lcd_rowaddress[i]) && (d < lcd_rowaddress[i] + EmulLCD::COLS))
331 emul->emulLCD->MoveCursor(i, d - lcd_rowaddress[i]);
336 else if (d & LCD_CGRAMADDR)
337 emul->emulLCD->SetCGRamAddr(d);
343 extern "C" unsigned char Emul_LCDReadReg(void)
345 return 0; /* This LCD model is never busy ;-) */
349 extern "C" void Emul_LCDWriteData(unsigned char d)
351 emul->emulLCD->PutChar(d);
355 extern "C" unsigned char Emul_LCDReadData(void)
357 return emul->emulLCD->GetChar();
360 #include "EmulLCD.moc"