diff --git a/Version.md b/Version.md
index bdddfb20..a8482d39 100644
--- a/Version.md
+++ b/Version.md
@@ -1,6 +1,6 @@
-Version 5.0.13 (2023/08/31)
+Version 5.2.0 (2023/09/30)
-This is a minor enhancement and bugfix release of MiniGUI 5.0.x, the stable version.
+This is a minor enhancement and bugfix release of MiniGUI 5.2.x, the stable version.
Other packages for MiniGUI resource, tools, components, and samples:
diff --git a/configure.ac b/configure.ac
index 60a92486..81097332 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.60)
-AC_INIT(libminigui, 5.0.14)
+AC_INIT(libminigui, 5.2.0)
AC_CONFIG_SRCDIR(src/main/main.c)
dnl Set various version strings - taken gratefully from the SDL sources
@@ -15,8 +15,8 @@ dnl Set various version strings - taken gratefully from the SDL sources
# set MINIGUI_BINARY_AGE and MINIGUI_INTERFACE_AGE to 0.
#
MINIGUI_MAJOR_VERSION=5
-MINIGUI_MINOR_VERSION=0
-MINIGUI_MICRO_VERSION=14
+MINIGUI_MINOR_VERSION=2
+MINIGUI_MICRO_VERSION=0
MINIGUI_INTERFACE_AGE=0
MINIGUI_BINARY_AGE=0
MINIGUI_VERSION=$MINIGUI_MAJOR_VERSION.$MINIGUI_MINOR_VERSION.$MINIGUI_MICRO_VERSION
diff --git a/include/gdi.h b/include/gdi.h
index 8788b313..5f5977d2 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -1709,7 +1709,8 @@ struct GAL_Surface;
typedef struct GAL_Surface *HSURF;
/**
- * \fn HSURF GUIAPI CreateSharedSurface (const char *name, DWORD flags,
+ * \fn HSURF GUIAPI CreateSharedSurface (GHANDLE video,
+ * const char *name, DWORD flags,
* int width, int height, int depth,
* Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
* \brief Creates a shared surface for specified size and pixel format.
@@ -1717,8 +1718,8 @@ typedef struct GAL_Surface *HSURF;
* This function creates a shared surface on the current video device with
* the specified size and pixel format. This function also registers
* the shared surface by using the specified name \a name to the server
- * if \a name is not NULL. Another client can use the name to retrieve
- * the shared surface by calling \a RetrieveSharedSurfaceFDByName().
+ * if \a name is not NULL. Another client can use the name to get
+ * the shared surface by calling \a GetSharedSurfaceFDByName().
* \param video The handle to the video; NULL for the current default video.
* \param name The gobal unique name for the shared surface.
@@ -1740,11 +1741,12 @@ typedef struct GAL_Surface *HSURF;
*
* \note This function only available when _MGSCHEMA_COMPOSITING is defined.
*
- * \sa DestroySharedSurface, RetrieveSharedSurfaceFDByName
+ * \sa DestroySharedSurface, GetSharedSurfaceFDByName
*
* Since 5.2.0
*/
-MG_EXPORT HSURF GUIAPI CreateSharedSurface (const char *name, DWORD flags,
+MG_EXPORT HSURF GUIAPI CreateSharedSurface (GHANDLE video,
+ const char *name, DWORD flags,
int width, int height, int depth,
Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
@@ -1792,7 +1794,7 @@ MG_EXPORT BOOL GUIAPI DestroySharedSurface (HSURF surf);
* Since 5.2.0
*/
MG_EXPORT int GUIAPI GetSharedSurfaceFDByClientWindow (int client,
- HWND hwnd);
+ HWND hwnd, size_t *map_size, DWORD *flags);
/**
* \fn int GUIAPI GetSharedSurfaceFDByName (const char *name)
@@ -1814,10 +1816,12 @@ MG_EXPORT int GUIAPI GetSharedSurfaceFDByClientWindow (int client,
*
* Since 5.2.0
*/
-MG_EXPORT int GUIAPI GetSharedSurfaceFDByName (const char *name);
+MG_EXPORT int GUIAPI GetSharedSurfaceFDByName (const char *name,
+ size_t *map_size, DWORD *flags);
/**
- * \fn HSURF GUIAPI AttachToSharedSurface (GHANDLE video, int fd)
+ * \fn HSURF GUIAPI AttachToSharedSurface (GHANDLE video, int fd,
+ * size_t map_size, DWORD flags)
* \brief Attaches to a shared surface.
*
* This function attaches to the shared surface which is represents by
@@ -1834,7 +1838,8 @@ MG_EXPORT int GUIAPI GetSharedSurfaceFDByName (const char *name);
*
* Since 5.2.0
*/
-MG_EXPORT HSURF GUIAPI AttachToSharedSurface (GHANDLE video, int fd);
+MG_EXPORT HSURF GUIAPI AttachToSharedSurface (GHANDLE video, int fd,
+ size_t map_size, DWORD flags);
/**
* \fn int GUIAPI GetSharedSurfaceInfo (HSURF surf, SIZE *size, int *pitch,
diff --git a/src/include/client.h b/src/include/client.h
index cd2771db..552af8a6 100644
--- a/src/include/client.h
+++ b/src/include/client.h
@@ -163,13 +163,13 @@ typedef struct OperateNSSurfInfo
/* Since 5.0.0 */
typedef struct _SharedSurfInfo {
+ size_t size; // whole size of the surface
+ off_t offset; // offset of pixel data
uint32_t flags; // the flags of the surface
uint32_t width, height;
uint32_t pitch;
uint32_t name; // when use flink name
uint32_t drm_format; // DRM pixel format
- size_t size; // whole size of the surface
- off_t offset; // offset of pixel data
} SHAREDSURFINFO;
typedef struct JoinLayerInfo {
diff --git a/src/include/map.h b/src/include/map.h
index 0ea02ccf..e4e704b7 100644
--- a/src/include/map.h
+++ b/src/include/map.h
@@ -119,7 +119,7 @@ int __mg_map_find_replace_or_insert (map_t* map, const void* key,
int __mg_map_replace (map_t* map, const void* key,
const void* val, free_val_fn free_val_alt);
-int __mg_map_erase (map_t* map, void* key);
+int __mg_map_erase (map_t* map, const void* key);
int __mg_map_get_size (map_t* map);
#if 0 /* deprecated code */
diff --git a/src/include/newgal.h b/src/include/newgal.h
index 96ac1693..023c004a 100644
--- a/src/include/newgal.h
+++ b/src/include/newgal.h
@@ -166,6 +166,9 @@ typedef struct _SharedSurfaceHeader {
size_t map_size;
/* the offset of pixels data */
off_t pixels_off;
+
+ /* the name of the shared surface. */
+ char name[NAME_MAX + 1];
} GAL_SharedSurfaceHeader;
#endif /* IS_COMPOSITING_SCHEMA */
diff --git a/src/include/server.h b/src/include/server.h
index 96c0b6f2..658d13bf 100644
--- a/src/include/server.h
+++ b/src/include/server.h
@@ -135,6 +135,9 @@ void __mg_release_global_res (int cli);
/* Since 5.2.0 */
int __mg_nssurf_map_new(void);
void __mg_nssurf_map_delete(void);
+int __mg_nssurf_map_operate_srv(const OPERATENSSURFINFO* req_info,
+ int cli, int fd);
+int __mg_get_shared_surface_srv(const char *itn_name, SHAREDSURFINFO *info);
void __mg_remove_client (int cli, int clifd);
diff --git a/src/misc/map.c b/src/misc/map.c
index e5e4a630..997ead11 100644
--- a/src/misc/map.c
+++ b/src/misc/map.c
@@ -243,7 +243,7 @@ map_entry_t* __mg_map_find (map_t* map, const void* key)
return entry;
}
-int __mg_map_erase (map_t* map, void* key)
+int __mg_map_erase (map_t* map, const void* key)
{
int retval = -1;
map_entry_t* entry = NULL;
diff --git a/src/newgdi/Makefile.am b/src/newgdi/Makefile.am
index 438bff36..0c1cb378 100644
--- a/src/newgdi/Makefile.am
+++ b/src/newgdi/Makefile.am
@@ -14,7 +14,8 @@ SRC_FILES = gdi.c attr.c clip.c map.c coor.c rect.c \
simple-glyph-renderer.c glyph-shaped.c \
textruns.c \
shape-glyphs-basic.c shape-glyphs-complex.c \
- layout.c layout-utils.c layout-ellipsize.c
+ layout.c layout-utils.c layout-ellipsize.c \
+ shared-surface.c
HDR_FILES = glyph.h drawtext.h mi.h midc.h mistruct.h miwideline.h \
pixel_ops.h mifillarc.h mispans.h polygon.h mifpoly.h \
diff --git a/src/newgdi/shared-surface.c b/src/newgdi/shared-surface.c
new file mode 100644
index 00000000..d5b01277
--- /dev/null
+++ b/src/newgdi/shared-surface.c
@@ -0,0 +1,282 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT NOTICE
+//
+// The following open source license statement does not apply to any
+// entity in the Exception List published by FMSoft.
+//
+// For more information, please visit:
+//
+// https://www.fmsoft.cn/exception-list
+//
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * This file is part of MiniGUI, a mature cross-platform windowing
+ * and Graphics User Interface (GUI) support system for embedded systems
+ * and smart IoT devices.
+ *
+ * Copyright (C) 2023, Beijing FMSoft Technologies Co., Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * Or,
+ *
+ * As this program is a library, any link to this program must follow
+ * GNU General Public License version 3 (GPLv3). If you cannot accept
+ * GPLv3, you need to be licensed from FMSoft.
+ *
+ * If you have got a commercial license of this program, please use it
+ * under the terms and conditions of the commercial license.
+ *
+ * For more information about the commercial license, please refer to
+ * .
+ */
+/*
+** The graphics display interface module of MiniGUI.
+**
+** Current maintainer: Wei Yongming.
+**
+** Create date: 1999.01.03
+*/
+
+#include
+#include
+#include
+
+#include "common.h"
+
+#ifdef _MGSCHEMA_COMPOSITING
+
+#include "minigui.h"
+#include "gdi.h"
+#include "window.h"
+#include "cliprect.h"
+#include "gal.h"
+#include "cursor.h"
+#include "internals.h"
+#include "inline.h"
+#include "dc.h"
+#include "debug.h"
+#include "client.h"
+#include "server.h"
+
+HSURF GUIAPI CreateSharedSurface(GHANDLE video, const char *name, DWORD flags,
+ int width, int height, int depth,
+ Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
+{
+ GAL_Surface *nssurf = NULL;
+
+ if (name) {
+ OPERATENSSURFINFO nssurf_req = {};
+
+ if (strlen(name) + 1 > sizeof(nssurf_req.name)) {
+ _ERR_PRINTF("TOOLONG: too long name for shared surface: %s\n",
+ name);
+ goto failed;
+ }
+
+ strcpy(nssurf_req.name, name);
+ nssurf_req.id_op = ID_NAMEDSSURFOP_REGISTER;
+
+ int result;
+ if (IsServer()) {
+ result = __mg_nssurf_map_operate_srv(&nssurf_req, 0, -1);
+ }
+ else {
+ REQUEST req;
+
+ req.id = REQID_OPERATENAMEDSSURF;
+ req.data = &nssurf_req;
+ req.len_data = sizeof(OPERATENSSURFINFO);
+
+ if (ClientRequest(&req, &result, sizeof(result))) {
+ _ERR_PRINTF("BAD_REQUEST: when registering name for a new shared surface\n");
+ goto failed;
+ }
+ }
+
+ if (result) {
+ _ERR_PRINTF("FAILED_REQUEST: when registering name of shared surface\n");
+ goto failed;
+ }
+ }
+
+ nssurf = GAL_CreateSharedRGBSurface(video, flags, 0666, width, height, depth,
+ Rmask, Gmask, Bmask, Amask);
+ if (nssurf == NULL) {
+ goto failed;
+ }
+
+ if (name) {
+ strcpy(nssurf->shared_header->name, name);
+
+ OPERATENSSURFINFO nssurf_req = {};
+ strcpy(nssurf_req.name, name);
+ nssurf_req.id_op = ID_NAMEDSSURFOP_SET;
+ nssurf_req.map_size = nssurf->shared_header->map_size;
+
+ int result;
+ if (IsServer()) {
+ result = __mg_nssurf_map_operate_srv(&nssurf_req, 0,
+ nssurf->shared_header->fd);
+ }
+ else {
+ REQUEST req;
+
+ req.id = REQID_OPERATENAMEDSSURF;
+ req.data = &nssurf_req;
+ req.len_data = sizeof(OPERATENSSURFINFO);
+
+ if (ClientRequestEx2(&req, NULL, 0, nssurf->shared_header->fd,
+ &result, sizeof(result), NULL)) {
+ _ERR_PRINTF("BAD_REQUEST: when setting fd of the new shared surface.\n");
+ goto failed;
+ }
+ }
+
+ if (result) {
+ _ERR_PRINTF("FAILED_REQUEST: when setting fd of the shared surface\n");
+ goto failed;
+ }
+ }
+ else {
+ nssurf->shared_header->name[0] = 0;
+ }
+
+ return nssurf;
+
+failed:
+ if (nssurf)
+ GAL_FreeSurface(nssurf);
+
+ return NULL;
+}
+
+BOOL GUIAPI DestroySharedSurface(HSURF surf)
+{
+ if (surf->shared_header == NULL) {
+ _ERR_PRINTF("INVALID_ARG: surface handle: %p\n", surf);
+ goto failed;
+ }
+
+ if (surf->shared_header->creator == getpid() &&
+ surf->shared_header->name[0]) {
+ /* This is a named shared surface created by this client */
+
+ OPERATENSSURFINFO nssurf_req = {};
+ strcpy(nssurf_req.name, surf->shared_header->name);
+ nssurf_req.id_op = ID_NAMEDSSURFOP_REVOKE;
+
+ int result;
+ if (IsServer()) {
+ result = __mg_nssurf_map_operate_srv(&nssurf_req, 0, -1);
+ }
+ else {
+ REQUEST req;
+
+ req.id = REQID_OPERATENAMEDSSURF;
+ req.data = &nssurf_req;
+ req.len_data = sizeof(OPERATENSSURFINFO);
+
+ if (ClientRequest(&req, &result, sizeof(result))) {
+ _ERR_PRINTF("BAD_REQUEST: when revoking name of a shared surface.\n");
+ goto failed;
+ }
+ }
+
+ if (result) {
+ _ERR_PRINTF("FAILED_REQUEST: when revoking name of a shared surface\n");
+ goto failed;
+ }
+ }
+
+ GAL_FreeSurface(surf);
+ return TRUE;
+
+failed:
+ return FALSE;
+}
+
+static int get_shared_surface(const char *name, size_t *map_size, DWORD *flags)
+{
+ int fd = -1;
+ SHAREDSURFINFO info;
+
+ if (IsServer()) {
+ fd = __mg_get_shared_surface_srv(name, &info);
+ }
+ else {
+ REQUEST req;
+
+ req.id = REQID_GETSHAREDSURFACE;
+ req.data = name;
+ req.len_data = strlen(name) + 1;
+
+ if (ClientRequestEx2(&req, NULL, 0, -1,
+ &info, sizeof(SHAREDSURFINFO), &fd) < 0) {
+ _ERR_PRINTF("BAD_REQUEST: when getting shared surface: %s\n", name);
+ goto failed;
+ }
+
+ if (fd < 0) {
+ _ERR_PRINTF("FAILED_REQUEST: when getting shared surface: %s\n", name);
+ goto failed;
+ }
+
+ _DBG_PRINTF("REQID_GETSHAREDSURFACE: size (%lu), flags (0x%x), fd: %d\n",
+ info.size, info.flags, fd);
+
+ }
+
+ if (fd >= 0) {
+ if (map_size)
+ *map_size = info.size;
+ if (flags)
+ *flags = info.flags;
+ }
+ return fd;
+
+failed:
+ return -1;
+}
+
+int GUIAPI GetSharedSurfaceFDByClientWindow(int client, HWND hwnd,
+ size_t *map_size, DWORD *flags)
+{
+ char itn_name[sizeof(APPSF_NAME_PREFIX) + NAME_MAX + 1];
+
+ int ret = snprintf(itn_name, sizeof(itn_name), APPSF_HWND_PATTER,
+ client, hwnd);
+ if (ret <= 0 || (size_t)ret >= sizeof(itn_name)) {
+ return -1;
+ }
+
+ return get_shared_surface(itn_name, map_size, flags);
+}
+
+int GUIAPI GetSharedSurfaceFDByName(const char *name,
+ size_t *map_size, DWORD *flags)
+{
+ char itn_name[sizeof(APPSF_NAME_PREFIX) + NAME_MAX + 1];
+
+ int ret = snprintf(itn_name, sizeof(itn_name), APPSF_NAME_PATTER, name);
+ if (ret <= 0 || (size_t)ret >= sizeof(itn_name)) {
+ return -1;
+ }
+
+ return get_shared_surface(itn_name, map_size, flags);
+}
+
+#endif /* defined _MGSCHEMA_COMPOSITING */
+
diff --git a/src/server/request.c b/src/server/request.c
index 78fc08f8..7b761ff4 100644
--- a/src/server/request.c
+++ b/src/server/request.c
@@ -812,68 +812,13 @@ void __mg_nssurf_map_delete(void)
__mg_map_destroy(__nssurf_map);
}
-/* get the fake screen surface (wallpaper pattern surface) */
-static int get_shared_surface (int cli, int clifd, void* buff, size_t len)
-{
- SHAREDSURFINFO info = {};
- int fd = -1;
-
- assert (__gal_fake_screen);
-
- if (strcmp(buff, SYSSF_WALLPAPER_PATTER) == 0 &&
- __gal_fake_screen->shared_header) {
- info.flags = __gal_fake_screen->flags;
- info.size = __gal_fake_screen->shared_header->map_size;
- fd = __gal_fake_screen->shared_header->fd;
- }
- else if (strncmp(buff, APPSF_NAME_PREFIX,
- sizeof(APPSF_NAME_PREFIX) - 1) == 0) {
- const char *name = buff + sizeof(APPSF_NAME_PREFIX) - 1;
- map_entry_t *entry = __mg_map_find(__nssurf_map, name);
- if (entry == NULL)
- goto failed;
-
- struct nssurf_info *nssurf_info = entry->val;
- assert(nssurf_info);
- info.size = nssurf_info->map_size;
- fd = nssurf_info->fd;
- }
- else if (strncmp(buff, APPSF_HWND_PREFIX,
- sizeof(APPSF_HWND_PREFIX) - 1) == 0) {
- int client;
- HWND hwnd;
- int ret = sscanf(buff, APPSF_HWND_PATTER, &client, &hwnd);
- if (ret != 2)
- goto failed;
-
- ZORDERNODE *znode = __mg_find_znode_by_client_hwnd(client, hwnd);
- if (znode == NULL)
- goto failed;
-
- PDC pdc = dc_HDC2PDC(znode->mem_dc);
- assert(pdc->surface->shared_header);
- info.size = pdc->surface->shared_header->map_size;
- info.width = pdc->surface->shared_header->width;
- info.height = pdc->surface->shared_header->height;
- info.pitch = pdc->surface->shared_header->pitch;
- info.offset = pdc->surface->shared_header->pixels_off;
- fd = pdc->surface->shared_header->fd;
- }
-
- return ServerSendReplyEx (clifd, &info, sizeof (SHAREDSURFINFO), fd);
-
-failed:
- return ServerSendReplyEx (clifd, &info, sizeof (SHAREDSURFINFO), -1);
-}
-
-static int
-operate_nssurface(int cli, int clifd, void* buff, size_t len, int fd)
+int __mg_nssurf_map_operate_srv(const OPERATENSSURFINFO* req_info,
+ int cli, int fd)
{
int result = -1;
map_entry_t *entry;
struct nssurf_info *nssurf_info;
- OPERATENSSURFINFO* req_info = (OPERATENSSURFINFO*)buff;
switch (req_info->id_op) {
case ID_NAMEDSSURFOP_REGISTER:
entry = __mg_map_find(__nssurf_map, req_info->name);
@@ -930,6 +875,75 @@ operate_nssurface(int cli, int clifd, void* buff, size_t len, int fd)
}
done:
+ return result;
+}
+
+int __mg_get_shared_surface_srv(const char *itn_name, SHAREDSURFINFO *info)
+{
+ int fd = -1;
+ assert (__gal_fake_screen);
+
+ if (strcmp(itn_name, SYSSF_WALLPAPER_PATTER) == 0 &&
+ __gal_fake_screen->shared_header) {
+ info->flags = __gal_fake_screen->flags;
+ info->size = __gal_fake_screen->shared_header->map_size;
+ fd = __gal_fake_screen->shared_header->fd;
+ }
+ else if (strncmp(itn_name, APPSF_NAME_PREFIX,
+ sizeof(APPSF_NAME_PREFIX) - 1) == 0) {
+ const char *name = itn_name + sizeof(APPSF_NAME_PREFIX) - 1;
+ map_entry_t *entry = __mg_map_find(__nssurf_map, name);
+ if (entry == NULL)
+ goto done;
+
+ struct nssurf_info *nssurf_info = entry->val;
+ assert(nssurf_info);
+ info->size = nssurf_info->map_size;
+ fd = nssurf_info->fd;
+ }
+ else if (strncmp(itn_name, APPSF_HWND_PREFIX,
+ sizeof(APPSF_HWND_PREFIX) - 1) == 0) {
+ int client;
+ HWND hwnd;
+ int ret = sscanf(itn_name, APPSF_HWND_PATTER, &client, &hwnd);
+ if (ret != 2)
+ goto done;
+
+ ZORDERNODE *znode = __mg_find_znode_by_client_hwnd(client, hwnd);
+ if (znode == NULL)
+ goto done;
+
+ PDC pdc = dc_HDC2PDC(znode->mem_dc);
+ assert(pdc->surface->shared_header);
+ info->size = pdc->surface->shared_header->map_size;
+ info->width = pdc->surface->shared_header->width;
+ info->height = pdc->surface->shared_header->height;
+ info->pitch = pdc->surface->shared_header->pitch;
+ info->offset = pdc->surface->shared_header->pixels_off;
+ fd = pdc->surface->shared_header->fd;
+ }
+
+done:
+ return fd;
+}
+
+/* get the fake screen surface (wallpaper pattern surface) */
+static int get_shared_surface (int cli, int clifd, void* buff, size_t len)
+{
+ SHAREDSURFINFO info = {};
+ int fd = __mg_get_shared_surface_srv(buff, &info);
+
+ return ServerSendReplyEx (clifd, &info, sizeof (SHAREDSURFINFO), fd);
+}
+
+static int
+operate_nssurface(int cli, int clifd, void* buff, size_t len, int fd)
+{
+ int result = -1;
+
+ assert(len >= sizeof(OPERATENSSURFINFO));
+ OPERATENSSURFINFO* req_info = (OPERATENSSURFINFO*)buff;
+ result = __mg_nssurf_map_operate_srv(req_info, cli, fd);
return ServerSendReply(clifd, &result, sizeof(int));
}