initial implementation for named shared surface

This commit is contained in:
Vincent Wei
2023-08-28 16:51:46 +08:00
parent c7569e9d32
commit 5a9b08fe94
12 changed files with 470 additions and 24 deletions
+1 -1
View File
@@ -6067,7 +6067,7 @@ error:
}
#ifdef _MGSCHEMA_COMPOSITING
int GUIAPI GetWindowSurfaceBufferFD (HWND hWnd)
int GUIAPI GetWindowSharedSurfaceFD (HWND hWnd)
{
MG_CHECK_RET (MG_IS_APP_WINDOW (hWnd), -1);
+20 -1
View File
@@ -105,6 +105,10 @@
#define REQID_GETSHAREDSURFACE 0x001C
// for compositing schema
#define SYSSF_WALLPAPER_PATTER "syssf-wallpaper-pattern"
#define APPSF_NAME_PREFIX "appsf-name-"
#define APPSF_NAME_PATTER "appsf-name-%s"
#define APPSF_HWND_PREFIX "appsf-hwnd-"
#define APPSF_HWND_PATTER "appsf-hwnd-%d-%p"
// for sharedfb schema
#define SYSSF_REAL_SCREEN "syssf-real-screen"
#define SYSSF_SHADOW_SCREEN "syssf-shadow-screen"
@@ -126,7 +130,14 @@
// Authenticate client
#define REQID_AUTHCLIENT 0x0023
#define REQID_SYS_LAST REQID_AUTHCLIENT
/* Since 5.2.0 */
// Operate a shared surface to register/revoke the name and set the fd
#define REQID_OPERATENAMEDSSURF 0x0024
#define ID_NAMEDSSURFOP_REGISTER 1
#define ID_NAMEDSSURFOP_SET 2
#define ID_NAMEDSSURFOP_REVOKE 3
#define REQID_SYS_LAST REQID_OPERATENAMEDSSURF
/*
* XXX: To fellows who need to add a new REQID,
@@ -142,6 +153,14 @@ MGUI_COMPILE_TIME_ASSERT(sys_request_id, MAX_SYS_REQID >= REQID_SYS_LAST);
#undef MGUI_COMPILE_TIME_ASSERT
/* Since 5.2.0 */
typedef struct OperateNSSurfInfo
{
int id_op;
char name[NAME_MAX + 1];
size_t map_size;
} OPERATENSSURFINFO;
/* Since 5.0.0 */
typedef struct _SharedSurfInfo {
uint32_t flags; // the flags of the surface
+5
View File
@@ -83,6 +83,11 @@ static inline int comp_key_string (const void *key1, const void *key2)
return strcmp (key1, key2);
}
static inline void free_val_alloc (void *val)
{
free (val);
}
typedef struct _map_t map_t;
typedef struct _map_entry_t {
struct rb_node node;
+5
View File
@@ -132,6 +132,10 @@ void __mg_client_del (int cli);
void __mg_release_global_res (int cli);
/* Since 5.2.0 */
int __mg_nssurf_map_new(void);
void __mg_nssurf_map_delete(void);
void __mg_remove_client (int cli, int clifd);
int __mg_handle_request (int clifd, int req_id, int cli);
@@ -150,6 +154,7 @@ int __mg_remove_all_znodes_of_client (int cli);
int __mg_handle_normal_mouse_move (const ZORDERINFO* zi, int x, int y);
int __mg_get_znode_at_point (const ZORDERINFO* zi, int x, int y, HWND* hwnd);
ZORDERNODE *__mg_find_znode_by_client_hwnd (int cli, HWND hwnd);
int __mg_do_reghook_operation (int cli, const REGHOOKINFO* info);
int __mg_handle_mouse_hook (int message, WPARAM wParam, LPARAM lParam);
+28
View File
@@ -55,6 +55,7 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include "common.h"
@@ -1520,6 +1521,33 @@ static BOOL _cb_update_rc_nocli (void* context,
}
#endif /* not defined _MGSCHEMA_COMPOSITING */
/* Since 5.2.0 */
ZORDERNODE *__mg_find_znode_by_client_hwnd (int cli, HWND hwnd)
{
ZORDERINFO* zi = get_zorder_info(cli);
ZORDERNODE* nodes;
if (zi == NULL)
return NULL;
int level, slot = -1;
nodes = GET_ZORDERNODE(zi);
for (level = 0; level < NR_ZORDER_LEVELS; level++) {
slot = zi->first_in_levels[level];
for (; slot > 0; slot = nodes[slot].next) {
if (nodes[slot].cli == cli && nodes[slot].hwnd == hwnd) {
goto found;
}
}
}
return NULL;
found:
assert(slot >= 0);
return nodes + slot;
}
int __mg_remove_all_znodes_of_client (int cli)
{
BOOL has_special = FALSE;
+1 -1
View File
@@ -3392,7 +3392,7 @@ struct GAL_Surface* GetSurfaceFromDC (HDC hdc)
}
#ifdef _MGSCHEMA_COMPOSITING
HDC GUIAPI CreateMemDCFromSurfaceBufferFD (int fd)
HDC GUIAPI CreateMemDCFromSharedSurfaceFD (int fd)
{
HDC memdc = HDC_INVALID;
GAL_Surface* surf;
+149 -8
View File
@@ -70,6 +70,8 @@
#include "server.h"
#include "sharedres.h"
#include "misc.h"
#include "map.h"
#include "dc.h"
typedef void (* ReleaseProc) (void* );
@@ -778,25 +780,159 @@ extern int __mg_clipboard_op (int cli, int clifd, void* buff, size_t len);
#endif
#if IS_COMPOSITING_SCHEMA
static map_t *__nssurf_map;
struct nssurf_info {
int creator;
int fd;
size_t map_size;
};
static void my_free_val(void *val)
{
struct nssurf_info *nssurf_info = val;
if (nssurf_info->fd >= 0)
close(nssurf_info->fd);
free(val);
}
int __mg_nssurf_map_new(void)
{
__nssurf_map = __mg_map_create(copy_key_string,
free_key_string, NULL, my_free_val, comp_key_string);
if (__nssurf_map == NULL)
return -1;
return 0;
}
void __mg_nssurf_map_delete(void)
{
assert(__nssurf_map);
__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;
SHAREDSURFINFO info = {};
int fd = -1;
assert (__gal_fake_screen);
info.flags = __gal_fake_screen->flags;
if (strcmp (buff, SYSSF_WALLPAPER_PATTER) == 0 &&
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;
return ServerSendReplyEx (clifd, &info, sizeof (SHAREDSURFINFO),
__gal_fake_screen->shared_header->fd);
fd = __gal_fake_screen->shared_header->fd;
}
else {
info.size = 0;
return ServerSendReplyEx (clifd, &info, sizeof (SHAREDSURFINFO), -1);
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 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);
if (entry)
goto done;
nssurf_info = malloc(sizeof(*nssurf_info));
if (nssurf_info == NULL)
goto done;
nssurf_info->creator = cli;
nssurf_info->fd = -1;
nssurf_info->map_size = 0;
if (__mg_map_insert(__nssurf_map, req_info->name, nssurf_info)) {
free(nssurf_info);
goto done;
}
break;
case ID_NAMEDSSURFOP_SET:
if (fd == -1) {
goto done;
}
entry = __mg_map_find(__nssurf_map, req_info->name);
if (entry == NULL)
goto done;
assert(entry->val);
nssurf_info = entry->val;
if (nssurf_info->creator != cli)
goto done;
nssurf_info->fd = fd;
nssurf_info->map_size = req_info->map_size;
result = 0;
break;
case ID_NAMEDSSURFOP_REVOKE:
entry = __mg_map_find(__nssurf_map, req_info->name);
if (entry == NULL)
goto done;
assert(entry->val);
nssurf_info = entry->val;
if (nssurf_info->creator != cli)
goto done;
if (__mg_map_erase(__nssurf_map, req_info->name))
goto done;
result = 0;
break;
default:
break;
}
done:
return ServerSendReply(clifd, &result, sizeof(int));
}
#else /* IS_COMPOSITING_SCHEMA */
/* get the rendering surface */
static int get_shared_surface (int cli, int clifd, void* buff, size_t len)
@@ -894,6 +1030,11 @@ static struct req_request {
{ move_to_layer, 0 }, // REQID_MOVETOLAYER
{ calc_position, 0 }, // REQID_CALCPOSITION
{ authenticate_client, 0 }, // REQID_AUTHCLIENT
#if IS_COMPOSITING_SCHEMA
{ operate_nssurface, 1 }, // REQID_OPERATENSSURF
#else
{ NULL, 0 },
#endif
};
BOOL GUIAPI RegisterRequestHandler (int req_id, REQ_HANDLER your_handler)
+13 -1
View File
@@ -299,9 +299,17 @@ BOOL GUIAPI ServerStartup (int nr_globals,
SHAREDRES_DEF_NR_TOPMOSTS = def_nr_topmosts;
SHAREDRES_DEF_NR_NORMALS = def_nr_normals;
/* Since 5.2.0 */
#ifdef _MGSCHEMA_COMPOSITING
if (__mg_nssurf_map_new()) {
_ERR_PRINTF ("mginit: failed to initialize map for named shared surface\n");
return FALSE;
}
#endif
if (__mg_init_layers () == -1) {
_ERR_PRINTF ("mginit: failed to initialize layers\n");
return FALSE;
goto fail_layers;
}
SHAREDRES_NR_LAYSERS = 1;
@@ -340,6 +348,10 @@ BOOL GUIAPI ServerStartup (int nr_globals,
fail:
__mg_cleanup_layers ();
fail_layers:
#ifdef _MGSCHEMA_COMPOSITING
__mg_nssurf_map_delete ();
#endif
return FALSE;
}