/** Check whether a composite manager is running. * \return True if such a manager is running. */ static bool composite_manager_running(void) { xcb_intern_atom_reply_t *atom_r; xcb_get_selection_owner_reply_t *selection_r; char *atom_name; bool result; if(!(atom_name = xcb_atom_name_by_screen("_NET_WM_CM", globalconf.default_screen))) { warn("error getting composite manager atom"); return false; } atom_r = xcb_intern_atom_reply(globalconf.connection, xcb_intern_atom_unchecked(globalconf.connection, false, a_strlen(atom_name), atom_name), NULL); p_delete(&atom_name); if(!atom_r) return false; selection_r = xcb_get_selection_owner_reply(globalconf.connection, xcb_get_selection_owner_unchecked(globalconf.connection, atom_r->atom), NULL); p_delete(&atom_r); result = selection_r != NULL && selection_r->owner != XCB_NONE; p_delete(&selection_r); return result; }
void atoms_init(xcb_connection_t *conn) { unsigned int i; xcb_intern_atom_cookie_t cs[countof(ATOM_LIST)]; xcb_intern_atom_reply_t *r; /* Create the atom and get the reply in a XCB way (e.g. send all * the requests at the same time and then get the replies) */ for(i = 0; i < countof(ATOM_LIST); i++) cs[i] = xcb_intern_atom_unchecked(conn, false, a_strlen(ATOM_LIST[i].name), ATOM_LIST[i].name); for(i = 0; i < countof(ATOM_LIST); i++) { if(!(r = xcb_intern_atom_reply(conn, cs[i], NULL))) /* An error occured, get reply for next atom */ continue; *ATOM_LIST[i].atom = r->atom; p_delete(&r); } }
EAPI void ecore_x_atoms_get(const char **names, int num, Ecore_X_Atom *atoms) { xcb_intern_atom_cookie_t cookies[num]; int i = 0; LOGFN(__FILE__, __LINE__, __FUNCTION__); CHECK_XCB_CONN; for (i = 0; i < num; i++) { cookies[i] = xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, strlen(names[i]), names[i]); } for (i = 0; i < num; i++) { xcb_intern_atom_reply_t *reply = NULL; if (!(reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookies[i], 0))) continue; atoms[i] = reply->atom; free(reply); } }
/** Remove systray information in X. */ void systray_cleanup(void) { xcb_intern_atom_reply_t *atom_systray_r; char *atom_name; if(!(atom_name = xcb_atom_name_by_screen("_NET_SYSTEM_TRAY", globalconf.default_screen)) || !(atom_systray_r = xcb_intern_atom_reply(globalconf.connection, xcb_intern_atom_unchecked(globalconf.connection, false, a_strlen(atom_name), atom_name), NULL))) { warn("error getting systray atom"); p_delete(&atom_name); return; } p_delete(&atom_name); xcb_set_selection_owner(globalconf.connection, XCB_NONE, atom_systray_r->atom, XCB_CURRENT_TIME); p_delete(&atom_systray_r); xcb_unmap_window(globalconf.connection, globalconf.systray.window); }
/** Initialize systray information in X. */ void systray_init(void) { xcb_intern_atom_cookie_t atom_systray_q; xcb_intern_atom_reply_t *atom_systray_r; char *atom_name; xcb_screen_t *xscreen = globalconf.screen; globalconf.systray.window = xcb_generate_id(globalconf.connection); xcb_create_window(globalconf.connection, xscreen->root_depth, globalconf.systray.window, xscreen->root, -1, -1, 1, 1, 0, XCB_COPY_FROM_PARENT, xscreen->root_visual, 0, NULL); atom_name = xcb_atom_name_by_screen("_NET_SYSTEM_TRAY", globalconf.default_screen); if(!atom_name) fatal("error getting systray atom name"); atom_systray_q = xcb_intern_atom_unchecked(globalconf.connection, false, a_strlen(atom_name), atom_name); p_delete(&atom_name); atom_systray_r = xcb_intern_atom_reply(globalconf.connection, atom_systray_q, NULL); if(!atom_systray_r) fatal("error getting systray atom"); globalconf.systray.atom = atom_systray_r->atom; p_delete(&atom_systray_r); }
bool KWinKScreenHelperEffect::checkValid() { #ifdef HAVE_XCB if (QX11Info::isPlatformX11()) { QScopedPointer<xcb_list_properties_reply_t, QScopedPointerPodDeleter> propsReply(xcb_list_properties_reply(QX11Info::connection(), xcb_list_properties_unchecked(QX11Info::connection(), QX11Info::appRootWindow()), NULL)); QScopedPointer<xcb_intern_atom_reply_t, QScopedPointerPodDeleter> atomReply(xcb_intern_atom_reply(QX11Info::connection(), xcb_intern_atom_unchecked(QX11Info::connection(), false, 25, "_KDE_KWIN_KSCREEN_SUPPORT"), NULL)); if (propsReply.isNull() || atomReply.isNull()) { return false; } auto *atoms = xcb_list_properties_atoms(propsReply.data()); for (int i = 0; i < propsReply->atoms_len; ++i) { if (atoms[i] == atomReply->atom) { m_atom = atomReply->atom; return true; } } m_atom = 0; return false; } #endif return false; }
xcb_window_t QXcbNativeInterface::locateSystemTray(xcb_connection_t *conn, const QXcbScreen *screen) { if (m_sysTraySelectionAtom == XCB_ATOM_NONE) { const QByteArray net_sys_tray = QString::fromLatin1("_NET_SYSTEM_TRAY_S%1").arg(screen->screenNumber()).toLatin1(); xcb_intern_atom_cookie_t intern_c = xcb_intern_atom_unchecked(conn, true, net_sys_tray.length(), net_sys_tray); xcb_intern_atom_reply_t *intern_r = xcb_intern_atom_reply(conn, intern_c, 0); if (!intern_r) return XCB_WINDOW_NONE; m_sysTraySelectionAtom = intern_r->atom; free(intern_r); } xcb_get_selection_owner_cookie_t sel_owner_c = xcb_get_selection_owner_unchecked(conn, m_sysTraySelectionAtom); xcb_get_selection_owner_reply_t *sel_owner_r = xcb_get_selection_owner_reply(conn, sel_owner_c, 0); if (!sel_owner_r) return XCB_WINDOW_NONE; xcb_window_t selection_window = sel_owner_r->owner; free(sel_owner_r); return selection_window; }
/** Remove systray information in X. * \param phys_screen Physical screen. */ void systray_cleanup(int phys_screen) { xcb_intern_atom_reply_t *atom_systray_r; char *atom_name; if(!globalconf.screens.tab[phys_screen].systray.registered) return; globalconf.screens.tab[phys_screen].systray.registered = false; if(!(atom_name = xcb_atom_name_by_screen("_NET_SYSTEM_TRAY", phys_screen)) || !(atom_systray_r = xcb_intern_atom_reply(globalconf.connection, xcb_intern_atom_unchecked(globalconf.connection, false, a_strlen(atom_name), atom_name), NULL))) { warn("error getting systray atom"); p_delete(&atom_name); return; } p_delete(&atom_name); xcb_set_selection_owner(globalconf.connection, XCB_NONE, atom_systray_r->atom, XCB_CURRENT_TIME); p_delete(&atom_systray_r); }
/** * Sends the InternAtom request. * @param name Name of the requested atom. * @ingroup Ecore_X_Atom_Group */ EAPI void ecore_x_atom_get_prefetch(const char *name) { xcb_intern_atom_cookie_t cookie; cookie = xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, strlen(name), name); _ecore_xcb_cookie_cache(cookie.sequence); }
/** Initialize systray information in X. * \param phys_screen Physical screen. */ void systray_init(int phys_screen) { xcb_client_message_event_t ev; xcb_screen_t *xscreen = xutil_screen_get(globalconf.connection, phys_screen); char *atom_name; xcb_intern_atom_cookie_t atom_systray_q; xcb_intern_atom_reply_t *atom_systray_r; xcb_atom_t atom_systray; /* Send requests */ if(!(atom_name = xcb_atom_name_by_screen("_NET_SYSTEM_TRAY", phys_screen))) { warn("error getting systray atom"); return; } atom_systray_q = xcb_intern_atom_unchecked(globalconf.connection, false, a_strlen(atom_name), atom_name); p_delete(&atom_name); globalconf.screens[phys_screen].systray.window = xcb_generate_id(globalconf.connection); xcb_create_window(globalconf.connection, xscreen->root_depth, globalconf.screens[phys_screen].systray.window, xscreen->root, -1, -1, 1, 1, 0, XCB_COPY_FROM_PARENT, xscreen->root_visual, 0, NULL); /* Fill event */ p_clear(&ev, 1); ev.response_type = XCB_CLIENT_MESSAGE; ev.window = xscreen->root; ev.format = 32; ev.type = MANAGER; ev.data.data32[0] = XCB_CURRENT_TIME; ev.data.data32[2] = globalconf.screens[phys_screen].systray.window; ev.data.data32[3] = ev.data.data32[4] = 0; if(!(atom_systray_r = xcb_intern_atom_reply(globalconf.connection, atom_systray_q, NULL))) { warn("error getting systray atom"); return; } ev.data.data32[1] = atom_systray = atom_systray_r->atom; p_delete(&atom_systray_r); xcb_set_selection_owner(globalconf.connection, globalconf.screens[phys_screen].systray.window, atom_systray, XCB_CURRENT_TIME); xcb_send_event(globalconf.connection, false, xscreen->root, 0xFFFFFF, (char *) &ev); }
/** Register systray in X. * \param phys_screen Physical screen. */ void systray_register(int phys_screen) { xcb_client_message_event_t ev; xcb_screen_t *xscreen = xutil_screen_get(globalconf.connection, phys_screen); char *atom_name; xcb_intern_atom_cookie_t atom_systray_q; xcb_intern_atom_reply_t *atom_systray_r; xcb_atom_t atom_systray; /* Set registered even if it fails to don't try again unless forced */ if(globalconf.screens.tab[phys_screen].systray.registered) return; globalconf.screens.tab[phys_screen].systray.registered = true; /* Send requests */ if(!(atom_name = xcb_atom_name_by_screen("_NET_SYSTEM_TRAY", phys_screen))) { warn("error getting systray atom"); return; } atom_systray_q = xcb_intern_atom_unchecked(globalconf.connection, false, a_strlen(atom_name), atom_name); p_delete(&atom_name); /* Fill event */ p_clear(&ev, 1); ev.response_type = XCB_CLIENT_MESSAGE; ev.window = xscreen->root; ev.format = 32; ev.type = MANAGER; ev.data.data32[0] = XCB_CURRENT_TIME; ev.data.data32[2] = globalconf.screens.tab[phys_screen].systray.window; ev.data.data32[3] = ev.data.data32[4] = 0; if(!(atom_systray_r = xcb_intern_atom_reply(globalconf.connection, atom_systray_q, NULL))) { warn("error getting systray atom"); return; } ev.data.data32[1] = atom_systray = atom_systray_r->atom; p_delete(&atom_systray_r); xcb_set_selection_owner(globalconf.connection, globalconf.screens.tab[phys_screen].systray.window, atom_systray, XCB_CURRENT_TIME); xcb_send_event(globalconf.connection, false, xscreen->root, 0xFFFFFF, (char *) &ev); }
/** Send InternAtom requests to get the Atoms X identifiers * * @return The EWMH InternAtom cookies */ xcb_intern_atom_cookie_t * atoms_init(void) { for(int atom_n = 0; atom_n < atoms_list_len; atom_n++) atoms_list[atom_n].cookie = xcb_intern_atom_unchecked(globalconf.connection, false, atoms_list[atom_n].name_len, atoms_list[atom_n].name); return xcb_ewmh_init_atoms(globalconf.connection, &globalconf.ewmh); }
static xcb_atom_t towel_window_get_atom(towel_window_t *win, const char *atom) { xcb_intern_atom_cookie_t cookie; xcb_intern_atom_reply_t *reply; xcb_atom_t ret; cookie = xcb_intern_atom_unchecked(win->conn, 0, strlen(atom), atom); reply = xcb_intern_atom_reply(win->conn, cookie, NULL); ret = reply->atom; free(reply); return ret; }
// === EmbedWindow() === uint LXCB::EmbedWindow(WId win, WId container){ if(DEBUG){ qDebug() << "XCB: EmbedWindow()"; } //This returns the damage control ID number (or 0 for a failure) if(win==0 || container==0){ return 0; } //qDebug() << "Embed Window:" << win << container; //Initialize any atoms that will be needed xcb_intern_atom_cookie_t ecookie = xcb_intern_atom_unchecked(QX11Info::connection(), 0, 7, "_XEMBED"); xcb_intern_atom_reply_t *ereply = xcb_intern_atom_reply(QX11Info::connection(), ecookie, NULL); if(ereply==0){ return 0; } //unable to initialize the atom xcb_atom_t emb = ereply->atom; free(ereply); //done with this structure //Reparent the window into the container xcb_reparent_window(QX11Info::connection(), win, container, 0, 0); xcb_map_window(QX11Info::connection(), win); //Now send the embed event to the app //qDebug() << " - send _XEMBED event"; xcb_client_message_event_t event; event.response_type = XCB_CLIENT_MESSAGE; event.format = 32; event.window = win; event.type = emb; //_XEMBED event.data.data32[0] = XCB_TIME_CURRENT_TIME; //CurrentTime; event.data.data32[1] = 0; //XEMBED_EMBEDDED_NOTIFY event.data.data32[2] = 0; event.data.data32[3] = container; //WID of the container event.data.data32[4] = 0; xcb_send_event(QX11Info::connection(), 0, win, XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *) &event); //Now setup any redirects and return //qDebug() << " - select Input"; //XSelectInput(disp, win, StructureNotifyMask); //Notify of structure changes //uint32_t val[] = {XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY}; //xcb_change_window_attributes(QX11Info::connection(), win, XCB_CW_EVENT_MASK, val); this->SelectInput(win); //qDebug() << " - Composite Redirect"; xcb_composite_redirect_window(QX11Info::connection(), win, XCB_COMPOSITE_REDIRECT_MANUAL); //Now map the window (will be a transparent child of the container) xcb_map_window(QX11Info::connection(), win); //Now create/register the damage handler xcb_damage_damage_t dmgID = xcb_generate_id(QX11Info::connection()); //This is a typedef for a 32-bit unsigned integer xcb_damage_create(QX11Info::connection(), dmgID, win, XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES); //qDebug() << " - Done"; return ( (uint) dmgID ); }
/** Register a new xproperty. * \param L The Lua VM state. * \return The number of elements pushed on stack. * \luastack * \lparam The name of the X11 property * \lparam One of "string", "number" or "boolean" */ int luaA_register_xproperty(lua_State *L) { const char *name; struct xproperty property; struct xproperty *found; const char *const args[] = { "string", "number", "boolean" }; xcb_intern_atom_reply_t *atom_r; int type; name = luaL_checkstring(L, 1); type = luaL_checkoption(L, 2, NULL, args); if (type == 0) property.type = PROP_STRING; else if (type == 1) property.type = PROP_NUMBER; else property.type = PROP_BOOLEAN; atom_r = xcb_intern_atom_reply(globalconf.connection, xcb_intern_atom_unchecked(globalconf.connection, false, a_strlen(name), name), NULL); if(!atom_r) return 0; property.atom = atom_r->atom; p_delete(&atom_r); found = xproperty_array_lookup(&globalconf.xproperties, &property); if(found) { /* Property already registered */ if(found->type != property.type) return luaL_error(L, "xproperty '%s' already registered with different type", name); } else { buffer_t buf; buffer_inita(&buf, a_strlen(name) + a_strlen("xproperty::") + 1); buffer_addf(&buf, "xproperty::%s", name); property.name = a_strdup(name); xproperty_array_insert(&globalconf.xproperties, property); signal_add(&window_class.signals, buf.s); signal_add(&global_signals, buf.s); buffer_wipe(&buf); } return 0; }
static int _e_alert_atom_get(const char *name) { xcb_intern_atom_cookie_t cookie; xcb_intern_atom_reply_t *reply; int a; cookie = xcb_intern_atom_unchecked(conn, 0, strlen(name), name); reply = xcb_intern_atom_reply(conn, cookie, NULL); if (!reply) return XCB_ATOM_NONE; a = reply->atom; free(reply); return a; }
void _ecore_xcb_atoms_init(void) { int i = 0, num = 0; LOGFN(__FILE__, __LINE__, __FUNCTION__); CHECK_XCB_CONN; num = (sizeof(atom_items) / sizeof(Atom_Item)); for (i = 0; i < num; i++) { cookies[i] = xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, strlen(atom_items[i].name), atom_items[i].name); } }
/** * Retrieves the atom value associated to a name. * * @param name Unused. * @return Associated atom value. * * Retrieves the atom value associated to a name. The reply is the * returned value of the function ecore_xcb_intern_atom_reply(). If * @p reply is @c NULL, the NULL atom is returned. Otherwise, the atom * associated to the name is returned. * * @ingroup Ecore_X_Atom_Group */ EAPI Ecore_X_Atom ecore_x_atom_get(const char *name) { xcb_intern_atom_cookie_t cookie; xcb_intern_atom_reply_t *reply; Ecore_X_Atom a; LOGFN(__FILE__, __LINE__, __FUNCTION__); CHECK_XCB_CONN; cookie = xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, strlen(name), name); reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookie, NULL); if (!reply) return XCB_ATOM_NONE; a = reply->atom; free(reply); return a; }
static void do_name(xcb_connection_t *c, const char *format, char *name) { xcb_intern_atom_reply_t *a = xcb_intern_atom_reply(c, xcb_intern_atom_unchecked(c, 1, strlen(name), name), NULL); if (a && a->atom != XCB_NONE) { printf (format, (unsigned long) a->atom, name); putchar ('\n'); } else { fprintf (stderr, "%s: no atom named \"%s\" on server \"%s\"\n", ProgramName, name, DisplayString); } if (a) free(a); }
int main(int argc,char**argv){ xcb_connection_t*d=xcb_connect(0,0); int32_t*x,*y,*tx=0,mx,my,rt=xcb_setup_roots_iterator(xcb_get_setup(d)).data->root,cs[255],*cz=cs+1; uint8_t mz,mZ; xcb_change_window_attributes(d,rt,XCB_CW_EVENT_MASK,&cwa); xcb_grab_key(d,1,rt,0,64,XCB_GRAB_MODE_ASYNC,XCB_GRAB_MODE_ASYNC); xcb_grab_key(d,1,rt,8,XCB_GRAB_ANY,XCB_GRAB_MODE_ASYNC,XCB_GRAB_MODE_ASYNC); xcb_grab_button(d,1,rt,XCB_EVENT_MASK_BUTTON_PRESS,XCB_GRAB_MODE_ASYNC,XCB_GRAB_MODE_ASYNC,XCB_NONE,XCB_NONE,XCB_GRAB_ANY,8); #ifdef COMPOSITE xcb_composite_redirect_subwindows(d,rt,XCB_COMPOSITE_REDIRECT_AUTOMATIC); #endif xcb_generic_event_t*e=0; main:xcb_flush(d); waitpid(-1,0,WNOHANG); noflush:x=y=cz-1; again:free(e); switch((e=xcb_wait_for_event(d))->response_type&127){ case XCB_BUTTON_PRESS: for(;x>cs;x--) if(*x==((xcb_button_press_event_t*)e)->child){ if(((xcb_key_press_event_t*)e)->detail==2)goto pocus; case XCB_KEY_PRESS: mz=128|((xcb_key_press_event_t*)e)->detail; my=((xcb_key_press_event_t*)e)->state; goto*(cz==cs+1?&&kcode:&&stack); } goto noflush; case XCB_KEY_RELEASE: if(((xcb_key_press_event_t*)e)->detail!=64||!tx)default:goto again; xt:x=tx; tx=0; goto stack; case XCB_CONFIGURE_REQUEST:{ void*p=buf; for(mz=0;mz<5;mz++) if(((xcb_configure_request_event_t*)e)->value_mask&1<<mz){*(uint32_t*)p=*(int16_t*)(((void*)e)+16+mz*2);p+=4;} if(((xcb_configure_request_event_t*)e)->value_mask&XCB_CONFIG_WINDOW_SIBLING){*(uint32_t*)p=((xcb_configure_request_event_t*)e)->sibling;p+=4;} if(mz=((xcb_configure_request_event_t*)e)->value_mask&XCB_CONFIG_WINDOW_STACK_MODE)*(uint32_t*)p=((xcb_configure_request_event_t*)e)->stack_mode; xcb_configure_window(d,((xcb_configure_request_event_t*)e)->window,((xcb_configure_request_event_t*)e)->value_mask,buf); if(mz){ p=xcb_query_tree_reply(d,xcb_query_tree_unchecked(d,rt),0); int32_t*cl=p+32+((xcb_query_tree_reply_t*)p)->children_len*4; for(y=p+32;y<cl;y++){ for(x=cs+1;x<cz;x++) if(*x==*y)goto nono; *y=0; nono:; } x=cs; for(y=p+32;y<cl;y++) if(*y)*++x=*y; free(p); goto pocus; }else goto main;} case XCB_MAP_REQUEST:{ void*p=xcb_get_window_attributes_reply(d,xcb_get_window_attributes_unchecked(d,((xcb_map_request_event_t*)e)->window),0); if(((xcb_get_window_attributes_reply_t*)p)->override_redirect){ free(p); goto pocus; } free(p); for(;x>cs;x--) if(*x==((xcb_map_request_event_t*)e)->window)goto noflush; xcb_map_window(d,*cz++=((xcb_map_request_event_t*)e)->window); goto hocus;} case XCB_MOTION_NOTIFY: *buf=mZ&&((xcb_motion_notify_event_t*)e)->root_x<=mx?:((xcb_motion_notify_event_t*)e)->root_x-mx; buf[1]=mZ&&((xcb_motion_notify_event_t*)e)->root_y<=my?:((xcb_motion_notify_event_t*)e)->root_y-my; xcb_configure_window(d,*x,mZ?XCB_CONFIG_WINDOW_WIDTH|XCB_CONFIG_WINDOW_HEIGHT:XCB_CONFIG_WINDOW_X|XCB_CONFIG_WINDOW_Y,buf); goto main; case XCB_BUTTON_RELEASE: xcb_ungrab_pointer(d,XCB_CURRENT_TIME); goto main; case XCB_UNMAP_NOTIFY:unmap:goto*(x==cs?&&noflush:*x==((xcb_unmap_notify_event_t*)e)->window&&--cz>cs+1?&&stack:(x--,&&unmap)); } stack:mx=*x; for(;x!=y;x+=x<y?:-1)*x=x[x<y?:-1]; *x=mx; hocus:x=cz-1; xcb_configure_window(d,*x,XCB_CONFIG_WINDOW_STACK_MODE,di); pocus:xcb_set_input_focus(d,XCB_INPUT_FOCUS_POINTER_ROOT,*x,XCB_CURRENT_TIME); if(!(mz&128))goto main; kcode:switch(mz&=127){ void*p; case 1:case 3: p=xcb_grab_pointer_reply(d,xcb_grab_pointer_unchecked(d,0,rt,XCB_EVENT_MASK_BUTTON_RELEASE|XCB_EVENT_MASK_POINTER_MOTION,XCB_GRAB_MODE_ASYNC,XCB_GRAB_MODE_ASYNC,XCB_NONE,XCB_NONE,XCB_CURRENT_TIME),0); if(((xcb_grab_pointer_reply_t*)p)->status!=XCB_GRAB_STATUS_SUCCESS){ free(p); goto noflush; } free(p); p=xcb_get_geometry_reply(d,xcb_get_geometry_unchecked(d,*y),0); mx=((xcb_get_geometry_reply_t*)p)->x; my=((xcb_get_geometry_reply_t*)p)->y; free(p); if(mZ=mz==1){ p=xcb_query_pointer_reply(d,xcb_query_pointer_unchecked(d,rt),0); mx=((xcb_query_pointer_reply_t*)p)->root_x-mx; my=((xcb_query_pointer_reply_t*)p)->root_y-my; free(p); } goto noflush; case 23:case 49: if(cz-cs<3)goto main; y=tx; tx=mz==23?(y!=cs+1?(y?:x)-1:x):!y||y==x?cs+1:y+1; if(y&&y<cz-1){ *buf=y[mz==23?:-1]; buf[1]=mz==23; xcb_configure_window(d,*y,XCB_CONFIG_WINDOW_SIBLING|XCB_CONFIG_WINDOW_STACK_MODE,buf); } xcb_configure_window(d,*tx,XCB_CONFIG_WINDOW_STACK_MODE,di); goto main; case 32:return 0; case 44: if(cz>cs+1)xcb_configure_window(d,*y,XCB_CONFIG_WINDOW_X|XCB_CONFIG_WINDOW_Y|XCB_CONFIG_WINDOW_WIDTH|XCB_CONFIG_WINDOW_HEIGHT,di); goto main; case 46: if(cz==cs+1)goto main; if(tx)goto*(mz|=128,&&xt); {xcb_intern_atom_cookie_t c1=xcb_intern_atom_unchecked(d,0,12,"WM_PROTOCOLS"),c2=xcb_intern_atom_unchecked(d,0,16,"WM_DELETE_WINDOW"); p=xcb_intern_atom_reply(d,c1,0); mx=((xcb_intern_atom_reply_t*)p)->atom; free(p); p=xcb_intern_atom_reply(d,c2,0);} my=((xcb_intern_atom_reply_t*)p)->atom; free(p); p=xcb_get_property_reply(d,xcb_get_property_unchecked(d,0,*y,mx,XCB_ATOM_ATOM,0,-1),0); xcb_send_event(d,0,*y,XCB_EVENT_MASK_NO_EVENT,(void*)(xcb_client_message_event_t[]){{.response_type=XCB_CLIENT_MESSAGE,.window=*y,.type=mx,.format=32,.data.data32={my,XCB_CURRENT_TIME}}});
void init_tabletwm() { memset(&key_win, 0, sizeof(key_win)); memset(&shutdown_win, 0, sizeof(shutdown_win)); xcb_void_cookie_t void_cookie; xcb_intern_atom_cookie_t atom_cookie[TWM_ATOM_LAST_VALUE]; uint32_t v[] = {XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_PROPERTY_CHANGE}; int i; char *a_atoms[TWM_ATOM_LAST_VALUE] = { "WM_SIZE_HINTS", "WM_NORMAL_HINTS", "WM_PROTOCOLS", "WM_DELETE_WINDOW", "WM_TRANSIENT_FOR", "_NET_SUPPORTING_WM_CHECK", "_NET_WM_NAME", "_NET_SUPPORTED", "_NET_WM_WINDOW_TYPE", "_NET_WM_WINDOW_TYPE_DESKTOP", "_NET_WM_WINDOW_TYPE_DOCK", "_NET_WM_WINDOW_TYPE_TOOLBAR", "_NET_WM_WINDOW_TYPE_MENU", "_NET_WM_WINDOW_TYPE_UTILITY", "_NET_WM_WINDOW_TYPE_SPLASH", "_NET_WM_WINDOW_TYPE_DIALOG", "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", "_NET_WM_WINDOW_TYPE_POPUP_MENU", "_NET_WM_WINDOW_TYPE_TOOLTIP", "_NET_WM_WINDOW_TYPE_NOTIFICATION", "_NET_WM_WINDOW_TYPE_COMBO", "_NET_WM_WINDOW_TYPE_DND", "_NET_WM_WINDOW_TYPE_NORMAL", "_NET_WM_ALLOWED_ACTIONS", "_NET_WM_ACTION_MOVE", "_NET_WM_ACTION_RESIZE", "_NET_WM_ACTION_MINIMIZE", "_NET_WM_ACTION_SHADE", "_NET_WM_ACTION_STICK", "_NET_WM_ACTION_MAXIMIZE_HORZ", "_NET_WM_ACTION_MAXIMIZE_VERT", "_NET_WM_ACTION_FULLSCREEN", "_NET_WM_ACTION_CHANGE_DESKTOP", "_NET_WM_ACTION_CLOSE", "_NET_WM_ACTION_ABOVE", "_NET_WM_ACTION_BELOW", "WM_CLASS", "WM_STATE", "_NET_ACTIVE_WINDOW", "WM_HINTS", "_XKB_RULES_NAMES", }; init_load_config(); wincache_init(); conn = xcb_connect(0, 0); assert(conn); scr = xcb_setup_roots_iterator(xcb_get_setup(conn)).data; width = scr->width_in_pixels; height = scr->height_in_pixels; // reserve the bottom part for the 1pixel-height, collapsed menu bar xcb_change_window_attributes(conn, scr->root, XCB_CW_EVENT_MASK, v); xcb_depth_iterator_t depth_iter; xcb_visualid_t root_visual = { 0 }; visual_type = NULL; for (depth_iter = xcb_screen_allowed_depths_iterator (scr); depth_iter.rem; xcb_depth_next (&depth_iter)) { xcb_visualtype_iterator_t visual_iter; visual_iter = xcb_depth_visuals_iterator (depth_iter.data); for (; visual_iter.rem; xcb_visualtype_next (&visual_iter)) { if (scr->root_visual == visual_iter.data->visual_id) { visual_type = visual_iter.data; break; } } } /* get atoms */ for(i=0; i < TWM_ATOM_LAST_VALUE; i++) { atom_cookie[i] = xcb_intern_atom_unchecked(conn, 0, strlen(a_atoms[i]), a_atoms[i]); }; xcb_flush(conn); xcb_intern_atom_reply_t *atom_reply; for(i=0; i < TWM_ATOM_LAST_VALUE; i++) { atom_reply = xcb_intern_atom_reply(conn, atom_cookie[i], 0), atoms[i] = atom_reply->atom; free(atom_reply); }; xcb_change_property(conn, XCB_PROP_MODE_REPLACE, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM_WM_DELETE_WINDOW]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_WINDOW_TYPE]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_WINDOW_TYPE_DESKTOP]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_WINDOW_TYPE_DOCK]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_WINDOW_TYPE_TOOLBAR]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_WINDOW_TYPE_MENU]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED] , XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_WINDOW_TYPE_UTILITY]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_WINDOW_TYPE_SPLASH]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_WINDOW_TYPE_DIALOG]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_WINDOW_TYPE_DROPDOWN_MENU]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_WINDOW_TYPE_POPUP_MENU]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_WINDOW_TYPE_TOOLTIP]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_WINDOW_TYPE_NOTIFICATION]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_WINDOW_TYPE_COMBO]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_WINDOW_TYPE_DND]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_WINDOW_TYPE_NORMAL]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_ALLOWED_ACTIONS]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_ACTION_MOVE]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_ACTION_RESIZE]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_ACTION_MINIMIZE]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_ACTION_SHADE]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_ACTION_STICK]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_ACTION_MAXIMIZE_HORZ]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_ACTION_MAXIMIZE_VERT]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_ACTION_FULLSCREEN]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_ACTION_CHANGE_DESKTOP]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_ACTION_CLOSE]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_ACTION_ABOVE]); xcb_change_property(conn, XCB_PROP_MODE_APPEND, scr->root, atoms[TWM_ATOM__NET_SUPPORTED], XCB_ATOM_ATOM, 32, 1, &atoms[TWM_ATOM__NET_WM_ACTION_BELOW]); // This window contains the menu and the virtual keyboard (when showed) // It is also used to ensure that the window manager is recognized as an Extended Window Manager Hints WM // By default it occupies one pixel at the bottom of the screen, to allow to detect when the mouse is moved to the bottom xcb_get_property_cookie_t kbd_info_cookie; xcb_get_property_reply_t *kbd_info; kbd_info_cookie = xcb_get_property(conn, 0, scr->root, atoms[TWM__XKB_RULES_NAMES], XCB_ATOM_STRING, 0, 1024); key_win.window = xcb_generate_id(conn); uint32_t values[1] = {XCB_EVENT_MASK_EXPOSURE|XCB_EVENT_MASK_BUTTON_RELEASE|XCB_EVENT_MASK_BUTTON_PRESS|XCB_EVENT_MASK_ENTER_WINDOW|XCB_EVENT_MASK_LEAVE_WINDOW}; void_cookie=xcb_create_window_checked (conn, XCB_COPY_FROM_PARENT, key_win.window, scr->root, 0, height-1, width, 1, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, scr->root_visual, XCB_CW_EVENT_MASK, values); xcb_flush(conn); kbd_info = xcb_get_property_reply(conn, kbd_info_cookie, 0); if (kbd_info!=NULL) { if (kbd_info->length>0) { char *p=((char *)(xcb_get_property_value(kbd_info))); int counter=0; int len, max; max=xcb_get_property_value_length(kbd_info); char *end=p+max; do { len = strnlen(p, max); if (*p!=0) { xkb_names[counter++] = strdup(p); } p+=len+1; max-=len+1; } while ((p < end) && (counter < 5)); } free(kbd_info); } if (xcb_request_check(conn, void_cookie)) { printf("Can't create the fake window\n"); } else { menuwin_init(); } shutdown_init(); }