    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Writing a Wayland Server Using Mir</title>
        <link>https://members.accu.org/index.php/articles/2498</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Design of applications and programs + CVu Journal Vol 30, #2 - May 2018</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c67/">Design</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c385/">302</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c67-385/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c67+385/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Writing a Wayland Server Using Mir</h1>
<p><strong>Author:</strong>&nbsp;Bob Schmidt</p>
<p>
<strong>Date:</strong> 06 May 2018 17:39:33 +01:00 or Sun, 06 May 2018 17:39:33 +01:00</p>
<p><strong>Summary:</strong>&nbsp;Alan Griffiths explains the basics of a new X11 replacement API.</p>
<p><strong>Body:</strong>&nbsp;<h2>We need a new windowing system</h2>

<p>The X-Windows system has been, and still is, immensely successful in providing a way to interact with computers. It underlies many desktop environments and graphical user interface toolkits and lets them work together. But it comes from an era when computers were very different from now, and there are real concerns that are hard to meet.</p>

<p>In 1980, computers were big things managed by experts and, maybe, connected to another computer in the same organization. Today a phone is a computer managed by a non-expert, and connected to the Internet. Then, having floating point co-processor was a feature; now, having a graphics co-processor is required.</p>

<p>In 1980, the cost of developing software was such that any benefit to be gained by â€˜listening inâ€™ on what was happening on the same computer was negligible. It wasnâ€™t as though there were billions of computers being used for online banking that would willingly install your program.</p>

<p>Adapting X11 to the new requirements of security and graphics performance isnâ€™t feasible. The open source world has settled on a replacement: Wayland. Wayland is a set of protocols and extension protocols that allow applications (clients) to talk to compositors (servers) without many of the problems inherent in X11.</p>

<p>Most open source desktop environments have been based on the X.Org server implementation and a range of different window managers and compositors. All this needs adapting to work with Wayland.</p>

<p>For example, the Gnome project has been adapting itâ€™s Mutter window manager to support Wayland; KDE has been adapting Kwin; and so on.</p>

<p>I work on another project, Mir, which in addition to being a compositor aims to provide the building blocks of generic window management and independence from the underlying graphics stack.</p>

<p>In this article Iâ€™m going to show you how easy it is to write a Wayland server using Mir.</p>

<h2>Building the code</h2>

<p>The code in this article needs Mir 0.31 or later. This exists in Ubuntu 18.04 and Fedora 28 both unreleased at the time of writing (but due for release before you read this), or from the mir-team/release PPA (See Sidebar).</p>

<p>It is also useful to install the <code>weston</code> package as the example makes use of <code>weston-terminal</code> as a Wayland based terminal application and the Qt toolkitâ€™s Wayland support : <code>qtwayland5</code>.</p>

<p>On Ubuntu use:</p>

<pre class="programlisting">
  $ sudo apt install libmiral-dev mir-graphics-  drivers-desktop weston qtwayland5 g++ cmake</pre>

<p>Or, if using Fedora, use:</p>

<pre class="programlisting">
  $ sudo dnf install mir-devel weston qtwayland5  g++ cmake</pre>
  
<p>The â€˜Mir Abstraction Layerâ€™ (MirAL) presents the server-side functionality in a way that makes it easy to use MirAL. There was an introduction to MirAL in <em>C Vu</em> 28.2.</p>

