summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-bitmap-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/lcd-bitmap-common.c')
-rw-r--r--firmware/drivers/lcd-bitmap-common.c166
1 files changed, 115 insertions, 51 deletions
diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c
index 8c38e513c6..94829b5d0c 100644
--- a/firmware/drivers/lcd-bitmap-common.c
+++ b/firmware/drivers/lcd-bitmap-common.c
@@ -40,43 +40,70 @@
40#define MAIN_LCD 40#define MAIN_LCD
41#endif 41#endif
42 42
43void LCDFN(set_framebuffer)(FBFN(data) *fb) 43#ifdef MAIN_LCD
44{ 44#define THIS_STRIDE STRIDE_MAIN
45 if (fb) 45#else
46 LCDFN(framebuffer) = fb; 46#define THIS_STRIDE STRIDE_REMOTE
47 else 47#endif
48 LCDFN(framebuffer) = &LCDFN(static_framebuffer)[0][0];
49}
50 48
49extern void viewport_set_buffer(struct viewport *vp,
50 struct frame_buffer_t *buffer,
51 const enum screen_type screen); /* viewport.c */
51/* 52/*
52 * draws the borders of the current viewport 53 * draws the borders of the current viewport
53 **/ 54 **/
54void LCDFN(draw_border_viewport)(void) 55void LCDFN(draw_border_viewport)(void)
55{ 56{
56 LCDFN(drawrect)(0, 0, current_vp->width, current_vp->height); 57 LCDFN(drawrect)(0, 0, LCDFN(current_viewport)->width, LCDFN(current_viewport)->height);
57} 58}
58 59
59/* 60/*
60 * fills the rectangle formed by current_vp 61 * fills the rectangle formed by LCDFN(current_viewport)
61 **/ 62 **/
62void LCDFN(fill_viewport)(void) 63void LCDFN(fill_viewport)(void)
63{ 64{
64 LCDFN(fillrect)(0, 0, current_vp->width, current_vp->height); 65 LCDFN(fillrect)(0, 0, LCDFN(current_viewport)->width, LCDFN(current_viewport)->height);
65} 66}
66 67
67 68
68/*** Viewports ***/ 69/*** Viewports ***/
69 70/* init_viewport Notes: When a viewport is initialized
70void LCDFN(set_viewport)(struct viewport* vp) 71 * if vp->buffer is NULL the default frame_buffer is assigned
72 * likewise the actual buffer, stride, get_address_fn
73 * are all filled with values from the default buffer if they are not set
74 * RETURNS either the viewport you passed or the default viewport if vp == NULL
75 */
76struct viewport* LCDFN(init_viewport)(struct viewport* vp)
71{ 77{
72 if (vp == NULL) 78 struct frame_buffer_t *fb_default = &LCDFN(framebuffer_default);
73 current_vp = &default_vp; 79 if (!vp) /* NULL vp grabs default viewport */
80 vp = &default_vp;
81
82 /* use defaults if no buffer is provided */
83 if (vp->buffer == NULL || vp->buffer->elems == 0)
84 vp->buffer = fb_default;
74 else 85 else
75 current_vp = vp; 86 {
87 if (vp->buffer->stride == 0)
88 vp->buffer->stride = fb_default->stride;
89
90 if (vp->buffer->data == NULL)
91 vp->buffer->data = fb_default->data;
92
93 if (vp->buffer->get_address_fn == NULL)
94 vp->buffer->get_address_fn = fb_default->get_address_fn;
95 }
96 return vp;
97}
98struct viewport* LCDFN(set_viewport_ex)(struct viewport* vp, int flags)
99{
100 vp = LCDFN(init_viewport)(vp);
101 struct viewport* last_vp = LCDFN(current_viewport);
102 LCDFN(current_viewport) = vp;
76 103
77#if LCDM(DEPTH) > 1 104#if LCDM(DEPTH) > 1
78 LCDFN(set_foreground)(current_vp->fg_pattern); 105 LCDFN(set_foreground)(vp->fg_pattern);
79 LCDFN(set_background)(current_vp->bg_pattern); 106 LCDFN(set_background)(vp->bg_pattern);
80#endif 107#endif
81 108
82#if defined(SIMULATOR) 109#if defined(SIMULATOR)
@@ -84,10 +111,11 @@ void LCDFN(set_viewport)(struct viewport* vp)
84 * be considered an error - the viewport will not draw as it might be 111 * be considered an error - the viewport will not draw as it might be
85 * expected. 112 * expected.
86 */ 113 */
87 if((unsigned) current_vp->x > (unsigned) LCDM(WIDTH) 114
88 || (unsigned) current_vp->y > (unsigned) LCDM(HEIGHT) 115 if((unsigned) vp->x > (unsigned) LCDM(WIDTH)
89 || current_vp->x + current_vp->width > LCDM(WIDTH) 116 || (unsigned) vp->y > (unsigned) LCDM(HEIGHT)
90 || current_vp->y + current_vp->height > LCDM(HEIGHT)) 117 || vp->x + vp->width > LCDM(WIDTH)
118 || vp->y + vp->height > LCDM(HEIGHT))
91 { 119 {
92#if !defined(HAVE_VIEWPORT_CLIP) 120#if !defined(HAVE_VIEWPORT_CLIP)
93 DEBUGF("ERROR: " 121 DEBUGF("ERROR: "
@@ -95,27 +123,68 @@ void LCDFN(set_viewport)(struct viewport* vp)
95 DEBUGF("NOTE: " 123 DEBUGF("NOTE: "
96#endif 124#endif
97 "set_viewport out of bounds: x: %d y: %d width: %d height:%d\n", 125 "set_viewport out of bounds: x: %d y: %d width: %d height:%d\n",
98 current_vp->x, current_vp->y, 126 vp->x, vp->y, vp->width, vp->height);
99 current_vp->width, current_vp->height);
100 } 127 }
101#endif 128#endif
129 if(last_vp)
130 {
131 if ((flags & VP_FLAG_CLEAR_FLAG) == VP_FLAG_CLEAR_FLAG)
132 last_vp->flags &= ~flags;
133 else
134 last_vp->flags |= flags;
135 }
136
137 return last_vp;
138}
139
140struct viewport* LCDFN(set_viewport)(struct viewport* vp)
141{
142 return LCDFN(set_viewport_ex)(vp, VP_FLAG_VP_DIRTY);
102} 143}
103 144
104struct viewport *LCDFN(get_viewport)(bool *is_default) 145struct viewport *LCDFN(get_viewport)(bool *is_default)
105{ 146{
106 *is_default = (current_vp == &default_vp); 147#if 0
107 return current_vp; 148 *is_default = memcmp(LCDFN(current_viewport),
149 &default_vp, sizeof(struct viewport)) == 0;
150#else
151 *is_default = LCDFN(current_viewport) == &default_vp;
152#endif
153
154 return LCDFN(current_viewport);
108} 155}
109 156
110void LCDFN(update_viewport)(void) 157void LCDFN(update_viewport)(void)
111{ 158{
112 LCDFN(update_rect)(current_vp->x, current_vp->y, 159 struct viewport* vp = LCDFN(current_viewport);
113 current_vp->width, current_vp->height); 160 if (vp->buffer->stride != LCDFN(framebuffer_default.stride))
161 {
162 LCDFN(update_viewport_rect)(0,0, vp->width, vp->height);
163 return;
164 }
165 LCDFN(update_rect)(vp->x, vp->y, vp->width, vp->height);
114} 166}
115 167
116void LCDFN(update_viewport_rect)(int x, int y, int width, int height) 168void LCDFN(update_viewport_rect)(int x, int y, int width, int height)
117{ 169{
118 LCDFN(update_rect)(current_vp->x + x, current_vp->y + y, width, height); 170 struct viewport* vp = LCDFN(current_viewport);
171
172 /* handle the case of viewport with differing stride from main screen */
173 if (vp->buffer->stride != LCDFN(framebuffer_default.stride))
174 {
175 struct frame_buffer_t *fb = vp->buffer;
176 viewport_set_buffer(vp, NULL, 0);
177
178 LCDFN(bitmap_part)
179 (fb->FBFN(ptr), vp->x, vp->y, fb->stride,
180 vp->x + x, vp->y + y, width, height);
181
182 LCDFN(update_rect)(vp->x + x, vp->y + y, width, height);
183 viewport_set_buffer(vp, fb, 0);
184 return;
185 }
186
187 LCDFN(update_rect)(vp->x + x, vp->y + y, width, height);
119} 188}
120 189
121#ifndef BOOTLOADER 190#ifndef BOOTLOADER
@@ -123,9 +192,9 @@ void LCDFN(update_viewport_rect)(int x, int y, int width, int height)
123static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str) 192static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str)
124{ 193{
125 unsigned short *ucs; 194 unsigned short *ucs;
126 font_lock(current_vp->font, true); 195 font_lock(LCDFN(current_viewport)->font, true);
127 struct font* pf = font_get(current_vp->font); 196 struct font* pf = font_get(LCDFN(current_viewport)->font);
128 int vp_flags = current_vp->flags; 197 int vp_flags = LCDFN(current_viewport)->flags;
129 int rtl_next_non_diac_width, last_non_diacritic_width; 198 int rtl_next_non_diac_width, last_non_diacritic_width;
130 199
131 if ((vp_flags & VP_FLAG_ALIGNMENT_MASK) != 0) 200 if ((vp_flags & VP_FLAG_ALIGNMENT_MASK) != 0)
@@ -136,13 +205,13 @@ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str)
136 /* center takes precedence */ 205 /* center takes precedence */
137 if (vp_flags & VP_FLAG_ALIGN_CENTER) 206 if (vp_flags & VP_FLAG_ALIGN_CENTER)
138 { 207 {
139 x = ((current_vp->width - w)/ 2) + x; 208 x = ((LCDFN(current_viewport)->width - w)/ 2) + x;
140 if (x < 0) 209 if (x < 0)
141 x = 0; 210 x = 0;
142 } 211 }
143 else 212 else
144 { 213 {
145 x = current_vp->width - w - x; 214 x = LCDFN(current_viewport)->width - w - x;
146 x += ofs; 215 x += ofs;
147 ofs = 0; 216 ofs = 0;
148 } 217 }
@@ -158,7 +227,7 @@ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str)
158 int width, base_width, drawmode = 0, base_ofs = 0; 227 int width, base_width, drawmode = 0, base_ofs = 0;
159 const unsigned short next_ch = ucs[1]; 228 const unsigned short next_ch = ucs[1];
160 229
161 if (x >= current_vp->width) 230 if (x >= LCDFN(current_viewport)->width)
162 break; 231 break;
163 232
164 is_diac = is_diacritic(*ucs, &is_rtl); 233 is_diac = is_diacritic(*ucs, &is_rtl);
@@ -219,8 +288,8 @@ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str)
219 * buffer using OR, and then draw the final bitmap instead of the 288 * buffer using OR, and then draw the final bitmap instead of the
220 * chars, without touching the drawmode 289 * chars, without touching the drawmode
221 **/ 290 **/
222 drawmode = current_vp->drawmode; 291 drawmode = LCDFN(current_viewport)->drawmode;
223 current_vp->drawmode = DRMODE_FG; 292 LCDFN(current_viewport)->drawmode = DRMODE_FG;
224 293
225 base_ofs = (base_width - width) / 2; 294 base_ofs = (base_width - width) / 2;
226 } 295 }
@@ -237,7 +306,7 @@ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str)
237 y, width - ofs, pf->height); 306 y, width - ofs, pf->height);
238 if (is_diac) 307 if (is_diac)
239 { 308 {
240 current_vp->drawmode = drawmode; 309 LCDFN(current_viewport)->drawmode = drawmode;
241 } 310 }
242 311
243 if (next_ch) 312 if (next_ch)
@@ -256,7 +325,7 @@ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str)
256 } 325 }
257 } 326 }
258 } 327 }
259 font_lock(current_vp->font, false); 328 font_lock(LCDFN(current_viewport)->font, false);
260} 329}
261#else /* BOOTLOADER */ 330#else /* BOOTLOADER */
262/* put a string at a given pixel position, skipping first ofs pixel columns */ 331/* put a string at a given pixel position, skipping first ofs pixel columns */
@@ -375,7 +444,7 @@ static struct scrollinfo* find_scrolling_line(int x, int y)
375 for(i=0; i<LCDFN(scroll_info).lines; i++) 444 for(i=0; i<LCDFN(scroll_info).lines; i++)
376 { 445 {
377 s = &LCDFN(scroll_info).scroll[i]; 446 s = &LCDFN(scroll_info).scroll[i];
378 if (s->x == x && s->y == y && s->vp == current_vp) 447 if (s->x == x && s->y == y && s->vp == LCDFN(current_viewport))
379 return s; 448 return s;
380 } 449 }
381 return NULL; 450 return NULL;
@@ -411,13 +480,13 @@ static bool LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string,
411 480
412 /* prepare rectangle for scrolling. x and y must be calculated early 481 /* prepare rectangle for scrolling. x and y must be calculated early
413 * for find_scrolling_line() to work */ 482 * for find_scrolling_line() to work */
414 cwidth = font_get(current_vp->font)->maxwidth; 483 cwidth = font_get(LCDFN(current_viewport)->font)->maxwidth;
415 height = font_get(current_vp->font)->height; 484 height = font_get(LCDFN(current_viewport)->font)->height;
416 y = y * (linebased ? height : 1); 485 y = y * (linebased ? height : 1);
417 x = x * (linebased ? cwidth : 1); 486 x = x * (linebased ? cwidth : 1);
418 width = current_vp->width - x; 487 width = LCDFN(current_viewport)->width - x;
419 488
420 if (y >= current_vp->height) 489 if (y >= LCDFN(current_viewport)->height)
421 return false; 490 return false;
422 491
423 s = find_scrolling_line(x, y); 492 s = find_scrolling_line(x, y);
@@ -430,7 +499,7 @@ static bool LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string,
430 * the string width is too small to scroll the scrolling line is 499 * the string width is too small to scroll the scrolling line is
431 * cleared as well */ 500 * cleared as well */
432 if (w < width || restart) { 501 if (w < width || restart) {
433 LCDFN(scroll_stop_viewport_rect)(current_vp, x, y, width, height); 502 LCDFN(scroll_stop_viewport_rect)(LCDFN(current_viewport), x, y, width, height);
434 LCDFN(putsxyofs)(x, y, x_offset, string); 503 LCDFN(putsxyofs)(x, y, x_offset, string);
435 /* nothing to scroll, or out of scrolling lines. Either way, get out */ 504 /* nothing to scroll, or out of scrolling lines. Either way, get out */
436 if (w < width || LCDFN(scroll_info).lines >= LCDM(SCROLLABLE_LINES)) 505 if (w < width || LCDFN(scroll_info).lines >= LCDM(SCROLLABLE_LINES))
@@ -443,7 +512,7 @@ static bool LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string,
443 strlcpy(s->linebuffer, string, sizeof(s->linebuffer)); 512 strlcpy(s->linebuffer, string, sizeof(s->linebuffer));
444 /* scroll bidirectional or forward only depending on the string width */ 513 /* scroll bidirectional or forward only depending on the string width */
445 if ( LCDFN(scroll_info).bidir_limit ) { 514 if ( LCDFN(scroll_info).bidir_limit ) {
446 s->bidir = w < (current_vp->width) * 515 s->bidir = w < (LCDFN(current_viewport)->width) *
447 (100 + LCDFN(scroll_info).bidir_limit) / 100; 516 (100 + LCDFN(scroll_info).bidir_limit) / 100;
448 } 517 }
449 else 518 else
@@ -457,7 +526,7 @@ static bool LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string,
457 s->y = y; 526 s->y = y;
458 s->width = width; 527 s->width = width;
459 s->height = height; 528 s->height = height;
460 s->vp = current_vp; 529 s->vp = LCDFN(current_viewport);
461 s->start_tick = current_tick + LCDFN(scroll_info).delay; 530 s->start_tick = current_tick + LCDFN(scroll_info).delay;
462 LCDFN(scroll_info).lines++; 531 LCDFN(scroll_info).lines++;
463 } else { 532 } else {
@@ -497,11 +566,6 @@ bool LCDFN(puts_scroll)(int x, int y, const unsigned char *string)
497 566
498#if !defined(HAVE_LCD_COLOR) || !defined(MAIN_LCD) 567#if !defined(HAVE_LCD_COLOR) || !defined(MAIN_LCD)
499/* see lcd-16bit-common.c for others */ 568/* see lcd-16bit-common.c for others */
500#ifdef MAIN_LCD
501#define THIS_STRIDE STRIDE_MAIN
502#else
503#define THIS_STRIDE STRIDE_REMOTE
504#endif
505 569
506void LCDFN(bmp_part)(const struct bitmap* bm, int src_x, int src_y, 570void LCDFN(bmp_part)(const struct bitmap* bm, int src_x, int src_y,
507 int x, int y, int width, int height) 571 int x, int y, int width, int height)