µGFX  2.9
version 2.9
gdisp_driver.h
Go to the documentation of this file.
1 /*
2  * This file is subject to the terms of the GFX License. If a copy of
3  * the license was not distributed with this file, you can obtain one at:
4  *
5  * http://ugfx.io/license.html
6  */
7 
8 /**
9  * @file src/gdisp/gdisp_driver.h
10  * @brief GDISP Graphic Driver subsystem low level driver header.
11  *
12  * @addtogroup GDISP
13  * @{
14  */
15 
16 #ifndef _GDISP_LLD_H
17 #define _GDISP_LLD_H
18 
19 #if GFX_USE_GDISP
20 
21 // Include the GDRIVER infrastructure
22 #include "../gdriver/gdriver.h"
23 
24 // Are we currently compiling the driver itself?
25 #if defined(GDISP_DRIVER_VMT)
26  #define IN_DRIVER GFXON
27 #else
28  #define IN_DRIVER GFXOFF
29 #endif
30 
31 // Is this a multiple driver situation?
32 #if defined(GDISP_DRIVER_LIST)
33  #define IS_MULTIPLE GFXON
34 #else
35  #define IS_MULTIPLE GFXOFF
36 #endif
37 
38 // Do we need to use VMT calling rather than direct calls to the driver?
39 #if IS_MULTIPLE || GDISP_NEED_PIXMAP
40  #define USE_VMT GFXON
41 #else
42  #define USE_VMT GFXOFF
43 #endif
44 
45 // Are we in the pixmap virtual driver
46 #ifndef IN_PIXMAP_DRIVER
47  #define IN_PIXMAP_DRIVER GFXOFF
48 #endif
49 
50 //------------------------------------------------------------------------------------------------------------
51 
52 // Our special auto-detect hardware code which uses the VMT.
53 #define HARDWARE_AUTODETECT 2
54 
55 #if USE_VMT && !IN_DRIVER
56  // Multiple controllers the default is to hardware detect
57  #define HARDWARE_DEFAULT HARDWARE_AUTODETECT
58 #else
59  // The default is not to include code functions that aren't needed
60  #define HARDWARE_DEFAULT GFXOFF
61 #endif
62 
63 //------------------------------------------------------------------------------------------------------------
64 
65 /**
66  * @name GDISP hardware accelerated support
67  * @{
68  */
69  /**
70  * @brief The display hardware can benefit from being de-initialized when usage is complete.
71  * @details Can be set to GFXON, GFXOFF or HARDWARE_AUTODETECT
72  *
73  * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
74  * @note This is most useful for displays such as remote network displays.
75  */
76  #ifndef GDISP_HARDWARE_DEINIT
77  #define GDISP_HARDWARE_DEINIT HARDWARE_DEFAULT
78  #endif
79 
80  /**
81  * @brief The display hardware can benefit from being flushed.
82  * @details Can be set to GFXON, GFXOFF or HARDWARE_AUTODETECT
83  *
84  * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
85  * @note Some controllers ** require ** the application to flush
86  */
87  #ifndef GDISP_HARDWARE_FLUSH
88  #define GDISP_HARDWARE_FLUSH HARDWARE_DEFAULT
89  #endif
90 
91  /**
92  * @brief Hardware streaming writing is supported.
93  * @details Can be set to GFXON, GFXOFF or HARDWARE_AUTODETECT
94  *
95  * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
96  * @note Either GDISP_HARDWARE_STREAM_WRITE or GDISP_HARDWARE_DRAWPIXEL must be provided by each driver
97  */
98  #ifndef GDISP_HARDWARE_STREAM_WRITE
99  #define GDISP_HARDWARE_STREAM_WRITE HARDWARE_DEFAULT
100  #endif
101 
102  /**
103  * @brief Hardware streaming reading of the display surface is supported.
104  * @details Can be set to GFXON, GFXOFF or HARDWARE_AUTODETECT
105  *
106  * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
107  *
108  */
109  #ifndef GDISP_HARDWARE_STREAM_READ
110  #define GDISP_HARDWARE_STREAM_READ HARDWARE_DEFAULT
111  #endif
112 
113  /**
114  * @brief Hardware supports setting the cursor position within the stream window.
115  * @details Can be set to GFXON, GFXOFF or HARDWARE_AUTODETECT
116  *
117  * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
118  * @note This is used to optimise setting of individual pixels within a stream window.
119  * It should therefore not be implemented unless it is cheaper than just setting
120  * a new window.
121  */
122  #ifndef GDISP_HARDWARE_STREAM_POS
123  #define GDISP_HARDWARE_STREAM_POS HARDWARE_DEFAULT
124  #endif
125 
126  /**
127  * @brief Hardware accelerated draw pixel.
128  * @details Can be set to GFXON, GFXOFF or HARDWARE_AUTODETECT
129  *
130  * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
131  * @note Either GDISP_HARDWARE_STREAM_WRITE or GDISP_HARDWARE_DRAWPIXEL must be provided by the driver
132  */
133  #ifndef GDISP_HARDWARE_DRAWPIXEL
134  #define GDISP_HARDWARE_DRAWPIXEL HARDWARE_DEFAULT
135  #endif
136 
137  /**
138  * @brief Hardware accelerated screen clears.
139  * @details Can be set to GFXON, GFXOFF or HARDWARE_AUTODETECT
140  *
141  * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
142  * @note This clears the entire display surface regardless of the clipping area currently set
143  */
144  #ifndef GDISP_HARDWARE_CLEARS
145  #define GDISP_HARDWARE_CLEARS HARDWARE_DEFAULT
146  #endif
147 
148  /**
149  * @brief Hardware accelerated rectangular fills.
150  * @details Can be set to GFXON, GFXOFF or HARDWARE_AUTODETECT
151  *
152  * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
153  */
154  #ifndef GDISP_HARDWARE_FILLS
155  #define GDISP_HARDWARE_FILLS HARDWARE_DEFAULT
156  #endif
157 
158  /**
159  * @brief Hardware accelerated fills from an image.
160  * @details Can be set to GFXON, GFXOFF or HARDWARE_AUTODETECT
161  *
162  * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
163  */
164  #ifndef GDISP_HARDWARE_BITFILLS
165  #define GDISP_HARDWARE_BITFILLS HARDWARE_DEFAULT
166  #endif
167 
168  /**
169  * @brief Hardware accelerated scrolling.
170  * @details Can be set to GFXON, GFXOFF or HARDWARE_AUTODETECT
171  *
172  * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
173  */
174  #ifndef GDISP_HARDWARE_SCROLL
175  #define GDISP_HARDWARE_SCROLL HARDWARE_DEFAULT
176  #endif
177 
178  /**
179  * @brief Reading back of pixel values.
180  * @details Can be set to GFXON, GFXOFF or HARDWARE_AUTODETECT
181  *
182  * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
183  */
184  #ifndef GDISP_HARDWARE_PIXELREAD
185  #define GDISP_HARDWARE_PIXELREAD HARDWARE_DEFAULT
186  #endif
187 
188  /**
189  * @brief The driver supports one or more control commands.
190  * @details Can be set to GFXON, GFXOFF or HARDWARE_AUTODETECT
191  *
192  * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
193  */
194  #ifndef GDISP_HARDWARE_CONTROL
195  #define GDISP_HARDWARE_CONTROL HARDWARE_DEFAULT
196  #endif
197 
198  /**
199  * @brief The driver supports a non-standard query.
200  * @details Can be set to GFXON, GFXOFF or HARDWARE_AUTODETECT
201  *
202  * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
203  */
204  #ifndef GDISP_HARDWARE_QUERY
205  #define GDISP_HARDWARE_QUERY HARDWARE_DEFAULT
206  #endif
207 
208  /**
209  * @brief The driver supports a clipping in hardware.
210  * @details Can be set to GFXON, GFXOFF or HARDWARE_AUTODETECT
211  *
212  * @note HARDWARE_AUTODETECT is only meaningful when GDISP_DRIVER_LIST is defined
213  * @note If this is defined the driver must perform its own clipping on all calls to
214  * the driver and respond appropriately if a parameter is outside the display area.
215  * @note If this is not defined then the software ensures that all calls to the
216  * driver do not exceed the display area (provided GDISP_NEED_CLIP or GDISP_NEED_VALIDATION
217  * has been set).
218  */
219  #ifndef GDISP_HARDWARE_CLIP
220  #define GDISP_HARDWARE_CLIP HARDWARE_DEFAULT
221  #endif
222 /** @} */
223 
224 //------------------------------------------------------------------------------------------------------------
225 
226 // For pixmaps certain routines MUST not be GFXOFF as they are needed for pixmap drawing
227 // Similarly some routines MUST not be GFXON as pixmap's don't provide them.
228 #if GDISP_NEED_PIXMAP && !IN_DRIVER
229  #if !GDISP_HARDWARE_DEINIT
230  #undef GDISP_HARDWARE_DEINIT
231  #define GDISP_HARDWARE_DEINIT HARDWARE_AUTODETECT
232  #endif
233  #if !GDISP_HARDWARE_DRAWPIXEL
234  #undef GDISP_HARDWARE_DRAWPIXEL
235  #define GDISP_HARDWARE_DRAWPIXEL HARDWARE_AUTODETECT
236  #endif
237  #if !GDISP_HARDWARE_PIXELREAD
238  #undef GDISP_HARDWARE_PIXELREAD
239  #define GDISP_HARDWARE_PIXELREAD HARDWARE_AUTODETECT
240  #endif
241  #if !GDISP_HARDWARE_CONTROL
242  #undef GDISP_HARDWARE_CONTROL
243  #define GDISP_HARDWARE_CONTROL HARDWARE_AUTODETECT
244  #endif
245  #if GDISP_HARDWARE_FLUSH == GFXON
246  #undef GDISP_HARDWARE_FLUSH
247  #define GDISP_HARDWARE_FLUSH HARDWARE_AUTODETECT
248  #endif
249  #if GDISP_HARDWARE_STREAM_WRITE == GFXON
250  #undef GDISP_HARDWARE_STREAM_WRITE
251  #define GDISP_HARDWARE_STREAM_WRITE HARDWARE_AUTODETECT
252  #endif
253  #if GDISP_HARDWARE_STREAM_READ == GFXON
254  #undef GDISP_HARDWARE_STREAM_READ
255  #define GDISP_HARDWARE_STREAM_READ HARDWARE_AUTODETECT
256  #endif
257  #if GDISP_HARDWARE_CLEARS == GFXON
258  #undef GDISP_HARDWARE_CLEARS
259  #define GDISP_HARDWARE_CLEARS HARDWARE_AUTODETECT
260  #endif
261  #if GDISP_HARDWARE_FILLS == GFXON
262  #undef GDISP_HARDWARE_FILLS
263  #define GDISP_HARDWARE_FILLS HARDWARE_AUTODETECT
264  #endif
265  #if GDISP_HARDWARE_BITFILLS == GFXON
266  #undef GDISP_HARDWARE_BITFILLS
267  #define GDISP_HARDWARE_BITFILLS HARDWARE_AUTODETECT
268  #endif
269  #if GDISP_HARDWARE_SCROLL == GFXON
270  #undef GDISP_HARDWARE_SCROLL
271  #define GDISP_HARDWARE_SCROLL HARDWARE_AUTODETECT
272  #endif
273  #if GDISP_HARDWARE_QUERY == GFXON
274  #undef GDISP_HARDWARE_QUERY
275  #define GDISP_HARDWARE_QUERY HARDWARE_AUTODETECT
276  #endif
277  #if GDISP_HARDWARE_CLIP == GFXON
278  #undef GDISP_HARDWARE_CLIP
279  #define GDISP_HARDWARE_CLIP HARDWARE_AUTODETECT
280  #endif
281 #endif
282 
283 //------------------------------------------------------------------------------------------------------------
284 
285 /* Verify information for packed pixels and define a non-packed pixel macro */
286 #if !GDISP_PACKED_PIXELS
287  #define gdispPackPixels(buf,cx,x,y,c) { ((gColor *)(buf))[(y)*(cx)+(x)] = (c); }
288 #elif !GDISP_HARDWARE_BITFILLS
289  #error "GDISP: packed pixel formats are only supported for hardware accelerated drivers."
290 #elif GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB888 \
291  && GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB444 \
292  && GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB666 \
293  && GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_CUSTOM
294  #error "GDISP: A packed pixel format has been specified for an unsupported pixel format."
295 #endif
296 
297 /* Support routine for packed pixel formats */
298 #if !defined(gdispPackPixels) || defined(__DOXYGEN__)
299  /**
300  * @brief Pack a pixel into a pixel buffer.
301  * @note This function performs no buffer boundary checking
302  * regardless of whether GDISP_NEED_CLIP has been specified.
303  *
304  * @param[in] buf The buffer to put the pixel in
305  * @param[in] cx The width of a pixel line
306  * @param[in] x, y The location of the pixel to place
307  * @param[in] color The color to put into the buffer
308  *
309  * @api
310  */
311  void gdispPackPixels(const gPixel *buf, gCoord cx, gCoord x, gCoord y, gColor color);
312 #endif
313 
314 //------------------------------------------------------------------------------------------------------------
315 
316 struct GDisplay {
317  struct GDriver d; // This must be the first element
318  #define gvmt(g) ((const GDISPVMT const *)((g)->d.vmt)) // For ease of access to the vmt member
319 
320  struct GDISPControl {
321  gCoord Width;
322  gCoord Height;
323  gOrientation Orientation;
324  gPowermode Powermode;
325  gU8 Backlight;
326  gU8 Contrast;
327  } g;
328 
329  void * priv; // A private area just for the drivers use.
330  void * board; // A private area just for the board interfaces use.
331 
332  gU8 systemdisplay;
333  gU8 controllerdisplay;
334  gU16 flags;
335  #define GDISP_FLG_INSTREAM 0x0001 // We are in a user based stream operation
336  #define GDISP_FLG_SCRSTREAM 0x0002 // The stream area currently covers the whole screen
337  #define GDISP_FLG_DRIVER 0x0004 // This flags and above are for use by the driver
338 
339  // Multithread Mutex
340  #if GDISP_NEED_MULTITHREAD
341  gMutex mutex;
342  #endif
343 
344  // Software clipping
345  #if GDISP_HARDWARE_CLIP != GFXON && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION)
346  gCoord clipx0, clipy0;
347  gCoord clipx1, clipy1; /* not inclusive */
348  #endif
349 
350  // Driver call parameters
351  struct {
352  gCoord x, y;
353  gCoord cx, cy;
354  gCoord x1, y1;
355  gCoord x2, y2;
356  gColor color;
357  void *ptr;
358  } p;
359 
360  // In call working buffers
361 
362  #if GDISP_NEED_TEXT
363  // Text rendering parameters
364  struct {
365  gFont font;
366  gColor color;
367  gColor bgcolor;
368  gCoord clipx0, clipy0;
369  gCoord clipx1, clipy1;
370  #if GDISP_NEED_TEXT_WORDWRAP
371  gCoord wrapx, wrapy;
372  gJustify lrj;
373  #endif
374  } t;
375  #endif
376  #if GDISP_LINEBUF_SIZE != 0 && ((GDISP_NEED_SCROLL && !GDISP_HARDWARE_SCROLL) || (!GDISP_HARDWARE_STREAM_WRITE && GDISP_HARDWARE_BITFILLS))
377  // A pixel line buffer
378  gColor linebuf[GDISP_LINEBUF_SIZE];
379  #endif
380 };
381 
382 typedef struct GDISPVMT {
383  GDriverVMT d;
384  #define GDISP_VFLG_DYNAMICONLY 0x0001 // This display should never be statically initialised
385  #define GDISP_VFLG_PIXMAP 0x0002 // This is a pixmap display
386  gBool (*init)(GDisplay *g);
387  void (*deinit)(GDisplay *g);
388  void (*writestart)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy
389  void (*writepos)(GDisplay *g); // Uses p.x,p.y
390  void (*writecolor)(GDisplay *g); // Uses p.color
391  void (*writestop)(GDisplay *g); // Uses no parameters
392  void (*readstart)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy
393  gColor (*readcolor)(GDisplay *g); // Uses no parameters
394  void (*readstop)(GDisplay *g); // Uses no parameters
395  void (*pixel)(GDisplay *g); // Uses p.x,p.y p.color
396  void (*clear)(GDisplay *g); // Uses p.color
397  void (*fill)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy p.color
398  void (*blit)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy p.x1,p.y1 (=srcx,srcy) p.x2 (=srccx), p.ptr (=buffer)
399  gColor (*get)(GDisplay *g); // Uses p.x,p.y
400  void (*vscroll)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy, p.y1 (=lines) p.color
401  void (*control)(GDisplay *g); // Uses p.x (=what) p.ptr (=value)
402  void *(*query)(GDisplay *g); // Uses p.x (=what);
403  void (*setclip)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy
404  void (*flush)(GDisplay *g); // Uses no parameters
405 } GDISPVMT;
406 
407 //------------------------------------------------------------------------------------------------------------
408 
409 // Do we need function definitions or macro's (via the VMT)
410 #if IN_DRIVER || !USE_VMT || defined(__DOXYGEN__)
411  #ifdef __cplusplus
412  extern "C" {
413  #endif
414 
415  // Should the driver routines be static or not
416  #if USE_VMT
417  #define LLDSPEC static
418  #else
419  #define LLDSPEC
420  #endif
421 
422  /**
423  * @brief Initialize the driver.
424  * @return gTrue if successful.
425  * @param[in] g The driver structure
426  * @param[out] g->g The driver must fill in the GDISPControl structure
427  */
428  LLDSPEC gBool gdisp_lld_init(GDisplay *g);
429 
430  #if GDISP_HARDWARE_DEINIT || defined(__DOXYGEN__)
431  /**
432  * @brief The driver is being de-initialized
433  * @pre GDISP_HARDWARE_FLUSH is GFXON
434  *
435  * @param[in] g The driver structure
436  *
437  */
438  LLDSPEC void gdisp_lld_deinit(GDisplay *g);
439  #endif
440 
441  #if GDISP_HARDWARE_FLUSH || defined(__DOXYGEN__)
442  /**
443  * @brief Flush the current drawing operations to the display
444  * @pre GDISP_HARDWARE_FLUSH is GFXON
445  *
446  * @param[in] g The driver structure
447  *
448  * @note The parameter variables must not be altered by the driver.
449  */
450  LLDSPEC void gdisp_lld_flush(GDisplay *g);
451  #endif
452 
453  #if GDISP_HARDWARE_STREAM_WRITE || defined(__DOXYGEN__)
454  /**
455  * @brief Start a streamed write operation
456  * @pre GDISP_HARDWARE_STREAM_WRITE is GFXON
457  *
458  * @param[in] g The driver structure
459  *
460  * @note g->p.x,g->p.y The window position
461  * @note g->p.cx,g->p.cy The window size
462  *
463  * @note The parameter variables must not be altered by the driver.
464  * @note Streaming operations that wrap the defined window have
465  * undefined results.
466  * @note This must be followed by a call to @p gdisp_lld_write_pos() if GDISP_HARDWARE_STREAM_POS is GFXON.
467  */
468  LLDSPEC void gdisp_lld_write_start(GDisplay *g);
469 
470  /**
471  * @brief Send a pixel to the current streaming position and then increment that position
472  * @pre GDISP_HARDWARE_STREAM_WRITE is GFXON
473  *
474  * @param[in] g The driver structure
475  *
476  * @note g->p.color The color to display at the curent position
477  * @note The parameter variables must not be altered by the driver.
478  */
479  LLDSPEC void gdisp_lld_write_color(GDisplay *g);
480 
481  /**
482  * @brief End the current streaming write operation
483  * @pre GDISP_HARDWARE_STREAM_WRITE is GFXON
484  *
485  * @param[in] g The driver structure
486  *
487  * @note The parameter variables must not be altered by the driver.
488  */
489  LLDSPEC void gdisp_lld_write_stop(GDisplay *g);
490 
491  #if GDISP_HARDWARE_STREAM_POS || defined(__DOXYGEN__)
492  /**
493  * @brief Change the current position within the current streaming window
494  * @pre GDISP_HARDWARE_STREAM_POS is GFXON and GDISP_HARDWARE_STREAM_WRITE is GFXON
495  *
496  * @param[in] g The driver structure
497  * @param[in] g->p.x,g->p.y The new position (which will always be within the existing stream window)
498  *
499  * @note The parameter variables must not be altered by the driver.
500  */
501  LLDSPEC void gdisp_lld_write_pos(GDisplay *g);
502  #endif
503  #endif
504 
505  #if GDISP_HARDWARE_STREAM_READ || defined(__DOXYGEN__)
506  /**
507  * @brief Start a streamed read operation
508  * @pre GDISP_HARDWARE_STREAM_READ is GFXON
509  *
510  * @param[in] g The driver structure
511  * @param[in] g->p.x,g->p.y The window position
512  * @param[in] g->p.cx,g->p.cy The window size
513  *
514  * @note The parameter variables must not be altered by the driver.
515  * @note Streaming operations that wrap the defined window have
516  * undefined results.
517  */
518  LLDSPEC void gdisp_lld_read_start(GDisplay *g);
519 
520  /**
521  * @brief Read a pixel from the current streaming position and then increment that position
522  * @return The color at the current position
523  * @pre GDISP_HARDWARE_STREAM_READ is GFXON
524  *
525  * @param[in] g The driver structure
526  *
527  * @note The parameter variables must not be altered by the driver.
528  */
529  LLDSPEC gColor gdisp_lld_read_color(GDisplay *g);
530 
531  /**
532  * @brief End the current streaming operation
533  * @pre GDISP_HARDWARE_STREAM_READ is GFXON
534  *
535  * @param[in] g The driver structure
536  *
537  * @note The parameter variables must not be altered by the driver.
538  */
539  LLDSPEC void gdisp_lld_read_stop(GDisplay *g);
540  #endif
541 
542  #if GDISP_HARDWARE_DRAWPIXEL || defined(__DOXYGEN__)
543  /**
544  * @brief Draw a pixel
545  * @pre GDISP_HARDWARE_DRAWPIXEL is GFXON
546  *
547  * @param[in] g The driver structure
548  * @param[in] g->p.x,g->p.y The pixel position
549  * @param[in] g->p.color The color to set
550  *
551  * @note The parameter variables must not be altered by the driver.
552  */
553  LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g);
554  #endif
555 
556  #if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__)
557  /**
558  * @brief Clear the screen using the defined color
559  * @pre GDISP_HARDWARE_CLEARS is GFXON
560  *
561  * @param[in] g The driver structure
562  * @param[in] g->p.color The color to set
563  *
564  * @note The parameter variables must not be altered by the driver.
565  */
566  LLDSPEC void gdisp_lld_clear(GDisplay *g);
567  #endif
568 
569  #if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
570  /**
571  * @brief Fill an area with a single color
572  * @pre GDISP_HARDWARE_FILLS is GFXON
573  *
574  * @param[in] g The driver structure
575  * @param[in] g->p.x,g->p.y The area position
576  * @param[in] g->p.cx,g->p.cy The area size
577  * @param[in] g->p.color The color to set
578  *
579  * @note The parameter variables must not be altered by the driver.
580  */
581  LLDSPEC void gdisp_lld_fill_area(GDisplay *g);
582  #endif
583 
584  #if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
585  /**
586  * @brief Fill an area using a bitmap
587  * @pre GDISP_HARDWARE_BITFILLS is GFXON
588  *
589  * @param[in] g The driver structure
590  * @param[in] g->p.x,g->p.y The area position
591  * @param[in] g->p.cx,g->p.cy The area size
592  * @param[in] g->p.x1,g->p.y1 The starting position in the bitmap
593  * @param[in] g->p.x2 The width of a bitmap line
594  * @param[in] g->p.ptr The pointer to the bitmap
595  *
596  * @note The parameter variables must not be altered by the driver.
597  */
598  LLDSPEC void gdisp_lld_blit_area(GDisplay *g);
599  #endif
600 
601  #if GDISP_HARDWARE_PIXELREAD || defined(__DOXYGEN__)
602  /**
603  * @brief Read a pixel from the display
604  * @return The color at the defined position
605  * @pre GDISP_HARDWARE_PIXELREAD is GFXON (and the application needs it)
606  *
607  * @param[in] g The driver structure
608  * @param[in] g->p.x,g->p.y The pixel position
609  *
610  * @note The parameter variables must not be altered by the driver.
611  */
612  LLDSPEC gColor gdisp_lld_get_pixel_color(GDisplay *g);
613  #endif
614 
615  #if (GDISP_HARDWARE_SCROLL && GDISP_NEED_SCROLL) || defined(__DOXYGEN__)
616  /**
617  * @brief Scroll an area of the screen
618  * @pre GDISP_HARDWARE_SCROLL is GFXON (and the application needs it)
619  *
620  * @param[in] g The driver structure
621  * @param[in] g->p.x,g->p.y The area position
622  * @param[in] g->p.cx,g->p.cy The area size
623  * @param[in] g->p.y1 The number of lines to scroll (positive or negative)
624  *
625  * @note The parameter variables must not be altered by the driver.
626  * @note This can be easily implemented if the hardware supports
627  * display area to display area copying.
628  * @note Clearing the exposed area on the scroll operation is not
629  * needed as the high level code handles this.
630  */
631  LLDSPEC void gdisp_lld_vertical_scroll(GDisplay *g);
632  #endif
633 
634  #if (GDISP_HARDWARE_CONTROL && GDISP_NEED_CONTROL) || defined(__DOXYGEN__)
635  /**
636  * @brief Control some feature of the hardware
637  * @pre GDISP_HARDWARE_CONTROL is GFXON (and the application needs it)
638  *
639  * @param[in] g The driver structure
640  * @param[in] g->p.x The operation to perform
641  * @param[in] g->p.ptr The operation parameter
642  *
643  * @note The parameter variables must not be altered by the driver.
644  */
645  LLDSPEC void gdisp_lld_control(GDisplay *g);
646  #endif
647 
648  #if (GDISP_HARDWARE_QUERY && GDISP_NEED_QUERY) || defined(__DOXYGEN__)
649  /**
650  * @brief Query some feature of the hardware
651  * @return The information requested (typecast as void *)
652  * @pre GDISP_HARDWARE_QUERY is GFXON (and the application needs it)
653  *
654  * @param[in] g The driver structure
655  * @param[in] g->p.x What to query
656  *
657  * @note The parameter variables must not be altered by the driver.
658  */
659  LLDSPEC void *gdisp_lld_query(GDisplay *g); // Uses p.x (=what);
660  #endif
661 
662  #if (GDISP_HARDWARE_CLIP && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION)) || defined(__DOXYGEN__)
663  /**
664  * @brief Set the hardware clipping area
665  * @pre GDISP_HARDWARE_CLIP is GFXON (and the application needs it)
666  *
667  * @param[in] g The driver structure
668  * @param[in] g->p.x,g->p.y The area position
669  * @param[in] g->p.cx,g->p.cy The area size
670  *
671  * @note The parameter variables must not be altered by the driver.
672  */
673  LLDSPEC void gdisp_lld_set_clip(GDisplay *g);
674  #endif
675 
676  #ifdef __cplusplus
677  }
678  #endif
679 
680 #else
681  #define gdisp_lld_init(g) gvmt(g)->init(g)
682  #define gdisp_lld_deinit(g) gvmt(g)->deinit(g)
683  #define gdisp_lld_flush(g) gvmt(g)->flush(g)
684  #define gdisp_lld_write_start(g) gvmt(g)->writestart(g)
685  #define gdisp_lld_write_pos(g) gvmt(g)->writepos(g)
686  #define gdisp_lld_write_color(g) gvmt(g)->writecolor(g)
687  #define gdisp_lld_write_stop(g) gvmt(g)->writestop(g)
688  #define gdisp_lld_read_start(g) gvmt(g)->readstart(g)
689  #define gdisp_lld_read_color(g) gvmt(g)->readcolor(g)
690  #define gdisp_lld_read_stop(g) gvmt(g)->readstop(g)
691  #define gdisp_lld_draw_pixel(g) gvmt(g)->pixel(g)
692  #define gdisp_lld_clear(g) gvmt(g)->clear(g)
693  #define gdisp_lld_fill_area(g) gvmt(g)->fill(g)
694  #define gdisp_lld_blit_area(g) gvmt(g)->blit(g)
695  #define gdisp_lld_get_pixel_color(g) gvmt(g)->get(g)
696  #define gdisp_lld_vertical_scroll(g) gvmt(g)->vscroll(g)
697  #define gdisp_lld_control(g) gvmt(g)->control(g)
698  #define gdisp_lld_query(g) gvmt(g)->query(g)
699  #define gdisp_lld_set_clip(g) gvmt(g)->setclip(g)
700 #endif
701 
702 //------------------------------------------------------------------------------------------------------------
703 
704 // If compiling the driver then build the VMT and set the low level driver color macros.
705 #if IN_DRIVER
706 
707  // Make sure the driver has a valid model
708  #if !GDISP_HARDWARE_STREAM_WRITE && !GDISP_HARDWARE_DRAWPIXEL
709  #error "GDISP Driver: Either GDISP_HARDWARE_STREAM_WRITE or GDISP_HARDWARE_DRAWPIXEL must be GFXON"
710  #endif
711 
712  // If we are not using multiple displays then hard-code the VMT name (except for the pixmap driver)
713  #if !IS_MULTIPLE && !IN_PIXMAP_DRIVER
714  #undef GDISP_DRIVER_VMT
715  #define GDISP_DRIVER_VMT GDISPVMT_OnlyOne
716  #endif
717 
718  // Default the flags if the driver doesn't specify any
719  #ifndef GDISP_DRIVER_VMT_FLAGS
720  #define GDISP_DRIVER_VMT_FLAGS 0
721  #endif
722 
723  // Routines needed by the general driver VMT
724  #ifdef __cplusplus
725  extern "C" {
726  #endif
727  gBool _gdispInitDriver(GDriver *g, void *param, unsigned driverinstance, unsigned systeminstance);
728  void _gdispPostInitDriver(GDriver *g);
729  void _gdispDeInitDriver(GDriver *g);
730  #ifdef __cplusplus
731  }
732  #endif
733 
734  // Build the VMT
735  /*
736  * This should read: const GDISPVMT const GDISP_DRIVER_VMT[1] = {{
737  * However, some major C compilers complain about duplicate const specifiers although this is perfectly valid standard C.
738  */
739  const GDISPVMT GDISP_DRIVER_VMT[1] = {{
740  { GDRIVER_TYPE_DISPLAY, 0, sizeof(GDisplay), _gdispInitDriver, _gdispPostInitDriver, _gdispDeInitDriver },
741  gdisp_lld_init,
742  #if GDISP_HARDWARE_DEINIT
743  gdisp_lld_deinit,
744  #else
745  0,
746  #endif
747  #if GDISP_HARDWARE_STREAM_WRITE
748  gdisp_lld_write_start,
749  #if GDISP_HARDWARE_STREAM_POS
750  gdisp_lld_write_pos,
751  #else
752  0,
753  #endif
754  gdisp_lld_write_color,
755  gdisp_lld_write_stop,
756  #else
757  0, 0, 0, 0,
758  #endif
759  #if GDISP_HARDWARE_STREAM_READ
760  gdisp_lld_read_start,
761  gdisp_lld_read_color,
762  gdisp_lld_read_stop,
763  #else
764  0, 0, 0,
765  #endif
766  #if GDISP_HARDWARE_DRAWPIXEL
767  gdisp_lld_draw_pixel,
768  #else
769  0,
770  #endif
771  #if GDISP_HARDWARE_CLEARS
772  gdisp_lld_clear,
773  #else
774  0,
775  #endif
776  #if GDISP_HARDWARE_FILLS
777  gdisp_lld_fill_area,
778  #else
779  0,
780  #endif
781  #if GDISP_HARDWARE_BITFILLS
782  gdisp_lld_blit_area,
783  #else
784  0,
785  #endif
786  #if GDISP_HARDWARE_PIXELREAD
787  gdisp_lld_get_pixel_color,
788  #else
789  0,
790  #endif
791  #if GDISP_HARDWARE_SCROLL && GDISP_NEED_SCROLL
792  gdisp_lld_vertical_scroll,
793  #else
794  0,
795  #endif
796  #if GDISP_HARDWARE_CONTROL && GDISP_NEED_CONTROL
797  gdisp_lld_control,
798  #else
799  0,
800  #endif
801  #if GDISP_HARDWARE_QUERY && GDISP_NEED_QUERY
802  gdisp_lld_query,
803  #else
804  0,
805  #endif
806  #if GDISP_HARDWARE_CLIP && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION)
807  gdisp_lld_set_clip,
808  #else
809  0,
810  #endif
811  #if GDISP_HARDWARE_FLUSH
812  gdisp_lld_flush,
813  #else
814  0,
815  #endif
816  }};
817 
818  //--------------------------------------------------------------------------------------------------------
819 
820  /* Low level driver pixel format information */
821  //-------------------------
822  // True-Color color system
823  //-------------------------
824  #if GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_TRUECOLOR
825  #define LLDCOLOR_SYSTEM GDISP_COLORSYSTEM_TRUECOLOR
826 
827  // Calculate the number of bits
828  #define LLDCOLOR_BITS_R ((GDISP_LLD_PIXELFORMAT>>8) & 0x0F)
829  #define LLDCOLOR_BITS_G ((GDISP_LLD_PIXELFORMAT>>4) & 0x0F)
830  #define LLDCOLOR_BITS_B ((GDISP_LLD_PIXELFORMAT>>0) & 0x0F)
831  #define LLDCOLOR_BITS (LLDCOLOR_BITS_R + LLDCOLOR_BITS_G + LLDCOLOR_BITS_B)
832 
833  // From the number of bits determine COLOR_TYPE, COLOR_TYPE_BITS and masking
834  #if LLDCOLOR_BITS <= 8
835  #define LLDCOLOR_TYPE gU8
836  #define LLDCOLOR_TYPE_BITS 8
837  #elif LLDCOLOR_BITS <= 16
838  #define LLDCOLOR_TYPE gU16
839  #define LLDCOLOR_TYPE_BITS 16
840  #elif LLDCOLOR_BITS <= 32
841  #define LLDCOLOR_TYPE gU32
842  #define LLDCOLOR_TYPE_BITS 32
843  #else
844  #error "GDISP: Cannot define low level driver color types with more than 32 bits"
845  #endif
846  #if LLDCOLOR_TYPE_BITS == LLDCOLOR_BITS
847  #define LLDCOLOR_NEEDS_MASK GFXOFF
848  #else
849  #define LLDCOLOR_NEEDS_MASK GFXON
850  #endif
851  #define LLDCOLOR_MASK() ((1 << LLDCOLOR_BITS)-1)
852 
853  // Calculate the component bit shifts
854  #if (GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_RGB
855  #define LLDCOLOR_SHIFT_R (LLDCOLOR_BITS_B+LLDCOLOR_BITS_G)
856  #define LLDCOLOR_SHIFT_G LLDCOLOR_BITS_B
857  #define LLDCOLOR_SHIFT_B 0
858  #else
859  #define LLDCOLOR_SHIFT_B (LLDCOLOR_BITS_R+LLDCOLOR_BITS_G)
860  #define LLDCOLOR_SHIFT_G LLDCOLOR_BITS_R
861  #define LLDCOLOR_SHIFT_R 0
862  #endif
863 
864  // Calculate LLDRED_OF, LLDGREEN_OF, LLDBLUE_OF and LLDRGB2COLOR
865  #if LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R == 8
866  #define LLDRED_OF(c) ((c) & (((1<<LLDCOLOR_BITS_R)-1) << LLDCOLOR_SHIFT_R))
867  #define LLDRGB2COLOR_R(r) ((LLDCOLOR_TYPE)((r) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))))
868  #elif LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R > 8
869  #define LLDRED_OF(c) (((c) & (((1<<LLDCOLOR_BITS_R)-1) << LLDCOLOR_SHIFT_R)) >> (LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R-8))
870  #define LLDRGB2COLOR_R(r) (((LLDCOLOR_TYPE)((r) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1)))) << (LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R-8))
871  #else // LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R < 8
872  #define LLDRED_OF(c) (((c) & (((1<<LLDCOLOR_BITS_R)-1) << LLDCOLOR_SHIFT_R)) << (8-(LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R)))
873  #define LLDRGB2COLOR_R(r) (((LLDCOLOR_TYPE)((r) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1)))) >> (8-(LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R)))
874  #endif
875  #if LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G == 8
876  #define LLDGREEN_OF(c) ((c) & (((1<<LLDCOLOR_BITS_G)-1) << LLDCOLOR_SHIFT_G))
877  #define LLDRGB2COLOR_G(g) ((LLDCOLOR_TYPE)((g) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))))
878  #elif LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G > 8
879  #define LLDGREEN_OF(c) (((c) & (((1<<LLDCOLOR_BITS_G)-1) << LLDCOLOR_SHIFT_G)) >> (LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G-8))
880  #define LLDRGB2COLOR_G(g) (((LLDCOLOR_TYPE)((g) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1)))) << (LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G-8))
881  #else // LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G < 8
882  #define LLDGREEN_OF(c) (((c) & (((1<<LLDCOLOR_BITS_G)-1) << LLDCOLOR_SHIFT_G)) << (8-(LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G)))
883  #define LLDRGB2COLOR_G(g) (((LLDCOLOR_TYPE)((g) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1)))) >> (8-(LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G)))
884  #endif
885  #if LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B == 8
886  #define LLDBLUE_OF(c) ((c) & (((1<<LLDCOLOR_BITS_B)-1) << LLDCOLOR_SHIFT_B))
887  #define LLDRGB2COLOR_B(b) ((LLDCOLOR_TYPE)((b) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1))))
888  #elif LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B > 8
889  #define LLDBLUE_OF(c) (((c) & (((1<<LLDCOLOR_BITS_B)-1) << LLDCOLOR_SHIFT_B)) >> (LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B-8))
890  #define LLDRGB2COLOR_B(b) (((LLDCOLOR_TYPE)((b) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1)))) << (LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B-8))
891  #else // LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B < 8
892  #define LLDBLUE_OF(c) (((c) & (((1<<LLDCOLOR_BITS_B)-1) << LLDCOLOR_SHIFT_B)) << (8-(LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B)))
893  #define LLDRGB2COLOR_B(b) (((LLDCOLOR_TYPE)((b) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1)))) >> (8-(LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B)))
894  #endif
895  #define LLDLUMA_OF(c) ((LLDRED_OF(c)+((gU16)LLDGREEN_OF(c)<<1)+LLDBLUE_OF(c))>>2)
896  #define LLDEXACT_RED_OF(c) (((gU16)(((c)>>LLDCOLOR_SHIFT_R)&((1<<LLDCOLOR_BITS_R)-1))*255)/((1<<LLDCOLOR_BITS_R)-1))
897  #define LLDEXACT_GREEN_OF(c) (((gU16)(((c)>>LLDCOLOR_SHIFT_G)&((1<<LLDCOLOR_BITS_G)-1))*255)/((1<<LLDCOLOR_BITS_G)-1))
898  #define LLDEXACT_BLUE_OF(c) (((gU16)(((c)>>LLDCOLOR_SHIFT_B)&((1<<LLDCOLOR_BITS_B)-1))*255)/((1<<LLDCOLOR_BITS_B)-1))
899  #define LLDEXACT_LUMA_OF(c) ((LLDEXACT_RED_OF(c)+((gU16)LLDEXACT_GREEN_OF(c)<<1)+LLDEXACT_BLUE_OF(c))>>2)
900  #define LLDLUMA2COLOR(l) (LLDRGB2COLOR_R(l) | LLDRGB2COLOR_G(l) | LLDRGB2COLOR_B(l))
901  #define LLDRGB2COLOR(r,g,b) (LLDRGB2COLOR_R(r) | LLDRGB2COLOR_G(g) | LLDRGB2COLOR_B(b))
902 
903  // Calculate LLDHTML2COLOR
904  #if LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R == 24
905  #define LLDHTML2COLOR_R(h) ((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))<<16))
906  #elif COLOR_BITS_R + COLOR_SHIFT_R > 24
907  #define LLDHTML2COLOR_R(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))<<16)) << (LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R-24))
908  #else // COLOR_BITS_R + COLOR_SHIFT_R < 24
909  #define LLDHTML2COLOR_R(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))<<16)) >> (24-(LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R)))
910  #endif
911  #if LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G == 16
912  #define LLDHTML2COLOR_G(h) ((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))<<8))
913  #elif LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G > 16
914  #define LLDHTML2COLOR_G(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))<<8)) << (LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G-16))
915  #else // LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G < 16
916  #define LLDHTML2COLOR_G(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))<<8)) >> (16-(LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G)))
917  #endif
918  #if LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B == 8
919  #define LLDHTML2COLOR_B(h) ((h) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1)))
920  #elif LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B > 8
921  #define LLDHTML2COLOR_B(h) (((h) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1))) << (LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B-8))
922  #else // LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B < 8
923  #define LLDHTML2COLOR_B(h) (((h) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1))) >> (8-(LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B)))
924  #endif
925  #define LLDHTML2COLOR(h) ((LLDCOLOR_TYPE)(LLDHTML2COLOR_R(h) | LLDHTML2COLOR_G(h) | LLDHTML2COLOR_B(h)))
926 
927  //-------------------------
928  // Gray-scale color system
929  //-------------------------
930  #elif (GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_GRAYSCALE
931  #define LLDCOLOR_SYSTEM GDISP_COLORSYSTEM_GRAYSCALE
932 
933  // Calculate the number of bits and shifts
934  #define LLDCOLOR_BITS (GDISP_LLD_PIXELFORMAT & 0xFF)
935  #define LLDCOLOR_BITS_R LLDCOLOR_BITS
936  #define LLDCOLOR_BITS_G LLDCOLOR_BITS
937  #define LLDCOLOR_BITS_B LLDCOLOR_BITS
938  #define LLDCOLOR_SHIFT_R 0
939  #define LLDCOLOR_SHIFT_G 0
940  #define LLDCOLOR_SHIFT_B 0
941 
942  // From the number of bits determine COLOR_TYPE, COLOR_TYPE_BITS and masking
943  #if LLDCOLOR_BITS <= 8
944  #define LLDCOLOR_TYPE gU8
945  #define LLDCOLOR_TYPE_BITS 8
946  #else
947  #error "GDISP: Cannot define gray-scale low level driver color types with more than 8 bits"
948  #endif
949  #if LLDCOLOR_TYPE_BITS == LLDCOLOR_BITS
950  #define LLDCOLOR_NEEDS_MASK GFXOFF
951  #else
952  #define LLDCOLOR_NEEDS_MASK GFXON
953  #endif
954  #define LLDCOLOR_MASK() ((1 << LLDCOLOR_BITS)-1)
955 
956  #if COLOR_BITS == 1
957  #define LLDRGB2COLOR(r,g,b) (((r)|(g)|(b)) ? 1 : 0)
958  #define LLDLUMA2COLOR(l) ((l) ? 1 : 0)
959  #define LLDHTML2COLOR(h) ((h) ? 1 : 0)
960  #define LLDLUMA_OF(c) ((c) ? 255 : 0)
961  #define LLDEXACT_LUMA_OF(c) LLDLUMA_OF(c)
962  #else
963  // They eye is more sensitive to green
964  #define LLDRGB2COLOR(r,g,b) ((LLDCOLOR_TYPE)(((gU16)(r)+(g)+(g)+(b)) >> (10-LLDCOLOR_BITS)))
965  #define LLDLUMA2COLOR(l) ((LLDCOLOR_TYPE)((l)>>(8-LLDCOLOR_BITS)))
966  #define LLDHTML2COLOR(h) ((LLDCOLOR_TYPE)(((((h)&0xFF0000)>>16)+(((h)&0x00FF00)>>7)+((h)&0x0000FF)) >> (10-LLDCOLOR_BITS)))
967  #define LLDLUMA_OF(c) (((c) & ((1<<LLDCOLOR_BITS)-1)) << (8-LLDCOLOR_BITS))
968  #define LLDEXACT_LUMA_OF(c) ((((gU16)(c) & ((1<<LLDCOLOR_BITS)-1))*255)/((1<<LLDCOLOR_BITS)-1))
969  #endif
970 
971  #define LLDRED_OF(c) LLDLUMA_OF(c)
972  #define LLDGREEN_OF(c) LLDLUMA_OF(c)
973  #define LLDBLUE_OF(c) LLDLUMA_OF(c)
974  #define LLDEXACT_RED_OF(c) LLDEXACT_LUMA_OF(c)
975  #define LLDEXACT_GREEN_OF(c) LLDEXACT_LUMA_OF(c)
976  #define LLDEXACT_BLUE_OF(c) LLDEXACT_LUMA_OF(c)
977 
978  //-------------------------
979  // Palette color system
980  //-------------------------
981  #elif (GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_PALETTE
982  #define LLDCOLOR_SYSTEM GDISP_COLORSYSTEM_PALETTE
983 
984  #error "GDISP: A palette color system for low level drivers is not currently supported"
985 
986  //-------------------------
987  // Some other color system
988  //-------------------------
989  #else
990  #error "GDISP: Unsupported color system for low level drivers"
991  #endif
992 
993  /* Which is the larger color type */
994  #if COLOR_BITS > LLDCOLOR_BITS
995  #define LARGER_COLOR_BITS COLOR_BITS
996  #define LARGER_COLOR_TYPE COLOR_TYPE
997  #else
998  #define LARGER_COLOR_BITS LLDCOLOR_BITS
999  #define LARGER_COLOR_TYPE LLDCOLOR_TYPE
1000  #endif
1001 
1002  /**
1003  * @brief Controls color conversion accuracy for a low level driver
1004  * @details Should higher precision be used when converting colors.
1005  * @note Color conversion is only necessary if GDISP_PIXELFORMAT != GDISP_LLD_PIXELFORMAT
1006  * @note It only makes sense to turn this on if you have a high bit depth display but
1007  * are running the application in low bit depths.
1008  * @note To achieve higher color accuracy bit shifting is replaced with multiplies and divides.
1009  */
1010  #ifndef GDISP_HARDWARE_USE_EXACT_COLOR
1011  #if LLDCOLOR_BITS_R - COLOR_BITS_R >= LLDCOLOR_BITS_R/2 || LLDCOLOR_BITS_G - COLOR_BITS_G >= LLDCOLOR_BITS_G/2 || LLDCOLOR_BITS_B - COLOR_BITS_B >= LLDCOLOR_BITS_B/2
1012  #define GDISP_HARDWARE_USE_EXACT_COLOR GFXON
1013  #else
1014  #define GDISP_HARDWARE_USE_EXACT_COLOR GFXOFF
1015  #endif
1016  #endif
1017 
1018  /* Low level driver pixel format conversion functions */
1019  #if GDISP_PIXELFORMAT == GDISP_LLD_PIXELFORMAT || defined(__DOXYGEN__)
1020  /**
1021  * @brief Convert from a standard color format to the low level driver pixel format
1022  * @note For use only by low level drivers
1023  */
1024  #define gdispColor2Native(c) (c)
1025  /**
1026  * @brief Convert from a low level driver pixel format to the standard color format
1027  * @note For use only by low level drivers
1028  */
1029  #define gdispNative2Color(c) (c)
1030  #elif COLOR_SYSTEM == GDISP_COLORSYSTEM_GRAYSCALE || LLDCOLOR_SYSTEM == GDISP_COLORSYSTEM_GRAYSCALE
1031  #if GDISP_HARDWARE_USE_EXACT_COLOR
1032  #define gdispColor2Native(c) LLDLUMA2COLOR(EXACT_LUMA_OF(c))
1033  #define gdispNative2Color(c) LUMA2COLOR(LLDEXACT_LUMA_OF(c))
1034  #else
1035  #define gdispColor2Native(c) LLDLUMA2COLOR(LUMA_OF(c))
1036  #define gdispNative2Color(c) LUMA2COLOR(LLDLUMA_OF(c))
1037  #endif
1038  #elif COLOR_SYSTEM == GDISP_COLORSYSTEM_TRUECOLOR && LLDCOLOR_SYSTEM == GDISP_COLORSYSTEM_TRUECOLOR
1039  #if GDISP_HARDWARE_USE_EXACT_COLOR
1040  #define gdispColor2Native(c) LLDRGB2COLOR(EXACT_RED_OF(c), EXACT_GREEN_OF(c), EXACT_BLUE_OF(c))
1041  #define gdispNative2Color(c) RGB2COLOR(LLDEXACT_RED_OF(c), LLDEXACT_GREEN_OF(c), LLDEXACT_BLUE_OF(c))
1042  #else
1043  #define gdispColor2Native(c) LLDRGB2COLOR(RED_OF(c), GREEN_OF(c), BLUE_OF(c))
1044  #define gdispNative2Color(c) RGB2COLOR(LLDRED_OF(c), LLDGREEN_OF(c), LLDBLUE_OF(c))
1045  #endif
1046  #else
1047  #error "GDISP: This pixel format conversion is not supported yet"
1048  #endif
1049 
1050 #endif
1051 
1052 //------------------------------------------------------------------------------------------------------------
1053 
1054 #undef IN_PIXMAP_DRIVER
1055 #undef IS_MULTIPLE
1056 #undef IN_DRIVER
1057 #undef USE_VMT
1058 #endif /* GFX_USE_GDISP */
1059 
1060 #endif /* _GDISP_LLD_H */
1061 /** @} */
COLOR_TYPE gColor
The color type definition.
Definition: gdisp_colors.h:437
const struct mf_font_s * gFont
The type of a font.
Definition: gdisp.h:93
gColor gPixel
The pixel format.
Definition: gdisp.h:226
gJustify
Type for the text justification.
Definition: gdisp.h:60
gOrientation
Type for the screen orientation.
Definition: gdisp.h:101
gPowermode
Type for the available power modes for the screen.
Definition: gdisp.h:114
gI16 gCoord
The type for a coordinate or length on the screen.
Definition: gdisp.h:39
#define GDISP_LINEBUF_SIZE
Define the default orientation for all displays in the system.
All runtime driver structures start with this structure.
Definition: gdriver.h:58
All driver VMT's start with this structure.
Definition: gdriver.h:66
A mutex.
Definition: gos.h:110