<p>To illustrate MirAL Iâ€™m going to show what is involved in writing a (very simple) window manager. It runs on desktops, tablets and phones and supports keyboard, mouse and touch input. It will support applications using the GTK and Qt toolkits, SDL2 applications and (using Xwayland X11 applications.</p>

<p>The full code for this example is available on github:</p>

<pre class="programlisting">
  $ git clone https://github.com/AlanGriffiths/  egmde.git
  $ git checkout article-1</pre>
  
<p>Naturally, the code is likely to evolve and inspire additional articles, so you will find other branches, but this branch goes with this article. Assuming that youâ€™ve MirAL installed as described above you can now build egmde as follows:</p>

<pre class="programlisting">
  $ mkdir egmde/build
  $ cd egmde/build
  $ cmake ..
  $ make</pre>
  
<p>After this you can start a basic egmde based desktop. By default this will use VT4, so first switch to VT4 (Ctrl-Alt-F4) to sign in and switch back again. Then type:</p>

<pre class="programlisting">
  $ ./egmde-desktop</pre>

<p>You should see a blank screen with a weston-terminal session. From this you can run commands and, in particular, start graphical applications. Perhaps qtcreator to examine the code?</p>

<p>Thereâ€™s very little code needed to get this basic shell running:</p>

<pre class="programlisting">
  $ wc -l *.h *.cpp *.sh
     88 egwindowmanager.h
     34 egmde.cpp
    420 egwindowmanager.cpp
     47 egmde-desktop.sh
    589 total</pre>

<h2>The example code</h2>

<p>A lot of the functionality (default placement of windows, menus etc.) comes with the MirAL library. For this exercise weâ€™ll implement one class and write a main function that injects it into MirAL. The main program looks like this:</p>

<pre class="programlisting">
  using namespace miral;
  int main(int argc, char const* argv[])
  {
    MirRunner runner{argc, argv};
    return runner.run_with(
      {
        set_window_management_policy&lt;egmde        ::WindowManagerPolicy&gt;()
      });
  }</pre>
  
<p>Most of the logic belonging to egmde is in the <code>egmde::WindowManagerPolicy</code> class. This implements a <code>miral::WindowManagerPolicy</code> interface that allows the window management to be customized. It looks like Listing 1.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
class WindowManagerPolicy : public CanonicalWindowManagerPolicy
{
public:
  using CanonicalWindowManagerPolicy
    ::CanonicalWindowManagerPolicy;
  bool handle_keyboard_event(
    MirKeyboardEvent const* event) override;
  bool handle_pointer_event(
    MirPointerEvent const* event) override;
  bool handle_touch_event(
    MirTouchEvent const* event) override;
  Rectangle confirm_placement_on_display(
    WindowInfo const&amp; window_info,
    MirWindowState new_state,
    Rectangle const&amp; new_placement) override;
  void handle_request_drag_and_drop(
    WindowInfo&amp; window_info) override;
  void handle_request_move(
    WindowInfo&amp; window_info, 
    MirInputEvent const* input_event) override;
  void handle_request_resize(
    WindowInfo&amp; window_info,
    MirInputEvent const* input_event,
    MirResizeEdge edge) override;
  private:
  ...
};
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 1</td>
	</tr>
</table>

<p>These are the functions that it is necessary to implement for a minimal shell. I wonâ€™t reproduce them all here, but Listing 2 should give a flavor.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
bool egmde::WindowManagerPolicy
  ::handle_keyboard_event(
  MirKeyboardEvent const* event)
{
  auto const action =
    mir_keyboard_event_action(event);
  auto const shift_state =
    mir_keyboard_event_modifiers(event) &amp;
    shift_states;
  if (action == mir_keyboard_action_down &amp;&amp;
    shift_state == mir_input_event_modifier_alt)
  {
    switch (mir_keyboard_event_scan_code(event))
    {
      case KEY_F4:
        tools.ask_client_to_close(
          tools.active_window());
        return true;

      case KEY_TAB:
        tools.focus_next_application();
        return true;

      case KEY_GRAVE:
        tools.focus_next_within_application();
        return true;

      default:;
    }
  }
  return false;
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 2</td>
	</tr>
</table>

<h2>The way of the MirAL API</h2>

<p>The MirAL API is designed so that it is easy to implement and run a Mir server and compose any special features. One aspect of this is the provision of building blocks that can be tailored by the developer and â€˜hooked upâ€™ in the <code>main()</code> function by adding them to the <code>run_with()</code> list. One of these is an â€˜internal clientâ€™ â€“ a â€˜clientâ€™ that runs in the server process but can use the client APIs to, for example, draw a surface.</p>

<p>The next iteration of egmde will add an internal client that paints a configurable wallpaper. I wonâ€™t show how that is implemented here, but I will show how it is added to <code>main()</code> program (see Listing 3).</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
int main(int argc, char const* argv[])
{
  MirRunner runner{argc, argv};
  egmde::Wallpaper wallpaper;
  runner.add_stop_callback([&amp;]
    {wallpaper.stop(); });
  return runner.run_with(
    {
      CommandLineOption{
        std::ref(wallpaper),
        &quot;wallpaper&quot;,
        &quot;Colour of wallpaper RGB&quot;,
        &quot;0x92006a&quot;},
      StartupInternalClient{&quot;wallpaper&quot;,
        std::ref(wallpaper)},
      set_window_management_policy
        &lt;egmde::WindowManagerPolicy&gt;()
    });
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 3</td>
	</tr>
</table>

<p>The <code>CommandLineOption</code> utility does a number of things, adds a configuration option to the command line, process the command line, and calls itâ€™s first argument. In this case we pass an instance of <code>egmde::Wallpaper</code> implements the function call operator to accept the wallpaper colour.</p>

<p>The <code>StartupInternalClient</code> utility takes an internal client object, waits for the server to start and then connects the client to the server, notifying the internal client object of both the client-side and server-side connection so that the server â€˜knowsâ€™ which client this is.</p>

<p>By supplying customizations to the <code>run_with()</code> as a list we make it easy to ensure the server is initialized before they are used and give the user flexibility in setting these objects up. For example, the <code>wallpaper</code> instance can be created and used in a a shutdown hook using <code>add_stop_callback()</code> before being used in the <code>run_with()</code> list.</p>

<p>This is achieved by declaring <code>run_with()</code> to take an initializer list:</p>

<pre class="programlisting">
  auto run_with(std::initializer_list
  &lt;std::function&lt;void(::mir::Server&amp;)&gt;&gt; options) 
  -&gt; int;</pre>
  
<p>Each of the supplied utilities â€˜knowsâ€™ how to integrate itself into the system using the <code>mir::Server</code>. User code should not need to do this directly, so part of the MirAL â€˜abstractionâ€™ is to keep this as an opaque type.</p>

<p>This approach has been proven effective by use in more advanced servers such as Unity8.</p>

<h2>The capabilities</h2>

<p>Mir tries to be agnostic about the window management style. There are example shells in the Mir project implementing several styles: â€˜floatingâ€™ windows, â€˜tilingâ€™ windows and fullscreen â€˜kioskâ€™ windows.</p>

<p>Although it was abandoned by Canonical, the Unity8 desktop shell demonstrates the potential of a shell based on Mir.</p>

<p>Mir is also used for Canonicalâ€™s â€˜Internet of Thingsâ€™ kiosk and for the Ubuntu Touch phone operating system.</p>

<h2>The limitations</h2>

<p>Support for Wayland isnâ€™t complete in Mir (nor, to varying extents, other compositors) and it isnâ€™t complete in the toolkits used to write applications. However, the commitment and momentum is there. It will happen soon.</p>

<h2>Conclusion</h2>

<p>If you are interested in experimenting with writing a shell to support Wayland clients then Mir might be an option.</p>

<table class="sidebartable">
	<tr>
		<td class="title">Other ways to get Mir and use for development</td>
	</tr>
	<tr>
		<td>
			<table class="journaltable">
				<tr>
					<td><h3>On other versions of Ubuntu</h3>
						
						<p>If you want to use Mir on earlier supported versions of Ubuntu then it is available from the Mir Release PPA. To add the PPA to your system:</p>
						<pre class="programlisting">
						
  $ sudo add-apt-repository ppa:mir-team/release
  $ sudo apt update</pre>
  
						<p>You can then follow the instructions in the main article. One word of caution though: on Ubuntu 16.04 the toolkit support for Wayland is somewhat dated and the experience is not great. On 17.10 things mostly work.</p>
						
						<p>To remove the PPA from your system:</p>
<pre class="programlisting">
  $ sudo ppa-purge mir-team/release</pre>
  
						<h3>On other versions of Fedora</h3>
						
						<p>Fedora versions 26 and 27 have an earlier version (1.5) of MirAL, that would require a few (simple) changes to the code to get the egmde example code working. More importantly Mirâ€™s support for Wayland in this earlier version is lacking. It is probably best to build your own (see next section).</p>
						
						<h3>Build your own Mir</h3>
						
						<p>There are instuctions for building Mir on the Mir website: <a href="https://mir-server.io/doc/getting_involved_in_mir.html">  https://mir-server.io/doc/getting_involved_in_mir.html</a></p>
						
						<p>To my knowledge these work on Ubuntu 16.04 or later, Fedora 28 or later and Debian sid. (If you try it on other distros please let me know how it works out.)</p>
					</td>
				</tr>
			</table>
		</td>
	</tr>

</table>

<h2>References</h2>

<p class="bibliomixed">egmde: <a href="https://github.com/AlanGriffiths/egmde/wiki">https://github.com/AlanGriffiths/egmde/wiki</a></p>

<p class="bibliomixed">Mir: <a href="https://mir-server.io/">https://mir-server.io/</a></p>

<p class="bibliomixed">Unity8 demo: <a href="https://www.youtube.com/watch?v=LUxVdURZdRk">https://www.youtube.com/watch?v=LUxVdURZdRk</a></p>

<p class="bibliomixed">egmde demo: <a href="https://www.youtube.com/watch?v=e4_SEybCB0M">https://www.youtube.com/watch?v=e4_SEybCB0M</a></p>

<p class="bibliomixed">Unity8 use of MirAL API: <a href="https://github.com/ubports/qtmir/blob/master/src/platforms/mirserver/qmirserver_p.cpp#L91">https://github.com/ubports/qtmir/blob/master/src/platforms/mirserver/qmirserver_p.cpp#L91</a></p>

<p class="bibliomixed">Ubuntu Touch: <a href="https://ubports.com/">https://ubports.com/</a></p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
