version 2.8
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.org/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 TRUE
27 #else
28  #define IN_DRIVER FALSE
29 #endif
30 
31 // Is this a multiple driver situation?
32 #if defined(GDISP_DRIVER_LIST)
33  #define IS_MULTIPLE TRUE
34 #else
35  #define IS_MULTIPLE FALSE
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 TRUE
41 #else
42  #define USE_VMT FALSE
43 #endif
44 
45 // Are we in the pixmap virtual driver
46 #ifndef IN_PIXMAP_DRIVER
47  #define IN_PIXMAP_DRIVER FALSE
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 FALSE
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 TRUE, FALSE 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 TRUE, FALSE 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 TRUE, FALSE 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 TRUE, FALSE 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 TRUE, FALSE 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 TRUE, FALSE 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 TRUE, FALSE 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 TRUE, FALSE 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 TRUE, FALSE 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 TRUE, FALSE 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 TRUE, FALSE 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 TRUE, FALSE 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 TRUE, FALSE 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 TRUE, FALSE 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 FALSE as they are needed for pixmap drawing
227 // Similarly some routines MUST not be TRUE 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 == TRUE
246  #undef GDISP_HARDWARE_FLUSH
247  #define GDISP_HARDWARE_FLUSH HARDWARE_AUTODETECT
248  #endif
249  #if GDISP_HARDWARE_STREAM_WRITE == TRUE
250  #undef GDISP_HARDWARE_STREAM_WRITE
251  #define GDISP_HARDWARE_STREAM_WRITE HARDWARE_AUTODETECT
252  #endif
253  #if GDISP_HARDWARE_STREAM_READ == TRUE
254  #undef GDISP_HARDWARE_STREAM_READ
255  #define GDISP_HARDWARE_STREAM_READ HARDWARE_AUTODETECT
256  #endif
257  #if GDISP_HARDWARE_CLEARS == TRUE
258  #undef GDISP_HARDWARE_CLEARS
259  #define GDISP_HARDWARE_CLEARS HARDWARE_AUTODETECT
260  #endif
261  #if GDISP_HARDWARE_FILLS == TRUE
262  #undef GDISP_HARDWARE_FILLS
263  #define GDISP_HARDWARE_FILLS HARDWARE_AUTODETECT
264  #endif
265  #if GDISP_HARDWARE_BITFILLS == TRUE
266  #undef GDISP_HARDWARE_BITFILLS
267  #define GDISP_HARDWARE_BITFILLS HARDWARE_AUTODETECT
268  #endif
269  #if GDISP_HARDWARE_SCROLL == TRUE
270  #undef GDISP_HARDWARE_SCROLL
271  #define GDISP_HARDWARE_SCROLL HARDWARE_AUTODETECT
272  #endif
273  #if GDISP_HARDWARE_QUERY == TRUE
274  #undef GDISP_HARDWARE_QUERY
275  #define GDISP_HARDWARE_QUERY HARDWARE_AUTODETECT
276  #endif
277  #if GDISP_HARDWARE_CLIP == TRUE
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) { ((color_t *)(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 pixel_t *buf, coord_t cx, coord_t x, coord_t y, color_t 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  coord_t Width;
322  coord_t Height;
323  orientation_t Orientation;
324  powermode_t Powermode;
325  uint8_t Backlight;
326  uint8_t 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  uint8_t systemdisplay;
333  uint8_t controllerdisplay;
334  uint16_t 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  gfxMutex mutex;
342  #endif
343 
344  // Software clipping
345  #if GDISP_HARDWARE_CLIP != TRUE && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION)
346  coord_t clipx0, clipy0;
347  coord_t clipx1, clipy1; /* not inclusive */
348  #endif
349 
350  // Driver call parameters
351  struct {
352  coord_t x, y;
353  coord_t cx, cy;
354  coord_t x1, y1;
355  coord_t x2, y2;
356  color_t 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  font_t font;
366  color_t color;
367  color_t bgcolor;
368  coord_t clipx0, clipy0;
369  coord_t clipx1, clipy1;
370  #if GDISP_NEED_TEXT_WORDWRAP
371  coord_t wrapx, wrapy;
372  justify_t 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  color_t 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  bool_t (*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  color_t (*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  color_t (*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 TRUE 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 bool_t 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 TRUE
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 TRUE
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 TRUE
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 TRUE.
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 TRUE
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 TRUE
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 TRUE and GDISP_HARDWARE_STREAM_WRITE is TRUE
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 TRUE
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 TRUE
524  *
525  * @param[in] g The driver structure
526  *
527  * @note The parameter variables must not be altered by the driver.
528  */
529  LLDSPEC color_t gdisp_lld_read_color(GDisplay *g);
530 
531  /**
532  * @brief End the current streaming operation
533  * @pre GDISP_HARDWARE_STREAM_READ is TRUE
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 TRUE
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 TRUE
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 TRUE
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 TRUE
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 TRUE (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 color_t 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 TRUE (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 TRUE (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 TRUE (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 TRUE (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 TRUE"
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  bool_t _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  const GDISPVMT const GDISP_DRIVER_VMT[1] = {{
736  { GDRIVER_TYPE_DISPLAY, 0, sizeof(GDisplay), _gdispInitDriver, _gdispPostInitDriver, _gdispDeInitDriver },
737  gdisp_lld_init,
738  #if GDISP_HARDWARE_DEINIT
739  gdisp_lld_deinit,
740  #else
741  0,
742  #endif
743  #if GDISP_HARDWARE_STREAM_WRITE
744  gdisp_lld_write_start,
745  #if GDISP_HARDWARE_STREAM_POS
746  gdisp_lld_write_pos,
747  #else
748  0,
749  #endif
750  gdisp_lld_write_color,
751  gdisp_lld_write_stop,
752  #else
753  0, 0, 0, 0,
754  #endif
755  #if GDISP_HARDWARE_STREAM_READ
756  gdisp_lld_read_start,
757  gdisp_lld_read_color,
758  gdisp_lld_read_stop,
759  #else
760  0, 0, 0,
761  #endif
762  #if GDISP_HARDWARE_DRAWPIXEL
763  gdisp_lld_draw_pixel,
764  #else
765  0,
766  #endif
767  #if GDISP_HARDWARE_CLEARS
768  gdisp_lld_clear,
769  #else
770  0,
771  #endif
772  #if GDISP_HARDWARE_FILLS
773  gdisp_lld_fill_area,
774  #else
775  0,
776  #endif
777  #if GDISP_HARDWARE_BITFILLS
778  gdisp_lld_blit_area,
779  #else
780  0,
781  #endif
782  #if GDISP_HARDWARE_PIXELREAD
783  gdisp_lld_get_pixel_color,
784  #else
785  0,
786  #endif
787  #if GDISP_HARDWARE_SCROLL && GDISP_NEED_SCROLL
788  gdisp_lld_vertical_scroll,
789  #else
790  0,
791  #endif
792  #if GDISP_HARDWARE_CONTROL && GDISP_NEED_CONTROL
793  gdisp_lld_control,
794  #else
795  0,
796  #endif
797  #if GDISP_HARDWARE_QUERY && GDISP_NEED_QUERY
798  gdisp_lld_query,
799  #else
800  0,
801  #endif
802  #if GDISP_HARDWARE_CLIP && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION)
803  gdisp_lld_set_clip,
804  #else
805  0,
806  #endif
807  #if GDISP_HARDWARE_FLUSH
808  gdisp_lld_flush,
809  #else
810  0,
811  #endif
812  }};
813 
814  //--------------------------------------------------------------------------------------------------------
815 
816  /* Low level driver pixel format information */
817  //-------------------------
818  // True-Color color system
819  //-------------------------
820  #if GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_TRUECOLOR
821  #define LLDCOLOR_SYSTEM GDISP_COLORSYSTEM_TRUECOLOR
822 
823  // Calculate the number of bits
824  #define LLDCOLOR_BITS_R ((GDISP_LLD_PIXELFORMAT>>8) & 0x0F)
825  #define LLDCOLOR_BITS_G ((GDISP_LLD_PIXELFORMAT>>4) & 0x0F)
826  #define LLDCOLOR_BITS_B ((GDISP_LLD_PIXELFORMAT>>0) & 0x0F)
827  #define LLDCOLOR_BITS (LLDCOLOR_BITS_R + LLDCOLOR_BITS_G + LLDCOLOR_BITS_B)
828 
829  // From the number of bits determine COLOR_TYPE, COLOR_TYPE_BITS and masking
830  #if LLDCOLOR_BITS <= 8
831  #define LLDCOLOR_TYPE uint8_t
832  #define LLDCOLOR_TYPE_BITS 8
833  #elif LLDCOLOR_BITS <= 16
834  #define LLDCOLOR_TYPE uint16_t
835  #define LLDCOLOR_TYPE_BITS 16
836  #elif LLDCOLOR_BITS <= 32
837  #define LLDCOLOR_TYPE uint32_t
838  #define LLDCOLOR_TYPE_BITS 32
839  #else
840  #error "GDISP: Cannot define low level driver color types with more than 32 bits"
841  #endif
842  #if LLDCOLOR_TYPE_BITS == LLDCOLOR_BITS
843  #define LLDCOLOR_NEEDS_MASK FALSE
844  #else
845  #define LLDCOLOR_NEEDS_MASK TRUE
846  #endif
847  #define LLDCOLOR_MASK() ((1 << LLDCOLOR_BITS)-1)
848 
849  // Calculate the component bit shifts
850  #if (GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_RGB
851  #define LLDCOLOR_SHIFT_R (LLDCOLOR_BITS_B+LLDCOLOR_BITS_G)
852  #define LLDCOLOR_SHIFT_G LLDCOLOR_BITS_B
853  #define LLDCOLOR_SHIFT_B 0
854  #else
855  #define LLDCOLOR_SHIFT_B (LLDCOLOR_BITS_R+LLDCOLOR_BITS_G)
856  #define LLDCOLOR_SHIFT_G LLDCOLOR_BITS_R
857  #define LLDCOLOR_SHIFT_R 0
858  #endif
859 
860  // Calculate LLDRED_OF, LLDGREEN_OF, LLDBLUE_OF and LLDRGB2COLOR
861  #if LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R == 8
862  #define LLDRED_OF(c) ((c) & (((1<<LLDCOLOR_BITS_R)-1) << LLDCOLOR_SHIFT_R))
863  #define LLDRGB2COLOR_R(r) ((LLDCOLOR_TYPE)((r) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))))
864  #elif LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R > 8
865  #define LLDRED_OF(c) (((c) & (((1<<LLDCOLOR_BITS_R)-1) << LLDCOLOR_SHIFT_R)) >> (LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R-8))
866  #define LLDRGB2COLOR_R(r) (((LLDCOLOR_TYPE)((r) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1)))) << (LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R-8))
867  #else // LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R < 8
868  #define LLDRED_OF(c) (((c) & (((1<<LLDCOLOR_BITS_R)-1) << LLDCOLOR_SHIFT_R)) << (8-(LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R)))
869  #define LLDRGB2COLOR_R(r) (((LLDCOLOR_TYPE)((r) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1)))) >> (8-(LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R)))
870  #endif
871  #if LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G == 8
872  #define LLDGREEN_OF(c) ((c) & (((1<<LLDCOLOR_BITS_G)-1) << LLDCOLOR_SHIFT_G))
873  #define LLDRGB2COLOR_G(g) ((LLDCOLOR_TYPE)((g) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))))
874  #elif LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G > 8
875  #define LLDGREEN_OF(c) (((c) & (((1<<LLDCOLOR_BITS_G)-1) << LLDCOLOR_SHIFT_G)) >> (LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G-8))
876  #define LLDRGB2COLOR_G(g) (((LLDCOLOR_TYPE)((g) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1)))) << (LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G-8))
877  #else // LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G < 8
878  #define LLDGREEN_OF(c) (((c) & (((1<<LLDCOLOR_BITS_G)-1) << LLDCOLOR_SHIFT_G)) << (8-(LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G)))
879  #define LLDRGB2COLOR_G(g) (((LLDCOLOR_TYPE)((g) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1)))) >> (8-(LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G)))
880  #endif
881  #if LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B == 8
882  #define LLDBLUE_OF(c) ((c) & (((1<<LLDCOLOR_BITS_B)-1) << LLDCOLOR_SHIFT_B))
883  #define LLDRGB2COLOR_B(b) ((LLDCOLOR_TYPE)((b) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1))))
884  #elif LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B > 8
885  #define LLDBLUE_OF(c) (((c) & (((1<<LLDCOLOR_BITS_B)-1) << LLDCOLOR_SHIFT_B)) >> (LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B-8))
886  #define LLDRGB2COLOR_B(b) (((LLDCOLOR_TYPE)((b) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1)))) << (LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B-8))
887  #else // LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B < 8
888  #define LLDBLUE_OF(c) (((c) & (((1<<LLDCOLOR_BITS_B)-1) << LLDCOLOR_SHIFT_B)) << (8-(LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B)))
889  #define LLDRGB2COLOR_B(b) (((LLDCOLOR_TYPE)((b) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1)))) >> (8-(LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B)))
890  #endif
891  #define LLDLUMA_OF(c) ((LLDRED_OF(c)+((uint16_t)LLDGREEN_OF(c)<<1)+LLDBLUE_OF(c))>>2)
892  #define LLDEXACT_RED_OF(c) (((uint16_t)(((c)>>LLDCOLOR_SHIFT_R)&((1<<LLDCOLOR_BITS_R)-1))*255)/((1<<LLDCOLOR_BITS_R)-1))
893  #define LLDEXACT_GREEN_OF(c) (((uint16_t)(((c)>>LLDCOLOR_SHIFT_G)&((1<<LLDCOLOR_BITS_G)-1))*255)/((1<<LLDCOLOR_BITS_G)-1))
894  #define LLDEXACT_BLUE_OF(c) (((uint16_t)(((c)>>LLDCOLOR_SHIFT_B)&((1<<LLDCOLOR_BITS_B)-1))*255)/((1<<LLDCOLOR_BITS_B)-1))
895  #define LLDEXACT_LUMA_OF(c) ((LLDEXACT_RED_OF(c)+((uint16_t)LLDEXACT_GREEN_OF(c)<<1)+LLDEXACT_BLUE_OF(c))>>2)
896  #define LLDLUMA2COLOR(l) (LLDRGB2COLOR_R(l) | LLDRGB2COLOR_G(l) | LLDRGB2COLOR_B(l))
897  #define LLDRGB2COLOR(r,g,b) (LLDRGB2COLOR_R(r) | LLDRGB2COLOR_G(g) | LLDRGB2COLOR_B(b))
898 
899  // Calculate LLDHTML2COLOR
900  #if LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R == 24
901  #define LLDHTML2COLOR_R(h) ((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))<<16))
902  #elif COLOR_BITS_R + COLOR_SHIFT_R > 24
903  #define LLDHTML2COLOR_R(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))<<16)) << (LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R-24))
904  #else // COLOR_BITS_R + COLOR_SHIFT_R < 24
905  #define LLDHTML2COLOR_R(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))<<16)) >> (24-(LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R)))
906  #endif
907  #if LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G == 16
908  #define LLDHTML2COLOR_G(h) ((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))<<8))
909  #elif LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G > 16
910  #define LLDHTML2COLOR_G(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))<<8)) << (LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G-16))
911  #else // LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G < 16
912  #define LLDHTML2COLOR_G(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))<<8)) >> (16-(LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G)))
913  #endif
914  #if LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B == 8
915  #define LLDHTML2COLOR_B(h) ((h) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1)))
916  #elif LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B > 8
917  #define LLDHTML2COLOR_B(h) (((h) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1))) << (LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B-8))
918  #else // LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B < 8
919  #define LLDHTML2COLOR_B(h) (((h) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1))) >> (8-(LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B)))
920  #endif
921  #define LLDHTML2COLOR(h) ((LLDCOLOR_TYPE)(LLDHTML2COLOR_R(h) | LLDHTML2COLOR_G(h) | LLDHTML2COLOR_B(h)))
922 
923  //-------------------------
924  // Gray-scale color system
925  //-------------------------
926  #elif (GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_GRAYSCALE
927  #define LLDCOLOR_SYSTEM GDISP_COLORSYSTEM_GRAYSCALE
928 
929  // Calculate the number of bits and shifts
930  #define LLDCOLOR_BITS (GDISP_LLD_PIXELFORMAT & 0xFF)
931  #define LLDCOLOR_BITS_R LLDCOLOR_BITS
932  #define LLDCOLOR_BITS_G LLDCOLOR_BITS
933  #define LLDCOLOR_BITS_B LLDCOLOR_BITS
934  #define LLDCOLOR_SHIFT_R 0
935  #define LLDCOLOR_SHIFT_G 0
936  #define LLDCOLOR_SHIFT_B 0
937 
938  // From the number of bits determine COLOR_TYPE, COLOR_TYPE_BITS and masking
939  #if LLDCOLOR_BITS <= 8
940  #define LLDCOLOR_TYPE uint8_t
941  #define LLDCOLOR_TYPE_BITS 8
942  #else
943  #error "GDISP: Cannot define gray-scale low level driver color types with more than 8 bits"
944  #endif
945  #if LLDCOLOR_TYPE_BITS == LLDCOLOR_BITS
946  #define LLDCOLOR_NEEDS_MASK FALSE
947  #else
948  #define LLDCOLOR_NEEDS_MASK TRUE
949  #endif
950  #define LLDCOLOR_MASK() ((1 << LLDCOLOR_BITS)-1)
951 
952  #if COLOR_BITS == 1
953  #define LLDRGB2COLOR(r,g,b) (((r)|(g)|(b)) ? 1 : 0)
954  #define LLDLUMA2COLOR(l) ((l) ? 1 : 0)
955  #define LLDHTML2COLOR(h) ((h) ? 1 : 0)
956  #define LLDLUMA_OF(c) ((c) ? 255 : 0)
957  #define LLDEXACT_LUMA_OF(c) LLDLUMA_OF(c)
958  #else
959  // They eye is more sensitive to green
960  #define LLDRGB2COLOR(r,g,b) ((LLDCOLOR_TYPE)(((uint16_t)(r)+(g)+(g)+(b)) >> (10-LLDCOLOR_BITS)))
961  #define LLDLUMA2COLOR(l) ((LLDCOLOR_TYPE)((l)>>(8-LLDCOLOR_BITS)))
962  #define LLDHTML2COLOR(h) ((LLDCOLOR_TYPE)(((((h)&0xFF0000)>>16)+(((h)&0x00FF00)>>7)+((h)&0x0000FF)) >> (10-LLDCOLOR_BITS)))
963  #define LLDLUMA_OF(c) (((c) & ((1<<LLDCOLOR_BITS)-1)) << (8-LLDCOLOR_BITS))
964  #define LLDEXACT_LUMA_OF(c) ((((uint16_t)(c) & ((1<<LLDCOLOR_BITS)-1))*255)/((1<<LLDCOLOR_BITS)-1))
965  #endif
966 
967  #define LLDRED_OF(c) LLDLUMA_OF(c)
968  #define LLDGREEN_OF(c) LLDLUMA_OF(c)
969  #define LLDBLUE_OF(c) LLDLUMA_OF(c)
970  #define LLDEXACT_RED_OF(c) LLDEXACT_LUMA_OF(c)
971  #define LLDEXACT_GREEN_OF(c) LLDEXACT_LUMA_OF(c)
972  #define LLDEXACT_BLUE_OF(c) LLDEXACT_LUMA_OF(c)
973 
974  //-------------------------
975  // Palette color system
976  //-------------------------
977  #elif (GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_PALETTE
978  #define LLDCOLOR_SYSTEM GDISP_COLORSYSTEM_PALETTE
979 
980  #error "GDISP: A palette color system for low level drivers is not currently supported"
981 
982  //-------------------------
983  // Some other color system
984  //-------------------------
985  #else
986  #error "GDISP: Unsupported color system for low level drivers"
987  #endif
988 
989  /* Which is the larger color type */
990  #if COLOR_BITS > LLDCOLOR_BITS
991  #define LARGER_COLOR_BITS COLOR_BITS
992  #define LARGER_COLOR_TYPE COLOR_TYPE
993  #else
994  #define LARGER_COLOR_BITS LLDCOLOR_BITS
995  #define LARGER_COLOR_TYPE LLDCOLOR_TYPE
996  #endif
997 
998  /**
999  * @brief Controls color conversion accuracy for a low level driver
1000  * @details Should higher precision be used when converting colors.
1001  * @note Color conversion is only necessary if GDISP_PIXELFORMAT != GDISP_LLD_PIXELFORMAT
1002  * @note It only makes sense to turn this on if you have a high bit depth display but
1003  * are running the application in low bit depths.
1004  * @note To achieve higher color accuracy bit shifting is replaced with multiplies and divides.
1005  */
1006  #ifndef GDISP_HARDWARE_USE_EXACT_COLOR
1007  #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
1008  #define GDISP_HARDWARE_USE_EXACT_COLOR TRUE
1009  #else
1010  #define GDISP_HARDWARE_USE_EXACT_COLOR FALSE
1011  #endif
1012  #endif
1013 
1014  /* Low level driver pixel format conversion functions */
1015  #if GDISP_PIXELFORMAT == GDISP_LLD_PIXELFORMAT || defined(__DOXYGEN__)
1016  /**
1017  * @brief Convert from a standard color format to the low level driver pixel format
1018  * @note For use only by low level drivers
1019  */
1020  #define gdispColor2Native(c) (c)
1021  /**
1022  * @brief Convert from a low level driver pixel format to the standard color format
1023  * @note For use only by low level drivers
1024  */
1025  #define gdispNative2Color(c) (c)
1026  #elif COLOR_SYSTEM == GDISP_COLORSYSTEM_GRAYSCALE || LLDCOLOR_SYSTEM == GDISP_COLORSYSTEM_GRAYSCALE
1027  #if GDISP_HARDWARE_USE_EXACT_COLOR
1028  #define gdispColor2Native(c) LLDLUMA2COLOR(EXACT_LUMA_OF(c))
1029  #define gdispNative2Color(c) LUMA2COLOR(LLDEXACT_LUMA_OF(c))
1030  #else
1031  #define gdispColor2Native(c) LLDLUMA2COLOR(LUMA_OF(c))
1032  #define gdispNative2Color(c) LUMA2COLOR(LLDLUMA_OF(c))
1033  #endif
1034  #elif COLOR_SYSTEM == GDISP_COLORSYSTEM_TRUECOLOR && LLDCOLOR_SYSTEM == GDISP_COLORSYSTEM_TRUECOLOR
1035  #if GDISP_HARDWARE_USE_EXACT_COLOR
1036  #define gdispColor2Native(c) LLDRGB2COLOR(EXACT_RED_OF(c), EXACT_GREEN_OF(c), EXACT_BLUE_OF(c))
1037  #define gdispNative2Color(c) RGB2COLOR(LLDEXACT_RED_OF(c), LLDEXACT_GREEN_OF(c), LLDEXACT_BLUE_OF(c))
1038  #else
1039  #define gdispColor2Native(c) LLDRGB2COLOR(RED_OF(c), GREEN_OF(c), BLUE_OF(c))
1040  #define gdispNative2Color(c) RGB2COLOR(LLDRED_OF(c), LLDGREEN_OF(c), LLDBLUE_OF(c))
1041  #endif
1042  #else
1043  #error "GDISP: This pixel format conversion is not supported yet"
1044  #endif
1045 
1046 #endif
1047 
1048 //------------------------------------------------------------------------------------------------------------
1049 
1050 #undef IN_PIXMAP_DRIVER
1051 #undef IS_MULTIPLE
1052 #undef IN_DRIVER
1053 #undef USE_VMT
1054 #endif /* GFX_USE_GDISP */
1055 
1056 #endif /* _GDISP_LLD_H */
1057 /** @} */
const struct mf_font_s * font_t
The type of a font.
Definition: gdisp.h:93
int16_t coord_t
The type for a coordinate or length on the screen.
Definition: gdisp.h:39
#define GDISP_NEED_CONTROL
Control some aspect of the hardware operation.
#define GDISP_NEED_SCROLL
Are scrolling functions needed.
#define GDISP_NEED_CLIP
Are clipping functions needed.
Definition: gdisp_options.h:71
All runtime driver structures start with this structure.
Definition: gdriver.h:58
#define GDISP_NEED_VALIDATION
Should all operations be clipped to the screen and colors validated.
Definition: gdisp_options.h:64
#define GDISP_LINEBUF_SIZE
Define the default orientation for all displays in the system.
A mutex.
Definition: gos.h:111
COLOR_TYPE color_t
The color type definition.
Definition: gdisp_colors.h:412
All driver VMT&#39;s start with this structure.
Definition: gdriver.h:66
color_t pixel_t
The pixel format.
Definition: gdisp.h:226
#define GDISP_NEED_QUERY
Query some aspect of the hardware operation.