+
+
+void BScreen::addStrut(Strut *strut) {
+ strutList.push_back(strut);
+}
+
+
+void BScreen::removeStrut(Strut *strut) {
+ strutList.remove(strut);
+}
+
+
+const Rect& BScreen::availableArea(void) const {
+ if (doFullMax())
+ return getRect(); // return the full screen
+ return usableArea;
+}
+
+
+void BScreen::updateAvailableArea(void) {
+ Rect old_area = usableArea;
+ usableArea = getRect(); // reset to full screen
+
+ /* these values represent offsets from the screen edge
+ * we look for the biggest offset on each edge and then apply them
+ * all at once
+ * do not be confused by the similarity to the names of Rect's members
+ */
+ unsigned int current_left = 0, current_right = 0, current_top = 0,
+ current_bottom = 0;
+
+ StrutList::const_iterator it = strutList.begin(), end = strutList.end();
+
+ for(; it != end; ++it) {
+ Strut *strut = *it;
+ if (strut->left > current_left)
+ current_left = strut->left;
+ if (strut->top > current_top)
+ current_top = strut->top;
+ if (strut->right > current_right)
+ current_right = strut->right;
+ if (strut->bottom > current_bottom)
+ current_bottom = strut->bottom;
+ }
+
+ usableArea.setPos(current_left, current_top);
+ usableArea.setSize(usableArea.width() - (current_left + current_right),
+ usableArea.height() - (current_top + current_bottom));
+
+ if (old_area != usableArea) {
+ BlackboxWindowList::iterator it = windowList.begin(),
+ end = windowList.end();
+ for (; it != end; ++it)
+ if ((*it)->isMaximized()) (*it)->remaximize();
+ }
+
+ updateWorkArea();
+}
+
+
+Workspace* BScreen::getWorkspace(unsigned int index) {
+ assert(index < workspacesList.size());
+ return workspacesList[index];
+}
+
+
+void BScreen::buttonPressEvent(XButtonEvent *xbutton) {
+ if (xbutton->button == 1) {
+ if (! isRootColormapInstalled())
+ image_control->installRootColormap();
+
+ if (workspacemenu->isVisible())
+ workspacemenu->hide();
+
+ if (rootmenu->isVisible())
+ rootmenu->hide();
+ } else if (xbutton->button == 2) {
+ int mx = xbutton->x_root - (workspacemenu->getWidth() / 2);
+ int my = xbutton->y_root - (workspacemenu->getTitleHeight() / 2);
+
+ if (mx < 0) mx = 0;
+ if (my < 0) my = 0;
+
+ if (mx + workspacemenu->getWidth() > getWidth())
+ mx = getWidth() - workspacemenu->getWidth() - getBorderWidth();
+
+ if (my + workspacemenu->getHeight() > getHeight())
+ my = getHeight() - workspacemenu->getHeight() - getBorderWidth();
+
+ workspacemenu->move(mx, my);
+
+ if (! workspacemenu->isVisible()) {
+ workspacemenu->removeParent();
+ workspacemenu->show();
+ }
+ } else if (xbutton->button == 3) {
+ int mx = xbutton->x_root - (rootmenu->getWidth() / 2);
+ int my = xbutton->y_root - (rootmenu->getTitleHeight() / 2);
+
+ if (mx < 0) mx = 0;
+ if (my < 0) my = 0;
+
+ if (mx + rootmenu->getWidth() > getWidth())
+ mx = getWidth() - rootmenu->getWidth() - getBorderWidth();
+
+ if (my + rootmenu->getHeight() > getHeight())
+ my = getHeight() - rootmenu->getHeight() - getBorderWidth();
+
+ rootmenu->move(mx, my);
+
+ if (! rootmenu->isVisible()) {
+ blackbox->checkMenu();
+ rootmenu->show();
+ }
+ // mouse wheel up
+ } else if (xbutton->button == 4) {
+ if (getCurrentWorkspaceID() >= getWorkspaceCount() - 1)
+ changeWorkspaceID(0);
+ else
+ changeWorkspaceID(getCurrentWorkspaceID() + 1);
+ // mouse wheel down
+ } else if (xbutton->button == 5) {
+ if (getCurrentWorkspaceID() == 0)
+ changeWorkspaceID(getWorkspaceCount() - 1);
+ else
+ changeWorkspaceID(getCurrentWorkspaceID() - 1);
+ }
+}
+
+
+void BScreen::toggleFocusModel(FocusModel model) {
+ if (model == SloppyFocus) {
+ saveSloppyFocus(True);
+ } else {
+ saveSloppyFocus(False);
+ saveAutoRaise(False);
+ saveClickRaise(False);
+ }
+
+ updateFocusModel();
+}
+
+
+void BScreen::updateFocusModel()
+{
+ std::for_each(workspacesList.begin(), workspacesList.end(),
+ std::mem_fun(&Workspace::updateFocusModel));
+}
+
+
+BTexture BScreen::readDatabaseTexture(const string &rname,
+ const string &default_color,
+ Configuration &style) {
+ BTexture texture;
+ string s;
+
+ if (style.getValue(rname, s))
+ texture = BTexture(s);
+ else
+ texture.setTexture(BTexture::Solid | BTexture::Flat);
+
+ // associate this texture with this screen
+ texture.setDisplay(getBaseDisplay(), getScreenNumber());
+ texture.setImageControl(image_control);
+
+ if (texture.texture() & BTexture::Solid) {
+ texture.setColor(readDatabaseColor(rname + ".color",
+ default_color, style));
+ texture.setColorTo(readDatabaseColor(rname + ".colorTo",
+ default_color, style));
+ } else if (texture.texture() & BTexture::Gradient) {
+ texture.setColor(readDatabaseColor(rname + ".color",
+ default_color, style));
+ texture.setColorTo(readDatabaseColor(rname + ".colorTo",
+ default_color, style));
+ }
+
+ return texture;
+}
+
+
+BColor BScreen::readDatabaseColor(const string &rname,
+ const string &default_color,
+ Configuration &style) {
+ BColor color;
+ string s;
+ if (style.getValue(rname, s))
+ color = BColor(s, getBaseDisplay(), getScreenNumber());
+ else
+ color = BColor(default_color, getBaseDisplay(), getScreenNumber());
+ return color;
+}
+
+
+XFontSet BScreen::readDatabaseFontSet(const string &rname,
+ Configuration &style) {
+ char *defaultFont = "fixed";
+
+ bool load_default = True;
+ string s;
+ XFontSet fontset = 0;
+ if (style.getValue(rname, s) && (fontset = createFontSet(s)))
+ load_default = False;
+
+ if (load_default) {
+ fontset = createFontSet(defaultFont);
+
+ if (! fontset) {
+ fprintf(stderr,
+ i18n(ScreenSet, ScreenDefaultFontLoadFail,
+ "BScreen::setCurrentStyle(): couldn't load default font.\n"));
+ exit(2);
+ }
+ }
+
+ return fontset;
+}
+
+
+XFontStruct *BScreen::readDatabaseFont(const string &rname,
+ Configuration &style) {
+ char *defaultFont = "fixed";
+
+ bool load_default = False;
+ string s;
+ XFontStruct *font = 0;
+ if (style.getValue(rname, s)) {
+ if ((font = XLoadQueryFont(blackbox->getXDisplay(), s.c_str())) == NULL) {
+ fprintf(stderr,
+ i18n(ScreenSet, ScreenFontLoadFail,
+ "BScreen::setCurrentStyle(): couldn't load font '%s'\n"),
+ s.c_str());
+
+ load_default = True;
+ }
+ } else {
+ load_default = True;
+ }
+
+ if (load_default) {
+ font = XLoadQueryFont(blackbox->getXDisplay(), defaultFont);
+ if (font == NULL) {
+ fprintf(stderr,
+ i18n(ScreenSet, ScreenDefaultFontLoadFail,
+ "BScreen::setCurrentStyle(): couldn't load default font.\n"));
+ exit(2);
+ }
+ }
+
+ return font;
+}
+
+
+#ifndef HAVE_STRCASESTR
+static const char * strcasestr(const char *str, const char *ptn) {
+ const char *s2, *p2;
+ for(; *str; str++) {
+ for(s2=str,p2=ptn; ; s2++,p2++) {
+ if (! *p2) return str;
+ if (toupper(*s2) != toupper(*p2)) break;
+ }
+ }
+ return NULL;
+}
+#endif // HAVE_STRCASESTR
+
+
+static const char *getFontElement(const char *pattern, char *buf,
+ int bufsiz, ...) {
+ const char *p, *v;
+ char *p2;
+ va_list va;
+
+ va_start(va, bufsiz);
+ buf[bufsiz-1] = 0;
+ buf[bufsiz-2] = '*';
+ while((v = va_arg(va, char *)) != NULL) {
+ p = strcasestr(pattern, v);
+ if (p) {
+ strncpy(buf, p+1, bufsiz-2);
+ p2 = strchr(buf, '-');
+ if (p2) *p2=0;
+ va_end(va);
+ return p;
+ }
+ }
+ va_end(va);
+ strncpy(buf, "*", bufsiz);
+ return NULL;
+}
+
+
+static const char *getFontSize(const char *pattern, int *size) {
+ const char *p;
+ const char *p2=NULL;
+ int n=0;
+
+ for (p=pattern; 1; p++) {
+ if (! *p) {
+ if (p2!=NULL && n>1 && n<72) {
+ *size = n; return p2+1;
+ } else {
+ *size = 16; return NULL;
+ }
+ } else if (*p=='-') {
+ if (n>1 && n<72 && p2!=NULL) {
+ *size = n;
+ return p2+1;
+ }
+ p2=p; n=0;
+ } else if (*p>='0' && *p<='9' && p2!=NULL) {
+ n *= 10;
+ n += *p-'0';
+ } else {
+ p2=NULL; n=0;
+ }
+ }
+}
+
+
+XFontSet BScreen::createFontSet(const string &fontname) {
+ XFontSet fs;
+ char **missing, *def = "-";
+ int nmissing, pixel_size = 0, buf_size = 0;
+ char weight[FONT_ELEMENT_SIZE], slant[FONT_ELEMENT_SIZE];
+
+ fs = XCreateFontSet(blackbox->getXDisplay(),
+ fontname.c_str(), &missing, &nmissing, &def);
+ if (fs && (! nmissing))
+ return fs;
+
+ const char *nfontname = fontname.c_str();
+#ifdef HAVE_SETLOCALE
+ if (! fs) {
+ if (nmissing) XFreeStringList(missing);
+
+ setlocale(LC_CTYPE, "C");
+ fs = XCreateFontSet(blackbox->getXDisplay(), fontname.c_str(),
+ &missing, &nmissing, &def);
+ setlocale(LC_CTYPE, "");
+ }
+#endif // HAVE_SETLOCALE
+
+ if (fs) {
+ XFontStruct **fontstructs;
+ char **fontnames;
+ XFontsOfFontSet(fs, &fontstructs, &fontnames);
+ nfontname = fontnames[0];
+ }
+
+ getFontElement(nfontname, weight, FONT_ELEMENT_SIZE,
+ "-medium-", "-bold-", "-demibold-", "-regular-", NULL);
+ getFontElement(nfontname, slant, FONT_ELEMENT_SIZE,
+ "-r-", "-i-", "-o-", "-ri-", "-ro-", NULL);
+ getFontSize(nfontname, &pixel_size);
+
+ if (! strcmp(weight, "*"))
+ strncpy(weight, "medium", FONT_ELEMENT_SIZE);
+ if (! strcmp(slant, "*"))
+ strncpy(slant, "r", FONT_ELEMENT_SIZE);
+ if (pixel_size < 3)
+ pixel_size = 3;
+ else if (pixel_size > 97)
+ pixel_size = 97;
+
+ buf_size = strlen(nfontname) + (FONT_ELEMENT_SIZE * 2) + 64;
+ char *pattern2 = new char[buf_size];
+ sprintf(pattern2,
+ "%s,"
+ "-*-*-%s-%s-*-*-%d-*-*-*-*-*-*-*,"
+ "-*-*-*-*-*-*-%d-*-*-*-*-*-*-*,*",
+ nfontname, weight, slant, pixel_size, pixel_size);
+ nfontname = pattern2;
+
+ if (nmissing)
+ XFreeStringList(missing);
+ if (fs)
+ XFreeFontSet(blackbox->getXDisplay(), fs);
+
+ fs = XCreateFontSet(blackbox->getXDisplay(), nfontname, &missing,
+ &nmissing, &def);
+
+ delete [] pattern2;
+
+ return fs;
+}