For each AppVM, there is a pair of `qubes-gui` (running in AppVM) and `qubes-guid` (running in the AppVM’s GuiVM, dom0 by default) processes connected over vchan.
Note that keyboard and mouse events are passed to AppVM only if a window belonging to this AppVM has focus.
AppVM has no way to get information on keystrokes fed to other AppVMs (e.g. XTEST extension will report the status of local AppVM keyboard only) or synthesize and pass events to other AppVMs.
- in dom0, the Xorg server is started with `LD_PRELOAD`-ed library named `shmoverride.so`. This library hooks all function calls related to shared memory.
-`qubes-guid` creates a shared memory segment, and then tells Xorg to attach it via `MIT-SHM` extension
- when Xorg tries to attach the segment (via glibc `shmat`) `shmoverride.so` intercepts this call and instead maps AppVM memory via `xc_map_foreign_pages` for the deprecated `MFNDUMP` message, or `xengnttab_map_domain_grant_refs` for the `WINDOW_DUMP` message.
- afterwards, we can use MIT-SHM functions, such as `XShmPutImage`, to draw onto a dom0 window. `XShmPutImage` will paint with DRAM speed, and many drivers use DMA to make this even faster.
The important detail is that `xc_map_foreign_pages` verifies that a given mfn range actually belongs to a given domain id (and the latter is provided by trusted `qubes-guid`). Therefore, rogue AppVM cannot gain anything by passing crafted mnfs in the `MFNDUMP` message. Similarly, `xengnttab_map_domain_grant_refs` will only map grants from the specific domain ID specified by qubes-guid, so crafted `WINDOW_DUMP` messages are not helpful to an attacker.
There are two reasons that `WINDOW_DUMP` is preferred over `MFNDUMP`:
1.`xc_map_foreign_pages` can only be used by dom0, as it allows accessing all memory of any VM. Allowing any VM other than dom0 to do this would be a security vulnerability.
2.`xc_map_foreign_pages` requires the guest physical address of the pages to map, but normal userspace processes (such as `qubes-gui` or Xorg) do not have access to that information. Therefore, the translation is done via the `u2mfn` out-of-tree kernel module.
Currently, using `WINDOW_DUMP` does come at a performance cost, because the AppVM’s X server must copy the pages from the application to the gntalloc-allocated memory. This will be solved by future improvements to gntalloc, which will allow exporting *any* page via gntalloc, including memory shared by another process.
It is important that the user knows which AppVM a given window belongs to. This prevents a rogue AppVM from painting a window pretending to belong to other AppVM or dom0 and trying to steal, for example, passwords.
In Qubes, a custom window decorator is used that paints a colourful frame (the colour is determined during AppVM creation) around decorated windows. Additionally, the window title always starts with **[name of the AppVM]**. If a window has an `override_redirect` attribute, meaning that it should not be treated by a window manager (typical case is menu windows), `qubes-guid` draws a two-pixel colourful frame inside it manually.
- if the user wants to copy local AppVM clipboard to qubes clipboard, she must focus on any window belonging to this AppVM, and press **Ctrl-Shift-C**. This combination is trapped by `qubes-guid`, and `CLIPBOARD_REQ` message is sent to AppVM. `qubes-gui` responds with `CLIPBOARD_DATA` message followed by clipboard contents.
- the user focuses on other AppVM window, presses **Ctrl-Shift-V**. This combination is trapped by `qubes-guid`, and `CLIPBOARD_DATA` message followed by qubes clipboard contents is sent to AppVM; `qubes-gui` copies data to the local clipboard, and then user can paste its contents to local applications normally.
The XEvents are handled by the `handle_xevent_eventname` function, and messages are handled by `handle_messagename` function. One should be very careful when altering the actual `select` loop, because both XEvents and vchan messages are buffered, and `select` will not wake for each message.
`qubes-guid` writes debugging information to `/var/log/qubes/qubes.domain_id.log` file; `qubes-gui` writes debugging information to `/var/log/qubes/gui_agent.log`.
The `override_redirect` window attribute is explained at [Override Redirect Flag](https://tronche.com/gui/x/xlib/window/attributes/override-redirect.html). The `transient_for` attribute is explained at [`transient_for` attribute](https://tronche.com/gui/x/icccm/sec-4.html#WM_TRANSIENT_FOR).
Window manager hints and flags are described in the [Extended Window Manager Hints (EWMH) spec](https://standards.freedesktop.org/wm-spec/latest/), especially under the `_NET_WM_STATE` section.
The "num_mfn" 32bit integers follow the shm_cmd structure; "off" is the offset of the composite buffer start in the first frame; "shmid" and "domid" parameters are just placeholders (to be filled by `qubes-guid`), so that we can use the same structure when talking to `shmoverride.so`.
<td>Update cursor pointer for a window. Supported cursor IDs are default cursor (0) and <ahref="https://tronche.com/gui/x/xlib/appendix/b/">X Font cursors</a> (with 0x100 bit set).</td>