Browse Source

Remove all unused TX widgets

tags/v1.3.90
Pierre Ossman 10 years ago
parent
commit
53f7857e44
11 changed files with 1 additions and 1487 deletions
  1. 1
    5
      unix/tx/CMakeLists.txt
  2. 0
    191
      unix/tx/TXEntry.h
  3. 0
    361
      unix/tx/TXImage.cxx
  4. 0
    97
      unix/tx/TXImage.h
  5. 0
    186
      unix/tx/TXMenu.cxx
  6. 0
    67
      unix/tx/TXMenu.h
  7. 0
    112
      unix/tx/TXMsgBox.h
  8. 0
    119
      unix/tx/TXScrollbar.cxx
  9. 0
    82
      unix/tx/TXScrollbar.h
  10. 0
    189
      unix/tx/TXViewport.cxx
  11. 0
    78
      unix/tx/TXViewport.h

+ 1
- 5
unix/tx/CMakeLists.txt View File

@@ -4,10 +4,6 @@ include_directories(${CMAKE_SOURCE_DIR}/common)
include_directories(${CMAKE_SOURCE_DIR}/common/rfb)

add_library(tx STATIC
TXWindow.cxx
TXScrollbar.cxx
TXViewport.cxx
TXImage.cxx
TXMenu.cxx)
TXWindow.cxx)

target_link_libraries(tx ${X11_LIBRARIES})

+ 0
- 191
unix/tx/TXEntry.h View File

@@ -1,191 +0,0 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
*
* This 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 software 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 software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
//
// TXEntry.h
//
// A TXEntry allows you to enter a single line of text in a window. The entry
// must be tall enough to contain a line of text - if not then it will be
// resized appropriately. If the passwd argument to the constructor is true,
// then the text in the entry will be replaced by asterisks on the screen.
//

#ifndef __TXENTRY_H__
#define __TXENTRY_H__

#include "TXWindow.h"
#include <X11/keysym.h>

#ifndef XK_ISO_Left_Tab
#define XK_ISO_Left_Tab 0xFE20
#endif
#ifndef XK_KP_Delete
#define XK_KP_Delete 0xFF9F
#endif

// TXEntryCallback's entryCallback() method is called when one of three special
// key presses have happened: Enter/Return, forward tab, or backward tab.
class TXEntry;
class TXEntryCallback {
public:
enum Detail { ENTER, NEXT_FOCUS, PREV_FOCUS };
virtual void entryCallback(TXEntry* entry, Detail detail, Time time)=0;
};


class TXEntry : public TXWindow, public TXEventHandler {
public:

TXEntry(Display* dpy_, TXEntryCallback* cb_=0,
TXWindow* parent_=0, bool passwd_=false, int w=1, int h=1)
: TXWindow(dpy_, w, h, parent_), cb(cb_),
passwd(passwd_), disabled_(false), gotFocus(false)
{
setEventHandler(this);
gc = XCreateGC(dpy, win(), 0, 0);
addEventMask(ExposureMask | KeyPressMask | FocusChangeMask
| ButtonPressMask);
text[0] = 0;
int textHeight = (defaultFS->ascent + defaultFS->descent);
int newHeight = __rfbmax(height(), textHeight + yPad*2 + bevel*2);
if (height() < newHeight) {
resize(width(), newHeight);
}
}

virtual ~TXEntry() {
XFreeGC(dpy, gc);
// overwrite memory used to store password - not critical, but can avoid
// accidental exposure of a password in uninitialised memory.
if (passwd)
memset(text, 0, maxLen);
}

// getText() gets the text in the entry.
const char* getText() { return text; }

// setText() sets the text in the entry.
void setText(const char* text_) {
strncpy(text, text_, maxLen-1);
text[maxLen-1] = 0;
paint();
}

// disabled() sets or queries the disabled state of the entry. A disabled
// entry cannot have text entered into it.
void disabled(bool b) { disabled_ = b; paint(); }
bool disabled() { return disabled_; }

private:
void paint() {
if (disabled_)
drawBevel(gc, 0, 0, width(), height(), bevel, disabledBg,darkBg,lightBg);
else
drawBevel(gc, 0, 0, width(), height(), bevel, enabledBg, darkBg,lightBg);
char* str = text;
char stars[maxLen];
if (passwd) {
int i;
for (i = 0; i < (int)strlen(text); i++) stars[i] = '*';
stars[i] = 0;
str = stars;
}
int tw = XTextWidth(defaultFS, str, strlen(str));
int startx = bevel + xPad;
if (startx + tw > width() - 2*bevel) {
startx = width() - 2*bevel - tw;
}
XDrawString(dpy, win(), defaultGC, startx,
(height() + defaultFS->ascent - defaultFS->descent) / 2,
str, strlen(str));
if (!disabled_ && gotFocus)
XDrawLine(dpy, win(), defaultGC, startx+tw,
(height() - defaultFS->ascent - defaultFS->descent) / 2,
startx+tw,
(height() + defaultFS->ascent + defaultFS->descent) / 2);
}

virtual void handleEvent(TXWindow* w, XEvent* ev) {
switch (ev->type) {
case Expose:
paint();
break;

case FocusIn:
gotFocus = true;
paint();
break;

case FocusOut:
gotFocus = false;
paint();
break;

case ButtonPress:
if (!disabled_)
XSetInputFocus(dpy, win(), RevertToParent, ev->xbutton.time);
break;

case KeyPress:
{
if (disabled_ || !gotFocus) break;
KeySym keysym;
XComposeStatus compose;
char buf[10];
int count = XLookupString(&ev->xkey, buf, 10, &keysym, &compose);
if (count >= 1 && buf[0] >= ' ' && buf[0] <= '~') {
if (strlen(text) + count >= maxLen) {
XBell(dpy, 0);
} else {
strncat(text, buf, count);
paint();
}
} else if (keysym == XK_BackSpace || keysym == XK_Delete ||
keysym == XK_KP_Delete) {
if (strlen(text) > 0) {
text[strlen(text)-1] = 0;
paint();
}
} else if (keysym == XK_Return || keysym == XK_KP_Enter ||
keysym == XK_Linefeed) {
if (cb) cb->entryCallback(this, TXEntryCallback::ENTER,
ev->xkey.time);
} else if ((keysym == XK_Tab || keysym == XK_KP_Tab)
&& !(ev->xkey.state & ShiftMask))
{
if (cb) cb->entryCallback(this, TXEntryCallback::NEXT_FOCUS,
ev->xkey.time);
} else if (((keysym == XK_Tab || keysym == XK_KP_Tab)
&& (ev->xkey.state & ShiftMask))
|| keysym == XK_ISO_Left_Tab)
{
if (cb) cb->entryCallback(this, TXEntryCallback::PREV_FOCUS,
ev->xkey.time);
}
}
}
}
GC gc;
enum { maxLen = 256 };
char text[maxLen];
TXEntryCallback* cb;
bool passwd;
bool disabled_;
bool gotFocus;
};

