// wmmixer - A mixer designed for WindowMaker // // Release 1.5 // Copyright (C) 1998 Sam Hawker <shawkie@geocities.com> // Copyright (C) 2002 Gordon Fraser <gordon@debian.org> // This software comes with ABSOLUTELY NO WARRANTY // This software is free software, and you are welcome to redistribute it // under certain conditions // See the COPYING file for details. #include "xhandler.h" //-------------------------------------------------------------------- XHandler::XHandler() { is_wmaker_ = WINDOWMAKER; is_ushape_ = USESHAPE; is_astep_ = AFTERSTEP; strcpy(display_name_, ""); strcpy(position_name_, ""); strcpy(ledcolor_name_, LEDCOLOR); strcpy(ledcolor_high_name_, LEDCOLOR_HIGH); strcpy(backcolor_name_, BACKCOLOR); strcpy(window_class_, CLASS); button_state_ = 0; icon_list_ = NULL; } //-------------------------------------------------------------------- XHandler::~XHandler() { XFreeGC(display_default_, graphics_context_); XFreePixmap(display_default_, pixmap_main); XFreePixmap(display_default_, pixmap_tile); XFreePixmap(display_default_, pixmap_disp); XFreePixmap(display_default_, pixmap_mask); XFreePixmap(display_default_, pixmap_icon); XFreePixmap(display_default_, pixmap_nrec); XDestroyWindow(display_default_, window_main_); if(is_wmaker_) XDestroyWindow(display_default_, window_icon_); XCloseDisplay(display_default_); delete[] icon_list_; } //-------------------------------------------------------------------- void XHandler::init(int argc, char** argv, int num_channels) { int display_depth; window_size_=is_astep_ ? ASTEPSIZE : NORMSIZE; if((display_default_ = XOpenDisplay(display_name_))==NULL) { std::cerr << NAME << " : Unable to open X display '" << XDisplayName(display_name_) << "'." << std::endl; exit(1); } initWindow(argc, argv); initColors(); display_depth = DefaultDepth(display_default_, DefaultScreen(display_default_)); initPixmaps(display_depth); initGraphicsContext(); initMask(); initIcons(num_channels); } //-------------------------------------------------------------------- bool XHandler::isLeftButton(int x, int y) { return(x>=BTN_LEFT_X && y>=BTN_LEFT_Y && x<=BTN_LEFT_X + BTN_WIDTH && y<=BTN_LEFT_Y + BTN_HEIGHT); } //-------------------------------------------------------------------- bool XHandler::isRightButton(int x, int y) { return(x>=BTN_RIGHT_X && y>=BTN_RIGHT_Y && x<=BTN_RIGHT_X + BTN_WIDTH && y<=BTN_RIGHT_Y + BTN_HEIGHT); } //-------------------------------------------------------------------- bool XHandler::isMuteButton(int x, int y) { return(x>=BTN_MUTE_X && y>=BTN_MUTE_Y && x<=BTN_MUTE_X + BTN_WIDTH && y<=BTN_MUTE_Y + BTN_HEIGHT); } //-------------------------------------------------------------------- bool XHandler::isRecButton(int x, int y) { return(x>=BTN_REC_X && y>=BTN_REC_Y && x<=BTN_REC_X + BTN_WIDTH && y<=BTN_REC_Y + BTN_HEIGHT); } //-------------------------------------------------------------------- bool XHandler::isVolumeBar(int x, int y) { return(x>=37 && x<=56 && y>=8 && y<=56); } //-------------------------------------------------------------------- unsigned long XHandler::getColor(char *colorname) { XColor color; XWindowAttributes winattr; XGetWindowAttributes(display_default_, window_root_, &winattr); color.pixel=0; XParseColor(display_default_, winattr.colormap, colorname, &color); color.flags=DoRed | DoGreen | DoBlue; XAllocColor(display_default_, winattr.colormap, &color); return color.pixel; } //-------------------------------------------------------------------- unsigned long XHandler::mixColor(char *colorname1, int prop1, char *colorname2, int prop2) { XColor color, color1, color2; XWindowAttributes winattr; XGetWindowAttributes(display_default_, window_root_, &winattr); XParseColor(display_default_, winattr.colormap, colorname1, &color1); XParseColor(display_default_, winattr.colormap, colorname2, &color2); color.pixel = 0; color.red = (color1.red*prop1+color2.red*prop2)/(prop1+prop2); color.green = (color1.green*prop1+color2.green*prop2)/(prop1+prop2); color.blue = (color1.blue*prop1+color2.blue*prop2)/(prop1+prop2); color.flags = DoRed | DoGreen | DoBlue; XAllocColor(display_default_, winattr.colormap, &color); return color.pixel; } //-------------------------------------------------------------------- void XHandler::repaint() { flush_expose(window_icon_); XCopyArea(display_default_, pixmap_disp, window_icon_, graphics_context_, 0, 0, 64, 64, window_size_/2-32, window_size_/2-32); flush_expose(window_main_); XCopyArea(display_default_, pixmap_disp, window_main_, graphics_context_, 0, 0, 64, 64, window_size_/2-32, window_size_/2-32); XEvent xev; while(XCheckTypedEvent(display_default_, Expose, &xev)); } //-------------------------------------------------------------------- void XHandler::update(unsigned channel) { if(is_wmaker_ || is_ushape_ || is_astep_) { XShapeCombineMask(display_default_, window_icon_, ShapeBounding, window_size_/2-32, window_size_/2-32, pixmap_mask, ShapeSet); XShapeCombineMask(display_default_, window_main_, ShapeBounding, window_size_/2-32, window_size_/2-32, pixmap_mask, ShapeSet); } else { XCopyArea(display_default_, pixmap_tile, pixmap_disp, graphics_context_, 0, 0, 64, 64, 0, 0); } XSetClipMask(display_default_, graphics_context_, pixmap_mask); XCopyArea(display_default_, pixmap_main, pixmap_disp, graphics_context_, 0, 0, 64, 64, 0, 0); XSetClipMask(display_default_, graphics_context_, None); XCopyArea(display_default_, pixmap_icon, pixmap_disp, graphics_context_, icon_list_[channel]*22, 0, 22, 22, 6, 5); } //-------------------------------------------------------------------- void XHandler::drawLeft(unsigned curleft) { XSetForeground(display_default_, graphics_context_, shade_colors_[(curleft*25)/100]); for(unsigned i=0;i<25;i++) { if(i >= (curleft*25)/100) { XSetForeground(display_default_, graphics_context_, colors_[3]); } else { XSetForeground(display_default_, graphics_context_, shade_colors_[i]); } XFillRectangle(display_default_, pixmap_disp, graphics_context_, 37, 55-2*i, 9, 1); } } //-------------------------------------------------------------------- void XHandler::drawRight(unsigned curright) { for(unsigned i=0;i<25;i++) { if(i >= (curright*25)/100) { XSetForeground(display_default_, graphics_context_, colors_[3]); } else { XSetForeground(display_default_, graphics_context_, shade_colors_[i]); } XFillRectangle(display_default_, pixmap_disp, graphics_context_, 48, 55-2*i, 9, 1); } } //-------------------------------------------------------------------- // Based on wmsmixer by Damian Kramer <psiren@hibernaculum.demon.co.uk> void XHandler::drawMono(unsigned curright) { XSetForeground(display_default_, graphics_context_, colors_[1]); for(unsigned i=0;i<25;i++) { if(i >= (curright*25)/100) { XSetForeground(display_default_, graphics_context_, colors_[3]); } else { XSetForeground(display_default_, graphics_context_, shade_colors_[i]); } XFillRectangle(display_default_, pixmap_disp, graphics_context_, 37, 55-2*i, 20, 1); } } //-------------------------------------------------------------------- void XHandler::drawBtns(int buttons, bool curshowrec) { if(buttons & BTNPREV) drawButton(BTN_LEFT_X, BTN_LEFT_Y, BTN_WIDTH, BTN_HEIGHT, (button_state_ & BTNPREV)); if(buttons & BTNNEXT) drawButton(BTN_RIGHT_X, BTN_RIGHT_Y, BTN_WIDTH, BTN_HEIGHT, (button_state_ & BTNNEXT)); if(buttons & BTNMUTE) drawButton(BTN_MUTE_X, BTN_MUTE_Y, BTN_WIDTH, BTN_HEIGHT, (button_state_ & BTNMUTE)); if(buttons & BTNREC){ drawButton(BTN_REC_X, BTN_REC_Y, BTN_WIDTH, BTN_HEIGHT, (button_state_ & BTNREC)); if(!curshowrec) XCopyArea(display_default_, pixmap_nrec, pixmap_disp, graphics_context_, 0, 0, 9, 8, 6, 47); else XCopyArea(display_default_, pixmap_main, pixmap_disp, graphics_context_, 6, 48, 9, 8, 6, 47); } } //-------------------------------------------------------------------- void XHandler::drawButton(int x, int y, int w, int h, bool down) { if(!down) XCopyArea(display_default_, pixmap_main, pixmap_disp, graphics_context_, x, y, w, h, x, y); else { XCopyArea(display_default_, pixmap_main, pixmap_disp, graphics_context_, x, y, 1, h-1, x+w-1, y+1); XCopyArea(display_default_, pixmap_main, pixmap_disp, graphics_context_, x+w-1, y+1, 1, h-1, x, y); XCopyArea(display_default_, pixmap_main, pixmap_disp, graphics_context_, x, y, w-1, 1, x+1, y+h-1); XCopyArea(display_default_, pixmap_main, pixmap_disp, graphics_context_, x+1, y+h-1, w-1, 1, x, y); } } //-------------------------------------------------------------------- int XHandler::flush_expose(Window w) { XEvent dummy; int i=0; while (XCheckTypedWindowEvent(display_default_, w, Expose, &dummy)) i++; return i; } //-------------------------------------------------------------------- int XHandler::getWindowSize() { return window_size_; } //-------------------------------------------------------------------- // --> inline //Display* XHandler::getDisplay() //{ // return display_default_; //} //-------------------------------------------------------------------- int XHandler::getButtonState() { return button_state_; } //-------------------------------------------------------------------- void XHandler::setButtonState(int button_state) { button_state_ = button_state; } //-------------------------------------------------------------------- void XHandler::setDisplay(char* arg) { sprintf(display_name_, "%s", arg); } //-------------------------------------------------------------------- void XHandler::setPosition(char* arg) { sprintf(position_name_, "%s", arg); } //-------------------------------------------------------------------- void XHandler::setLedColor(char* arg) { sprintf(ledcolor_name_, "%s", arg); } //-------------------------------------------------------------------- void XHandler::setLedHighColor(char* arg) { sprintf(ledcolor_high_name_, "%s", arg); } //-------------------------------------------------------------------- void XHandler::setBackColor(char* arg) { sprintf(backcolor_name_, "%s", arg); } //-------------------------------------------------------------------- void XHandler::setWindowClass(char* arg) { snprintf(window_class_, 254, "%s", arg); } //-------------------------------------------------------------------- void XHandler::setUnshaped() { is_ushape_ = 1; } //-------------------------------------------------------------------- void XHandler::setWindowMaker() { is_wmaker_ = 1; } //-------------------------------------------------------------------- void XHandler::setAfterStep() { is_astep_ = 1; } //-------------------------------------------------------------------- Atom XHandler::getDeleteWin() { return deleteWin; } //-------------------------------------------------------------------- void XHandler::initIcons(int num) { if(icon_list_) delete[] icon_list_; icon_list_ = new unsigned[num]; icon_list_[0] = 0; icon_list_[1] = 7; icon_list_[2] = 8; icon_list_[3] = 2; icon_list_[4] = 1; icon_list_[5] = 6; icon_list_[6] = 4; icon_list_[7] = 5; icon_list_[8] = 3; for(int counter=9; counter<num; counter++) icon_list_[counter] = 9; } //-------------------------------------------------------------------- void XHandler::initGraphicsContext() { XGCValues gcv; unsigned long gcm; gcm = GCForeground | GCBackground | GCGraphicsExposures; gcv.graphics_exposures = 0; gcv.foreground = fore_pix; gcv.background = back_pix; graphics_context_ = XCreateGC(display_default_, window_root_, gcm, &gcv); } //-------------------------------------------------------------------- void XHandler::initPixmaps(int display_depth) { XpmColorSymbol const xpmcsym[4]={{(char *)"back_color", NULL, colors_[0]}, {(char *)"led_color_high", NULL, colors_[1]}, {(char *)"led_color_med", NULL, colors_[2]}, {(char *)"led_color_low", NULL, colors_[3]}}; XpmAttributes xpmattr; xpmattr.numsymbols = 4; xpmattr.colorsymbols = (XpmColorSymbol *)xpmcsym; xpmattr.exactColors = false; xpmattr.closeness = 40000; xpmattr.valuemask = XpmColorSymbols | XpmExactColors | XpmCloseness; XpmCreatePixmapFromData(display_default_, window_root_, (char **)wmmixer_xpm, &pixmap_main, &pixmap_mask, &xpmattr); XpmCreatePixmapFromData(display_default_, window_root_, (char **)tile_xpm, &pixmap_tile, NULL, &xpmattr); XpmCreatePixmapFromData(display_default_, window_root_, (char **)icons_xpm, &pixmap_icon, NULL, &xpmattr); XpmCreatePixmapFromData(display_default_, window_root_, (char **)norec_xpm, &pixmap_nrec, NULL, &xpmattr); pixmap_disp = XCreatePixmap(display_default_, window_root_, 64, 64, display_depth); } //-------------------------------------------------------------------- void XHandler::initWindow(int argc, char** argv) { char *wname = argv[0]; int screen, dummy = 0; XWMHints wmhints; XSizeHints shints; XClassHint classHint; XTextProperty name; screen = DefaultScreen(display_default_); _XA_GNUSTEP_WM_FUNC = XInternAtom(display_default_, "_GNUSTEP_WM_FUNCTION", false); deleteWin = XInternAtom(display_default_, "WM_DELETE_WINDOW", false); shints.x = 0; shints.y = 0; // shints.flags = USSize; shints.flags = 0; // Gordon bool pos = (XWMGeometry(display_default_, DefaultScreen(display_default_), position_name_, NULL, 0, &shints, &shints.x, &shints.y, &shints.width, &shints.height, &dummy) & (XValue | YValue)); shints.min_width = window_size_; shints.min_height = window_size_; shints.max_width = window_size_; shints.max_height = window_size_; shints.base_width = window_size_; shints.base_height = window_size_; shints.width = window_size_; shints.height = window_size_; shints.flags=PMinSize | PMaxSize | PBaseSize; // Gordon window_root_ = RootWindow(display_default_, screen); back_pix = getColor((char *)"white"); fore_pix = getColor((char *)"black"); window_main_ = XCreateSimpleWindow(display_default_, window_root_, shints.x, shints.y, shints.width, shints.height, 0, fore_pix, back_pix); window_icon_ = XCreateSimpleWindow(display_default_, window_root_, shints.x, shints.y, shints.width, shints.height, 0, fore_pix, back_pix); XSetWMNormalHints(display_default_, window_main_, &shints); wmhints.icon_x = shints.x; wmhints.icon_y = shints.y; if(is_wmaker_ || is_astep_ || pos) shints.flags |= USPosition; if(is_wmaker_) { wmhints.initial_state = WithdrawnState; wmhints.flags = StateHint | IconWindowHint | IconPositionHint | WindowGroupHint; wmhints.icon_window = window_icon_; wmhints.icon_x = shints.x; wmhints.icon_y = shints.y; wmhints.window_group = window_main_; } else { wmhints.initial_state = NormalState; wmhints.flags = WindowGroupHint | StateHint; } classHint.res_name=(char *)NAME; classHint.res_class = window_class_; XSetClassHint(display_default_, window_main_, &classHint); XSetClassHint(display_default_, window_icon_, &classHint); if (XStringListToTextProperty(&wname, 1, &name) == 0) { std::cerr << wname << ": can't allocate window name" << std::endl; exit(1); } XSetWMName(display_default_, window_main_, &name); XSetWMHints(display_default_, window_main_, &wmhints); XSetCommand(display_default_, window_main_, argv, argc); XSetWMProtocols(display_default_, window_main_, &deleteWin, 1); // Close } //-------------------------------------------------------------------- // Initialize main colors and shaded color-array for bars void XHandler::initColors() { colors_[0] = mixColor(ledcolor_name_, 0, backcolor_name_, 100); colors_[1] = mixColor(ledcolor_name_, 100, backcolor_name_, 0); colors_[2] = mixColor(ledcolor_name_, 60, backcolor_name_, 40); colors_[3] = mixColor(ledcolor_name_, 25, backcolor_name_, 75); for(int count=0; count<25; count++) { shade_colors_[count] = mixColor(ledcolor_high_name_, count*2, ledcolor_name_, 100-count*4); } } //-------------------------------------------------------------------- void XHandler::initMask() { XSetClipMask(display_default_, graphics_context_, pixmap_mask); XCopyArea( display_default_, pixmap_main, pixmap_disp, graphics_context_, 0, 0, 64, 64, 0, 0); XSetClipMask(display_default_, graphics_context_, None); XStoreName( display_default_, window_main_, NAME); XSetIconName(display_default_, window_main_, NAME); if(is_wmaker_ || is_ushape_ || is_astep_) { XShapeCombineMask(display_default_, window_icon_, ShapeBounding, window_size_/2-32, window_size_/2-32, pixmap_mask, ShapeSet); XShapeCombineMask(display_default_, window_main_, ShapeBounding, window_size_/2-32, window_size_/2-32, pixmap_mask, ShapeSet); } else { XCopyArea(display_default_, pixmap_tile, pixmap_disp, graphics_context_, 0, 0, 64, 64, 0, 0); } XSelectInput(display_default_, window_main_, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask); XSelectInput(display_default_, window_icon_, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask); XMapWindow(display_default_, window_main_); }