Move private functions from compton.h to compton.c
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
332a873729
commit
796b0e0448
223
src/compton.c
223
src/compton.c
|
@ -118,6 +118,12 @@ update_ewmh_active_win(session_t *ps);
|
|||
static void
|
||||
draw_callback(EV_P_ ev_idle *w, int revents);
|
||||
|
||||
static void
|
||||
render(session_t *ps, int x, int y, int dx, int dy, int wid, int hei,
|
||||
double opacity, bool argb, bool neg,
|
||||
xcb_render_picture_t pict, glx_texture_t *ptex,
|
||||
const region_t *reg_paint, const glx_prog_main_t *pprogram);
|
||||
|
||||
typedef struct ev_session_timer {
|
||||
ev_timer w;
|
||||
session_t *ps;
|
||||
|
@ -216,6 +222,103 @@ static const char *background_props_str[] = {
|
|||
/// have a pointer to current session passed in.
|
||||
session_t *ps_g = NULL;
|
||||
|
||||
/**
|
||||
* Free Xinerama screen info.
|
||||
*
|
||||
* XXX consider moving to x.c
|
||||
*/
|
||||
static inline void
|
||||
free_xinerama_info(session_t *ps) {
|
||||
#ifdef CONFIG_XINERAMA
|
||||
if (ps->xinerama_scr_regs) {
|
||||
for (int i = 0; i < ps->xinerama_nscrs; ++i)
|
||||
pixman_region32_fini(&ps->xinerama_scr_regs[i]);
|
||||
free(ps->xinerama_scr_regs);
|
||||
}
|
||||
cxfree(ps->xinerama_scrs);
|
||||
ps->xinerama_scrs = NULL;
|
||||
ps->xinerama_nscrs = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy all resources in a <code>struct _win</code>.
|
||||
*/
|
||||
static inline void
|
||||
free_win_res(session_t *ps, win *w) {
|
||||
free_win_res_glx(ps, w);
|
||||
free_paint(ps, &w->paint);
|
||||
pixman_region32_fini(&w->bounding_shape);
|
||||
free_paint(ps, &w->shadow_paint);
|
||||
// BadDamage may be thrown if the window is destroyed
|
||||
set_ignore_cookie(ps,
|
||||
xcb_damage_destroy(ps->c, w->damage));
|
||||
rc_region_unref(&w->reg_ignore);
|
||||
free(w->name);
|
||||
free(w->class_instance);
|
||||
free(w->class_general);
|
||||
free(w->role);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free root tile related things.
|
||||
*/
|
||||
static inline void
|
||||
free_root_tile(session_t *ps) {
|
||||
free_picture(ps, &ps->root_tile_paint.pict);
|
||||
free_texture(ps, &ps->root_tile_paint.ptex);
|
||||
if (ps->root_tile_fill) {
|
||||
xcb_free_pixmap(ps->c, ps->root_tile_paint.pixmap);
|
||||
ps->root_tile_paint.pixmap = XCB_NONE;
|
||||
}
|
||||
ps->root_tile_paint.pixmap = None;
|
||||
ps->root_tile_fill = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current system clock in milliseconds.
|
||||
*/
|
||||
static inline time_ms_t
|
||||
get_time_ms(void) {
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
return tv.tv_sec % SEC_WRAP * 1000 + tv.tv_usec / 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize a region.
|
||||
*/
|
||||
static inline void
|
||||
resize_region(session_t *ps, region_t *region, short mod) {
|
||||
if (!mod || !region) return;
|
||||
// Loop through all rectangles
|
||||
int nrects;
|
||||
int nnewrects = 0;
|
||||
pixman_box32_t *rects = pixman_region32_rectangles(region, &nrects);
|
||||
pixman_box32_t *newrects = calloc(nrects, sizeof *newrects);
|
||||
for (int i = 0; i < nrects; i++) {
|
||||
int x1 = max_i(rects[i].x1 - mod, 0);
|
||||
int y1 = max_i(rects[i].y1 - mod, 0);
|
||||
int x2 = min_i(rects[i].x2 + mod, ps->root_width);
|
||||
int y2 = min_i(rects[i].y2 + mod, ps->root_height);
|
||||
int wid = x2 - x1;
|
||||
int hei = y2 - y1;
|
||||
if (wid <= 0 || hei <= 0)
|
||||
continue;
|
||||
newrects[nnewrects] = (pixman_box32_t) {
|
||||
.x1 = x1, .x2 = x2, .y1 = y1, .y2 = y2
|
||||
};
|
||||
++nnewrects;
|
||||
}
|
||||
|
||||
pixman_region32_fini(region);
|
||||
pixman_region32_init_rects(region, newrects, nnewrects);
|
||||
|
||||
free(newrects);
|
||||
}
|
||||
|
||||
static inline int
|
||||
get_alpha_step(session_t *ps, opacity_t o) {
|
||||
double d = ((double) o) / OPAQUE;
|
||||
|
@ -240,6 +343,86 @@ set_tgt_clip(session_t *ps, region_t *reg) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Xinerama screen a window is on.
|
||||
*
|
||||
* Return an index >= 0, or -1 if not found.
|
||||
*
|
||||
* XXX move to x.c
|
||||
*/
|
||||
static inline void
|
||||
cxinerama_win_upd_scr(session_t *ps, win *w) {
|
||||
#ifdef CONFIG_XINERAMA
|
||||
w->xinerama_scr = -1;
|
||||
|
||||
if (!ps->xinerama_scrs)
|
||||
return;
|
||||
|
||||
xcb_xinerama_screen_info_t *scrs = xcb_xinerama_query_screens_screen_info(ps->xinerama_scrs);
|
||||
int length = xcb_xinerama_query_screens_screen_info_length(ps->xinerama_scrs);
|
||||
for (int i = 0; i < length; i++) {
|
||||
xcb_xinerama_screen_info_t *s = &scrs[i];
|
||||
if (s->x_org <= w->g.x && s->y_org <= w->g.y
|
||||
&& s->x_org + s->width >= w->g.x + w->widthb
|
||||
&& s->y_org + s->height >= w->g.y + w->heightb) {
|
||||
w->xinerama_scr = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// XXX Move to x.c
|
||||
static void
|
||||
cxinerama_upd_scrs(session_t *ps) {
|
||||
#ifdef CONFIG_XINERAMA
|
||||
// XXX Consider deprecating Xinerama, switch to RandR when necessary
|
||||
free_xinerama_info(ps);
|
||||
|
||||
if (!ps->o.xinerama_shadow_crop || !ps->xinerama_exists) return;
|
||||
|
||||
xcb_xinerama_is_active_reply_t *active =
|
||||
xcb_xinerama_is_active_reply(ps->c,
|
||||
xcb_xinerama_is_active(ps->c), NULL);
|
||||
if (!active || !active->state) {
|
||||
free(active);
|
||||
return;
|
||||
}
|
||||
free(active);
|
||||
|
||||
ps->xinerama_scrs = xcb_xinerama_query_screens_reply(ps->c,
|
||||
xcb_xinerama_query_screens(ps->c), NULL);
|
||||
if (!ps->xinerama_scrs)
|
||||
return;
|
||||
|
||||
xcb_xinerama_screen_info_t *scrs = xcb_xinerama_query_screens_screen_info(ps->xinerama_scrs);
|
||||
ps->xinerama_nscrs = xcb_xinerama_query_screens_screen_info_length(ps->xinerama_scrs);
|
||||
|
||||
ps->xinerama_scr_regs = allocchk(malloc(sizeof(region_t)
|
||||
* ps->xinerama_nscrs));
|
||||
for (int i = 0; i < ps->xinerama_nscrs; ++i) {
|
||||
const xcb_xinerama_screen_info_t * const s = &scrs[i];
|
||||
pixman_region32_init_rect(&ps->xinerama_scr_regs[i], s->x_org, s->y_org, s->width, s->height);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Find matched window.
|
||||
*
|
||||
* XXX move to win.c
|
||||
*/
|
||||
static inline win *
|
||||
find_win_all(session_t *ps, const Window wid) {
|
||||
if (!wid || PointerRoot == wid || wid == ps->root || wid == ps->overlay)
|
||||
return NULL;
|
||||
|
||||
win *w = find_win(ps, wid);
|
||||
if (!w) w = find_toplevel(ps, wid);
|
||||
if (!w) w = find_toplevel2(ps, wid);
|
||||
return w;
|
||||
}
|
||||
|
||||
void queue_redraw(session_t *ps) {
|
||||
// If --benchmark is used, redraw is always queued
|
||||
if (!ps->redraw_needed && !ps->o.benchmark)
|
||||
|
@ -1401,7 +1584,7 @@ win_blur_background(session_t *ps, win *w, xcb_render_picture_t tgt_buffer,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
render(session_t *ps, int x, int y, int dx, int dy, int wid, int hei,
|
||||
double opacity, bool argb, bool neg,
|
||||
xcb_render_picture_t pict, glx_texture_t *ptex,
|
||||
|
@ -2065,7 +2248,7 @@ finish_unmap_win(session_t *ps, win **_w) {
|
|||
/* damage region */
|
||||
add_damage_from_win(ps, w);
|
||||
|
||||
free_wpaint(ps, w);
|
||||
free_paint(ps, &w->paint);
|
||||
free_paint(ps, &w->shadow_paint);
|
||||
}
|
||||
|
||||
|
@ -4607,7 +4790,7 @@ redir_stop(session_t *ps) {
|
|||
// If we don't destroy them here, looks like the resources are just
|
||||
// kept inaccessible somehow
|
||||
for (win *w = ps->list; w; w = w->next)
|
||||
free_wpaint(ps, w);
|
||||
free_paint(ps, &w->paint);
|
||||
|
||||
xcb_composite_unredirect_subwindows(ps->c, ps->root, XCB_COMPOSITE_REDIRECT_MANUAL);
|
||||
// Unmap overlay window
|
||||
|
@ -4775,40 +4958,6 @@ x_event_callback(EV_P_ ev_io *w, int revents) {
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cxinerama_upd_scrs(session_t *ps) {
|
||||
#ifdef CONFIG_XINERAMA
|
||||
// XXX Consider deprecating Xinerama, switch to RandR when necessary
|
||||
free_xinerama_info(ps);
|
||||
|
||||
if (!ps->o.xinerama_shadow_crop || !ps->xinerama_exists) return;
|
||||
|
||||
xcb_xinerama_is_active_reply_t *active =
|
||||
xcb_xinerama_is_active_reply(ps->c,
|
||||
xcb_xinerama_is_active(ps->c), NULL);
|
||||
if (!active || !active->state) {
|
||||
free(active);
|
||||
return;
|
||||
}
|
||||
free(active);
|
||||
|
||||
ps->xinerama_scrs = xcb_xinerama_query_screens_reply(ps->c,
|
||||
xcb_xinerama_query_screens(ps->c), NULL);
|
||||
if (!ps->xinerama_scrs)
|
||||
return;
|
||||
|
||||
xcb_xinerama_screen_info_t *scrs = xcb_xinerama_query_screens_screen_info(ps->xinerama_scrs);
|
||||
ps->xinerama_nscrs = xcb_xinerama_query_screens_screen_info_length(ps->xinerama_scrs);
|
||||
|
||||
ps->xinerama_scr_regs = allocchk(malloc(sizeof(region_t)
|
||||
* ps->xinerama_nscrs));
|
||||
for (int i = 0; i < ps->xinerama_nscrs; ++i) {
|
||||
const xcb_xinerama_screen_info_t * const s = &scrs[i];
|
||||
pixman_region32_init_rect(&ps->xinerama_scr_regs[i], s->x_org, s->y_org, s->width, s->height);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a session.
|
||||
*
|
||||
|
|
192
src/compton.h
192
src/compton.h
|
@ -52,12 +52,6 @@ win *find_toplevel2(session_t *ps, Window wid);
|
|||
|
||||
void map_win(session_t *ps, Window id);
|
||||
|
||||
void
|
||||
render(session_t *ps, int x, int y, int dx, int dy, int wid, int hei,
|
||||
double opacity, bool argb, bool neg,
|
||||
xcb_render_picture_t pict, glx_texture_t *ptex,
|
||||
const region_t *reg_paint, const glx_prog_main_t *pprogram);
|
||||
|
||||
/**
|
||||
* Reset filter on a <code>Picture</code>.
|
||||
*/
|
||||
|
@ -119,19 +113,6 @@ free_picture(session_t *ps, xcb_render_picture_t *p) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy a <code>Damage</code>.
|
||||
*/
|
||||
inline static void
|
||||
free_damage(session_t *ps, xcb_damage_damage_t *p) {
|
||||
if (*p) {
|
||||
// BadDamage will be thrown if the window is destroyed
|
||||
set_ignore_cookie(ps,
|
||||
xcb_damage_destroy(ps->c, *p));
|
||||
*p = None;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy a condition list.
|
||||
*/
|
||||
|
@ -141,23 +122,6 @@ free_wincondlst(c2_lptr_t **pcondlst) {
|
|||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free Xinerama screen info.
|
||||
*/
|
||||
static inline void
|
||||
free_xinerama_info(session_t *ps) {
|
||||
#ifdef CONFIG_XINERAMA
|
||||
if (ps->xinerama_scr_regs) {
|
||||
for (int i = 0; i < ps->xinerama_nscrs; ++i)
|
||||
pixman_region32_fini(&ps->xinerama_scr_regs[i]);
|
||||
free(ps->xinerama_scr_regs);
|
||||
}
|
||||
cxfree(ps->xinerama_scrs);
|
||||
ps->xinerama_scrs = NULL;
|
||||
ps->xinerama_nscrs = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OPENGL
|
||||
/**
|
||||
* Bind texture in paint_t if we are using GLX backend.
|
||||
|
@ -203,69 +167,6 @@ free_paint(session_t *ps, paint_t *ppaint) {
|
|||
ppaint->pixmap = XCB_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free w->paint.
|
||||
*/
|
||||
static inline void
|
||||
free_wpaint(session_t *ps, win *w) {
|
||||
free_paint(ps, &w->paint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy all resources in a <code>struct _win</code>.
|
||||
*/
|
||||
static inline void
|
||||
free_win_res(session_t *ps, win *w) {
|
||||
free_win_res_glx(ps, w);
|
||||
free_paint(ps, &w->paint);
|
||||
pixman_region32_fini(&w->bounding_shape);
|
||||
free_paint(ps, &w->shadow_paint);
|
||||
free_damage(ps, &w->damage);
|
||||
rc_region_unref(&w->reg_ignore);
|
||||
free(w->name);
|
||||
free(w->class_instance);
|
||||
free(w->class_general);
|
||||
free(w->role);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free root tile related things.
|
||||
*/
|
||||
static inline void
|
||||
free_root_tile(session_t *ps) {
|
||||
free_picture(ps, &ps->root_tile_paint.pict);
|
||||
free_texture(ps, &ps->root_tile_paint.ptex);
|
||||
if (ps->root_tile_fill) {
|
||||
xcb_free_pixmap(ps->c, ps->root_tile_paint.pixmap);
|
||||
ps->root_tile_paint.pixmap = XCB_NONE;
|
||||
}
|
||||
ps->root_tile_paint.pixmap = None;
|
||||
ps->root_tile_fill = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current system clock in milliseconds.
|
||||
*/
|
||||
static inline time_ms_t
|
||||
get_time_ms(void) {
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
return tv.tv_sec % SEC_WRAP * 1000 + tv.tv_usec / 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert time from milliseconds to struct timeval.
|
||||
*/
|
||||
static inline struct timeval
|
||||
ms_to_tv(int timeout) {
|
||||
return (struct timeval) {
|
||||
.tv_sec = timeout / MS_PER_SEC,
|
||||
.tv_usec = timeout % MS_PER_SEC * (US_PER_SEC / MS_PER_SEC)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a XTextProperty of a single string.
|
||||
*/
|
||||
|
@ -301,26 +202,6 @@ wid_set_text_prop(session_t *ps, Window wid, Atom prop_atom, char *str) {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop listening for events on a particular window.
|
||||
*/
|
||||
static inline void
|
||||
win_ev_stop(session_t *ps, win *w) {
|
||||
// Will get BadWindow if the window is destroyed
|
||||
set_ignore_cookie(ps,
|
||||
xcb_change_window_attributes(ps->c, w->id, XCB_CW_EVENT_MASK, (const uint32_t[]) { 0 }));
|
||||
|
||||
if (w->client_win) {
|
||||
set_ignore_cookie(ps,
|
||||
xcb_change_window_attributes(ps->c, w->client_win, XCB_CW_EVENT_MASK, (const uint32_t[]) { 0 }));
|
||||
}
|
||||
|
||||
if (ps->shape_exists) {
|
||||
set_ignore_cookie(ps,
|
||||
xcb_shape_select_input(ps->c, w->id, 0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump an drawable's info.
|
||||
*/
|
||||
|
@ -366,20 +247,6 @@ win_validate_pixmap(session_t *ps, win *w) {
|
|||
free_paint(ps, &w->paint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find matched window.
|
||||
*/
|
||||
static inline win *
|
||||
find_win_all(session_t *ps, const Window wid) {
|
||||
if (!wid || PointerRoot == wid || wid == ps->root || wid == ps->overlay)
|
||||
return NULL;
|
||||
|
||||
win *w = find_win(ps, wid);
|
||||
if (!w) w = find_toplevel(ps, wid);
|
||||
if (!w) w = find_toplevel2(ps, wid);
|
||||
return w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a convolution kernel.
|
||||
*/
|
||||
|
@ -393,38 +260,6 @@ normalize_conv_kern(int wid, int hei, xcb_render_fixed_t *kern) {
|
|||
kern[i] = DOUBLE_TO_XFIXED(XFIXED_TO_DOUBLE(kern[i]) * factor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize a region.
|
||||
*/
|
||||
static inline void
|
||||
resize_region(session_t *ps, region_t *region, short mod) {
|
||||
if (!mod || !region) return;
|
||||
// Loop through all rectangles
|
||||
int nrects;
|
||||
int nnewrects = 0;
|
||||
pixman_box32_t *rects = pixman_region32_rectangles(region, &nrects);
|
||||
pixman_box32_t *newrects = calloc(nrects, sizeof *newrects);
|
||||
for (int i = 0; i < nrects; i++) {
|
||||
int x1 = max_i(rects[i].x1 - mod, 0);
|
||||
int y1 = max_i(rects[i].y1 - mod, 0);
|
||||
int x2 = min_i(rects[i].x2 + mod, ps->root_width);
|
||||
int y2 = min_i(rects[i].y2 + mod, ps->root_height);
|
||||
int wid = x2 - x1;
|
||||
int hei = y2 - y1;
|
||||
if (wid <= 0 || hei <= 0)
|
||||
continue;
|
||||
newrects[nnewrects] = (pixman_box32_t) {
|
||||
.x1 = x1, .x2 = x2, .y1 = y1, .y2 = y2
|
||||
};
|
||||
++nnewrects;
|
||||
}
|
||||
|
||||
pixman_region32_fini(region);
|
||||
pixman_region32_init_rects(region, newrects, nnewrects);
|
||||
|
||||
free(newrects);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OPENGL
|
||||
/**
|
||||
* Ensure we have a GLX context.
|
||||
|
@ -439,31 +274,4 @@ ensure_glx_context(session_t *ps) {
|
|||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get the Xinerama screen a window is on.
|
||||
*
|
||||
* Return an index >= 0, or -1 if not found.
|
||||
*/
|
||||
static inline void
|
||||
cxinerama_win_upd_scr(session_t *ps, win *w) {
|
||||
#ifdef CONFIG_XINERAMA
|
||||
w->xinerama_scr = -1;
|
||||
|
||||
if (!ps->xinerama_scrs)
|
||||
return;
|
||||
|
||||
xcb_xinerama_screen_info_t *scrs = xcb_xinerama_query_screens_screen_info(ps->xinerama_scrs);
|
||||
int length = xcb_xinerama_query_screens_screen_info_length(ps->xinerama_scrs);
|
||||
for (int i = 0; i < length; i++) {
|
||||
xcb_xinerama_screen_info_t *s = &scrs[i];
|
||||
if (s->x_org <= w->g.x && s->y_org <= w->g.y
|
||||
&& s->x_org + s->width >= w->g.x + w->widthb
|
||||
&& s->y_org + s->height >= w->g.y + w->heightb) {
|
||||
w->xinerama_scr = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// vim: set et sw=2 :
|
||||
|
|
21
src/win.c
21
src/win.c
|
@ -1194,7 +1194,7 @@ void win_update_bounding_shape(session_t *ps, win *w) {
|
|||
win_rounded_corners(ps, w);
|
||||
|
||||
// Window shape changed, we should free old wpaint and shadow pict
|
||||
free_wpaint(ps, w);
|
||||
free_paint(ps, &w->paint);
|
||||
free_paint(ps, &w->shadow_paint);
|
||||
//printf_errf("(): free out dated pict");
|
||||
|
||||
|
@ -1265,3 +1265,22 @@ bool win_is_region_ignore_valid(session_t *ps, win *w) {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop listening for events on a particular window.
|
||||
*/
|
||||
void win_ev_stop(session_t *ps, win *w) {
|
||||
// Will get BadWindow if the window is destroyed
|
||||
set_ignore_cookie(ps,
|
||||
xcb_change_window_attributes(ps->c, w->id, XCB_CW_EVENT_MASK, (const uint32_t[]) { 0 }));
|
||||
|
||||
if (w->client_win) {
|
||||
set_ignore_cookie(ps,
|
||||
xcb_change_window_attributes(ps->c, w->client_win, XCB_CW_EVENT_MASK, (const uint32_t[]) { 0 }));
|
||||
}
|
||||
|
||||
if (ps->shape_exists) {
|
||||
set_ignore_cookie(ps,
|
||||
xcb_shape_select_input(ps->c, w->id, 0));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -332,6 +332,9 @@ void
|
|||
win_update_frame_extents(session_t *ps, win *w, Window client);
|
||||
bool add_win(session_t *ps, Window id, Window prev);
|
||||
|
||||
// Stop receiving events (except ConfigureNotify, XXX why?) from a window
|
||||
void win_ev_stop(session_t *ps, win *w);
|
||||
|
||||
/**
|
||||
* Get the leader of a window.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue