4 * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
5 * Copyright 2000,2001 Bernardo Innocenti <bernie@codewiz.org>
6 * This file is part of DevLib - See README.devlib for information.
11 * \author Bernardo Innocenti <bernie@develer.com>
13 * \brief Custom Qt widget for emulating a graphics LCD display (implementation)
18 *#* Revision 1.1 2006/01/16 03:51:35 bernie
19 *#* Add LCD Qt emulator.
25 #include <qsizepolicy.h>
32 #define LCD_FG_COLOR 0x0, 0x0, 0x0
33 #define LCD_BG_COLOR 0xBB, 0xCC, 0xBB
36 EmulLCD::EmulLCD(QWidget *parent, const char *name) :
37 QFrame(parent, name, WRepaintNoErase | WResizeNoErase),
38 lcd_font("courier", 18),
39 fg_color(LCD_FG_COLOR),
40 bg_color(LCD_BG_COLOR),
48 "01234567890123456789"
49 "abcdefghijhlmnopqrst"
50 "ABCDEFGHIJKLMNOPQRST"
51 "!@#$%^&*()_+|{}':?><",
55 lcd_font.setFixedPitch(true);
58 // get exact font size
59 QFontMetrics fm(lcd_font);
60 font_width = fm.width(QChar(' '));
61 font_height = fm.height();
64 setFrameStyle(QFrame::Panel | QFrame::Sunken);
66 frame_width = frameWidth();
76 QSizePolicy EmulLCD::sizePolicy() const
78 return QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed, false);
82 QSize EmulLCD::sizeHint() const
85 font_width * COLS + frame_width * 2,
86 font_height * ROWS + frame_width * 2);
90 void EmulLCD::drawContents(QPainter *p)
96 void EmulLCD::SetPainter(QPainter & p)
98 p.setBackgroundMode(OpaqueMode);
100 p.setBackgroundColor(bg_color);
104 void EmulLCD::RedrawText(QPainter & p)
110 for (r = 0; r < ROWS; r++)
111 for (c = 0; c < COLS; c++)
116 void EmulLCD::PrintChar(QPainter & p, int row, int col)
118 // Fetch char from DD RAM
119 unsigned char c = ddram[row][col];
121 // Map some Hitachi characters to ISO Latin1
125 c = 0xBA; // "degrees" glyph
129 c = 0xB5; // "micro" glyph
132 default: // all others
136 // Draw char on display
137 int x = col * font_width + frame_width;
138 int y = row * font_height + frame_width;
139 bool restore_colors = false;
141 if (show_cursor && (row == cr_row) && (col == cr_col))
143 // Exchange FG/BG colors
145 p.setBackgroundColor(fg_color);
146 restore_colors = true;
149 p.drawText(x, y, x + font_width, y + font_height, 0 /*tf*/,
150 QString(QChar(c)), 1);
154 // Restore FG/BG colors
156 p.setBackgroundColor(bg_color);
161 void EmulLCD::MoveCursor(int r, int c)
163 // Save old cursor position
164 int old_row = cr_row;
165 int old_col = cr_col;
172 if (show_cursor && (old_col != cr_col || old_row != cr_row))
178 PrintChar(p, cr_row, cr_col);
181 PrintChar(p, old_row, old_col);
186 void EmulLCD::ShowCursor(bool show)
190 // Draw (or erase) cursor
193 PrintChar(p, cr_row, cr_col);
197 void EmulLCD::AdvanceCursor()
200 if (cr_col == COLS - 1)
202 if (cr_row == ROWS - 1)
205 MoveCursor(cr_row + 1, 0);
208 MoveCursor(cr_row, cr_col + 1);
212 void EmulLCD::PutChar(unsigned char c)
216 // Write data in CGRAM
217 cgram[cgramaddr] = c;
219 // Auto increment CGRAM address
220 cgramaddr = (cgramaddr + 1) & 0x3F;
225 ddram[cr_row][cr_col] = c;
231 PrintChar(p, cr_row, cr_col);
238 char EmulLCD::GetChar()
240 char c = ddram[cr_row][cr_col];
246 void EmulLCD::Clear()
248 memset(ddram, ' ', sizeof(ddram));
256 void EmulLCD::SetCGRamAddr(unsigned char addr)
258 cgramaddr = addr & (sizeof(cgram) - 1);
262 // Hitachi LM044L register-level emulation
264 #define INI_DISPLAY 0x30
265 #define INI_OP_DISP 0x38 /* 8 bits, 2 lines, 5x7 dots */
266 #define ON_DISPLAY 0x0F /* Switch on display */
267 #define OFF_DISPLAY 0x08 /* Switch off display */
268 #define CLR_DISPLAY 0x01 /* Clear display */
269 #define CURSOR_BLOCK 0x0D /* Show cursor (block) */
270 #define CURSOR_LINE 0x0F /* Show cursor (line) */
271 #define CURSOR_OFF 0x0C /* Hide cursor */
272 #define MODE_DISPL 0x06
273 #define SHIFT_DISPLAY 0x18
274 #define MOVESHIFT_LEFT 0x00
275 #define MOVESHIFT_RIGHT 0x04
276 #define LCD_CGRAMADDR (1<<6)
277 #define LCD_DDRAMADDR (1<<7)
280 extern "C" void Emul_LCDWriteReg(unsigned char d)
282 static const unsigned char lcd_rowaddress[EmulLCD::ROWS] = { 0x80, 0xC0, 0x94, 0xD4 };
287 emul->emulLCD->Clear();
292 emul->emulLCD->ShowCursor(true);
296 emul->emulLCD->ShowCursor(false);
300 // Set DDRAM address?
301 if (d & LCD_DDRAMADDR)
303 for (int i = 0; i < EmulLCD::ROWS; i++)
305 if ((d >= lcd_rowaddress[i]) && (d < lcd_rowaddress[i] + EmulLCD::COLS))
307 emul->emulLCD->MoveCursor(i, d - lcd_rowaddress[i]);
312 else if (d & LCD_CGRAMADDR)
313 emul->emulLCD->SetCGRamAddr(d);
319 extern "C" unsigned char Emul_LCDReadReg(void)
321 return 0; /* This LCD model is never busy ;-) */
325 extern "C" void Emul_LCDWriteData(unsigned char d)
327 emul->emulLCD->PutChar(d);
331 extern "C" unsigned char Emul_LCDReadData(void)
333 return emul->emulLCD->GetChar();
336 #include "EmulLCD.moc"