// bbsmount_base.cc for bbsmount - an tool for simple mounting in X11 // // Copyright (c) 2001 by Miroslav Jezbera, jezberam@phoenix.inf.upol.cz // // 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. // // (See the included file COPYING / GPL-2.0) // #ifdef HAVE_CONFIG_H # include "config.h" #endif /* HAVE_CONFIG_H */ #ifdef HAVE_UNISTD_H # include #endif /* HAVE_UNISTD_H */ #include #include #define __USE_BSD 1 #include #include "bbsmount_base.hh" #include "bbsmount.hh" File::File(const char * file_name, const char * images_prefix) { path = NULL; const_cast(images_path) = images_prefix; FindFile(file_name); } File::~File() { if (path) free(path); } bool File::Exist(void) const { return (path != NULL); } char * File::GetPath(void) const { return path; } void File::FindFile(const char *file_name) { struct stat info; char *str, *default_dir; int length; if (!file_name) return; if (stat(file_name, &info) == 0) { // This file is in current directory path = strdup(file_name); return; } if (images_path) { length = strlen(images_path); str = (char *)malloc(sizeof(char) * (length + strlen(file_name) + 2)); str = strcpy(str, images_path); if (str[length - 1] != '/') { str[length + 1] = '\0'; str[length] = '/'; } str = strcat(str, file_name); if (stat(str, &info) == 0) { // This file is in image_prefix path = str; return; } free(str); } default_dir = IMAGES_DIR; length = strlen(default_dir); str = (char *)malloc(sizeof(char) * (length + strlen(file_name) + 2)); sprintf(str, "%s/%s", default_dir, file_name); if (stat(str, &info) == 0) { // This file is in default directory path = str; return; } free(str); } Action::Action() { command_if_mouted = 0; command_if_not_mounted = 0; button = 0; modifiers = 0; nmodifiers = 0; } Action::Action(const Action ©) { command_if_mouted = copy.GetCommand(true); command_if_not_mounted = copy.GetCommand(false); button = copy.GetButton(); modifiers = copy.GetModifiers(); nmodifiers = copy.GetNegativeModifiers(); } Action::~Action() { } unsigned int Action::GetCommand(const bool mounted) const { if (mounted) return command_if_mouted; else return command_if_not_mounted; } unsigned int Action::GetButton() const { return button; } unsigned int Action::GetModifiers() const { return modifiers; } unsigned int Action::GetNegativeModifiers() const { return nmodifiers; } bool Action::IsActive(const unsigned int _button, const unsigned int state) const { return (_button == button && (state & modifiers) == modifiers && (state & nmodifiers) == 0); } void Action::SetCommand(const unsigned int command, const bool mounted) { if (mounted) { command_if_mouted = command; if (!command_if_not_mounted) command_if_not_mounted = command; } else { command_if_not_mounted = command; if (!command_if_mouted) command_if_mouted = command; } } void Action::SetButton(const unsigned int _button) { button = _button; } void Action::AddModifier(const unsigned int _modifier) { if (!(_modifier & nmodifiers)) modifiers |= _modifier; } void Action::AddNegativeModifier(const unsigned int _modifier) { if (!(_modifier & modifiers)) nmodifiers |= _modifier; } MountPoint::MountPoint(const string &_mountpoint) { mountpoint = _mountpoint; mounted_image = not_mounted_image = mounted_info = not_mounted_info = error_info = 0; mounted = false; commandlock = false; was_error = false; } MountPoint::MountPoint(const MountPoint ©) { mountpoint = copy.GetMountPoint(); mounted_image = copy.GetMountedImage(); description = copy.getDescription(); not_mounted_image = copy.GetNotMountedImage(); mounted_info = copy.getMountedInfo(); not_mounted_info = copy.getNotMountedInfo(); error_info = copy.getErrorInfo(); mounted = copy.IsMounted(); actions = copy.GetActions(); commandlock = false; was_error = false; } MountPoint::~MountPoint() { } bool MountPoint::IsMounted() const { return mounted; } unsigned int MountPoint::GetMountedImage() const { return mounted_image; } unsigned int MountPoint::GetNotMountedImage() const { return not_mounted_image; } unsigned int MountPoint::GetCurrentImage(bool &ismounted) const { ismounted = mounted; if (ismounted) return mounted_image; else return not_mounted_image; } unsigned int MountPoint::getMountedInfo(void) const { return mounted_info; } unsigned int MountPoint::getNotMountedInfo(void) const { return not_mounted_info; } unsigned int MountPoint::getErrorInfo(void) const { return error_info; } unsigned int MountPoint::getCurrentInfo(void) const { if (was_error) return error_info; else if (mounted) return mounted_info; else return not_mounted_info; } const string & MountPoint::GetMountPoint() const { return mountpoint; } const string & MountPoint::getDescription(void) const { return description; } const string & MountPoint::getLastError(void) const { return last_error; } const set & MountPoint::GetActions() const { return actions; } unsigned int MountPoint::GetCommand(const unsigned int button, const unsigned int state) const { set::iterator pointer = actions.begin(); for (; pointer != actions.end(); pointer++) if (pointer->IsActive(button, state)) return pointer->GetCommand(mounted); return 0; } bool MountPoint::IsLocked() const { return commandlock; } void MountPoint::AddAction(const Action &action) { actions.insert(action); } void MountPoint::SetMountedImage(const unsigned int image) { mounted_image = image; } void MountPoint::SetNotMountedImage(const unsigned int image) { not_mounted_image = image; } void MountPoint::setMountedInfo(const unsigned int infotext) { mounted_info = infotext; } void MountPoint::setNotMountedInfo(const unsigned int infotext) { not_mounted_info = infotext; } void MountPoint::setErrorInfo(const unsigned int infotext) { error_info = infotext; } void MountPoint::setDescription(const string &desc) { description = desc; } void MountPoint::setLastError(const string &error) { was_error = true; last_error = error; } void MountPoint::clearError(void) { was_error = false; last_error.erase(); } void MountPoint::SetMounted(const bool is_mounted) { was_error = false; mounted = is_mounted; } void MountPoint::Lock() { commandlock = true; } void MountPoint::Unlock() { commandlock = false; } MyImage::MyImage(Display *_dpy, const Pixmap image, const Pixmap shape) { normal_pixmap = image; shape_pixmap = shape; dpy = _dpy; } MyImage::MyImage(Display *_dpy, const Window &rootwin, XpmImage *image) { XpmAttributes attrs; int result; dpy = _dpy; attrs.visual = DefaultVisual(dpy, DefaultScreen(dpy)); attrs.colormap = DefaultColormap(dpy, DefaultScreen(dpy)); attrs.depth = DefaultDepth(dpy, DefaultScreen(dpy)); attrs.width = 0; attrs.height = 0; attrs.x_hotspot = 0; attrs.y_hotspot = 0; attrs.cpp = 0; attrs.pixels = (Pixel *)0; attrs.npixels = 0; attrs.colorsymbols = (XpmColorSymbol *)0; attrs.numsymbols = 0; attrs.rgb_fname = NULL; attrs.nextensions = 0; attrs.extensions = (XpmExtension *)0; attrs.closeness = 0; attrs.exactColors = True; attrs.valuemask = XpmVisual | XpmColormap | XpmDepth | XpmExactColors | XpmCloseness; result = XpmCreatePixmapFromXpmImage(dpy, rootwin, image, &normal_pixmap, &shape_pixmap, &attrs); switch (result) { case XpmColorError: #if DEBUG if (debug_level >= dbg_warning) printf("XpmError: Color substitution was needed.\n"); #endif break; case XpmColorFailed: printf("XpmError: Color allocation failed! Insufficient colors available, increase screen depth\n"); attrs.exactColors = False; attrs.closeness = 50000; result = XpmCreatePixmapFromXpmImage(dpy, rootwin, image, &normal_pixmap, &shape_pixmap, &attrs); if (result != XpmSuccess && result != XpmColorError) printf("XpmError: Dithering failed!\n"); else printf("Using dithered image.\n"); break; case XpmNoMemory: printf("XpmError: Not enough memory for XpmImage to Pixmap conversion!\n"); break; case XpmSuccess: #if DEBUG if (debug_level >= dbg_all_work) printf("Conversion from XpmImage to Pixmap was successful.\n"); #endif break; } XpmFreeAttributes(&attrs); } MyImage::MyImage(const MyImage ©) { normal_pixmap = copy.GetImage(); shape_pixmap = copy.GetImageShape(); dpy = AppWindow->getXDisplay(); } MyImage::~MyImage() { XFreePixmap(dpy, normal_pixmap); XFreePixmap(dpy, shape_pixmap); } Display * MyImage::GetDisplay() { return dpy; } Pixmap MyImage::GetImage(void) const { return normal_pixmap; } Pixmap MyImage::GetImageShape(void) const { return shape_pixmap; } MountWindow::MountWindow(MountPoint *_mountpoint, Display *_display, const Window _parent, const int _x, const int _y, const unsigned int _width, const unsigned int _height) { unsigned long create_mask; XSetWindowAttributes attribs; XGCValues values; mountpoint = _mountpoint; display = _display; parent = _parent; x = _x; y = _y; width = _width; height = _height; drawmounted = false; create_mask = CWBackPixmap | CWEventMask; attribs.background_pixmap = AppWindow->GetPixmaps().draw; raised = true; // attribs.event_mask = ButtonPressMask | ButtonReleaseMask | ExposureMask; attribs.event_mask = ButtonPressMask | ButtonReleaseMask | ExposureMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask; mywindow = XCreateWindow(display, parent, x, y, width, height, 0, CopyFromParent, InputOutput, CopyFromParent, create_mask, &attribs); mywindowgc = XCreateGC(display, mywindow, 0L, &values); } MountWindow::~MountWindow() { XFreeGC(display, mywindowgc); XDestroyWindow(display, mywindow); } const Window MountWindow::GetWindow() const { return mywindow; } MountPoint & MountWindow::GetMountPoint(void) { return (*mountpoint); } void MountWindow::Update(void) { bool ismounted; mountpoint->GetCurrentImage(ismounted); if (ismounted != drawmounted) Draw(); } void MountWindow::SetPressed(const bool is_pressed) { if (is_pressed == raised) Draw(!is_pressed); } void MountWindow::Draw(const bool _raised) { XGCValues values; int imageidx; if (raised != _raised) { raised = _raised; XSetWindowBackgroundPixmap(display, mywindow, (raised ? AppWindow->GetPixmaps().draw : AppWindow->GetPixmaps().draw_pressed)); } imageidx = mountpoint->GetCurrentImage(drawmounted); values.clip_mask = AppWindow->GetImage(imageidx).GetImageShape(); XClearWindow(display, mywindow); XChangeGC(display, mywindowgc, GCClipMask, &values); XCopyArea(display, AppWindow->GetImage(imageidx).GetImage(), mywindow, mywindowgc, 0, 0, width, height, 0, 0); } void MountWindow::Draw(const int _x, const int _y, const unsigned int _width, const unsigned int _height) { bool ismounted; int imageidx; imageidx = mountpoint->GetCurrentImage(ismounted); if (ismounted != drawmounted) Draw(); else { XClearArea(display, mywindow, _x, _y, _width, _height, False); XCopyArea(display, AppWindow->GetImage(imageidx).GetImage(), mywindow, mywindowgc, _x, _y, _width, _height, _x, _y); } } void MountWindow::Resize(const unsigned int _width, const unsigned int _height) { width = _width; height = _height; XResizeWindow(display, mywindow, width, height); } void MountWindow::Move(const int _x, const int _y) { x = _x; y = _y; XMoveWindow(display, mywindow, x, y); } void MountWindow::MoveResize(const int _x, const int _y, const unsigned int _width, const unsigned int _height) { x = _x; y = _y; width = _width; height = _height; XMoveResizeWindow(display, mywindow, x, y, width, height); }