1 /****************************************************************************
3 ** Copyright (C) 2002-2003 Tim Jansen <tim@tjansen.de>
4 ** Copyright (C) 2007-2008 Urs Wolfer <uwolfer @ kde.org>
6 ** This file is part of KDE.
8 ** This program is free software; you can redistribute it and/or modify
9 ** it under the terms of the GNU General Public License as published by
10 ** the Free Software Foundation; either version 2 of the License, or
11 ** (at your option) any later version.
13 ** This program is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ** GNU General Public License for more details.
18 ** You should have received a copy of the GNU General Public License
19 ** along with this program; see the file COPYING. If not, write to
20 ** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 ** Boston, MA 02110-1301, USA.
23 ****************************************************************************/
34 #include <KWallet/Wallet>
39 class HostPreferences;
42 * Generic widget that displays a remote framebuffer.
43 * Implement this if you want to add another backend.
45 * Things to take care of:
46 * @li The RemoteView is responsible for its size. In
47 * non-scaling mode, set the fixed size of the widget
48 * to the remote resolution. In scaling mode, set the
49 * maximum size to the remote size and minimum size to the
50 * smallest resolution that your scaler can handle.
51 * @li if you override mouseMoveEvent()
52 * you must ignore the QEvent, because the KRDC widget will
53 * need it for stuff like toolbar auto-hide and bump
54 * scrolling. If you use x11Event(), make sure that
55 * MotionNotify events will be forwarded.
58 class KDE_EXPORT RemoteView : public QWidget
74 * Describes the state of a local cursor, if there is such a concept in the backend.
75 * With local cursors, there are two cursors: the cursor on the local machine (client),
76 * and the cursor on the remote machine (server). Because there is usually some lag,
77 * some backends show both cursors simultanously. In the VNC backend the local cursor
78 * is a dot and the remote cursor is the 'real' cursor, usually an arrow.
81 Q_ENUMS(DotCursorState)
84 CursorOn, ///< Always show local cursor (and the remote one).
85 CursorOff, ///< Never show local cursor, only the remote one.
86 /// Try to measure the lag and enable the local cursor if the latency is too high.
91 * State of the connection. The state of the connection is returned
92 * by @ref RemoteView::status().
94 * Not every state transition is allowed. You are only allowed to transition
95 * a state to the following state, with three exceptions:
96 * @li You can move from every state directly to Disconnected
97 * @li You can move from every state except Disconnected to
99 * @li You can move from Disconnected to Connecting
101 * @ref RemoteView::setStatus() will follow this rules for you.
102 * (If you add/remove a state here, you must adapt it)
105 Q_ENUMS(RemoteStatus)
130 virtual ~RemoteView();
133 * Checks whether the backend supports scaling. The
134 * default implementation returns false.
135 * @return true if scaling is supported
138 virtual bool supportsScaling() const;
141 * Checks whether the widget is in scale mode. The
142 * default implementation always returns false.
143 * @return true if scaling is activated. Must always be
144 * false if @ref supportsScaling() returns false
145 * @see supportsScaling()
147 virtual bool scaling() const;
150 * Checks whether the backend supports the concept of local cursors. The
151 * default implementation returns false.
152 * @return true if local cursors are supported/known
153 * @see DotCursorState
154 * @see showDotCursor()
155 * @see dotCursorState()
157 virtual bool supportsLocalCursor() const;
160 * Sets the state of the dot cursor, if supported by the backend.
161 * The default implementation does nothing.
162 * @param state the new state (CursorOn, CursorOff or
164 * @see dotCursorState()
165 * @see supportsLocalCursor()
167 virtual void showDotCursor(DotCursorState state);
170 * Returns the state of the local cursor. The default implementation returns
172 * @return true if local cursors are supported/known
173 * @see showDotCursor()
174 * @see supportsLocalCursor()
176 virtual DotCursorState dotCursorState() const;
179 * Checks whether the view is in view-only mode. This means
180 * that all input is ignored.
182 virtual bool viewOnly();
185 * Checks whether grabbing all possible keys is enabled.
187 virtual bool grabAllKeys();
190 * Returns the resolution of the remote framebuffer.
191 * It should return a null @ref QSize when the size
193 * The backend must also emit a @ref framebufferSizeChanged()
194 * when the size of the framebuffer becomes available
195 * for the first time or the size changed.
196 * @return the remote framebuffer size, a null QSize
199 virtual QSize framebufferSize();
202 * Initiate the disconnection. This doesn't need to happen
203 * immediately. The call must not block.
206 virtual void startQuitting();
209 * Checks whether the view is currently quitting.
210 * @return true if it is quitting
211 * @see startQuitting()
214 virtual bool isQuitting();
217 * @return the host the view is connected to
219 virtual QString host();
222 * @return the port the view is connected to
227 * Initialize the view (for example by showing configuration
228 * dialogs to the user) and start connecting. Should not block
229 * without running the event loop (so displaying a dialog is ok).
230 * When the view starts connecting the application must call
231 * @ref setStatus() with the status Connecting.
232 * @return true if successful (so far), false
235 * @see disconnected()
236 * @see disconnectedError()
237 * @see statusChanged()
239 virtual bool start() = 0;
242 * Called when the configuration is changed.
243 * The default implementation does nothing.
245 virtual void updateConfiguration();
249 * Returns the current host preferences of this view.
251 virtual HostPreferences* hostPreferences() = 0;
255 * Returns the current status of the connection.
256 * @return the status of the connection
259 RemoteStatus status();
262 * @return the current url
268 * Called to enable or disable scaling.
269 * Ignored if @ref supportsScaling() is false.
270 * The default implementation does nothing.
271 * @param s true to enable, false to disable.
272 * @see supportsScaling()
275 virtual void enableScaling(bool scale);
278 * Enables/disables the view-only mode.
279 * Ignored if @ref supportsScaling() is false.
280 * The default implementation does nothing.
281 * @param viewOnly true to enable, false to disable.
282 * @see supportsScaling()
285 virtual void setViewOnly(bool viewOnly);
288 * Enables/disables grabbing all possible keys.
289 * @param grabAllKeys true to enable, false to disable.
293 virtual void setGrabAllKeys(bool grabAllKeys);
296 * Called to let the backend know it when
297 * we switch from/to fullscreen.
298 * @param on true when switching to fullscreen,
299 * false when switching from fullscreen.
301 virtual void switchFullscreen(bool on);
304 * Sends a QKeyEvent to the remote server.
305 * @param event the key to send
307 virtual void keyEvent(QKeyEvent *event);
310 * Called when the visible place changed so remote
311 * view can resize itself.
313 virtual void scaleResize(int w, int h);
317 * Emitted when the size of the remote screen changes. Also
318 * called when the size is known for the first time.
319 * @param x the width of the screen
320 * @param y the height of the screen
322 void framebufferSizeChanged(int w, int h);
325 * Emitted when the view connected successfully.
330 * Emitted when the view disconnected without error.
335 * Emitted when the view disconnected with error.
337 void disconnectedError();
340 * Emitted when the view has a specific error.
342 void errorMessage(const QString &title, const QString &message);
345 * Emitted when the status of the view changed.
346 * @param s the new status
348 void statusChanged(RemoteView::RemoteStatus s);
351 * Emitted when the password dialog is shown or hidden.
352 * @param b true when the dialog is shown, false when it has been hidden
354 void showingPasswordDialog(bool b);
357 * Emitted when the mouse on the remote side has been moved.
358 * @param x the new x coordinate
359 * @param y the new y coordinate
360 * @param buttonMask the mask of mouse buttons (bit 0 for first mouse
361 * button, 1 for second button etc)a
363 void mouseStateChanged(int x, int y, int buttonMask);
366 RemoteView(QWidget *parent = 0);
368 void focusInEvent(QFocusEvent *event);
369 void focusOutEvent(QFocusEvent *event);
372 * The status of the remote view.
374 RemoteStatus m_status;
377 * Set the status of the connection.
378 * Emits a statusChanged() signal.
379 * Note that the states need to be set in a certain order,
380 * see @ref Status. setStatus() will try to do this
381 * transition automatically, so if you are in Connecting
382 * and call setStatus(Preparing), setStatus() will
383 * emit a Authenticating and then Preparing.
384 * If you transition backwards, it will emit a
385 * Disconnected before doing the transition.
386 * @param s the new status
388 virtual void setStatus(RemoteStatus s);
390 QCursor localDotCursor() const;
397 bool m_keyboardIsGrabbed;
401 QString readWalletPassword(bool fromUserNameOnly = false);
402 void saveWalletPassword(const QString &password, bool fromUserNameOnly = false);
403 KWallet::Wallet *m_wallet;
406 DotCursorState m_dotCursorState;