TODO ---- * Command for executing new programs. * Commands for changing z order and focus. * Think about protocol version management * Try to assure that messages aren't repeated or are sent for hidden windows. Overview ======== The protocol is a line based protocol following this simple syntax: OPERATION,SERIAL[,ARG1[,ARG2,[...]]] Each operation will have an increasing serial number. The initial value is implementation defined. The goal is to have a generic protocol that can be used for other display systems (e.g. VNC) as well. One line may not exceed 1024 bytes, including newline. The protocol has no concept of hidden or unmapped windows. A window does not exist unless it is visible. Note that a minimized window is an exception to this rule. The protocol has no way of indicating failure, meaning that all commands are expected to succeed. If a command fails, the receiving end must send a corresponding command back, indicating the actual state. Data types ========== Window ID are written in hex, like 0x4321. Window positions can be negative. This happens when a window is moved outside the desktop. All integers fit inside 32 bits. Strings are sent in UTF-8 and do not contain any characters less than 0x20 or the character , (comma). Server to Client Operations =========================== CREATE ------ Allocate structures for a new window. Syntax: CREATE,,,,, Indicates that a window has appeared on the server. If PARENT is non-zero then the new window is a child of that window (it's transient for it). The special value 0xFFFFFFFF for PARENT means that the window is a popup window without a parent. It's commonly used for splash screens, tool tips and context menus. The group id identifies a set of windows that belong together. It is currently only used for modal windows and DESTROYGRP. Flags: 0x0001 : Create a window that's modal with regard to the other windows in the same group. Note that very little information is included in this message. Things like title and state will come in subsequent messages. This message should only be used to allocate data structures for the new window. DESTROY ------- Remove a window. Syntax: DESTROY,,, Remove the window and deallocate all associated structures. DESTROYGRP ---------- Destroy an entire group of windows. Syntax: DESTROYGRP,,, Every window that belongs to the group GRPID should be destroyed as if they each got a DESTROY message. POSITION -------- Move and/or resize a window. Syntax: POSITION,,,,,,, If the window isn't visible yet (because a STATE hasn't been set or because it's minimized), you must store the position and size. A new POSITION is not guaranteed to be sent when the window changes state. TITLE ----- Sets a window title. Syntax: TITLE,,,,<FLAGS> The text is guaranteed to be stripped of control characters (< 0x20). Note that this has the same requirement as POSITION, that the title needs to be stored for newly created windows until a STATE is sent. It is however not guaranteed that a TITLE will be sent before the first STATE. ZCHANGE ------- The window moved in z order. Syntax: ZCHANGE,<SERIAL>,<ID>,<BEHIND>,<FLAGS> The window with the id ID is behind the window with the id BEHIND. If BEHIND is 0, then this window should be brought to the front. The ID window is the window to be moved, while the BEHIND window is only used as a reference. STATE ----- Changes the window's state and/or title. Syntax: STATE,<SERIAL>,<ID>,<STATE>,<FLAGS> State can have one of three values: 0 : "Normal" window. 1 : Minimized. 2 : Maximized. The initial STATE for a window will always be preceeded by one CREATE and one POSITION. Optionally, a TITLE may also be sent before the first STATE. DEBUG ----- Debug output from the server component. Syntax: DEBUG,<SERIAL>,<STRING> Used for debugging. SYNCBEGIN --------- Indicates that a synchronisation has begun. Syntax: SYNCBEGIN,<SERIAL>,<FLAGS> Sent when the server starts a synchronisation. The client should flush all information at this point. SYNCEND ------- Indicates that a synchronisation is complete. Syntac: SYNCEND,<SERIAL>,<FLAGS> Sent when the last message that is part of the synchronisation has been sent. This may be followed by duplicate messages and/or messages referring invalid windows that were queued up during the synchronisation. HELLO ----- Initial message sent by server. Syntax: HELLO,<SERIAL>,<FLAGS> The server starts each connection by sending this message. Normally the client will react by sending a SYNC back to the server. Flags: 0x0001 : This is a reconnect to an existing session. 0x0002 : The desktop is currently hidden (see HIDE). ACK --- Acknowledgement of a request to manipulate a window. Syntax: ACK,<SERIAL>,<ACKSERIAL> Whenever one of the commands POSITION, ZCHANGE, STATE or FOCUS is executed on the server, the server will send an ACK back to the client. The purpose of this is to inform the client of when the operation was actually performed, allowing high latencies in the channel. HIDE ---- The desktop has become hidden on the server. Syntax: HIDE,<SERIAL>,<FLAGS> This message is sent when the desktop on the server is obscured by something that cannot be tracked. The client should remove all windows and display the entire desktop, allowing the user to handle whatever is blocking the view. Note that updates to windows will still be sent as the windows still exist on the server, they are merely not visible. UNHIDE ------ The desktop has been restored on the server. Syntax: UNHIDE,<SERIAL>,<FLAGS> This message is sent some time after a HIDE, indicating that the windowed view has been restored. If the client has dropped all information about windows then it can send a SYNC to re-enumerate them. SETICON ------- Sets an icon for a window. Syntax: SETICON,<SERIAL>,<ID>,<CHUNK>,<FORMAT>,<WIDTH>,<HEIGHT>,<DATA> This message is sent when a window is initially created and at any time when the application modifies its icon. A window can have multiple icons, but only one of a given format and size. A SETICON received for an already existing format and size is expected to over- write that icon. Since icons can potentially be very large, it can easily overflow the line limitation in the protocol. To handle this, multiple SETICON will be issued with an ever increasing chunk number. The initial chunk is 0 (zero) and all chunks must be sent in order. Multiple SETICON sets for the same window may not interleave. SETICON sets for different windows may interleave though. Formats: RGBA : Four bytes of data per pixel, representing red, green, blue and alpha, in that order. Data is the raw icon data written in hex (e.g. 3fab32...). Chunks must be divided on a whole byte boundary. Case is not specified. DELICON ------- Removes an icon for a window. Syntax: DELICON,<SERIAL>,<ID>,<FORMAT>,<WIDTH>,<HEIGHT> Removes the icon of a window matching the given format and size, previously set with SETICON. This command may not be interleaved with a SETICON set. Client to Server Operations =========================== SYNC ---- Request a synchronisation of window information. Syntax: SYNC,<SERIAL>,<FLAGS> For each window, the server will send CREATE, POSITION and STATE, in that order, just as if the window was created. Note that a TITLE may also, optionally, be sent before the STATE. POSITION -------- Identical to the command sent from server to client. TITLE ----- Identical to the command sent from server to client. ZCHANGE ------- Identical to the command sent from server to client. STATE ----- Identical to the command sent from server to client. FOCUS ----- Sets which window has input focus. Syntax: FOCUS,<SERIAL>,<ID>,<FLAGS> Changes which window that will recieve the keyboard events. Note that this might cause the window to change z order. DESTROY ------- Identical to the command sent from server to client. Test Cases ========== A list of test cases is found below. These should be verified before commit, ideally with different window managers (KWin, Metacity, Blackbox, IceWM etc). You can also test without a window manager. 1 Start Wordpad. Verify taskbar icon. 2 Resize Wordpad main window. 3 Open "Open Dialog". Resize, bigger than main window. Verify no additional task bar icons. Verify that the Open dialog is focused. 4 Open File Format box dropdown. Verify that it correctly appears outside main window. Verify no additional task bar icons. 5 Abort Open. Select About Wordpad. Verify no additional task bar icons. Verify that the About dialog is focused. 6 Minimize and restore Wordpad using the WM. Verify that both the Wordpad and About window is minimized and restored, and that the About window ends up in front of Wordpad. This test is known to fail with some WMs. Close the About dialog. 7 Open Wordpad Help. Verify task bar icon. 8 Switch between Help and Wordpad window using a X11 taskbar. 9 In Wordpad, right click at the bottom of the document, and verify that the menu correctly appears outside the main window. Verify no additional task bar icons. 10 Click on the New icon. Select Text Document. Verify that the taskbar icon is updated. 11 Write something. Try the Find dialog (Ctrl-F). Move it outside the main window. Verify no task bar icons. 12 Make Wordpad very small and try to use the menus. 13 Start Internet Explorer. 14 Minimize IE using the IE button. Restore. 15 Minimize IE using the taskbar. Restore. 16 Maximize IE using the IE button. Restore. 17 Maximize IE using the taskbar. Restore. 18 Open an additional IE window and verify you can switch between them. 19 Try the menus in Microsoft Office XP, which uses shaded menus. 20 Test transient windows: Run a program (ie Excel) seamlessly and open a modal dialog (ie Open). Move the dialog so it partially overlaps its parent window. Cover both windows with a third (ie a maximized xterm). Click on Excel's taskbar entry to bring it to the front. 21 Test topmost windows: Run Task Manager seamlessly (...\seamlessrdpshell.exe taskmgr). From Task Manager's File menu, select 'New Task (Run)' and run Notepad. Move Notepad so it partially overlaps Task Manager. Cover both windows with a native window (ie a maximized xterm). Click on Notepad's taskbar entry to bring it to the front. 22 Test X11 window close: Start Notepad and open the Help Browser. Close the Help Browser window on the X11 side using your window manager. Verify that rdesktop still runs and that the Notepad application window still exists. 23 Test window restacking: Run Mozilla Seamonkey and open two separate windows. From the first one, select the other one from the windows menu. Verify that the other window is brought to the front. Test this using both the mouse and the keyboard. 24 Test restacking of a bottom window. For this test, you'll need to the tool "notepadbehindwordpad.exe". Run Task Manager seamlessly. Start Notepad and Wordpad from it. Manually stack the windows as (from top to bottom) Task Manager - Notepad - xterm - Wordpad. Make sure the windows partially overlaps. From Task Manager, execute notepadbehindwordpad.exe. This test is expected to fail when rdesktop emits the warning about broken WM at startup. 25 Test restacking of a middle window. For this test, you'll need to the tool "notepadbehindwordpad.exe". Run Task Manager seamlessly. Start Paint, Notepad, and Wordpad from it. Manually stack the windows as (from top to bottom) Task Manager - Notepad - xterm - Wordpad - Paint. Make sure the windows partially overlaps. From Task Manager, execute notepadbehindwordpad.exe. This test is expected to fail when rdesktop emits the warning about broken WM at startup.