#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()); }