#endif

+ 0
- 361
unix/tx/TXImage.cxx View File

@@ -1,361 +0,0 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
*
* This 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 software 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 software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
//
// TXImage.cxx
//


#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <list>
#include <rfb/TransImageGetter.h>
#include <rfb/Exception.h>
#include <rfb/LogWriter.h>
#include "TXWindow.h"
#include "TXImage.h"

using namespace rfb;

static rfb::LogWriter vlog("TXImage");

TXImage::TXImage(Display* d, int width, int height, Visual* vis_, int depth_)
: xim(0), dpy(d), vis(vis_), depth(depth_), tig(0), cube(0)
{
#ifdef HAVE_MITSHM
shminfo = 0;
#endif
width_ = width;
height_ = height;
for (int i = 0; i < 256; i++)
colourMap[i].r = colourMap[i].g = colourMap[i].b = 0;

if (!vis)
vis = DefaultVisual(dpy,DefaultScreen(dpy));
if (!depth)
depth = DefaultDepth(dpy,DefaultScreen(dpy));

createXImage();
getNativePixelFormat(vis, depth);
colourmap = this;
format.bpp = 0; // just make it different to any valid format, so that...
setPF(nativePF); // ...setPF() always works
}

TXImage::~TXImage()
{
if (data != (rdr::U8*)xim->data) delete [] data;
destroyXImage();
delete tig;
delete cube;
}

void TXImage::resize(int w, int h)
{
if (w == width() && h == height()) return;

int oldStrideBytes = getStride() * (format.bpp/8);
int rowsToCopy = __rfbmin(h, height());
int bytesPerRow = __rfbmin(w, width()) * (format.bpp/8);
rdr::U8* oldData = 0;
bool allocData = false;

if (data != (rdr::U8*)xim->data) {
oldData = (rdr::U8*)data;
allocData = true;
} else {
oldData = new rdr::U8[xim->bytes_per_line * height()];
memcpy(oldData, xim->data, xim->bytes_per_line * height());
}

destroyXImage();
width_ = w;
height_ = h;
createXImage();

if (allocData)
data = new rdr::U8[width() * height() * (format.bpp/8)];
else
data = (rdr::U8*)xim->data;

int newStrideBytes = getStride() * (format.bpp/8);
for (int i = 0; i < rowsToCopy; i++)
memcpy((rdr::U8*)data + newStrideBytes * i, oldData + oldStrideBytes * i,
bytesPerRow);
delete [] oldData;
}

void TXImage::setPF(const PixelFormat& newPF)
{
if (newPF.equal(format)) return;
format = newPF;

if (data != (rdr::U8*)xim->data) delete [] data;
delete tig;
tig = 0;

if (format.equal(nativePF) && format.trueColour) {
data = (rdr::U8*)xim->data;
} else {
data = new rdr::U8[width() * height() * (format.bpp/8)];
tig = new TransImageGetter();
tig->init(this, nativePF, 0, cube);
}
}

int TXImage::getStride() const
{
if (data == (rdr::U8*)xim->data)
return xim->bytes_per_line / (xim->bits_per_pixel / 8);
else
return width();
}

