+++ /dev/null
-/* 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.
- */
-
-#include <map>
-
-#define XK_MISCELLANY
-#define XK_LATIN1
-#define XK_CURRENCY
-#include <rfb/keysymdef.h>
-
-#include <rfb_win32/CKeyboard.h>
-#include <rfb/LogWriter.h>
-#include <rfb_win32/OSVersion.h>
-#include "keymap.h"
-
-using namespace rfb;
-
-static LogWriter vlog("CKeyboard");
-
-
-// Client-side RFB keyboard event sythesis
-
-class CKeymapper {
-
-public:
- CKeymapper()
- {
- for (unsigned int i = 0; i < sizeof(keymap) / sizeof(keymap_t); i++) {
- int extendedVkey = keymap[i].vk + (keymap[i].extended ? 256 : 0);
- if (keysymMap.find(extendedVkey) == keysymMap.end()) {
- keysymMap[extendedVkey] = keymap[i].keysym;
- }
- }
- }
-
- // lookup() tries to find a match for vkey with the extended flag. We check
- // first for an exact match including the extended flag, then try without the
- // extended flag.
- rdr::U32 lookup(int extendedVkey) {
-
- // There's no real definition of the meaning of
- // VK_SEPARATOR/XK_KP_Separator or VK_DECIMAL/XK_KP_Decimal. As
- // http://blogs.msdn.com/michkap/archive/2006/09/13/752377.aspx
- // puts it: "As for what is actually assigned to VK_DECIMAL, that
- // is something that for every keyboard is either defined in a
- // standard or decided by the person/people who submitted the
- // keyboard layout. It may match the locale's preferences or it
- // may not". In a VNC context, we are considering a SEPARATOR to
- // be a comma and a DECIMAL to be a dot.
- if (extendedVkey == VK_DECIMAL || extendedVkey == VK_SEPARATOR) {
- char buf[4];
- if (!GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, (LPTSTR) buf,
- sizeof(buf) / sizeof(TCHAR))) {
- vlog.debug("failed to retrieve LOCALE_SDECIMAL");
- } else {
- switch (buf[0]) {
- case ',':
- extendedVkey = VK_SEPARATOR;
- break;
- case '.':
- extendedVkey = VK_DECIMAL;
- break;
- }
- }
- }
-
- if (keysymMap.find(extendedVkey) != keysymMap.end())
- return keysymMap[extendedVkey];
- if (keysymMap.find(extendedVkey ^ 256) != keysymMap.end())
- return keysymMap[extendedVkey ^ 256];
- return 0;
- }
-
-private:
- std::map<int,rdr::U32> keysymMap;
-} ckeymapper;
-
-
-class ModifierKeyReleaser {
-public:
- ModifierKeyReleaser(InputHandler* writer_, int vkCode, bool extended)
- : writer(writer_), extendedVkey(vkCode + (extended ? 256 : 0)),
- keysym(0)
- {}
- void release(std::map<int,rdr::U32>* downKeysym) {
- if (downKeysym->find(extendedVkey) != downKeysym->end()) {
- keysym = (*downKeysym)[extendedVkey];
- vlog.debug("fake release extendedVkey 0x%x, keysym 0x%x",
- extendedVkey, keysym);
- writer->keyEvent(keysym, false);
- }
- }
- ~ModifierKeyReleaser() {
- if (keysym) {
- vlog.debug("fake press extendedVkey 0x%x, keysym 0x%x",
- extendedVkey, keysym);
- writer->keyEvent(keysym, true);
- }
- }
- InputHandler* writer;
- int extendedVkey;
- rdr::U32 keysym;
-};
-
-// IS_PRINTABLE_LATIN1 tests if a character is either a printable latin1
-// character, or 128, which is the Euro symbol on Windows.
-#define IS_PRINTABLE_LATIN1(c) (((c) >= 32 && (c) <= 126) || (c) == 128 || \
- ((c) >= 160 && (c) <= 255))
-
-void win32::CKeyboard::keyEvent(InputHandler* writer, rdr::U8 vkey,
- rdr::U32 flags, bool down)
-{
- bool extended = (flags & 0x1000000);
- int extendedVkey = vkey + (extended ? 256 : 0);
-
- // If it's a release, just release whichever keysym corresponded to the same
- // key being pressed, regardless of how it would be interpreted in the
- // current keyboard state.
- if (!down) {
- releaseKey(writer, extendedVkey);
- return;
- }
-
- // We should always pass every down event to ToAscii() otherwise it can get
- // out of sync.
-
- // XXX should we pass CapsLock, ScrollLock or NumLock to ToAscii - they
- // actually alter the lock state on the keyboard?
-
- BYTE keystate[256];
- GetKeyboardState(keystate);
- rdr::U8 chars[2];
-
- int nchars = ToAscii(vkey, 0, keystate, (WORD*)&chars, 0);
-
- // See if it's in the Windows VK code -> X keysym map. We do this before
- // looking at the result of ToAscii so that e.g. we recognise that it's
- // XK_KP_Add rather than '+'.
-
- rdr::U32 keysym = ckeymapper.lookup(extendedVkey);
- if (keysym) {
- vlog.debug("mapped key: extendedVkey 0x%x", extendedVkey);
- pressKey(writer, extendedVkey, keysym);
- return;
- }
-
- if (nchars < 0) {
- // Dead key - the next call to ToAscii() will give us either the accented
- // character or two characters.
- vlog.debug("ToAscii dead key (1): extendedVkey 0x%x", extendedVkey);
- return;
- }
-
- if (nchars > 0 && IS_PRINTABLE_LATIN1(chars[0])) {
- // Got a printable latin1 character. We must release Control and Alt
- // (AltGr) if they were both pressed, so that the latin1 character is seen
- // without them by the VNC server.
- ModifierKeyReleaser lctrl(writer, VK_CONTROL, 0);
- ModifierKeyReleaser rctrl(writer, VK_CONTROL, 1);
- ModifierKeyReleaser lalt(writer, VK_MENU, 0);
- ModifierKeyReleaser ralt(writer, VK_MENU, 1);
-
- if ((keystate[VK_CONTROL] & 0x80) && (keystate[VK_MENU] & 0x80)) {
- lctrl.release(&downKeysym);
- rctrl.release(&downKeysym);
- lalt.release(&downKeysym);
- ralt.release(&downKeysym);
- }
-
- for (int i = 0; i < nchars; i++) {
- vlog.debug("ToAscii key (1): extendedVkey 0x%x", extendedVkey);
- if (chars[i] == 128) { // special hack for euro!
- pressKey(writer, extendedVkey, XK_EuroSign);
- } else {
- pressKey(writer, extendedVkey, chars[i]);
- }
- }
- return;
- }
-
- // Either no chars were generated, or something outside the printable
- // character range. Try ToAscii() without the Control and Alt keys down to
- // see if that yields an ordinary character.
-
- keystate[VK_CONTROL] = keystate[VK_LCONTROL] = keystate[VK_RCONTROL] = 0;
- keystate[VK_MENU] = keystate[VK_LMENU] = keystate[VK_RMENU] = 0;
-
- nchars = ToAscii(vkey, 0, keystate, (WORD*)&chars, 0);
-
- if (nchars < 0) {
- // So it would be a dead key if neither control nor alt were pressed.
- // However, we know that at least one of control and alt must be pressed.
- // We can't leave it at this stage otherwise the next call to ToAscii()
- // with a valid character will get wrongly interpreted in the context of
- // this bogus dead key. Working on the assumption that a dead key followed
- // by space usually returns the dead character itself, try calling ToAscii
- // with VK_SPACE.
- vlog.debug("ToAscii dead key (2): extendedVkey 0x%x", extendedVkey);
- nchars = ToAscii(VK_SPACE, 0, keystate, (WORD*)&chars, 0);
- if (nchars < 0) {
- vlog.debug("ToAscii dead key (3): extendedVkey 0x%x - giving up!",
- extendedVkey);
- return;
- }
- }
-
- if (nchars > 0 && IS_PRINTABLE_LATIN1(chars[0])) {
- for (int i = 0; i < nchars; i++) {
- vlog.debug("ToAscii key (2) (no ctrl/alt): extendedVkey 0x%x",
- extendedVkey);
- if (chars[i] == 128) { // special hack for euro!
- pressKey(writer, extendedVkey, XK_EuroSign);
- } else {
- pressKey(writer, extendedVkey, chars[i]);
- }
- }
- return;
- }
-
- vlog.debug("no chars regardless of control and alt: extendedVkey 0x%x",
- extendedVkey);
-}
-
-// releaseAllKeys() - write key release events to the server for all keys
-// that are currently regarded as being down.
-void win32::CKeyboard::releaseAllKeys(InputHandler* writer) {
- std::map<int,rdr::U32>::iterator i, next_i;
- for (i=downKeysym.begin(); i!=downKeysym.end(); i=next_i) {
- next_i = i; next_i++;
- writer->keyEvent((*i).second, false);
- downKeysym.erase(i);
- }
-}
-
-// releaseKey() - write a key up event to the server, but only if we've
-// actually sent a key down event for the given key. The key up event always
-// contains the same keysym we used in the key down event, regardless of what
-// it would look up as using the current keyboard state.
-void win32::CKeyboard::releaseKey(InputHandler* writer, int extendedVkey)
-{
- if (downKeysym.find(extendedVkey) != downKeysym.end()) {
- vlog.debug("release extendedVkey 0x%x, keysym 0x%x",
- extendedVkey, downKeysym[extendedVkey]);
- writer->keyEvent(downKeysym[extendedVkey], false);
- downKeysym.erase(extendedVkey);
- }
-}
-
-// pressKey() - write a key down event to the server, and record which keysym
-// was sent as corresponding to the given extendedVkey. The only tricky bit is
-// that if we are trying to press an extendedVkey which is already marked as
-// down but with a different keysym, then we need to release the old keysym
-// first. This can happen in two cases: (a) when a single key press results in
-// more than one character, and (b) when shift is released while another key is
-// autorepeating.
-void win32::CKeyboard::pressKey(InputHandler* writer, int extendedVkey,
- rdr::U32 keysym)
-{
- if (downKeysym.find(extendedVkey) != downKeysym.end()) {
- if (downKeysym[extendedVkey] != keysym) {
- vlog.debug("release extendedVkey 0x%x, keysym 0x%x",
- extendedVkey, downKeysym[extendedVkey]);
- writer->keyEvent(downKeysym[extendedVkey], false);
- }
- }
- vlog.debug("press extendedVkey 0x%x, keysym 0x%x",
- extendedVkey, keysym);
- writer->keyEvent(keysym, true);
- downKeysym[extendedVkey] = keysym;
-}
+++ /dev/null
-/* 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.
- */
-
-// -=- CKeyboard.h
-//
-// Client-side keyboard handling for Win32
-
-#ifndef __RFB_WIN32_CKEYBOARD_H__
-#define __RFB_WIN32_CKEYBOARD_H__
-
-#include <rfb/InputHandler.h>
-#include <map>
-
-namespace rfb {
-
- namespace win32 {
-
- class CKeyboard {
- public:
- void keyEvent(InputHandler* writer, rdr::U8 vkey, rdr::U32 flags,
- bool down);
- void releaseAllKeys(InputHandler* writer);
- const std::map<int,rdr::U32>& pressedKeys() const {return downKeysym;};
- bool keyPressed(int k) const {return downKeysym.find(k)!=downKeysym.end();}
- private:
- void releaseKey(InputHandler* writer, int extendedVkey);
- void pressKey(InputHandler* writer, int extendedVkey, rdr::U32 keysym);
- std::map<int,rdr::U32> downKeysym;
- };
-
- }; // win32
-
-}; // rfb
-
-#endif // __RFB_WIN32_CKEYBOARD_H__
set(RFB_WIN32_SOURCES
AboutDialog.cxx
- CKeyboard.cxx
Clipboard.cxx
- CPointer.cxx
CurrentUser.cxx
DeviceContext.cxx
DeviceFrameBuffer.cxx
EventManager.cxx
LaunchProcess.cxx
ListViewControl.cxx
- LowLevelKeyEvents.cxx
MonitorInfo.cxx
MsgWindow.cxx
OSVersion.cxx
- ProgressControl.cxx
RegConfig.cxx
Registry.cxx
SecurityPage.cxx
SocketManager.cxx
TCharArray.cxx
Threading.cxx
- ToolBar.cxx
TsSessions.cxx
Win32Util.cxx
WMCursor.cxx
+++ /dev/null
-/* 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.
- */
-
-#include <windows.h>
-#include <rfb/LogWriter.h>
-#include <rfb_win32/CPointer.h>
-
-using namespace rfb;
-using namespace win32;
-
-static LogWriter vlog("CPointer");
-
-
-CPointer::CPointer() : currButtonMask(0), intervalQueued(false), threeEmulating(false) {
-}
-
-CPointer::~CPointer() {
- intervalTimer.stop();
- threeTimer.stop();
-}
-
-
-void CPointer::pointerEvent(InputHandler* writer, const Point& pos, int buttonMask) {
- //
- // - Duplicate Event Filtering
- //
-
- bool maskChanged = buttonMask != currButtonMask;
- bool posChanged = !pos.equals(currPos);
- if (!(posChanged || maskChanged))
- return;
-
- // Pass on the event to the event-interval handler
- threePointerEvent(writer, pos, buttonMask);
-
- // Save the position and mask
- currPos = pos;
- currButtonMask = buttonMask;
-}
-
-
-inline int _abs(int x) {return x>0 ? x : -x;}
-
-int emulate3Mask(int buttonMask) {
- // - Release left & right and press middle
- vlog.debug("emulate3: active");
- buttonMask &= ~5;
- buttonMask |= 2;
- return buttonMask;
-}
-
-void CPointer::threePointerEvent(InputHandler* writer, const Point& pos, int buttonMask) {
- //
- // - 3-Button Mouse Emulation
- //
-
- if (emulate3) {
-
- bool leftChanged = (buttonMask & 1) != (currButtonMask & 1);
- bool rightChanged = (buttonMask & 4) != (currButtonMask & 4);
-
- if (leftChanged || rightChanged) {
- // - One of left or right have changed
-
- if ((buttonMask & 5) == 1 || (buttonMask & 5) == 4) {
- // - One is up, one is down. Start a timer, so that if it
- // expires then we know we should actually send this event
- vlog.debug("emulate3: start timer");
- threeTimer.start(100);
- threePos = pos;
- threeMask = buttonMask;
- return;
-
- } else if (threeTimer.isActive()) {
- // - Both are up or both are down, and we were timing for an emulation event
- // Stop the timer and flush the stored event
- vlog.debug("emulate3: stop timer (state)");
- threeTimer.stop();
- if (threeEmulating == ((buttonMask & 5) == 5))
- intervalPointerEvent(writer, threePos, threeMask);
- else
- threeEmulating = ((buttonMask & 5) == 5);
- }
-
- } else {
-
- if (threeTimer.isActive()) {
- // - We are timing for an emulation event
-
- if (_abs(threePos.x - pos.x) > 4 || _abs(threePos.y - pos.y) > 4) {
- // If the mouse has moved too far since the button-change event then flush
- vlog.debug("emulate3: stop timer (moved)");
- threeTimer.stop();
- intervalPointerEvent(writer, threePos, threeMask);
-
- } else {
- // Otherwise, we ignore the new event
- return;
- }
- }
-
- }
-
- // - If neither left nor right are down, stop emulating
- if ((buttonMask & 5) == 0)
- threeEmulating = false;
-
- // - If emulating, release left & right and press middle
- if (threeEmulating)
- buttonMask = emulate3Mask(buttonMask);
-
- }
-
- // - Let the event pass through to the next stage of processing
- intervalPointerEvent(writer, pos, buttonMask);
-}
-
-void CPointer::intervalPointerEvent(InputHandler* writer, const Point& pos, int buttonMask) {
- //
- // - Pointer Event Interval
- //
- vlog.write(101, "ptrEvent: %d,%d (%lx)", pos.x, pos.y, buttonMask);
-
- // Send the event immediately if we haven't sent one for a while
- bool sendNow = !intervalTimer.isActive();
-
- if (intervalMask != buttonMask) {
- // If the buttons have changed then flush queued events and send now
- sendNow = true;
- if (intervalQueued)
- writer->pointerEvent(intervalPos, intervalMask);
- intervalQueued = false;
- }
-
- if (!sendNow) {
- // If we're not sending now then just queue the event
- intervalQueued = true;
- intervalPos = pos;
- intervalMask = buttonMask;
- } else {
- // Start the interval timer if required, and send the event
- intervalQueued = false;
- intervalMask = buttonMask;
- if (pointerEventInterval)
- intervalTimer.start(pointerEventInterval);
- writer->pointerEvent(pos, buttonMask);
- }
-}
-
-void CPointer::handleTimer(InputHandler* writer, int timerId) {
- if (timerId == intervalTimer.getId()) {
- // Pointer interval has expired - send any queued events
- if (intervalQueued) {
- writer->pointerEvent(intervalPos, intervalMask);
- intervalQueued = false;
- } else {
- intervalTimer.stop();
- }
-
- } else if (timerId == threeTimer.getId()) {
- // 3-Button emulation timer has expired - send what we've got
- vlog.debug("emulate3: timeout");
- threeTimer.stop();
-
- // If emulating, release left & right and press middle
- if (threeEmulating)
- threeMask = emulate3Mask(threeMask);
-
- intervalPointerEvent(writer, threePos, threeMask);
- }
-}
+++ /dev/null
-/* 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.
- */
-
-// -=- CPointer.h
-//
-// Client-side pointer event handling for Win32
-
-#ifndef __RFB_WIN32_CPOINTER_H__
-#define __RFB_WIN32_CPOINTER_H__
-
-#include <rdr/Exception.h>
-#include <rfb/Configuration.h>
-#include <rfb/InputHandler.h>
-#include <rfb/Rect.h>
-#include <rfb_win32/IntervalTimer.h>
-
-namespace rfb {
-
- namespace win32 {
-
- class CPointer {
- public:
- CPointer();
- ~CPointer();
-
- void pointerEvent(InputHandler* writer, const Point& pos, int buttonMask);
- void handleTimer(InputHandler* writer, int timerId);
-
- void setHWND(HWND w) {intervalTimer.setHWND(w); threeTimer.setHWND(w);}
- void setIntervalTimerId(int id) {intervalTimer.setId(id);}
- void set3ButtonTimerId(int id) {threeTimer.setId(id);}
-
- void enableEmulate3(bool enable) {emulate3 = enable;}
- void enableInterval(int millis) {pointerEventInterval = millis;}
- private:
- Point currPos;
- int currButtonMask;
-
- bool emulate3;
- int pointerEventInterval;
-
- void intervalPointerEvent(InputHandler* writer, const Point& pos, int buttonMask);
- IntervalTimer intervalTimer;
- bool intervalQueued;
- Point intervalPos;
- int intervalMask;
-
- void threePointerEvent(InputHandler* writer, const Point& pos, int buttonMask);
- IntervalTimer threeTimer;
- Point threePos;
- int threeMask;
- bool threeEmulating;
- };
-
- }; // win32
-
-}; // rfb
-
-#endif // __RFB_WIN32_CPOINTER_H__
+++ /dev/null
-/* 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.
- */
-
-#ifndef __RFB_WIN32_LOGPALETTE_H__
-#define __RFB_WIN32_LOGPALETTE_H__
-
-#include <windows.h>
-#include <rdr/Exception.h>
-
-namespace rfb {
- namespace win32 {
-
- class LogicalPalette {
- public:
- LogicalPalette() {
- BYTE buf[sizeof(LOGPALETTE)+256*sizeof(PALETTEENTRY)];
- LOGPALETTE* logpal = (LOGPALETTE*)buf;
- logpal->palVersion = 0x300;
- logpal->palNumEntries = 256;
- for (int i=0; i<256;i++) {
- logpal->palPalEntry[i].peRed = 0;
- logpal->palPalEntry[i].peGreen = 0;
- logpal->palPalEntry[i].peBlue = 0;
- logpal->palPalEntry[i].peFlags = 0;
- }
- palette = CreatePalette(logpal);
- if (!palette)
- throw rdr::SystemException("failed to CreatePalette", GetLastError());
- }
- ~LogicalPalette() {
- if (palette && !DeleteObject(palette))
- throw rdr::SystemException("del palette failed", GetLastError());
- }
- void setEntries(int start, int count, const Colour* cols) {
- if (numEntries < count) {
- ResizePalette(palette, start+count);
- numEntries = start+count;
- }
- PALETTEENTRY* logpal = new PALETTEENTRY[count];
- for (int i=0; i<count; i++) {
- logpal[i].peRed = cols[i].r >> 8;
- logpal[i].peGreen = cols[i].g >> 8;
- logpal[i].peBlue = cols[i].b >> 8;
- logpal[i].peFlags = 0;
- }
- UnrealizeObject(palette);
- SetPaletteEntries(palette, start, count, logpal);
- delete [] logpal;
- }
- HPALETTE getHandle() {return palette;}
- protected:
- HPALETTE palette;
- int numEntries;
- };
-
- class PaletteSelector {
- public:
- PaletteSelector(HDC dc, HPALETTE pal) : device(dc), redrawRequired(false) {
- oldPal = SelectPalette(dc, pal, FALSE);
- redrawRequired = RealizePalette(dc) > 0;
- }
- ~PaletteSelector() {
- if (oldPal) SelectPalette(device, oldPal, TRUE);
- }
- bool isRedrawRequired() {return redrawRequired;}
- protected:
- HPALETTE oldPal;
- HDC device;
- bool redrawRequired;
- };
-
- };
-};
-
-#endif
+++ /dev/null
-/* 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.
- */
-
-#include <windows.h>
-#include <rfb_win32/LowLevelKeyEvents.h>
-#include <rfb/Threading.h>
-#include <rfb/LogWriter.h>
-#include <list>
-
-using namespace rfb;
-using namespace win32;
-
-static LogWriter vlog("LowLevelKeyEvents");
-
-
-HHOOK hook = 0;
-std::list<HWND> windows;
-Mutex windowLock;
-
-
-static bool filterKeyEvent(int vkCode) {
- switch (vkCode) {
- case VK_LWIN:
- case VK_RWIN:
- case VK_SNAPSHOT:
- return true;
- case VK_TAB:
- if (GetAsyncKeyState(VK_MENU) & 0x8000)
- return true;
- case VK_ESCAPE:
- if (GetAsyncKeyState(VK_MENU) & 0x8000)
- return true;
- if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
- return true;
- }
- return false;
-}
-
-LRESULT CALLBACK LowLevelKeyEventProc(int nCode,
- WPARAM wParam,
- LPARAM lParam) {
- if (nCode >= 0) {
- Lock l(windowLock);
- HWND foreground = GetForegroundWindow();
- std::list<HWND>::iterator i;
- for (i=windows.begin(); i!=windows.end(); i++) {
- if (*i == foreground) {
- UINT msgType = wParam;
- KBDLLHOOKSTRUCT* msgInfo = (KBDLLHOOKSTRUCT*)lParam;
- if (filterKeyEvent(msgInfo->vkCode)) {
- vlog.debug("filtered event %lx(%lu) %lu", msgInfo->vkCode, msgInfo->vkCode, msgType);
- PostMessage(*i, wParam, msgInfo->vkCode, (msgInfo->scanCode & 0xff) << 16);
- return 1;
- }
- }
- }
- }
- return CallNextHookEx(hook, nCode, wParam, lParam);
-}
-
-
-bool rfb::win32::enableLowLevelKeyEvents(HWND hwnd) {
-// *** return false; // *** THIS CODE IS EXPERIMENTAL, SO DISABLED BY DEFAULT!
- Lock l(windowLock);
- if (windows.empty() && !hook)
- hook = SetWindowsHookEx(WH_KEYBOARD_LL, &LowLevelKeyEventProc, GetModuleHandle(0), 0);
- if (hook)
- windows.push_back(hwnd);
- vlog.debug("enable %p -> %s", hwnd, hook ? "success" : "failure");
- return hook != 0;
-}
-
-void rfb::win32::disableLowLevelKeyEvents(HWND hwnd) {
- vlog.debug("disable %p", hwnd);
- Lock l(windowLock);
- windows.remove(hwnd);
- if (windows.empty() && hook) {
- UnhookWindowsHookEx(hook);
- hook = 0;
- }
-}
+++ /dev/null
-/* 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.
- */
-
-// -=- LowLevelKeyEvents.h
-//
-// This interface allows keyboard events destined for a particular window
-// to be intercepted early in the keyboard message queue and posted directly
-// to the window. This is used to avoid having the operating system process
-// keys such as VK_LWIN, VK_RWIN, etc.
-//
-
-#ifndef __RFB_WIN32_LOW_LEVEL_KEY_EVENTS_H__
-#define __RFB_WIN32_LOW_LEVEL_KEY_EVENTS_H__
-
-namespace rfb {
-
- namespace win32 {
-
- // enableLowLevelKeyEvents
- // Specifies that keyboard events destined for the specified window should
- // be posted directly to the window, rather than being passed via the normal
- // Windows keyboard message queue.
- bool enableLowLevelKeyEvents(HWND hwnd);
-
- // disableLowLevelKeyEvents
- // Causes the specified window to revert to the normal Windows keyboard
- // event processing mechanism.
- void disableLowLevelKeyEvents(HWND hwnd);
-
- };
-
-};
-
-#endif // __RFB_WIN32_LOW_LEVEL_KEY_EVENTS_H__
+++ /dev/null
-/* Copyright (C) 2005 TightVNC Team. 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.
- *
- *
- *
- */
-
-// -=- ProgressControl.cxx
-
-#include <rfb_win32/ProgressControl.h>
-
-using namespace rfb;
-using namespace rfb::win32;
-
-#define MAX_RANGE 0xFFFF
-
-ProgressControl::ProgressControl(HWND hwndProgress)
-{
- m_hwndProgress = hwndProgress;
-
- m_dw64MaxValue = 0;
- m_dw64CurrentValue = 0;
-}
-
-ProgressControl::~ProgressControl()
-{
-}
-
-bool
-ProgressControl::init(DWORD64 maxValue, DWORD64 position)
-{
- if (m_dw64CurrentValue > m_dw64MaxValue) return false;
-
- m_dw64CurrentValue = position;
- m_dw64MaxValue = maxValue;
-
- if (!SendMessage(m_hwndProgress, PBM_SETRANGE, (WPARAM) 0, MAKELPARAM(0, MAX_RANGE)))
- return false;
-
- return true;
-}
-
-bool
-ProgressControl::clear()
-{
- m_dw64CurrentValue = 0;
- return show();
-}
-
-bool
-ProgressControl::increase(DWORD64 value)
-{
- if ((m_dw64MaxValue - m_dw64CurrentValue) > value) {
- m_dw64CurrentValue += value;
- } else {
- m_dw64CurrentValue = m_dw64MaxValue;
- }
- return show();
-}
-
-bool
-ProgressControl::show()
-{
- DWORD curPos;
- if (m_dw64MaxValue != 0) {
- curPos = (DWORD) ((m_dw64CurrentValue * MAX_RANGE) / m_dw64MaxValue);
- } else {
- curPos = 0;
- }
-
- if (!SendMessage(m_hwndProgress, PBM_SETPOS, (WPARAM) curPos, (LPARAM) 0))
- return false;
-
- return true;
-}
-
-int
-ProgressControl::getCurrentPercent()
-{
- if (m_dw64MaxValue == 0) return 0;
-
- return ((int) ((m_dw64CurrentValue * 100) / m_dw64MaxValue));
-}
+++ /dev/null
-/* Copyright (C) 2005 TightVNC Team. 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.
- *
- *
- *
- */
-
-// -=- ProgressControl.h
-
-#ifndef __RFB_WIN32_PROGRESSCONTROL_H__
-#define __RFB_WIN32_PROGRESSCONTROL_H__
-
-#include <windows.h>
-#include <commctrl.h>
-
-namespace rfb {
- namespace win32 {
- class ProgressControl
- {
- public:
- ProgressControl(HWND hwndProgress);
- ~ProgressControl();
-
- bool init(DWORD64 maxValue, DWORD64 position);
-
- bool increase(DWORD64 value);
- bool clear();
-
- int getCurrentPercent();
-
- private:
- HWND m_hwndProgress;
-
- DWORD64 m_dw64MaxValue;
- DWORD64 m_dw64CurrentValue;
-
- bool show();
- };
- }
-}
-
-#endif // __RFB_WIN32_PROGRESSCONTROL_H__
+++ /dev/null
-/* Copyright (C) 2004 TightVNC Team. 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.
- */
-
-// -=- ToolBar control class.
-
-#include "ToolBar.h"
-
-using namespace rfb::win32;
-
-ToolBar::ToolBar() : hwndToolBar(0), tbID(-1) {
- INITCOMMONCONTROLSEX icex;
-
- // Ensure that the common control DLL is loaded
- icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
- icex.dwICC = ICC_BAR_CLASSES;
- InitCommonControlsEx(&icex);
-}
-
-ToolBar::~ToolBar() {
- DestroyWindow(getHandle());
-}
-
-bool ToolBar::create(int _tbID, HWND _parentHwnd, DWORD dwStyle) {
- parentHwnd = _parentHwnd;
- dwStyle |= WS_CHILD;
-
- // Create the ToolBar window
- hwndToolBar = CreateWindowEx(0, TOOLBARCLASSNAME, 0, dwStyle,
- 0, 0, 25, 25, parentHwnd, (HMENU)_tbID, GetModuleHandle(0), 0);
-
- if (hwndToolBar) {
- tbID = _tbID;
-
- // It's required for backward compatibility
- SendMessage(hwndToolBar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
- }
- return (hwndToolBar ? true : false);
-};
-
-int ToolBar::addBitmap(int nButtons, UINT bitmapID) {
- assert(nButtons > 0);
- TBADDBITMAP resBitmap;
- resBitmap.hInst = GetModuleHandle(0);
- resBitmap.nID = bitmapID;
- return SendMessage(getHandle(), TB_ADDBITMAP, nButtons, (LPARAM)&resBitmap);
-}
-
-int ToolBar::addSystemBitmap(UINT stdBitmapID) {
- TBADDBITMAP resBitmap;
- resBitmap.hInst = HINST_COMMCTRL;
- resBitmap.nID = stdBitmapID;
- return SendMessage(getHandle(), TB_ADDBITMAP, 0, (LPARAM)&resBitmap);
-}
-
-bool ToolBar::setBitmapSize(int width, int height) {
- int result = SendMessage(getHandle(), TB_SETBITMAPSIZE,
- 0, MAKELONG(width, height));
- return (result ? true : false);
-}
-
-bool ToolBar::addButton(int iBitmap, int idCommand, BYTE state, BYTE style, UINT dwData, int iString) {
- TBBUTTON tbb;
- tbb.iBitmap = iBitmap;
- tbb.idCommand = idCommand;
- tbb.fsState = state;
- tbb.fsStyle = style;
- tbb.dwData = dwData;
- tbb.iString = iString;
-
- int result = SendMessage(getHandle(), TB_ADDBUTTONS, 1, (LPARAM)&tbb);
- if (result) {
- SendMessage(getHandle(), TB_AUTOSIZE, 0, 0);
- }
- return (result ? true : false);
-}
-
-bool ToolBar::addNButton(int nButtons, LPTBBUTTON tbb) {
- assert(nButtons > 0);
- assert(tbb > 0);
- int result = SendMessage(getHandle(), TB_ADDBUTTONS, nButtons, (LPARAM)tbb);
- if (result) {
- SendMessage(getHandle(), TB_AUTOSIZE, 0, 0);
- }
- return (result ? true : false);
-}
-
-bool ToolBar::deleteButton(int indexButton) {
- assert(indexButton >= 0);
- int result = SendMessage(getHandle(), TB_DELETEBUTTON, indexButton, 0);
-
- if (result) {
- SendMessage(getHandle(), TB_AUTOSIZE, 0, 0);
- }
- return (result ? true : false);
-}
-
-bool ToolBar::insertButton(int indexButton, LPTBBUTTON tbb) {
- assert(indexButton >= 0);
- assert(tbb > 0);
- int result = SendMessage(getHandle(), TB_INSERTBUTTON,
- indexButton, (LPARAM)tbb);
-
- if (result) {
- SendMessage(getHandle(), TB_AUTOSIZE, 0, 0);
- }
- return (result ? true : false);
-}
-
-int ToolBar::getButtonInfo(int idButton, TBBUTTONINFO *btnInfo) {
- assert(idButton >= 0);
- assert(btnInfo > 0);
- return SendMessage(getHandle(), TB_GETBUTTONINFO, idButton, (LPARAM)btnInfo);
-}
-
-int ToolBar::getButtonsHeight() {
- return HIWORD(SendMessage(getHandle(), TB_GETBUTTONSIZE, 0, 0));
-}
-
-int ToolBar::getButtonsWidth() {
- return LOWORD(SendMessage(getHandle(), TB_GETBUTTONSIZE, 0, 0));
-}
-
-bool ToolBar::setButtonInfo(int idButton, TBBUTTONINFO* btnInfo) {
- assert(idButton >= 0);
- assert(btnInfo > 0);
- int result = SendMessage(getHandle(), TB_SETBUTTONINFO,
- idButton, (LPARAM)(LPTBBUTTONINFO)btnInfo);
- return (result ? true : false);
-}
-
-bool ToolBar::checkButton(int idButton, bool check) {
- assert(idButton >= 0);
- int result = SendMessage(getHandle(), TB_CHECKBUTTON,
- idButton, MAKELONG(check, 0));
- return (result ? true : false);
-}
-
-bool ToolBar::enableButton(int idButton, bool enable) {
- assert(idButton >= 0);
- int result = SendMessage(getHandle(), TB_ENABLEBUTTON,
- idButton, MAKELONG(enable, 0));
- return (result ? true : false);
-}
-
-bool ToolBar::pressButton(int idButton, bool press) {
- assert(idButton >= 0);
- int result = SendMessage(getHandle(), TB_PRESSBUTTON,
- idButton, MAKELONG(press, 0));
- return (result ? true : false);
-}
-
-bool ToolBar::getButtonRect(int nIndex, LPRECT buttonRect) {
- int result = SendMessage(getHandle(), TB_GETITEMRECT,
- nIndex, (LPARAM)buttonRect);
- return (result ? true : false);
-}
-
-bool ToolBar::setButtonSize(int width, int height) {
- assert(width > 0);
- assert(height > 0);
- int result = SendMessage(getHandle(), TB_SETBUTTONSIZE,
- 0, MAKELONG(width, height));
- if (result) {
- SendMessage(getHandle(), TB_AUTOSIZE, 0, 0);
- return true;
- }
- return false;
-}
-
-void ToolBar::autoSize() {
- DWORD style = SendMessage(getHandle(), TB_GETSTYLE, 0, 0);
- if (style & CCS_NORESIZE) {
- RECT r, btnRect;
- GetClientRect(parentHwnd, &r);
- getButtonRect(0, &btnRect);
- int height = getButtonsHeight() + btnRect.top * 2 + 2;
- SetWindowPos(getHandle(), HWND_TOP, 0, 0, r.right - r.left, height,
- SWP_NOMOVE);
- } else {
- SendMessage(getHandle(), TB_AUTOSIZE, 0, 0);
- }
-}
-
-int ToolBar::getHeight() {
- RECT r;
- GetWindowRect(getHandle(), &r);
- return r.bottom - r.top;
-}
-
-int ToolBar::getTotalWidth() {
- SIZE size;
- SendMessage(getHandle(), TB_GETMAXSIZE, 0, (LPARAM)(LPSIZE)&size);
- return size.cx;
-}
-
-void ToolBar::show() {
- ShowWindow(getHandle(), SW_SHOW);
-}
-
-void ToolBar::hide() {
- ShowWindow(getHandle(), SW_HIDE);
-}
-
-bool ToolBar::isVisible() {
- DWORD style = GetWindowLong(getHandle(), GWL_STYLE);
- return (bool)(style & WS_VISIBLE);
-}
+++ /dev/null
-/* Copyright (C) 2004 TightVNC Team. 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.
- */
-
-// -=- ToolBar control class.
-
-#include <windows.h>
-#include <commctrl.h>
-#include <assert.h>
-
-namespace rfb {
-
- namespace win32 {
-
- class ToolBar {
- public:
- ToolBar();
- virtual ~ToolBar();
-
- // create() creates a windows toolbar. dwStyle is a combination of
- // the toolbar control and button styles. It returns TRUE if successful,
- // or FALSE otherwise.
- bool create(int tbID, HWND parentHwnd,
- DWORD dwStyle = WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT);
-
- // -=- Button images operations
-
- // addBitmap() adds one or more images from resources to
- // the list of button images available for a toolbar.
- // Returns the index of the first new image if successful,
- // or -1 otherwise.
- int addBitmap(int nButtons, UINT bitmapID);
-
- // addSystemBitmap() adds the system-defined button bitmaps to the list
- // of the toolbar button specifying by stdBitmapID. Returns the index of
- // the first new image if successful, or -1 otherwise.
- int addSystemBitmap(UINT stdBitmapID);
-
- // setBitmapSize() sets the size of the bitmapped images to be added
- // to a toolbar. It returns TRUE if successful, or FALSE otherwise.
- // You must call it before addBitmap().
- bool setBitmapSize(int width, int height);
-
- // -=- Button operations
-
- // addButton() adds one button.
- bool addButton(int iBitmap, int idCommand, BYTE state=TBSTATE_ENABLED,
- BYTE style=TBSTYLE_BUTTON, UINT dwData=0, int iString=0);
-
- // addNButton() adds nButtons buttons to a toolbar.
- bool addNButton(int nButtons, LPTBBUTTON tbb);
-
- // deleteButton() removes a button from the toolbar.
- bool deleteButton(int nIndex);
-
- // insertButton() inserts a button in a toolbar control by index.
- bool insertButton(int nIndex, LPTBBUTTON tbb);
-
- // getButtonInfo() retrieves extended information about a toolbar's
- // button. It returns index of the button if successful, or -1 otherwise.
- int getButtonInfo(int idButton, TBBUTTONINFO *btnInfo);
-
- // getButtonsHeight() retrieves the height of the toolbar buttons.
- int getButtonsHeight();
-
- // getButtonsWidth() retrieves the width of the toolbar buttons.
- int getButtonsWidth();
-
- // setButtonInfo() sets the information for an existing button
- // in a toolbar.
- bool setButtonInfo(int idButton, TBBUTTONINFO* ptbbi);
-
- // checkButton() checks or unchecks a given button in a toolbar control.
- bool checkButton(int idButton, bool check);
-
- // enableButton() enables or disables the specified button
- // in the toolbar.
- bool enableButton(int idButton, bool enable);
-
- // pressButton() presses or releases the specified button in the toolbar.
- bool pressButton(int idButton, bool press);
-
- // getButtonRect() gets the bounding rectangle of a button in a toolbar.
- bool getButtonRect(int nIndex, LPRECT buttonRect);
-
- // setButtonSize() sets the size of the buttons to be added to a toolbar.
- // Button size must be largen the button bitmap.
- bool setButtonSize(int width, int height);
-
- // -=- ToolBar operations
-
- // autoSize() resizes the toolbar window.
- void autoSize();
-
- // getHandle() returns handle to a toolbar window.
- HWND getHandle() { return hwndToolBar; }
-
- // getHeight() returns the toolbar window height.
- int getHeight();
-
- // getTotalWidth() returns the total size of all buttons and
- // separators in the toolbar.
- int getTotalWidth();
-
- // show() displays the toolbar window.
- void show();
-
- // hide() hides the toolbar window.
- void hide();
-
- // isVisible() check the toolbar window on visible.
- bool isVisible();
-
- protected:
- HWND hwndToolBar;
- HWND parentHwnd;
- int tbID;
- };
-
- }; // win32
-
-}; // rfb