#include "Border.h"
#include "Client.h"
#include "Manager.h"
GC Border::m_drawGC;
unsigned long Border::m_frameBackgroundPixel = 0;
unsigned long Border::m_buttonBackgroundPixel;
unsigned long Border::m_borderPixel;
declareList(RectangleList, XRectangle);
implementList(RectangleList, XRectangle);
class BorderRectangleList : public RectangleList {
public:
BorderRectangleList() { }
~BorderRectangleList() { }
void appendRect(int x, int y, int w, int h);
};
void BorderRectangleList::appendRect(int x, int y, int w, int h) {
XRectangle r;
r.x = x;
r.y = y;
r.width = w;
r.height = h;
append(r);
}
Border::Border(Client *const c, Window child) : m_client(c), m_parent(0), m_tab(0), m_child(child), m_hideButton(0), m_closeButton(0), m_label(0), m_hideButtonGtk(0), m_closeButtonGtk(0), m_tabGtk(0), m_labelGtk(0), m_gdkwindow(0) {
m_parent = root();
if (m_frameBackgroundPixel == 0) {
m_frameBackgroundPixel = windowManager()->allocateColour(frame_bg, "frame background");
m_buttonBackgroundPixel = windowManager()->allocateColour(button_bg, "button background");
m_borderPixel = windowManager()->allocateColour(border_fg, "border");
m_drawGC = DefaultGC(display(), DefaultScreen(display()));
}
}
Border::~Border() {
if (m_parent != root()) {
if (!m_parent) fprintf(stderr,"wmG: zero parent in Border::~Border\n");
else {
XDestroyWindow(display(), m_tab);
gtk_widget_destroy(m_labelGtk);
gtk_widget_destroy(m_tabGtk);
XDestroyWindow(display(), m_hideButton);
// gtk_widget_destroy(m_hideButtonGtk);
XDestroyWindow(display(), m_closeButton);
// gtk_widget_destroy(m_closeButtonGtk);
XDestroyWindow(display(), m_parent);
}
}
}
void Border::fatal(char *s) {
windowManager()->fatal(s);
}
Display *Border::display() {
return m_client->display();
}
WindowManager *Border::windowManager() {
return m_client->windowManager();
}
Window Border::root() {
return m_client->root();
}
void Border::expose(XExposeEvent *e) {
if (e->window != m_tab) return;
drawLabel();
}
void Border::drawLabel() {
m_label = m_client->m_label;
if (m_label) {
gtk_label_set_text(GTK_LABEL(m_labelGtk), m_label);
// gtk_widget_draw_default(m_labelGtk);
}
}
Boolean Border::isTransient(void) {
return m_client->isTransient();
}
Boolean Border::isFixedSize(void) {
return m_client->isFixedSize();
}
void Border::shapeParent(int w, int h) {
XRectangle r;
r.x = 0;
r.y = 0;
r.width = w + frame_size * 2;
r.height = h + 20 + frame_size * 2;
XShapeCombineRectangles(display(), m_parent, ShapeBounding, 0, 0, &r, 1, ShapeSet, YXBanded);
r.x = xIndent();
r.y = yIndent();
r.width = w;
r.height = h;
XShapeCombineRectangles(display(), m_parent, ShapeClip, 0, 0, &r, 1, ShapeSet, YXBanded);
}
void Border::shapeTab(int w, int) {
XRectangle r;
r.x = 0;
r.y = 0;
r.width = w;
r.height = title_size;
XShapeCombineRectangles(display(), m_tab, ShapeBounding, 0, 0, &r, 1, ShapeSet, YXBanded);
r.x = 1;
r.y = 1;
r.width = w - 2;
r.height = title_size - 2;
XShapeCombineRectangles(display(), m_tab, ShapeClip, 0, 0, &r, 1, ShapeSet, YXBanded);
r.x = r.y = 0;
r.width = r.height = title_size - 4;
XShapeCombineRectangles(display(), m_hideButton, ShapeBounding, 0, 0, &r, 1, ShapeSet, YXBanded);
r.x = r.y = 1;
r.width = r.height = title_size - 6;
XShapeCombineRectangles(display(), m_hideButton, ShapeClip, 0, 0, &r, 1, ShapeSet, YXBanded);
r.x = r.y = 0;
r.width = r.height = title_size - 4;
XShapeCombineRectangles(display(), m_closeButton, ShapeBounding, 0, 0, &r, 1, ShapeSet, YXBanded);
r.x = r.y = 1;
r.width = r.height = title_size - 6;
XShapeCombineRectangles(display(), m_closeButton, ShapeClip, 0, 0, &r, 1, ShapeSet, YXBanded);
}
void Border::configure(int x, int y, int w, int h, unsigned long mask, int detail, Boolean active, Boolean onlyActivate) {
if(!m_parent || m_parent == root()) {
m_parent = XCreateSimpleWindow(display(), root(), 1, 1, 1, 1, 0, m_borderPixel, m_frameBackgroundPixel);
// m_tab = XCreateSimpleWindow(display(), m_parent, 1, 1, 1, 1, 0, m_borderPixel, m_frameBackgroundPixel);
m_tabGtk = gtk_plug_new(m_parent);
// gtk_window_set_policy(GTK_WINDOW(m_tabGtk), true, true, false);
gtk_widget_show(m_tabGtk);
m_labelGtk = gtk_label_new(m_label);
gtk_widget_show(m_labelGtk);
gtk_container_add(GTK_CONTAINER(m_tabGtk), m_labelGtk);
m_hideButton = XCreateSimpleWindow(display(), m_parent, 1, 1, 1, 1, 0, m_borderPixel, m_buttonBackgroundPixel);
// m_hideButtonGtk = gtk_window_new(GTK_WINDOW_TOPLEVEL);
// gtk_widget_show(m_hideButtonGtk);
m_closeButton = XCreateSimpleWindow(display(), m_parent, 1, 1, 1, 1, 0, m_borderPixel, m_buttonBackgroundPixel);
// m_closeButtonGtk = gtk_window_new(GTK_WINDOW_TOPLEVEL);
// gtk_widget_show(m_closeButtonGtk);
m_tab = GTK_XWINDOW(m_tabGtk);
XReparentWindow(display(), m_tab, m_parent, frame_size, frame_size);
}
shapeTab(w, h);
drawLabel();
XMapWindow(display(), m_tab);
XSelectInput(display(), m_parent, SubstructureRedirectMask | SubstructureNotifyMask | ButtonPressMask | ButtonReleaseMask);
XSelectInput(display(), m_tab, ExposureMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask);
XSelectInput(display(), m_hideButton, ButtonPressMask | ButtonReleaseMask);
XSelectInput(display(), m_closeButton, ButtonPressMask | ButtonReleaseMask);
gtk_widget_set_state(m_labelGtk, (active == True ? GTK_STATE_SELECTED : GTK_STATE_NORMAL));
gtk_widget_set_state(m_tabGtk, (active == True ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL));
mask |= CWX | CWY | CWWidth | CWHeight | CWBorderWidth;
gtk_widget_set_usize(m_labelGtk, w - 2, title_size - 2);
gtk_widget_set_usize(m_tabGtk, w - 2, title_size - 2);
// gtk_widget_set_usize(m_hideButtonGtk, title_size - 4, title_size - 4);
// gtk_widget_set_usize(m_closeButtonGtk, title_size - 4, title_size - 4);
XWindowChanges wc;
wc.x = x - (m_client->m_hasBorder ? xIndent() : 0);
wc.y = y - (m_client->m_hasBorder ? yIndent() : (yIndent() - frame_size));
wc.width = w + (m_client->m_hasBorder ? frame_size * 2 : 0);
wc.height = h + (m_client->m_hasBorder ? (yIndent() + frame_size) : (yIndent() - frame_size));
wc.border_width = 0;
wc.sibling = None;
wc.stack_mode = detail;
XConfigureWindow(display(), m_parent, mask, &wc);
unsigned long rmask = 0L;
if (mask & CWWidth) rmask |= CWX;
if (mask & CWHeight) rmask |= CWY;
wc.x = frame_size;
wc.y = frame_size;
wc.height = title_size;
wc.width = w;
XConfigureWindow(display(), m_tab, mask, &wc);
shapeTab(w, h);
wc.x = w - (title_size - 4);
wc.y = frame_size + 2;
wc.width = wc.height = title_size - 4;
XConfigureWindow(display(), m_closeButton, mask, &wc);
wc.x = w - ((title_size - 4) * 2) - 1;
wc.y = frame_size + 2;
wc.width = wc.height = title_size - 4;
XConfigureWindow(display(), m_hideButton, mask, &wc);
if(m_gdkwindow != 0)
gtk_widget_set_parent_window(m_tabGtk, m_gdkwindow);
// reparent();
XMoveResizeWindow(display(), m_client->m_window, xIndent(), yIndent(), m_client->m_w, m_client->m_h);
// gtk_widget_draw_default(m_labelGtk);
if(m_gdkwindow != 0)
m_gdkwindow = gdk_window_foreign_new(m_tab);
}
void Border::moveTo(int x, int y) {
XWindowChanges wc;
wc.x = x - xIndent();
wc.y = y - yIndent();
XConfigureWindow(display(), m_parent, CWX | CWY, &wc);
// gtk_widget_draw_default(m_labelGtk);
}
void Border::map() {
if (m_parent == root()) {
fprintf(stderr, "wmG: bad parent in Border::map()\n");
} else {
XMapWindow(display(), m_parent);
if (m_client->m_hasTitle == True) {
XMapWindow(display(), m_tab);
// gtk_widget_draw_default(m_labelGtk);
XMapWindow(display(), m_hideButton);
XMapWindow(display(), m_closeButton);
}
}
}
void Border::mapRaised() {
if (m_parent == root()) {
fprintf(stderr, "wmG: bad parent in Border::mapRaised()\n");
} else {
XMapRaised(display(), m_parent);
if (m_client->m_hasTitle == True) {
XMapWindow(display(), m_tab);
XMapRaised(display(), GTK_XWINDOW(m_tabGtk));
// gtk_widget_draw_default(m_labelGtk);
XMapRaised(display(), m_hideButton);
XMapRaised(display(), m_closeButton);
}
}
}
void Border::lower() {
XLowerWindow(display(), m_parent);
}
void Border::unmap() {
if (m_parent == root()) {
fprintf(stderr, "wmG: bad parent in Border::unmap()\n");
} else {
XUnmapWindow(display(), m_parent);
if (m_client->m_hasTitle == True) {
XUnmapWindow(display(), m_tab);
XUnmapWindow(display(), m_hideButton);
XUnmapWindow(display(), m_closeButton);
}
}
}
void Border::reparent() {
XReparentWindow(display(), m_child, m_parent, xIndent(), yIndent());
}
syntax highlighted by Code2HTML, v. 0.9.1