void TXImage::put(Window win, GC gc, const rfb::Rect& r)
{
if (r.is_empty()) return;
int x = r.tl.x;
int y = r.tl.y;
int w = r.width();
int h = r.height();
if (data != (rdr::U8*)xim->data) {
rdr::U8* ximDataStart = ((rdr::U8*)xim->data + y * xim->bytes_per_line
+ x * (xim->bits_per_pixel / 8));
tig->getImage(ximDataStart, r,
xim->bytes_per_line / (xim->bits_per_pixel / 8));
}
#ifdef HAVE_MITSHM
if (usingShm()) {
XShmPutImage(dpy, win, gc, xim, x, y, x, y, w, h, False);
return;
}
#endif
XPutImage(dpy, win, gc, xim, x, y, x, y, w, h);
}

void TXImage::setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs)
{
for (int i = 0; i < nColours; i++) {
colourMap[firstColour+i].r = rgbs[i*3];
colourMap[firstColour+i].g = rgbs[i*3+1];
colourMap[firstColour+i].b = rgbs[i*3+2];
}
}

void TXImage::updateColourMap()
{
if (tig != 0)
tig->setColourMapEntries(0, 0);
}

void TXImage::lookup(int index, int* r, int* g, int* b)
{
*r = colourMap[index].r;
*g = colourMap[index].g;
*b = colourMap[index].b;
}

#ifdef HAVE_MITSHM
static bool caughtError = false;

static int XShmAttachErrorHandler(Display *dpy, XErrorEvent *error)
{
caughtError = true;
return 0;
}

class TXImageCleanup {
public:
std::list<TXImage*> images;
~TXImageCleanup() {
while (!images.empty())
delete images.front();
}
};

static TXImageCleanup imageCleanup;
#endif

void TXImage::createXImage()
{
#ifdef HAVE_MITSHM
int major, minor;
Bool pixmaps;

if (XShmQueryVersion(dpy, &major, &minor, &pixmaps)) {
shminfo = new XShmSegmentInfo;

xim = XShmCreateImage(dpy, vis, depth, ZPixmap,
0, shminfo, width(), height());

if (xim) {
shminfo->shmid = shmget(IPC_PRIVATE,
xim->bytes_per_line * xim->height,
IPC_CREAT|0777);

if (shminfo->shmid != -1) {
shminfo->shmaddr = xim->data = (char*)shmat(shminfo->shmid, 0, 0);

if (shminfo->shmaddr != (char *)-1) {

shminfo->readOnly = False;

XErrorHandler oldHdlr = XSetErrorHandler(XShmAttachErrorHandler);
XShmAttach(dpy, shminfo);
XSync(dpy, False);
XSetErrorHandler(oldHdlr);

if (!caughtError) {
vlog.debug("Using shared memory XImage");
imageCleanup.images.push_back(this);
return;
}

shmdt(shminfo->shmaddr);
} else {
vlog.error("shmat failed");
perror("shmat");
}

shmctl(shminfo->shmid, IPC_RMID, 0);
} else {
vlog.error("shmget failed");
perror("shmget");
}

XDestroyImage(xim);
xim = 0;
} else {
vlog.error("XShmCreateImage failed");
}

delete shminfo;
shminfo = 0;
}
#endif

xim = XCreateImage(dpy, vis, depth, ZPixmap,
0, 0, width(), height(), BitmapPad(dpy), 0);

xim->data = (char*)malloc(xim->bytes_per_line * xim->height);
if (!xim->data) {
vlog.error("malloc failed");
exit(1);
}
}

void TXImage::destroyXImage()
{
#ifdef HAVE_MITSHM
if (shminfo) {
vlog.debug("Freeing shared memory XImage");
shmdt(shminfo->shmaddr);
shmctl(shminfo->shmid, IPC_RMID, 0);
delete shminfo;
shminfo = 0;
imageCleanup.images.remove(this);
}
#endif
// XDestroyImage() will free(xim->data) if appropriate
if (xim) XDestroyImage(xim);
xim = 0;
}


static bool supportedBPP(int bpp) {
return (bpp == 8 || bpp == 16 || bpp == 32);
}

static int depth2bpp(Display* dpy, int depth)
{
int nformats;
XPixmapFormatValues* format = XListPixmapFormats(dpy, &nformats);

int i;
for (i = 0; i < nformats; i++)
if (format[i].depth == depth) break;

if (i == nformats || !supportedBPP(format[i].bits_per_pixel))
throw rfb::Exception("Error: couldn't find suitable pixmap format");

int bpp = format[i].bits_per_pixel;
XFree(format);
return bpp;
}

void TXImage::getNativePixelFormat(Visual* vis, int depth)
{
int bpp;
int trueColour, bigEndian;
int redShift, greenShift, blueShift;
int redMax, greenMax, blueMax;

cube = 0;

bpp = depth2bpp(dpy, depth);
bigEndian = (ImageByteOrder(dpy) == MSBFirst);
trueColour = (vis->c_class == TrueColor);

vlog.info("Using default colormap and visual, %sdepth %d.",
(vis->c_class == TrueColor) ? "TrueColor, " :
((vis->c_class == PseudoColor) ? "PseudoColor, " : ""),
depth);

redShift = ffs(vis->red_mask) - 1;
greenShift = ffs(vis->green_mask) - 1;
blueShift = ffs(vis->blue_mask) - 1;
redMax = vis->red_mask >> redShift;
greenMax = vis->green_mask >> greenShift;
blueMax = vis->blue_mask >> blueShift;

nativePF = PixelFormat(bpp, depth, bigEndian, trueColour,
redMax, greenMax, blueMax,
redShift, greenShift, blueShift);

if (!trueColour) {
XColor xc[256];
cube = new rfb::ColourCube(6,6,6);
int r;
for (r = 0; r < cube->nRed; r++) {
for (int g = 0; g < cube->nGreen; g++) {
for (int b = 0; b < cube->nBlue; b++) {
int i = (r * cube->nGreen + g) * cube->nBlue + b;
xc[i].red = r * 65535 / (cube->nRed-1);
xc[i].green = g * 65535 / (cube->nGreen-1);
xc[i].blue = b * 65535 / (cube->nBlue-1);
}
}
}

TXWindow::getColours(dpy, xc, cube->size());

for (r = 0; r < cube->nRed; r++) {
for (int g = 0; g < cube->nGreen; g++) {
for (int b = 0; b < cube->nBlue; b++) {
int i = (r * cube->nGreen + g) * cube->nBlue + b;
cube->set(r, g, b, xc[i].pixel);
}
}
}
}
}

