// 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 <unistd.h>
#endif /* HAVE_UNISTD_H */
#include <sys/stat.h>
#include <sys/types.h>
#define __USE_BSD 1
#include <string.h>
#include "bbsmount_base.hh"
#include "bbsmount.hh"
File::File(const char * file_name, const char * images_prefix) {
path = NULL;
const_cast<char *>(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<Action> &
MountPoint::GetActions() const
{
return actions;
}
unsigned int
MountPoint::GetCommand(const unsigned int button, const unsigned int state) const
{
set<Action>::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);
}
syntax highlighted by Code2HTML, v. 0.9.1