version 2.8
gdisp_pixmap.c
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 #include "../../gfx.h"
9 
10 #if GFX_USE_GDISP && GDISP_NEED_PIXMAP
11 
12 // We undef everything because the system may think we are in a single controller situation
13 // but the pixmap supports adds another virtual display
14 #undef GDISP_HARDWARE_DEINIT
15 #undef GDISP_HARDWARE_FLUSH
16 #undef GDISP_HARDWARE_STREAM_WRITE
17 #undef GDISP_HARDWARE_STREAM_READ
18 #undef GDISP_HARDWARE_STREAM_POS
19 #undef GDISP_HARDWARE_DRAWPIXEL
20 #undef GDISP_HARDWARE_CLEARS
21 #undef GDISP_HARDWARE_FILLS
22 #undef GDISP_HARDWARE_BITFILLS
23 #undef GDISP_HARDWARE_SCROLL
24 #undef GDISP_HARDWARE_PIXELREAD
25 #undef GDISP_HARDWARE_CONTROL
26 #undef GDISP_HARDWARE_QUERY
27 #undef GDISP_HARDWARE_CLIP
28 #define GDISP_HARDWARE_DEINIT TRUE
29 #define GDISP_HARDWARE_DRAWPIXEL TRUE
30 #define GDISP_HARDWARE_PIXELREAD TRUE
31 #define GDISP_HARDWARE_CONTROL TRUE
32 #define IN_PIXMAP_DRIVER TRUE
33 #define GDISP_DRIVER_VMT GDISPVMT_pixmap
34 #define GDISP_DRIVER_VMT_FLAGS (GDISP_VFLG_DYNAMICONLY|GDISP_VFLG_PIXMAP)
35 
36 // This pseudo driver currently only supports unpacked formats with more than 8 bits per pixel
37 // that is, we only support GRAY_SCALE and PALETTE with 8 bits per pixel or any unpacked TRUE_COLOR format.
38 #if (GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_GRAYSCALE) && (GDISP_LLD_PIXELFORMAT & 0xFF) != 8
39  #error "GDISP Pixmap: Pixmap's do not currently support the specified GDISP_LLD_PIXELFORMAT"
40 #endif
41 
42 #include "gdisp_driver.h"
43 #include "../gdriver/gdriver.h"
44 
45 typedef struct pixmap {
46  #if GDISP_NEED_PIXMAP_IMAGE
47  uint8_t imghdr[8]; // This field must come just before the data member.
48  #endif
49  color_t pixels[1]; // We really want pixels[0] but some compilers don't allow that even though it is C standard.
50  } pixmap;
51 
52 GDisplay *gdispPixmapCreate(coord_t width, coord_t height) {
53  GDisplay *g;
54  pixmap *p;
55  unsigned i;
56 
57  // Calculate the size of the display surface in bytes
58  i = width*height*sizeof(color_t);
59  if (i < 2*sizeof(coord_t))
60  i = 2*sizeof(coord_t);
61 
62  // Allocate the pixmap
63  if (!(p = gfxAlloc(i+sizeof(pixmap)-sizeof(p->pixels))))
64  return 0;
65 
66  // Fill in the image header (if required)
67  #if GDISP_NEED_PIXMAP_IMAGE
68  p->imghdr[0] = 'N';
69  p->imghdr[1] = 'I';
70  p->imghdr[2] = (uint8_t)(width >> 8);
71  p->imghdr[3] = (uint8_t)width;
72  p->imghdr[4] = (uint8_t)(height >> 8);
73  p->imghdr[5] = (uint8_t)height;
74  p->imghdr[6] = (uint8_t)(GDISP_PIXELFORMAT >> 8);
75  p->imghdr[7] = (uint8_t)(GDISP_PIXELFORMAT);
76  #endif
77 
78  // Save the width and height so the driver can retrieve it.
79  ((coord_t *)p->pixels)[0] = width;
80  ((coord_t *)p->pixels)[1] = height;
81 
82  // Register the driver
83  g = (GDisplay *)gdriverRegister(&GDISPVMT_pixmap->d, p);
84  if (!g)
85  gfxFree(p);
86  return g;
87 }
88 
89 void gdispPixmapDelete(GDisplay *g) {
90  if (gvmt(g) != GDISPVMT_pixmap)
91  return;
92  gdriverUnRegister(&g->d);
93 }
94 
95 pixel_t *gdispPixmapGetBits(GDisplay *g) {
96  if (gvmt(g) != GDISPVMT_pixmap)
97  return 0;
98  return ((pixmap *)g->priv)->pixels;
99 }
100 
101 #if GDISP_NEED_PIXMAP_IMAGE
102  void *gdispPixmapGetMemoryImage(GDisplay *g) {
103  if (gvmt(g) != GDISPVMT_pixmap)
104  return 0;
105  return ((pixmap *)g->priv)->imghdr;
106  }
107 #endif
108 
109 /*===========================================================================*/
110 /* Driver exported functions. */
111 /*===========================================================================*/
112 
113 LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
114  // The user api function should have already allocated and initialised the pixmap
115  // structure and put it into the priv member during driver initialisation.
116  if (!g->priv)
117  return FALSE;
118 
119  // Initialize the GDISP structure
120  // Width and height were saved into the start of the framebuffer.
121  g->g.Width = ((coord_t *)((pixmap *)g->priv)->pixels)[0];
122  g->g.Height = ((coord_t *)((pixmap *)g->priv)->pixels)[1];
123  g->g.Backlight = 100;
124  g->g.Contrast = 50;
125  g->g.Orientation = GDISP_ROTATE_0;
126  g->g.Powermode = powerOn;
127  g->board = 0;
128 
129  return TRUE;
130 }
131 
132 LLDSPEC void gdisp_lld_deinit(GDisplay *g) {
133  gfxFree(g->priv);
134 }
135 
136 LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
137  unsigned pos;
138 
139  #if GDISP_NEED_CONTROL
140  switch(g->g.Orientation) {
141  case GDISP_ROTATE_0:
142  default:
143  pos = g->p.y * g->g.Width + g->p.x;
144  break;
145  case GDISP_ROTATE_90:
146  pos = (g->g.Width-g->p.x-1) * g->g.Height + g->p.y;
147  break;
148  case GDISP_ROTATE_180:
149  pos = (g->g.Height-g->p.y-1) * g->g.Width + g->g.Width-g->p.x-1;
150  break;
151  case GDISP_ROTATE_270:
152  pos = g->p.x * g->g.Height + g->g.Height-g->p.y-1;
153  break;
154  }
155  #else
156  pos = g->p.y * g->g.Width + g->p.x;
157  #endif
158 
159  ((pixmap *)(g)->priv)->pixels[pos] = g->p.color;
160 }
161 
162 LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
163  unsigned pos;
164 
165  #if GDISP_NEED_CONTROL
166  switch(g->g.Orientation) {
167  case GDISP_ROTATE_0:
168  default:
169  pos = g->p.y * g->g.Width + g->p.x;
170  break;
171  case GDISP_ROTATE_90:
172  pos = (g->g.Width-g->p.x-1) * g->g.Height + g->p.y;
173  break;
174  case GDISP_ROTATE_180:
175  pos = (g->g.Height-g->p.y-1) * g->g.Width + g->g.Width-g->p.x-1;
176  break;
177  case GDISP_ROTATE_270:
178  pos = g->p.x * g->g.Height + g->g.Height-g->p.y-1;
179  break;
180  }
181  #else
182  pos = g->p.y * g->g.Width + g->p.x;
183  #endif
184 
185  return ((pixmap *)(g)->priv)->pixels[pos];
186 }
187 
188 #if GDISP_NEED_CONTROL
189  LLDSPEC void gdisp_lld_control(GDisplay *g) {
190  switch(g->p.x) {
191  case GDISP_CONTROL_ORIENTATION:
192  if (g->g.Orientation == (orientation_t)g->p.ptr)
193  return;
194  switch((orientation_t)g->p.ptr) {
195  case GDISP_ROTATE_0:
196  case GDISP_ROTATE_180:
197  if (g->g.Orientation == GDISP_ROTATE_90 || g->g.Orientation == GDISP_ROTATE_270) {
198  coord_t tmp;
199 
200  tmp = g->g.Width;
201  g->g.Width = g->g.Height;
202  g->g.Height = tmp;
203  }
204  break;
205  case GDISP_ROTATE_90:
206  case GDISP_ROTATE_270:
207  if (g->g.Orientation == GDISP_ROTATE_0 || g->g.Orientation == GDISP_ROTATE_180) {
208  coord_t tmp;
209 
210  tmp = g->g.Width;
211  g->g.Width = g->g.Height;
212  g->g.Height = tmp;
213  }
214  break;
215  default:
216  return;
217  }
218  g->g.Orientation = (orientation_t)g->p.ptr;
219  return;
220  }
221  }
222 #endif
223 
224 #endif /* GFX_USE_GDISP */
GDisplay * gdispPixmapCreate(coord_t width, coord_t height)
Create an off-screen pixmap that can be drawn to just like a normal display.
void gdriverUnRegister(GDriver *driver)
UnRegister a driver instance.
Definition: gdriver.c:69
int16_t coord_t
The type for a coordinate or length on the screen.
Definition: gdisp.h:39
GDriver * gdriverRegister(const GDriverVMT *vmt, void *param)
Register a new driver instance.
Definition: gdriver.c:31
GDISP Graphic Driver subsystem low level driver header.
#define FALSE
Generic &#39;false&#39; boolean constant.
Definition: gfx.h:31
void gdispPixmapDelete(GDisplay *g)
Destroy an off-screen pixmap.
void * gfxAlloc(size_t sz)
Allocate memory.
void * gdispPixmapGetMemoryImage(GDisplay *g)
Get a pointer to a native format gdispImage.
pixel_t * gdispPixmapGetBits(GDisplay *g)
Get a pointer to the pixels of the display surface.
void gfxFree(void *ptr)
Free memory.
COLOR_TYPE color_t
The color type definition.
Definition: gdisp_colors.h:412
Definition: gdisp.h:118
#define TRUE
Generic &#39;true&#39; boolean constant.
Definition: gfx.h:38
color_t pixel_t
The pixel format.
Definition: gdisp.h:226