+ 0
- 97
unix/tx/TXImage.h View File

@@ -1,97 +0,0 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
*
* This 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 software 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 software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
//
// TXImage.h
//
// A TXImage represents a rectangular off-screen image in any RFB pixel format.
// By default it will use the "native" pixel format for the screen, which will
// be an 8-bit colourmap unless the X display is TrueColor. The pixel format
// can be changed via the setPF() method. The pixel data is accessible via the
// data member inherited from FullFramePixelBuffer, or can be set via the
// fillRect(), imageRect(), copyRect() and maskRect() methods, also inherited
// from PixelBuffer. A rectangle of the image can be drawn into an X Window
// via the put() method. If using a colourmap, the setColourMapEntries() and
// updateColourMap() methods must be called to set up the colourmap as
// appropriate.


#ifndef __TXIMAGE_H__
#define __TXIMAGE_H__

#include <X11/Xlib.h>
#include <rfb/PixelBuffer.h>
#include <rfb/ColourMap.h>
#include <rfb/ColourCube.h>
#ifdef HAVE_MITSHM
#include <X11/extensions/XShm.h>
#endif

namespace rfb { class TransImageGetter; }

class TXImage : public rfb::FullFramePixelBuffer, public rfb::ColourMap {
public:
TXImage(Display* dpy, int width, int height, Visual* vis=0, int depth=0);
~TXImage();

// resize() resizes the image, preserving the image data where possible.
void resize(int w, int h);

// put causes the given rectangle to be drawn onto the given window.
void put(Window win, GC gc, const rfb::Rect& r);

// setColourMapEntries() changes some of the entries in the colourmap.
// However these settings won't take effect until updateColourMap() is
// called. This is because recalculating the internal translation table can
// be expensive.
void setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs);
void updateColourMap();

#ifdef HAVE_MITSHM
bool usingShm() { return shminfo; }
#else
bool usingShm() { return 0; }
#endif

// PixelBuffer methods
// width(), height(), getPF() etc are inherited from PixelBuffer
virtual void setPF(const rfb::PixelFormat& pf);
virtual int getStride() const;

private:

// ColourMap method
virtual void lookup(int index, int* r, int* g, int* b);

void createXImage();
void destroyXImage();
void getNativePixelFormat(Visual* vis, int depth);

XImage* xim;
Display* dpy;
Visual* vis;
int depth;
#ifdef HAVE_MITSHM
XShmSegmentInfo* shminfo;
#endif
rfb::TransImageGetter* tig;
rfb::Colour colourMap[256];
rfb::PixelFormat nativePF;
rfb::ColourCube* cube;
};

#endif

+ 0
- 186
unix/tx/TXMenu.cxx View File

@@ -1,186 +0,0 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
*
* This 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 software 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 software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
//
// TXMenu.cxx
//

#include "TXMenu.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <rfb/util.h>
#include <X11/keysym.h>

TXMenu::TXMenu(Display* dpy_, TXMenuCallback* cb_, int w, int h,
TXWindow* parent_)
: TXWindow(dpy_, w, h, parent_), cb(cb_), nEntries(0),
highlight(-1)
{
setEventHandler(this);
gc = XCreateGC(dpy, win(), 0, 0);
addEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask |
PointerMotionMask | EnterWindowMask | LeaveWindowMask);
}

TXMenu::~TXMenu()
{
XFreeGC(dpy, gc);
for (int i = 0; i < nEntries; i++)
delete [] text[i];
}

inline int TXMenu::entryHeight(int i)
{
if (text[i])
return defaultFS->ascent + defaultFS->descent + bevel*2 + yPad*2;
else
return yPad*2 + 1;
}

void TXMenu::addEntry(const char* text_, long id_)
{
assert(nEntries < maxEntries);
text[nEntries] = rfb::strDup(text_);
checked[nEntries] = false;
id[nEntries++] = id_;
int tw = 0;
if (text_)
tw = XTextWidth(defaultFS, text_, strlen(text_));
int newWidth = width();
if (tw + bevel*2 + xPad*5 + tickSize > width())
newWidth = tw + bevel*2 + xPad*5 + tickSize;
int newHeight = 0;
for (int i = 0; i < nEntries; i++)
newHeight += entryHeight(i);
resize(newWidth, newHeight);
}

