/* 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. */ // -=- DesktopWindow.h // Each VNC connection instance (CConn) creates a DesktopWindow the // server initialisation message has been received. The CConn is // responsible for all RFB-specific and network issues. The // DesktopWindow is responsible for all GUI management issues. // // DesktopWindow provides a FullFramePixelBuffer interface for the // CConn to render updates into. It also requires a callback object // to be supplied, which will be notified when various events occur. #ifndef __RFB_WIN32_DESKTOP_WINDOW_H__ #define __RFB_WIN32_DESKTOP_WINDOW_H__ #include #include #include #include #include #include #include namespace rfb { namespace win32 { class DesktopWindow : rfb::win32::Clipboard::Notifier { public: class Callback; DesktopWindow(Callback* cb_); ~DesktopWindow(); // - Window message handling procedure LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam); // - Window message handling procedure for the framebuffer window LRESULT processFrameMessage(UINT msg, WPARAM wParam, LPARAM lParam); // - Separate message handling procedure for mouse events // It's called from both processMessage() and processFrameMessage() void processMouseMessage(UINT msg, WPARAM wParam, LPARAM lParam); // - Determine the native pixel format of the window // This can (and often will) differ from the PixelBuffer format PixelFormat getNativePF() const; // - Get the underlying window handle // This is used by F8Menu to modify the window's menu HWND getHandle() const {return handle;} // - Get the framebuffer window handle HWND getFrameHandle() const {return frameHandle;} // - Set the window title void setName(const char* name); // - Set the key that causes the system/F8 menu to be displayed void setMenuKey(rdr::U8 key) { menuKey = key; } // - Pointer event handling void setEmulate3(bool em3) { ptr.enableEmulate3(em3); } void setPointerEventInterval(int interval) { ptr.enableInterval(interval); } // - Set the pixel format, size etc of the underlying PixelBuffer void setPF(const PixelFormat& pf); PixelFormat getPF() const { return buffer->getPixelFormat(); } void setSize(int w, int h); void setColour(int i, int r, int g, int b) {buffer->setColour(i, r, g, b);} void setAutoScaling(bool as); bool isAutoScaling() const { return autoScaling; } void setDesktopScale(int scale); int getDesktopScale() const { return buffer->getScale(); } void setDesktopScaleFilter(unsigned int scaleFilterID); unsigned int getDesktopScaleFilterID() const { return buffer->getScaleFilterID(); } void fitBufferToWindow(bool repaint = true); void printScale(); // - Set the cursor to render when the pointer is within the desktop buffer void setCursor(int w, int h, const Point& hotspot, void* data, void* mask); void showCursor() { showLocalCursor(); } void convertCursorToBuffer(); // - Set the window fullscreen / determine whether it is fullscreen void setFullscreen(bool fs); bool isFullscreen() { return fullscreenActive; } // - Set/get the toolbar's state void setShowToolbar(bool st); bool isToolbarEnabled() { return showToolbar; } void refreshToolbarButtons(); // - Set whether to disable special Windows keys & pass them straight to server void setDisableWinKeys(bool dwk); // - Set/get which monitor the window should be displayed on void setMonitor(const char* monitor); char* getMonitor() const; // - Set the local clipboard void serverCutText(const char* str, rdr::U32 len); // - Completion of one FramebufferUpdate void framebufferUpdateEnd(); // - Draw into the desktop buffer & update the window void fillRect(const Rect& r, Pixel pix); void imageRect(const Rect& r, void* pixels); void copyRect(const Rect& r, int srcX, int srcY); void invertRect(const Rect& r); // - Update the window palette if the display is palette-based. // Colours are pulled from the desktop buffer's ColourMap. // Only the specified range of indexes is dealt with. // After the update, the entire window is redrawn. void refreshWindowPalette(int start, int count); // Clipboard::Notifier interface void notifyClipboardChanged(const char* text, int len); // DesktopWindow Callback interface class Callback : public InputHandler { public: virtual ~Callback() {} virtual void displayChanged() = 0; virtual void paintCompleted() = 0; virtual bool sysCommand(WPARAM wParam, LPARAM lParam) = 0; virtual void closeWindow() = 0; virtual void refreshMenu(bool enableSysItems) = 0; }; Callback *getCallback() const { return callback; } // Currently accessible so that the CConn can releaseAllKeys & check // whether Ctrl and Alt are down... rfb::win32::CKeyboard kbd; protected: // Routines to convert between Desktop and client (window) coordinates Point desktopToClient(const Point& p) { Point pos = p; if (client_size.width() > buffer->width()) pos.x += (client_size.width() - buffer->width()) / 2; else if (client_size.width() < buffer->width()) pos.x -= scrolloffset.x; if (client_size.height() > buffer->height()) pos.y += (client_size.height() - buffer->height()) / 2; else if (client_size.height() < buffer->height()) pos.y -= scrolloffset.y; return pos; } Rect desktopToClient(const Rect& r) { return Rect(desktopToClient(r.tl), desktopToClient(r.br)); } Point clientToDesktop(const Point& p) { Point pos = p; if (client_size.width() > buffer->width()) pos.x -= (client_size.width() - buffer->width()) / 2; else if (client_size.width() < buffer->width()) pos.x += scrolloffset.x; if (client_size.height() > buffer->height()) pos.y -= (client_size.height() - buffer->height()) / 2; else if (client_size.height() < buffer->height()) pos.y += scrolloffset.y; return pos; } Rect clientToDesktop(const Rect& r) { return Rect(clientToDesktop(r.tl), clientToDesktop(r.br)); } // Internal routine used by the scrollbars & bump scroller to select // the portion of the Desktop to display bool setViewportOffset(const Point& tl); // Bump scroll handling. Bump scrolling is used if the window is // in fullscreen mode and the Desktop is larger than the window bool processBumpScroll(const Point& cursorPos); void setBumpScroll(bool on); bool bumpScroll; Point bumpScrollDelta; IntervalTimer bumpScrollTimer; // Track modified areas of the framebuffer void updateWindow(); // Locally-rendered VNC cursor void hideLocalCursor(); void showLocalCursor(); void renderLocalCursor(); // The system-rendered cursor void hideSystemCursor(); void showSystemCursor(); // cursorOutsideBuffer() is called whenever we detect that the mouse has // moved outside the desktop. It restores the system arrow cursor. void cursorOutsideBuffer(); // Returns true if part of the supplied rect is visible, false otherwise bool invalidateDesktopRect(const Rect& crect, bool scaling=true); // Determine whether or not we need to enable/disable scrollbars and set the // window style accordingly void calculateScrollBars(); // Resizes the main window against the pixel buffer size void resizeDesktopWindowToBuffer(); // Win32-specific input handling rfb::win32::CPointer ptr; Point oldpos; rfb::win32::Clipboard clipboard; // Palette handling LogicalPalette windowPalette; bool palette_changed; // - Full-screen mode RECT fullscreenOldRect; DWORD fullscreenOldFlags; bool fullscreenActive; bool fullscreenRestore; // Damage tracking rfb::Region damage; IntervalTimer updateTimer; // Cursor handling Cursor cursor; bool systemCursorVisible; // Should system-cursor be drawn? bool trackingMouseLeave; bool cursorInBuffer; // Is cursor position within server buffer? (ONLY for LocalCursor) bool cursorVisible; // Is cursor currently rendered? bool cursorAvailable; // Is cursor available for rendering? bool internalSetCursor; Point cursorPos; ManagedPixelBuffer cursorBacking; Rect cursorBackingRect; U8 *cursorImage; U8 *cursorMask; int cursorWidth; int cursorHeight; Point cursorHotspot; // ToolBar handling ViewerToolBar tb; bool showToolbar; // Remote desktop name char desktopName[255]; // Local window state win32::ScaledDIBSectionBuffer* buffer; double aspect_corr; bool has_focus; bool autoScaling; Rect window_size; Rect client_size; Point scrolloffset; Point maxscrolloffset; HWND handle; HWND frameHandle; rdr::U8 menuKey; Callback* callback; }; }; }; #endif // __RFB_WIN32_DESKTOP_WINDOW_H__