static LRESULT CALLBACK cbt_hook_proc(int code, WPARAM wparam, LPARAM lparam) { if (!g_wm_seamless_focus) goto end; if (code < 0) goto end; switch (code) { case HCBT_MINMAX: { int show, state, blocked; HWND hwnd, blocked_hwnd; unsigned int serial; LONG style; WaitForSingleObject(g_mutex, INFINITE); blocked_hwnd = long_to_hwnd(g_shdata->blocked_state_hwnd); serial = g_shdata->blocked_state_serial; blocked = g_shdata->blocked_state; ReleaseMutex(g_mutex); hwnd = (HWND) wparam; style = GetWindowLong(hwnd, GWL_STYLE); if (!(style & WS_VISIBLE)) break; show = LOWORD(lparam); if ((show == SW_NORMAL) || (show == SW_SHOWNORMAL) || (show == SW_RESTORE)) state = 0; else if ((show == SW_MINIMIZE) || (show == SW_SHOWMINIMIZED)) state = 1; else if ((show == SW_MAXIMIZE) || (show == SW_SHOWMAXIMIZED)) state = 2; else { debug("Unexpected show: %d", show); break; } if ((blocked_hwnd == hwnd) && (blocked == state)) vchannel_write("ACK", "%u", serial); else vchannel_write("STATE", "0x%08lx,0x%08x,0x%08x", hwnd, state, 0); break; } default: break; } end: return CallNextHookEx(g_cbt_hook, code, wparam, lparam); }
static void update_position(HWND hwnd) { RECT rect, blocked; HWND blocked_hwnd; unsigned int serial; WaitForSingleObject(g_mutex, INFINITE); blocked_hwnd = long_to_hwnd(g_shdata->block_move_hwnd); serial = g_shdata->block_move_serial; memcpy(&blocked, &g_shdata->block_move, sizeof(RECT)); ReleaseMutex(g_mutex); vchannel_block(); if (!GetWindowRect(hwnd, &rect)) { debug("GetWindowRect failed!"); goto end; } if ((hwnd == blocked_hwnd) && (rect.left == blocked.left) && (rect.top == blocked.top) && (rect.right == blocked.right) && (rect.bottom == blocked.bottom)) goto end; vchannel_write("POSITION", "0x%08lx,%d,%d,%d,%d,0x%08x", hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0); end: vchannel_unblock(); }
static void update_zorder(HWND hwnd) { HWND behind; HWND block_hwnd, block_behind; unsigned int serial; WaitForSingleObject(g_mutex, INFINITE); serial = g_shdata->blocked_zchange_serial; block_hwnd = long_to_hwnd(g_shdata->blocked_zchange[0]); block_behind = long_to_hwnd(g_shdata->blocked_zchange[1]); ReleaseMutex(g_mutex); vchannel_block(); behind = GetNextWindow(hwnd, GW_HWNDPREV); while (behind) { LONG style; style = GetWindowLong(behind, GWL_STYLE); if ((!(style & WS_CHILD) || (style & WS_POPUP)) && (style & WS_VISIBLE)) break; behind = GetNextWindow(behind, GW_HWNDPREV); } if ((hwnd == block_hwnd) && (behind == block_behind)) vchannel_write("ACK", "%u", serial); else { int flags = 0; LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); // handle always on top if (exstyle & WS_EX_TOPMOST) flags |= SEAMLESS_CREATE_TOPMOST; vchannel_write("ZCHANGE", "0x%08lx,0x%08lx,0x%08x", hwnd, behind, flags); } vchannel_unblock(); }
static void process_cmds(void) { char line[VCHANNEL_MAX_LINE]; int size; char *p, *tok1, *tok2, *tok3, *tok4, *tok5, *tok6, *tok7, *tok8; while ((size = g_vchannel_read_fn(line, sizeof(line))) >= 0) { p = unescape(line); tok1 = get_token(&p); tok2 = get_token(&p); tok3 = get_token(&p); tok4 = get_token(&p); tok5 = get_token(&p); tok6 = get_token(&p); tok7 = get_token(&p); tok8 = get_token(&p); if (strcmp(tok1, "SYNC") == 0) do_sync(); else if (strcmp(tok1, "STATE") == 0) do_state(strtoul(tok2, NULL, 0), long_to_hwnd(strtoul(tok3, NULL, 0)), strtol(tok4, NULL, 0)); else if (strcmp(tok1, "POSITION") == 0) do_position(strtoul(tok2, NULL, 0), long_to_hwnd(strtoul(tok3, NULL, 0)), strtol(tok4, NULL, 0), strtol(tok5, NULL, 0), strtol(tok6, NULL, 0), strtol(tok7, NULL, 0)); else if (strcmp(tok1, "ZCHANGE") == 0) do_zchange(strtoul(tok2, NULL, 0), long_to_hwnd(strtoul(tok3, NULL, 0)), long_to_hwnd(strtoul(tok4, NULL, 0))); else if (strcmp(tok1, "FOCUS") == 0) do_focus(strtoul(tok2, NULL, 0), long_to_hwnd(strtoul(tok3, NULL, 0))); else if (strcmp(tok1, "DESTROY") == 0) do_destroy(long_to_hwnd(strtoul(tok3, NULL, 0))); else if (strcmp(tok1, "SPAWN") == 0) do_spawn(strtoul(tok2, NULL, 0), tok3); else if (strcmp(tok1, "PERSISTENT") == 0) do_persistent(strtoul(tok2, NULL, 0), strtol(tok3, NULL, 0)); free(p); } }