sapphire-0.15.8/0040755000175000001440000000000007414171012011743 5ustar asuserssapphire-0.15.8/ChangeLog0100644000175000001440000000075007414167047013531 0ustar asusers0.15.8 (31 Dec 2001) * Added a patch from Chris Boyle fixes some bugs and it will now compile with gcc 3.x 0.15.7 (3 Nov 2001) * fixed compile warnings * updated linked list code * Got rid of autoconf generated makefile. Going back to basics! * changes to README, HISTORY files * tweaked client list cleanup in window manager destructor * clean ups in windowmanager and client code FOCUS ON THE FUTURE IS CODE CLEANUP AND BETTER MORE EFFICIENT CODE sapphire-0.15.8/Makefile0100644000175000001440000000307007414170543013410 0ustar asusers# Sapphire Makefile # # frankhale@yahoo.com # 27 Oct 2001 CC = g++ CFLAGS = -g -O2 -Wall prefix = /usr XROOT = $(prefix)/X11R6 DESTDIR = INCLUDES = -I$(XROOT)/include LDPATH = -L$(XROOT)/lib LIBS = -lXext -lX11 # If you change this, remember to change it in windowmanager.cc (line 34), # and in data/menu/default (lines 43-47, the themes section). CONFIGURATION_PATH=/usr/share/sapphire # DEBUG = Outputs debug information DEFINES = #-DDEBUG HEADERS = linkedlist.hh \ basemenu.hh \ rootmenu.hh \ iconmenu.hh \ menulex.hh \ scanner.hh \ theme.hh \ toolbar.hh \ image.hh \ windowmanager.hh \ client.hh \ sapphire.hh OBJS = linkedlist.o \ basemenu.o \ rootmenu.o \ iconmenu.o \ menulex.o \ scanner.o \ theme.o \ toolbar.o \ image.o \ windowmanager.o \ client.o \ misc.o \ main.o all: sapphire sapphire: $(OBJS) $(CC) $(OBJS) $(LDPATH) $(LIBS) -o $@ $(OBJS): %.o: %.cc $(HEADERS) $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -c $< -o $@ install: all install -s sapphire $(DESTDIR)$(prefix)/bin/ install -d $(DESTDIR)$(CONFIGURATION_PATH)/ install -d $(DESTDIR)$(CONFIGURATION_PATH)/themes/ install -m 644 data/themes/* $(DESTDIR)$(CONFIGURATION_PATH)/themes/ install -d $(DESTDIR)$(CONFIGURATION_PATH)/menu/ install -m 644 data/menu/* $(DESTDIR)$(CONFIGURATION_PATH)/menu/ uninstall: rm $(DESTDIR)$(prefix)/bin/sapphire rm -rf $(DESTDIR)$(CONFIGURATION_PATH) clean: rm -f sapphire $(OBJS) core .PHONY: all install clean sapphire-0.15.8/basemenu.cc0100644000175000001440000006332307371023050014055 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "sapphire.hh" BaseMenu::BaseMenu() { menu_pix=None; select_pix=None; title_pix=None; select_gc = None; menu_gc = None; back_gc = None; mi = new LinkedList; menu.menuTitle="Sapphire Menu"; menu.hasTitle=False; bottom_edge=False; right_edge=False; counter=0; extra_width=0; font = XLoadQueryFont(wm->getDisplay(), wm->getTheme()->getMenuFont()); create_mask = CWBackPixmap | CWBackPixel | CWBorderPixel | CWOverrideRedirect | CWEventMask; attrib.background_pixmap = None; attrib.background_pixel = wm->getBackgroundColor().pixel; attrib.border_pixel = wm->getBorderColor().pixel; attrib.override_redirect = True; attrib.event_mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ExposureMask | EnterWindowMask | LeaveWindowMask; //gv.background = wm->getBackgroundColor().pixel; //select_gc = XCreateGC(wm->getDisplay(), wm->getRootWindow(), GCTile , &gv); //back_gc = XCreateGC(wm->getDisplay(), wm->getRootWindow(), GCTile, &gv); menu.x = 1; menu.y = 1; menu.x_move = 1; menu.y_move = 1; menu.height=1; menu.width=1; menu.total_item_height=1; item_width = menu.width; item_height = font->ascent + font->descent + 8; menu.window = XCreateWindow(wm->getDisplay(), wm->getRootWindow(), menu.x, menu.y, menu.width, menu.height, 1, DefaultDepth(wm->getDisplay(), wm->getScreen()), InputOutput, DefaultVisual(wm->getDisplay(), wm->getScreen()), create_mask, &attrib); menu.title = XCreateWindow(wm->getDisplay(), menu.window, 0, 0, menu.width, item_height, 0, DefaultDepth(wm->getDisplay(), wm->getScreen()), InputOutput, DefaultVisual(wm->getDisplay(), wm->getScreen()), create_mask, &attrib); menu.item_window = XCreateWindow(wm->getDisplay(), menu.window, 0, item_height - 2, menu.width, menu.height-item_height, 0, DefaultDepth(wm->getDisplay(), wm->getScreen()), InputOutput, DefaultVisual(wm->getDisplay(), wm->getScreen()), create_mask, &attrib); curs = XDefineCursor(wm->getDisplay(), menu.window, XCreateFontCursor(wm->getDisplay(), XC_left_ptr)); menu.isVisible = False; curr = new BaseMenuItem(); curr = None; enterOnce = True; } BaseMenu::~BaseMenu() { mi->removeAll(); XDestroyWindow(wm->getDisplay(), menu.title); XDestroyWindow(wm->getDisplay(), menu.item_window); XDestroyWindow(wm->getDisplay(), menu.window); XFreeGC(wm->getDisplay(), menu_gc); XFreeGC(wm->getDisplay(), select_gc); XFreeGC(wm->getDisplay(), back_gc); wm->getImageControl()->removeImage(title_pix); wm->getImageControl()->removeImage(menu_pix); wm->getImageControl()->removeImage(select_pix); wm->getImageControl()->removeImage(menufont_pix); delete mi; delete curr; } // This updates all graphics contexts, gradient pixmaps and determines placement of all menu items. void BaseMenu::update_all() { LinkedListIterator it(mi); int temp_width=0; int temp_ascent=0; int temp_descent=0; unsigned int count=0; unsigned int char_count=0; menu.total_item_height=1; // If menu is created with no items lets make a few defaults // so things work out nice. if (mi->count() == 0) { char_count = strlen(menu.menuTitle); menu.width = XTextWidth(wm->getXFont(), menu.menuTitle, strlen(menu.menuTitle)); XTextExtents(font, menu.menuTitle , char_count, &direction, &ascent, &descent, &overall); temp_width = overall.width; temp_ascent = overall.ascent; temp_descent= overall.descent; menu.width = temp_width + 40; item_width = temp_ascent + temp_descent + 8; menu.height = item_height; menu.total_item_height = item_height+3; } else { //============================================================= for(; it.current(); it++) { char_count = strlen(it.current()->name); XTextExtents(font, it.current()->name , char_count, &direction, &ascent, &descent, &overall); if (char_count < strlen(menu.menuTitle)) { char_count = strlen(menu.menuTitle); XTextExtents(font, menu.menuTitle , char_count, &direction, &ascent, &descent, &overall); } if (char_count > count) { count = char_count; temp_width = overall.width; temp_ascent = overall.ascent; temp_descent= overall.descent; } menu.width = temp_width + 40; item_width = temp_ascent + temp_descent + 8; menu.height = item_height * mi->count(); it.current()->item_x = item_width/2+4; it.current()->item_y = item_height/2+4+menu.total_item_height; menu.total_item_height += item_height; } menu.total_item_height += item_height; } menu.width+=extra_width; setTitleVisible(menu.hasTitle); createMenuImage(); createMenuSelectImage(); createMenuTitleImage(); createMenuFontImage(); XClearWindow(wm->getDisplay(), menu.title); XClearWindow(wm->getDisplay(), menu.item_window); XGCValues gv; gv.tile = select_pix; select_gc = XCreateGC(wm->getDisplay(), wm->getRootWindow(), GCTile , &gv); XSetFillStyle(wm->getDisplay(), select_gc, FillTiled); gv.tile = menu_pix; back_gc = XCreateGC(wm->getDisplay(), wm->getRootWindow(), GCTile, &gv); XSetFillStyle(wm->getDisplay(), back_gc, FillTiled); gv.font = font->fid; gv.tile = menufont_pix; menu_gc = XCreateGC(wm->getDisplay(), wm->getRootWindow(), GCTile | GCFont, &gv); XSetFillStyle(wm->getDisplay(), menu_gc, FillTiled); testMenuEdgeDetect(this); if (menu.y + menu.height >= wm->getYRes()) { bottom_edge=True; }else { bottom_edge=False; } if(bottom_edge) { XMoveWindow(wm->getDisplay(), menu.window, menu.x, wm->getYRes() - menu.height - item_height - 4); } } // This updates all graphics contexts, gradient pixmaps and determines placement of all menu items. void BaseMenu::update_menu() { LinkedListIterator it(mi); int temp_width=0; int temp_ascent=0; int temp_descent=0; unsigned int count=0; unsigned int char_count=0; menu.total_item_height=1; // If menu is created with no items lets make a few defaults // so things work out nice. if (mi->count() == 0) { char_count = strlen(menu.menuTitle); menu.width = XTextWidth(wm->getXFont(), menu.menuTitle, strlen(menu.menuTitle)); XTextExtents(font, menu.menuTitle , char_count, &direction, &ascent, &descent, &overall); temp_width = overall.width; temp_ascent = overall.ascent; temp_descent= overall.descent; menu.width = temp_width + 40; item_width = temp_ascent + temp_descent + 8; menu.height = item_height; menu.total_item_height = item_height+3; } else { //============================================================= for(; it.current(); it++) { char_count = strlen(it.current()->name); XTextExtents(font, it.current()->name , char_count, &direction, &ascent, &descent, &overall); if (char_count < strlen(menu.menuTitle)) { char_count = strlen(menu.menuTitle); XTextExtents(font, menu.menuTitle , char_count, &direction, &ascent, &descent, &overall); } if (char_count > count) { count = char_count; temp_width = overall.width; temp_ascent = overall.ascent; temp_descent= overall.descent; } menu.width = temp_width + 40; item_width = temp_ascent + temp_descent + 8; menu.height = item_height * mi->count(); it.current()->item_x = item_width/2+4; it.current()->item_y = item_height/2+4+menu.total_item_height; menu.total_item_height += item_height; } menu.total_item_height += item_height; } menu.width+=extra_width; setTitleVisible(menu.hasTitle); } void BaseMenu::hide() { XUnmapWindow(wm->getDisplay(), menu.window); } void BaseMenu::setTitleVisible(bool s) { menu.hasTitle=s; if(menu.hasTitle) { XResizeWindow(wm->getDisplay(), menu.window, menu.width, menu.total_item_height); XResizeWindow(wm->getDisplay(), menu.title, menu.width, item_height); XMoveResizeWindow(wm->getDisplay(), menu.item_window, 0, item_height, menu.width, menu.total_item_height); } else { XResizeWindow(wm->getDisplay(), menu.window, menu.width, menu.total_item_height - item_height); XResizeWindow(wm->getDisplay(), menu.title, menu.width, item_height); XMoveResizeWindow(wm->getDisplay(), menu.item_window, 0, 0, menu.width, menu.total_item_height); } } void BaseMenu::reconfigure() { XGCValues gv; XFreeFont(wm->getDisplay(), font); font = XLoadQueryFont(wm->getDisplay(), wm->getTheme()->getMenuFont()); update_menu(); XFreePixmap(wm->getDisplay(), title_pix); XFreePixmap(wm->getDisplay(), menu_pix); XFreePixmap(wm->getDisplay(), select_pix); XFreePixmap(wm->getDisplay(), menufont_pix); createMenuImage(); createMenuSelectImage(); createMenuTitleImage(); createMenuFontImage(); XClearWindow(wm->getDisplay(), menu.title); XClearWindow(wm->getDisplay(), menu.item_window); XFreeGC(wm->getDisplay(), menu_gc); XFreeGC(wm->getDisplay(), select_gc); XFreeGC(wm->getDisplay(), back_gc); gv.tile = select_pix; select_gc = XCreateGC(wm->getDisplay(), wm->getRootWindow(), GCTile , &gv); XSetFillStyle(wm->getDisplay(), select_gc, FillTiled); gv.tile = menu_pix; back_gc = XCreateGC(wm->getDisplay(), wm->getRootWindow(), GCTile, &gv); XSetFillStyle(wm->getDisplay(), back_gc, FillTiled); gv.font = font->fid; gv.tile = menufont_pix; menu_gc = XCreateGC(wm->getDisplay(), wm->getRootWindow(), GCTile | GCFont, &gv); XSetFillStyle(wm->getDisplay(), menu_gc, FillTiled); redraw(); } // Redraws the entire contents of the menu. void BaseMenu::redraw() { //int text_width=0; // We need an Iterator for our menu items. This lets us traverse through // the list and paint each menu item. LinkedListIterator it(mi); for(; it.current(); it++) { if(strcmp(it.current()->name, "separator")==0) { XDrawLine(wm->getDisplay(), menu.item_window, menu_gc, it.current()->item_x - 14, it.current()->item_y-5, menu.width-1, it.current()->item_y-5); XDrawLine(wm->getDisplay(), menu.item_window, menu_gc, it.current()->item_x - 14, it.current()->item_y-6, menu.width-1, it.current()->item_y-6); } else { XDrawString(wm->getDisplay(), menu.item_window, menu_gc, it.current()->item_x, it.current()->item_y + 2, it.current()->name, strlen(it.current()->name)); if(it.current()->sub) { XDrawRectangle(wm->getDisplay(), menu.item_window, menu_gc, it.current()->item_x + menu.width - 35, it.current()->item_y - 7, 8, 8); } } // Draws a bounding box around each menu item. This helped me figure out the algorithm to test which item the // pointer was over. // //XDrawRectangle(wm->getDisplay(), menu.item_window, menu_gc, it.current()->item_x - 14, it.current()->item_y - 14, menu.width-1, it.current()->item_y + item_height - 15); } XDrawString(wm->getDisplay(), menu.title, menu_gc, 8, 16 , menu.menuTitle, strlen(menu.menuTitle)); //text_width=XTextWidth(wm->font, menu.menuTitle, strlen(menu.menuTitle)); //XDrawString(wm->getDisplay(), menu.title, menu_gc, // menu.width/2 - text_width/2, // 14 , // menu.menuTitle, strlen(menu.menuTitle)); } // Redraws a single menu item on the menu. void BaseMenu::redraw(BaseMenuItem *i) { if(strcmp(i->name, "separator")==0) { XDrawLine(wm->getDisplay(), menu.item_window, menu_gc, i->item_x - 14, i->item_y-5, menu.width-1, i->item_y-5); XDrawLine(wm->getDisplay(), menu.item_window, menu_gc, i->item_x - 14, i->item_y-6, menu.width-1, i->item_y-6); } else { XDrawString(wm->getDisplay(), menu.item_window, menu_gc, i->item_x, i->item_y + 2, i->name, strlen(i->name)); if(i->sub) { XDrawRectangle(wm->getDisplay(), menu.item_window, menu_gc, i->item_x + menu.width - 35, i->item_y - 7, 8, 8); } } // Draws a bounding box around each menu item. This helped me figure out the algorithm to test which item the // pointer was over. // //XDrawRectangle(wm->getDisplay(), menu.item_window, menu_gc, it.current()->item_x - 14, it.current()->item_y - 14, menu.width-1, it.current()->item_y + item_height - 15); } void BaseMenu::insert(char *n, BaseMenu *sub) { BaseMenuItem *item = new BaseMenuItem(); item->name = new char[strlen(n)+1]; strcpy(item->name, n); item->sub = sub; // defaults item->isSelected=False; item->exec = ""; item->function = 0; item->item_x = item->item_y = 0; mi->insert(item); } void BaseMenu::insert(char *n, char *exec, int func) { BaseMenuItem *item = new BaseMenuItem(); char *buffer = new char[100]; if (exec[0] == '~') { sprintf(buffer, "%s%s", getenv("HOME"), exec+1); strcpy(exec, buffer); } delete [] buffer; item->exec = new char[strlen(exec)+1]; strcpy(item->exec, exec); item->name = new char[strlen(n)+1]; strcpy(item->name, n); item->function = func; // defaults item->isSelected=False; item->sub = None; item->item_x = item->item_y = 0; mi->insert(item); } void BaseMenu::insert(char *n, char *exec, BaseMenu *sub, int func) { BaseMenuItem *item = new BaseMenuItem(); char *buffer = new char[100]; if (exec[0] == '~') { sprintf(buffer, "%s%s", getenv("HOME"), exec+1); strcpy(exec, buffer); } delete [] buffer; item->exec = new char[strlen(exec)+1]; strcpy(item->exec, exec); item->name = new char[strlen(n)+1]; strcpy(item->name, n); item->isSelected=False; item->sub = sub; item->function = func; item->item_x = item->item_y = 0; mi->insert(item); } int BaseMenu::remove(BaseMenuItem* element) { mi->remove(element); return mi->count(); } void BaseMenu::removeAll() { mi->removeAll(); update_all(); } void BaseMenu::execute(char *s) { char command[strlen(s)+8]; sprintf(command, "exec %s &", s); system(command); } void BaseMenu::show() { int mouse_x=0; int mouse_y=0; // Gets the coordinates of the mouse getMousePosition(&mouse_x, &mouse_y); // Check to make sure menu will be displayed on the screen. if (mouse_x + menu.width > wm->getXRes()) { menu.x = wm->getXRes() - menu.width - 1; right_edge=True; } else { menu.x = mouse_x; right_edge=False; } if (mouse_y + menu.height > wm->getYRes()) { menu.y = wm->getYRes() - menu.height - item_height - 4; bottom_edge=True; }else { menu.y = mouse_y; bottom_edge=False; } // Move the menu to the position of the mouse pointer XMoveWindow(wm->getDisplay(), menu.window, menu.x, menu.y); // Show the menu windows XMapRaised(wm->getDisplay(), menu.window); XMapSubwindows(wm->getDisplay(),menu.window); menu.isVisible=True; } void BaseMenu::getMousePosition(int *x, int *y) { Window dw1=None; Window dw2=None; int t1=0; int t2=0; unsigned int t3=0; XQueryPointer(wm->getDisplay(), wm->getRootWindow(), &dw1, &dw2, x, y, &t1, &t2, &t3); } void BaseMenu::show(int x, int y) { menu.x = x; menu.y = y; XMoveWindow(wm->getDisplay(), menu.window, x, y); // Show the menu windows XMapSubwindows(wm->getDisplay(),menu.window); XMapRaised(wm->getDisplay(), menu.window); XClearWindow(wm->getDisplay(), menu.item_window); menu.isVisible=True; } void BaseMenu::showSub(BaseMenu *sub, int x, int y) { sub->menu.x = x; sub->menu.y = y; XMoveWindow(wm->getDisplay(), sub->menu.window, x, y); // Show the menu windows XMapSubwindows(wm->getDisplay(), sub->menu.window); XMapRaised(wm->getDisplay(), sub->menu.window); sub->menu.isVisible=True; } void BaseMenu::hide(BaseMenu *sub) { if (sub->menu.isVisible) { // hide the menu windows XUnmapSubwindows(wm->getDisplay(), sub->menu.window); XUnmapWindow(wm->getDisplay(), sub->menu.window); sub->menu.isVisible=False; } } BaseMenuItem *BaseMenu::findMenuItem(int x, int y) { int item_xpos2=0; int item_ypos2=0; if(mi->count()) { LinkedListIterator it(mi); for(; it.current(); it++) { // Draws a bounding box around each menu item. This helped me figure out the algorithm to test which item the // pointer was over. // //XDrawRectangle(wm->getDisplay(), menu.item_window, menu_gc, it.current()->item_x - 14, // it.current()->item_y - 14, menu.width-1, it.current()->item_y + item_height - 15); item_xpos2 = menu.width-1; item_ypos2 = it.current()->item_y + item_height - 15; if ( (x >= it.current()->item_x - 14) && (x < item_xpos2) && (y >= it.current()->item_y - 14) && (y < item_ypos2) ) { return it.current(); } } } return NULL; } void BaseMenu::handle_button_press_event(XButtonEvent *e) { switch (e->button) { case Button1: { if(e->window == menu.title) move(); else if (curr) handle_button1_press(curr); break; } case Button2: { if(curr) handle_button2_press(curr); break; } case Button3: { if (curr) handle_button3_press(curr); break; } } } void BaseMenu::handle_button_release_event(XButtonEvent *e) { switch (e->button) { case Button1: { if (curr) { handle_button1_release(curr); switch( curr->function ) { // function 1 is wm shutdown case 1: { wm->quit_nicely(); } break; case 2: // do nothing this is a menu separator { } break; case 3: // This will start another window manager { //wm->start_another_windowmanager(curr->exec); } break; case 4: // restart Sapphire { wm->restart(); } break; case 5: // reconfigure Sapphire (theme, menu) { wm->reconfigureMenu(); } break; case 6: // change theme { Toolbar *t = wm->getToolbar(); t->setStartMenuButtonStateNotPressed(); t->getToolbarMenu()->hide(t->getToolbarMenu()); wm->getRootMenu()->hideAllVisibleSubmenus(); wm->changeTheme(curr->exec); } break; default: // Default is to execute a command or file { Toolbar *t = wm->getToolbar(); t->setStartMenuButtonStateNotPressed(); t->getToolbarMenu()->hide(t->getToolbarMenu()); wm->getRootMenu()->hideAllVisibleSubmenus(); execute(curr->exec); } break; } } break; } case Button2: { if (curr) handle_button2_release(curr); break; } case Button3: { if(e->window == menu.title) hideAllVisibleSubmenus(); else if (curr) handle_button3_release(curr); break; } } } void BaseMenu::move() { wm->setMenu(this); wm->setMenuEvent(true); } void BaseMenu::setMenuPos(int x, int y) { menu.x = x; menu.y = y; XMoveWindow(wm->getDisplay(), menu.window, x, y); } void BaseMenu::handle_enter_notify(XCrossingEvent *e) { if(curr) { LinkedList *temp_mi; LinkedListIterator it(mi); for(; it.current(); it++) { if (it.current()->sub && it.current()->sub->menu.isVisible) { it.current()->sub->hide(it.current()->sub); temp_mi = it.current()->sub->mi; LOOP: LinkedListIterator n(temp_mi); for(; n.current(); n++) { if(n.current()->sub && n.current()->sub->menu.isVisible) { n.current()->sub->hide(n.current()->sub); temp_mi = n.current()->sub->mi; goto LOOP; } } } } XFillRectangle(wm->getDisplay(), menu.item_window, select_gc, 0, curr->item_y - 15, item_width - item_height - 2, item_height - 1 ); if(curr->sub) { testMenuEdgeDetect(curr->sub); if(curr->sub->right_edge) { if(curr->sub->bottom_edge) showSub(curr->sub,menu.x - curr->sub->menu.width - 1, wm->getYRes() - curr->sub->menu.height - 27); else showSub(curr->sub,menu.x - curr->sub->menu.width - 1, menu.y + curr->item_y - 15); } else { if(curr->sub->bottom_edge) { showSub(curr->sub,menu.x + menu.width + 1, wm->getYRes() - curr->sub->menu.height - 27); } else { showSub(curr->sub,menu.x + menu.width + 1, menu.y + curr->item_y - 15); } } } redraw(curr); } } void BaseMenu::handle_leave_notify(XCrossingEvent *e) { if(curr) { XFillRectangle(wm->getDisplay(), menu.item_window, back_gc, 0, curr->item_y -15, item_width - item_height - 2, item_height - 1); redraw(curr); curr = NULL; } } void BaseMenu::hideAllVisibleSubmenus() { LinkedList *temp_mi; hide(this); LinkedListIterator it(mi); for(; it.current(); it++) { if (it.current()->sub && it.current()->sub->menu.isVisible) { it.current()->sub->hide(it.current()->sub); temp_mi = it.current()->sub->mi; LOOP: // Yuck I'm using a goto... ;-( LinkedListIterator n(temp_mi); for(; n.current(); n++) { if(n.current()->sub && n.current()->sub->menu.isVisible) { n.current()->sub->hide(n.current()->sub); temp_mi = n.current()->sub->mi; goto LOOP; } } } } } void BaseMenu::setAllMenuTitlesVisible(BaseMenu *sub, bool s) { sub->setTitleVisible(s); LinkedListIterator it(sub->mi); for(; it.current(); it++) { if (it.current()->sub) setAllMenuTitlesVisible(it.current()->sub, s); } } void BaseMenu::handle_expose_event(XExposeEvent *e) { if(e->count == 0) redraw(); } void BaseMenu::handle_motion_notify_event(XMotionEvent *e) { // for moving the menu. menu.x_move = e->x; menu.y_move = e->y; //---------------------- XEvent temp; if(e->window == menu.title) { /* DO NOTHING */ } else if(e->window == menu.item_window) { BaseMenuItem *i = findMenuItem(e->x, e->y); if (i && enterOnce) { curr = i; if(! strcmp(i->name, "separator")==0) handle_enter_notify(&temp.xcrossing); enterOnce=False; } else { BaseMenuItem *i = findMenuItem(e->x, e->y); if (i != curr) { handle_leave_notify(&temp.xcrossing); curr = i; enterOnce=True; } } } } void BaseMenu::handle_config_notify_event(XConfigureEvent *e) { } void BaseMenu::createMenuImage() { unsigned long style=0; style = wm->getTheme()->getMenuStyle(); menu_pix = wm->getImageControl()->renderImage( //"menu_frame", menu.width, menu.height, style, wm->getTheme()->getMenuColorFrom(), wm->getTheme()->getMenuColorTo() ); XSetWindowBackgroundPixmap(wm->getDisplay(), menu.item_window, menu_pix); } void BaseMenu::createMenuSelectImage() { unsigned long style=0; style = wm->getTheme()->getMenuSelectStyle(); select_pix = wm->getImageControl()->renderImage( //"menu_select", menu.width, item_height, style, wm->getTheme()->getMenuSelectColorFrom(), wm->getTheme()->getMenuSelectColorTo() ); } void BaseMenu::createMenuFontImage() { unsigned long style=0; style = wm->getTheme()->getFontStyle(); menufont_pix = wm->getImageControl()->renderImage( //"menu_font", font->ascent, font->descent, style, wm->getTheme()->getMenuFontColorFrom(), wm->getTheme()->getMenuFontColorTo() ); } void BaseMenu::createMenuTitleImage() { unsigned long style=0; style = wm->getTheme()->getMenuTitleStyle(); title_pix = wm->getImageControl()->renderImage( //"menu_title", menu.width, item_height+1, style, wm->getTheme()->getMenuTitleColorFrom(), wm->getTheme()->getMenuTitleColorTo() ); XSetWindowBackgroundPixmap(wm->getDisplay(), menu.title, title_pix); } void BaseMenu::testMenuEdgeDetect(BaseMenu *sub) { int mouse_x=0; int mouse_y=0; bool rightEdge=False; bool bottomEdge=False; // Gets the coordinates of the mouse getMousePosition(&mouse_x, &mouse_y); rightEdge = ( ( this->menu.x + sub->menu.width + 150 ) < (wm->getXRes()) ) ? True : False; bottomEdge = ( mouse_y + sub->menu.height >= wm->getYRes() ) ? True : False; // Check to make sure menu will be displayed on the screen. if (rightEdge) sub->right_edge=False; else sub->right_edge=True; if (bottomEdge) sub->bottom_edge=True; else sub->bottom_edge=False; } sapphire-0.15.8/client.cc0100644000175000001440000011746607414170253013552 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "sapphire.hh" Client::Client() { // One thing I cannot stand is fucking variables that are cryptic. // I gotta lay off the dope when I code, shit! shaped = false; moving = false; shaded = false; maxsized = false; name = "unknown"; // Defaults for this Clients x, y position and width and height. x = 1; y = 1; width = 1; height = 1; oumx = 1; oumy = 1; oumwidth = 1; oumheight = 1; old_width = width; old_height = height; default_titlebar_height = wm->getIHeight() + DEFAULT_SPACE; default_client_name_x = DEFAULT_SPACE + 20; default_client_name_y = wm->getFontPosition(); //DEFAULT_SPACE + wm->getXFont()->ascent + 2; default_button_width= 13; default_button_height= 13; client_position[40]=0; text_width=0; right_sidebar_width=10; // These are set to there real defaults in the reparent function. default_close_button_x = 0; default_close_button_y = 0; default_shade_button_x = 0; default_shade_button_y = 0; default_minimize_button_x = 0; default_minimize_button_y = 0; default_maximize_button_x = 0; default_maximize_button_y = 0; close_button_pressed=false; shade_button_pressed=false; minimize_button_pressed=false; maximize_button_pressed=false; // Mouse Button defaults button1=button2=button3=false; // Window Decorations // // The parent_window is the main parent. The titlebar is a child of the parent_window // all other button windows are childs of the titlebar. has_titlebar=true; has_close_button=true; has_minimize_button=true; has_maximize_button=true; has_shade_button=true; frame_pix=None; // Pixmap used for the titlebar button_pix=None;// Pixmap used for titlebar buttons ignore_unmap=0; close.window = maximize.window = minimize.window = shadeButton.window = window = parent = transient = title = right_sidebar = resize_win = None; } Client::~Client() { } Window Client::createTopLevelWindow(int x, int y, unsigned int width,unsigned int height,unsigned int borderwidth) { XSetWindowAttributes attrib; unsigned long create_mask = CWOverrideRedirect | CWBackPixmap | CWBackPixel | CWBorderPixel | CWCursor | CWEventMask; attrib.background_pixmap = None; attrib.background_pixel = wm->getBackgroundColor().pixel; attrib.border_pixel = wm->getBorderColor().pixel; attrib.override_redirect = true; attrib.cursor = XCreateFontCursor(wm->getDisplay(), XC_left_ptr); attrib.event_mask = StructureNotifyMask | SubstructureNotifyMask | SubstructureRedirectMask | ExposureMask | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask | FocusChangeMask; return (XCreateWindow(wm->getDisplay(), wm->getRootWindow(), x,y,width,height,borderwidth, DefaultDepth(wm->getDisplay(), wm->getScreen()), InputOutput, DefaultVisual(wm->getDisplay(), wm->getScreen()), create_mask, &attrib)); } Window Client::createChildWindow(Window parent, int x, int y, unsigned int width,unsigned int height,unsigned int borderwidth) { XSetWindowAttributes attrib; unsigned long create_mask = CWBackPixmap | CWBackPixel | CWBorderPixel | CWCursor | CWEventMask; attrib.background_pixmap = None; attrib.background_pixel = wm->getBackgroundColor().pixel; attrib.border_pixel = wm->getBorderColor().pixel; attrib.cursor = XCreateFontCursor(wm->getDisplay(), XC_left_ptr); attrib.event_mask = StructureNotifyMask | SubstructureNotifyMask | SubstructureRedirectMask | ExposureMask | EnterWindowMask | LeaveWindowMask | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; return (XCreateWindow(wm->getDisplay(), parent, x,y,width,height,borderwidth, DefaultDepth(wm->getDisplay(), wm->getScreen()), InputOutput, DefaultVisual(wm->getDisplay(), wm->getScreen()), create_mask, &attrib)); } void Client::make_new_client(Window w) { long dummy; XWMHints *hints; XWindowAttributes attr; // Populate the hints structure with the window hints (w) has. hints = XGetWMHints(wm->getDisplay(), w); // Create a new Client object. Client *c = new Client(); // Insert the client into the window manager client list. wm->insertClient(c); // Assign the window (w) to c->window, c->window represents the application. c->window = w; c->ignore_unmap = 0; XGetWindowAttributes(wm->getDisplay(), c->window, &attr); c->x = attr.x; c->y = attr.y; c->width = attr.width; c->height = attr.height; c->cmap = attr.colormap; c->size = XAllocSizeHints(); init_position(c); XGetWMNormalHints(wm->getDisplay(), c->window, c->size, &dummy); XSelectInput(wm->getDisplay(), c->window, ColormapChangeMask | PropertyChangeMask | EnterWindowMask ); getTransients(c); if (XFetchName(wm->getDisplay(), c->window, &c->name)==0) c->name=NULL; if (isViewable(c)) c->ignore_unmap++; change_gravity(c, 1); // Determine if this client needs window decorations. setButtonPositionDefaults(c); determineWindowDecorations(c); if (hints) XFree(hints); // Do all the necessary reparenting for this client reparent(c); // If this client should be iconic on start then we won't map it. isIconic(c); XAddToSaveSet(wm->getDisplay(), c->window); XSetWindowBorderWidth(wm->getDisplay(), c->window, 0); } void Client::init_position(Client *c) { /* Adapted from aewm 1.1.2 */ int xmax = wm->getXRes(); int ymax = wm->getYRes(); int mouse_x=0, mouse_y=0; if (c->size->flags & (USSize)) { c->width = c->size->width; c->height = c->size->height; } else { /* we would check PSize here, if GTK didn't blow goats */ /* make sure it's big enough to click at */ if (c->width < 2 * theight(c)) c->width = 2 * theight(c); if (c->height < theight(c)) c->height = theight(c); } if (c->size->flags & USPosition) { c->x = c->size->x; c->y = c->size->y; } else { if (c->size->flags & PPosition) { c->x = c->size->x; c->y = c->size->y; } if (c->x < 0) c->x = 0; if (c->y < 0) c->y = 0; if (c->x > xmax) c->x = xmax - 5; if (c->y > ymax) c->y = ymax - 5; } if (c->x == 0 && c->y == 0) { get_mouse_position(&mouse_x, &mouse_y); if (c->width < xmax) c->x = (mouse_x / 2); if (c->height + theight(c) < ymax) c->y = (mouse_y / 2); c->y += theight(c); change_gravity(c, -1); } } void Client::remove_client(Client *c) { XEvent foo; XGrabServer(wm->getDisplay()); if(! XCheckTypedWindowEvent(wm->getDisplay(), c->window, DestroyNotify, &foo)) { // Sets input focus back to the root window XSetInputFocus(wm->getDisplay(), wm->getRootWindow(), RevertToPointerRoot, CurrentTime); change_gravity(c, -1); XReparentWindow(wm->getDisplay(), c->window, wm->getRootWindow(), c->x, c->y); XRemoveFromSaveSet(wm->getDisplay(), c->window); XDestroyWindow(wm->getDisplay(), c->close.window); XDestroyWindow(wm->getDisplay(), c->maximize.window); XDestroyWindow(wm->getDisplay(), c->minimize.window); XDestroyWindow(wm->getDisplay(), c->shadeButton.window); XDestroyWindow(wm->getDisplay(), c->right_sidebar); XDestroyWindow(wm->getDisplay(), c->resize_win); XDestroyWindow(wm->getDisplay(), c->title); XDestroyWindow(wm->getDisplay(), c->parent); if (c->name) XFree(c->name); if (c->size) XFree(c->size); wm->getImageControl()->removeImage(c->frame_pix); wm->getImageControl()->removeImage(c->right_pix); wm->getImageControl()->removeImage(c->button_pix); wm->getImageControl()->removeImage(c->resize_pix); wm->removeClient(c); delete c; } XSync(wm->getDisplay(), false); XUngrabServer(wm->getDisplay()); } void Client::setButtonPositionDefaults(Client *c) { c->default_close_button_x = 4; c->default_close_button_y = theight(c) / 2 - 7; c->default_shade_button_x = c->width - 44; c->default_shade_button_y = theight(c) / 2 - 7; c->default_minimize_button_x = c->width - 27; c->default_minimize_button_y = theight(c) / 2 - 7; c->default_maximize_button_x = c->width - 10; c->default_maximize_button_y = theight(c) / 2 - 7; } void Client::reparent(Client *c) { createParentWindow(c); createTitlebarWindow(c); createRightSidebarWindow(c); createResizeWindow(c); createCloseButtonWindow(c); createMinimizeButtonWindow(c); createMaximizeButtonWindow(c); createShadeButtonWindow(c); if (wm->getShape()) { XShapeSelectInput(wm->getDisplay(), c->window, ShapeNotifyMask); set_shape(c); } // If this window doesn't request that it shouldn't be reparented // then we will go ahead an reparent it to c->parent which is the // parent window which holds the client application window ( c->window ) aswell // as the titlebar window and the button windows. if (c->has_titlebar) { int x, y; unsigned int width, height, border, depth; Window win; XGetGeometry(wm->getDisplay(), c->parent, &win, &x, &y, &width, &height, &border, &depth); XReparentWindow(wm->getDisplay(), c->window, c->parent, 0, theight(c)); if(y <= theight(c)) { XMoveWindow(wm->getDisplay(), c->parent, x, y); c->y = theight(c); } else { XMoveWindow(wm->getDisplay(), c->parent, x, y - theight(c)); c->y = y; } } else { // If we don't need to reparent it with window decorations then we // reparent it back to the root window and move it to where it wishes // to be when mapped. XReparentWindow(wm->getDisplay(), c->window, wm->getRootWindow(), 0, 0); XMoveWindow(wm->getDisplay(), c->window, c->x, c->y); } createButtonImage(c); createResizeImage(c); send_config(c); } void Client::createParentWindow(Client *c) { c->parent = createTopLevelWindow ( c->x, c->y - theight(c), c->width + right_sidebar_width, c->height + theight(c), DEFAULT_BORDER_SIZE ); } void Client::createTitlebarWindow(Client *c) { c->title = createChildWindow ( c->parent, 0, 0, c->width + right_sidebar_width, theight(c), 0 ); } void Client::createRightSidebarWindow(Client *c) { c->right_sidebar = createChildWindow ( c->parent, c->width, theight(c), right_sidebar_width, c->height - 10, 1 ); } void Client::createResizeWindow(Client *c) { c->resize_win = createChildWindow ( c->parent, c->width, c->height + 10, right_sidebar_width, 10, 1 ); } void Client::createCloseButtonWindow(Client *c) { c->close.x = c->default_close_button_x; c->close.y = c->default_close_button_y; c->close.width = c->default_button_width; c->close.height = c->default_button_height; c->close.window = createChildWindow ( c->title, c->close.x, c->close.y, c->close.width, c->close.height, 1 ); } void Client::createMinimizeButtonWindow(Client *c) { c->minimize.x = c->default_minimize_button_x; c->minimize.y = c->default_minimize_button_y; c->minimize.width = c->default_button_width; c->minimize.height = c->default_button_height; c->minimize.window = createChildWindow ( c->title, c->minimize.x, c->minimize.y, c->minimize.width, c->minimize.height, 1 ); } void Client::createMaximizeButtonWindow(Client *c) { c->maximize.x = c->default_maximize_button_x; c->maximize.y = c->default_maximize_button_y; c->maximize.width = c->default_button_width; c->maximize.height = c->default_button_height; c->maximize.window = createChildWindow ( c->title, c->maximize.x, c->maximize.y, c->maximize.width, c->maximize.height, 1 ); } void Client::createShadeButtonWindow(Client *c) { c->shadeButton.x = c->default_shade_button_x; c->shadeButton.y = c->default_shade_button_y; c->shadeButton.width = c->default_button_height; c->shadeButton.height = c->default_button_height; c->shadeButton.window = createChildWindow ( c->title, c->shadeButton.x, c->shadeButton.y, c->shadeButton.width, c->shadeButton.height, 1 ); } int Client::theight(Client *c) const { //return ((c->transient ? 2*DEFAULT_SPACE : wm->iheight) + DEFAULT_SPACE); // For now this function will pass a Client object. Even though we don't // use it for much, I still might want to have transients have a different style // than there top level parents later on. // // For instance I could turn off some of the titlebar buttons, or I could change the // height of the client's titlebar and button width and height. // // This is the reason why I am passing the Client object to this function. I simply // haven't made up my mind at this point. return c->default_titlebar_height; } void Client::getTransients(Client *c) { Window trans; XGetTransientForHint(wm->getDisplay(), c->window, &trans); c->transient = trans; } void Client::determineWindowDecorations(Client *c) { // This code was ripped from somewhere but since Client.cc // is coded so fucking badly it doesn't work for anything. int format; Atom atom_return; unsigned long num, len; if (XGetWindowProperty(wm->getDisplay(), c->window, wm->getMotifWMHintsAtom(), 0, PropMwmHintsElements, false, wm->getMotifWMHintsAtom(), &atom_return, &format, &num, &len, (unsigned char **) &c->mwm_hint) == Success && c->mwm_hint) if (num == PropMwmHintsElements) { if (c->mwm_hint->flags & MwmHintsDecorations) { if (c->mwm_hint->decorations & MwmDecorAll) { c->has_titlebar=c->has_close_button=c->has_minimize_button=c->has_maximize_button=c->has_shade_button=true; } else { c->has_titlebar=c->has_close_button=c->has_minimize_button=c->has_maximize_button=c->has_shade_button=false; if (c->mwm_hint->decorations & MwmDecorTitle) c->has_titlebar = true; c->has_minimize_button = true; c->has_maximize_button = true; c->has_shade_button=true; c->has_close_button=true; } } }} Client *Client::find_client(Window w) { if (w && w != wm->getRootWindow()) { if(wm->getClientCount()) { LinkedListIterator it(wm->getClientListObject()); for(; it.current(); it++) { if (w == it.current()->parent || w == it.current()->title || w == it.current()->window || w == it.current()->close.window || w == it.current()->maximize.window || w == it.current()->minimize.window || w == it.current()->resize_win || w == it.current()->right_sidebar || w == it.current()->shadeButton.window ) { return it.current(); } } } } return NULL; } int Client::isViewable(Client *c) { XWindowAttributes attr; XGetWindowAttributes(wm->getDisplay(), c->window, &attr); return attr.map_state; } void Client::createTitleImage(Client* c) { unsigned long style=0; style = wm->getTheme()->getTitlebarStyle(); c->frame_pix = wm->getImageControl()->renderImage( c->width+c->right_sidebar_width, theight(c), style, wm->getTheme()->getClientColorFrom(), wm->getTheme()->getClientColorTo()); XSetWindowBackgroundPixmap(wm->getDisplay(), c->title, c->frame_pix); } void Client::createRightSidebarImage(Client *c) { unsigned long style=0; style = wm->getTheme()->getRightSidebarStyle(); c->right_pix = wm->getImageControl()->renderImage( 10, c->height + theight(c) - 10, style, wm->getTheme()->getRightSidebarColorFrom(), wm->getTheme()->getRightSidebarColorTo()); XSetWindowBackgroundPixmap(wm->getDisplay(), c->right_sidebar, c->right_pix); } void Client::createResizeImage(Client *c) { unsigned long style=0; style = wm->getTheme()->getResizeStyle(); c->resize_pix = wm->getImageControl()->renderImage( 10, 10, style, wm->getTheme()->getResizeColorFrom(), wm->getTheme()->getResizeColorTo()); XSetWindowBackgroundPixmap(wm->getDisplay(), c->resize_win, c->resize_pix); } void Client::createButtonImage(Client* c) { unsigned long style=0; style = wm->getTheme()->getButtonStyle(); c->button_pix = wm->getImageControl()->renderImage( c->default_button_width, c->default_button_height, style, wm->getTheme()->getButtonColorFrom(), wm->getTheme()->getButtonColorTo()); XSetWindowBackgroundPixmap(wm->getDisplay(), c->shadeButton.window, c->button_pix); XSetWindowBackgroundPixmap(wm->getDisplay(), c->close.window, c->button_pix); XSetWindowBackgroundPixmap(wm->getDisplay(), c->minimize.window, c->button_pix); XSetWindowBackgroundPixmap(wm->getDisplay(), c->maximize.window, c->button_pix); } void Client::reconfigure(Client *c) { createTitleImage(c); createRightSidebarImage(c); redraw(c); } void Client::send_config(Client *c) { XConfigureEvent ce; XEvent foo; ce.type = ConfigureNotify; ce.event = c->window; ce.window = c->window; ce.x = c->x; ce.y = c->y; ce.width = c->width; ce.height = c->height; ce.border_width = 0; ce.above = None; ce.override_redirect = 0; if(! XCheckTypedWindowEvent(wm->getDisplay(), c->window, DestroyNotify, &foo)) { if(! moving) reconfigure(c); } XSendEvent(wm->getDisplay(), c->window, false, StructureNotifyMask, (XEvent *)&ce); } void Client::move(Client *c) { if (c) { moving=true; drag(c); XMoveWindow(wm->getDisplay(), c->parent, c->x, c->y -theight(c)); send_config(c); moving=false; } } void Client::drag(Client *c) { XEvent ev; int x1=c->x; int y1=c->y; int old_cx = c->x; int old_cy = c->y; wm->grabPointer(wm->getRootWindow(), ButtonPressMask | ButtonReleaseMask | PointerMotionMask, wm->getMoveCursor()); XGrabServer(wm->getDisplay()); get_mouse_position(&x1, &y1); draw_outline(c); for (;;) { XMaskEvent(wm->getDisplay(), ButtonPressMask | ButtonReleaseMask | PointerMotionMask, &ev); switch (ev.type) { case MotionNotify: draw_outline(c); /* clear */ c->x = old_cx + (ev.xmotion.x_root - x1); c->y = old_cy + (ev.xmotion.y_root - y1); draw_outline(c); break; case ButtonRelease: draw_outline(c); /* clear */ XUngrabServer(wm->getDisplay()); wm->ungrabPointer(); return; } } } void Client::resize(Client *c) { if (c) { sweep(c); if (c->maxsized) { c->maxsized = false; } XMoveResizeWindow(wm->getDisplay(), c->parent, c->x, c->y - theight(c), c->width+c->right_sidebar_width, c->height + theight(c)); XMoveResizeWindow(wm->getDisplay(), c->title, 0, 0, c->width+c->right_sidebar_width, theight(c)); XMoveResizeWindow(wm->getDisplay(), c->right_sidebar, c->width, theight(c), c->right_sidebar_width, c->height - 10); XMoveResizeWindow(wm->getDisplay(), c->resize_win, c->width, c->height + 10, 10, 10); XMoveWindow(wm->getDisplay(), c->maximize.window, c->width - 10, c->maximize.y); XMoveWindow(wm->getDisplay(), c->minimize.window, c->width - 27, c->minimize.y); XMoveWindow(wm->getDisplay(), c->shadeButton.window, c->width - 44, c->shadeButton.y); XMoveResizeWindow(wm->getDisplay(), c->window, 0, theight(c), c->width, c->height); send_config(c); } } void Client::recalculate_sweep(Client *c, int x1, int y1, int x2, int y2) { int basex=0; int basey=0; c->width = abs(x1 - x2) - DEFAULT_BORDER_SIZE; c->height = abs(y1 - y2) - DEFAULT_BORDER_SIZE; if (c->size->flags & PResizeInc) { basex = (c->size->flags & PBaseSize) ? c->size->base_width : (c->size->flags & PMinSize) ? c->size->min_width : c->x; basey = (c->size->flags & PBaseSize) ? c->size->base_height : (c->size->flags & PMinSize) ? c->size->min_height : c->y; c->width -= (c->width - basex) % c->size->width_inc; c->height -= (c->height - basey) % c->size->height_inc; } if (c->size->flags & PMinSize) { if (c->width < c->size->min_width) c->width = c->size->min_width; if (c->height < c->size->min_height) c->height = c->size->min_height; } if (c->size->flags & PMaxSize) { if (c->width > c->size->max_width) c->width = c->size->max_width; if (c->height > c->size->max_height) c->height = c->size->max_height; } c->x = (x1 <= x2) ? x1 : x1 - c->width; c->y = (y1 <= y2) ? y1 : y1 - c->height; } void Client::sweep(Client *c) { XEvent ev; int old_cx = c->x; int old_cy = c->y; wm->grabPointer(wm->getRootWindow(), ButtonReleaseMask | PointerMotionMask, wm->getResizeCursor()); draw_outline(c); for (;;) { XMaskEvent(wm->getDisplay(), ButtonPressMask | ButtonReleaseMask | PointerMotionMask, &ev); switch (ev.type) { case MotionNotify: draw_outline(c); recalculate_sweep(c, old_cx, old_cy, ev.xmotion.x_root , ev.xmotion.y_root); draw_outline(c); break; case ButtonRelease: draw_outline(c); wm->ungrabPointer(); return; } } } void Client::draw_outline(Client *c) { if(c->shaded) { XDrawRectangle(wm->getDisplay(), wm->getRootWindow(), wm->getInvertGC(), c->x, /* x */ c->y - theight(c) + DEFAULT_BORDER_SIZE/2, /* y */ c->width+10, /* width */ theight(c) + DEFAULT_BORDER_SIZE); /* height */ } else { XDrawRectangle(wm->getDisplay(), wm->getRootWindow(), wm->getInvertGC(), c->x + DEFAULT_BORDER_SIZE/2, /* x */ c->y - theight(c) + DEFAULT_BORDER_SIZE/2, /* y */ c->width + 10 + DEFAULT_BORDER_SIZE, /* width */ c->height + theight(c) + DEFAULT_BORDER_SIZE); /* height */ sprintf(c->client_position, "%dx%d+%d+%d", c->width+c->right_sidebar_width, c->height+theight(c), c->x, c->y); c->text_width=XTextWidth(wm->getXFont(), c->client_position, strlen(c->client_position)); XDrawString(wm->getDisplay(), wm->getRootWindow(), wm->getInvertGC(), c->x + c->width - XTextWidth(wm->getXFont(), c->client_position, strlen(c->client_position)), c->y + c->height - DEFAULT_SPACE, c->client_position, strlen(c->client_position)); } } void Client::maximumresize(Client *c) { // Check to see if this window can be resized more // if its at its max size then lets leave it alone. if (c && !(c->size->flags & PMaxSize) ) { if (c->maxsized) { c->x = c->oumx; c->y = c->oumy; c->width = c->oumwidth; c->height = c->oumheight; c->maxsized = false; } else { c->oumx = c->x; c->oumy = c->y; c->oumwidth = c->width; c->oumheight = c->height; c->x = 1; if (wm->getTheme()->getToolbarExtraStyle() & TOOLBAR_TOP) { c->y = 28 + theight(c); c->width = wm->getXRes() - 14; c->height = wm->getYRes() - theight(c) - 34; c->maxsized = true; } else { c->y = 0 + theight(c); c->width = wm->getXRes() - 14; c->height = wm->getYRes() - 28 - theight(c); c->maxsized = true; } } XMoveResizeWindow(wm->getDisplay(), c->parent, c->x, c->y - theight(c), c->width + c->right_sidebar_width, c->height + theight(c)); XMoveResizeWindow(wm->getDisplay(), c->title, 0, 0, c->width+c->right_sidebar_width, theight(c)); XMoveResizeWindow(wm->getDisplay(), c->right_sidebar, c->width, theight(c), c->right_sidebar_width, c->height - 10); XMoveResizeWindow(wm->getDisplay(), c->resize_win, c->width, c->height + 10, right_sidebar_width, 10); XMoveWindow(wm->getDisplay(), c->maximize.window, c->width - 10, c->maximize.y); XMoveWindow(wm->getDisplay(), c->minimize.window, c->width - 27, c->minimize.y); XMoveWindow(wm->getDisplay(), c->shadeButton.window, c->width - 44, c->shadeButton.y); XMoveResizeWindow(wm->getDisplay(), c->window, 0, theight(c), c->width, c->height); send_config(c); } } void Client::hide(Client *c) { c->ignore_unmap++; if(c->has_titlebar) { XUnmapSubwindows(wm->getDisplay(), c->parent); XUnmapWindow(wm->getDisplay(), c->parent); } else { XUnmapWindow(wm->getDisplay(), c->window); } set_wm_state(c, IconicState); wm->getIconMenu()->addIcon(c->name, c); } void Client::unhide(Client *c) { mapClient(c); } // This repaints the titlebar and buttons on it, It also paints the window title. void Client::redraw(Client *c) { if (c->has_titlebar) { XClearWindow(wm->getDisplay(), c->title); XClearWindow(wm->getDisplay(), c->close.window); XClearWindow(wm->getDisplay(), c->minimize.window); XClearWindow(wm->getDisplay(), c->maximize.window); XClearWindow(wm->getDisplay(), c->shadeButton.window); XClearWindow(wm->getDisplay(), c->right_sidebar); XClearWindow(wm->getDisplay(), c->resize_win); // Close Button XDrawLine(wm->getDisplay(), c->close.window, wm->getBorderGC(), 2,2,c->close.width - 3,c->close.height-3); XDrawLine(wm->getDisplay(), c->close.window, wm->getBorderGC(), 2,c->close.height - 3,c->close.width-3,2); // Maximize Button XDrawRectangle(wm->getDisplay(), c->maximize.window, wm->getBorderGC(), 2, 2, c->maximize.width - 5, c->maximize.height - 5); XDrawLine(wm->getDisplay(), c->maximize.window, wm->getBorderGC(), 2, 3, c->maximize.width - 3, 3); // Minimize Button XDrawRectangle(wm->getDisplay(), c->minimize.window, wm->getBorderGC(), 2, c->minimize.height - 5, c->minimize.width - 5, 2); draw_shade_button(c); if (c->name) { XDrawString(wm->getDisplay(), c->title, wm->getStringGC(), c->default_client_name_x, c->default_client_name_y, c->name, strlen(c->name)); } } } void Client::draw_shade_button(Client *c) { if (c->shaded) { // Draws a triangle pointing down which indicates that this // window is shaded. // XDrawLine(wm->getDisplay(), c->shadeButton.window,wm->getBorderGC(), 2, 5, 11, 5); XDrawLine(wm->getDisplay(), c->shadeButton.window,wm->getBorderGC(), 3, 6, 10, 6); XDrawLine(wm->getDisplay(), c->shadeButton.window,wm->getBorderGC(), 4, 7, 9, 7); XDrawLine(wm->getDisplay(), c->shadeButton.window,wm->getBorderGC(), 5, 8, 8, 8); XDrawLine(wm->getDisplay(), c->shadeButton.window,wm->getBorderGC(), 6, 9, 7, 9); } else { // Draws a triangle pointing up which indicates that this // window is not shaded. // XDrawLine(wm->getDisplay(), c->shadeButton.window,wm->getBorderGC(), 6, 5, 7, 5); XDrawLine(wm->getDisplay(), c->shadeButton.window,wm->getBorderGC(), 5, 6, 8, 6); XDrawLine(wm->getDisplay(), c->shadeButton.window,wm->getBorderGC(), 4, 7, 9, 7); XDrawLine(wm->getDisplay(), c->shadeButton.window,wm->getBorderGC(), 3, 8, 10, 8); XDrawLine(wm->getDisplay(), c->shadeButton.window,wm->getBorderGC(), 2, 9, 11, 9); } } void Client::change_gravity(Client *c, int multiplier) { int dy = 0; int gravity = (c->size->flags & PWinGravity) ? c->size->win_gravity : NorthWestGravity; switch (gravity) { case NorthWestGravity: case NorthEastGravity: case NorthGravity: dy = theight(c); break; case CenterGravity: dy = theight(c)/2; break; } c->y += multiplier * dy; } void Client::set_shape(Client *c) { int n, order; XRectangle *rect; rect = XShapeGetRectangles(wm->getDisplay(), c->window, ShapeBounding, &n, &order); if (n > 1) XShapeCombineShape(wm->getDisplay(), c->parent, ShapeBounding, 0, theight(c), c->window, ShapeBounding, ShapeSet); XFree(rect); } void Client::get_mouse_position(int *x, int *y) { Window dw1=None; Window dw2=None; int t1=0; int t2=0; unsigned int t3=0; XQueryPointer(wm->getDisplay(), wm->getRootWindow(), &dw1, &dw2, x, y, &t1, &t2, &t3); } void Client::shade(Client *c) { if (c->shaded) { XResizeWindow(wm->getDisplay(), c->parent, c->width+10, c->height + theight(c)); c->shaded=false; } else { XResizeWindow(wm->getDisplay(), c->parent, c->width+10, theight(c)); c->shaded=true; } } void Client::closeButtonPressed(Client *c) { XSetWindowBorderWidth(wm->getDisplay(), c->close.window, 2); XEvent ev; for (;;) { XMaskEvent(wm->getDisplay(), ButtonReleaseMask | LeaveWindowMask, &ev); switch (ev.type) { case LeaveNotify: { XSetWindowBorderWidth(wm->getDisplay(), c->close.window, 1); return; } case ButtonRelease: { XSetWindowBorderWidth(wm->getDisplay(), c->close.window, 1); send_wm_delete(c); return; } } } } void Client::shadeButtonPressed(Client *c) { XSetWindowBorderWidth(wm->getDisplay(), c->shadeButton.window, 2); XEvent ev; for (;;) { XMaskEvent(wm->getDisplay(), ButtonReleaseMask | LeaveWindowMask, &ev); switch (ev.type) { case LeaveNotify: { XSetWindowBorderWidth(wm->getDisplay(), c->shadeButton.window, 1); return; } case ButtonRelease: { XSetWindowBorderWidth(wm->getDisplay(), c->shadeButton.window, 1); XRaiseWindow(wm->getDisplay(), c->parent); shade(c); return; } } } } void Client::minimizeButtonPressed(Client *c) { XSetWindowBorderWidth(wm->getDisplay(), c->minimize.window, 2); XEvent ev; for (;;) { XMaskEvent(wm->getDisplay(), ButtonReleaseMask | LeaveWindowMask, &ev); switch (ev.type) { case LeaveNotify: { XSetWindowBorderWidth(wm->getDisplay(), c->minimize.window, 1); return; } case ButtonRelease: { XSetWindowBorderWidth(wm->getDisplay(), c->minimize.window, 1); hide(c); return; } } } } void Client::maximizeButtonPressed(Client *c) { XSetWindowBorderWidth(wm->getDisplay(), c->maximize.window, 2); XEvent ev; for (;;) { XMaskEvent(wm->getDisplay(), ButtonReleaseMask | LeaveWindowMask, &ev); switch (ev.type) { case LeaveNotify: { XSetWindowBorderWidth(wm->getDisplay(), c->maximize.window, 1); return; } case ButtonRelease: { XSetWindowBorderWidth(wm->getDisplay(), c->maximize.window, 1); switch(ev.xbutton.button) { case 1: { if(c->shaded) { shade(c); XRaiseWindow(wm->getDisplay(), c->parent); // Make sure it doesn't keep resizing if its already max resized if (! c->maxsized) maximumresize(c); } else { XRaiseWindow(wm->getDisplay(), c->parent); maximumresize(c); } return; } } } } } } void Client::send_wm_delete(Client *c) { if (c) send_xmessage(c->window, wm->getWMProtocolsAtom(), wm->getWMDeleteAtom(), CurrentTime); } int Client::send_xmessage(Window w, Atom a, long x, long y) { XEvent ev; long mask; memset(&ev, '\0', sizeof ev); ev.type = ClientMessage; ev.xclient.window = w; ev.xclient.message_type = a; ev.xclient.format = 32; ev.xclient.data.l[0] = x; ev.xclient.data.l[1] = y; mask = (w == wm->getRootWindow()) ? SubstructureRedirectMask : 0L; return XSendEvent(wm->getDisplay(), w, false, mask, &ev); } void Client::set_wm_state(Client *c, int state) { long data[2]; data[0] = (long) state; data[1] = (long) None; /* icon window */ c->state = state; XChangeProperty(wm->getDisplay(), c->window, wm->getWMStateAtom(), wm->getWMStateAtom(), 32, PropModeReplace, (unsigned char *)data, 2); } int Client::get_wm_state(Client *c) { Atom real_type; int real_format, state; unsigned long n, extra; unsigned char *data; if ((XGetWindowProperty(wm->getDisplay(), c->window, wm->getWMStateAtom(), 0L, 2L, false, AnyPropertyType, &real_type, &real_format, &n, &extra, &data) == Success) && n) { state = *(int *)data; XFree(data); return state; } else return WithdrawnState; } void Client::handle_enter_event(XCrossingEvent *e) { Client *c = find_client(e->window); if(c) XSetInputFocus(wm->getDisplay(), c->window, RevertToPointerRoot, CurrentTime); } void Client::handle_button_press_event(XButtonEvent *e) { Client *c = find_client(e->window); if (c) { switch (e->button) { case Button1: { if(c->close.window == e->window) closeButtonPressed(c); else if (c->maximize.window == e->window) maximizeButtonPressed(c); else if (c->minimize.window == e->window) minimizeButtonPressed(c); else if (c->shadeButton.window == e->window) shadeButtonPressed(c); else if (c->right_sidebar == e->window) { XRaiseWindow(wm->getDisplay(), c->parent); redraw(c); move(c); } else if (c->resize_win == e->window) { XRaiseWindow(wm->getDisplay(), c->parent); resize(c); } else if (c->title == e->window) { XRaiseWindow(wm->getDisplay(), c->parent); redraw(c); move(c); } break; } case Button2: { if (c->title == e->window) { // Middle click also allows you to shade the window. if(c->shaded) { XRaiseWindow(wm->getDisplay(), c->parent); shade(c); redraw(c); } else { XRaiseWindow(wm->getDisplay(), c->parent); shade(c); redraw(c); } } break; } } } } void Client::handle_configure_request(XConfigureRequestEvent *e) { Client *c = find_client(e->window); XWindowChanges wc; if (c) { change_gravity(c, -1); if (e->value_mask & CWX) c->x = e->x; if (e->value_mask & CWY) c->y = e->y; if (e->value_mask & CWWidth) c->width = e->width; if (e->value_mask & CWHeight) c->height = e->height; change_gravity(c, 1); if (c->width != wc.width && c->height != wc.height) { if (c->has_titlebar) XMoveResizeWindow(wm->getDisplay(), c->window, 0, theight(c), c->width, c->height); if (c->has_titlebar) XMoveResizeWindow(wm->getDisplay(), c->parent, c->x, c->y - theight(c), c->width+c->right_sidebar_width, c->height + theight(c)); XMoveResizeWindow(wm->getDisplay(), c->title, 0, 0, c->width+c->right_sidebar_width, theight(c)); XMoveResizeWindow(wm->getDisplay(), c->right_sidebar, c->width, theight(c), c->right_sidebar_width, c->height - 10); XMoveResizeWindow(wm->getDisplay(), c->resize_win, c->width, c->height + 10, right_sidebar_width, 10); XMoveWindow(wm->getDisplay(), c->maximize.window, c->width - 10, c->maximize.y); XMoveWindow(wm->getDisplay(), c->minimize.window, c->width - 27, c->minimize.y); XMoveWindow(wm->getDisplay(), c->shadeButton.window, c->width - 44, c->shadeButton.y); } wc.x = c->x; wc.y = c->y - theight(c); wc.width = c->width + c->right_sidebar_width; wc.height = c->height + theight(c); wc.border_width = DEFAULT_BORDER_SIZE; wc.sibling = e->above; wc.stack_mode = e->detail; XConfigureWindow(wm->getDisplay(), c->parent, e->value_mask, &wc); // If a window has been shaded and we get a configure request // we need to fix the shade button so it shows the correct state. // Otherwise the client will be mapped but show that its been // shaded. If you try and move it, it will draw a shaded outline. if(c->shaded) shade(c); send_config(c); } if(c && c->has_titlebar) { wc.x = 0; wc.y = theight(c); } else { wc.x = e->x; wc.y = e->y; } wc.width = e->width; wc.height = e->height; wc.sibling = e->above; wc.stack_mode = e->detail; XConfigureWindow(wm->getDisplay(), e->window, e->value_mask, &wc); } void Client::handle_map_request(XMapRequestEvent *e) { Client *c = find_client(e->window); if (c) mapClient(c); else make_new_client(e->window); } void Client::handle_unmap_event(XUnmapEvent *e) { Client *c = find_client(e->window); if (c) { if (c->ignore_unmap) c->ignore_unmap--; else { if (get_wm_state(c) == IconicState) XMapWindow(wm->getDisplay(), c->window); else { set_wm_state(c, WithdrawnState); remove_client(c); } } } } void Client::handle_client_message(XClientMessageEvent *e) { Client *c = find_client(e->window); if (c) { if(e->message_type == wm->getWMChangeStateAtom()) if(e->format == 32 && e->data.l[0] == IconicState) hide(c); } } void Client::handle_colormap_change(XColormapEvent *e) { Client *c = find_client(e->window); if (c && e->c_new) { c->cmap = e->colormap; installColorMap(c->cmap); } } void Client::handle_property_change(XPropertyEvent *e) { Client *c = find_client(e->window); long dummy; if (c) { switch (e->atom) { case XA_WM_NAME: { if (c->name) XFree(c->name); XFetchName(wm->getDisplay(), c->window, &c->name); XClearWindow(wm->getDisplay(), c->title); redraw(c); } break; case XA_WM_NORMAL_HINTS: { XGetWMNormalHints(wm->getDisplay(), c->window, c->size, &dummy); } break; //case XA_WM_ICON_NAME: //break; case XA_WM_TRANSIENT_FOR: getTransients(c); break; } } } void Client::handle_expose_event(XExposeEvent *e) { Client *c = find_client(e->window); if (c && e->count == 0) redraw(c); } void Client::handle_destroy_notify(XDestroyWindowEvent *e) { Client *c = find_client(e->window); if(c) remove_client(c); } void Client::handle_shape_change(XShapeEvent *e) { Client *c = find_client(e->window); if (c) { c->shaped=true; set_shape(c); } } void Client::installColorMap(Colormap cmap) { XInstallColormap(wm->getDisplay(), cmap); } void Client::isIconic(Client *c) { // Determine if this client is already in its iconic state upon creation // if so then we won't map it, but just iconify it. if (get_wm_state(c) == IconicState) hide(c); else mapClient(c); } void Client::mapClient(Client *c) { if (c->has_titlebar) { if(c->has_shade_button) XMapWindow(wm->getDisplay(), c->shadeButton.window); if(c->has_close_button) XMapWindow(wm->getDisplay(), c->close.window); if(c->has_minimize_button) XMapWindow(wm->getDisplay(), c->minimize.window); if(c->has_maximize_button) XMapWindow(wm->getDisplay(), c->maximize.window); XMapWindow(wm->getDisplay(), c->right_sidebar); XMapWindow(wm->getDisplay(), c->resize_win); XMapWindow(wm->getDisplay(), c->title); XMapWindow(wm->getDisplay(), c->window); XMapRaised(wm->getDisplay(), c->parent); } else XMapWindow(wm->getDisplay(), c->window); set_wm_state(c, NormalState); } void Client::themeChange(Client *c) { if (c->has_titlebar) { XFreePixmap(wm->getDisplay(), c->frame_pix); XFreePixmap(wm->getDisplay(), c->right_pix); XFreePixmap(wm->getDisplay(), c->button_pix); XFreePixmap(wm->getDisplay(), c->resize_pix); createTitleImage(c); createRightSidebarImage(c); createButtonImage(c); createResizeImage(c); redraw(c); } } void Client::raise() { XRaiseWindow(wm->getDisplay(), parent); redraw(this); } sapphire-0.15.8/HISTORY0100644000175000001440000000065507371010060013027 0ustar asusersSapphire Window Manager - History --------------------------------- Sapphire was originally developed from the aewm window manager by Decklin Foster . aewm can be found at http://www.red-bean.com/~decklin/aewm/. I've been given permission by Decklin Foster to release my changes to aewm under the GPL. I thank him greatly for that!!! Sapphire also borrows the image code from Blackbox by Brad Hughes. sapphire-0.15.8/image.cc0100644000175000001440000007730607414165525013362 0ustar asusers/* * image.cc - Defines how images are handled. * Copyright (C) 1997-1999 by Brad Hughes, bhughes@tcac.net * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include "sapphire.hh" #include #ifdef GradientHack # include # include #endif // ************************************************************************* // Graphics engine class code // ************************************************************************* BImage::BImage(BImageControl *c, unsigned int w, unsigned int h) { control = c; width = ((signed) w > 0) ? w : 1; height = ((signed) h > 0) ? h : 1; red = new unsigned char[width * height]; green = new unsigned char[width * height]; blue = new unsigned char[width * height]; cpc = control->colorsPerChannel(); cpccpc = cpc * cpc; control->getMaskTables(&tr, &tg, &tb, &roff, &goff, &boff); if (control->v()->c_class != TrueColor) control->getColorTable(&colors, &ncolors); } BImage::~BImage(void) { if (red) delete [] red; if (green) delete [] green; if (blue) delete [] blue; } Pixmap BImage::render(unsigned long texture, const BColor &c1, const BColor &c2) { if (texture & BImage_Solid) return render_solid(texture, c1); else if (texture & BImage_Gradient) return render_gradient(texture, c1, c2); return None; } Pixmap BImage::render_solid(unsigned long texture, const BColor &color) { int inverted = 0; if ((texture & BImage_Sunken) && (! (texture & BImage_Invert))) inverted = 1; else if (texture & BImage_Invert) inverted = 1; background(color); if (texture & BImage_Bevel1) bevel1(True, (color.red == color.green && color.green == color.blue && color.blue == 0)); else if (texture & BImage_Bevel2) bevel2(True, (color.red == color.green && color.green == color.blue && color.blue == 0)); if (inverted) invert(); return renderPixmap(); } Pixmap BImage::render_gradient(unsigned long texture, const BColor &color1, const BColor &color2) { int inverted = 0; if (texture & BImage_Sunken) { from = color2; to = color1; if (! (texture & BImage_Invert)) inverted = 1; } else { from = color1; to = color2; if (texture & BImage_Invert) inverted = 1; } if (texture & BImage_Diagonal) dgradient(); else if (texture & BImage_Horizontal) hgradient(); else if (texture & BImage_Vertical) vgradient(); if (texture & BImage_Bevel1) bevel1(False); else if (texture & BImage_Bevel2) bevel2(False); if (inverted) invert(); return renderPixmap(); } XImage *BImage::renderXImage(void) { XImage *image = XCreateImage(control->d(), control->v(), control->depth(), ZPixmap, 0, 0, width, height, 32, 0); if (! image) { fprintf(stderr, "BImage::renderXImage: error creating XImage\n"); return 0; } unsigned char *d = (unsigned char *) malloc(image->bytes_per_line * height); if (! d) { fprintf(stderr, "BImage::renderXImage: error allocating memory for image\n"); XDestroyImage(image); return 0; } register unsigned int x, y, r = 0, g = 0, b = 0, i, off; unsigned char *idata = d, *pd = d, *pr, *pg, *pb; unsigned long pixel; if ((! tr) || (! tg) || (! tb)) { fprintf(stderr, "BImage::renderXImage: error getting color mask tables\n"); XDestroyImage(image); return 0; } if (control->v()->c_class != TrueColor) if ((! colors) || (! ncolors)) { fprintf(stderr, "BImage::renderXImage: error getting pseudo color tables\n"); XDestroyImage(image); return 0; } if (control->dither()) { short er, eg, eb, *OR, *og, *ob, *nor, *nog, *nob, *por, *pog, *pob; unsigned short *ort, *ogt, *obt; control->getDitherBuffers(width + 2, &OR, &og, &ob, &nor, &nog, &nob, &ort, &ogt, &obt); if ((! OR) || (! og) || (! ob) || (! nor) || (! nog) || (! nob) || (! ort) || (! ogt) || (! obt)) { fprintf(stderr, "BImage::renderXImage: error getting dither information\n"); XDestroyImage(image); return 0; } x = width; por = OR; pog = og; pob = ob; pr = red; pg = green; pb = blue; while (x--) { *(por++) = *(pr++); *(pog++) = *(pg++); *(pob++) = *(pb++); } *por = *pog = *pob = 0; for (y = 0, off = 0; y < height; y++) { if (y < (height - 1)) { for (x = 0, i = off + width; x < width; x++, i++) { *(nor + x) = *(red + i); *(nog + x) = *(green + i); *(nob + x) = *(blue + i); } i--; *(nor + x) = *(red + i); *(nog + x) = *(green + i); *(nob + x) = *(blue + i); } for (x = 0; x < width; x++) { if (*(OR + x) > 255) *(OR + x) = 255; else if (*(OR + x) < 0) *(OR + x) = 0; if (*(og + x) > 255) *(og + x) = 255; else if (*(og + x) < 0) *(og + x) = 0; if (*(ob + x) > 255) *(ob + x) = 255; else if (*(ob + x) < 0) *(ob + x) = 0; r = *(tr + *(OR + x)); g = *(tg + *(og + x)); b = *(tb + *(ob + x)); switch (control->v()->c_class) { case StaticColor: case PseudoColor: pixel = (r * cpccpc) + (g * cpc) + b; *idata++ = colors[pixel].pixel; break; case TrueColor: pixel = (r << roff) | (g << goff) | (b << boff); switch (image->byte_order) { case MSBFirst: { switch (image->bits_per_pixel) { case 32: *(idata++) = (pixel >> 24); case 24: *(idata++) = (pixel >> 16); case 16: *(idata++) = (pixel >> 8); default: *(idata++) = (pixel); } break; } case LSBFirst: { *(idata++) = pixel; switch (image->bits_per_pixel) { case 32: *(idata++) = (pixel >> 8); *(idata++) = (pixel >> 16); *(idata++) = (pixel >> 24); break; case 24: *(idata++) = (pixel >> 8); *(idata++) = (pixel >> 16); break; case 16: *(idata++) = (pixel >> 8); break; } break; } } break; default: fprintf(stderr, "BImage::renderXImage: unsupported visual\n"); image->data = (char *) d; XDestroyImage(image); return 0; } er = *(OR + x) - *(ort + *(OR + x)); eg = *(og + x) - *(ogt + *(og + x)); eb = *(ob + x) - *(obt + *(ob + x)); *(OR + x + 1) += er; *(og + x + 1) += eg; *(ob + x + 1) += eb; *(nor + x) += er; *(nog + x) += eg; *(nob + x) += eb; *(nor + x + 1) -= (er >> 1) + (er >> 2); *(nog + x + 1) -= (eg >> 1) + (eg >> 2); *(nob + x + 1) -= (eb >> 1) + (eb >> 2); } off += image->width; idata = (pd += image->bytes_per_line); por = OR; OR = nor; nor = por; pog = og; og = nog; nog = pog; pob = ob; ob = nob; nob = pob; } } else { for (y = 0, off = 0; y < height; y++) { for (x = 0; x < width; x++, off++) { r = *(tr + *(red + off)); g = *(tg + *(green + off)); b = *(tb + *(blue + off)); switch (control->v()->c_class) { case StaticColor: case PseudoColor: pixel = (r * cpccpc) + (g * cpc) + b; *idata++ = colors[pixel].pixel; break; case TrueColor: pixel = (r << roff) | (g << goff) | (b << boff); switch (image->byte_order) { case MSBFirst: { switch (image->bits_per_pixel) { case 32: *(idata++) = (pixel >> 24); case 24: *(idata++) = (pixel >> 16); case 16: *(idata++) = (pixel >> 8); default: *(idata++) = (pixel); } break; } case LSBFirst: { *(idata++) = pixel; switch (image->bits_per_pixel) { case 32: *(idata++) = (pixel >> 8); *(idata++) = (pixel >> 16); *(idata++) = (pixel >> 24); break; case 24: *(idata++) = (pixel >> 8); *(idata++) = (pixel >> 16); break; case 16: *(idata++) = (pixel >> 8); break; } break; } } break; default: fprintf(stderr, "BImage::renderXImage: unsupported visual\n"); image->data = (char *) d; XDestroyImage(image); return 0; } } idata = (pd += image->bytes_per_line); } } image->data = (char *) d; return image; } Pixmap BImage::renderPixmap(void) { Pixmap pixmap = XCreatePixmap(control->d(), control->drawable(), width, height, control->depth()); if (pixmap == None) { fprintf(stderr, "BImage::renderPixmap: error creating pixmap\n"); return None; } XImage *image = renderXImage(); if (! image) { XFreePixmap(control->d(), pixmap); return None; } XPutImage(control->d(), pixmap, DefaultGC(control->d(), control->screen()), image, 0, 0, 0, 0, width, height); XDestroyImage(image); return pixmap; } void BImage::background(const BColor &c) { unsigned int i, wh = width * height; bg = c; for (i = 0; i < wh; i++) { *(red + i) = c.red; *(green + i) = c.green; *(blue + i) = c.blue; } } void BImage::bevel1(Bool solid, Bool solidblack) { if (width > 2 && height > 2) { unsigned char *pr = red, *pg = green, *pb = blue; register unsigned char r, g, b, rr ,gg ,bb; register unsigned int w = width, h = height - 1, wh = w * h; if (solid) { if (solidblack) { r = g = b = 0xc0; rr = gg = bb = 0x60; } else { r = bg.red + (bg.red >> 1); if (r < bg.red) r = ~0; g = bg.green + (bg.green >> 1); if (g < bg.green) g = ~0; b = bg.blue + (bg.blue >> 1); if (b < bg.blue) b = ~0; rr = (bg.red >> 2) + (bg.red >> 1); if (rr > bg.red) rr = 0; gg = (bg.green >> 2) + (bg.green >> 1); if (gg > bg.green) gg = 0; bb = (bg.blue >> 2) + (bg.blue >> 1); if (bb > bg.blue) bb = 0; } while (--w) { *pr = r; *pg = g; *pb = b; *((pr++) + wh) = rr; *((pg++) + wh) = gg; *((pb++) + wh) = bb; } *pr = r; *pg = g; *pb = b; *(pr + wh) = rr; *(pg + wh) = gg; *(pb + wh) = bb; pr = red + width; pg = green + width; pb = blue + width; while (--h) { *pr = r; *pg = g; *pb = b; pr += width - 1; pg += width - 1; pb += width - 1; *(pr++) = rr; *(pg++) = gg; *(pb++) = bb; } *pr = r; *pg = g; *pb = b; pr += width - 1; pg += width - 1; pb += width - 1; *pr = rr; *pg = gg; *pb = bb; } else { while (--w) { r = *pr; rr = r + (r >> 1); if (rr < r) rr = ~0; g = *pg; gg = g + (g >> 1); if (gg < g) gg = ~0; b = *pb; bb = b + (b >> 1); if (bb < b) bb = ~0; *pr = rr; *pg = gg; *pb = bb; r = *(pr + wh); rr = (r >> 2) + (r >> 1) ; if (rr > r) rr = 0; g = *(pg + wh); gg = (g >> 2) + (g >> 1); if (gg > g) gg = 0; b = *(pb + wh); bb = (b >> 2) + (b >> 1); if (bb > b) bb = 0; *((pr++) + wh) = rr; *((pg++) + wh) = gg; *((pb++) + wh) = bb; } r = *pr; rr = r + (r >> 1); if (rr < r) rr = ~0; g = *pg; gg = g + (g >> 1); if (gg < g) gg = ~0; b = *pb; bb = b + (b >> 1); if (bb < b) bb = ~0; *pr = rr; *pg = gg; *pb = bb; r = *(pr + wh); rr = (r >> 2) + (r >> 1); if (rr > r) rr = 0; g = *(pg + wh); gg = (g >> 2) + (g >> 1); if (gg > g) gg = 0; b = *(pb + wh); bb = (b >> 2) + (b >> 1); if (bb > b) bb = 0; *(pr + wh) = rr; *(pg + wh) = gg; *(pb + wh) = bb; pr = red + width; pg = green + width; pb = blue + width; while (--h) { r = *pr; rr = r + (r >> 1); if (rr < r) rr = ~0; g = *pg; gg = g + (g >> 1); if (gg < g) gg = ~0; b = *pb; bb = b + (b >> 1); if (bb < b) bb = ~0; *pr = rr; *pg = gg; *pb = bb; pr += width - 1; pg += width - 1; pb += width - 1; r = *pr; rr = (r >> 2) + (r >> 1); if (rr > r) rr = 0; g = *pg; gg = (g >> 2) + (g >> 1); if (gg > g) gg = 0; b = *pb; bb = (b >> 2) + (b >> 1); if (bb > b) bb = 0; *(pr++) = rr; *(pg++) = gg; *(pb++) = bb; } r = *pr; rr = r + (r >> 1); if (rr < r) rr = ~0; g = *pg; gg = g + (g >> 1); if (gg < g) gg = ~0; b = *pb; bb = b + (b >> 1); if (bb < b) bb = ~0; *pr = rr; *pg = gg; *pb = bb; pr += width - 1; pg += width - 1; pb += width - 1; r = *pr; rr = (r >> 2) + (r >> 1); if (rr > r) rr = 0; g = *pg; gg = (g >> 2) + (g >> 1); if (gg > g) gg = 0; b = *pb; bb = (b >> 2) + (b >> 1); if (bb > b) bb = 0; *pr = rr; *pg = gg; *pb = bb; } } } void BImage::bevel2(Bool solid, Bool solidblack) { if (width > 4 && height > 4) { unsigned char r, g, b, rr ,gg ,bb, *pr = red + width + 1, *pg = green + width + 1, *pb = blue + width + 1; unsigned int w = width - 2, h = height - 1, wh = width * (height - 3); if (solid) { if (solidblack) { r = g = b = 0xc0; rr = gg = bb = 0x60; } else { r = bg.red + (bg.red >> 1); if (r < bg.red) r = ~0; g = bg.green + (bg.green >> 1); if (g < bg.green) g = ~0; b = bg.blue + (bg.blue >> 1); if (b < bg.blue) b = ~0; rr = (bg.red >> 2) + (bg.red >> 1); if (rr > bg.red) rr = 0; gg = (bg.green >> 2) + (bg.green >> 1); if (gg > bg.green) gg = 0; bb = (bg.blue >> 2) + (bg.blue >> 1); if (bb > bg.blue) bb = 0; } while (--w) { *pr = r; *pg = g; *pb = b; *((pr++) + wh) = rr; *((pg++) + wh) = gg; *((pb++) + wh) = bb; } pr = red + width; pg = green + width; pb = blue + width; while (--h) { *(++pr) = r; *(++pg) = g; *(++pb) = b; pr += width - 3; pg += width - 3; pb += width - 3; *(pr++) = rr; *(pg++) = gg; *(pb++) = bb; pr++; pg++; pb++; } } else { while (--w) { r = *pr; rr = r + (r >> 1); if (rr < r) rr = ~0; g = *pg; gg = g + (g >> 1); if (gg < g) gg = ~0; b = *pb; bb = b + (b >> 1); if (bb < b) bb = ~0; *pr = rr; *pg = gg; *pb = bb; r = *(pr + wh); rr = (r >> 2) + (r >> 1); if (rr > r) rr = 0; g = *(pg + wh); gg = (g >> 2) + (g >> 1); if (gg > g) gg = 0; b = *(pb + wh); bb = (b >> 2) + (b >> 1); if (bb > b) bb = 0; *((pr++) + wh) = rr; *((pg++) + wh) = gg; *((pb++) + wh) = bb; } pr = red + width; pg = green + width; pb = blue + width; while (--h) { r = *pr; rr = r + (r >> 1); if (rr < r) rr = ~0; g = *pg; gg = g + (g >> 1); if (gg < g) gg = ~0; b = *pb; bb = b + (b >> 1); if (bb < b) bb = ~0; *(++pr) = rr; *(++pg) = gg; *(++pb) = bb; pr += width - 3; pg += width - 3; pb += width - 3; r = *pr; rr = (r >> 2) + (r >> 1); if (rr > r) rr = 0; g = *pg; gg = (g >> 2) + (g >> 1); if (gg > g) gg = 0; b = *pb; bb = (b >> 2) + (b >> 1); if (bb > b) bb = 0; *(pr++) = rr; *(pg++) = gg; *(pb++) = bb; pr++; pg++; pb++; } } } } void BImage::invert(void) { register unsigned int i, j, wh = (width * height) - 1; unsigned char tmp; for (i = 0, j = wh; j > i; j--, i++) { tmp = *(red + j); *(red + j) = *(red + i); *(red + i) = tmp; tmp = *(green + j); *(green + j) = *(green + i); *(green + i) = tmp; tmp = *(blue + j); *(blue + j) = *(blue + i); *(blue + i) = tmp; } } void BImage::dgradient(void) { float fr = (float) from.red, fg = (float) from.green, fb = (float) from.blue, tr = (float) to.red, tg = (float) to.green, tb = (float) to.blue, w = (float) (width * 2), h = (float) (height * 2), yr = 0.0, yg = 0.0, yb = 0.0, xr, xg, xb, drx, dgx, dbx, dry, dgy, dby; unsigned char *pr = red, *pg = green, *pb = blue; register unsigned int x, y; drx = dry = (tr - fr); dgx = dgy = (tg - fg); dbx = dby = (tb - fb); drx /= w; dgx /= w; dbx /= w; dry /= h; dgy /= h; dby /= h; for (y = 0; y < height; y++) { xr = fr + yr; xg = fg + yg; xb = fb + yb; for (x = 0; x < width; x++) { *(pr++) = (unsigned char) (xr); *(pg++) = (unsigned char) (xg); *(pb++) = (unsigned char) (xb); xr += drx; xg += dgx; xb += dbx; } yr += dry; yg += dgy; yb += dby; } } void BImage::hgradient(void) { float fr, fg, fb, tr, tg, tb, drx, dgx, dbx, xr, xg, xb, w = (float) width; unsigned char *pr, *pg, *pb, *rr, *gg, *bb; register unsigned int x, y; xr = fr = (float) from.red; xg = fg = (float) from.green; xb = fb = (float) from.blue; tr = (float) to.red; tg = (float) to.green; tb = (float) to.blue; drx = (tr - fr) / w; dgx = (tg - fg) / w; dbx = (tb - fb) / w; pr = red; pg = green; pb = blue; // this renders one line of the hgradient for (x = 0; x < width; x++) { *(pr++) = (unsigned char) (xr); *(pg++) = (unsigned char) (xg); *(pb++) = (unsigned char) (xb); xr += drx; xg += dgx; xb += dbx; } // and this copies to the rest of the image for (y = 1; y < height; y++) { rr = red; gg = green; bb = blue; for (x = 0; x < width; x++) { *(pr++) = *(rr++); *(pg++) = *(gg++); *(pb++) = *(bb++); } } } void BImage::vgradient(void) { float fr, fg, fb, tr, tg, tb, dry, dgy, dby, yr, yg, yb, h = (float) height; unsigned char *pr = red, *pg = green, *pb = blue; register unsigned char r, g, b; register unsigned int x, y; yr = fr = (float) from.red; yg = fg = (float) from.green; yb = fb = (float) from.blue; tr = (float) to.red; tg = (float) to.green; tb = (float) to.blue; dry = (tr - fr) / h; dgy = (tg - fg) / h; dby = (tb - fb) / h; for (y = 0; y < height; y++) { yr += dry; yg += dgy; yb += dby; r = (unsigned char) (yr); g = (unsigned char) (yg); b = (unsigned char) (yb); for (x = 0; x < width; x++) { *(pr++) = r; *(pg++) = g; *(pb++) = b; } } } // ************************************************************************* // Image control class code // ************************************************************************* BImageControl::BImageControl() { display = wm->getDisplay(); screen_depth = wm->getDepth(); window = wm->getRootWindow(); screen_number = wm->getScreen(); colors = 0; colors_per_channel = ncolors = 0; int count; XPixmapFormatValues *pmv = XListPixmapFormats(display, &count); root_colormap = DefaultColormap(display, screen_number); if (pmv) { bits_per_pixel = 0; for (int i = 0; i < count; i++) if (pmv[i].depth == screen_depth) { bits_per_pixel = pmv[i].bits_per_pixel; break; } } if (bits_per_pixel == 0) bits_per_pixel = screen_depth; if (pmv) XFree(pmv); red_offset = green_offset = blue_offset = 0; switch (wm->getVisual()->c_class) { case TrueColor: { int i; // compute tables for red channel unsigned long mask = wm->getVisual()->red_mask, emask = mask; while (! (mask & 1)) { red_offset++; mask >>= 1; } for (i = 0; i < 256; i++) { rmask_table[i] = (i * mask + 0x7f) / 0xff; rerr_table[i] = ((rmask_table[i] << 8) / (emask >> red_offset)); } // compute tables for green channel emask = mask = wm->getVisual()->green_mask; while (! (mask & 1)) { green_offset++; mask >>= 1; } for (i = 0; i < 256; i++) { gmask_table[i] = (i * mask + 0x7f) / 0xff; gerr_table[i] = ((gmask_table[i] << 8) / (emask >> green_offset)); } // compute tables for blue channel emask = mask = wm->getVisual()->blue_mask; while (! (mask & 1)) { blue_offset++; mask >>= 1; } for (i = 0; i < 256; i++) { bmask_table[i] = (i * mask + 0x7f) / 0xff; berr_table[i] = ((bmask_table[i] << 8) / (emask >> blue_offset)); } } break; case PseudoColor: case StaticColor: { colors_per_channel = wm->getColorsPerChannel(); ncolors = colors_per_channel * colors_per_channel * colors_per_channel; if (ncolors > (1 << screen_depth)) { colors_per_channel = (1 << screen_depth) / 3; ncolors = colors_per_channel * colors_per_channel * colors_per_channel; } if (colors_per_channel < 2 || ncolors > (1 << screen_depth)) { fprintf(stderr, "BImageControl::BImageControl: invalid colormap size %d " "(%d/%d/%d)", ncolors, colors_per_channel, colors_per_channel, colors_per_channel); exit(1); } colors = new XColor[ncolors]; if (! colors) { fprintf(stderr, "BImageControl::BImageControl: error allocating " "colormap\n"); exit(1); } int i = 0, ii, p, r, g, b; unsigned long mask = colors_per_channel - 1; for (i = 0; i < 256; i++) { rmask_table[i] = gmask_table[i] = bmask_table[i] = (i * mask + 0x7f) / 0xff; rerr_table[i] = gerr_table[i] = berr_table[i] = ((rmask_table[i] << 8) / (mask)); } for (int r = 0, i = 0; r < colors_per_channel; r++) for (int g = 0; g < colors_per_channel; g++) for (int b = 0; b < colors_per_channel; b++, i++) { colors[i].red = (r * 0xffff) / (colors_per_channel - 1); colors[i].green = (g * 0xffff) / (colors_per_channel - 1); colors[i].blue = (b * 0xffff) / (colors_per_channel - 1);; colors[i].flags = DoRed|DoGreen|DoBlue; } //blackbox->syncGrabServer(); XGrabServer(wm->getDisplay()); XSync(wm->getDisplay(), False); for (i = 0; i < ncolors; i++) if (! XAllocColor(display, root_colormap, &colors[i])) { fprintf(stderr, "couldn't alloc color %i %i %i\n", colors[i].red, colors[i].green, colors[i].blue); colors[i].flags = 0; } else colors[i].flags = DoRed|DoGreen|DoBlue; //blackbox->ungrabServer(); XUngrabServer(wm->getDisplay()); XColor icolors[256]; int incolors = (((1 << screen_depth) > 256) ? 256 : (1 << screen_depth)); for (i = 0; i < incolors; i++) icolors[i].pixel = i; XQueryColors(display, root_colormap, icolors, incolors); for (i = 0; i < ncolors; i++) { if (! colors[i].flags) { unsigned long chk = 0xffffffff, pixel, close = 0; p = 2; while (p--) { for (ii = 0; ii < incolors; ii++) { r = (colors[i].red - icolors[i].red) >> 8; g = (colors[i].green - icolors[i].green) >> 8; b = (colors[i].blue - icolors[i].blue) >> 8; pixel = (r * r) + (g * g) + (b * b); if (pixel < chk) { chk = pixel; close = ii; } colors[i].red = icolors[close].red; colors[i].green = icolors[close].green; colors[i].blue = icolors[close].blue; if (XAllocColor(display, root_colormap, &colors[i])) { colors[i].flags = DoRed|DoGreen|DoBlue; break; } } } } } break; } case GrayScale: case StaticGray: fprintf(stderr, "BImageControl::BImageControl: GrayScale/StaticGray " "visual unsupported\n"); break; default: fprintf(stderr, "BImageControl::BImageControl: unsupported visual %d\n", wm->getVisual()->c_class); exit(1); } cache = new LinkedList; dither_buf_width = 0; red_err = green_err = blue_err = next_red_err = next_green_err = next_blue_err = 0; } BImageControl::~BImageControl(void) { if (red_err) delete [] red_err; if (green_err) delete [] green_err; if (blue_err) delete [] blue_err; if (next_red_err) delete [] next_red_err; if (next_green_err) delete [] next_green_err; if (next_blue_err) delete [] next_blue_err; if (colors) { unsigned long *pixels = new unsigned long [ncolors]; int i; for (i = 0; i < ncolors; i++) *(pixels + i) = (*(colors + i)).pixel; XFreeColors(display, DefaultColormap(display, screen_number), pixels, ncolors, 0); delete [] colors; } if (cache->count()) { //printf("BImageContol::~BImageControl: pixmap cache - " // "releasing %d pixmaps\n", n); //for (i = 0; i < n; i++) { // Cache *tmp = cache->first(); // XFreePixmap(display, tmp->pixmap); // cache->remove(tmp); // delete tmp; //} LinkedListIterator it(cache); for (; it.current(); it++) { XFreePixmap(display, it.current()->pixmap); } cache->removeAll(); } delete cache; } Bool BImageControl::dither(void) { return wm->getImageDither(); } Visual *BImageControl::v(void) { return wm->getVisual(); } // ************************************************************************* // pixmap cache control // ************************************************************************* Pixmap BImageControl::searchCache( //char* name, unsigned int width, unsigned int height, unsigned long texture, const BColor &c1, const BColor &c2) { if (cache->count()) { LinkedListIterator it(cache); for (; it.current(); it++) { if ( //(strcmp(it.current()->name, name)==0) && (it.current()->width == width) && (it.current()->height == height) && (it.current()->texture == texture) && (it.current()->pixel1 == c1.pixel)) if (texture & BImage_Gradient) { if (it.current()->pixel2 == c2.pixel) { it.current()->count++; return it.current()->pixmap; } } else { it.current()->count++; return it.current()->pixmap; } } } return None; } Pixmap BImageControl::renderImage(/*char* name,*/ unsigned int width, unsigned int height, unsigned long texture, const BColor &c1, const BColor &c2) { Pixmap pixmap = searchCache(/*name,*/ width, height, texture, c1, c2); if (pixmap) return pixmap; BImage image(this, width, height); pixmap = image.render(texture, c1, c2); if (pixmap) { Cache *tmp = new Cache; //tmp->name = name; tmp->pixmap = pixmap; tmp->width = width; tmp->height = height; tmp->count = 1; tmp->texture = texture; tmp->pixel1 = c1.pixel; if (texture & BImage_Gradient) tmp->pixel2 = c2.pixel; else tmp->pixel2 = 0l; cache->insert(tmp); return pixmap; } return None; } void BImageControl::removeAllImages() { LinkedListIterator it(cache); for (; it.current(); it++) XFreePixmap(display, it.current()->pixmap); cache->removeAll(); } void BImageControl::removeImage(Pixmap pixmap) { if (pixmap) { LinkedListIterator it(cache); for (; it.current(); it++) { if (it.current()->pixmap == pixmap) { Cache *tmp = it.current(); tmp->count--; if (! tmp->count) { XFreePixmap(display, tmp->pixmap); cache->remove(tmp); delete tmp; } return; } } } } unsigned long BImageControl::getColor(const char *colorname, unsigned char *r, unsigned char *g, unsigned char *b) { XColor color; XWindowAttributes attributes; XGetWindowAttributes(display, window, &attributes); color.pixel = 0; if (!XParseColor(display, attributes.colormap, colorname, &color)) { fprintf(stderr, "BImageControl::getColor: color parse error: \"%s\"\n", colorname); } else if (!XAllocColor(display, attributes.colormap, &color)) { fprintf(stderr, "BImageControl::getColor: color alloc error: \"%s\"\n", colorname); } if (color.red == 65535) *r = 0xff; else *r = (unsigned char) (color.red / 0xff); if (color.green == 65535) *g = 0xff; else *g = (unsigned char) (color.green / 0xff); if (color.blue == 65535) *b = 0xff; else *b = (unsigned char) (color.blue / 0xff); return color.pixel; } unsigned long BImageControl::getColor(const char *colorname) { XColor color; XWindowAttributes attributes; XGetWindowAttributes(display, window, &attributes); color.pixel = 0; if (!XParseColor(display, attributes.colormap, colorname, &color)) { fprintf(stderr, "BImageControl::getColor: color parse error: \"%s\"\n", colorname); } else if (!XAllocColor(display, attributes.colormap, &color)) { fprintf(stderr, "BImageControl::getColor: color alloc error: \"%s\"\n", colorname); } return color.pixel; } void BImageControl::getMaskTables(unsigned short **rmt, unsigned short **gmt, unsigned short **bmt, int *roff, int *goff, int *boff) { if (rmt) *rmt = rmask_table; if (gmt) *gmt = gmask_table; if (bmt) *bmt = bmask_table; if (roff) *roff = red_offset; if (goff) *goff = green_offset; if (boff) *boff = blue_offset; } void BImageControl::getColorTable(XColor **c, int *n) { if (c) *c = colors; if (n) *n = ncolors; } void BImageControl::getDitherBuffers(unsigned int w, short **r, short **g, short **b, short **nr, short **ng, short **nb, unsigned short **ret, unsigned short **get, unsigned short **bet) { if (w > dither_buf_width) { if (red_err) delete [] red_err; if (green_err) delete [] green_err; if (blue_err) delete [] blue_err; if (next_red_err) delete [] next_red_err; if (next_green_err) delete [] next_green_err; if (next_blue_err) delete [] next_blue_err; dither_buf_width = w; red_err = new short[dither_buf_width]; green_err = new short[dither_buf_width]; blue_err = new short[dither_buf_width]; next_red_err = new short[dither_buf_width]; next_green_err = new short[dither_buf_width]; next_blue_err = new short[dither_buf_width]; } *r = red_err; *g = green_err; *b = blue_err; *nr = next_red_err; *ng = next_green_err; *nb = next_blue_err; *ret = rerr_table; *get = gerr_table; *bet = berr_table; } void BImageControl::installRootColormap(void) { //blackbox->syncGrabServer(); XGrabServer(wm->getDisplay()); XSync(wm->getDisplay(), False); Bool install = True; int i = 0, ncmap = 0; Colormap *cmaps = XListInstalledColormaps(display, window, &ncmap); if (cmaps) { for (i = 0; i < ncmap; i++) if (*(cmaps + i) == root_colormap) install = False; if (install) XInstallColormap(display, root_colormap); XFree(cmaps); } //blackbox->ungrabServer(); XUngrabServer(wm->getDisplay()); } sapphire-0.15.8/LICENSE0100644000175000001440000004307607141165453012770 0ustar asusers GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. sapphire-0.15.8/data/0040755000175000001440000000000007201726222012657 5ustar asuserssapphire-0.15.8/data/menu/0040755000175000001440000000000007201726245013630 5ustar asuserssapphire-0.15.8/data/menu/default0100644000175000001440000000162407414166227015203 0ustar asusersmenu(Sapphire 0.15.x) { submenu (terminals) { exec (xterm) {xterm -bg black -fg white} exec (rxvt) {rxvt -bg black -fg white} } submenu (internet) { exec (netscape) {netscape} exec (licq) {licq} } submenu (utilities) { submenu (editors) { exec (nedit) {nedit} exec (xedit) {xedit} exec (emacs) {emacs} } submenu (other) { exec (xload) {xload} exec (xosview) {xosview} exec (xclock) {xclock} exec (xcalc) {xcalc} } } submenu (fun) { exec (xeyes) {xeyes} exec (xlogo) {xlogo} } submenu (themes) { theme (default) {/usr/share/sapphire/themes/default.theme} theme (darkblue){/usr/share/sapphire/themes/darkblue.theme} theme (slate) {/usr/share/sapphire/themes/slate.theme} theme (rose) {/usr/share/sapphire/themes/rose.theme} theme (gray) {/usr/share/sapphire/themes/gray.theme} } separator reconfigure restart exit } sapphire-0.15.8/data/themes/0040755000175000001440000000000007201726254014151 5ustar asuserssapphire-0.15.8/data/themes/darkblue.theme0100644000175000001440000000531507371014232016761 0ustar asuserstitlebar.style: Gradient Horizontal Raised Bevel button.style: Gradient Diagonal Raised Bevel toolbar.style: Gradient Vertical Flat Bevel clock.style: Gradient Diagonal Sunken Bevel menu.style: Gradient Diagonal Flat menutitle.style: Gradient Horizontal Flat Bevel menuselect.style: Solid Flat resize.style: Gradient Diagonal Raised Bevel handle.style: Gradient Diagonal Raised Bevel root.background: true root.style: Solid titlebar.color.from.red: 0 titlebar.color.from.green: 0 titlebar.color.from.blue: 73 titlebar.color.to.red: 255 titlebar.color.to.green: 255 titlebar.color.to.blue: 255 titlebarFocus.color.from.red: 100 titlebarFocus.color.from.green: 100 titlebarFocus.color.from.blue: 100 titlebarFocus.color.to.red: 255 titlebarFocus.color.to.green: 255 titlebarFocus.color.to.blue: 255 button.color.from.red: 255 button.color.from.green: 255 button.color.from.blue: 255 button.color.to.red: 69 button.color.to.green: 84 button.color.to.blue: 115 clock.color.from.red: 0 clock.color.from.green: 0 clock.color.from.blue: 73 clock.color.to.red: 255 clock.color.to.green: 255 clock.color.to.blue: 255 toolbar.color.from.red: 0 toolbar.color.from.green: 0 toolbar.color.from.blue: 73 toolbar.color.to.red: 255 toolbar.color.to.green: 255 toolbar.color.to.blue: 255 menu.color.from.red: 111 menu.color.from.green: 111 menu.color.from.blue: 111 menu.color.to.red: 255 menu.color.to.green: 255 menu.color.to.blue: 255 menuTitle.color.from.red: 255 menuTitle.color.from.green: 255 menuTitle.color.from.blue: 255 menuTitle.color.to.red: 0 menuTitle.color.to.green: 0 menuTitle.color.to.blue: 73 menuSelect.color.from.red: 200 menuSelect.color.from.green: 200 menuSelect.color.from.blue: 200 menuSelect.color.to.red: 255 menuSelect.color.to.green: 255 menuSelect.color.to.blue: 255 resize.color.from.red: 200 resize.color.from.green: 200 resize.color.from.blue: 200 resize.color.to.red: 255 resize.color.to.green: 255 resize.color.to.blue: 255 handle.color.from.red: 200 handle.color.from.green: 200 handle.color.from.blue: 200 handle.color.to.red: 255 handle.color.to.green: 255 handle.color.to.blue: 255 font.color.from.red: 255 font.color.from.green: 255 font.color.from.blue: 255 font.color.to.red: 111 font.color.to.green: 111 font.color.to.blue: 111 menufont.color.from.red: 0 menufont.color.from.green: 0 menufont.color.from.blue: 0 menufont.color.to.red: 0 menufont.color.to.green: 0 menufont.color.to.blue: 0 root.color.from.red: 0 root.color.from.green: 0 root.color.from.blue: 73 root.color.to.red: 0 root.color.to.green: 0 root.color.to.blue: 0 font: -*-lucida-medium-r-normal-*-10-*-*-*-*-*-*-* menufont: -*-lucida-medium-r-normal-*-10-*-*-*-*-*-*-* sapphire-0.15.8/data/themes/default.theme0100644000175000001440000000436307371013272016621 0ustar asuserstitlebar.style: Gradient Horizontal Raised Bevel button.style: Gradient Diagonal Raised Bevel toolbar.style: Gradient Vertical Flat Bevel clock.style: Gradient Diagonal Sunken Bevel menu.style: Gradient Diagonal Flat menutitle.style: Gradient Horizontal Flat Bevel menuselect.style: Solid Flat resize.style: Gradient Diagonal Raised Bevel handle.style: Gradient Diagonal Raised Bevel root.background: true root.style: Solid titlebar.color.from.red: 89 titlebar.color.from.green: 107 titlebar.color.from.blue: 137 titlebar.color.to.red: 200 titlebar.color.to.green: 200 titlebar.color.to.blue: 200 titlebarFocus.color.from.red: 100 titlebarFocus.color.from.green: 100 titlebarFocus.color.from.blue: 100 titlebarFocus.color.to.red: 255 titlebarFocus.color.to.green: 255 titlebarFocus.color.to.blue: 255 button.color.from.red: 181 button.color.from.green: 181 button.color.from.blue: 181 button.color.to.red: 225 button.color.to.green: 225 button.color.to.blue: 225 menu.color.from.red: 100 menu.color.from.green: 100 menu.color.from.blue: 100 menu.color.to.red: 255 menu.color.to.green: 255 menu.color.to.blue: 255 toolbar.color.from.red: 117 toolbar.color.from.green: 142 toolbar.color.from.blue: 183 toolbar.color.to.red: 70 toolbar.color.to.green: 70 toolbar.color.to.blue: 70 menuTitle.color.from.red: 89 menuTitle.color.from.green: 107 menuTitle.color.from.blue: 137 menuTitle.color.to.red: 200 menuTitle.color.to.green: 200 menuTitle.color.to.blue: 200 menuSelect.color.from.red: 200 menuSelect.color.from.green: 200 menuSelect.color.from.blue: 200 menuSelect.color.to.red: 255 menuSelect.color.to.green: 255 menuSelect.color.to.blue: 255 resize.color.from.red: 200 resize.color.from.green: 200 resize.color.from.blue: 200 resize.color.to.red: 255 resize.color.to.green: 255 resize.color.to.blue: 255 handle.color.from.red: 200 handle.color.from.green: 200 handle.color.from.blue: 200 handle.color.to.red: 255 handle.color.to.green: 255 handle.color.to.blue: 255 root.color.from.red: 89 root.color.from.green: 107 root.color.from.blue: 137 root.color.to.red: 0 root.color.to.green: 0 root.color.to.blue: 0 font: -*-lucida-medium-r-normal-*-10-*-*-*-*-*-*-* menufont: -*-lucida-medium-r-normal-*-10-*-*-*-*-*-*-* sapphire-0.15.8/data/themes/gray.theme0100644000175000001440000000502207371014215016126 0ustar asuserstitlebar.style: Gradient Horizontal Raised Bevel button.style: Gradient Diagonal Raised Bevel toolbar.style: Gradient Vertical Flat Bevel clock.style: Gradient Diagonal Sunken Bevel menu.style: Gradient Diagonal Flat menutitle.style: Gradient Horizontal Flat Bevel menuselect.style: Solid Flat resize.style: Gradient Diagonal Raised Bevel handle.style: Gradient Diagonal Raised Bevel root.background: true root.style: Solid titlebar.color.from.red: 122 titlebar.color.from.green: 125 titlebar.color.from.blue: 137 titlebar.color.to.red: 200 titlebar.color.to.green: 200 titlebar.color.to.blue: 200 button.color.from.red: 225 button.color.from.green: 225 button.color.from.blue: 225 button.color.to.red: 111 button.color.to.green: 111 button.color.to.blue: 111 clock.color.from.red: 122 clock.color.from.green: 125 clock.color.from.blue: 137 clock.color.to.red: 225 clock.color.to.green: 225 clock.color.to.blue: 225 toolbar.color.from.red: 122 toolbar.color.from.green: 125 toolbar.color.from.blue: 137 toolbar.color.to.red: 225 toolbar.color.to.green: 225 toolbar.color.to.blue: 225 menu.color.from.red: 122 menu.color.from.green: 125 menu.color.from.blue: 137 menu.color.to.red: 255 menu.color.to.green: 255 menu.color.to.blue: 255 menuTitle.color.from.red: 147 menuTitle.color.from.green: 150 menuTitle.color.from.blue: 160 menuTitle.color.to.red: 200 menuTitle.color.to.green: 200 menuTitle.color.to.blue: 200 menuSelect.color.from.red: 111 menuSelect.color.from.green: 111 menuSelect.color.from.blue: 111 menuSelect.color.to.red: 255 menuSelect.color.to.green: 255 menuSelect.color.to.blue: 255 resize.color.from.red: 200 resize.color.from.green: 200 resize.color.from.blue: 200 resize.color.to.red: 255 resize.color.to.green: 255 resize.color.to.blue: 255 handle.color.from.red: 122 handle.color.from.green: 125 handle.color.from.blue: 137 handle.color.to.red: 255 handle.color.to.green: 255 handle.color.to.blue: 255 font.color.from.red: 0 font.color.from.green: 0 font.color.from.blue: 0 font.color.to.red: 0 font.color.to.green: 0 font.color.to.blue: 0 menufont.color.from.red: 0 menufont.color.from.green: 0 menufont.color.from.blue: 0 menufont.color.to.red: 0 menufont.color.to.green: 0 menufont.color.to.blue: 0 root.color.from.red: 122 root.color.from.green: 125 root.color.from.blue: 137 root.color.to.red: 225 root.color.to.green: 225 root.color.to.blue: 225 font: -*-lucida-medium-r-normal-*-10-*-*-*-*-*-*-* menufont: -*-lucida-medium-r-normal-*-10-*-*-*-*-*-*-* sapphire-0.15.8/data/themes/rose.theme0100644000175000001440000000502207371014204016132 0ustar asuserstitlebar.style: Gradient Horizontal Raised Bevel button.style: Gradient Diagonal Raised Bevel toolbar.style: Gradient Vertical Flat Bevel clock.style: Gradient Diagonal Sunken Bevel menu.style: Gradient Diagonal Flat menutitle.style: Gradient Horizontal Flat Bevel menuselect.style: Solid Flat resize.style: Gradient Diagonal Raised Bevel handle.style: Gradient Diagonal Raised Bevel root.background: true root.style: Solid titlebar.color.from.red: 165 titlebar.color.from.green: 106 titlebar.color.from.blue: 106 titlebar.color.to.red: 200 titlebar.color.to.green: 200 titlebar.color.to.blue: 200 button.color.from.red: 225 button.color.from.green: 225 button.color.from.blue: 225 button.color.to.red: 111 button.color.to.green: 111 button.color.to.blue: 111 clock.color.from.red: 165 clock.color.from.green: 106 clock.color.from.blue: 106 clock.color.to.red: 225 clock.color.to.green: 225 clock.color.to.blue: 225 toolbar.color.from.red: 165 toolbar.color.from.green: 106 toolbar.color.from.blue: 106 toolbar.color.to.red: 225 toolbar.color.to.green: 225 toolbar.color.to.blue: 225 menu.color.from.red: 165 menu.color.from.green: 106 menu.color.from.blue: 106 menu.color.to.red: 255 menu.color.to.green: 255 menu.color.to.blue: 255 menuTitle.color.from.red: 198 menuTitle.color.from.green: 127 menuTitle.color.from.blue: 127 menuTitle.color.to.red: 200 menuTitle.color.to.green: 200 menuTitle.color.to.blue: 200 menuSelect.color.from.red: 198 menuSelect.color.from.green: 127 menuSelect.color.from.blue: 127 menuSelect.color.to.red: 255 menuSelect.color.to.green: 255 menuSelect.color.to.blue: 255 resize.color.from.red: 200 resize.color.from.green: 200 resize.color.from.blue: 200 resize.color.to.red: 255 resize.color.to.green: 255 resize.color.to.blue: 255 handle.color.from.red: 165 handle.color.from.green: 106 handle.color.from.blue: 106 handle.color.to.red: 255 handle.color.to.green: 255 handle.color.to.blue: 255 font.color.from.red: 0 font.color.from.green: 0 font.color.from.blue: 0 font.color.to.red: 0 font.color.to.green: 0 font.color.to.blue: 0 menufont.color.from.red: 0 menufont.color.from.green: 0 menufont.color.from.blue: 0 menufont.color.to.red: 0 menufont.color.to.green: 0 menufont.color.to.blue: 0 root.color.from.red: 165 root.color.from.green: 106 root.color.from.blue: 106 root.color.to.red: 225 root.color.to.green: 225 root.color.to.blue: 225 font: -*-lucida-medium-r-normal-*-10-*-*-*-*-*-*-* menufont: -*-lucida-medium-r-normal-*-10-*-*-*-*-*-*-* sapphire-0.15.8/data/themes/slate.theme0100644000175000001440000000532307371014333016301 0ustar asuserstitlebar.style: Gradient Horizontal Raised Bevel button.style: Gradient Diagonal Raised Bevel toolbar.style: Gradient Vertical Flat Bevel clock.style: Gradient Diagonal Sunken Bevel menu.style: Gradient Diagonal Flat menutitle.style: Gradient Horizontal Flat Bevel menuselect.style: Solid Flat resize.style: Gradient Diagonal Raised Bevel handle.style: Gradient Diagonal Raised Bevel root.background: true root.style: Solid titlebar.color.from.red: 111 titlebar.color.from.green: 124 titlebar.color.from.blue: 132 titlebar.color.to.red: 200 titlebar.color.to.green: 200 titlebar.color.to.blue: 200 titlebarFocus.color.from.red: 100 titlebarFocus.color.from.green: 100 titlebarFocus.color.from.blue: 100 titlebarFocus.color.to.red: 255 titlebarFocus.color.to.green: 255 titlebarFocus.color.to.blue: 255 button.color.from.red: 225 button.color.from.green: 225 button.color.from.blue: 225 button.color.to.red: 111 button.color.to.green: 111 button.color.to.blue: 111 clock.color.from.red: 84 clock.color.from.green: 98 clock.color.from.blue: 101 clock.color.to.red: 255 clock.color.to.green: 255 clock.color.to.blue: 255 toolbar.color.from.red: 111 toolbar.color.from.green: 124 toolbar.color.from.blue: 132 toolbar.color.to.red: 70 toolbar.color.to.green: 70 toolbar.color.to.blue: 70 menu.color.from.red: 111 menu.color.from.green: 124 menu.color.from.blue: 132 menu.color.to.red: 255 menu.color.to.green: 255 menu.color.to.blue: 255 menuTitle.color.from.red: 84 menuTitle.color.from.green: 98 menuTitle.color.from.blue: 101 menuTitle.color.to.red: 200 menuTitle.color.to.green: 200 menuTitle.color.to.blue: 200 menuSelect.color.from.red: 200 menuSelect.color.from.green: 200 menuSelect.color.from.blue: 200 menuSelect.color.to.red: 255 menuSelect.color.to.green: 255 menuSelect.color.to.blue: 255 resize.color.from.red: 200 resize.color.from.green: 200 resize.color.from.blue: 200 resize.color.to.red: 255 resize.color.to.green: 255 resize.color.to.blue: 255 handle.color.from.red: 200 handle.color.from.green: 200 handle.color.from.blue: 200 handle.color.to.red: 255 handle.color.to.green: 255 handle.color.to.blue: 255 font.color.from.red: 0 font.color.from.green: 0 font.color.from.blue: 0 font.color.to.red: 0 font.color.to.green: 0 font.color.to.blue: 0 menufont.color.from.red: 0 menufont.color.from.green: 0 menufont.color.from.blue: 0 menufont.color.to.red: 0 menufont.color.to.green: 0 menufont.color.to.blue: 0 root.color.from.red: 84 root.color.from.green: 98 root.color.from.blue: 101 root.color.to.red: 0 root.color.to.green: 0 root.color.to.blue: 0 font: -*-lucida-medium-r-normal-*-10-*-*-*-*-*-*-* menufont: -*-lucida-medium-r-normal-*-10-*-*-*-*-*-*-* sapphire-0.15.8/iconmenu.cc0100644000175000001440000000431607371023033014071 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "sapphire.hh" IconMenu::IconMenu() : BaseMenu() { setMenuTitle("Icons"); update_all(); wm->addToExtraMenuList(this); } IconMenu::~IconMenu(void) { } void IconMenu::insert(char *name, Client *c) { BaseMenuItem *item = new BaseMenuItem(); if(name==NULL) { char *noname = "no name"; name = noname; } item->name = new char[strlen(name)+1]; strcpy(item->name, name); item->client = c; // defaults item->icon = None; item->sub = None; item->isSelected=False; item->exec = ""; item->function = 0; item->item_x = item->item_y = 0; getMenuItemList()->insert(item); } void IconMenu::addIcon(char *name, Client *c) { insert(name, c); update_all(); } // if I wanted all sub menus to have the same button behavior I would declare // a class derived from BaseMenu which would only define the button functions // and then derive the main menu and sub menus from that so all menus would // have the same behavior when the items were clicked. // // With the code the way it is now only the first main menu will have the button // behavior defined by these functions. void IconMenu::handle_button1_press(BaseMenuItem *curr) { if (curr) { curr->client->unhide(curr->client); hide(this); remove(curr); update_all(); } } void IconMenu::handle_button1_release(BaseMenuItem *curr) { } sapphire-0.15.8/NEWS0100644000175000001440000000055407201430561012444 0ustar asusersSapphire - News about development. There are two major things going on. 1. Rewrite codename Blueberry is being developed. Its just started and only 3 days into the effort. 2. Sapphire's current codebase is being updated. Lots of code clean up will be done. Various other tweaks mostly internal will be done. -- Updated: 5 Nov 2000 frankhale@lycos.com sapphire-0.15.8/README0100644000175000001440000000026507371007625012635 0ustar asusersSapphire - Just another X11R6 window manager To install Sapphire: type these commands at the commandline. tar zxvf sapphire-0.15.x.tar.gz cd sapphire-0.15.x make su make install sapphire-0.15.8/linkedlist.cc0100644000175000001440000001041007414165525014421 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "linkedlist.hh" using namespace std; _LinkedList::_LinkedList() { // Get our linked list started. // Do our default initialization here. head = NULL; tail = NULL; iter = NULL; elements=0; } _LinkedList::~_LinkedList() { // remove each element removeAll(); } void _LinkedList::removeAll() { Element *temp; //holds the element to be deleted while(head != NULL) //while anything is in the LL { temp = head; //grab the top item head=head->next; //move the next up delete temp; //and delete the old top. } //now we know everything is gone, so reset to empty state tail=iter=0; elements=0; } // Inserts an element onto the end of the list. void _LinkedList::insert(void *data) { // We want to add an element by its data. We // don't want the user of the list to be concerned // about creating a new element his/her self. // Allocate memory for a new Element. Element *temp = new Element(); // Set the temp element data to the data passed // to this function. temp->data = data; // If head is NULL we have an empty list. if(head==NULL) { // If the list is empty then insert it at // the beginning of the list. head = tail = temp; temp->prev = NULL; } else { // List has elements in it already, // Insert onto the end of the list. tail->next = temp; temp->prev = tail; } // Remember that this element is // at the end of the list. tail = temp; temp->next = NULL; // Add one to the number of elements. elements++; } Element* _LinkedList::find(void *data) { Element *temp = NULL; temp = head; // This for loop iterates through the elements // so we can check for the data. If we find data // then we found our element. for (; temp != NULL;) { // Return the element if we find its data if (temp->data == data) return temp; temp = temp->next; } // The data doesn't belong to any element in // our list. return NULL; } void _LinkedList::remove(void *data) { // We can't delete an element if // that element doesn't exist in // the first place. Element *temp = find(data); // If temp element is NULL that means // we didn't find the element we were // looking for. if(temp == NULL) { cerr << "_LinkedList::remove : element not found" << endl; return; } else { // On the off chance there is duplicates get rid of them. //while(temp) //{ if(temp==head) head = temp->next; //if head just drop off else temp->prev->next = temp->next; //else drop out. if(temp==tail) tail = temp->prev; //if tail just drop off else temp->next->prev = temp->prev; //else drop out delete temp; // Subtract one from total elements. elements--; // Look again to see if there is a duplicate //temp = find(data); temp = NULL; //} } } /* _LinkedListIterator Below */ _LinkedListIterator::_LinkedListIterator() { } void _LinkedListIterator::setList(_LinkedList *l, int direction) { if(l != NULL) { list = l; element = NULL; reset(direction); } else { cerr << "_LinkedListIterator: List is NULL" << endl; exit(-1); } } void _LinkedListIterator::reset(int direction) { switch(direction) { case FORWARD: list->setForward(); element = list->head; break; case BACKWARD: list->setBackward(); element = list->tail; break; default: cerr << "_LinkedListIterator: Illegal direction for list traversal using FORWARD" << endl; list->setForward(); element = list->head; break; } } sapphire-0.15.8/main.cc0100644000175000001440000000172307371022723013204 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "sapphire.hh" int main(int argc, char *argv[]) { WindowManager sapphire(argc,argv); return 0; } sapphire-0.15.8/menulex.cc0100644000175000001440000001701607414165525013745 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "sapphire.hh" MenuLex::MenuLex(char *filename, RootMenu *menu) : Scanner(filename) { root = menu; menulist = wm->getMenuList(); error=false; submenus=1; name=new char[255]; exe=new char[255]; } MenuLex::~MenuLex() { delete [] name; delete [] exe; } BaseMenu* MenuLex::getLastMenu() { if(menulist->count()) return menulist->last(); return NULL; } BaseMenu* MenuLex::getMenu(int index) { int counter=0; if(index==0) return root; LinkedListIterator it(menulist); for(; it.current(); it++) { if(counter==index) return it.current(); counter++; } return NULL; } void MenuLex::parse() { // Check to see if this menu file is gramatically correct. do { getNextToken(); } while(menu(true)); // If we didn't get any errors when we validated the menu // then lets build the menu. if(!error) { rewind(); do { getNextToken(); } while(menu(false)); LinkedListIterator it(menulist); for(; it.current(); it++) { it.current()->update_all(); } } else { // If there was an error use the default menu. root->defaultMenu(); } } bool MenuLex::menu(bool validate) { if(match("menu")) { getNextToken(); if(match("(")) { clearToken(); getNextToken(true); strcpy(name, currentToken()); //printf("name = %s\n", currentToken()); if(! validate) root->setMenuTitle(name); getNextToken(); if(match(")")) { getNextToken(); if(match("{")) { getNextToken(); if(match("}")) { printf("There was an error parsing your menu configuration file, I have to use the default menu because of this problem.\n"); error = true; return true; } else { while(statement(root, validate)) { getNextToken(); } if(match("}")) { return true; } else { printf("missing } near (%s)\n", name); error = true; return false; } } } else { printf("missing { near menu\n"); error = true; return false; } } else { printf("missing ) near menu\n"); error = true; return false; } } else { printf("missing ( near menu\n"); error = true; return false; } } return false; } bool MenuLex::submenu(BaseMenu *sub, bool validate) { BaseMenu *child=NULL; if(match("submenu")) { getNextToken(); if(match("(")) { clearToken(); getNextToken(true); strcpy(name, currentToken()); getNextToken(); if(match(")")) { getNextToken(); if(match("{")) { getNextToken(); if(! validate) { child = new BaseMenu(); child->setMenuTitle(name); menulist->insert(child); sub->insert(name, child); } while(statement(child, validate)) { getNextToken(); } if(match("}")) { if(! validate) { submenus=0; } return true; } } else { printf("missing { near submenu\n"); error = true; return false; } } else { printf("missing ) near submenu\n"); error = true; return false; } } else { printf("missing ( near submenu\n"); error = true; return false; } } return false; } bool MenuLex::separator(BaseMenu *sub, bool validate) { if(match("separator")) { if(! validate) sub->insert("separator", "", 2); return true; } return false; } bool MenuLex::exit(BaseMenu* sub, bool validate) { if(match("exit")) { if(! validate) sub->insert("exit", "", 1); return true; } return false; } bool MenuLex::restart(BaseMenu* sub, bool validate) { if(match("restart")) { if(! validate) sub->insert("restart", "", 4); return true; } return false; } bool MenuLex::reconfigure(BaseMenu* sub, bool validate) { if(match("reconfigure")) { if(! validate) sub->insert("reconfigure", "", 5); return true; } return false; } bool MenuLex::exec(BaseMenu *sub, bool validate) { if(match("exec")) { getNextToken(); if(match("(")) { clearToken(); getNextToken(true); strcpy(name, currentToken()); //printf("name = %s\n", name); getNextToken(); if(match(")")) { getNextToken(); if(match("{")) { clearToken(); getNextToken(true); strcpy(exe, currentToken()); //printf("exec: %s\n", currentToken()); if(! validate) { //printf("sub1's name = %s | inserting %s\n", sub1->getMenuTitle(), name); sub->insert(name, exe, 0); } getNextToken(); if(match("}")) return true; } else { printf("missing { near exec\n"); error = true; return false; } } else { printf("missing ) near exec\n"); error = true; return false; } } else { printf("missing ( near exec\n"); error = true; return false; } } return false; } bool MenuLex::theme(BaseMenu *sub, bool validate) { if(match("theme")) { getNextToken(); if(match("(")) { clearToken(); getNextToken(true); strcpy(name, currentToken()); //printf("theme name = %s\n", name); getNextToken(); if(match(")")) { getNextToken(); if(match("{")) { clearToken(); getNextToken(true); strcpy(exe, currentToken()); //printf("theme patch: %s\n", currentToken()); if(! validate) { //printf("sub1's name = %s | inserting %s\n", sub1->getMenuTitle(), name); sub->insert(name, exe, 6); } getNextToken(); if(match("}")) return true; } else { printf("missing { near theme\n"); error = true; return false; } } else { printf("missing ) near theme\n"); error = true; return false; } } else { printf("missing ( near theme\n"); error = true; return false; } } return false; } bool MenuLex::statement(BaseMenu *sub, bool validate) { // This dispatches each statement function. if(submenu(sub, validate)) return true; if(exec(sub, validate)) return true; if(theme(sub, validate)) return true; if(separator(sub, validate)) return true; if(exit(sub, validate)) return true; if(restart(sub, validate)) return true; if(reconfigure(sub, validate)) return true; return false; } sapphire-0.15.8/misc.cc0100644000175000001440000000325407371022710013210 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "sapphire.hh" void signalhandler(int i) { fprintf(stderr, "%s: Caught a signal, exiting...", windowmanager_name); wm->quit_nicely(); } // This is a utility function which just prints some extra information // when an error has occurred. void err(char *fmt, ...) { va_list argp; fprintf(stderr, "%s: ", windowmanager_name); va_start(argp, fmt); vfprintf(stderr, fmt, argp); va_end(argp); fprintf(stderr, "\n"); } int handle_xerror(Display *dpy, XErrorEvent *e) { if (e->error_code == BadAccess && e->resourceid == wm->getRootWindow()) { err("root window unavailible (maybe another wm is running?)"); exit(1); } #ifdef DEBUG else { char msg[80]; XGetErrorText(dpy, e->error_code, msg, sizeof(msg)); err("X error (%#x): %s", e->resourceid, msg); } #endif return 0; } sapphire-0.15.8/theme.cc0100644000175000001440000005571207414165525013377 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "sapphire.hh" Theme::Theme() { } Theme::~Theme() { delete [] currentTheme; delete [] font; delete [] menufont; } void Theme::parseTheme(char *themeFile) { XrmInitialize(); XrmValue value; char *value_type; currentTheme = new char[strlen(themeFile)+1]; strcpy(currentTheme, themeFile); resource_db = XrmGetFileDatabase(themeFile); if (resource_db==NULL) return; if (! (titlebar_style=readDatabaseTexture("titlebar.style", "Titlebar.Style"))) { titlebar_style=BImage_Gradient|BImage_Horizontal|BImage_Raised|BImage_Bevel2; } if (! (button_style=readDatabaseTexture("button.style", "Button.Style"))) { button_style=BImage_Gradient|BImage_Diagonal|BImage_Raised|BImage_Bevel2; } if (! (toolbar_style=readDatabaseTexture("toolbar.style", "Toolbar.Style"))) { toolbar_style=BImage_Gradient|BImage_Vertical|BImage_Raised|BImage_Bevel2; } if (! (clock_style=readDatabaseTexture("clock.style", "clock.Style"))) { clock_style=BImage_Gradient|BImage_Vertical|BImage_Raised|BImage_Bevel2; } if (! (menu_style=readDatabaseTexture("menu.style", "Menu.Style"))) { menu_style=BImage_Gradient|BImage_Diagonal|BImage_Raised|BImage_Bevel2; } if (! (menu_title_style=readDatabaseTexture("menutitle.style", "MenuTitle.Style"))) { menu_title_style=BImage_Gradient|BImage_Horizontal|BImage_Raised|BImage_Bevel2; } if (! (menu_select_style=readDatabaseTexture("menuselect.style", "MenuSelect.Style"))) { menu_select_style=BImage_Gradient|BImage_Vertical|BImage_Raised|BImage_Bevel2; } if (! (resize_style=readDatabaseTexture("resize.style", "Resize.Style"))) { resize_style=BImage_Gradient|BImage_Horizontal|BImage_Raised|BImage_Bevel2; } if (! (right_sidebar_style=readDatabaseTexture("handle.style", "Handle.Style"))) { right_sidebar_style=BImage_Gradient|BImage_Horizontal|BImage_Raised|BImage_Bevel2; } if (XrmGetResource(resource_db, "root.background", "Root.Background", &value_type, &value)) { if(strcmp(value.addr, "true")==0) { root_extra_style=ROOT_ON; } else { root_extra_style=ROOT_OFF; } } if (! (root_style=readDatabaseTexture("root.style", "Root.Style"))) { root_extra_style=ROOT_OFF; root_style=BImage_Solid; } if (! (font_style=readDatabaseTexture("font.style", "Font.Style"))) { font_style=BImage_Solid; } // Client color from if (XrmGetResource(resource_db, "titlebar.color.from.red", "Titlebar.Color.From.Red", &value_type, &value)) { sscanf(value.addr, "%d", &client[0].red); } else { client[0].red=89; } if (XrmGetResource(resource_db, "titlebar.color.from.green", "Titlebar.Color.From.Green", &value_type, &value)) { sscanf(value.addr, "%d", &client[0].green); } else { client[0].green=107; } if (XrmGetResource(resource_db, "titlebar.color.from.blue", "Titlebar.Color.From.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &client[0].blue); } else { client[0].blue=137; } // Client color to if (XrmGetResource(resource_db, "titlebar.color.to.red", "Titlebar.Color.To.Red", &value_type, &value)) { sscanf(value.addr, "%d", &client[1].red); } else { client[1].red=200; } if (XrmGetResource(resource_db, "titlebar.color.to.green", "Titlebar.Color.To.Green", &value_type, &value)) { sscanf(value.addr, "%d", &client[1].green); } else { client[1].green=200; } if (XrmGetResource(resource_db, "titlebar.color.to.blue", "Titlebar.Color.To.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &client[1].blue); } else { client[1].blue=200; } // Client Focus from if (XrmGetResource(resource_db, "titlebarFocus.color.from.red", "TitlebarFocus.Color.From.Red", &value_type, &value)) { sscanf(value.addr, "%d", &client_focus[0].red); } else { client_focus[0].red=100; } if (XrmGetResource(resource_db, "titlebarFocus.color.from.green", "TitlebarFocus.Color.From.Green", &value_type, &value)) { sscanf(value.addr, "%d", &client_focus[0].green); } else { client_focus[0].green=100; } if (XrmGetResource(resource_db, "titlebarFocus.color.from.blue", "TitlebarFocus.Color.From.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &client_focus[0].blue); } else { client_focus[0].blue=100; } // Client Focus color to if (XrmGetResource(resource_db, "titlebarFocus.color.to.red", "TitlebarFocus.Color.To.Red", &value_type, &value)) { sscanf(value.addr, "%d", &client_focus[1].red); } else { client_focus[1].red=255; } if (XrmGetResource(resource_db, "titlebarFocus.color.to.green", "TitlebarFocus.Color.To.Green", &value_type, &value)) { sscanf(value.addr, "%d", &client_focus[1].green); } else { client_focus[1].green=255; } if (XrmGetResource(resource_db, "titlebarFocus.color.to.blue", "TitlebarFocus.Color.To.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &client_focus[1].blue); } else { client_focus[1].blue=255; } // Button color from if (XrmGetResource(resource_db, "button.color.from.red", "Button.Color.From.Red", &value_type, &value)) { sscanf(value.addr, "%d", &buttons[0].red); } else { buttons[0].red=181; } if (XrmGetResource(resource_db, "button.color.from.green", "Button.Color.From.Green", &value_type, &value)) { sscanf(value.addr, "%d", &buttons[0].green); } else { buttons[0].green=181; } if (XrmGetResource(resource_db, "button.color.from.blue", "Button.Color.From.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &buttons[0].blue); } else { buttons[0].blue=181; } // Button color to if (XrmGetResource(resource_db, "button.color.to.red", "Button.Color.To.Red", &value_type, &value)) { sscanf(value.addr, "%d", &buttons[1].red); } else { buttons[1].red=225; } if (XrmGetResource(resource_db, "button.color.to.green", "Button.Color.To.Green", &value_type, &value)) { sscanf(value.addr, "%d", &buttons[1].green); } else { buttons[1].green=225; } if (XrmGetResource(resource_db, "button.color.to.blue", "Button.Color.To.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &buttons[1].blue); } else { buttons[1].blue=225; } // Menu color from if (XrmGetResource(resource_db, "menu.color.from.red", "Menu.Color.From.Red", &value_type, &value)) { sscanf(value.addr, "%d", &menu[0].red); } else { menu[0].red=100; } if (XrmGetResource(resource_db, "menu.color.from.green", "Menu.Color.From.Green", &value_type, &value)) { sscanf(value.addr, "%d", &menu[0].green); } else { menu[0].green=100; } if (XrmGetResource(resource_db, "menu.color.from.blue", "Menu.Color.From.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &menu[0].blue); } else { menu[0].blue=100; } // Menu color to if (XrmGetResource(resource_db, "menu.color.to.red", "Menu.Color.To.Red", &value_type, &value)) { sscanf(value.addr, "%d", &menu[1].red); } else { menu[1].red=255; } if (XrmGetResource(resource_db, "menu.color.to.green", "Menu.Color.To.Green", &value_type, &value)) { sscanf(value.addr, "%d", &menu[1].green); } else { menu[1].green=255; } if (XrmGetResource(resource_db, "menu.color.to.blue", "Menu.Color.To.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &menu[1].blue); } else { menu[1].blue=255; } // Menu Title from if (XrmGetResource(resource_db, "menuTitle.color.from.red", "MenuTitle.Color.From.Red", &value_type, &value)) { sscanf(value.addr, "%d", &menu_title[0].red); } else { menu_title[0].red=89; } if (XrmGetResource(resource_db, "menuTitle.color.from.green", "MenuTitle.Color.From.Green", &value_type, &value)) { sscanf(value.addr, "%d", &menu_title[0].green); } else { menu_title[0].green=107; } if (XrmGetResource(resource_db, "menuTitle.color.from.blue", "MenuTitle.Color.From.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &menu_title[0].blue); } else { menu_title[0].blue=137; } // Menu Title color to if (XrmGetResource(resource_db, "menuTitle.color.to.red", "MenuTitle.Color.To.Red", &value_type, &value)) { sscanf(value.addr, "%d", &menu_title[1].red); } else { menu_title[1].red=200; } if (XrmGetResource(resource_db, "menuTitle.color.to.green", "MenuTitle.Color.To.Green", &value_type, &value)) { sscanf(value.addr, "%d", &menu_title[1].green); } else { menu_title[1].green=200; } if (XrmGetResource(resource_db, "menuTitle.color.to.blue", "MenuTitle.Color.To.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &menu_title[1].blue); } else { menu_title[1].blue=200; } // Menu Select from if (XrmGetResource(resource_db, "menuSelect.color.from.red", "MenuSelect.Color.From.Red", &value_type, &value)) { sscanf(value.addr, "%d", &menu_select[0].red); } else { menu_select[0].red=200; } if (XrmGetResource(resource_db, "menuSelect.color.from.green", "MenuSelect.Color.From.Green", &value_type, &value)) { sscanf(value.addr, "%d", &menu_select[0].green); } else { menu_select[0].green=200; } if (XrmGetResource(resource_db, "menuSelect.color.from.blue", "MenuSelect.Color.From.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &menu_select[0].blue); } else { menu_select[0].blue=200; } // Menu Select color to if (XrmGetResource(resource_db, "menuSelect.color.to.red", "MenuSelect.Color.To.Red", &value_type, &value)) { sscanf(value.addr, "%d", &menu_select[1].red); } else { menu_select[1].red=255; } if (XrmGetResource(resource_db, "menuSelect.color.to.green", "MenuSelect.Color.To.Green", &value_type, &value)) { sscanf(value.addr, "%d", &menu_select[1].green); } else { menu_select[1].green=255; } if (XrmGetResource(resource_db, "menuSelect.color.to.blue", "MenuSelect.Color.To.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &menu_select[1].blue); } else { menu_select[1].blue=255; } // Toolbar from if (XrmGetResource(resource_db, "toolbar.color.from.red", "Toolbar.Color.From.Red", &value_type, &value)) { sscanf(value.addr, "%d", &toolbar[0].red); } else { toolbar[0].red=117; } if (XrmGetResource(resource_db, "toolbar.color.from.green", "Toolbar.Color.From.Green", &value_type, &value)) { sscanf(value.addr, "%d", &toolbar[0].green); } else { toolbar[0].green=142; } if (XrmGetResource(resource_db, "toolbar.color.from.blue", "Toolbar.Color.From.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &toolbar[0].blue); } else { toolbar[0].blue=183; } // Toolbar color to if (XrmGetResource(resource_db, "toolbar.color.to.red", "Toolbar.Color.To.Red", &value_type, &value)) { sscanf(value.addr, "%d", &toolbar[1].red); } else { toolbar[1].red=70; } if (XrmGetResource(resource_db, "toolbar.color.to.green", "Toolbar.Color.To.Green", &value_type, &value)) { sscanf(value.addr, "%d", &toolbar[1].green); } else { toolbar[1].green=70; } if (XrmGetResource(resource_db, "toolbar.color.to.blue", "Toolbar.Color.To.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &toolbar[1].blue); } else { toolbar[1].blue=70; } // Resize from if (XrmGetResource(resource_db, "resize.color.from.red", "Resize.Color.From.Red", &value_type, &value)) { sscanf(value.addr, "%d", &resize[0].red); } else { resize[0].red=100; } if (XrmGetResource(resource_db, "resize.color.from.green", "Resize.Color.From.Green", &value_type, &value)) { sscanf(value.addr, "%d", &resize[0].green); } else { resize[0].green=100; } if (XrmGetResource(resource_db, "resize.color.from.blue", "Resize.Color.From.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &resize[0].blue); } else { resize[0].blue=100; } // Resize color to if (XrmGetResource(resource_db, "resize.color.to.red", "Resize.Color.To.Red", &value_type, &value)) { sscanf(value.addr, "%d", &resize[1].red); } else { resize[1].red=255; } if (XrmGetResource(resource_db, "resize.color.to.green", "Resize.Color.To.Green", &value_type, &value)) { sscanf(value.addr, "%d", &resize[1].green); } else { resize[1].green=255; } if (XrmGetResource(resource_db, "resize.color.to.blue", "Resize.Color.To.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &resize[1].blue); } else { resize[1].blue=255; } // Clock color from if (XrmGetResource(resource_db, "clock.color.from.red", "Clock.Color.From.Red", &value_type, &value)) { sscanf(value.addr, "%d", &clock[0].red); } else { clock[0].red=100; } if (XrmGetResource(resource_db, "clock.color.from.green", "Clock.Color.From.Green", &value_type, &value)) { sscanf(value.addr, "%d", &clock[0].green); } else { clock[0].green=100; } if (XrmGetResource(resource_db, "clock.color.from.blue", "Clock.Color.From.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &clock[0].blue); } else { clock[0].blue=100; } // Clock color to if (XrmGetResource(resource_db, "clock.color.to.red", "Clock.Color.To.Red", &value_type, &value)) { sscanf(value.addr, "%d", &clock[1].red); } else { clock[1].red=255; } if (XrmGetResource(resource_db, "clock.color.to.green", "Clock.Color.To.Green", &value_type, &value)) { sscanf(value.addr, "%d", &clock[1].green); } else { clock[1].green=255; } if (XrmGetResource(resource_db, "clock.color.to.blue", "Clock.Color.To.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &clock[1].blue); } else { clock[1].blue=255; } // Handle from if (XrmGetResource(resource_db, "handle.color.from.red", "Handle.Color.From.Red", &value_type, &value)) { sscanf(value.addr, "%d", &right_sidebar[0].red); } else { right_sidebar[0].red=100; } if (XrmGetResource(resource_db, "handle.color.from.green", "Handle.Color.From.Green", &value_type, &value)) { sscanf(value.addr, "%d", &right_sidebar[0].green); } else { right_sidebar[0].green=100; } if (XrmGetResource(resource_db, "handle.color.from.blue", "Handle.Color.From.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &right_sidebar[0].blue); } else { right_sidebar[0].blue=100; } // Handle color to if (XrmGetResource(resource_db, "handle.color.to.red", "Handle.Color.To.Red", &value_type, &value)) { sscanf(value.addr, "%d", &right_sidebar[1].red); } else { right_sidebar[1].red=255; } if (XrmGetResource(resource_db, "handle.color.to.green", "Handle.Color.To.Green", &value_type, &value)) { sscanf(value.addr, "%d", &right_sidebar[1].green); } else { right_sidebar[1].green=255; } if (XrmGetResource(resource_db, "handle.color.to.blue", "Handle.Color.To.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &right_sidebar[1].blue); } else { right_sidebar[1].blue=255; } if (XrmGetResource(resource_db, "command", "Command", &value_type, &value)) { char command[value.size+8]; sprintf(command, "exec %s &", value.addr); system(command); } if (XrmGetResource(resource_db, "font", "Font", &value_type, &value)) { font = new char[value.size]; strcpy(font, value.addr); xfont = XLoadQueryFont(wm->getDisplay(), font); if(! xfont) { char f[43]; sprintf(f, "-*-lucida-medium-r-normal-*-12-*-*-*-*-*-*-*"); font = new char[43]; strcpy(font, f); } } else { char f[43]; sprintf(f, "-*-lucida-medium-r-normal-*-12-*-*-*-*-*-*-*"); font = new char[43]; strcpy(font, f); } if (XrmGetResource(resource_db, "menufont", "MenuFont", &value_type, &value)) { menufont = new char[value.size]; strcpy(menufont, value.addr); xfont = XLoadQueryFont(wm->getDisplay(), menufont); if(! xfont) { char f[43]; sprintf(f, "-*-lucida-bold-r-normal-*-15-*-*-*-*-*-*-*"); menufont = new char[43]; strcpy(menufont, f); } } else { char f[43]; sprintf(f, "-*-lucida-bold-r-normal-*-15-*-*-*-*-*-*-*"); menufont = new char[43]; strcpy(menufont, f); } // Font color from if (XrmGetResource(resource_db, "font.color.from.red", "Font.Color.From.Red", &value_type, &value)) { sscanf(value.addr, "%d", &font_color[0].red); } else { font_color[0].red=0; } if (XrmGetResource(resource_db, "font.color.from.green", "Font.Color.From.Green", &value_type, &value)) { sscanf(value.addr, "%d", &font_color[0].green); } else { font_color[0].green=0; } if (XrmGetResource(resource_db, "font.color.from.blue", "Font.Color.From.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &font_color[0].blue); } else { font_color[0].blue=0; } // Font color to if (XrmGetResource(resource_db, "font.color.to.red", "Font.Color.To.Red", &value_type, &value)) { sscanf(value.addr, "%d", &font_color[1].red); } else { font_color[1].red=255; } if (XrmGetResource(resource_db, "font.color.to.green", "Font.Color.To.Green", &value_type, &value)) { sscanf(value.addr, "%d", &font_color[1].green); } else { font_color[1].green=255; } if (XrmGetResource(resource_db, "font.color.to.blue", "Font.Color.To.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &font_color[1].blue); } else { font_color[1].blue=255; } // MenuFont color from if (XrmGetResource(resource_db, "menufont.color.from.red", "MenuFont.Color.From.Red", &value_type, &value)) { sscanf(value.addr, "%d", &menufont_color[0].red); } else { menufont_color[0].red=0; } if (XrmGetResource(resource_db, "menufont.color.from.green", "MenuFont.Color.From.Green", &value_type, &value)) { sscanf(value.addr, "%d", &menufont_color[0].green); } else { menufont_color[0].green=0; } if (XrmGetResource(resource_db, "menufont.color.from.blue", "MenuFont.Color.From.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &menufont_color[0].blue); } else { menufont_color[0].blue=0; } // MenuFont color to if (XrmGetResource(resource_db, "menufont.color.to.red", "MenuFont.Color.To.Red", &value_type, &value)) { sscanf(value.addr, "%d", &menufont_color[1].red); } else { menufont_color[1].red=255; } if (XrmGetResource(resource_db, "menufont.color.to.green", "MenuFont.Color.To.Green", &value_type, &value)) { sscanf(value.addr, "%d", &menufont_color[1].green); } else { menufont_color[1].green=255; } if (XrmGetResource(resource_db, "menufont.color.to.blue", "MenuFont.Color.To.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &menufont_color[1].blue); } else { menufont_color[1].blue=255; } // Root color from if (XrmGetResource(resource_db, "root.color.from.red", "Root.Color.From.Red", &value_type, &value)) { sscanf(value.addr, "%d", &root[0].red); } else { root[0].red=0; } if (XrmGetResource(resource_db, "root.color.from.green", "Root.Color.From.Green", &value_type, &value)) { sscanf(value.addr, "%d", &root[0].green); } else { root[0].green=0; } if (XrmGetResource(resource_db, "root.color.from.blue", "Root.Color.From.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &root[0].blue); } else { root[0].blue=0; } // Root color to if (XrmGetResource(resource_db, "root.color.to.red", "Root.Color.To.Red", &value_type, &value)) { sscanf(value.addr, "%d", &root[1].red); } else { root[1].red=255; } if (XrmGetResource(resource_db, "root.color.to.green", "Root.Color.To.Green", &value_type, &value)) { sscanf(value.addr, "%d", &root[1].green); } else { root[1].green=255; } if (XrmGetResource(resource_db, "root.color.to.blue", "Root.Color.To.Blue", &value_type, &value)) { sscanf(value.addr, "%d", &root[1].blue); } else { root[1].blue=255; } XrmDestroyDatabase(resource_db); } unsigned long Theme::readDatabaseTexture(char *rname, char *rclass) { XrmValue value; char *value_type; unsigned long texture = 0; if (XrmGetResource(resource_db, rname, rclass, &value_type, &value)) { if (strstr(value.addr, "Inverted")) { texture |= BImage_Invert; } else { if (strstr(value.addr, "Solid")) { texture |= BImage_Solid; } else if (strstr(value.addr, "Gradient")) { texture |= BImage_Gradient; if (strstr(value.addr, "Diagonal")) { texture |= BImage_Diagonal; } else if (strstr(value.addr, "Horizontal")) { texture |= BImage_Horizontal; } else if (strstr(value.addr, "Vertical")) { texture |= BImage_Vertical; } else texture |= BImage_Diagonal; } else texture |= BImage_Solid; if (strstr(value.addr, "Raised")) texture |= BImage_Raised; else if (strstr(value.addr, "Sunken")) texture |= BImage_Sunken; else if (strstr(value.addr, "Flat")) texture |= BImage_Flat; else texture |= BImage_Raised; if (! (texture & BImage_Flat)) if (strstr(value.addr, "Bevel")) if (strstr(value.addr, "Bevel1")) texture |= BImage_Bevel1; else if (strstr(value.addr, "Bevel2")) texture |= BImage_Bevel2; else texture |= BImage_Bevel1; } } return texture; return 0; } sapphire-0.15.8/data.inst0100755000175000001440000000317507201704365013570 0ustar asusers#!/bin/bash # # Sapphire 0.15.4 and above # # This script is putting configurations files in place so Sapphire can run properly. # # Date: 6 Nov 2000 ############################################################### # DO NOT HAND EDIT THIS VARIABLE. SAPPHIRE WILL LOOK HERE # ANYWAY. IF YOU HAND EDIT THIS BAD THINGS WILL SURELY HAPPEN # POSSIBLY COREDUMPS OR SEGMENTATION FAULTS. # # THIS WILL REMAIN LIKE THIS UNTIL SAPPHIRE HAS BETTER HANDLING # OF CONFIGURATION FILES. CONFIGURATION_PATH=/usr/local/share/sapphire ############################################################### if [ -d $CONFIGURATION_PATH ] then echo "$CONFIGURATION_PATH directory already exists"; else mkdir $CONFIGURATION_PATH echo "created directory $CONFIGURATION_PATH"; fi # Check to see if there is a themes directory if [ -d $CONFIGURATION_PATH/themes ] then echo "$CONFIGURATION_PATH directory already exists, copying over current themes"; cp data/themes/* $CONFIGURATION_PATH/themes else mkdir $CONFIGURATION_PATH/themes echo "created directory $CONFIGURATION_PATH/themes"; cp data/themes/* $CONFIGURATION_PATH/themes echo "themes were copied to $CONFIGURATION_PATH/themes"; fi # Check to see if there is a menu directory if [ -d $CONFIGURATION_PATH/menu ] then echo "$CONFIGURATION_PATH/menu directory already exists, copying over current menu files"; cp data/menu/* $CONFIGURATION_PATH/menu else mkdir $CONFIGURATION_PATH/menu echo "created directory $CONFIGURATION_PATH/menu"; cp data/menu/* $CONFIGURATION_PATH/menu echo "menu files were copied to $CONFIGURATION_PATH/menu"; fi echo echo "Installation of Sapphire's configuration files is complete."; sapphire-0.15.8/rootmenu.cc0100644000175000001440000000323607414165525014137 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "sapphire.hh" RootMenu::RootMenu() : BaseMenu() { } // This parses the menu file and creates the root menu. void RootMenu::parseMenuConfigurationFile() { //char *menupath = "/.sapphire/menu/default"; //char path[strlen(HOME)+strlen(menupath)]; //sprintf(path, "%s%s", HOME, menupath); char *menupath = "/menu/default"; char path[strlen(configuration_home)+strlen(menupath)+1]; sprintf(path, "%s%s", configuration_home, menupath); MenuLex *ml = new MenuLex(path, this); ml->parse(); delete ml; } void RootMenu::defaultMenu() { printf("somethings wrong with your menu configuration, using default menu\n"); setMenuTitle("Default Menu"); insert("xterm", "xterm", 0); insert("reconfigure", "", 5); insert("exit", "", 1); update_all(); wm->addToMenuList(this); } sapphire-0.15.8/scanner.cc0100644000175000001440000001135507414165525013721 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "sapphire.hh" Scanner::Scanner(char* filename) { if((in = fopen(filename, "r"))==NULL) { printf("can't open file: %s\n", filename); wm->getRootMenu()->defaultMenu(); } else backup_pos = ftell(in); int i; for(i='a'; i<='z'; ++i) char_class[i]=letters; for(i='A'; i<='Z'; ++i) char_class[i]=letters; for(i='0'; i<='9'; ++i) char_class[i]=letters; char_class['`']=letters; char_class['\'']=letters; char_class['!']=letters; char_class['@']=letters; char_class['#']=letters; char_class['$']=letters; char_class['%']=letters; char_class['^']=letters; char_class['&']=letters; char_class['_']=letters; char_class['+']=letters; char_class['=']=letters; char_class['\\']=letters; char_class['?']=letters; char_class[':']=letters; char_class[';']=letters; char_class[',']=letters; char_class['|']=letters; char_class['\"']=letters; char_class['~']=letters; char_class['/']=letters; char_class['-']=letters; char_class['.']=letters; char_class['<']=letters; char_class['>']=letters; // These characters are used in configuration file constructs char_class['{']=openbrace; char_class['}']=closebrace; char_class['[']=openbracket; char_class[']']=closebracket; char_class['(']=openparen; char_class[')']=closeparen; char_class['*']=letters; char_class[' ']=whitespace; char_class['\0']=whitespace; char_class['\n']=whitespace; char_class['\r']=whitespace; char_class['\t']=whitespace; char_class[EOF]=whitespace; token = new char[MAX_TOKEN_BUFFER]; character='\0'; } Scanner::~Scanner() { if (in!=NULL) fclose(in); delete [] token; } void Scanner::concat() { int i=strlen(token); if(i == MAX_TOKEN_BUFFER) { token = new char[i]; } token[i]=character; token[i+1]='\0'; } void Scanner::getNextToken(bool spaces) { if (in==NULL) return; if (!spaces) { char_class[' ']=whitespace; strcpy (token, ""); } else { char_class[' ']=letters; } bool backslash=false; switch(char_class[character]) { case letters: while((char_class[character]==letters) || backslash) { concat(); fscanf(in, "%c", &character); if (character=='\\') { fscanf(in, "%c", &character); backslash=true; } else backslash=false; } return; break; case special: while(char_class[character]==special) { concat(); fscanf(in, "%c", &character); } return; break; case openparen: while(char_class[character]==openparen) { concat(); fscanf(in, "%c", &character); } return; break; case closeparen: while(char_class[character]==closeparen) { concat(); fscanf(in, "%c", &character); } return; break; case openbrace: while(char_class[character]==openbrace) { concat(); fscanf(in, "%c", &character); } return; break; case closebrace: while(char_class[character]==closebrace) { concat(); fscanf(in, "%c", &character); } return; break; case openbracket: while(char_class[character]==openbracket) { concat(); fscanf(in, "%c", &character); } return; break; case closebracket: while(char_class[character]==closebracket) { concat(); fscanf(in, "%c", &character); } return; break; case whitespace: while(char_class[character]==whitespace) { if(spaces) { concat(); } fscanf(in, "%c", &character); if(feof(in)) return; } getNextToken(); break; } } bool Scanner::match(char* t) { return ( (strcmp(t, token)==0) ? true : false ); } bool Scanner::matchNextToken(char* t) { if(match(t)) return true; else putBackToken(); return false; } bool Scanner::eof() { if ( in==NULL ) return true; return ( feof(in) ? true : false ); } sapphire-0.15.8/toolbar.cc0100644000175000001440000004050007371022660013716 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "sapphire.hh" Toolbar::Toolbar() { font_width=0; frame_pix=None; clock_pix=None; button_pix=None; root_pix=None; toolbarMenuVisible=False; Month[0] = "January"; Month[1] = "February"; Month[2] = "March"; Month[3] = "April"; Month[4] = "May"; Month[5] = "June"; Month[6] = "July"; Month[7] = "August"; Month[8] = "September"; Month[9] = "October"; Month[10] = "November"; Month[11] = "December"; create_mask = CWBackPixmap | CWBackPixel | CWBorderPixel | CWOverrideRedirect | CWEventMask; attrib.background_pixmap = None; attrib.background_pixel = wm->getBackgroundColor().pixel; attrib.border_pixel = wm->getBorderColor().pixel; attrib.override_redirect = True; attrib.event_mask = StructureNotifyMask | LeaveWindowMask | ButtonPressMask | ButtonReleaseMask | ExposureMask; default_button_width=15; default_button_height=15; createToolbarWindow(); createClockWindow(); createCycleUpButtonWindow(); createCycleDownButtonWindow(); createStartMenuButtonWindow(); tm = new ToolbarMenu(); reconfigure(); if(wm->getTheme()->getRootExtraStyle() & ROOT_ON) createRootImage(); if (wm->getTheme()->getToolbarExtraStyle()) { XMapSubwindows(wm->getDisplay(), frame.window); XMapWindow(wm->getDisplay(), frame.window); } } Toolbar::~Toolbar() { wm->getImageControl()->removeImage(clock_pix); wm->getImageControl()->removeImage(frame_pix); wm->getImageControl()->removeImage(button_pix); XDestroyWindow(wm->getDisplay(), clock.window); XDestroyWindow(wm->getDisplay(), cycleUp.window); XDestroyWindow(wm->getDisplay(), cycleDown.window); XDestroyWindow(wm->getDisplay(), startmenu.window); XDestroyWindow(wm->getDisplay(), frame.window); if(root_pix) wm->getImageControl()->removeImage(root_pix); delete tm; } void Toolbar::createToolbarWindow() { // check to see if toolbar is to be at top or bottom of the screen // then place toolbar in correct location if (wm->getTheme()->getToolbarExtraStyle() & TOOLBAR_TOP) { frame.width=wm->getXRes() / 2; frame.height = 25; frame.x = wm->getXRes() / 2 - frame.width / 2; frame.y = 0; } else { frame.width = wm->getXRes() / 2; frame.height = 25; frame.x = wm->getXRes() / 2 - frame.width / 2; frame.y = wm->getYRes() - frame.height; } frame.window = XCreateWindow(wm->getDisplay(), wm->getRootWindow(), frame.x, frame.y, frame.width, frame.height, 1, DefaultDepth(wm->getDisplay(), wm->getScreen()), InputOutput, DefaultVisual(wm->getDisplay(), wm->getScreen()), create_mask, &attrib); } void Toolbar::createClockWindow() { clock.x = frame.width - 160; clock.y = 3; clock.width = 130; clock.height = wm->getXFont()->ascent + wm->getXFont()->descent+2; clock.window = XCreateWindow(wm->getDisplay(), frame.window, clock.x, clock.y, clock.width, clock.height, 1, DefaultDepth(wm->getDisplay(), wm->getScreen()), InputOutput, DefaultVisual(wm->getDisplay(), wm->getScreen()), create_mask, &attrib); } void Toolbar::createCycleUpButtonWindow() { cycleUp.x = 36; cycleUp.y = 4; cycleUp.width = default_button_width; cycleUp.height = default_button_height; cycleUp.window = XCreateWindow(wm->getDisplay(), frame.window, cycleUp.x, cycleUp.y, cycleUp.width, cycleUp.height, 1, DefaultDepth(wm->getDisplay(), wm->getScreen()), InputOutput, DefaultVisual(wm->getDisplay(), wm->getScreen()), create_mask, &attrib); } void Toolbar::createCycleDownButtonWindow() { cycleDown.x = 54; cycleDown.y = 4; cycleDown.width = default_button_width; cycleDown.height = default_button_height; cycleDown.window = XCreateWindow(wm->getDisplay(), frame.window, cycleDown.x, cycleDown.y, cycleDown.width, cycleDown.height, 1, DefaultDepth(wm->getDisplay(), wm->getScreen()), InputOutput, DefaultVisual(wm->getDisplay(), wm->getScreen()), create_mask, &attrib); } void Toolbar::createStartMenuButtonWindow() { startmenu.x = 10; startmenu.y = 4; startmenu.width = default_button_width; startmenu.height = default_button_height; startmenu.window = XCreateWindow(wm->getDisplay(), frame.window, startmenu.x, startmenu.y, startmenu.width, startmenu.height, 1, DefaultDepth(wm->getDisplay(), wm->getScreen()), InputOutput, DefaultVisual(wm->getDisplay(), wm->getScreen()), create_mask, &attrib); } void Toolbar::createToolBarImage() { unsigned long style=0; style = wm->getTheme()->getToolbarStyle(); frame_pix = wm->getImageControl()->renderImage( //"toolbar_frame", frame.width, frame.height, style, wm->getTheme()->getToolbarColorFrom(), wm->getTheme()->getToolbarColorTo() ); XSetWindowBackgroundPixmap(wm->getDisplay(), frame.window, frame_pix); } void Toolbar::createButtonImage() { unsigned long style=0; style = wm->getTheme()->getButtonStyle(); button_pix = wm->getImageControl()->renderImage( //"toolbar_button", default_button_width, default_button_height, style, wm->getTheme()->getButtonColorFrom(), wm->getTheme()->getButtonColorTo() ); XSetWindowBackgroundPixmap(wm->getDisplay(), startmenu.window, button_pix); XSetWindowBackgroundPixmap(wm->getDisplay(), cycleUp.window, button_pix); XSetWindowBackgroundPixmap(wm->getDisplay(), cycleDown.window, button_pix); } void Toolbar::createClockImage() { unsigned long style=0; style = wm->getTheme()->getClockStyle(); clock_pix = wm->getImageControl()->renderImage( //"toolbar_clock", clock.width, clock.height, style, wm->getTheme()->getClockColorFrom(), wm->getTheme()->getClockColorTo() ); XSetWindowBackgroundPixmap(wm->getDisplay(), clock.window, clock_pix); } void Toolbar::createRootImage() { unsigned long style=0; style = wm->getTheme()->getRootStyle(); root_pix = wm->getImageControl()->renderImage( //"root", wm->getXRes(), wm->getYRes(), style, wm->getTheme()->getRootColorFrom(), wm->getTheme()->getRootColorTo() ); XSetWindowBackgroundPixmap(wm->getDisplay(), wm->getRootWindow(), root_pix); XClearWindow(wm->getDisplay(), wm->getRootWindow()); } void Toolbar::changeTheme() { XFreePixmap(wm->getDisplay(), clock_pix); XFreePixmap(wm->getDisplay(), frame_pix); XFreePixmap(wm->getDisplay(), button_pix); if(wm->getTheme()->getRootExtraStyle() & ROOT_ON) { XFreePixmap(wm->getDisplay(), root_pix); createRootImage(); } createToolBarImage(); createButtonImage(); createClockImage(); XClearWindow(wm->getDisplay(), frame.window); XClearWindow(wm->getDisplay(), clock.window); redraw(); } void Toolbar::reconfigure() { createToolBarImage(); createButtonImage(); createClockImage(); XClearWindow(wm->getDisplay(), frame.window); XClearWindow(wm->getDisplay(), clock.window); XClearWindow(wm->getDisplay(), cycleUp.window); XClearWindow(wm->getDisplay(), cycleDown.window); XClearWindow(wm->getDisplay(), startmenu.window); // check to see if toolbar is to be at top or bottom of the screen // then place toolbar in correct location if (wm->getTheme()->getToolbarExtraStyle() & TOOLBAR_TOP) { frame.width=wm->getXRes() / 2; frame.height = 25; frame.x = wm->getXRes() / 2 - frame.width / 2; frame.y = 0; XMoveResizeWindow(wm->getDisplay(), frame.window, frame.x, frame.y , frame.width, frame.height); } else { frame.width = wm->getXRes() / 2; frame.height = 25; frame.x = wm->getXRes() / 2 - frame.width / 2; frame.y = wm->getYRes() - frame.height; XMoveResizeWindow(wm->getDisplay(), frame.window, frame.x, frame.y , frame.width, frame.height); } checkClock(True); } void Toolbar::do_button_press_event(XButtonEvent *e) { wm->Grab(); switch (e->button) { case Button1: { if (startmenu.window == e->window) { popup_toolbar_menu(); break; } else if(cycleUp.window == e->window) { cycle_windows_up(); break; } else if(cycleDown.window == e->window) { cycle_windows_down(); break; } break; } //case Button2: //{ //break; //} //case Button3: //{ //break; //} } wm->Ungrab(); } void Toolbar::redraw() { XClearWindow(wm->getDisplay(), cycleUp.window); XClearWindow(wm->getDisplay(), cycleDown.window); XClearWindow(wm->getDisplay(), startmenu.window); int hh = cycleUp.height / 2, hw = cycleUp.width / 2; XPoint cycleDownpts[3]; cycleDownpts[0].x = hw + 3; cycleDownpts[0].y = hh -2; cycleDownpts[1].x = -3; cycleDownpts[1].y = 6; cycleDownpts[2].x = -3; cycleDownpts[2].y = -6; XFillPolygon(wm->getDisplay(), cycleDown.window, wm->getBorderGC(), cycleDownpts, 3, Convex, CoordModePrevious); XPoint cycleUppts[3]; cycleUppts[0].x = hw - 4; cycleUppts[0].y = hh + 4; cycleUppts[1].x = 7; cycleUppts[1].y = 0; cycleUppts[2].x = -3; cycleUppts[2].y = -7; XFillPolygon(wm->getDisplay(), cycleUp.window, wm->getBorderGC(), cycleUppts, 3, Convex, CoordModePrevious); drawStartMenuButton(); checkClock(True); } void Toolbar::handle_expose_event(XExposeEvent *e) { if(e->count == 0) redraw(); } void Toolbar::checkClock(bool redraw) { static int hour, minute, day, month, year; time_t tmp; struct tm *tt=NULL; if ((tmp = time(NULL)) != -1) { tt = localtime(&tmp); if (tt->tm_min != minute || tt->tm_hour != hour || day != tt->tm_mday || month != tt->tm_mon || year != tt->tm_year) { hour = tt->tm_hour; minute = tt->tm_min; day = tt->tm_mday; month = tt->tm_mon; year = tt->tm_year; XClearWindow(wm->getDisplay(), clock.window); redraw = True; } } if (redraw) { char t[25]; strftime(t, 256,wm->getClockFormat(),tt); int len = strlen(t); int font_width_test = XTextWidth(wm->getXFont(), t, strlen(t)) + 8; int x_pos=0; font_width = font_width_test; x_pos = frame.width - font_width - 5; clock.width = font_width; //clock.height = wm->getXFont()->ascent + wm->getXFont()->descent * DEFAULT_SPACE - 2; clock.height = 20; int y_pos = 1; createClockImage(); XMoveResizeWindow(wm->getDisplay(), clock.window, x_pos , y_pos , font_width, clock.height); XDrawString(wm->getDisplay(), clock.window, wm->getStringGC(), 3, 25 / 2 + wm->getXFont()->descent, t, len); } } void Toolbar::hideToolbar() { XUnmapSubwindows(wm->getDisplay(), frame.window); } void Toolbar::showToolbar() { XMapSubwindows(wm->getDisplay(), frame.window); XMapWindow(wm->getDisplay(), frame.window); } void Toolbar::popup_toolbar_menu() { XSetWindowBorderWidth(wm->getDisplay(), startmenu.window, 2); XEvent ev; for (;;) { XMaskEvent(wm->getDisplay(), ButtonReleaseMask | LeaveWindowMask, &ev); switch (ev.type) { case LeaveNotify: { XSetWindowBorderWidth(wm->getDisplay(), startmenu.window, 1); return; } case ButtonRelease: { XSetWindowBorderWidth(wm->getDisplay(), startmenu.window, 1); if(! toolbarMenuVisible) { wm->reconfigureMenu(); toolbarMenuVisible=True; tm->hideAllVisibleSubmenus(); tm->setAllMenuTitlesVisible(tm, False); if(wm->getTheme()->getToolbarExtraStyle() & TOOLBAR_TOP) tm->show(frame.x, frame.y + frame.height + 1); else tm->show(frame.x, frame.y - tm->getMenuHeight() - 2); } else { toolbarMenuVisible=False; tm->hideAllVisibleSubmenus(); tm->setAllMenuTitlesVisible(tm, True); } return; } } } } void Toolbar::cycle_windows_up() { XSetWindowBorderWidth(wm->getDisplay(), cycleUp.window, 2); XEvent ev; for (;;) { XMaskEvent(wm->getDisplay(), ButtonReleaseMask | LeaveWindowMask, &ev); switch (ev.type) { case LeaveNotify: { XSetWindowBorderWidth(wm->getDisplay(), cycleUp.window, 1); return; } case ButtonRelease: { XSetWindowBorderWidth(wm->getDisplay(), cycleUp.window, 1); XCirculateSubwindowsUp(wm->getDisplay(), wm->getRootWindow()); return; } } } } void Toolbar::cycle_windows_down() { XSetWindowBorderWidth(wm->getDisplay(), cycleDown.window, 2); XEvent ev; for (;;) { XMaskEvent(wm->getDisplay(), ButtonReleaseMask | LeaveWindowMask, &ev); switch (ev.type) { case LeaveNotify: { XSetWindowBorderWidth(wm->getDisplay(), cycleDown.window, 1); return; } case ButtonRelease: { XSetWindowBorderWidth(wm->getDisplay(), cycleDown.window, 1); XCirculateSubwindowsDown(wm->getDisplay(), wm->getRootWindow()); return; } } } } void Toolbar::setStartMenuButtonStateNotPressed() { if(toolbarMenuVisible) { tm->hideAllVisibleSubmenus(); toolbarMenuVisible=False; drawStartMenuButton(); } } void Toolbar::drawStartMenuButton() { bool top = wm->getTheme()->getToolbarExtraStyle() & TOOLBAR_TOP; XClearWindow(wm->getDisplay(), startmenu.window); if(top) { if (toolbarMenuVisible) { // Draws a triangle pointing down // XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(), 3, 6, 12, 6); XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(), 4, 7, 11, 7); XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(), 5, 8, 10, 8); XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(), 6, 9, 9, 9); XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(), 7, 10, 8, 10); } else { // Draws a triangle pointing up // XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(), 7, 6, 8, 6); XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(), 6, 7, 9, 7); XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(), 5, 8, 10, 8); XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(), 4, 9, 11, 9); XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(), 3, 10, 12, 10); } } else { if (!toolbarMenuVisible) { // Draws a triangle pointing down // XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(), 3, 6, 12, 6); XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(), 4, 7, 11, 7); XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(), 5, 8, 10, 8); XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(), 6, 9, 9, 9); XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(), 7, 10, 8, 10); } else { // Draws a triangle pointing up // XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(), 7, 6, 8, 6); XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(), 6, 7, 9, 7); XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(), 5, 8, 10, 8); XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(), 4, 9, 11, 9); XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(), 3, 10, 12, 10); } } } // ToolbarMenu Class Definition below ToolbarMenu::ToolbarMenu() : BaseMenu() { setMenuTitle("Toolbar Menu"); update_all(); wm->addToExtraMenuList(this); } void ToolbarMenu::addMenu(char *title, BaseMenu *sub) { insert(title, sub); update_all(); } sapphire-0.15.8/windowmanager.cc0100644000175000001440000004646607414165525015145 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "windowmanager.hh" WindowManager *wm; char* windowmanager_author = "Frank Hale"; char* windowmanager_author_email = "frankhale@yahoo.com"; char* windowmanager_name = "sapphire"; char* windowmanager_version = "Sapphire 0.15.7pre7 (Blackberry)"; char* windowmanager_usage = "[-display ] [-version]\n"; char* windowmanager_exit_message = "\nThank you for using Sapphire.\n\nPlease Send all bug reports, suggestions, ideas, patches to frankhale@yahoo.com\n"; char* configuration_home = "/usr/share/sapphire"; char* HOME; // This function sets up default values for variables, gets command line args, // sets up our signal handlers, and performs initialization of certain things // to get ready for the window manager to start managing windows. WindowManager::WindowManager(int argc, char **argv) { ::wm = this; HOME = new char[strlen(getenv("HOME"))+1]; strcpy(HOME, getenv("HOME")); font_pix = None; menu_event = false; clock_format = "%m %d %H:%M"; toolbar_visible = true; toolbar_position = false; configurationPath = NULL; windowmanager_conf = NULL; display = NULL; XSetWindowAttributes attr; XColor dummy; head_client = new Client(); // Allocate memory for our linked lists. ClientList = new LinkedList; menulist = new LinkedList; extramenulist = new LinkedList; for (int i = 1; i < argc; i++) { if ((strcmp(argv[i], "-display")==0) && i+1dpy, XC_left_ptr)); // Atoms xa_wm_state = XInternAtom(dpy, "WM_STATE", False); xa_wm_change_state = XInternAtom(dpy, "WM_CHANGE_STATE", False); xa_wm_protos = XInternAtom(dpy, "WM_PROTOCOLS", False); xa_wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False); xa_wm_cmapwins = XInternAtom(dpy, "WM_COLORMAP_WINDOWS", False); xa_wm_take_focus = XInternAtom(dpy, "WM_TAKE_FOCUS", False); xa_wm_motif_hints = XInternAtom(dpy, "_MOTIF_WM_HINTS", False); foreground_color = DEFAULT_FOREGROUND_COLOR; background_color = DEFAULT_BACKGROUND_COLOR; border_color = DEFAULT_BORDER_COLOR; // Colors XAllocNamedColor(dpy, DefaultColormap(dpy, screen), foreground_color, &xforeground_color, &dummy); XAllocNamedColor(dpy, DefaultColormap(dpy, screen), background_color, &xbackground_color, &dummy); XAllocNamedColor(dpy, DefaultColormap(dpy, screen), border_color, &xborder_color, &dummy); colors_per_channel = 4; image_dither = True; image_control = new BImageControl(); image_control->installRootColormap(); theme = new Theme(); getCurrentTheme(); font = theme->getFont(); menufont = theme->getMenuFont(); xfont = XLoadQueryFont(dpy, font); if (!xfont) { // We should really check here to see if we can // find another font just incase. Dying here without // checking again is not cool! err("the default font was not found, aborting."); exit(-1); } iheight = xfont->ascent + xfont->descent + 2 * DEFAULT_SPACE; font_position = iheight - xfont->descent; if(! QueryShapeExtentions()) { printf("What no shape extentions, God you must be using an old X11 release.\n\nHave a nice life\n\nBa Bye...\n\n"); } move_curs = XCreateFontCursor(dpy, XC_fleur); resize_curs = XCreateFontCursor(dpy, XC_plus); left_arrow = XCreateFontCursor(dpy, XC_left_ptr); createFontPixmap(); gv.font = xfont->fid; gv.tile = font_pix; string_gc = XCreateGC(dpy, root, GCTile | GCFont , &gv); XSetFillStyle(dpy, string_gc, FillTiled); gv.foreground = xborder_color.pixel; gv.line_width = DEFAULT_BORDER_SIZE; border_gc = XCreateGC(dpy, root, GCForeground | GCLineWidth, &gv); gv.function = GXinvert; gv.subwindow_mode = IncludeInferiors; invert_gc = XCreateGC(dpy, root, GCFunction | GCSubwindowMode | GCLineWidth, &gv); attr.event_mask = SubstructureRedirectMask | SubstructureNotifyMask | ColormapChangeMask | ButtonPressMask | ButtonReleaseMask | PropertyChangeMask | PointerMotionMask | FocusChangeMask | KeyPressMask | ExposureMask ; XChangeWindowAttributes(dpy, root, CWEventMask, &attr); xres = WidthOfScreen(ScreenOfDisplay(wm->dpy, wm->screen)); yres = HeightOfScreen(ScreenOfDisplay(wm->dpy, wm->screen)); rm = new RootMenu(); t = new Toolbar(); im = new IconMenu(); addToMenuList(rm); rm->parseMenuConfigurationFile(); t->getToolbarMenu()->addMenu("icon menu", im); t->getToolbarMenu()->addMenu("root menu", rm); t->getToolbarMenu()->update_all(); scan_windows(); do_event_loop(); } WindowManager::~WindowManager() { unsigned int i, nwins; Window dw1, dw2, *wins; Client *temp_client=NULL; XQueryTree(dpy, root, &dw1, &dw2, &wins, &nwins); for (i = 0; i < nwins; i++) { temp_client = head_client->find_client(wins[i]); if(temp_client) { temp_client->remove_client(temp_client); } } XFree(wins); ClientList->removeAll(); delete head_client; delete ClientList; image_control->removeImage(font_pix); XFreeFont(dpy, xfont); XFreeGC(dpy, invert_gc); XFreeGC(dpy, string_gc); XFreeGC(dpy, border_gc); delete t; delete rm; delete im; menulist->removeAll(); extramenulist->removeAll(); delete menulist; delete extramenulist; delete theme; delete image_control; delete [] HOME; delete [] windowmanager_conf; delete [] configurationPath; } void WindowManager::getCurrentTheme() { XrmDatabase resource_db; XrmValue value; char *value_type; FILE* currentTheme; bool themeLoaded = false; windowmanager_conf = new char[strlen(HOME) + 32]; sprintf(windowmanager_conf, "%s/.sapphire/wmconf", HOME); if((currentTheme = fopen(windowmanager_conf, "r"))!=NULL) { fclose(currentTheme); XrmInitialize(); resource_db = XrmGetFileDatabase(windowmanager_conf); if (XrmGetResource(resource_db, "toolbar.visible", "Toolbar.Visible", &value_type, &value)) { if(strcmp(value.addr, "true")==0) { theme->setToolbarVisible(); toolbar_visible=true; } else { toolbar_visible=false; } } if (XrmGetResource(resource_db, "toolbar.position", "Toolbar.Position", &value_type, &value)) { if(strcmp(value.addr, "top")==0) { theme->setToolbarTop(); toolbar_position = true; } else { toolbar_position = false; } } // Clock format if (XrmGetResource(resource_db,"clock.format","Clock.Format",&value_type,&value)) { clock_format= new char[value.size]; strcpy(clock_format,value.addr); } else { clock_format="%m %d %H:%M"; } if (XrmGetResource(resource_db, "start.theme", "Start.Theme", &value_type, &value)) { char *buffer = new char[value.size+strlen(HOME)]; strcpy(buffer, value.addr); if (value.addr[0] == '~') { sprintf(buffer, "%s%s", HOME, value.addr+1); } if((currentTheme = fopen(buffer, "r"))!=NULL) { fclose(currentTheme); theme->parseTheme(buffer); themeLoaded=true; } delete [] buffer; } XrmDestroyDatabase(resource_db); } if (! themeLoaded) { char* defaultTheme = new char[strlen(configuration_home) + 32]; sprintf(defaultTheme, "%s/themes/default.theme", configuration_home); theme->parseTheme(defaultTheme); theme->setToolbarVisible(); delete [] defaultTheme; } } void WindowManager::createFontPixmap() { unsigned long style=0; style = wm->getTheme()->getFontStyle(); font_pix = wm->getImageControl()->renderImage( //"xfont", xfont->ascent, xfont->descent, style, wm->getTheme()->getFontColorFrom(), wm->getTheme()->getFontColorTo() ); } // We really should have some way to check if the menu needs // reconfiguring. It shouldn't do anymore processing than // it needs to. void WindowManager::reconfigureMenu() { XGrabServer(dpy); if(menulist->count()) { menulist->removeAll(); rm->removeAll(); addToMenuList(rm); rm->parseMenuConfigurationFile(); } XUngrabServer(dpy); } int WindowManager::QueryShapeExtentions() { int dummy2; return shape = XShapeQueryExtension(dpy, &shape_event, &dummy2); } void WindowManager::scan_windows() { unsigned int i, nwins; Window dw1, dw2, *wins; XWindowAttributes attr; XQueryTree(dpy, root, &dw1, &dw2, &wins, &nwins); for (i = 0; i < nwins; i++) { XGetWindowAttributes(dpy, wins[i], &attr); if (!attr.override_redirect && attr.map_state == IsViewable) head_client->make_new_client(wins[i]); } XFree(wins); } void WindowManager::do_event_loop() { XEvent ev; BaseMenu *m = None; int xfd = ConnectionNumber(wm->dpy); int dx=0,dy=0; for (;;) { if(XPending(wm->dpy)) { XNextEvent(wm->dpy, &ev); switch (ev.type) { case ButtonPress: { head_client->handle_button_press_event(&ev.xbutton); t->do_button_press_event(&ev.xbutton); m = findInMenuList(&ev.xbutton.window); if(m) { m->handle_button_press_event(&ev.xbutton); } switch(ev.xbutton.button) { case 2: { if(ev.xbutton.window == root) { t->setStartMenuButtonStateNotPressed(); im->update_all(); im->setAllMenuTitlesVisible(im,True); im->show(); } break; } case 3: { if(ev.xbutton.window == root) { t->setStartMenuButtonStateNotPressed(); rm->hideAllVisibleSubmenus(); reconfigureMenu(); rm->setAllMenuTitlesVisible(rm, True); rm->show(); } break; } default: { if(ev.xbutton.window == root) { t->setStartMenuButtonStateNotPressed(); im->setAllMenuTitlesVisible(im, False); im->hide(im); rm->setAllMenuTitlesVisible(rm, False); rm->hideAllVisibleSubmenus(); rm->hide(rm); } } break; } break; } case ButtonRelease: { m = findInMenuList(&ev.xbutton.window); if(m) m->handle_button_release_event(&ev.xbutton); switch(ev.xbutton.button) { case 1: case 2: case 3: default: { if(menu_event) { wm->ungrabPointer(); menu_event=false; } } break; } break; } case ConfigureRequest: { head_client->handle_configure_request(&ev.xconfigurerequest); break; } case ConfigureNotify: { break; } case DestroyNotify: { head_client->handle_destroy_notify(&ev.xdestroywindow); break; } case MapRequest: { head_client->handle_map_request(&ev.xmaprequest); break; } case UnmapNotify: { head_client->handle_unmap_event(&ev.xunmap); break; } case ClientMessage: { head_client->handle_client_message(&ev.xclient); break; } case ColormapNotify: { head_client->handle_colormap_change(&ev.xcolormap); break; } case PropertyNotify: { head_client->handle_property_change(&ev.xproperty); break; } case LeaveNotify: { m = findInMenuList(&ev.xcrossing.window); if(m) m->handle_leave_notify(&ev.xcrossing); break; } case EnterNotify: { head_client->handle_enter_event(&ev.xcrossing); m = findInMenuList(&ev.xcrossing.window); if(m) m->handle_enter_notify(&ev.xcrossing); break; } case MotionNotify: { if(menu_event) { grabPointer(root, ButtonReleaseMask | PointerMotionMask, move_curs); dx = ev.xmotion.x_root - menu->menu.x_move; dy = ev.xmotion.y_root - menu->menu.y_move; menu->menu.x = dx; menu->menu.y = dy; XMoveWindow(dpy, menu->menu.window, dx, dy); } m = findInMenuList(&ev.xmotion.window); if(m) m->handle_motion_notify_event(&ev.xmotion); break; } case Expose: { head_client->handle_expose_event(&ev.xexpose); t->handle_expose_event(&ev.xexpose); rm->handle_expose_event(&ev.xexpose); m = findInMenuList(&ev.xexpose.window); if(m) m->handle_expose_event(&ev.xexpose); break; } default: { if (wm->shape && ev.type == wm->shape_event) head_client->handle_shape_change((XShapeEvent *)&ev); break; } } } else { fd_set rfds; FD_ZERO(&rfds); FD_SET(xfd, &rfds); struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 1000; select(xfd + 1, &rfds, 0, 0, &tv); t->checkClock(); } } } // Function: // // void WindowManager::quit_nicely() // // Purpose: // // This functions sole purpose in life is to preform clean up so that we can // shutdown Sapphire safely. // // Returns: // // This function returns nothing. // void WindowManager::quit_nicely() { saveCurrentTheme(); this->~WindowManager(); XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); XInstallColormap(dpy, DefaultColormap(dpy, screen)); XCloseDisplay(dpy); printf("%s", windowmanager_exit_message); exit(0); } void WindowManager::restart() { saveCurrentTheme(); this->~WindowManager(); XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); XInstallColormap(dpy, DefaultColormap(dpy, screen)); XCloseDisplay(dpy); execl("/bin/sh", "sh", "-c", windowmanager_name, 0); } BaseMenu* WindowManager::findInMenuList(Window *w) { if(extramenulist->count()) { LinkedListIterator mx(extramenulist); for(; mx.current(); mx++) { if(*w == mx.current()->getMenuWindow() || *w == mx.current()->getMenuTitleWindow() || *w == mx.current()->getMenuItemWindow()) { return mx.current(); } } } if(menulist->count()) { LinkedListIterator my(menulist); for(; my.current(); my++) { if(*w == my.current()->getMenuWindow() || *w == my.current()->getMenuTitleWindow() || *w == my.current()->getMenuItemWindow()) { return my.current(); } } } return NULL; } void WindowManager::grabPointer(Window w, unsigned int mask, Cursor curs) { if (! XGrabPointer(dpy, w, False, mask, GrabModeAsync, GrabModeAsync, None, curs, CurrentTime) == GrabSuccess ) return; } void WindowManager::ungrabPointer() { XUngrabPointer(dpy, CurrentTime); } void WindowManager::changeTheme(char* themeFile) { image_control->removeAllImages(); theme->parseTheme(themeFile); XFreeFont(dpy, xfont); XFreeGC(dpy, string_gc); if(font_pix) XFreePixmap(dpy, font_pix); xfont = XLoadQueryFont(dpy, theme->getFont()); if(!xfont) { err("the font specified in the current theme was not found, using default font."); xfont = XLoadQueryFont(dpy, font); } font_position = iheight - xfont->descent; createFontPixmap(); gv.font = xfont->fid; gv.tile = font_pix; string_gc = XCreateGC(dpy, root, GCTile | GCFont , &gv); XSetFillStyle(dpy, string_gc, FillTiled); t->changeTheme(); if(ClientList->count()) { LinkedListIterator c(ClientList); for(; c.current(); c++) { c.current()->themeChange(c.current()); } } if(menulist->count()) { LinkedListIterator mx(menulist); for(; mx.current(); mx++) { mx.current()->reconfigure(); } } if(extramenulist->count()) { LinkedListIterator my(extramenulist); for(; my.current(); my++) { my.current()->reconfigure(); } } } void WindowManager::saveCurrentTheme() { // Hopefully I've gotten the bugs out of this function // Only time will tell.... char* save_theme = theme->getCurrentTheme(); FILE *wmconf; if((wmconf = fopen(windowmanager_conf, "w"))==NULL) { char *sapphire_config_dir = new char[strlen(HOME)+30]; sprintf(sapphire_config_dir, "%s/.sapphire", HOME); printf("sapphire_config_dir = %s\n", sapphire_config_dir); mkdir(sapphire_config_dir, S_IRWXU); delete [] sapphire_config_dir; if((wmconf = fopen(windowmanager_conf, "w"))==NULL) { perror("error:\n"); exit(-1); } } if(toolbar_visible) fprintf(wmconf, "toolbar.visible: true\n"); else fprintf(wmconf, "toolbar.visible: false\n"); if(toolbar_position) fprintf(wmconf, "toolbar.position: top\n"); else fprintf(wmconf, "toolbar.position: bottom\n"); fprintf(wmconf, "start.theme: %s\n", save_theme); fprintf(wmconf, "clock.format: %s\n", clock_format); //fprintf(wmconf, "desktops.count: %d\n", max_desktops); fclose(wmconf); } sapphire-0.15.8/basemenu.hh0100644000175000001440000001073307371023325014071 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _BASEMENU_HH_ #define _BASEMENU_HH_ class BaseMenu { protected: // Contains the menu items of this menu. LinkedList *mi; Pixmap menu_pix; Pixmap select_pix; Pixmap title_pix; Pixmap menufont_pix; XSetWindowAttributes attrib; unsigned long create_mask; GC menu_gc; GC select_gc; GC back_gc; XFontStruct *font; XCharStruct overall; int direction; int ascent; int descent; int counter; // for window menu icons / desktop number / etc. int extra_width; bool bottom_edge; bool right_edge; unsigned int item_width,item_height; Cursor curs; // Used to know which item to paint. BaseMenuItem *curr; // This is for our synthetic enter event and we only want this to happen once. bool enterOnce; public: struct Menu { char* menuTitle; Window title; Window window; Window item_window; int x,y; int x_move, y_move; int width,height; bool hasTitle; bool isVisible; unsigned int total_item_height; } menu; public: BaseMenu(); virtual ~BaseMenu(); void setMenuTitle(char* t) { menu.hasTitle=True; menu.menuTitle=new char[strlen(t)+1]; strcpy(menu.menuTitle,t); } char* getMenuTitle() const { return menu.menuTitle; } LinkedList *getMenuItemList() const { return mi; } void setTitleVisible(bool s); void setMenuPos(int x, int y); void show(); void show(int x, int y); void showSub(BaseMenu *sub, int x, int y); void hide(BaseMenu *sub); void hideAllVisibleSubmenus(); void setAllMenuTitlesVisible(BaseMenu *sub, bool s); int getMenuHeight() const { return menu.height; } void update_all(); void update_menu(); void reconfigure(); virtual void insert(char *n, BaseMenu *sub); virtual void insert(char *n, char *exec, int func); virtual void insert(char *n, char *exec, BaseMenu *sub, int func); int remove(BaseMenuItem *element); void removeAll(); BaseMenuItem *findMenuItem(int x, int y); void handle_button_press_event(XButtonEvent *e); void handle_button_release_event(XButtonEvent *e); void handle_enter_notify(XCrossingEvent *e); void handle_leave_notify(XCrossingEvent *e); void handle_expose_event(XExposeEvent *e); void handle_motion_notify_event(XMotionEvent *e); void handle_config_notify_event(XConfigureEvent *e); // The menu item behavoir is defined with these // virtual functions in a derived class. virtual void handle_button1_press(BaseMenuItem *curr) { /* Has no default behavior */ } virtual void handle_button2_press(BaseMenuItem *curr) { /* Has no default behavior */ } virtual void handle_button3_press(BaseMenuItem *curr) { /* Has no default behavior */ } virtual void handle_button1_release(BaseMenuItem *curr) { /* Has no default behavior */ } virtual void handle_button2_release(BaseMenuItem *curr) { /* Has no default behavior */ } virtual void handle_button3_release(BaseMenuItem *curr) { /* Has no default behavior */ } void execute(char *s); // Count relative to zero int getItemCount() const { return mi->count() - 1; } Window getMenuTitleWindow() const { return menu.title; } Window getMenuWindow() const { return menu.window; } Window getMenuItemWindow() const { return menu.item_window; } virtual void redraw(); void hide(); protected: virtual void redraw(BaseMenuItem *m); private: void move(); void createMenuImage(); void createMenuSelectImage(); void createMenuTitleImage(); void createMenuFontImage(); void getMousePosition(int *x, int *y); void testMenuEdgeDetect(BaseMenu *sub); }; #endif sapphire-0.15.8/basemenuitem.hh0100644000175000001440000000257007371023317014751 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _BASEMENUITEM_HH_ #define _BASEMENUITEM_HH_ // Represents a menu item. class BaseMenuItem { public: char *name; // visible name appearing on menu char *exec; // command this item executes. int function; // this would replace exec and execute a // window manager function like shutting down. BaseMenu *sub; // submenu this item points to. bool isSelected; int item_x, item_y; Window icon; // window associated with an icon. Client *client; int index; }; #endif sapphire-0.15.8/client.hh0100644000175000001440000001411007371023311013534 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _CLIENT_HH_ class Client { private: Display *dpy; Window title; Window window; Window parent; Window transient; Window right_sidebar; Window resize_win; Pixmap frame_pix; // Pixmap used for the titlebar Pixmap button_pix; // Pixmap used for titlebar buttons Pixmap right_pix; Pixmap resize_pix; Widget shadeButton; Widget maximize; Widget minimize; Widget close; bool moving; int right_sidebar_width; int default_button_width; int default_button_height; int default_close_button_x; int default_close_button_y; int default_shade_button_x; int default_shade_button_y; int default_minimize_button_x; int default_minimize_button_y; int default_maximize_button_x; int default_maximize_button_y; int default_titlebar_height; int default_client_name_x; int default_client_name_y; int close_button_pressed; int shade_button_pressed; int minimize_button_pressed; int maximize_button_pressed; char *name; char client_position[40]; int text_width; bool shaped; long state; // bitmap of what desktops this client is in int desktop_mask; int away; Colormap cmap; XSizeHints *size; int ignore_unmap; int x; int y; int width; int height; bool override_redirect; int oumx; int oumy; int oumwidth; int oumheight; int old_width; int old_height; bool button1; bool button2; bool button3; bool shaded; bool maxsized; // Titlebar turned on/off bool has_titlebar; // Client buttons turned on/off bool has_close_button; bool has_minimize_button; bool has_maximize_button; bool has_shade_button; bool has_focus; MwmHints *mwm_hint; public: /* member functions */ Client(); ~Client(); Client *find_client(Window w); private: Window createChildWindow(Window parent, int x, int y, unsigned int width, unsigned int height,unsigned int borderwidth); Window createTopLevelWindow(int x, int y, unsigned int width, unsigned int height,unsigned int borderwidth); void init_position(Client *c); void reparent(Client *c); void send_config(Client *c); void resize(Client *c); void move(Client *c); void change_gravity(Client *c, int multiplier); void shade(Client *c); void maximumresize(Client *c); void closeButtonPressed(Client *c); void shadeButtonPressed(Client *c); void minimizeButtonPressed(Client *c); void maximizeButtonPressed(Client *c); void set_shape(Client *c); void drag(Client *c); void sweep(Client *c); void recalculate_sweep(Client *c, int x1, int y1, int x2, int y2); void draw_outline(Client *c); void draw_shade_button(Client *c); int get_wm_state(Client *c); void set_wm_state(Client *c, int state); void redraw(Client *c); void installColorMap(Colormap cmap); void isIconic(Client *c); // If this client is iconic the unmap it otherwise map it int isViewable(Client *c); // Is this client visible? void mapClient(Client *c); // Map Client to screen void getTransients(Client *c); // Set this clients transient // Client window decoration member functions void determineWindowDecorations(Client *c); // Determines if this client needs to have a titlebar and what buttons to display. void createTitleImage(Client* c); // Creates the Title Image void createButtonImage(Client* c); // Creates the Button Image void createRightSidebarImage(Client *c); void createResizeImage(Client *c); void setButtonPositionDefaults(Client *c); void createParentWindow(Client *c); // Creates the Parent Window void createTitlebarWindow(Client *c); // Creates the Titlebar Window void createCloseButtonWindow(Client *c); // Creates the Close Button Window void createMinimizeButtonWindow(Client *c); // Creates the Minimize Button Window void createMaximizeButtonWindow(Client *c); // Creates the Maximimize Button Window void createShadeButtonWindow(Client *c); // Creates the Shade Button Window void createRightSidebarWindow(Client *c); void createResizeWindow(Client *c); int theight(Client *c) const; // returns the titlebar height for a client int send_xmessage(Window w, Atom a, long x, long y); void send_wm_delete(Client *c); void reconfigure(Client *c); public: void hide(Client *c); void unhide(Client *c); void show(Client *c) { mapClient(c); } void raise(); void get_mouse_position(int *x, int *y); void make_new_client(Window w); // Client Events void handle_unmap_event(XUnmapEvent *e); void handle_button_press_event(XButtonEvent *e); void handle_client_message(XClientMessageEvent *e); void handle_colormap_change(XColormapEvent *e); void handle_configure_request(XConfigureRequestEvent *e); void handle_enter_event(XCrossingEvent *e); void handle_expose_event(XExposeEvent *e); void handle_map_request(XMapRequestEvent *e); void handle_property_change(XPropertyEvent *e); void handle_destroy_notify(XDestroyWindowEvent *e); Window getParentWindow() const { return parent; } void themeChange(Client *c); void handle_shape_change(XShapeEvent *e); void remove_client(Client *c); }; #endif sapphire-0.15.8/iconmenu.hh0100644000175000001440000000223407371023250014101 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _ICONMENU_HH #define _ICONMENU_HH class IconMenu : public BaseMenu { public: IconMenu(); ~IconMenu(); void insert(char *name, Client *c); void addIcon(char *name, Client *c); void handle_button1_press(BaseMenuItem* curr); void handle_button1_release(BaseMenuItem* curr); }; #endif sapphire-0.15.8/image.hh0100644000175000001440000001070707371023243013354 0ustar asusers/* * image.hh - Header for image class in Sapphire. * Copyright (C) 1997-1999 by Brad Hughes, bhughes@tcac.net * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __Image_hh #define __Image_hh #include "sapphire.hh" typedef struct BColor { // this is a bad hack to get theme.cc // from complaining because its code // is messed up. /*unsigned char*/ int red, green, blue; unsigned long pixel; }; // bevel options #define BImage_Flat (1<<1) #define BImage_Sunken (1<<2) #define BImage_Raised (1<<3) // textures #define BImage_Solid (1<<4) #define BImage_Gradient (1<<5) // gradients #define BImage_Horizontal (1<<6) #define BImage_Vertical (1<<7) #define BImage_Diagonal (1<<8) // bevel types #define BImage_Bevel1 (1<<9) #define BImage_Bevel2 (1<<10) // inverted image #define BImage_Invert (1<<11) class BImage { private: BImageControl *control; XColor *colors; BColor bg, from, to; int roff, goff, boff, ncolors, cpc, cpccpc; unsigned char *red, *green, *blue; unsigned int width, height; unsigned short *tr, *tg, *tb; protected: void invert(void); void bevel1(Bool = True, Bool = False); void bevel2(Bool = True, Bool = False); void dgradient(void); void hgradient(void); void vgradient(void); void background(const BColor &); XImage *renderXImage(void); Pixmap renderPixmap(void); public: BImage(BImageControl *, unsigned int, unsigned int); ~BImage(void); Pixmap render(unsigned long, const BColor &, const BColor &); Pixmap render_solid(unsigned long, const BColor &); Pixmap render_gradient(unsigned long, const BColor &, const BColor &); }; class BImageControl { private: Colormap root_colormap; Display *display; Window window; // == blackbox->Root(); XColor *colors; int colors_per_channel, ncolors, screen_number, screen_depth, bits_per_pixel, red_offset, green_offset, blue_offset; unsigned short rmask_table[256], gmask_table[256], bmask_table[256], rerr_table[256], gerr_table[256], berr_table[256]; unsigned int dither_buf_width; short *red_err, *green_err, *blue_err, *next_red_err, *next_green_err, *next_blue_err; typedef struct Cache { char *name; Pixmap pixmap; unsigned int count, width, height; unsigned long pixel1, pixel2, texture; } Cache; LinkedList *cache; protected: Pixmap searchCache( //char* name, unsigned int, unsigned int, unsigned long, const BColor &, const BColor &); public: BImageControl(); ~BImageControl(void); // user configurable information Bool dither(void); // details Display *d(void) { return display; } Visual *v(void); Window drawable(void) { return window; } int bpp(void) { return bits_per_pixel; } int depth(void) { return screen_depth; } int screen(void) { return screen_number; } int colorsPerChannel(void) { return colors_per_channel; } unsigned long getColor(const char *); unsigned long getColor(const char *, unsigned char *, unsigned char *, unsigned char *); void installRootColormap(void); // image cache/render requests Pixmap renderImage(/*char* name,*/ unsigned int, unsigned int, unsigned long, const BColor &, const BColor &); void removeImage(Pixmap); void removeAllImages(); // dither buffers void getDitherBuffers(unsigned int, short **, short **, short **, short **, short **, short **, unsigned short **, unsigned short **, unsigned short **); // rgb mask color lookup tables void getMaskTables(unsigned short **, unsigned short **, unsigned short **, int *, int *, int *); // allocated colors void getColorTable(XColor **, int *); }; #endif sapphire-0.15.8/linkedlist.hh0100644000175000001440000001135007414165525014437 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _LINKEDLIST_H_ #define _LINKEDLIST_H_ // Forward declaration. LinkedListIterator needs to be a friend of LinkedList. class _LinkedListIterator; class _LinkedList; // Directions you can traverse the list const int FORWARD = 0; const int BACKWARD = 1; // Element is an node in the list. class Element { public: // This is pretty nasty but I am using friend classed // to circumvent having to write get/set functions, but // I wanna make the next,prev, and data pointers private. // But I still need LinkedList and LinkedListIterator // to access those pointers. friend class _LinkedList; friend class _LinkedListIterator; private: // Variables Element *next; // Pointer to next element Element *prev; // Pointer to previous element void *data; // The data that is stored in this element public: // Member functions Element() { next=NULL; prev=NULL; data=NULL; } }; // LinkedList is a list of elements. class _LinkedList { private: // Variables Element *head, *tail, *iter; int elements; friend class _LinkedListIterator; private: // Member functions // Returns the next element Element* getNextElement() { return (iter != NULL) ? iter=iter->next : NULL; } // Returns the previous element Element* getPrevElement() { return (iter != NULL) ? iter=iter->prev : NULL; } // The next two functions set the direction of traversal // This is for iterating purposes and functions with // LinkedListIterator operator++ and operator--. void setForward() { iter = head; } void setBackward() { iter = tail; } public: // Member functions _LinkedList(); ~_LinkedList(); void* getHead() { return head->data; } void* getTail() { return tail->data; } void insert(void *data); // Inserts an element by data (NOT NODE) void remove(void *data); // Removes an element based on its data void removeAll(); // Remove all elements in this list. Note // that the destructor will do clean up for // you so you don't have to explicity call // this function. Element* find(void *data); // Finds an element by its data // Returns the number of elements in this list int getElementCount() const { return elements; } int count() const { return elements; } }; // LinkedListIterator iterates a list so you can do something with each element. class _LinkedListIterator { private: // Variables _LinkedList *list; Element *element; public: // Member functions _LinkedListIterator(); // Constructor is passed a list and the desired direction of // tranversal. The direction FORWARD is assumed. _LinkedListIterator(_LinkedList *l, int direction = FORWARD) { setList(l, direction); } // The next two functions iterate the list either forward // or backward depending on the direction you specified. void operator++(int) { if(element) element = list->getNextElement(); } void operator--(int) { if(element) element = list->getPrevElement(); } // Reset interation to the beginning depending on the direction // you desire. void reset(int direction = FORWARD); void setList(_LinkedList *l, int direction = FORWARD); void* current() { return ( (element) ? element->data : NULL); } }; template class LinkedList : public _LinkedList { public: LinkedList() : _LinkedList() { } T* first() { return (T*) _LinkedList::getHead(); } T* last() { return (T*) _LinkedList::getTail(); } void insert(T *d) { _LinkedList::insert( (T*) d); } void remove(T *d) { _LinkedList::remove( (T*) d); } }; template class LinkedListIterator : public _LinkedListIterator { public: LinkedListIterator() : _LinkedListIterator() {} LinkedListIterator(_LinkedList *l, int direction = FORWARD) : _LinkedListIterator(l, direction){} T* current() { return (T*) _LinkedListIterator::current(); } }; #endif sapphire-0.15.8/menulex.hh0100644000175000001440000000335207414165525013755 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _MENULEX_HH_ #define _MENULEX_HH_ class MenuLex : public Scanner { private: /* variables */ char* name; // Name displayed in menu title char* exe; RootMenu *root; LinkedList *menulist; int submenus; bool error; public: /* Constructor, Destructor and Member functions */ MenuLex(char *filename, RootMenu *menu); ~MenuLex(); void parse(); private: /* Member functions */ bool menu(bool validate); bool exec(BaseMenu *sub, bool validate); bool theme(BaseMenu *sub, bool validate); bool submenu(BaseMenu *sub, bool validate); bool separator(BaseMenu *sub, bool validate); bool exit(BaseMenu* sub, bool validate); bool restart(BaseMenu* sub, bool validate); bool reconfigure(BaseMenu* sub, bool validate); BaseMenu* getMenu(int index); BaseMenu* getLastMenu(); bool statement(BaseMenu *sub, bool validate); }; #endif sapphire-0.15.8/rootmenu.hh0100644000175000001440000000206707366642017014154 0ustar asusers/* * rootmenu.hh - Declares the RootMenu class. * Copyright (C) 2000 Frank Hale * frankhale@lycos.com * http://sapphire.sourceforge.net/ * * Updated: 5 Nov 2000 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _ROOTMENU_HH #define _ROOTMENU_HH class RootMenu : public BaseMenu { public: RootMenu(); void parseMenuConfigurationFile(); void defaultMenu(); }; #endif sapphire-0.15.8/sapphire.hh0100644000175000001440000000723107371023175014107 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _SAPPHIRE_HH_ #define _SAPPHIRE_HH_ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern char* windowmanager_author; extern char* windowmanager_author_email; extern char* windowmanager_name; extern char* windowmanager_version; extern char* windowmanager_usage; extern char* windowmanager_exit_message; // If you change the following you must change ./data.inst so that // the configuration files get put into the same directory. At the // current time Sapphire will crash if it cannot find its config // files. This will be fixed in the future. extern char* configuration_home; extern char* HOME; /* default settings */ #define DEFAULT_FOREGROUND_COLOR "black" #define DEFAULT_BACKGROUND_COLOR "lightgray" #define DEFAULT_BORDER_COLOR "black" #define DEFAULT_BORDER_SIZE 1 #define DEFAULT_SPACE 3 #define DEFAULT_MARGIN 6 #define DEFAULT_MINIMUM_SIZE 10 // MOTIF hints #define MwmHintsFunctions (1l << 0) #define MwmHintsDecorations (1l << 1) #define MwmFuncAll (1l << 0) #define MwmFuncResize (1l << 1) #define MwmFuncMove (1l << 2) #define MwmFuncIconify (1l << 3) #define MwmFuncMaximize (1l << 4) #define MwmFuncClose (1l << 5) #define MwmDecorAll (1l << 0) #define MwmDecorBorder (1l << 1) #define MwmDecorHandle (1l << 2) #define MwmDecorTitle (1l << 3) #define MwmDecorMenu (1l << 4) #define MwmDecorIconify (1l << 5) #define MwmDecorMaximize (1l << 6) #define PropMwmHintsElements 3 typedef struct MwmHints { unsigned long flags, functions, decorations; } MwmHints; struct Widget { Window window; int x,y; int width,height; bool pressed; }; extern int handle_xerror(Display *dpy, XErrorEvent *e); extern void err(char *fmt, ...); extern void show_event(XEvent e); extern void signalhandler(int i); // Forward declarations for all the classes in Sapphire class BImageControl; class BImage; class WindowManager; class Client; class BaseMenuItem; class BaseMenu; class RootMenu; class IconMenu; class Toolbar; class Theme; class Scanner; class MenuLex; // Include all of the header files #include "linkedlist.hh" #include "image.hh" #include "theme.hh" #include "basemenuitem.hh" #include "basemenu.hh" #include "client.hh" #include "toolbar.hh" #include "rootmenu.hh" #include "iconmenu.hh" #include "scanner.hh" #include "menulex.hh" #include "windowmanager.hh" #endif sapphire-0.15.8/scanner.hh0100644000175000001440000000322507414165525013730 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _SCANNER_HH_ #define _SCANNER_HH_ #define MAX_TOKEN_BUFFER 255 class Scanner { private: char* token; enum char_codes { letters, special, whitespace, openbrace, closebrace, openbracket, closebracket, openparen, closeparen }; char_codes char_class[128]; FILE *in; long backup_pos; char character; public: Scanner(char *filename); ~Scanner(); void getNextToken(bool spaces=false); char* currentToken() const { return token; } bool matchNextToken(char* t); bool match(char* t); void rewind() { if (in==NULL) return; ::rewind(in); } bool eof(); void clearToken() { strcpy (token, ""); } void savePosition() { backup_pos = ftell(in); } void putBackToken() { fseek(in, backup_pos, SEEK_SET); } void concat(); }; #endif sapphire-0.15.8/theme.hh0100644000175000001440000002207107371023164013373 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _THEME_HH_ #define _THEME_HH_ #define TOOLBAR_TOP (1<<1) #define TOOLBAR_VISIBLE (1<<2) #define ROOT_ON (1<<1) #define ROOT_OFF (1<<2) class Theme { private: XrmDatabase resource_db; char* currentTheme; char* font; char* menufont; XFontStruct *xfont; // Each array has 2 elements // // 0 = color_from used for gradients // 1 = color_to used for gradients // // If the image is supposed to be solid then the first color_from is used. // BColor client[2]; BColor buttons[2]; BColor clock[2]; BColor menu[2]; BColor menu_title[2]; BColor menu_select[2]; BColor toolbar[2]; BColor root[2]; BColor client_focus[2]; BColor resize[2]; BColor right_sidebar[2]; BColor font_color[2]; BColor menufont_color[2]; // Bit masks for the different styles for window decorations unsigned long titlebar_style; unsigned long button_style; unsigned long toolbar_style; unsigned long toolbar_extra_style; unsigned long clock_style; unsigned long menu_style; unsigned long menu_title_style; unsigned long menu_select_style; unsigned long resize_style; unsigned long right_sidebar_style; unsigned long root_style; unsigned long root_extra_style; unsigned long font_style; public: Theme(); // This creates the default theme ~Theme(); // This has no purpose since we don't dynamically allocate any memory char* getFont() const { return font; } char* getMenuFont() const { return menufont; } void parseTheme(char *themeFile); char* getCurrentTheme() const { return currentTheme; } unsigned long readDatabaseTexture(char *rname, char *rclass); void setFontStyle(unsigned long style) { font_style=style; } unsigned long getFontStyle() const { return font_style; } void setRootExtraStyle(unsigned long style) { root_extra_style=style; } unsigned long getRootExtraStyle() const { return root_extra_style; } void setRootStyle(unsigned long style) { root_style=style; } unsigned long getRootStyle() const { return root_style; } void setRightSidebarStyle(unsigned long style) { right_sidebar_style=style; } unsigned long getRightSidebarStyle() const { return right_sidebar_style; } void setResizeStyle(unsigned long style) { resize_style=style; } unsigned long getResizeStyle() const { return resize_style; } void setTitlebarStyle(unsigned long style) { titlebar_style=style; } unsigned long getTitlebarStyle() const { return titlebar_style; } void setButtonStyle(unsigned long style) { button_style=style; } unsigned long getButtonStyle() const { return button_style; } void setToolbarStyle(unsigned long style) { toolbar_style=style; } unsigned long getToolbarStyle() const { return toolbar_style; } void setToolbarExtraStyle(unsigned long style) { toolbar_extra_style=style; } unsigned long getToolbarExtraStyle() const { return toolbar_extra_style; } void setToolbarVisible() { toolbar_extra_style|=TOOLBAR_VISIBLE; } void setToolbarTop() { toolbar_extra_style|=TOOLBAR_TOP; } void setClockStyle(unsigned long style) { clock_style=style; } unsigned long getClockStyle() const { return clock_style; } void setMenuStyle(unsigned long style) { menu_style=style; } unsigned long getMenuStyle() const { return menu_style; } void setMenuTitleStyle(unsigned long style) { menu_title_style=style; } unsigned long getMenuTitleStyle() const { return menu_title_style; } void setMenuSelectStyle(unsigned long style) { menu_select_style=style; } unsigned long getMenuSelectStyle() const { return menu_select_style; } void setMenuFontColor(BColor c) { menufont_color[0]=c; } void setMenuFontColorFrom(BColor c) { menufont_color[0]=c; } void setMenuFontColorTo(BColor c) { menufont_color[1]=c; } void setFontColor(BColor c) { font_color[0]=c; } void setFontColorFrom(BColor c) { font_color[0]=c; } void setFontColorTo(BColor c) { font_color[1]=c; } void setClockColor(BColor c) { clock[0]=c; } void setClockColorFrom(BColor c) { clock[0]=c; } void setClockColorTo(BColor c) { clock[1]=c; } void setRightSidebarColor(BColor c) { right_sidebar[0]=c; } void setRightSidebarColorFrom(BColor c) { right_sidebar[0]=c; } void setRightSidebarColorTo(BColor c) { right_sidebar[1]=c; } void setResizeColor(BColor c) { resize[0]=c; } void setResizeColorFrom(BColor c) { resize[0]=c; } void setResizeColorTo(BColor c) { resize[1]=c; } void setClientColor(BColor c) { client[0]=c; } void setClientColorFrom(BColor c) { client[0]=c; } void setClientColorTo(BColor c) { client[1]=c; } void setClientFocusColor(BColor c) { client_focus[0]=c; } void setClientFocusColorFrom(BColor c) { client_focus[0]=c; } void setClientFocusColorTo(BColor c) { client_focus[1]=c; } void setButtonColor(BColor c) { buttons[0] = c; } void setButtonColorFrom(BColor c) { buttons[0] = c; } void setButtonColorTo(BColor c) { buttons[1] = c; } void setMenuTitleColor(BColor c) { menu_title[0]=c; } void setMenuTitleColorFrom(BColor c) { menu_title[0]=c; } void setMenuTitleColorTo(BColor c) { menu_title[1]=c; } void setMenuColor(BColor c) { menu[0]=c; } void setMenuColorFrom(BColor c) { menu[0]=c; } void setMenuColorTo(BColor c) { menu[1]=c; } void setMenuSelectColor(BColor c) { menu_select[0]=c; } void setMenuSelectColorFrom(BColor c) { menu_select[0]=c; } void setMenuSelectColorTo(BColor c) { menu_select[1]=c; } void setToolbarColor(BColor c) { toolbar[0]=c; } void setToolbarColorFrom(BColor c) { toolbar[0]=c; } void setToolbarColorTo(BColor c) { toolbar[1]=c; } void setRootColor(BColor c) { root[0] = c; } void setRootColorFrom(BColor c) { root[0] = c; } void setRootColorTo(BColor c) { root[1] = c; } BColor getMenuFontColor() const { return menufont_color[0];} BColor getMenuFontColorFrom() const { return menufont_color[0];} BColor getMenuFontColorTo() const { return menufont_color[1];} BColor getFontColor() const { return font_color[0]; } BColor getFontColorFrom() const { return font_color[0]; } BColor getFontColorTo() const { return font_color[1]; } BColor getClockColor() const { return clock[0]; } BColor getClockColorFrom() const { return clock[0]; } BColor getClockColorTo() const { return clock[1]; } BColor getRightSidebarColor() const { return right_sidebar[0]; } BColor getRightSidebarColorFrom() const { return right_sidebar[0]; } BColor getRightSidebarColorTo() const { return right_sidebar[1]; } BColor getResizeColor() const { return resize[0]; } BColor getResizeColorFrom() const { return resize[0]; } BColor getResizeColorTo() const { return resize[1]; } BColor getClientColorFrom() const { return client[0]; } BColor getClientColorTo() const { return client[1]; } BColor getClientColor() const { return client[0]; } BColor getClientFocusColorFrom() const { return client_focus[0]; } BColor getClientFocusColorTo() const { return client_focus[1]; } BColor getClientFocusColor() const { return client_focus[0]; } BColor getButtonColorFrom() const { return buttons[0]; } BColor getButtonColorTo() const { return buttons[1]; } BColor getButtonColor() const { return buttons[0]; } BColor getMenuColorFrom() const { return menu[0]; } BColor getMenuColorTo() const { return menu[1]; } BColor getMenuColor() const { return menu[0]; } BColor getMenuTitleColorFrom() const { return menu_title[0]; } BColor getMenuTitleColorTo() const { return menu_title[1]; } BColor getMenuTitleColor() const { return menu_title[0]; } BColor getMenuSelectColorFrom() const { return menu_select[0]; } BColor getMenuSelectColorTo() const { return menu_select[1]; } BColor getMenuSelectColor() const { return menu_select[0]; } BColor getToolbarColorFrom() const { return toolbar[0]; } BColor getToolbarColorTo() const { return toolbar[1]; } BColor getToolbarColor() const { return toolbar[0]; } BColor getRootColorFrom() const { return root[0]; } BColor getRootColorTo() const { return root[1]; } BColor getRootColor() const { return root[0]; } }; #endif sapphire-0.15.8/toolbar.hh0100644000175000001440000001054007371023157013733 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _TOOLBAR_HH_ #define _TOOLBAR_HH_ // Toolbar menu is a combination of your icon and root menus. class ToolbarMenu : public BaseMenu { public: ToolbarMenu(); // addMenu inserts an already created menu into the Toolbar menu // the idea is that the toolbar menu will be a combination of your // icon menu, root menu, and in the future the workspace menu. void addMenu(char *title, BaseMenu *sub); }; // The declaration of the Toolbar class. This class describes all the code // used to maintain a toolbar in Sapphire. class Toolbar { private: /* variables */ Pixmap frame_pix; Pixmap clock_pix; Pixmap button_pix; Pixmap root_pix; XSetWindowAttributes attrib; unsigned long create_mask; struct Frame { Window window; int x,y; unsigned int width,height; }; Frame frame; // This describes the default button width/height used by the toolbar. I have // adopted the size as 15 pixels for both width and height for buttons. That goes // for toolbar buttons aswell. int default_button_width; int default_button_height; // This describes the width of the font used to calculate the size of the clock // window. Its also used in order to place the clock on the toolbar so that its // fully visible. int font_width; // This is the current set of widgets on the toolbar. Widget startmenu; Widget clock; Widget cycleUp; Widget cycleDown; // Used to hold char *Month[12]; // Represents the toolbar menu ToolbarMenu *tm; // Is the toolbarMenuVisible? bool toolbarMenuVisible; public: /* member functions */ // Toolbar constructor this creates the Sapphire toolbar. Toolbar(); // Destructor takes care of clean up (ie. deleting the pixmaps, detroying windows // no longer needed, and removing images from the image cache. ~Toolbar(); // lets another class gain access to the toolbar menu. ToolbarMenu *getToolbarMenu() const { return tm; } // If things change then we need to reconfigure void reconfigure(); void do_button_press_event(XButtonEvent *e); void handle_expose_event(XExposeEvent *e); void redraw(); void checkClock(bool redraw=False); void hideToolbar(); void showToolbar(); // I use this to reset the start button if you select the menu // from the root background. If the menu is popped up on the start // menu then we have to reset and hide that menu since it contains the same // menu's as the ones which pops up when you right click or middle click // on the root window. void setStartMenuButtonStateNotPressed(); void changeTheme(); //void desktopChanged(); private: // The next set of 5 functions create the windows which are associated with // the Sapphire toolbar. void createToolbarWindow(); void createClockWindow(); void createCycleUpButtonWindow(); void createCycleDownButtonWindow(); void createStartMenuButtonWindow();; // The next 4 functions are used to create the images and pixmaps which are // used to make the toolbar look cool. void createToolBarImage(); void createButtonImage(); void createClockImage(); void createRootImage(); // The next 3 functions are button handler functions. These dispatch the code // which executes the various functions the toolbar offers. void popup_toolbar_menu(); void cycle_windows_up(); void cycle_windows_down(); // This function draws the start menu button in two different states. // // - pointing up // - pointing down void drawStartMenuButton(); }; #endif sapphire-0.15.8/windowmanager.hh0100644000175000001440000001354107371023067015137 0ustar asusers/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _WM_HH_ #define _WM_HH_ #include "sapphire.hh" class WindowManager { private: /* variables */ LinkedList *menulist; LinkedList *extramenulist; LinkedList *ClientList; Client *head_client; Toolbar *t; IconMenu *im; RootMenu *rm; Theme *theme; BImageControl *image_control; BaseMenu *menu; Atom xa_wm_state; Atom xa_wm_change_state; Atom xa_wm_protos; Atom xa_wm_delete; Atom xa_wm_cmapwins; Atom xa_wm_take_focus; Atom xa_wm_motif_hints; Window root; Display *dpy; Visual *visual; Pixmap font_pix; XFontStruct *xfont; XGCValues gv; XColor xforeground_color; XColor xbackground_color; XColor xborder_color; GC invert_gc; GC string_gc; GC border_gc; Cursor move_curs; Cursor resize_curs; Cursor left_arrow; char *display; char *font; char *menufont; char *foreground_color; char *background_color; char *border_color; int depth; int xres; int yres; int shape_event; int colors_per_channel; int toolbar_position; int toolbar_visible; int screen; int iheight; int font_position; bool image_dither; bool shape; bool menu_event; // Configuration file stuff char *clock_format; char *configurationPath; char *windowmanager_conf; static KeySym AltKeys[]; public: // member functions below WindowManager(int argc, char **argv); ~WindowManager(); XColor getBorderColor() const { return xborder_color; } XColor getForegroundColor() const { return xforeground_color; } XColor getBackgroundColor() const { return xbackground_color; } GC getInvertGC() const { return invert_gc; } GC getStringGC() const { return string_gc; } GC getBorderGC() const { return border_gc; } int getIHeight() const { return iheight; } char* getMenuFont() const { return menufont; } Cursor getMoveCursor() const { return move_curs; } Cursor getResizeCursor() const { return resize_curs; } Cursor getLeftArrowCursor() const { return left_arrow; } XFontStruct* getXFont() const { return xfont; } bool getShape() const { return shape; } void setShape(bool s) { shape=s; } int getFontPosition() const { return font_position; } Theme* getTheme() const { return theme; } void changeTheme(char* themeFile); // Client List member functions void insertClient(Client *c) { ClientList->insert(c); } void removeClient(Client *c) { ClientList->remove(c); } unsigned int getClientCount() const { return ClientList->count(); } LinkedList* getClientListObject() const { return ClientList; } // Server Grab member functions void Grab() { XGrabServer(dpy); } void Ungrab() { XUngrabServer(dpy); } void SyncUngrab() { XSync(dpy, False); XUngrabServer(dpy); } void addToMenuList(BaseMenu *m) { menulist->insert(m); } void addToExtraMenuList(BaseMenu *m) { extramenulist->insert(m); } void reconfigureMenu(); void removeFromMenuList(BaseMenu *m) { menulist->remove(m); } LinkedList* getMenuList() { return menulist; } BaseMenu* findInMenuList(Window *w); Atom getWMChangeStateAtom() const { return xa_wm_change_state; } Atom getWMStateAtom() const { return xa_wm_state; } Atom getWMDeleteAtom() const { return xa_wm_delete; } Atom getWMProtocolsAtom() const { return xa_wm_protos; } Atom getWMFocusAtom() const { return xa_wm_take_focus; } Atom getWMColormapAtom() const { return xa_wm_cmapwins; } Atom getMotifWMHintsAtom() const { return xa_wm_motif_hints; } int getDepth() const { return depth; } int getScreen() const { return screen; } Visual* getVisual() const { return visual; } int getColorsPerChannel() const { return colors_per_channel; } bool getImageDither() const { return image_dither; } BImageControl *getImageControl() const { return image_control; } Display* getDisplay() const { return dpy; } Window getRootWindow() const { return root; } RootMenu* getRootMenu() const { return rm; } IconMenu* getIconMenu() const { return im; } Toolbar* getToolbar() const { return t; } void grabPointer(Window w, unsigned int mask, Cursor curs); void ungrabPointer(); void quit_nicely(); void restart(); int getXRes() const { return xres; } int getYRes() const { return yres; } char* getClockFormat() const { return clock_format; } //void handleKeyPress(XEvent *ev); // desktop is from 0 to 15, inclusive (not a bit mask like in changeDesktop) void goToDesktop(int desktop); void goToNextDesktop(); void goToPreviousDesktop(); void setMenu(BaseMenu* bm) { menu=bm; } void setMenuEvent(bool me) { menu_event=me; } private: /* member functions */ int QueryShapeExtentions(); void scan_windows(); void do_event_loop(); void createFontPixmap(); void createMenuFontPixmap(); void saveCurrentTheme(); void getCurrentTheme(); }; extern WindowManager *wm; #endif sapphire-0.15.8/ISSUES0100644000175000001440000000051507414171012012677 0ustar asusersThere are too many issues to list. This was my first attempt at creating a window manager. It was started in 1999. The code has many issues and is very difficult to maintain. If you find a bug please send me a bug report or a patch =) frankhale@yahoo.com Or catch me on IRC logged into irc.openprojects.net at channel #sapphirewm