aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJoel Bodenmann <joel@seriouslyembedded.com>2015-11-27 20:39:28 +0100
committerJoel Bodenmann <joel@seriouslyembedded.com>2015-11-27 20:39:28 +0100
commit5a99092b794373966e444296c57991631e712c70 (patch)
tree3e2853ab9730ece7398f508238ac2707e485b346 /src
parenteaf0b19fb8428b9e2e47798294d6ba83a56d186e (diff)
parentf16ee702727a811288749a0722ddb138dd559fa8 (diff)
downloaduGFX-5a99092b794373966e444296c57991631e712c70.tar.gz
uGFX-5a99092b794373966e444296c57991631e712c70.tar.bz2
uGFX-5a99092b794373966e444296c57991631e712c70.zip
Merge branch 'master' of https://bitbucket.org/Tectu/ugfx
Diffstat (limited to 'src')
-rw-r--r--src/gdisp/gdisp_image.h2
-rw-r--r--src/gdisp/gdisp_image_bmp.c33
-rw-r--r--src/gdisp/gdisp_image_gif.c22
-rw-r--r--src/gdisp/gdisp_image_native.c40
-rw-r--r--src/gos/gos.h17
-rw-r--r--src/gos/gos_arduino.h2
-rw-r--r--src/gos/gos_options.h5
-rw-r--r--src/gos/gos_rules.h11
-rw-r--r--src/gos/gos_x_heap.c11
-rw-r--r--src/gos/gos_x_heap.h42
-rw-r--r--src/gwin/gwin_keyboard.c2
-rw-r--r--src/gwin/gwin_keyboard.h2
12 files changed, 112 insertions, 77 deletions
diff --git a/src/gdisp/gdisp_image.h b/src/gdisp/gdisp_image.h
index 4613bea7..2b6fdf19 100644
--- a/src/gdisp/gdisp_image.h
+++ b/src/gdisp/gdisp_image.h
@@ -66,7 +66,7 @@ typedef struct gdispImage {
uint32_t maxmemused; /* @< How much RAM has been allocated (maximum) */
#endif
const struct gdispImageHandlers * fns; /* @< Don't mess with this! */
- struct gdispImagePrivate * priv; /* @< Don't mess with this! */
+ void * priv; /* @< Don't mess with this! */
} gdispImage;
#ifdef __cplusplus
diff --git a/src/gdisp/gdisp_image_bmp.c b/src/gdisp/gdisp_image_bmp.c
index 73549ae3..371fdf2d 100644
--- a/src/gdisp/gdisp_image_bmp.c
+++ b/src/gdisp/gdisp_image_bmp.c
@@ -53,14 +53,17 @@ typedef struct gdispImagePrivate_BMP {
} gdispImagePrivate_BMP;
void gdispImageClose_BMP(gdispImage *img) {
- if (img->priv) {
+ gdispImagePrivate_BMP *priv;
+
+ priv = (gdispImagePrivate_BMP *)img->priv;
+ if (priv) {
#if GDISP_NEED_IMAGE_BMP_1 || GDISP_NEED_IMAGE_BMP_4 || GDISP_NEED_IMAGE_BMP_4_RLE || GDISP_NEED_IMAGE_BMP_8 || GDISP_NEED_IMAGE_BMP_8_RLE
- if (img->priv->palette)
- gdispImageFree(img, (void *)img->priv->palette, img->priv->palsize*sizeof(color_t));
+ if (priv->palette)
+ gdispImageFree(img, (void *)priv->palette, priv->palsize*sizeof(color_t));
#endif
- if (img->priv->frame0cache)
- gdispImageFree(img, (void *)img->priv->frame0cache, img->width*img->height*sizeof(pixel_t));
- gdispImageFree(img, (void *)img->priv, sizeof(gdispImagePrivate_BMP));
+ if (priv->frame0cache)
+ gdispImageFree(img, (void *)priv->frame0cache, img->width*img->height*sizeof(pixel_t));
+ gdispImageFree(img, (void *)priv, sizeof(gdispImagePrivate_BMP));
img->priv = 0;
}
}
@@ -89,11 +92,11 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) {
img->flags = 0;
/* Allocate our private area */
- if (!(img->priv = (gdispImagePrivate_BMP *)gdispImageAlloc(img, sizeof(gdispImagePrivate_BMP))))
+ if (!(img->priv = gdispImageAlloc(img, sizeof(gdispImagePrivate_BMP))))
return GDISP_IMAGE_ERR_NOMEMORY;
/* Initialise the essential bits in the private area */
- priv = img->priv;
+ priv = (gdispImagePrivate_BMP *)img->priv;
priv->frame0cache = 0;
priv->bmpflags = 0;
#if GDISP_NEED_IMAGE_BMP_1 || GDISP_NEED_IMAGE_BMP_4 || GDISP_NEED_IMAGE_BMP_4_RLE || GDISP_NEED_IMAGE_BMP_8 || GDISP_NEED_IMAGE_BMP_8_RLE
@@ -119,7 +122,7 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) {
// Detect our bitmap version
if (offsetColorTable == 12+14) {
- img->priv->bmpflags |= BMP_V2;
+ priv->bmpflags |= BMP_V2;
// Read the header
if (gfileRead(img->f, priv->buf, 12-4) != 12-4)
@@ -129,7 +132,7 @@ gdispImageError gdispImageOpen_BMP(gdispImage *img) {
// Get the height
img->height = gdispImageGetAlignedLE16(priv->buf, 2);
if (img->height < 0) {
- img->priv->bmpflags |= BMP_TOP_TO_BOTTOM;
+ priv->bmpflags |= BMP_TOP_TO_BOTTOM;
img->height = -img->height;
}
// Get the planes
@@ -361,7 +364,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) {
color_t * pc;
coord_t len;
- priv = img->priv;
+ priv = (gdispImagePrivate_BMP *)img->priv;
pc = priv->buf;
len = 0;
@@ -372,7 +375,7 @@ static coord_t getPixels(gdispImage *img, coord_t x) {
uint8_t b[4];
uint8_t m;
- priv = img->priv;
+ priv = (gdispImagePrivate_BMP *)img->priv;
pc = priv->buf;
len = 0;
@@ -703,7 +706,7 @@ gdispImageError gdispImageCache_BMP(gdispImage *img) {
size_t len;
/* If we are already cached - just return OK */
- priv = img->priv;
+ priv = (gdispImagePrivate_BMP *)img->priv;
if (priv->frame0cache)
return GDISP_IMAGE_ERR_OK;
@@ -720,6 +723,8 @@ gdispImageError gdispImageCache_BMP(gdispImage *img) {
priv->rlecode = 0;
#endif
+ pcs = priv->buf; // This line is just to prevent a compiler warning.
+
if (priv->bmpflags & BMP_TOP_TO_BOTTOM) {
for(y = 0, pcd = priv->frame0cache; y < img->height; y++) {
x = 0; pos = 0;
@@ -756,7 +761,7 @@ gdispImageError gdispGImageDraw_BMP(GDisplay *g, gdispImage *img, coord_t x, coo
coord_t mx, my;
coord_t pos, len, st;
- priv = img->priv;
+ priv = (gdispImagePrivate_BMP *)img->priv;
/* Check some reasonableness */
if (sx >= img->width || sy >= img->height) return GDISP_IMAGE_ERR_OK;
diff --git a/src/gdisp/gdisp_image_gif.c b/src/gdisp/gdisp_image_gif.c
index f3e9d8dd..5a3f68c6 100644
--- a/src/gdisp/gdisp_image_gif.c
+++ b/src/gdisp/gdisp_image_gif.c
@@ -117,7 +117,7 @@ static gdispImageError startDecodeGif(gdispImage *img) {
gifimgdecode * decode;
uint16_t cnt;
- priv = img->priv;
+ priv = (gdispImagePrivate_GIF *)img->priv;
// We need the decode ram, and possibly a palette
if (!(decode = (gifimgdecode *)gdispImageAlloc(img, sizeof(gifimgdecode)+priv->frame.palsize*sizeof(color_t))))
@@ -179,7 +179,7 @@ baddatacleanup:
static void stopDecodeGif(gdispImage *img) {
gdispImagePrivate_GIF * priv;
- priv = img->priv;
+ priv = (gdispImagePrivate_GIF *)img->priv;
// Free the decode data
if (priv->decode) {
@@ -214,7 +214,7 @@ static uint16_t getBytesGif(gdispImage *img) {
uint16_t code, prefix;
uint8_t bdata;
- priv = img->priv;
+ priv = (gdispImagePrivate_GIF *)img->priv;
decode = priv->decode;
cnt = 0;
@@ -346,7 +346,7 @@ static gdispImageError initFrameGif(gdispImage *img) {
uint8_t blocktype;
uint8_t blocksz;
- priv = img->priv;
+ priv = (gdispImagePrivate_GIF *)img->priv;
// Save the dispose info from the existing frame
priv->dispose.flags = priv->frame.flags;
@@ -504,7 +504,7 @@ void gdispImageClose_GIF(gdispImage *img) {
gifimgcache * cache;
gifimgcache * ncache;
- priv = img->priv;
+ priv = (gdispImagePrivate_GIF *)img->priv;
if (priv) {
// Free any stored frames
cache = priv->cache;
@@ -515,7 +515,7 @@ void gdispImageClose_GIF(gdispImage *img) {
}
if (priv->palette)
gdispImageFree(img, (void *)priv->palette, priv->palsize*sizeof(color_t));
- gdispImageFree(img, (void *)img->priv, sizeof(gdispImagePrivate_GIF));
+ gdispImageFree(img, (void *)priv, sizeof(gdispImagePrivate_GIF));
img->priv = 0;
}
}
@@ -539,11 +539,11 @@ gdispImageError gdispImageOpen_GIF(gdispImage *img) {
img->flags = 0;
/* Allocate our private area */
- if (!(img->priv = (gdispImagePrivate_GIF *)gdispImageAlloc(img, sizeof(gdispImagePrivate_GIF))))
+ if (!(img->priv = gdispImageAlloc(img, sizeof(gdispImagePrivate_GIF))))
return GDISP_IMAGE_ERR_NOMEMORY;
/* Initialise the essential bits in the private area */
- priv = img->priv;
+ priv = (gdispImagePrivate_GIF *)img->priv;
priv->flags = 0;
priv->palsize = 0;
priv->palette = 0;
@@ -610,7 +610,7 @@ gdispImageError gdispImageCache_GIF(gdispImage *img) {
uint16_t cnt;
/* If we are already cached - just return OK */
- priv = img->priv;
+ priv = (gdispImagePrivate_GIF *)img->priv;
if (priv->curcache)
return GDISP_IMAGE_ERR_OK;
@@ -779,7 +779,7 @@ gdispImageError gdispGImageDraw_GIF(GDisplay *g, gdispImage *img, coord_t x, coo
uint16_t cnt, gcnt;
uint8_t col;
- priv = img->priv;
+ priv = (gdispImagePrivate_GIF *)img->priv;
/* Handle previous frame disposing */
if (priv->dispose.flags & (GIFL_DISPOSECLEAR|GIFL_DISPOSEREST)) {
@@ -1116,7 +1116,7 @@ delaytime_t gdispImageNext_GIF(gdispImage *img) {
delaytime_t delay;
uint8_t blocksz;
- priv = img->priv;
+ priv = (gdispImagePrivate_GIF *)img->priv;
// Save the delay and convert to millisecs
delay = (delaytime_t)priv->frame.delay * 10;
diff --git a/src/gdisp/gdisp_image_native.c b/src/gdisp/gdisp_image_native.c
index df7c9f72..28706564 100644
--- a/src/gdisp/gdisp_image_native.c
+++ b/src/gdisp/gdisp_image_native.c
@@ -26,16 +26,19 @@
void *gdispImageAlloc(gdispImage *img, size_t sz);
void gdispImageFree(gdispImage *img, void *ptr, size_t sz);
-typedef struct gdispImagePrivate {
+typedef struct gdispImagePrivate_NATIVE {
pixel_t *frame0cache;
pixel_t buf[BLIT_BUFFER_SIZE_NATIVE];
- } gdispImagePrivate;
+ } gdispImagePrivate_NATIVE;
void gdispImageClose_NATIVE(gdispImage *img) {
- if (img->priv) {
- if (img->priv->frame0cache)
- gdispImageFree(img, (void *)img->priv->frame0cache, img->width * img->height * sizeof(pixel_t));
- gdispImageFree(img, (void *)img->priv, sizeof(gdispImagePrivate));
+ gdispImagePrivate_NATIVE * priv;
+
+ priv = (gdispImagePrivate_NATIVE *)img->priv;
+ if (priv) {
+ if (priv->frame0cache)
+ gdispImageFree(img, (void *)priv->frame0cache, img->width * img->height * sizeof(pixel_t));
+ gdispImageFree(img, (void *)priv, sizeof(gdispImagePrivate_NATIVE));
img->priv = 0;
}
}
@@ -59,9 +62,9 @@ gdispImageError gdispImageOpen_NATIVE(gdispImage *img) {
img->height = (((uint16_t)hdr[4])<<8) | (hdr[5]);
if (img->width < 1 || img->height < 1)
return GDISP_IMAGE_ERR_BADDATA;
- if (!(img->priv = (gdispImagePrivate *)gdispImageAlloc(img, sizeof(gdispImagePrivate))))
+ if (!(img->priv = gdispImageAlloc(img, sizeof(gdispImagePrivate_NATIVE))))
return GDISP_IMAGE_ERR_NOMEMORY;
- img->priv->frame0cache = 0;
+ ((gdispImagePrivate_NATIVE *)(img->priv))->frame0cache = 0;
img->type = GDISP_IMAGE_TYPE_NATIVE;
return GDISP_IMAGE_ERR_OK;
@@ -69,20 +72,22 @@ gdispImageError gdispImageOpen_NATIVE(gdispImage *img) {
gdispImageError gdispImageCache_NATIVE(gdispImage *img) {
size_t len;
+ gdispImagePrivate_NATIVE * priv;
/* If we are already cached - just return OK */
- if (img->priv->frame0cache)
+ priv = (gdispImagePrivate_NATIVE *)img->priv;
+ if (priv->frame0cache)
return GDISP_IMAGE_ERR_OK;
/* We need to allocate the cache */
len = img->width * img->height * sizeof(pixel_t);
- img->priv->frame0cache = (pixel_t *)gdispImageAlloc(img, len);
- if (!img->priv->frame0cache)
+ priv->frame0cache = (pixel_t *)gdispImageAlloc(img, len);
+ if (!priv->frame0cache)
return GDISP_IMAGE_ERR_NOMEMORY;
/* Read the entire bitmap into cache */
gfileSetPos(img->f, FRAME0POS_NATIVE);
- if (gfileRead(img->f, img->priv->frame0cache, len) != len)
+ if (gfileRead(img->f, priv->frame0cache, len) != len)
return GDISP_IMAGE_ERR_BADDATA;
return GDISP_IMAGE_ERR_OK;
@@ -91,6 +96,9 @@ gdispImageError gdispImageCache_NATIVE(gdispImage *img) {
gdispImageError gdispGImageDraw_NATIVE(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy) {
coord_t mx, mcx;
size_t pos, len;
+ gdispImagePrivate_NATIVE * priv;
+
+ priv = (gdispImagePrivate_NATIVE *)img->priv;
/* Check some reasonableness */
if (sx >= img->width || sy >= img->height) return GDISP_IMAGE_ERR_OK;
@@ -98,8 +106,8 @@ gdispImageError gdispGImageDraw_NATIVE(GDisplay *g, gdispImage *img, coord_t x,
if (sy + cy > img->height) cy = img->height - sy;
/* Draw from the image cache - if it exists */
- if (img->priv->frame0cache) {
- gdispGBlitArea(g, x, y, cx, cy, sx, sy, img->width, img->priv->frame0cache);
+ if (priv->frame0cache) {
+ gdispGBlitArea(g, x, y, cx, cy, sx, sy, img->width, priv->frame0cache);
return GDISP_IMAGE_ERR_OK;
}
@@ -115,14 +123,14 @@ gdispImageError gdispGImageDraw_NATIVE(GDisplay *g, gdispImage *img, coord_t x,
for(mx = x, mcx = cx; mcx > 0; mcx -= len, mx += len) {
// Read the data
len = gfileRead(img->f,
- img->priv->buf,
+ priv->buf,
mcx > BLIT_BUFFER_SIZE_NATIVE ? (BLIT_BUFFER_SIZE_NATIVE*sizeof(pixel_t)) : (mcx * sizeof(pixel_t)))
/ sizeof(pixel_t);
if (!len)
return GDISP_IMAGE_ERR_BADDATA;
/* Blit the chunk of data */
- gdispGBlitArea(g, mx, y, len, 1, 0, 0, len, img->priv->buf);
+ gdispGBlitArea(g, mx, y, len, 1, 0, 0, len, priv->buf);
}
/* Get the position for the start of the next line */
diff --git a/src/gos/gos.h b/src/gos/gos.h
index c3cdca50..1c4ef865 100644
--- a/src/gos/gos.h
+++ b/src/gos/gos.h
@@ -176,6 +176,23 @@
void gfxFree(void *ptr);
/**
+ * @brief Use gfxAlloc and gfxFree to implement malloc() and free()
+ *
+ * @notes Sometimes your application will include functions that
+ * want to internally use malloc() and free(). As the default
+ * implementations of these in your C library are almost
+ * invariably incorrect for an embedded platform, this option
+ * allows you to emulate those calls with gfxAlloc() and gfxFree().
+ * An example is the C library routine rand() which on many
+ * implementations internally uses malloc().
+ *
+ * @api
+ */
+ #ifndef GFX_EMULATE_MALLOC
+ #define GFX_EMULATE_MALLOC FALSE
+ #endif
+
+ /**
* @brief Yield the current thread
* @details Give up the rest of the current time slice for this thread in order to give other threads
* a chance to run.
diff --git a/src/gos/gos_arduino.h b/src/gos/gos_arduino.h
index 6a18aaec..3019d271 100644
--- a/src/gos/gos_arduino.h
+++ b/src/gos/gos_arduino.h
@@ -31,7 +31,7 @@
/* Type definitions */
/*===========================================================================*/
-typedef bool bool_t;
+typedef unsigned char bool_t;
#if 0
// Already defined by Arduino
diff --git a/src/gos/gos_options.h b/src/gos/gos_options.h
index 4b33f5ac..0c6fd7a7 100644
--- a/src/gos/gos_options.h
+++ b/src/gos/gos_options.h
@@ -181,9 +181,10 @@
#define GFX_FREERTOS_USE_TRACE FALSE
#endif
/**
- * @brief How much RAM should uGFX use for the heap
+ * @brief How much RAM should uGFX use for the heap when using its own internal heap allocator
* @details Defaults to 0.
- * @note Only used when the generic ugfx heap code is used (GFX_USE_OS_RAW32, GFX_USE_OS_ARDUINO, GFX_US_OS_KEIL, GFX_USE_OS_CMSIS)
+ * @note Only used when the internal ugfx heap allocator is used
+ * (GFX_USE_OS_RAW32, GFX_USE_OS_ARDUINO, GFX_US_OS_KEIL, GFX_USE_OS_CMSIS)
* @note If 0 then the standard C runtime malloc(), free() and realloc()
* are used.
* @note If it is non-zero then this is the number of bytes of RAM
diff --git a/src/gos/gos_rules.h b/src/gos/gos_rules.h
index b0184eb0..d2e64ff1 100644
--- a/src/gos/gos_rules.h
+++ b/src/gos/gos_rules.h
@@ -32,5 +32,16 @@
#error "GOS: GFX_FREERTOS_USE_TRACE is only available for the FreeRTOS port."
#endif
+#if GFX_EMULATE_MALLOC
+ #if GFX_USE_OS_WIN32 || GFX_USE_OS_LINUX || GFX_USE_OS_OSX || GFX_USE_OS_ECOS || \
+ (GFX_OS_HEAP_SIZE == 0 && (GFX_USE_OS_RAW32 || GFX_USE_OS_ARDUINO || GFX_USE_OS_CMSIS || GFX_USE_OS_KEIL))
+ #if GFX_DISPLAY_RULE_WARNINGS
+ #warning "GOS: Cannot emulate malloc as gfxAlloc() internally uses malloc on this platform"
+ #endif
+ #undef GFX_EMULATE_MALLOC
+ #define GFX_EMULATE_MALLOC FALSE
+ #endif
+#endif
+
#endif /* _GOS_RULES_H */
/** @} */
diff --git a/src/gos/gos_x_heap.c b/src/gos/gos_x_heap.c
index cd78f403..7e79d1c6 100644
--- a/src/gos/gos_x_heap.c
+++ b/src/gos/gos_x_heap.c
@@ -194,3 +194,14 @@
#endif
#endif /* GOS_NEED_X_HEAP */
+
+#if GFX_EMULATE_MALLOC
+ #include <stdlib.h>
+
+ void* malloc(size_t size) {
+ return gfxAlloc(size);
+ }
+ void free(void *ptr) {
+ gfxFree(ptr);
+ }
+#endif
diff --git a/src/gos/gos_x_heap.h b/src/gos/gos_x_heap.h
index 3612989c..0fbfc905 100644
--- a/src/gos/gos_x_heap.h
+++ b/src/gos/gos_x_heap.h
@@ -5,38 +5,10 @@
* http://ugfx.org/license.html
*/
-/**
- * The raw32 GOS implementation supports any 32 bit processor with or without an
- * underlying operating system. It uses cooperative multi-tasking. Be careful
- * when writing device drivers not to disturb the assumptions this creates by performing
- * call-backs to uGFX code unless you define the INTERRUPTS_OFF() and INTERRUPTS_ON() macros.
- * It still requires some C runtime library support...
- * enough startup to initialise the stack, interrupts, static data etc and call main().
- * setjmp() and longjmp() - for threading
- * memcpy() - for heap and threading
- * malloc(), realloc and free() - if GFX_OS_HEAP_SIZE == 0
- *
- * You must also define the following routines in your own code so that timing functions will work...
- * systemticks_t gfxSystemTicks(void);
- * systemticks_t gfxMillisecondsToTicks(delaytime_t ms);
- */
#ifndef _GOS_X_HEAP_H
#define _GOS_X_HEAP_H
-#if GOS_NEED_X_HEAP
-
-
-/*===========================================================================*/
-/* Special Macros */
-/*===========================================================================*/
-
-/**
- * @brief Set the maximum size of the heap.
- * @note If set to 0 then the C runtime library malloc() and free() are used.
- */
-#ifndef GFX_OS_HEAP_SIZE
- #define GFX_OS_HEAP_SIZE 0
-#endif
+#if GOS_NEED_X_HEAP || defined(__DOXYGEN__)
/*===========================================================================*/
/* Type definitions */
@@ -46,7 +18,17 @@
extern "C" {
#endif
- #if GFX_OS_HEAP_SIZE != 0
+ #if GFX_OS_HEAP_SIZE != 0 || defined(__DOXYGEN__)
+ /**
+ * @brief Take a chunk of memory and add it to the available heap
+ * @note Memory added must obviously not already be on the heap.
+ * @note It is allowable to add multiple non-contiguous blocks of memory
+ * to the heap. If however it is contiguous with a previously added block
+ * it will get merged with the existing block in order to allow
+ * allocations that span the boundary.
+ * @pre GFX_OS_HEAP_SIZE != 0 and an operating system that uses the
+ * internal ugfx heap allocator rather than its own allocator.
+ */
void gfxAddHeapBlock(void *ptr, size_t sz);
#endif
diff --git a/src/gwin/gwin_keyboard.c b/src/gwin/gwin_keyboard.c
index 7080cd5d..59befa3f 100644
--- a/src/gwin/gwin_keyboard.c
+++ b/src/gwin/gwin_keyboard.c
@@ -364,7 +364,7 @@ GSourceHandle gwinKeyboardGetEventSource(GHandle gh) {
return (GSourceHandle)gh;
}
-void gwinKeyboardSetLayout(GHandle gh, struct GVKeyTable *layout) {
+void gwinKeyboardSetLayout(GHandle gh, const struct GVKeyTable *layout) {
#define gk ((GKeyboardObject *)gh)
if (gh->vmt != (gwinVMT *)&keyboardVMT)
diff --git a/src/gwin/gwin_keyboard.h b/src/gwin/gwin_keyboard.h
index 347b4bb4..a09127bd 100644
--- a/src/gwin/gwin_keyboard.h
+++ b/src/gwin/gwin_keyboard.h
@@ -101,7 +101,7 @@ GSourceHandle gwinKeyboardGetEventSource(GHandle gh);
* @note Changing the layout resets the keyboard to key set 0 of the keyboard and cancels any
* pending shifts.
*/
-void gwinKeyboardSetLayout(GHandle gh, struct GVKeyTable *layout);
+void gwinKeyboardSetLayout(GHandle gh, const struct GVKeyTable *layout);
/**
* @defgroup Renderings_Keyboard Renderings