void TXMenu::check(long id_, bool checked_)
{
for (int i = 0; i < nEntries; i++) {
if (id[i] == id_) {
checked[i] = checked_;
break;
}
}
}

void TXMenu::paint()
{
int y = 0;
for (int i = 0; i < nEntries; i++) {
if (text[i]) {
if (i == highlight)
drawBevel(gc, 0, y, width(), entryHeight(i), bevel,
defaultBg, darkBg, lightBg);
else
XClearArea(dpy, win(), 0, y, width(), entryHeight(i), false);
if (checked[i])
XCopyPlane(dpy, tick, win(), defaultGC, 0, 0, tickSize, tickSize,
bevel + xPad,
y + bevel + yPad + defaultFS->ascent - tickSize, 1);

XDrawImageString(dpy, win(), defaultGC, bevel + xPad*2 + tickSize,
y + bevel + yPad + defaultFS->ascent,
text[i], strlen(text[i]));
} else {
XDrawLine(dpy, win(), defaultGC, bevel + xPad, y + entryHeight(i) / 2,
width() - bevel - xPad, y + entryHeight(i) / 2);
}
y += entryHeight(i);
}
}

void TXMenu::handleEvent(TXWindow* w, XEvent* ev)
{
switch (ev->type) {
case Expose:
paint();
break;

case ButtonRelease:
{
int y = ev->xmotion.y;
int entryY = 0;
for (int i = 0; i < nEntries; i++) {
if (y >= entryY && y <= entryY + entryHeight(i)) {
if (cb && text[i])
cb->menuSelect(id[i], this);
break;
}
entryY += entryHeight(i);
}
highlight = -1;
paint();
break;
}

case ButtonPress:
case MotionNotify:
{
int y = ev->xmotion.y;
int entryY = 0;
for (int i = 0; i < nEntries; i++) {
if (y >= entryY && y <= entryY + entryHeight(i)) {
if (highlight != i) {
highlight = i;
paint();
}
break;
}
entryY += entryHeight(i);
}
break;
}

case KeyPress:
{
KeySym ks;
char str[256];
XLookupString(&ev->xkey, str, 256, &ks, NULL);
if (ks == XK_Escape) {
highlight = -1;
unmap();
} else if (ks == XK_Down || ks == XK_Up) {
if (nEntries < 1) break;
if (highlight < 0)
highlight = (ks == XK_Down ? nEntries-1 : 0);
int start = highlight;
int inc = (ks == XK_Down ? 1 : nEntries-1);
do {
highlight = (highlight + inc) % nEntries;
} while (highlight != start && !text[highlight]);
paint();
} else if (ks == XK_space || ks == XK_KP_Space ||
ks == XK_Return || ks == XK_KP_Enter) {
if (cb && highlight >= 0 && text[highlight])
cb->menuSelect(id[highlight], this);
highlight = -1;
paint();
}
break;
}

case EnterNotify:
case LeaveNotify:
highlight = -1;
paint();
break;
}
}

+ 0
- 67
unix/tx/TXMenu.h View File

@@ -1,67 +0,0 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
*
* This 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 software 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 software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
//
// TXMenu.h
//
// A TXMenu consists of multiple entries which can be added one at a time.
// Each entry consists of some text, and has an associated integer identifier.
// A callback is made when a menu entry is selected.
//

#ifndef __TXMENU_H__
#define __TXMENU_H__

#include "TXWindow.h"

// TXMenuCallback's menuSelect() method is called when a particular menu entry
// is selected. The id argument identifies the menu entry.
class TXMenu;
class TXMenuCallback {
public:
virtual void menuSelect(long id, TXMenu* menu)=0;
};

class TXMenu : public TXWindow, public TXEventHandler {
public:
TXMenu(Display* dpy_, TXMenuCallback* cb=0, int width=1, int height=1,
TXWindow* parent_=0);
virtual ~TXMenu();

// addEntry() adds an entry to the end of the menu with the given text and
// identifier.
void addEntry(const char* text, long id);

// check() sets whether the given menu entry should have a tick next to it.
void check(long id, bool checked);

private:
int entryHeight(int i);
virtual void handleEvent(TXWindow* w, XEvent* ev);
void paint();

GC gc;
TXMenuCallback* cb;
enum { maxEntries = 64 };
char* text[maxEntries];
long id[maxEntries];
bool checked[maxEntries];
int nEntries;
int highlight;
};

#endif

+ 0
- 112
unix/tx/TXMsgBox.h View File

@@ -1,112 +0,0 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
*
* This 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 software 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 software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
//
// TXMsgBox.h
//
// A TXMsgBox is a specialised pop-up dialog window, designed to present
// the user with a small amount of textual information, and potentially to
// obtain their response.
// TXMsgBoxes are always modal, and may have an Ok button, Ok+Cancel buttons,
// or Yes+No buttons.
// The MsgBox helper function creates a TXMsgBox on the fly, runs it, and
// returns the result.
//

#ifndef __TXMSGBOX_H__
#define __TXMSGBOX_H__

#include "TXDialog.h"
#include "TXLabel.h"
#include "TXButton.h"

