diff --git a/include/gdi.h b/include/gdi.h index dfe07c4f..1d14a58c 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -1886,7 +1886,7 @@ MG_EXPORT const char *GUIAPI GetSharedSurfaceInfo (HSURF surf, int *fd, /** * \fn BOOL GUIAPI LockSharedSurface (HSURF surf, * unsigned *dirty_age, int *nr_dirty_rects, const RECT **dirty_rects) - * \brief Locks the shared surface. + * \brief Locks the shared surface for read. * * This function lock the given shared surface \a surf and returns * the dirty age. @@ -1911,25 +1911,22 @@ MG_EXPORT BOOL GUIAPI LockSharedSurface (HSURF surf, unsigned *dirty_age, int *nr_dirty_rects, const RECT **dirty_rects); /** - * \fn BOOL GUIAPI UnlockSharedSurface (HSURF surf, BOOL clear_dirty) - * \brief Unlocks the shared surface and clears the dirty information. + * \fn BOOL GUIAPI UnlockSharedSurface (HSURF surf) + * \brief Unlocks the shared surface. * - * This function unlocks the shared surface \a surf, and clears its dirty - * information if \a clear_dirty is TRUE. + * This function unlocks the given shared surface \a surf. * * \param surf The handle to the shared surface. - * \param clear_dirty A boolean value indicates whether to clear the dirty - * information of the shared surface. * * \return TRUE on success; otherwise failure. * * \note This function only available when _MGSCHEMA_COMPOSITING is defined. * - * \sa LockSharedSurfaceIfDirty + * \sa LockSharedSurface * * Since 5.2.0 */ -MG_EXPORT BOOL GUIAPI UnlockSharedSurface (HSURF surf, BOOL clear_dirty); +MG_EXPORT BOOL GUIAPI UnlockSharedSurface (HSURF surf); /** * \fn BOOL GUIAPI DetachFromSharedSurface (HSURF surf) diff --git a/include/window.h b/include/window.h index 2621eb90..2edca72a 100644 --- a/include/window.h +++ b/include/window.h @@ -2990,18 +2990,22 @@ typedef struct _WINMASKINFO { if the client moved to a new layer */ #define MSG_LAYERCHANGED 0x0149 +/* Since 5.2.0; the server send this message to the client + if a window has been composited to the screen. */ +#define MSG_WINCOMPOSITED 0x014A + #endif /* defined _MGRM_PROCESSES */ /* Since 5.0.0: for managing message thread */ -#define MSG_MANAGE_MSGTHREAD 0x014A +#define MSG_MANAGE_MSGTHREAD 0x014B #define MSGTHREAD_SIGNIN 0x00 #define MSGTHREAD_SIGNOUT 0x01 /* Since 5.0.0: for calculating the default position */ -#define MSG_CALC_POSITION 0x014B +#define MSG_CALC_POSITION 0x014C /* Since 5.0.6: for waking up the client */ -#define MSG_WAKEUP_CLIENT 0x014C +#define MSG_WAKEUP_CLIENT 0x014D /** * \def MSG_DOESNEEDIME diff --git a/src/client/client.c b/src/client/client.c index cd1da6b9..0535c1cf 100644 --- a/src/client/client.c +++ b/src/client/client.c @@ -184,6 +184,21 @@ static void process_socket_message (MSG *msg) LOSWORD(msg->wParam), HISWORD(msg->wParam), LOSWORD(msg->lParam), HISWORD(msg->lParam)); } +#ifdef _MGSCHEMA_COMPOSITING + else if (msg->message == MSG_WINCOMPOSITED) { + /* Since 5.2.0 */ + int slot = (int)msg->wParam; + HWND hwnd = (HWND)msg->lParam; + if (__mg_client_check_znode_hwnd(slot, hwnd, __mg_client_id)) { + GAL_Surface *ssurf = ((PMAINWIN)hwnd)->surf; + assert(ssurf->shared_header); + __mg_lock_file_for_write(ssurf->fd); + ssurf->dirty_info->nr_dirty_rcs = 0; + ssurf->dirty_info->dirty_age++; + __mg_unlock_file_for_write(ssurf->fd); + } + } +#endif else { if (msg->hwnd == HWND_NULL) { msg->hwnd = HWND_DESKTOP; diff --git a/src/include/client.h b/src/include/client.h index 552af8a6..b9122b71 100644 --- a/src/include/client.h +++ b/src/include/client.h @@ -378,6 +378,7 @@ void __mg_start_client_desktop (void); void __mg_update_window (HWND hwnd, int left, int top, int right, int bottom); +BOOL __mg_client_check_znode_hwnd (int slot, HWND hwnd, int cli); BOOL __mg_client_check_hwnd (HWND hwnd, int cli); BOOL __mg_client_on_layer_changed (GHANDLE layer_handle, int zi_shmid); diff --git a/src/include/drawsemop.h b/src/include/drawsemop.h index 907ee068..ba6b452a 100644 --- a/src/include/drawsemop.h +++ b/src/include/drawsemop.h @@ -82,21 +82,6 @@ again: extern int __mg_client_id; -#if 0 -#ifdef _MGSCHEMA_COMPOSITING -# define LOCK_SURFACE_SEM(num) \ - do { \ - printf("Locking semaphor %d for client: %d\n", num, __mg_client_id); \ - my_sem_op(SHAREDRES_SEMID_SHARED_SURF, num, -1); \ - } while (0) -# define UNLOCK_SURFACE_SEM(num) \ - do { \ - my_sem_op(SHAREDRES_SEMID_SHARED_SURF, num, 1); \ - printf("Unlocked semaphor %d for client: %d\n", num, __mg_client_id); \ - } while (0) -#endif -#endif - #ifdef _MGHAVE_CURSOR #define LOCK_CURSOR_SEM() my_sem_op(SHAREDRES_SEMID, _IDX_SEM_CURSOR, -1) diff --git a/src/include/msgstr.h b/src/include/msgstr.h index 94638a1f..4f753c90 100644 --- a/src/include/msgstr.h +++ b/src/include/msgstr.h @@ -396,10 +396,10 @@ char * __mg_msgstr3 [] = "MSG_SRVNOTIFY", // 0x0147 "MSG_UPDATECLIWIN", // 0x0148 "MSG_LAYERCHANGED", // 0x0149 - "MSG_MANAGE_MSGTHREAD", // 0x014A - "MSG_CALC_POSITION", // 0x014B - "", // 0x014C - "", // 0x014D + "MSG_WINCOMPOSITED", // 0x014A + "MSG_MANAGE_MSGTHREAD", // 0x014B + "MSG_CALC_POSITION", // 0x014C + "MSG_WAKEUP_CLIENT", // 0x014D "", // 0x014E "", // 0x014F diff --git a/src/kernel/compsor-manager.c b/src/kernel/compsor-manager.c index 81b0c1d9..fea53aaf 100644 --- a/src/kernel/compsor-manager.c +++ b/src/kernel/compsor-manager.c @@ -130,7 +130,6 @@ static const CompositorOps* load_default_compositor (void) static void lock_znode_surface (PDC pdc, ZORDERNODE* node) { - _DBG_PRINTF("lock count for node %p: %d\n", node, node->lock_count); if (node->lock_count == 0) { if (pdc->surface->shared_header) { __mg_lock_file_for_read(pdc->surface->fd); @@ -145,12 +144,17 @@ static void lock_znode_surface (PDC pdc, ZORDERNODE* node) node->lock_count++; } -static void unlock_znode_surface (PDC pdc, ZORDERNODE* node) +static BOOL unlock_znode_surface (PDC pdc, ZORDERNODE* node) { - _DBG_PRINTF("lock count for node %p: %d\n", node, node->lock_count); + BOOL need_reset = FALSE; if (node->lock_count > 0) { node->lock_count--; if (node->lock_count == 0) { + if (node->changes != pdc->surface->dirty_info->dirty_age) { + node->changes = pdc->surface->dirty_info->dirty_age; + need_reset = TRUE; + } + if (pdc->surface->shared_header) { __mg_unlock_file_for_read(pdc->surface->fd); } @@ -160,6 +164,19 @@ static void unlock_znode_surface (PDC pdc, ZORDERNODE* node) node->dirty_rcs = NULL; } } + + return need_reset; +} + +static void reset_znode_surface_dirty (PDC pdc, ZORDERNODE* node, int slot) +{ + if (node->cli == 0 || slot == 0) { + pdc->surface->dirty_info->nr_dirty_rcs = 0; + } + else if (node->hwnd) { + MSG msg = { HWND_NULL, MSG_WINCOMPOSITED, slot, (LPARAM)node->hwnd }; + __mg_send2client(&msg, node); + } } #if 0 /* not optimized */ @@ -324,10 +341,8 @@ static void composite_layer (MG_Layer* layer, CompositorCtxt* ctxt, nodes = GET_MENUNODE(zi); for (i = 0; i < zi->nr_popupmenus; i++) { pdc = dc_HDC2PDC (nodes[i].mem_dc); - - nodes[i].changes = pdc->surface->dirty_info->dirty_age; - pdc->surface->dirty_info->nr_dirty_rcs = 0; - unlock_znode_surface (pdc, nodes + i); + if (unlock_znode_surface (pdc, nodes + i)) + reset_znode_surface_dirty (pdc, nodes + i, i); } } @@ -337,9 +352,8 @@ static void composite_layer (MG_Layer* layer, CompositorCtxt* ctxt, while ((next = __kernel_get_next_znode (zi, next)) > 0) { if (nodes [next].flags & ZOF_VISIBLE) { pdc = dc_HDC2PDC (nodes[next].mem_dc); - nodes[next].changes = pdc->surface->dirty_info->dirty_age; - pdc->surface->dirty_info->nr_dirty_rcs = 0; - unlock_znode_surface (pdc, nodes + next); + if (unlock_znode_surface (pdc, nodes + next)) + reset_znode_surface_dirty (pdc, nodes + next, next); } } @@ -348,9 +362,8 @@ static void composite_layer (MG_Layer* layer, CompositorCtxt* ctxt, if (layer == mgTopmostLayer) { pdc = dc_HDC2PDC (HDC_SCREEN); if (pdc->surface->w > 0 && pdc->surface->h > 0) { - nodes[0].changes = pdc->surface->dirty_info->dirty_age; - pdc->surface->dirty_info->nr_dirty_rcs = 0; - unlock_znode_surface (pdc, nodes); + if (unlock_znode_surface (pdc, nodes)) + reset_znode_surface_dirty (pdc, nodes, 0); } } } diff --git a/src/kernel/desktop-comm.c b/src/kernel/desktop-comm.c index 27677dec..afafea46 100644 --- a/src/kernel/desktop-comm.c +++ b/src/kernel/desktop-comm.c @@ -154,7 +154,7 @@ static int dskAllocZOrderNode (PMAINWIN pWin) return AllocZOrderNode (0, (HWND)pWin, (HWND)pWin->pMainWin, get_znode_flags_from_style (pWin), - &rc, pWin->spCaption, HDC_INVALID, -1, + &rc, pWin->spCaption, HDC_INVALID, CT_OPAQUE, 0); } diff --git a/src/kernel/desktop-procs.c b/src/kernel/desktop-procs.c index 7067aaac..795ad32f 100644 --- a/src/kernel/desktop-procs.c +++ b/src/kernel/desktop-procs.c @@ -865,7 +865,7 @@ static int srvAllocZOrderNode (int cli, HWND hwnd, HWND main_win, #endif /* def _MGSCHEMA_COMPOSITING */ free_slot = AllocZOrderNode (cli, hwnd, - main_win, flags, rc, caption, memdc, fd, ct, ct_arg); + main_win, flags, rc, caption, memdc, ct, ct_arg); if ((free_slot != -1) && OnZNodeOperation) OnZNodeOperation (ZNOP_ALLOCATE, cli, free_slot); @@ -1020,7 +1020,7 @@ static int srvMoveWindow (int cli, int idx_znode, const RECT* rcWin, } #endif /* def _MGSCHEMA_COMPOSITING */ - ret = dskMoveWindow (cli, idx_znode, memdc, fd, rcWin); + ret = dskMoveWindow (cli, idx_znode, memdc, rcWin); if (ret == 0 && OnZNodeOperation) OnZNodeOperation (ZNOP_MOVEWIN, cli, idx_znode); @@ -2907,6 +2907,21 @@ int __mg_handle_mouse_hook (int message, WPARAM wParam, LPARAM lParam) } #endif /* deprecated code */ +/* used by client to check the validation of a hwnd in the given znode slot. */ +BOOL __mg_client_check_znode_hwnd (int slot, HWND hwnd, int cli) +{ + BOOL ret = FALSE; + ZORDERINFO* zi = __mg_zorder_info; + ZORDERNODE* nodes; + + nodes = GET_ZORDERNODE(zi); + lock_zi_for_read (zi); + if (nodes[slot].hwnd == hwnd && nodes[slot].cli == cli) + ret = TRUE; + unlock_zi_for_read (zi); + return ret; +} + /* used by client to check the validation of a hwnd */ BOOL __mg_client_check_hwnd (HWND hwnd, int cli) { diff --git a/src/kernel/desktop.c b/src/kernel/desktop.c index 153be360..5ab17cb0 100644 --- a/src/kernel/desktop.c +++ b/src/kernel/desktop.c @@ -1648,6 +1648,7 @@ static int srvStartTrackPopupMenu (int cli, const RECT* rc, HWND ptmi, menu_nodes [zi->nr_popupmenus].flags = ZOF_TYPE_POPUPMENU; menu_nodes [zi->nr_popupmenus].rc = *rc; menu_nodes [zi->nr_popupmenus].hwnd = ptmi; + menu_nodes [zi->nr_popupmenus].cli = 0; #ifdef _MGSCHEMA_COMPOSITING menu_nodes [zi->nr_popupmenus].changes = 0; menu_nodes [zi->nr_popupmenus].ct = CT_OPAQUE; @@ -2149,7 +2150,7 @@ static void update_on_new_visible_znode (void* layer, ZORDERINFO* zi, static int AllocZOrderNodeEx (ZORDERINFO* zi, int cli, HWND hwnd, HWND main_win, DWORD flags, const RECT *rc, const char *caption, - HDC mem_dc, int fd, int ct, DWORD ct_arg) + HDC mem_dc, int ct, DWORD ct_arg) { DWORD type = flags & ZOF_TYPE_MASK; int *first = NULL, *nr_nodes = NULL; @@ -2419,10 +2420,10 @@ static int AllocZOrderNodeEx (ZORDERINFO* zi, int cli, HWND hwnd, HWND main_win, static inline int AllocZOrderNode (int cli, HWND hwnd, HWND main_win, DWORD flags, const RECT *rc, const char *caption, - HDC mem_dc, int fd, int ct, DWORD ct_arg) + HDC mem_dc, int ct, DWORD ct_arg) { return AllocZOrderNodeEx (get_zorder_info(cli), cli, hwnd, main_win, - flags, rc, caption, mem_dc, fd, ct, ct_arg); + flags, rc, caption, mem_dc, ct, ct_arg); } static void prepare_to_delete_visible_znode (void* layer, ZORDERINFO* zi, @@ -3362,8 +3363,7 @@ static int dskHideWindow (int cli, int idx_znode) return 0; } -static int dskMoveWindow (int cli, int idx_znode, HDC memdc, int fd, - const RECT* rcWin) +static int dskMoveWindow (int cli, int idx_znode, HDC memdc, const RECT* rcWin) { DWORD type; int level, *first = NULL; diff --git a/src/newgdi/shared-surface.c b/src/newgdi/shared-surface.c index acd715e5..0c767a44 100644 --- a/src/newgdi/shared-surface.c +++ b/src/newgdi/shared-surface.c @@ -355,7 +355,7 @@ failed: return FALSE; } -BOOL GUIAPI UnlockSharedSurface(HSURF surf, BOOL clear_dirty) +BOOL GUIAPI UnlockSharedSurface(HSURF surf) { if (surf->shared_header == NULL) { _WRN_PRINTF("INVALID_ARG: surface handle: %p\n", surf); @@ -363,11 +363,6 @@ BOOL GUIAPI UnlockSharedSurface(HSURF surf, BOOL clear_dirty) } __mg_unlock_file_for_read(surf->fd); - - if (clear_dirty) { - surf->dirty_info->nr_dirty_rcs = 0; - } - return TRUE; failed: