diff options
author | Constantin Kaplinsky <const@tightvnc.com> | 2006-05-25 05:36:48 +0000 |
---|---|---|
committer | Constantin Kaplinsky <const@tightvnc.com> | 2006-05-25 05:36:48 +0000 |
commit | d1e4e901e29d8ef27a6583648c7148b1a5b2facf (patch) | |
tree | fb34ead4006e43ac22aa6368c6a622320f234261 /tx | |
parent | 729598cb00d791bbdfe23ebe0023d3a1c3962f83 (diff) | |
download | tigervnc-d1e4e901e29d8ef27a6583648c7148b1a5b2facf.tar.gz tigervnc-d1e4e901e29d8ef27a6583648c7148b1a5b2facf.zip |
Migrating to new directory structure adopted from the RealVNC's source tree. Windows part should be complete. For the Unix part, more changes will follow.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@592 3789f03b-4d11-0410-bbf8-ca57d06f2519
Diffstat (limited to 'tx')
-rw-r--r-- | tx/Makefile.in | 17 | ||||
-rw-r--r-- | tx/TXButton.h | 124 | ||||
-rw-r--r-- | tx/TXCheckbox.h | 142 | ||||
-rw-r--r-- | tx/TXDialog.h | 101 | ||||
-rw-r--r-- | tx/TXEntry.h | 191 | ||||
-rw-r--r-- | tx/TXImage.cxx | 353 | ||||
-rw-r--r-- | tx/TXImage.h | 97 | ||||
-rw-r--r-- | tx/TXLabel.h | 126 | ||||
-rw-r--r-- | tx/TXMenu.cxx | 186 | ||||
-rw-r--r-- | tx/TXMenu.h | 67 | ||||
-rw-r--r-- | tx/TXMsgBox.h | 112 | ||||
-rw-r--r-- | tx/TXScrollbar.cxx | 119 | ||||
-rw-r--r-- | tx/TXScrollbar.h | 82 | ||||
-rw-r--r-- | tx/TXViewport.cxx | 155 | ||||
-rw-r--r-- | tx/TXViewport.h | 77 | ||||
-rw-r--r-- | tx/TXWindow.cxx | 486 | ||||
-rw-r--r-- | tx/TXWindow.h | 211 |
17 files changed, 0 insertions, 2646 deletions
diff --git a/tx/Makefile.in b/tx/Makefile.in deleted file mode 100644 index 89c30b17..00000000 --- a/tx/Makefile.in +++ /dev/null @@ -1,17 +0,0 @@ - -SRCS = TXWindow.cxx TXScrollbar.cxx TXViewport.cxx TXImage.cxx TXMenu.cxx - -OBJS = $(SRCS:.cxx=.o) - -DIR_CPPFLAGS = -I$(top_srcdir) @X_CFLAGS@ # X_CFLAGS are really CPPFLAGS - -library = libtx.a - -all:: $(library) - -$(library): $(OBJS) - rm -f $(library) - $(AR) $(library) $(OBJS) - $(RANLIB) $(library) - -# followed by boilerplate.mk diff --git a/tx/TXButton.h b/tx/TXButton.h deleted file mode 100644 index b7472797..00000000 --- a/tx/TXButton.h +++ /dev/null @@ -1,124 +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. - */ -// -// TXButton.h -// -// A TXButton is a clickable button with some text in it. The button must be -// big enough to contain the text - if not then it will be resized -// appropriately. -// - -#ifndef __TXBUTTON_H__ -#define __TXBUTTON_H__ - -#include "TXWindow.h" -#include <rfb/util.h> - -// TXButtonCallback's buttonActivate() method is called when a button is -// activated. -class TXButton; -class TXButtonCallback { -public: - virtual void buttonActivate(TXButton* button)=0; -}; - - -class TXButton : public TXWindow, public TXEventHandler { -public: - - TXButton(Display* dpy_, const char* text_, TXButtonCallback* cb_=0, - TXWindow* parent_=0, int w=1, int h=1) - : TXWindow(dpy_, w, h, parent_), cb(cb_), down(false), - disabled_(false) - { - setEventHandler(this); - setText(text_); - gc = XCreateGC(dpy, win(), 0, 0); - XSetFont(dpy, gc, defaultFont); - addEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask); - } - - virtual ~TXButton() { - XFreeGC(dpy, gc); - } - - // setText() changes the text in the button. - void setText(const char* text_) { - text.buf = rfb::strDup(text_); - int textWidth = XTextWidth(defaultFS, text.buf, strlen(text.buf)); - int textHeight = (defaultFS->ascent + defaultFS->descent); - int newWidth = __rfbmax(width(), textWidth + xPad*2 + bevel*2); - int newHeight = __rfbmax(height(), textHeight + yPad*2 + bevel*2); - if (width() < newWidth || height() < newHeight) { - resize(newWidth, newHeight); - } - } - - // disabled() sets or queries the disabled state of the checkbox. A disabled - // checkbox cannot be changed via the user interface. - void disabled(bool b) { disabled_ = b; paint(); } - bool disabled() { return disabled_; } - -private: - - void paint() { - int tw = XTextWidth(defaultFS, text.buf, strlen(text.buf)); - int startx = (width() - tw) / 2; - int starty = (height() + defaultFS->ascent - defaultFS->descent) / 2; - if (down || disabled_) { - drawBevel(gc, 0, 0, width(), height(), bevel, defaultBg, darkBg,lightBg); - startx++; starty++; - } else { - drawBevel(gc, 0, 0, width(), height(), bevel, defaultBg, lightBg,darkBg); - } - - XSetForeground(dpy, gc, disabled_ ? disabledFg : defaultFg); - XDrawString(dpy, win(), gc, startx, starty, text.buf, strlen(text.buf)); - } - - virtual void handleEvent(TXWindow* w, XEvent* ev) { - switch (ev->type) { - case Expose: - paint(); - break; - case ButtonPress: - if (!disabled_) { - down = true; - paint(); - } - break; - case ButtonRelease: - if (!down) break; - down = false; - paint(); - if (ev->xbutton.x >= 0 && ev->xbutton.x < width() && - ev->xbutton.y >= 0 && ev->xbutton.y < height()) { - if (cb) cb->buttonActivate(this); - } - break; - } - } - - GC gc; - rfb::CharArray text; - TXButtonCallback* cb; - bool down; - bool disabled_; -}; - -#endif diff --git a/tx/TXCheckbox.h b/tx/TXCheckbox.h deleted file mode 100644 index 0880b38c..00000000 --- a/tx/TXCheckbox.h +++ /dev/null @@ -1,142 +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. - */ -// -// TXCheckbox.h -// -// A TXCheckbox has a box which may be "checked" with some text next to it. -// The checkbox window must be big enough to contain the text - if not then it -// will be resized appropriately. -// -// There are two styles of checkbox: the normal style which uses a tick in a -// square box, and the radio style which uses a dot inside a circle. The -// default behaviour when clicking on the checkbox is to toggle it on or off, -// but this behaviour can be changed by the callback object. In particular to -// get radiobutton behaviour, the callback must ensure that only one of a set -// of radiobuttons is selected. -// - -#ifndef __TXCHECKBOX_H__ -#define __TXCHECKBOX_H__ - -#include "TXWindow.h" -#include <rfb/util.h> - -// TXCheckboxCallback's checkboxSelect() method is called when the state of a -// checkbox changes. -class TXCheckbox; -class TXCheckboxCallback { -public: - virtual void checkboxSelect(TXCheckbox* checkbox)=0; -}; - - -class TXCheckbox : public TXWindow, public TXEventHandler { -public: - TXCheckbox(Display* dpy_, const char* text_, TXCheckboxCallback* cb_, - bool radio_=false, TXWindow* parent_=0, int w=1, int h=1) - : TXWindow(dpy_, w, h, parent_), cb(cb_), text(0), - boxSize(radio_ ? 12 : 13), boxPad(4), - checked_(false), disabled_(false), radio(radio_) - { - setEventHandler(this); - setText(text_); - gc = XCreateGC(dpy, win(), 0, 0); - XSetFont(dpy, gc, defaultFont); - addEventMask(ExposureMask| ButtonPressMask | ButtonReleaseMask); - } - - virtual ~TXCheckbox() { - XFreeGC(dpy, gc); - if (text) free(text); - } - - // setText() changes the text in the checkbox. - void setText(const char* text_) { - if (text) free(text); - text = strdup((char*)text_); - int textWidth = XTextWidth(defaultFS, text, strlen(text)); - int textHeight = (defaultFS->ascent + defaultFS->descent); - int newWidth = __rfbmax(width(), textWidth + xPad*2 + boxPad*2 + boxSize); - int newHeight = __rfbmax(height(), textHeight + yPad*2); - if (width() < newWidth || height() < newHeight) { - resize(newWidth, newHeight); - } - } - - // checked() sets or queries the state of the checkbox - void checked(bool b) { checked_ = b; paint(); } - bool checked() { return checked_; } - - // disabled() sets or queries the disabled state of the checkbox. A disabled - // checkbox cannot be changed via the user interface. - void disabled(bool b) { disabled_ = b; paint(); } - bool disabled() { return disabled_; } - -private: - void paint() { - if (disabled_) - drawBevel(gc, xPad + boxPad, (height() - boxSize) / 2, boxSize, boxSize, - bevel, disabledBg, darkBg, lightBg, radio); - else - drawBevel(gc, xPad + boxPad, (height() - boxSize) / 2, boxSize, boxSize, - bevel, enabledBg, darkBg, lightBg, radio); - XSetBackground(dpy, gc, disabled_ ? disabledBg : enabledBg); - XSetForeground(dpy, gc, disabled_ ? disabledFg : defaultFg); - if (checked_) { - Pixmap icon = radio ? dot : tick; - int iconSize = radio ? dotSize : tickSize; - XCopyPlane(dpy, icon, win(), gc, 0, 0, iconSize, iconSize, - xPad + boxPad + (boxSize - iconSize) / 2, - (height() - iconSize) / 2, 1); - } - XDrawString(dpy, win(), gc, xPad + boxSize + boxPad*2, - (height() + defaultFS->ascent - defaultFS->descent) / 2, - text, strlen(text)); - } - - virtual void handleEvent(TXWindow* w, XEvent* ev) { - switch (ev->type) { - case Expose: - paint(); - break; - case ButtonPress: - break; - case ButtonRelease: - if (ev->xbutton.x >= 0 && ev->xbutton.x < width() && - ev->xbutton.y >= 0 && ev->xbutton.y < height()) { - if (!disabled_) { - checked_ = !checked_; - if (cb) cb->checkboxSelect(this); - paint(); - } - } - break; - } - } - - TXCheckboxCallback* cb; - GC gc; - char* text; - int boxSize; - int boxPad; - bool checked_; - bool disabled_; - bool radio; -}; - -#endif diff --git a/tx/TXDialog.h b/tx/TXDialog.h deleted file mode 100644 index c8d601c3..00000000 --- a/tx/TXDialog.h +++ /dev/null @@ -1,101 +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. - */ -// -// TXDialog.h -// -// A TXDialog is a pop-up dialog window. The dialog can be made visible by -// calling its show() method. Dialogs can be modal or non-modal. For a modal -// dialog box, the show() method only returns when the dialog box has been -// dismissed. For a non-modal dialog box, the show() method returns -// immediately. -// - -#ifndef __TXDIALOG_H__ -#define __TXDIALOG_H__ - -#include "TXWindow.h" -#include <errno.h> - -// XXX Lynx/OS 2.3: protos for bzero(), select() -#ifdef Lynx -#include <sys/proto.h> -#endif - -class TXDialog : public TXWindow, public TXDeleteWindowCallback { -public: - TXDialog(Display* dpy, int width, int height, const char* name, - bool modal_=false) - : TXWindow(dpy, width, height), done(false), ok(false), modal(modal_) - { - toplevel(name, this); - resize(width, height); - } - - virtual ~TXDialog() {} - - // show() makes the dialog visible. For a modal dialog box, this processes X - // events until the done flag has been set, after which it returns the value - // of the ok flag. For a non-modal dialog box it always returns true - // immediately. - bool show() { - ok = false; - done = false; - initDialog(); - raise(); - map(); - if (modal) { - while (true) { - TXWindow::handleXEvents(dpy); - if (done) { - return ok; - } - fd_set rfds; - FD_ZERO(&rfds); - FD_SET(ConnectionNumber(dpy), &rfds); - int n = select(FD_SETSIZE, &rfds, 0, 0, 0); - if (n < 0) throw rdr::SystemException("select",errno); - } - } - return true; - } - - // initDialog() can be overridden in a derived class. Typically it is used - // to make sure that checkboxes have the right state, etc. - virtual void initDialog() {} - - // resize() is overidden here to re-center the dialog - void resize(int w, int h) { - TXWindow::resize(w,h); - int dpyWidth = WidthOfScreen(DefaultScreenOfDisplay(dpy)); - int dpyHeight = HeightOfScreen(DefaultScreenOfDisplay(dpy)); - setUSPosition((dpyWidth - width() - 10) / 2, (dpyHeight - height() - 30) / 2); - } - -protected: - virtual void deleteWindow(TXWindow* w) { - ok = false; - done = true; - unmap(); - } - - bool done; - bool ok; - bool modal; -}; - -#endif diff --git a/tx/TXEntry.h b/tx/TXEntry.h deleted file mode 100644 index 1785a5f5..00000000 --- a/tx/TXEntry.h +++ /dev/null @@ -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 diff --git a/tx/TXImage.cxx b/tx/TXImage.cxx deleted file mode 100644 index 5fa68288..00000000 --- a/tx/TXImage.cxx +++ /dev/null @@ -1,353 +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 <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() -{ - tig->setColourMapEntries(0, 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) -{ - cube = 0; - nativePF.depth = depth; - nativePF.bpp = depth2bpp(dpy, depth); - nativePF.bigEndian = (ImageByteOrder(dpy) == MSBFirst); - nativePF.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); - - if (nativePF.trueColour) { - - nativePF.redShift = ffs(vis->red_mask) - 1; - nativePF.greenShift = ffs(vis->green_mask) - 1; - nativePF.blueShift = ffs(vis->blue_mask) - 1; - nativePF.redMax = vis->red_mask >> nativePF.redShift; - nativePF.greenMax = vis->green_mask >> nativePF.greenShift; - nativePF.blueMax = vis->blue_mask >> nativePF.blueShift; - - } else { - - 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); - } - } - } - } -} diff --git a/tx/TXImage.h b/tx/TXImage.h deleted file mode 100644 index 055bd22d..00000000 --- a/tx/TXImage.h +++ /dev/null @@ -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 diff --git a/tx/TXLabel.h b/tx/TXLabel.h deleted file mode 100644 index 3d5200d6..00000000 --- a/tx/TXLabel.h +++ /dev/null @@ -1,126 +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. - */ -// -// TXLabel.h -// -// An TXLabel allows you to put up multiline text in a window with various -// alignments. The label must be big enough to contain the text - if not then -// it will be resized appropriately. -// - -#ifndef __TXLABEL_H__ -#define __TXLABEL_H__ - -#include <stdlib.h> -#include "TXWindow.h" -#include <rfb/util.h> - -class TXLabel : public TXWindow, public TXEventHandler { -public: - enum HAlign { left, centre, right }; - enum VAlign { top, middle, bottom }; - - TXLabel(Display* dpy_, const char* text_, TXWindow* parent_=0, - int w=1, int h=1, HAlign ha=centre, VAlign va=middle) - : TXWindow(dpy_, w, h, parent_), lineSpacing(2), lines(0), - halign(ha), valign(va) - { - setEventHandler(this); - setText(text_); - addEventMask(ExposureMask); - } - - // setText() changes the text in the label. - void setText(const char* text_) { - text.buf = rfb::strDup(text_); - lines = 0; - int lineStart = 0; - int textWidth = 0; - int i = -1; - do { - i++; - if (text.buf[i] == '\n' || text.buf[i] == 0) { - int tw = XTextWidth(defaultFS, &text.buf[lineStart], i-lineStart); - if (tw > textWidth) textWidth = tw; - lineStart = i+1; - lines++; - } - } while (text.buf[i] != 0); - int textHeight = ((defaultFS->ascent + defaultFS->descent + lineSpacing) - * lines); - int newWidth = __rfbmax(width(), textWidth + xPad*2); - int newHeight = __rfbmax(height(), textHeight + yPad*2); - if (width() < newWidth || height() < newHeight) { - resize(newWidth, newHeight); - } - invalidate(); - } - -private: - int xOffset(int textWidth) { - switch (halign) { - case left: return xPad; - case right: return width() - xPad - textWidth; - default: return (width() - textWidth) / 2; - } - } - - int yOffset(int lineNum) { - int textHeight = ((defaultFS->ascent + defaultFS->descent + lineSpacing) - * lines); - int lineOffset = ((defaultFS->ascent + defaultFS->descent + lineSpacing) - * lineNum + defaultFS->ascent); - switch (valign) { - case top: return yPad + lineOffset; - case bottom: return height() - yPad - textHeight + lineOffset; - default: return (height() - textHeight) / 2 + lineOffset; - } - } - - void paint() { - int lineNum = 0; - int lineStart = 0; - int i = -1; - do { - i++; - if (text.buf[i] == '\n' || text.buf[i] == 0) { - int tw = XTextWidth(defaultFS, &text.buf[lineStart], i-lineStart); - XDrawString(dpy, win(), defaultGC, xOffset(tw), yOffset(lineNum), - &text.buf[lineStart], i-lineStart); - lineStart = i+1; - lineNum++; - } - } while (text.buf[i] != 0); - } - - virtual void handleEvent(TXWindow* w, XEvent* ev) { - switch (ev->type) { - case Expose: - paint(); - break; - } - } - - int lineSpacing; - rfb::CharArray text; - int lines; - HAlign halign; - VAlign valign; -}; - -#endif diff --git a/tx/TXMenu.cxx b/tx/TXMenu.cxx deleted file mode 100644 index 92712f55..00000000 --- a/tx/TXMenu.cxx +++ /dev/null @@ -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; - } -} diff --git a/tx/TXMenu.h b/tx/TXMenu.h deleted file mode 100644 index d0245ee9..00000000 --- a/tx/TXMenu.h +++ /dev/null @@ -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 diff --git a/tx/TXMsgBox.h b/tx/TXMsgBox.h deleted file mode 100644 index ff84e6ae..00000000 --- a/tx/TXMsgBox.h +++ /dev/null @@ -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 diff --git a/tx/TXScrollbar.cxx b/tx/TXScrollbar.cxx deleted file mode 100644 index 47e124c3..00000000 --- a/tx/TXScrollbar.cxx +++ /dev/null @@ -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; - } -} diff --git a/tx/TXScrollbar.h b/tx/TXScrollbar.h deleted file mode 100644 index 87fec3d8..00000000 --- a/tx/TXScrollbar.h +++ /dev/null @@ -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 diff --git a/tx/TXViewport.cxx b/tx/TXViewport.cxx deleted file mode 100644 index abe51734..00000000 --- a/tx/TXViewport.cxx +++ /dev/null @@ -1,155 +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), needScrollbars(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() -{ - needScrollbars = (!bumpScroll && - (width() < child->width() || height() < child->height()) && - (width() > scrollbarSize && height() > scrollbarSize)); - if (needScrollbars) { - clipper->resize(width()-scrollbarSize, height()-scrollbarSize); - hScrollbar->map(); - vScrollbar->map(); - } else { - clipper->resize(width(), height()); - hScrollbar->unmap(); - vScrollbar->unmap(); - } - - setOffset(xOff, yOff); - - if (needScrollbars) { - hScrollbar->move(0, height()-scrollbarSize); - hScrollbar->resize(width()-scrollbarSize, scrollbarSize); - hScrollbar->set(child->width(), -xOff, width()-scrollbarSize); - 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); -} diff --git a/tx/TXViewport.h b/tx/TXViewport.h deleted file mode 100644 index 0c9857d2..00000000 --- a/tx/TXViewport.h +++ /dev/null @@ -1,77 +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 needScrollbars; - int bumpScrollX, bumpScrollY; -}; -#endif diff --git a/tx/TXWindow.cxx b/tx/TXWindow.cxx deleted file mode 100644 index 6d211beb..00000000 --- a/tx/TXWindow.cxx +++ /dev/null @@ -1,486 +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. - */ -// -// TXWindow.cxx -// - -#include <X11/Xatom.h> -#include "TXWindow.h" -#include <list> -#include <stdio.h> -#include <stdlib.h> -#include <rfb/util.h> - -std::list<TXWindow*> windows; - -Atom wmProtocols, wmDeleteWindow, wmTakeFocus; -Atom xaTIMESTAMP, xaTARGETS, xaSELECTION_TIME, xaSELECTION_STRING; -Atom xaCLIPBOARD; -unsigned long TXWindow::black, TXWindow::white; -unsigned long TXWindow::defaultFg, TXWindow::defaultBg; -unsigned long TXWindow::lightBg, TXWindow::darkBg; -unsigned long TXWindow::disabledFg, TXWindow::disabledBg; -unsigned long TXWindow::enabledBg; -unsigned long TXWindow::scrollbarBg; -Colormap TXWindow::cmap = 0; -GC TXWindow::defaultGC = 0; -Font TXWindow::defaultFont = 0; -XFontStruct* TXWindow::defaultFS = 0; -Time TXWindow::cutBufferTime = 0; -Pixmap TXWindow::dot = 0, TXWindow::tick = 0; -const int TXWindow::dotSize = 4, TXWindow::tickSize = 8; -char* TXWindow::defaultWindowClass; - -void TXWindow::init(Display* dpy, const char* defaultWindowClass_) -{ - cmap = DefaultColormap(dpy,DefaultScreen(dpy)); - wmProtocols = XInternAtom(dpy, "WM_PROTOCOLS", False); - wmDeleteWindow = XInternAtom(dpy, "WM_DELETE_WINDOW", False); - wmTakeFocus = XInternAtom(dpy, "WM_TAKE_FOCUS", False); - xaTIMESTAMP = XInternAtom(dpy, "TIMESTAMP", False); - xaTARGETS = XInternAtom(dpy, "TARGETS", False); - xaSELECTION_TIME = XInternAtom(dpy, "SELECTION_TIME", False); - xaSELECTION_STRING = XInternAtom(dpy, "SELECTION_STRING", False); - xaCLIPBOARD = XInternAtom(dpy, "CLIPBOARD", False); - XColor cols[6]; - cols[0].red = cols[0].green = cols[0].blue = 0x0000; - cols[1].red = cols[1].green = cols[1].blue = 0xbbbb; - cols[2].red = cols[2].green = cols[2].blue = 0xeeee; - cols[3].red = cols[3].green = cols[3].blue = 0x5555; - cols[4].red = cols[4].green = cols[4].blue = 0x8888; - cols[5].red = cols[5].green = cols[5].blue = 0xffff; - getColours(dpy, cols, 6); - black = defaultFg = cols[0].pixel; - defaultBg = disabledBg = cols[1].pixel; - lightBg = cols[2].pixel; - darkBg = disabledFg = cols[3].pixel; - scrollbarBg = cols[4].pixel; - white = enabledBg = cols[5].pixel; - defaultGC = XCreateGC(dpy, DefaultRootWindow(dpy), 0, 0); - defaultFS - = XLoadQueryFont(dpy, "-*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*"); - if (!defaultFS) { - defaultFS = XLoadQueryFont(dpy, "fixed"); - if (!defaultFS) { - fprintf(stderr,"Failed to load any font\n"); - exit(1); - } - } - defaultFont = defaultFS->fid; - XSetForeground(dpy, defaultGC, defaultFg); - XSetBackground(dpy, defaultGC, defaultBg); - XSetFont(dpy, defaultGC, defaultFont); - XSelectInput(dpy, DefaultRootWindow(dpy), PropertyChangeMask); - - static char dotBits[] = { 0x06, 0x0f, 0x0f, 0x06}; - dot = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), dotBits, - dotSize, dotSize); - static char tickBits[] = { 0x80, 0xc0, 0xe2, 0x76, 0x3e, 0x1c, 0x08, 0x00}; - tick = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), tickBits, - tickSize, tickSize); - defaultWindowClass = rfb::strDup(defaultWindowClass_); -} - -void TXWindow::handleXEvents(Display* dpy) -{ - while (XPending(dpy)) { - XEvent ev; - XNextEvent(dpy, &ev); - if (ev.type == MappingNotify) { - XRefreshKeyboardMapping(&ev.xmapping); - } else if (ev.type == PropertyNotify && - ev.xproperty.window == DefaultRootWindow(dpy) && - ev.xproperty.atom == XA_CUT_BUFFER0) { - cutBufferTime = ev.xproperty.time; - } else { - std::list<TXWindow*>::iterator i; - for (i = windows.begin(); i != windows.end(); i++) { - if ((*i)->win() == ev.xany.window) - (*i)->handleXEvent(&ev); - } - } - } -} - -void TXWindow::getColours(Display* dpy, XColor* cols, int nCols) -{ - bool* got = new bool[nCols]; - bool failed = false; - int i; - for (i = 0; i < nCols; i++) { - if (XAllocColor(dpy, cmap, &cols[i])) { - got[i] = true; - } else { - got[i] = false; - failed = true; - } - } - - if (!failed) { - delete [] got; - return; - } - - // AllocColor has failed. This is because the colormap is full. So the - // only thing we can do is use the "shared" pixels in the colormap. The - // code below is designed to work even when the colormap isn't full so is - // more complex than it needs to be in this case. However it would be - // useful one day to be able to restrict the number of colours allocated by - // an application so I'm leaving it in here. - - // For each pixel in the colormap, try to allocate exactly its RGB values. - // If this returns a different pixel then it must be a private or - // unallocated pixel, so we can't use it. If it returns us the same pixel - // again, it's almost certainly a shared colour, so we can use it (actually - // it is possible that it was an unallocated pixel which we've now - // allocated - by going through the pixels in reverse order we make this - // unlikely except for the lowest unallocated pixel - this works because of - // the way the X server allocates new pixels). - - int cmapSize = DisplayCells(dpy,DefaultScreen(dpy)); - - XColor* cm = new XColor[cmapSize]; - bool* shared = new bool[cmapSize]; - bool* usedAsNearest = new bool[cmapSize]; - - for (i = 0; i < cmapSize; i++) { - cm[i].pixel = i; - shared[i] = usedAsNearest[i] = false; - } - - XQueryColors(dpy, cmap, cm, cmapSize); - - for (i = cmapSize-1; i >= 0; i--) { - if (XAllocColor(dpy, cmap, &cm[i])) { - if (cm[i].pixel == (unsigned long)i) { - shared[i] = true; - } else { - XFreeColors(dpy, cmap, &cm[i].pixel, 1, 0); - } - } - } - - for (int j = 0; j < nCols; j++) { - unsigned long minDistance = ULONG_MAX; - unsigned long nearestPixel = 0; - if (!got[j]) { - for (i = 0; i < cmapSize; i++) { - if (shared[i]) { - unsigned long rd = (cm[i].red - cols[j].red)/2; - unsigned long gd = (cm[i].green - cols[j].green)/2; - unsigned long bd = (cm[i].blue - cols[j].blue)/2; - unsigned long distance = (rd*rd + gd*gd + bd*bd); - - if (distance < minDistance) { - minDistance = distance; - nearestPixel = i; - } - } - } - - cols[j].pixel = nearestPixel; - usedAsNearest[nearestPixel] = true; - } - } - - for (i = 0; i < cmapSize; i++) { - if (shared[i] && !usedAsNearest[i]) { - unsigned long p = i; - XFreeColors(dpy, cmap, &p, 1, 0); - } - } -} - -Window TXWindow::windowWithName(Display* dpy, Window top, const char* name) -{ - char* windowName; - if (XFetchName(dpy, top, &windowName)) { - if (strcmp(windowName, name) == 0) { - XFree(windowName); - return top; - } - XFree(windowName); - } - - Window* children; - Window dummy; - unsigned int nchildren; - if (!XQueryTree(dpy, top, &dummy, &dummy, &children,&nchildren) || !children) - return 0; - - for (int i = 0; i < (int)nchildren; i++) { - Window w = windowWithName(dpy, children[i], name); - if (w) { - XFree((char*)children); - return w; - } - } - XFree((char*)children); - return 0; -} - - -TXWindow::TXWindow(Display* dpy_, int w, int h, TXWindow* parent_, - int borderWidth) - : dpy(dpy_), xPad(3), yPad(3), bevel(2), parent(parent_), width_(w), - height_(h), eventHandler(0), dwc(0), eventMask(0), toplevel_(false) -{ - sizeHints.flags = 0; - XSetWindowAttributes attr; - attr.background_pixel = defaultBg; - attr.border_pixel = 0; - Window par = parent ? parent->win() : DefaultRootWindow(dpy); - win_ = XCreateWindow(dpy, par, 0, 0, width_, height_, borderWidth, - CopyFromParent, CopyFromParent, CopyFromParent, - CWBackPixel | CWBorderPixel, &attr); - if (parent) map(); - - windows.push_back(this); -} - -TXWindow::~TXWindow() -{ - windows.remove(this); - XDestroyWindow(dpy, win()); -} - -void TXWindow::toplevel(const char* name, TXDeleteWindowCallback* dwc_, - int argc, char** argv, const char* windowClass, - bool iconic) -{ - toplevel_ = true; - XWMHints wmHints; - wmHints.flags = InputHint|StateHint; - wmHints.input = True; - wmHints.initial_state = iconic ? IconicState : NormalState; - XClassHint classHint; - if (!windowClass) windowClass = defaultWindowClass; - classHint.res_name = (char*)name; - classHint.res_class = (char*)windowClass; - XSetWMProperties(dpy, win(), 0, 0, argv, argc, - &sizeHints, &wmHints, &classHint); - XStoreName(dpy, win(), name); - XSetIconName(dpy, win(), name); - Atom protocols[10]; - int nProtocols = 0; - protocols[nProtocols++] = wmTakeFocus; - dwc = dwc_; - if (dwc) - protocols[nProtocols++] = wmDeleteWindow; - XSetWMProtocols(dpy, win(), protocols, nProtocols); - addEventMask(StructureNotifyMask); -} - -void TXWindow::setMaxSize(int w, int h) -{ - sizeHints.flags |= PMaxSize; - sizeHints.max_width = w; - sizeHints.max_height = h; - XSetWMNormalHints(dpy, win(), &sizeHints); -} - -void TXWindow::setUSPosition(int x, int y) -{ - sizeHints.flags |= USPosition; - sizeHints.x = x; - sizeHints.y = y; - XSetWMNormalHints(dpy, win(), &sizeHints); - move(x, y); -} - -void TXWindow::setGeometry(const char* geom, int x, int y, int w, int h) -{ - char defGeom[256]; - sprintf(defGeom,"%dx%d+%d+%d",w,h,x,y); - XWMGeometry(dpy, DefaultScreen(dpy), strEmptyToNull((char*)geom), defGeom, - 0, &sizeHints, &x, &y, &w, &h, &sizeHints.win_gravity); - sizeHints.flags |= PWinGravity; - setUSPosition(x, y); - resize(w, h); -} - -TXEventHandler* TXWindow::setEventHandler(TXEventHandler* h) -{ - TXEventHandler* old = eventHandler; - eventHandler = h; - return old; -} - -void TXWindow::addEventMask(long mask) -{ - eventMask |= mask; - XSelectInput(dpy, win(), eventMask); -} - -void TXWindow::removeEventMask(long mask) -{ - eventMask &= ~mask; - XSelectInput(dpy, win(), eventMask); -} - -void TXWindow::unmap() -{ - XUnmapWindow(dpy, win()); - if (toplevel_) { - XUnmapEvent ue; - ue.type = UnmapNotify; - ue.display = dpy; - ue.event = DefaultRootWindow(dpy); - ue.window = win(); - ue.from_configure = False; - XSendEvent(dpy, DefaultRootWindow(dpy), False, - (SubstructureRedirectMask|SubstructureNotifyMask), - (XEvent*)&ue); - } -} - -void TXWindow::resize(int w, int h) -{ - //if (w == width_ && h == height_) return; - XResizeWindow(dpy, win(), w, h); - width_ = w; - height_ = h; - resizeNotify(); -} - -void TXWindow::setBorderWidth(int bw) -{ - XWindowChanges c; - c.border_width = bw; - XConfigureWindow(dpy, win(), CWBorderWidth, &c); -} - -void TXWindow::ownSelection(Atom selection, Time time) -{ - XSetSelectionOwner(dpy, selection, win(), time); - if (XGetSelectionOwner(dpy, selection) == win()) { - selectionOwner_[selection] = true; - selectionOwnTime[selection] = time; - } -} - -void TXWindow::handleXEvent(XEvent* ev) -{ - switch (ev->type) { - - case ClientMessage: - if (ev->xclient.message_type == wmProtocols) { - if ((Atom)ev->xclient.data.l[0] == wmDeleteWindow) { - if (dwc) dwc->deleteWindow(this); - } else if ((Atom)ev->xclient.data.l[0] == wmTakeFocus) { - takeFocus(ev->xclient.data.l[1]); - } - } - break; - - case ConfigureNotify: - if (ev->xconfigure.width != width_ || ev->xconfigure.height != height_) { - width_ = ev->xconfigure.width; - height_ = ev->xconfigure.height; - resizeNotify(); - } - break; - - case SelectionNotify: - if (ev->xselection.property != None) { - Atom type; - int format; - unsigned long nitems, after; - unsigned char *data; - XGetWindowProperty(dpy, win(), ev->xselection.property, 0, 16384, True, - AnyPropertyType, &type, &format, - &nitems, &after, &data); - if (type != None) { - selectionNotify(&ev->xselection, type, format, nitems, data); - XFree(data); - break; - } - } - selectionNotify(&ev->xselection, 0, 0, 0, 0); - break; - - case SelectionRequest: - { - XSelectionEvent se; - se.type = SelectionNotify; - se.display = ev->xselectionrequest.display; - se.requestor = ev->xselectionrequest.requestor; - se.selection = ev->xselectionrequest.selection; - se.time = ev->xselectionrequest.time; - se.target = ev->xselectionrequest.target; - if (ev->xselectionrequest.property == None) - ev->xselectionrequest.property = ev->xselectionrequest.target; - if (!selectionOwner_[se.selection]) { - se.property = None; - } else { - se.property = ev->xselectionrequest.property; - if (se.target == xaTARGETS) { - Atom targets[2]; - targets[0] = xaTIMESTAMP; - targets[1] = XA_STRING; - XChangeProperty(dpy, se.requestor, se.property, XA_ATOM, 32, - PropModeReplace, (unsigned char*)targets, 2); - } else if (se.target == xaTIMESTAMP) { - rdr::U32 t = selectionOwnTime[se.selection]; - XChangeProperty(dpy, se.requestor, se.property, XA_INTEGER, 32, - PropModeReplace, (unsigned char*)&t, 1); - } else if (se.target == XA_STRING) { - if (!selectionRequest(se.requestor, se.selection, se.property)) - se.property = None; - } - } - XSendEvent(dpy, se.requestor, False, 0, (XEvent*)&se); - break; - } - - case SelectionClear: - selectionOwner_[ev->xselectionclear.selection] = false; - break; - } - - if (eventHandler) eventHandler->handleEvent(this, ev); -} - -void TXWindow::drawBevel(GC gc, int x, int y, int w, int h, int b, - unsigned long middle, unsigned long tl, - unsigned long br, bool round) -{ - if (round) { - XGCValues gcv; - gcv.line_width = b; - XChangeGC(dpy, gc, GCLineWidth, &gcv); - XSetForeground(dpy, gc, middle); - XFillArc(dpy, win(), gc, x, y, w-b/2, h-b/2, 0, 360*64); - XSetForeground(dpy, gc, tl); - XDrawArc(dpy, win(), gc, x, y, w-b/2, h-b/2, 45*64, 180*64); - XSetForeground(dpy, gc, br); - XDrawArc(dpy, win(), gc, x, y, w-b/2, h-b/2, 225*64, 180*64); - } else { - XSetForeground(dpy, gc, middle); - if (w-2*b > 0 && h-2*b > 0) - XFillRectangle(dpy, win(), gc, x+b, y+b, w-2*b, h-2*b); - XSetForeground(dpy, gc, tl); - XFillRectangle(dpy, win(), gc, x, y, w, b); - XFillRectangle(dpy, win(), gc, x, y, b, h); - XSetForeground(dpy, gc, br); - for (int i = 0; i < b; i++) { - if (w-i > 0) XFillRectangle(dpy, win(), gc, x+i, y+h-1-i, w-i, 1); - if (h-1-i > 0) XFillRectangle(dpy, win(), gc, x+w-1-i, y+i+1, 1, h-1-i); - } - } -} diff --git a/tx/TXWindow.h b/tx/TXWindow.h deleted file mode 100644 index 5ada181b..00000000 --- a/tx/TXWindow.h +++ /dev/null @@ -1,211 +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. - */ -// -// TXWindow.h -// -// A TXWindow is the base class for all tx windows (widgets). In addition it -// contains a number of static methods and members which are used throughout -// tx. -// -// Before calling any other tx methods, TXWindow::init() must be called with -// the X display to use. - -#ifndef __TXWINDOW_H__ -#define __TXWINDOW_H__ - -#include <rdr/types.h> -#include <X11/X.h> -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <map> - - -// TXDeleteWindowCallback's deleteWindow() method is called when a top-level -// window is "deleted" (closed) by the user using the window manager. -class TXWindow; -class TXDeleteWindowCallback { -public: - virtual void deleteWindow(TXWindow* w) = 0; -}; - -// TXEventHandler is an interface implemented by classes wanting to handle X -// events on a window. Most derived classes of window are their own event -// handlers. -class TXEventHandler { -public: - virtual void handleEvent(TXWindow* w, XEvent* ev) = 0; -}; - -class TXWindow { -public: - - // Constructor - creates a window of the given size, with the default - // background (currently grey). It is mapped by default if it has a parent. - // If no parent is specified its parent is the root window and it will remain - // unmapped. - TXWindow(Display* dpy_, int width=1, int height=1, TXWindow* parent_=0, - int borderWidth=0); - virtual ~TXWindow(); - - // toplevel() declares that this is a top-level window. Various - // window-manager-related properties are set on the window. The given - // TXDeleteWindowCallback is notified when the window is "deleted" (cloesd) - // by the user. - void toplevel(const char* name, TXDeleteWindowCallback* dwc=0, - int argc=0, char** argv=0, const char* windowClass=0, - bool iconic=false); - - // setMaxSize() tells the window manager the maximum size to allow a - // top-level window. It has no effect on a non-top-level window. - void setMaxSize(int w, int h); - - // setUSPosition() tells the window manager the position which the "user" has - // asked for a top-level window. Most window managers ignore requests by a - // program for position, so you have to tell it that the "user" asked for the - // position. This has no effect on a non-top-level window. - void setUSPosition(int x, int y); - - void setGeometry(const char* geom, int x, int y, int w, int h); - - // setTransientFor() tells the window manager that this window is "owned" by - // the given window. The window manager can use this information as it sees - // fit. - void setTransientFor(Window w) { XSetTransientForHint(dpy, win(), w); } - - // setEventHandler() sets the TXEventHandler to handle X events for this - // window. It returns the previous event handler, so that handlers can chain - // themselves. - TXEventHandler* setEventHandler(TXEventHandler* h); - - // Accessor methods - Window win() { return win_; } - int width() { return width_; } - int height() { return height_; } - - // selectionOwner() returns true if this window owns the given selection. - bool selectionOwner(Atom selection) { return selectionOwner_[selection]; } - - // Wrappers around common Xlib calls - void addEventMask(long mask); - void removeEventMask(long mask); - void map() { XMapWindow(dpy, win()); } - void unmap(); - void setBg(unsigned long bg) { XSetWindowBackground(dpy, win(), bg); } - void move(int x, int y) { XMoveWindow(dpy, win(), x, y); } - void resize(int w, int h); - void raise() { XRaiseWindow(dpy, win()); } - void setBorderWidth(int bw); - void invalidate(int x=0, int y=0, int w=0, int h=0) { XClearArea(dpy, win(), x, y, w, h, True); } - - // ownSelection requests that the window owns the given selection from the - // given time (the time should be taken from an X event). - void ownSelection(Atom selection, Time time); - - - // drawBevel draws a rectangular or circular bevel filling the given - // rectangle, using the given colours for the middle, the top/left and the - // bottom/right. - void drawBevel(GC gc, int x, int y, int w, int h, int b, - unsigned long middle, unsigned long tl, unsigned long br, - bool round=false); - - // Methods to be overridden in a derived class - - // resizeNotify() is called whenever the window's dimensions may have - // changed. - virtual void resizeNotify() {} - - // takeFocus() is called when the window has received keyboard focus from the - // window manager. - virtual void takeFocus(Time time) {} - - // selectionNotify() is called when the selection owner has replied to a - // request for information about a selection from the selection owner. - virtual void selectionNotify(XSelectionEvent* ev, Atom type, int format, - int nitems, void* data) {} - - // selectionRequest() is called when this window is the selection owner and - // another X client has requested the selection. It should set the given - // property on the given window to the value of the given selection, - // returning true if successful, false otherwise. - virtual bool selectionRequest(Window requestor, - Atom selection, Atom property) { return false;} - - // Static methods - - // init() must be called before any other tx methods. - static void init(Display* dpy, const char* defaultWindowClass); - - // getColours() sets the pixel values in the cols array to the best available - // for the given rgb values, even in the case of a full colormap. - static void getColours(Display* dpy, XColor* cols, int nCols); - - // handleXEvents() should be called whenever there are events to handle on - // the connection to the X display. It process all available events, then - // returns when there are no more events to process. - static void handleXEvents(Display* dpy); - - // windowWithName() locates a window with a given name on a display. - static Window windowWithName(Display* dpy, Window top, const char* name); - - // strEmptyToNull() returns the string it's given but turns an empty string - // into null, which can be useful for passing rfb parameters to Xlib calls. - static char* strEmptyToNull(char* s) { return s && s[0] ? s : 0; } - - // The following are default values for various things. - static unsigned long black, white; - static unsigned long defaultFg, defaultBg, lightBg, darkBg; - static unsigned long disabledFg, disabledBg, enabledBg; - static unsigned long scrollbarBg; - static GC defaultGC; - static Colormap cmap; - static Font defaultFont; - static XFontStruct* defaultFS; - static Time cutBufferTime; - static Pixmap dot, tick; - static const int dotSize, tickSize; - static char* defaultWindowClass; - - Display* const dpy; - - int xPad, yPad, bevel; - -private: - - // handleXEvent() is called from handleXEvents() when an event for this - // window arrives. It does general event processing before calling on to the - // event handler. - void handleXEvent(XEvent* ev); - - TXWindow* parent; - Window win_; - int width_, height_; - TXEventHandler* eventHandler; - TXDeleteWindowCallback* dwc; - long eventMask; - XSizeHints sizeHints; - std::map<Atom,Time> selectionOwnTime; - std::map<Atom,bool> selectionOwner_; - bool toplevel_; -}; - -extern Atom wmProtocols, wmDeleteWindow, wmTakeFocus; -extern Atom xaTIMESTAMP, xaTARGETS, xaSELECTION_TIME, xaSELECTION_STRING; -extern Atom xaCLIPBOARD; - -#endif |