enum TXMsgBoxFlags {
MB_OK = 0,
MB_OKCANCEL = 1,
MB_YESNO = 4,
MB_ICONERROR = 0x10,
MB_ICONQUESTION = 0x20,
MB_ICONWARNING = 0x30,
MB_ICONINFORMATION = 0x40,
MB_DEFBUTTON1 = 0,
MB_DEFBUTTON2 = 0x100
};

class TXMsgBox : public TXDialog, public TXButtonCallback {
public:
TXMsgBox(Display* dpy, const char* text, unsigned int flags, const char* title=0)
: TXDialog(dpy, 1, 1, "Message", true),
textLabel(dpy, "", this),
okButton(dpy, "OK", this, this, 60),
cancelButton(dpy, "Cancel", this, this, 60)
{
textLabel.xPad = 8;
textLabel.move(0, yPad*4);
textLabel.setText(text);
resize(textLabel.width(),
textLabel.height() + okButton.height() + yPad*12);

switch (flags & 0x30) {
case MB_ICONERROR:
toplevel("Error", this); break;
case MB_ICONQUESTION:
toplevel("Question", this); break;
case MB_ICONWARNING:
toplevel("Warning", this); break;
case MB_ICONINFORMATION:
toplevel("Information", this); break;
default:
if (title)
toplevel(title, this);
break;
};

switch (flags & 0x7) {
default:
okButton.move((width() - okButton.width()) / 2,
height() - yPad*4 - okButton.height());
cancelButton.unmap();
break;
case MB_OKCANCEL:
case MB_YESNO:
okButton.move(((width()/2) - okButton.width()) / 2,
height() - yPad*4 - okButton.height());
cancelButton.move(((width()*3/2) - cancelButton.width()) / 2,
height() - yPad*4 - cancelButton.height());
if ((flags & 0x7) == MB_YESNO) {
okButton.setText("Yes");
cancelButton.setText("No");
}
break;
};

setBorderWidth(1);
}

virtual void buttonActivate(TXButton* b) {
ok = (b == &okButton);
done = true;
unmap();
}

TXLabel textLabel;
TXButton okButton;
TXButton cancelButton;
};

#endif

+ 0
- 119
unix/tx/TXScrollbar.cxx View File

@@ -1,119 +0,0 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
*
* This 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 software 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 software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
//
// TXScrollbar.cxx
//

#include "TXScrollbar.h"
#include <stdio.h>
#include <assert.h>

TXScrollbar::TXScrollbar(Display* dpy_, int width, int height, bool vert,
TXScrollbarCallback* cb_, TXWindow* parent_)
: TXWindow(dpy_, width, height, parent_), cb(cb_), vertical(vert),
clickedInThumb(false)
{
setEventHandler(this);
gc = XCreateGC(dpy, win(), 0, 0);
addEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask |
ButtonMotionMask);
setBg(scrollbarBg);
limit[0] = len[0] = limit[1] = len[1] = 1;
start[0] = start[1] = 0;
}

TXScrollbar::~TXScrollbar()
{
XFreeGC(dpy, gc);
}

void TXScrollbar::set(int limit_, int start_, int len_, bool vert)
{
assert(limit_ > 0 && len_ >= 0 && len_ <= limit_);

if (start_ < 0) start_ = 0;
if (start_ > limit_ - len_) start_ = limit_ - len_;

if (limit[vert] != limit_ || start[vert] != start_ || len[vert] != len_) {
limit[vert] = limit_;
start[vert] = start_;
len[vert] = len_;
paint();
}
}

void TXScrollbar::paint()
{
int x = scaleToBarX(start[0]);
int y = scaleToBarY(start[1]);
int w = scaleToBarX(len[0]);
int h = scaleToBarY(len[1]);
if (y > 0) XClearArea(dpy, win(), 0, 0, 0, y, false);
if (x > 0) XClearArea(dpy, win(), 0, y, x, y+h, false);
XClearArea(dpy, win(), x+w, y, 0, y+h, false);
XClearArea(dpy, win(), 0, y+h, 0, 0, false);
drawBevel(gc, x, y, w, h, bevel, defaultBg, lightBg, darkBg);
}

void TXScrollbar::handleEvent(TXWindow* w, XEvent* ev)
{
switch (ev->type) {
case Expose:
paint();
break;

case ButtonPress:
{
xDown = ev->xbutton.x;
yDown = ev->xbutton.y;
xStart = start[0];
yStart = start[1];
bool clickedInThumbX = false;
if (xDown < scaleToBarX(start[0])) {
set(limit[0], start[0] - len[0], len[0], false);
} else if (xDown >= scaleToBarX(start[0]+len[0])) {
set(limit[0], start[0] + len[0], len[0], false);
} else {
clickedInThumbX = true;
}
bool clickedInThumbY = false;
if (yDown < scaleToBarY(start[1])) {
set(limit[1], start[1] - len[1], len[1], true);
} else if (yDown >= scaleToBarY(start[1]+len[1])) {
set(limit[1], start[1] + len[1], len[1], true);
} else {
clickedInThumbY = true;
}
clickedInThumb = clickedInThumbX && clickedInThumbY;
if (cb) cb->scrollbarPos(start[0], start[1], this);
}
break;

case ButtonRelease:
case MotionNotify:
while (XCheckTypedWindowEvent(dpy, win(), MotionNotify, ev));
if (clickedInThumb) {
int dx = ev->xmotion.x - xDown;
int dy = ev->xmotion.y - yDown;
set(limit[0], xStart + barToScaleX(dx), len[0], false);
set(limit[1], yStart + barToScaleY(dy), len[1], true);
if (cb) cb->scrollbarPos(start[0], start[1], this);
}
break;
}
}

+ 0
- 82
unix/tx/TXScrollbar.h View File

@@ -1,82 +0,0 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
*
* This 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 software 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 software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
//
// TXScrollbar.h
//
// A TXScrollbar represents a range of values starting at start, of length len,
// between zero and limit. The vertical argument to the constructor says
// whether the scrollbar is horizontal or vertical.
//
// In fact it can represent a range in each dimension but usually one of the
// dimensions is fixed, according to the vertical flag (for a vertical
// scrollbar, the horizontal dimension is fixed, and vice-versa).
//
// The TXScrollbarCallback argument is an object which will be notified when
// the user has attempted to move the scrollbar. The x and y arguments to the
// scrollbarPos() method give the start values in the respective dimensions.
// They are guaranteed to be between 0 and limit-len.
//

#ifndef __TXSCROLLBAR_H__
#define __TXSCROLLBAR_H__

#include "TXWindow.h"

class TXScrollbarCallback;

class TXScrollbar : public TXWindow, public TXEventHandler {
public:
TXScrollbar(Display* dpy_, int width=1, int height=1, bool vertical=false,
TXScrollbarCallback* cb=0, TXWindow* parent_=0);
virtual ~TXScrollbar();

// set() sets the limit, start and length of the range represented by the
// scrollbar. The values of limit and len passed in must be valid
// (i.e. limit > 0 and 0 <= len <= limit). Values of start are clipped to
// the range 0 to limit-len.
void set(int limit, int start, int len) { set(limit, start, len, vertical); }

// set() with an extra argument vert can be used to represent a range in both
// dimensions simultaneously.
void set(int limit, int start, int len, bool vert);

virtual void handleEvent(TXWindow* w, XEvent* ev);

private:
int scaleToBarX(int x) { return (x * width() + limit[0]/2) / limit[0]; }
int scaleToBarY(int y) { return (y * height() + limit[1]/2) / limit[1]; }
int barToScaleX(int x) { return (x * limit[0] + width()/2) / width(); }
int barToScaleY(int y) { return (y * limit[1] + height()/2) / height(); }
void paint();

GC gc;
TXScrollbarCallback* cb;
int limit[2];
int start[2];
int len[2];
int xDown, yDown;
int xStart, yStart;
bool vertical;
bool clickedInThumb;
};

class TXScrollbarCallback {
public:
virtual void scrollbarPos(int x, int y, TXScrollbar* sb)=0;
};
#endif

+ 0
- 189
unix/tx/TXViewport.cxx View File

@@ -1,189 +0,0 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
*
* This 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 software 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 software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
//
// TXViewport.cxx
//

#include "TXViewport.h"
#include <stdio.h>

TXViewport::TXViewport(Display* dpy_, int w, int h, TXWindow* parent_)
: TXWindow(dpy_, w, h, parent_), child(0), hScrollbar(0),
vScrollbar(0), scrollbarSize(15), xOff(0), yOff(0), bumpScrollTimer(this),
bumpScroll(false), needXScrollbar(false), needYScrollbar(false),
bumpScrollX(0), bumpScrollY(0)
{
clipper = new TXWindow(dpy, width()-scrollbarSize, height()-scrollbarSize,
this);
clipper->setBg(black);
hScrollbar = new TXScrollbar(dpy, width()-scrollbarSize, scrollbarSize,
false, this, this);
vScrollbar = new TXScrollbar(dpy, scrollbarSize, height()-scrollbarSize,
true, this, this);
}

TXViewport::~TXViewport()
{
delete clipper;
delete hScrollbar;
delete vScrollbar;
}

void TXViewport::setChild(TXWindow* child_)
{
child = child_;
XReparentWindow(dpy, child->win(), clipper->win(), 0, 0);
xOff = yOff = 0;
child->map();
resizeNotify();
}

bool TXViewport::setOffset(int x, int y)
{
if (clipper->width() >= child->width()) {
x = (clipper->width() - child->width()) / 2;
} else {
if (x > 0) x = 0;
if (x + child->width() < clipper->width())
x = clipper->width() - child->width();
}

if (clipper->height() >= child->height()) {
y = (clipper->height() - child->height()) / 2;
} else {
if (y > 0) y = 0;
if (y + child->height() < clipper->height())
y = clipper->height() - child->height();
}

if (x != xOff || y != yOff) {
xOff = x;
yOff = y;
child->move(xOff, yOff);
return true;
}

return false;
}

void TXViewport::setBumpScroll(bool b)
{
bumpScroll = b;
resizeNotify();
}

// Note: bumpScrollEvent() only works if the viewport is positioned at 0,0 and
// is the same width and height as the screen.
bool TXViewport::bumpScrollEvent(XMotionEvent* ev)
{
if (!bumpScroll) return false;
int bumpScrollPixels = 20;
bumpScrollX = bumpScrollY = 0;

if (ev->x_root == width()-1) bumpScrollX = -bumpScrollPixels;
else if (ev->x_root == 0) bumpScrollX = bumpScrollPixels;
if (ev->y_root == height()-1) bumpScrollY = -bumpScrollPixels;
else if (ev->y_root == 0) bumpScrollY = bumpScrollPixels;

if (bumpScrollX || bumpScrollY) {
if (bumpScrollTimer.isStarted()) return true;
if (setOffset(xOff + bumpScrollX, yOff + bumpScrollY)) {
bumpScrollTimer.start(25);
return true;
}
}

bumpScrollTimer.stop();
return false;
}

bool TXViewport::handleTimeout(rfb::Timer* timer) {
return setOffset(xOff + bumpScrollX, yOff + bumpScrollY);
}

void TXViewport::resizeNotify()
{
int winMaxWidth, winMaxHeight;

winMaxWidth = child->width();
winMaxHeight = child->height();

needXScrollbar = false;
needYScrollbar = false;
if (!bumpScroll && height() > scrollbarSize && width() > scrollbarSize) {
needXScrollbar = (width() < child->width());
needYScrollbar = (height() < child->height());
// Adding an horizontal scrollbar occupies space, which might cause the
// need to add a vertical scrollbar, and vice-versa. These additional
// checks should solve this problem
if (needXScrollbar && (height() - scrollbarSize < child->height()))
needYScrollbar = true;
if (needYScrollbar && (width() - scrollbarSize < child->width()))
needXScrollbar = true;
}

if (needXScrollbar)
winMaxHeight += scrollbarSize;
if (needYScrollbar)
winMaxWidth += scrollbarSize;
setMaxSize(winMaxWidth, winMaxHeight);

if (needXScrollbar && needYScrollbar) {
clipper->resize(width()-scrollbarSize, height()-scrollbarSize);
hScrollbar->map();
vScrollbar->map();
} else if (needXScrollbar) {
clipper->resize(width(), height()-scrollbarSize);
hScrollbar->map();
vScrollbar->unmap();
} else if (needYScrollbar) {
clipper->resize(width()-scrollbarSize, height());
hScrollbar->unmap();
vScrollbar->map();
} else {
clipper->resize(width(), height());
hScrollbar->unmap();
vScrollbar->unmap();
}

setOffset(xOff, yOff);

if (needXScrollbar) {
hScrollbar->move(0, height()-scrollbarSize);
hScrollbar->resize(width()-scrollbarSize, scrollbarSize);
hScrollbar->set(child->width(), -xOff, width()-scrollbarSize);
}

if (needYScrollbar) {
vScrollbar->move(width()-scrollbarSize, 0);
vScrollbar->resize(scrollbarSize, height()-scrollbarSize);
vScrollbar->set(child->height(), -yOff, height()-scrollbarSize);
}
}

void TXViewport::scrollbarPos(int x, int y, TXScrollbar* sb)
{
if (sb == hScrollbar) {
x = -x;
y = yOff;
} else {
x = xOff;
y = -y;
}
setOffset(x, y);
}

+ 0
- 78
unix/tx/TXViewport.h View File

@@ -1,78 +0,0 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
*
* This 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 software 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 software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
//
// TXViewport.h
//
// A TXViewport allows a large window to be viewed by adding scrollbars to the
// right and bottom if necessary. It also has a bump-scroll mode where there
// are no scrollbars, and scrolling is achieved by bumping up against the edge
// of the screen instead. Note that this only works when the viewport fills
// the entire screen. If the child window is smaller than the viewport, it is
// always positioned centrally in the viewport.

#ifndef __TXVIEWPORT_H__
#define __TXVIEWPORT_H__

#include <rfb/Timer.h>
#include "TXWindow.h"
#include "TXScrollbar.h"

class TXViewport : public TXWindow, public TXScrollbarCallback,
public rfb::Timer::Callback {
public:
TXViewport(Display* dpy_, int width, int height, TXWindow* parent_=0);
virtual ~TXViewport();

// setChild() sets the child window which is to be viewed in the viewport.
void setChild(TXWindow* child_);

// setOffset() sets the position of the child in the viewport. Note that the
// offsets are negative. For example when the offset is (-100,-30), position
// (100,30) in the child window is at the top-left of the viewport. The
// offsets given are clipped to keep the child window filling the viewport
// (except where the child window is smaller than the viewport, in which case
// it is always positioned centrally in the viewport). It returns true if
// the child was repositioned.
bool setOffset(int x, int y);

// setBumpScroll() puts the viewport in bump-scroll mode.
void setBumpScroll(bool b);

// bumpScrollEvent() can be called with a MotionNotify event which may
// potentially be against the edge of the screen. It returns true if the
// event was used for bump-scrolling, false if it should be processed
// normally.
bool bumpScrollEvent(XMotionEvent* ev);

private:
virtual void resizeNotify();
virtual void scrollbarPos(int x, int y, TXScrollbar* sb);
virtual bool handleTimeout(rfb::Timer* timer);
TXWindow* clipper;
TXWindow* child;
TXScrollbar* hScrollbar;
TXScrollbar* vScrollbar;
const int scrollbarSize;
int xOff, yOff;
rfb::Timer bumpScrollTimer;
bool bumpScroll;
bool needXScrollbar;
bool needYScrollbar;
int bumpScrollX, bumpScrollY;
};
#endif

Loading…
Cancel
Save