Phase 80j: clean X11 from shutdown.c, framewin.c, properties.c
- shutdown.c: RestoreDesktop/wWipeDesktop/restoreWindows moved entirely to x11_backend.c; policy file contains only vtable dispatch stubs - framewin.c: wFrameWindowPaint restructured — policy logic stays, X11 rendering (resizebar lines, titlebar pixmap ops) dispatched through new frame_paint_resizebar/frame_paint_titlebar vtable slots - properties.c: all 6 functions (PropGetProtocols, PropGetCheckProperty, PropSetWMakerProtocols, PropSetIconTileHint, PropGetClientLeader, PropGetWindowState, PropCleanUp) replaced with vtable dispatch stubs; X11 implementations inlined into x11_backend.c New vtable slots: frame_paint_resizebar, frame_paint_titlebar, prop_get_client_leader, prop_get_window_state. All three files verified X11-free with nm.
This commit is contained in:
parent
a5d6720a1c
commit
6d4fc32b28
|
|
@ -1703,6 +1703,12 @@ typedef struct WMBackend {
|
|||
|
||||
unsigned long (*keysym_from_name)(const char *name);
|
||||
|
||||
void (*frame_paint_resizebar)(struct WFrameWindow *fwin);
|
||||
void (*frame_paint_titlebar)(struct WFrameWindow *fwin, int state);
|
||||
|
||||
WNativeWindow (*prop_get_client_leader)(WNativeWindow window);
|
||||
int (*prop_get_window_state)(WNativeWindow window);
|
||||
|
||||
} WMBackend;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -6208,6 +6208,12 @@ static unsigned long wl_keysym_from_name(const char *name)
|
|||
return (unsigned long)xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS);
|
||||
}
|
||||
|
||||
static void wl_noop_frame_paint_resizebar(WFrameWindow *fwin) { (void)fwin; }
|
||||
static void wl_noop_frame_paint_titlebar(WFrameWindow *fwin, int state) { (void)fwin; (void)state; }
|
||||
|
||||
static WNativeWindow wl_noop_prop_get_client_leader(WNativeWindow window) { (void)window; return WNATIVE_NONE; }
|
||||
static int wl_noop_prop_get_window_state(WNativeWindow window) { (void)window; return -1; }
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* vtable */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
|
@ -6425,4 +6431,8 @@ const WMBackend wl_backend = {
|
|||
.pixmap_create_from_xbm = wl_noop_pixmap_create_from_xbm,
|
||||
.pixmap_create = wl_noop_pixmap_create,
|
||||
.keysym_from_name = wl_keysym_from_name,
|
||||
.frame_paint_resizebar = wl_noop_frame_paint_resizebar,
|
||||
.frame_paint_titlebar = wl_noop_frame_paint_titlebar,
|
||||
.prop_get_client_leader = wl_noop_prop_get_client_leader,
|
||||
.prop_get_window_state = wl_noop_prop_get_window_state,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
#include "../../resources.h"
|
||||
#include "../../superfluous.h"
|
||||
#include "../../shutdown.h" /* Shutdown(), WShutdownMode */
|
||||
#include "../../winspector.h"
|
||||
#include "../../main.h" /* Restart() */
|
||||
#include "../../icon.h"
|
||||
#include "../../appicon.h"
|
||||
|
|
@ -2482,6 +2483,111 @@ x11_texture_free_gc(GC gc)
|
|||
/* Frame decoration helpers (Phase 80) */
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
x11_frame_paint_resizebar(WFrameWindow *fwin)
|
||||
{
|
||||
Window win;
|
||||
int w, h, cw;
|
||||
GC light_gc, dim_gc;
|
||||
WTexSolid *texture = (WTexSolid *) fwin->resizebar_texture[0];
|
||||
|
||||
w = fwin->resizebar->width;
|
||||
h = fwin->resizebar->height;
|
||||
cw = fwin->resizebar_corner_width;
|
||||
light_gc = texture->light_gc;
|
||||
dim_gc = texture->dim_gc;
|
||||
win = fwin->resizebar->window;
|
||||
|
||||
XDrawLine(dpy, win, dim_gc, 0, 0, w, 0);
|
||||
XDrawLine(dpy, win, light_gc, 0, 1, w, 1);
|
||||
XDrawLine(dpy, win, dim_gc, cw, 2, cw, h);
|
||||
XDrawLine(dpy, win, light_gc, cw + 1, 2, cw + 1, h);
|
||||
XDrawLine(dpy, win, dim_gc, w - cw - 2, 2, w - cw - 2, h);
|
||||
XDrawLine(dpy, win, light_gc, w - cw - 1, 2, w - cw - 1, h);
|
||||
#ifdef SHADOW_RESIZEBAR
|
||||
XDrawLine(dpy, win, light_gc, 0, 1, 0, h - 1);
|
||||
XDrawLine(dpy, win, dim_gc, w - 1, 2, w - 1, h - 1);
|
||||
XDrawLine(dpy, win, dim_gc, 1, h - 1, cw, h - 1);
|
||||
XDrawLine(dpy, win, dim_gc, cw + 2, h - 1, w - cw - 2, h - 1);
|
||||
XDrawLine(dpy, win, dim_gc, w - cw, h - 1, w - 1, h - 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
x11_frame_paint_titlebar(WFrameWindow *fwin, int state)
|
||||
{
|
||||
WScreen *scr = fwin->screen_ptr;
|
||||
int x, y, w, h;
|
||||
int lofs = 6, rofs = 6;
|
||||
int titlelen;
|
||||
int allButtons = 1;
|
||||
|
||||
if (wPreferences.new_style != TS_NEW) {
|
||||
if (fwin->left_button && !fwin->flags.hide_left_button && !fwin->flags.lbutton_dont_fit)
|
||||
lofs += fwin->left_button->width + 3;
|
||||
else
|
||||
allButtons = 0;
|
||||
#ifdef XKB_BUTTON_HINT
|
||||
if (fwin->language_button && !fwin->flags.hide_language_button
|
||||
&& !fwin->flags.languagebutton_dont_fit)
|
||||
lofs += fwin->language_button->width;
|
||||
else
|
||||
allButtons = 0;
|
||||
#endif
|
||||
if (fwin->right_button && !fwin->flags.hide_right_button && !fwin->flags.rbutton_dont_fit)
|
||||
rofs += fwin->right_button->width + 3;
|
||||
else
|
||||
allButtons = 0;
|
||||
}
|
||||
#ifdef XKB_BUTTON_HINT
|
||||
fwin->languagebutton_image = scr->b_pixmaps[WBUT_XKBGROUP1 + fwin->languagemode];
|
||||
#endif
|
||||
|
||||
if (fwin->title && fwin->titlebar->window) {
|
||||
Drawable buf;
|
||||
char *title;
|
||||
|
||||
title = ShrinkString(*fwin->font, fwin->title, fwin->titlebar->width - lofs - rofs);
|
||||
titlelen = strlen(title);
|
||||
w = WMWidthOfString(*fwin->font, title, titlelen);
|
||||
|
||||
switch (fwin->flags.justification) {
|
||||
case WTJ_LEFT: x = lofs; break;
|
||||
case WTJ_RIGHT: x = fwin->titlebar->width - w - rofs; break;
|
||||
default:
|
||||
if (!allButtons)
|
||||
x = lofs + (fwin->titlebar->width - w - lofs - rofs) / 2;
|
||||
else
|
||||
x = (fwin->titlebar->width - w) / 2;
|
||||
break;
|
||||
}
|
||||
|
||||
y = *fwin->title_clearance + TITLEBAR_EXTEND_SPACE;
|
||||
h = WMFontHeight(*fwin->font);
|
||||
if (y*2 + h > *fwin->title_max_height)
|
||||
y = (*fwin->title_max_height - h) / 2;
|
||||
if (y*2 + h < *fwin->title_min_height)
|
||||
y = (*fwin->title_min_height - h) / 2;
|
||||
|
||||
buf = XCreatePixmap(dpy, fwin->titlebar->window, w + 2, h, scr->w_depth);
|
||||
XSetClipMask(dpy, scr->copy_gc, None);
|
||||
|
||||
if (fwin->title_texture[state]->any.type != WTEX_SOLID) {
|
||||
XCopyArea(dpy, fwin->title_back[state], buf, scr->copy_gc,
|
||||
x - 1, y, w + 2, h, 0, 0);
|
||||
} else {
|
||||
XSetForeground(dpy, scr->copy_gc, fwin->title_texture[state]->solid.normal.pixel);
|
||||
XFillRectangle(dpy, buf, scr->copy_gc, 0, 0, w + 2, h);
|
||||
}
|
||||
|
||||
WMDrawString(scr->wmscreen, buf, fwin->title_color[state],
|
||||
*fwin->font, 1, 0, title, titlelen);
|
||||
XCopyArea(dpy, buf, fwin->titlebar->window, scr->copy_gc, 0, 0, w + 2, h, x - 1, y);
|
||||
XFreePixmap(dpy, buf);
|
||||
wfree(title);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
x11_frame_paint_impl(struct WFrameWindow *fwin)
|
||||
{
|
||||
|
|
@ -2692,7 +2798,23 @@ static void x11_netwm_update_opacity(WWindow *wwin) { wNETWMUpdateWindowOpacity(
|
|||
|
||||
static void x11_prop_get_protocols(WNativeWindow window, WProtocols *prots)
|
||||
{
|
||||
PropGetProtocols((Window)window, prots);
|
||||
Atom *protocols;
|
||||
int count, i;
|
||||
|
||||
memset(prots, 0, sizeof(WProtocols));
|
||||
if (!XGetWMProtocols(dpy, (Window)window, &protocols, &count))
|
||||
return;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (protocols[i] == w_global.atom.wm.take_focus)
|
||||
prots->TAKE_FOCUS = 1;
|
||||
else if (protocols[i] == w_global.atom.wm.delete_window)
|
||||
prots->DELETE_WINDOW = 1;
|
||||
else if (protocols[i] == w_global.atom.wm.save_yourself)
|
||||
prots->SAVE_YOURSELF = 1;
|
||||
else if (protocols[i] == w_global.atom.gnustep.wm_miniaturize_window)
|
||||
prots->MINIATURIZE_WINDOW = 1;
|
||||
}
|
||||
XFree(protocols);
|
||||
}
|
||||
|
||||
static unsigned char *x11_prop_get_check_property(WNativeWindow window,
|
||||
|
|
@ -2701,23 +2823,102 @@ static unsigned char *x11_prop_get_check_property(WNativeWindow window,
|
|||
int format, int count,
|
||||
int *ret_count)
|
||||
{
|
||||
return PropGetCheckProperty((Window)window, (Atom)hint, (Atom)type,
|
||||
format, count, ret_count);
|
||||
Atom type_ret;
|
||||
int fmt_ret;
|
||||
unsigned long nitems_ret, bytes_after_ret;
|
||||
unsigned char *data;
|
||||
int tmp = (count <= 0) ? 0xffffff : count;
|
||||
|
||||
if (XGetWindowProperty(dpy, (Window)window, (Atom)hint, 0, tmp, False, (Atom)type,
|
||||
&type_ret, &fmt_ret, &nitems_ret, &bytes_after_ret,
|
||||
&data) != Success || !data)
|
||||
return NULL;
|
||||
|
||||
if ((type != AnyPropertyType && (Atom)type != type_ret)
|
||||
|| (count > 0 && nitems_ret != (unsigned long)count)
|
||||
|| (format != 0 && format != fmt_ret)) {
|
||||
XFree(data);
|
||||
return NULL;
|
||||
}
|
||||
if (ret_count)
|
||||
*ret_count = nitems_ret;
|
||||
return data;
|
||||
}
|
||||
|
||||
static void x11_prop_set_wmaker_protocols(WNativeWindow root)
|
||||
{
|
||||
PropSetWMakerProtocols((Window)root);
|
||||
Atom protocols[3];
|
||||
int count = 0;
|
||||
protocols[count++] = w_global.atom.wmaker.menu;
|
||||
protocols[count++] = w_global.atom.wmaker.wm_function;
|
||||
protocols[count++] = w_global.atom.wmaker.noticeboard;
|
||||
XChangeProperty(dpy, (Window)root, w_global.atom.wmaker.wm_protocols, WA_ATOM,
|
||||
32, PropModeReplace, (unsigned char *)protocols, count);
|
||||
}
|
||||
|
||||
static void x11_prop_set_icon_tile(WScreen *scr, RImage *image)
|
||||
{
|
||||
PropSetIconTileHint(scr, image);
|
||||
static Atom imageAtom = 0;
|
||||
unsigned char *tmp;
|
||||
int x, y;
|
||||
|
||||
if (scr->info_window == None)
|
||||
return;
|
||||
if (!imageAtom)
|
||||
imageAtom = XInternAtom(dpy, "_RGBA_IMAGE", False);
|
||||
|
||||
tmp = malloc(image->width * image->height * 4 + 4);
|
||||
if (!tmp) return;
|
||||
|
||||
tmp[0] = image->width >> 8;
|
||||
tmp[1] = image->width & 0xff;
|
||||
tmp[2] = image->height >> 8;
|
||||
tmp[3] = image->height & 0xff;
|
||||
|
||||
if (image->format == RRGBAFormat) {
|
||||
memcpy(&tmp[4], image->data, image->width * image->height * 4);
|
||||
} else {
|
||||
char *ptr = (char *)(tmp + 4);
|
||||
char *src = (char *)image->data;
|
||||
for (y = 0; y < image->height; y++)
|
||||
for (x = 0; x < image->width; x++) {
|
||||
*ptr++ = *src++; *ptr++ = *src++; *ptr++ = *src++; *ptr++ = 255;
|
||||
}
|
||||
}
|
||||
XChangeProperty(dpy, scr->info_window, w_global.atom.wmaker.icon_tile,
|
||||
imageAtom, 8, PropModeReplace, tmp, image->width * image->height * 4 + 4);
|
||||
wfree(tmp);
|
||||
}
|
||||
|
||||
static void x11_prop_cleanup(WNativeWindow root)
|
||||
{
|
||||
PropCleanUp((Window)root);
|
||||
XDeleteProperty(dpy, (Window)root, w_global.atom.wmaker.wm_protocols);
|
||||
XDeleteProperty(dpy, (Window)root, w_global.atom.wmaker.noticeboard);
|
||||
XDeleteProperty(dpy, (Window)root, WA_WM_ICON_SIZE);
|
||||
}
|
||||
|
||||
static WNativeWindow x11_prop_get_client_leader(WNativeWindow window)
|
||||
{
|
||||
Window *win;
|
||||
Window leader;
|
||||
win = (Window *)x11_prop_get_check_property(window,
|
||||
(unsigned long)w_global.atom.wm.client_leader, (unsigned long)WA_WINDOW, 32, 1, NULL);
|
||||
if (!win) return WNATIVE_NONE;
|
||||
leader = *win;
|
||||
XFree(win);
|
||||
return (WNativeWindow)leader;
|
||||
}
|
||||
|
||||
static int x11_prop_get_window_state(WNativeWindow window)
|
||||
{
|
||||
long *data;
|
||||
long state;
|
||||
data = (long *)x11_prop_get_check_property(window,
|
||||
(unsigned long)w_global.atom.wm.state, (unsigned long)w_global.atom.wm.state, 32, 1, NULL);
|
||||
if (!data) return -1;
|
||||
state = *data;
|
||||
XFree(data);
|
||||
return state;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
@ -2857,14 +3058,68 @@ static void x11_appicon_paint(WAppIcon *aicon)
|
|||
/* Shutdown (Phase 80) */
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
static void x11_colormap_install(WScreen *scr, WWindow *wwin); /* forward */
|
||||
|
||||
static void x11_restore_windows(WMBag *bag, WMBagIterator iter)
|
||||
{
|
||||
WCoreWindow *next, *core;
|
||||
WWindow *wwin;
|
||||
|
||||
if (iter == NULL)
|
||||
core = WMBagFirst(bag, &iter);
|
||||
else
|
||||
core = WMBagNext(bag, &iter);
|
||||
|
||||
if (core == NULL)
|
||||
return;
|
||||
|
||||
x11_restore_windows(bag, iter);
|
||||
|
||||
while (core->stacking->under)
|
||||
core = core->stacking->under;
|
||||
|
||||
while (core) {
|
||||
next = core->stacking->above;
|
||||
if (core->descriptor.parent_type == WCLASS_WINDOW) {
|
||||
Window window;
|
||||
wwin = core->descriptor.parent;
|
||||
window = wwin->client_win;
|
||||
wUnmanageWindow(wwin, !wwin->flags.internal_window, False);
|
||||
XMapWindow(dpy, window);
|
||||
}
|
||||
core = next;
|
||||
}
|
||||
}
|
||||
|
||||
static void x11_restore_desktop(WScreen *scr)
|
||||
{
|
||||
RestoreDesktop(scr);
|
||||
if (scr->helper_pid > 0) {
|
||||
kill(scr->helper_pid, SIGTERM);
|
||||
scr->helper_pid = 0;
|
||||
}
|
||||
XGrabServer(dpy);
|
||||
wDestroyInspectorPanels();
|
||||
x11_restore_windows(scr->stacking_list, NULL);
|
||||
XUngrabServer(dpy);
|
||||
XSetInputFocus(dpy, PointerRoot, RevertToParent, CurrentTime);
|
||||
x11_colormap_install(scr, NULL);
|
||||
x11_prop_cleanup((WNativeWindow)scr->root_win);
|
||||
x11_netwm_cleanup(scr);
|
||||
XSync(dpy, 0);
|
||||
}
|
||||
|
||||
static void x11_wipe_desktop(WScreen *scr)
|
||||
{
|
||||
wWipeDesktop(scr);
|
||||
WWindow *wwin = scr->focused_window;
|
||||
while (wwin) {
|
||||
if (wwin->protocols.DELETE_WINDOW)
|
||||
wClientSendProtocol(wwin, w_global.atom.wm.delete_window,
|
||||
w_global.timestamp.last_event);
|
||||
else
|
||||
wClientKill(wwin);
|
||||
wwin = wwin->prev;
|
||||
}
|
||||
XSync(dpy, False);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
@ -3366,6 +3621,10 @@ const WMBackend x11_backend = {
|
|||
.pixmap_create_from_xbm = x11_pixmap_create_from_xbm,
|
||||
.pixmap_create = x11_pixmap_create,
|
||||
.keysym_from_name = x11_keysym_from_name,
|
||||
.frame_paint_resizebar = x11_frame_paint_resizebar,
|
||||
.frame_paint_titlebar = x11_frame_paint_titlebar,
|
||||
.prop_get_client_leader = x11_prop_get_client_leader,
|
||||
.prop_get_window_state = x11_prop_get_window_state,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
128
src/framewin.c
128
src/framewin.c
|
|
@ -870,19 +870,14 @@ void wFrameWindowPaint(WFrameWindow * fwin)
|
|||
|
||||
if (fwin->flags.need_texture_remake) {
|
||||
int i;
|
||||
|
||||
fwin->flags.need_texture_remake = 0;
|
||||
fwin->flags.need_texture_change = 0;
|
||||
|
||||
if (fwin->flags.single_texture) {
|
||||
remakeTexture(fwin, 0);
|
||||
updateTexture(fwin);
|
||||
} else {
|
||||
/* first render the texture for the current state... */
|
||||
remakeTexture(fwin, state);
|
||||
/* ... and paint it */
|
||||
updateTexture(fwin);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (i != state)
|
||||
remakeTexture(fwin, i);
|
||||
|
|
@ -892,7 +887,6 @@ void wFrameWindowPaint(WFrameWindow * fwin)
|
|||
|
||||
if (fwin->flags.need_texture_change) {
|
||||
fwin->flags.need_texture_change = 0;
|
||||
|
||||
updateTexture(fwin);
|
||||
}
|
||||
|
||||
|
|
@ -905,129 +899,11 @@ void wFrameWindowPaint(WFrameWindow * fwin)
|
|||
if (fwin->resizebar && fwin->resizebar->window
|
||||
&& !fwin->flags.repaint_only_titlebar
|
||||
&& fwin->resizebar_texture[0]->any.type == WTEX_SOLID) {
|
||||
Window win;
|
||||
int w, h;
|
||||
int cw;
|
||||
GC light_gc, dim_gc;
|
||||
WTexSolid *texture = (WTexSolid *) fwin->resizebar_texture[0];
|
||||
|
||||
w = fwin->resizebar->width;
|
||||
h = fwin->resizebar->height;
|
||||
cw = fwin->resizebar_corner_width;
|
||||
light_gc = texture->light_gc;
|
||||
dim_gc = texture->dim_gc;
|
||||
win = fwin->resizebar->window;
|
||||
|
||||
XDrawLine(dpy, win, dim_gc, 0, 0, w, 0);
|
||||
XDrawLine(dpy, win, light_gc, 0, 1, w, 1);
|
||||
|
||||
XDrawLine(dpy, win, dim_gc, cw, 2, cw, h);
|
||||
XDrawLine(dpy, win, light_gc, cw + 1, 2, cw + 1, h);
|
||||
|
||||
XDrawLine(dpy, win, dim_gc, w - cw - 2, 2, w - cw - 2, h);
|
||||
XDrawLine(dpy, win, light_gc, w - cw - 1, 2, w - cw - 1, h);
|
||||
|
||||
#ifdef SHADOW_RESIZEBAR
|
||||
XDrawLine(dpy, win, light_gc, 0, 1, 0, h - 1);
|
||||
XDrawLine(dpy, win, dim_gc, w - 1, 2, w - 1, h - 1);
|
||||
XDrawLine(dpy, win, dim_gc, 1, h - 1, cw, h - 1);
|
||||
XDrawLine(dpy, win, dim_gc, cw + 2, h - 1, w - cw - 2, h - 1);
|
||||
XDrawLine(dpy, win, dim_gc, w - cw, h - 1, w - 1, h - 1);
|
||||
#endif /* SHADOW_RESIZEBAR */
|
||||
wm_backend->frame_paint_resizebar(fwin);
|
||||
}
|
||||
|
||||
if (fwin->titlebar && !fwin->flags.repaint_only_resizebar) {
|
||||
int x, y, w, h;
|
||||
int lofs = 6, rofs = 6;
|
||||
int titlelen;
|
||||
int allButtons = 1;
|
||||
|
||||
if (wPreferences.new_style != TS_NEW) {
|
||||
if (fwin->left_button && !fwin->flags.hide_left_button && !fwin->flags.lbutton_dont_fit)
|
||||
lofs += fwin->left_button->width + 3;
|
||||
else
|
||||
allButtons = 0;
|
||||
|
||||
#ifdef XKB_BUTTON_HINT
|
||||
if (fwin->language_button && !fwin->flags.hide_language_button
|
||||
&& !fwin->flags.languagebutton_dont_fit)
|
||||
lofs += fwin->language_button->width;
|
||||
else
|
||||
allButtons = 0;
|
||||
#endif
|
||||
|
||||
if (fwin->right_button && !fwin->flags.hide_right_button && !fwin->flags.rbutton_dont_fit)
|
||||
rofs += fwin->right_button->width + 3;
|
||||
else
|
||||
allButtons = 0;
|
||||
}
|
||||
#ifdef XKB_BUTTON_HINT
|
||||
fwin->languagebutton_image = scr->b_pixmaps[WBUT_XKBGROUP1 + fwin->languagemode];
|
||||
#endif
|
||||
|
||||
if (fwin->title && fwin->titlebar->window) {
|
||||
Drawable buf;
|
||||
char *title;
|
||||
|
||||
title = ShrinkString(*fwin->font, fwin->title, fwin->titlebar->width - lofs - rofs);
|
||||
titlelen = strlen(title);
|
||||
w = WMWidthOfString(*fwin->font, title, titlelen);
|
||||
|
||||
switch (fwin->flags.justification) {
|
||||
case WTJ_LEFT:
|
||||
x = lofs;
|
||||
break;
|
||||
|
||||
case WTJ_RIGHT:
|
||||
x = fwin->titlebar->width - w - rofs;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!allButtons)
|
||||
x = lofs + (fwin->titlebar->width - w - lofs - rofs) / 2;
|
||||
else
|
||||
x = (fwin->titlebar->width - w) / 2;
|
||||
break;
|
||||
}
|
||||
|
||||
y = *fwin->title_clearance + TITLEBAR_EXTEND_SPACE;
|
||||
h = WMFontHeight(*fwin->font);
|
||||
|
||||
if (y*2 + h > *fwin->title_max_height)
|
||||
y = (*fwin->title_max_height - h) / 2;
|
||||
|
||||
if (y*2 + h < *fwin->title_min_height)
|
||||
y = (*fwin->title_min_height - h) / 2;
|
||||
|
||||
/* We use a w+2 buffer to have an extra pixel on the left and
|
||||
* another one on the right. This is because for some odd reason,
|
||||
* sometimes when using AA fonts (when libfreetype2 is compiled
|
||||
* with bytecode interpreter turned off), some fonts are drawn
|
||||
* starting from x = -1 not from 0 as requested. Observed with
|
||||
* capital A letter on the bold 'trebuchet ms' font. -Dan
|
||||
*/
|
||||
buf = XCreatePixmap(dpy, fwin->titlebar->window, w + 2, h, scr->w_depth);
|
||||
|
||||
XSetClipMask(dpy, scr->copy_gc, None);
|
||||
|
||||
if (fwin->title_texture[state]->any.type != WTEX_SOLID) {
|
||||
XCopyArea(dpy, fwin->title_back[state], buf, scr->copy_gc,
|
||||
x - 1, y, w + 2, h, 0, 0);
|
||||
} else {
|
||||
XSetForeground(dpy, scr->copy_gc, fwin->title_texture[state]->solid.normal.pixel);
|
||||
XFillRectangle(dpy, buf, scr->copy_gc, 0, 0, w + 2, h);
|
||||
}
|
||||
|
||||
/*XDrawRectangle(dpy, buf, WMColorGC(scr->white),1,0,w,h-1); */
|
||||
WMDrawString(scr->wmscreen, buf, fwin->title_color[state],
|
||||
*fwin->font, 1, 0, title, titlelen);
|
||||
|
||||
XCopyArea(dpy, buf, fwin->titlebar->window, scr->copy_gc, 0, 0, w + 2, h, x - 1, y);
|
||||
|
||||
wm_backend->pixmap_free((unsigned long)buf);
|
||||
|
||||
wfree(title);
|
||||
}
|
||||
wm_backend->frame_paint_titlebar(fwin, state);
|
||||
|
||||
if (fwin->left_button)
|
||||
handleButtonExpose(&fwin->left_button->descriptor, NULL);
|
||||
|
|
|
|||
140
src/properties.c
140
src/properties.c
|
|
@ -37,161 +37,37 @@ int PropGetWMClass(Window window, char **wm_class, char **wm_instance)
|
|||
|
||||
void PropGetProtocols(Window window, WProtocols * prots)
|
||||
{
|
||||
Atom *protocols;
|
||||
int count, i;
|
||||
|
||||
memset(prots, 0, sizeof(WProtocols));
|
||||
if (!XGetWMProtocols(dpy, window, &protocols, &count)) {
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < count; i++) {
|
||||
if (protocols[i] == w_global.atom.wm.take_focus)
|
||||
prots->TAKE_FOCUS = 1;
|
||||
else if (protocols[i] == w_global.atom.wm.delete_window)
|
||||
prots->DELETE_WINDOW = 1;
|
||||
else if (protocols[i] == w_global.atom.wm.save_yourself)
|
||||
prots->SAVE_YOURSELF = 1;
|
||||
else if (protocols[i] == w_global.atom.gnustep.wm_miniaturize_window)
|
||||
prots->MINIATURIZE_WINDOW = 1;
|
||||
}
|
||||
XFree(protocols);
|
||||
wm_backend->prop_get_protocols((WNativeWindow)window, prots);
|
||||
}
|
||||
|
||||
unsigned char *PropGetCheckProperty(Window window, Atom hint, Atom type, int format, int count, int *retCount)
|
||||
{
|
||||
Atom type_ret;
|
||||
int fmt_ret;
|
||||
unsigned long nitems_ret;
|
||||
unsigned long bytes_after_ret;
|
||||
unsigned char *data;
|
||||
int tmp;
|
||||
|
||||
if (count <= 0)
|
||||
tmp = 0xffffff;
|
||||
else
|
||||
tmp = count;
|
||||
|
||||
if (XGetWindowProperty(dpy, window, hint, 0, tmp, False, type,
|
||||
&type_ret, &fmt_ret, &nitems_ret, &bytes_after_ret,
|
||||
(unsigned char **)&data) != Success || !data)
|
||||
return NULL;
|
||||
|
||||
if ((type != AnyPropertyType && type != type_ret)
|
||||
|| (count > 0 && nitems_ret != count)
|
||||
|| (format != 0 && format != fmt_ret)) {
|
||||
XFree(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (retCount)
|
||||
*retCount = nitems_ret;
|
||||
|
||||
return data;
|
||||
return wm_backend->prop_get_check_property((WNativeWindow)window,
|
||||
(unsigned long)hint, (unsigned long)type, format, count, retCount);
|
||||
}
|
||||
|
||||
|
||||
void PropSetWMakerProtocols(Window root)
|
||||
{
|
||||
Atom protocols[3];
|
||||
int count = 0;
|
||||
|
||||
|
||||
protocols[count++] = w_global.atom.wmaker.menu;
|
||||
protocols[count++] = w_global.atom.wmaker.wm_function;
|
||||
protocols[count++] = w_global.atom.wmaker.noticeboard;
|
||||
|
||||
XChangeProperty(dpy, root, w_global.atom.wmaker.wm_protocols, WA_ATOM,
|
||||
32, PropModeReplace, (unsigned char *)protocols, count);
|
||||
wm_backend->prop_set_wmaker_protocols((WNativeWindow)root);
|
||||
}
|
||||
|
||||
void PropSetIconTileHint(WScreen * scr, RImage * image)
|
||||
{
|
||||
static Atom imageAtom = 0;
|
||||
unsigned char *tmp;
|
||||
int x, y;
|
||||
|
||||
|
||||
if (scr->info_window == None)
|
||||
return;
|
||||
|
||||
if (!imageAtom) {
|
||||
/*
|
||||
* WIDTH, HEIGHT (16 bits, MSB First)
|
||||
* array of R,G,B,A bytes
|
||||
*/
|
||||
imageAtom = XInternAtom(dpy, "_RGBA_IMAGE", False);
|
||||
}
|
||||
|
||||
tmp = malloc(image->width * image->height * 4 + 4);
|
||||
if (!tmp) {
|
||||
wwarning("could not allocate memory to set _WINDOWMAKER_ICON_TILE hint");
|
||||
return;
|
||||
}
|
||||
|
||||
tmp[0] = image->width >> 8;
|
||||
tmp[1] = image->width & 0xff;
|
||||
tmp[2] = image->height >> 8;
|
||||
tmp[3] = image->height & 0xff;
|
||||
|
||||
if (image->format == RRGBAFormat) {
|
||||
memcpy(&tmp[4], image->data, image->width * image->height * 4);
|
||||
} else {
|
||||
char *ptr = (char *)(tmp + 4);
|
||||
char *src = (char *)image->data;
|
||||
|
||||
for (y = 0; y < image->height; y++) {
|
||||
for (x = 0; x < image->width; x++) {
|
||||
*ptr++ = *src++;
|
||||
*ptr++ = *src++;
|
||||
*ptr++ = *src++;
|
||||
*ptr++ = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XChangeProperty(dpy, scr->info_window, w_global.atom.wmaker.icon_tile,
|
||||
imageAtom, 8, PropModeReplace, tmp, image->width * image->height * 4 + 4);
|
||||
wfree(tmp);
|
||||
|
||||
wm_backend->prop_set_icon_tile(scr, image);
|
||||
}
|
||||
|
||||
Window PropGetClientLeader(Window window)
|
||||
{
|
||||
Window *win;
|
||||
Window leader;
|
||||
|
||||
win = (Window *) PropGetCheckProperty(window, w_global.atom.wm.client_leader, WA_WINDOW, 32, 1, NULL);
|
||||
|
||||
if (!win)
|
||||
return None;
|
||||
|
||||
leader = (Window) * win;
|
||||
XFree(win);
|
||||
|
||||
return leader;
|
||||
return (Window)wm_backend->prop_get_client_leader((WNativeWindow)window);
|
||||
}
|
||||
|
||||
int PropGetWindowState(Window window)
|
||||
{
|
||||
long *data;
|
||||
long state;
|
||||
|
||||
data = (long *)PropGetCheckProperty(window, w_global.atom.wm.state,
|
||||
w_global.atom.wm.state, 32, 1, NULL);
|
||||
|
||||
if (!data)
|
||||
return -1;
|
||||
|
||||
state = *data;
|
||||
XFree(data);
|
||||
|
||||
return state;
|
||||
return wm_backend->prop_get_window_state((WNativeWindow)window);
|
||||
}
|
||||
|
||||
void PropCleanUp(Window root)
|
||||
{
|
||||
|
||||
XDeleteProperty(dpy, root, w_global.atom.wmaker.wm_protocols);
|
||||
XDeleteProperty(dpy, root, w_global.atom.wmaker.noticeboard);
|
||||
XDeleteProperty(dpy, root, WA_WM_ICON_SIZE);
|
||||
wm_backend->prop_cleanup((WNativeWindow)root);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@
|
|||
#include "shutdown.h"
|
||||
|
||||
|
||||
static void restoreWindows(WMBag *bag, WMBagIterator iter);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
|
|
@ -109,42 +108,6 @@ void Shutdown(WShutdownMode mode)
|
|||
}
|
||||
}
|
||||
|
||||
static void restoreWindows(WMBag * bag, WMBagIterator iter)
|
||||
{
|
||||
WCoreWindow *next;
|
||||
WCoreWindow *core;
|
||||
WWindow *wwin;
|
||||
|
||||
if (iter == NULL) {
|
||||
core = WMBagFirst(bag, &iter);
|
||||
} else {
|
||||
core = WMBagNext(bag, &iter);
|
||||
}
|
||||
|
||||
if (core == NULL)
|
||||
return;
|
||||
|
||||
restoreWindows(bag, iter);
|
||||
|
||||
/* go to the end of the list */
|
||||
while (core->stacking->under)
|
||||
core = core->stacking->under;
|
||||
|
||||
while (core) {
|
||||
next = core->stacking->above;
|
||||
|
||||
if (core->descriptor.parent_type == WCLASS_WINDOW) {
|
||||
Window window;
|
||||
|
||||
wwin = core->descriptor.parent;
|
||||
window = wwin->client_win;
|
||||
wUnmanageWindow(wwin, !wwin->flags.internal_window, False);
|
||||
XMapWindow(dpy, window);
|
||||
}
|
||||
core = next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
* RestoreDesktop--
|
||||
|
|
@ -159,51 +122,10 @@ static void restoreWindows(WMBag * bag, WMBagIterator iter)
|
|||
*/
|
||||
void RestoreDesktop(WScreen * scr)
|
||||
{
|
||||
|
||||
if (scr->helper_pid > 0) {
|
||||
kill(scr->helper_pid, SIGTERM);
|
||||
scr->helper_pid = 0;
|
||||
}
|
||||
|
||||
XGrabServer(dpy);
|
||||
wDestroyInspectorPanels();
|
||||
|
||||
/* reparent windows back to the root window, keeping the stacking order */
|
||||
restoreWindows(scr->stacking_list, NULL);
|
||||
|
||||
XUngrabServer(dpy);
|
||||
XSetInputFocus(dpy, PointerRoot, RevertToParent, CurrentTime);
|
||||
wm_backend->colormap_install(scr, NULL);
|
||||
wm_backend->prop_cleanup((WNativeWindow)scr->root_win);
|
||||
wm_backend->netwm_cleanup(scr);
|
||||
XSync(dpy, 0);
|
||||
wm_backend->restore_desktop(scr);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
* wipeDesktop--
|
||||
* Kills all windows in a screen. Send DeleteWindow to all windows
|
||||
* that support it and KillClient on all windows that don't.
|
||||
*
|
||||
* Side effects:
|
||||
* All managed windows are closed.
|
||||
*
|
||||
* TODO: change to XQueryTree()
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
void wWipeDesktop(WScreen * scr)
|
||||
{
|
||||
WWindow *wwin;
|
||||
|
||||
|
||||
wwin = scr->focused_window;
|
||||
while (wwin) {
|
||||
if (wwin->protocols.DELETE_WINDOW)
|
||||
wClientSendProtocol(wwin, w_global.atom.wm.delete_window,
|
||||
w_global.timestamp.last_event);
|
||||
else
|
||||
wClientKill(wwin);
|
||||
wwin = wwin->prev;
|
||||
}
|
||||
XSync(dpy, False);
|
||||
wm_backend->wipe_desktop(scr);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue