Mir

Merge lp:~mir-team/mir/x11-multi-window into lp:mir

Proposed by Nick Dedekind
Status: Work in progress
Proposed branch: lp:~mir-team/mir/x11-multi-window
Merge into: lp:mir
Diff against target: 708 lines (+210/-89)
10 files modified
src/platforms/mesa/server/x11/graphics/display.cpp (+81/-44)
src/platforms/mesa/server/x11/graphics/display.h (+15/-5)
src/platforms/mesa/server/x11/graphics/display_buffer.cpp (+13/-5)
src/platforms/mesa/server/x11/graphics/display_buffer.h (+6/-2)
src/platforms/mesa/server/x11/graphics/display_configuration.cpp (+26/-17)
src/platforms/mesa/server/x11/graphics/display_configuration.h (+8/-8)
src/platforms/mesa/server/x11/graphics/graphics.cpp (+8/-0)
src/platforms/mesa/server/x11/graphics/platform.cpp (+4/-3)
src/platforms/mesa/server/x11/graphics/platform.h (+2/-0)
src/platforms/mesa/server/x11/input/input_platform.cpp (+47/-5)
To merge this branch: bzr merge lp:~mir-team/mir/x11-multi-window
Reviewer Review Type Date Requested Status
Mir development team Pending
Review via email: mp+317439@code.launchpad.net

Commit message

Added support for multiple x11 windows

To post a comment you must log in.

Unmerged revisions

4037. By Nick Dedekind

Multiple window support

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/platforms/mesa/server/x11/graphics/display.cpp'
--- src/platforms/mesa/server/x11/graphics/display.cpp 2017-02-15 07:38:33 +0000
+++ src/platforms/mesa/server/x11/graphics/display.cpp 2017-02-16 10:45:38 +0000
@@ -18,12 +18,12 @@
1818
19#include "mir/graphics/platform.h"19#include "mir/graphics/platform.h"
20#include "mir/graphics/display_report.h"20#include "mir/graphics/display_report.h"
21#include "mir/graphics/display_configuration_policy.h"
21#include "mir/graphics/egl_error.h"22#include "mir/graphics/egl_error.h"
22#include "mir/graphics/virtual_output.h"23#include "mir/graphics/virtual_output.h"
23#include "mir/renderer/gl/context.h"24#include "mir/renderer/gl/context.h"
24#include "mir/graphics/gl_config.h"25#include "mir/graphics/gl_config.h"
25#include "mir/graphics/atomic_frame.h"26#include "mir/graphics/atomic_frame.h"
26#include "display_configuration.h"
27#include "display.h"27#include "display.h"
28#include "display_buffer.h"28#include "display_buffer.h"
2929
@@ -107,7 +107,7 @@
107107
108mgx::X11Window::X11Window(::Display* x_dpy,108mgx::X11Window::X11Window(::Display* x_dpy,
109 EGLDisplay egl_dpy,109 EGLDisplay egl_dpy,
110 geom::Size const size,110 geom::Rectangle const& geometry,
111 EGLConfig const egl_cfg)111 EGLConfig const egl_cfg)
112 : x_dpy{x_dpy}112 : x_dpy{x_dpy}
113{113{
@@ -157,7 +157,7 @@
157 auto mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;157 auto mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
158158
159 win = XCreateWindow(x_dpy, root, 0, 0,159 win = XCreateWindow(x_dpy, root, 0, 0,
160 size.width.as_int(), size.height.as_int(),160 geometry.size.width.as_int(), geometry.size.height.as_int(),
161 0, visInfo->depth, InputOutput,161 0, visInfo->depth, InputOutput,
162 visInfo->visual, mask, &attr);162 visInfo->visual, mask, &attr);
163163
@@ -170,12 +170,12 @@
170 // TODO: Due to a bug, resize doesn't work after XGrabKeyboard under Unity.170 // TODO: Due to a bug, resize doesn't work after XGrabKeyboard under Unity.
171 // For now, make window unresizeable.171 // For now, make window unresizeable.
172 // http://stackoverflow.com/questions/14555703/x11-unable-to-move-window-after-xgrabkeyboard172 // http://stackoverflow.com/questions/14555703/x11-unable-to-move-window-after-xgrabkeyboard
173 sizehints.base_width = size.width.as_int();173 sizehints.base_width = geometry.size.width.as_int();
174 sizehints.base_height = size.height.as_int();174 sizehints.base_height = geometry.size.height.as_int();
175 sizehints.min_width = size.width.as_int();175 sizehints.min_width = geometry.size.width.as_int();
176 sizehints.min_height = size.height.as_int();176 sizehints.min_height = geometry.size.height.as_int();
177 sizehints.max_width = size.width.as_int();177 sizehints.max_width = geometry.size.width.as_int();
178 sizehints.max_height = size.height.as_int();178 sizehints.max_height = geometry.size.height.as_int();
179 sizehints.flags = PSize | PMinSize | PMaxSize;179 sizehints.flags = PSize | PMinSize | PMaxSize;
180180
181 XSetNormalHints(x_dpy, win, &sizehints);181 XSetNormalHints(x_dpy, win, &sizehints);
@@ -198,12 +198,16 @@
198198
199 Atom wmDeleteMessage = XInternAtom(x_dpy, "WM_DELETE_WINDOW", False);199 Atom wmDeleteMessage = XInternAtom(x_dpy, "WM_DELETE_WINDOW", False);
200 XSetWMProtocols(x_dpy, win, &wmDeleteMessage, 1);200 XSetWMProtocols(x_dpy, win, &wmDeleteMessage, 1);
201
202 wmLogicalPosition = XInternAtom(x_dpy, "WM_LOGICAL_POSITION", False);
203 XPoint pt{(short)geometry.top_left.x.as_int(), (short)geometry.top_left.y.as_int()};
204 XChangeProperty(x_dpy, win, wmLogicalPosition, XA_POINT, 16, PropModeReplace, (unsigned char *) &pt, 2);
201 }205 }
202206
203 XMapWindow(x_dpy, win);207 XMapWindow(x_dpy, win);
204208
205 XEvent xev;209 XEvent xev;
206 do 210 do
207 {211 {
208 XNextEvent(x_dpy, &xev);212 XNextEvent(x_dpy, &xev);
209 }213 }
@@ -225,8 +229,16 @@
225 return r_mask;229 return r_mask;
226}230}
227231
232void mgx::X11Window::set_geometry(mir::geometry::Rectangle const& geometry)
233{
234 XPoint pt{(short)geometry.top_left.x.as_int(), (short)geometry.top_left.y.as_int()};
235 XChangeProperty(x_dpy, win, wmLogicalPosition, XA_POINT, 16, PropModeReplace, (unsigned char *) &pt, 2);
236}
237
228mgx::Display::Display(::Display* x_dpy,238mgx::Display::Display(::Display* x_dpy,
239 uint requested_output_count,
229 geom::Size const requested_size,240 geom::Size const requested_size,
241 std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy,
230 std::shared_ptr<GLConfig> const& gl_config,242 std::shared_ptr<GLConfig> const& gl_config,
231 std::shared_ptr<DisplayReport> const& report)243 std::shared_ptr<DisplayReport> const& report)
232 : shared_egl{*gl_config},244 : shared_egl{*gl_config},
@@ -235,50 +247,63 @@
235 gl_config{gl_config},247 gl_config{gl_config},
236 pixel_width{get_pixel_width(x_dpy)},248 pixel_width{get_pixel_width(x_dpy)},
237 pixel_height{get_pixel_height(x_dpy)},249 pixel_height{get_pixel_height(x_dpy)},
238 scale{1.0f},
239 report{report},250 report{report},
240 orientation{mir_orientation_normal},
241 last_frame{std::make_shared<AtomicFrame>()}251 last_frame{std::make_shared<AtomicFrame>()}
242{252{
243 shared_egl.setup(x_dpy);253 shared_egl.setup(x_dpy);
244254
245 win = std::make_unique<X11Window>(x_dpy,255 for (uint i = 0; i < requested_output_count; i++) {
246 shared_egl.display(),256 auto win = std::make_unique<X11Window>(x_dpy,
247 actual_size,257 shared_egl.display(),
248 shared_egl.config());258 geom::Rectangle{{0,0}, actual_size},
249259 shared_egl.config());
250 auto red_mask = win->red_mask();260
251 pf = (red_mask == 0xFF0000 ? mir_pixel_format_argb_8888261 auto red_mask = win->red_mask();
252 : mir_pixel_format_abgr_8888);262 pf = (red_mask == 0xFF0000 ? mir_pixel_format_argb_8888
253263 : mir_pixel_format_abgr_8888);
254 display_buffer = std::make_unique<mgx::DisplayBuffer>(264
255 x_dpy,265 auto output_id = display_configuration.add_output(pf,
256 *win,266 actual_size,
257 actual_size,267 geom::Size{actual_size.width * pixel_width, actual_size.height * pixel_height},
258 shared_egl.context(),268 1.0f,
259 last_frame,269 mir_orientation_normal);
260 report,270
261 orientation,271 auto display_buffer = std::make_unique<mgx::DisplayBuffer>(x_dpy,
262 *gl_config);272 *win,
263273 geom::Rectangle{{0,0}, actual_size},
274 shared_egl.context(),
275 last_frame,
276 report,
277 mir_orientation_normal,
278 output_id,
279 *gl_config);
280
281 outputs.insert({ output_id, new OutputWindow{std::move(win), std::move(display_buffer)} });
282 }
264 shared_egl.make_current();283 shared_egl.make_current();
265284
285 initial_conf_policy->apply_to(display_configuration);
286 configure(display_configuration);
287
266 report->report_successful_display_construction();288 report->report_successful_display_construction();
267}289}
268290
269mgx::Display::~Display() noexcept291mgx::Display::~Display() noexcept
270{292{
293 for (auto output: outputs) {
294 delete output.second;
295 }
271}296}
272297
273void mgx::Display::for_each_display_sync_group(std::function<void(mg::DisplaySyncGroup&)> const& f)298void mgx::Display::for_each_display_sync_group(std::function<void(mg::DisplaySyncGroup&)> const& f)
274{299{
275 f(*display_buffer);300 for (const auto& output : outputs)
301 f(*(output.second->display_buffer));
276}302}
277303
278std::unique_ptr<mg::DisplayConfiguration> mgx::Display::configuration() const304std::unique_ptr<mg::DisplayConfiguration> mgx::Display::configuration() const
279{305{
280 return std::make_unique<mgx::DisplayConfiguration>(306 return display_configuration.clone();
281 pf, actual_size, geom::Size{actual_size.width * pixel_width, actual_size.height * pixel_height}, scale, orientation);
282}307}
283308
284void mgx::Display::configure(mg::DisplayConfiguration const& new_configuration)309void mgx::Display::configure(mg::DisplayConfiguration const& new_configuration)
@@ -289,18 +314,30 @@
289 std::logic_error("Invalid or inconsistent display configuration"));314 std::logic_error("Invalid or inconsistent display configuration"));
290 }315 }
291316
292 MirOrientation o = mir_orientation_normal;317 new_configuration.for_each_output([&](DisplayConfigurationOutput const& new_conf_output)
293 float new_scale = scale;
294
295 new_configuration.for_each_output([&](DisplayConfigurationOutput const& conf_output)
296 {318 {
297 o = conf_output.orientation;319 display_configuration.for_each_output([&](UserDisplayConfigurationOutput& current_conf_output)
298 new_scale = conf_output.scale;320 {
321 if (current_conf_output.id == new_conf_output.id) {
322
323 current_conf_output.scale = new_conf_output.scale;
324 current_conf_output.orientation = new_conf_output.orientation;
325 current_conf_output.top_left = new_conf_output.top_left;
326 current_conf_output.used = new_conf_output.used;
327 current_conf_output.power_mode = new_conf_output.power_mode;
328 current_conf_output.form_factor = new_conf_output.form_factor;
329 // TODO - current_mode_index for sizing.
330
331 auto search = outputs.find(new_conf_output.id);
332 if(search != outputs.end()) {
333 auto output = search->second;
334 output->display_buffer->set_orientation(new_conf_output.orientation);
335 output->display_buffer->set_geometry(new_conf_output.extents());
336 output->win->set_geometry(new_conf_output.extents());
337 }
338 }
339 });
299 });340 });
300
301 orientation = o;
302 display_buffer->set_orientation(orientation);
303 scale = new_scale;
304}341}
305342
306void mgx::Display::register_configuration_change_handler(343void mgx::Display::register_configuration_change_handler(
307344
=== modified file 'src/platforms/mesa/server/x11/graphics/display.h'
--- src/platforms/mesa/server/x11/graphics/display.h 2017-02-15 07:38:33 +0000
+++ src/platforms/mesa/server/x11/graphics/display.h 2017-02-16 10:45:38 +0000
@@ -24,12 +24,14 @@
24#include "mir/renderer/gl/context_source.h"24#include "mir/renderer/gl/context_source.h"
25#include "mir_toolkit/common.h"25#include "mir_toolkit/common.h"
26#include "egl_helper.h"26#include "egl_helper.h"
27#include "display_configuration.h"
2728
28#include <X11/Xlib.h>29#include <X11/Xlib.h>
29#include <X11/Xutil.h>30#include <X11/Xutil.h>
30#include <EGL/egl.h>31#include <EGL/egl.h>
3132
32#include <memory>33#include <memory>
34#include <unordered_map>
3335
34namespace mir36namespace mir
35{37{
@@ -39,6 +41,7 @@
39class AtomicFrame;41class AtomicFrame;
40class GLConfig;42class GLConfig;
41class DisplayReport;43class DisplayReport;
44class DisplayConfigurationPolicy;
4245
43namespace X46namespace X
44{47{
@@ -50,15 +53,18 @@
50public:53public:
51 X11Window(::Display* const x_dpy,54 X11Window(::Display* const x_dpy,
52 EGLDisplay egl_dpy,55 EGLDisplay egl_dpy,
53 geometry::Size const size,56 mir::geometry::Rectangle const& geometry,
54 EGLConfig const egl_cfg);57 EGLConfig const egl_cfg);
55 ~X11Window();58 ~X11Window();
5659
57 operator Window() const;60 operator Window() const;
58 unsigned long red_mask() const;61 unsigned long red_mask() const;
5962
63 void set_geometry(mir::geometry::Rectangle const& geometry);
64
60private:65private:
61 ::Display* const x_dpy;66 ::Display* const x_dpy;
67 ::Atom wmLogicalPosition;
62 Window win;68 Window win;
63 unsigned long r_mask;69 unsigned long r_mask;
64};70};
@@ -69,7 +75,9 @@
69{75{
70public:76public:
71 explicit Display(::Display* x_dpy,77 explicit Display(::Display* x_dpy,
78 uint requested_output_count,
72 geometry::Size const requested_size,79 geometry::Size const requested_size,
80 std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy,
73 std::shared_ptr<GLConfig> const& gl_config,81 std::shared_ptr<GLConfig> const& gl_config,
74 std::shared_ptr<DisplayReport> const& report);82 std::shared_ptr<DisplayReport> const& report);
75 ~Display() noexcept;83 ~Display() noexcept;
@@ -110,13 +118,15 @@
110 std::shared_ptr<GLConfig> const gl_config;118 std::shared_ptr<GLConfig> const gl_config;
111 float pixel_width;119 float pixel_width;
112 float pixel_height;120 float pixel_height;
113 float scale;
114 std::unique_ptr<X11Window> win;
115 MirPixelFormat pf;121 MirPixelFormat pf;
116 std::shared_ptr<DisplayReport> const report;122 std::shared_ptr<DisplayReport> const report;
117 MirOrientation orientation; //TODO: keep entire current display configuration
118 std::shared_ptr<AtomicFrame> last_frame;123 std::shared_ptr<AtomicFrame> last_frame;
119 std::unique_ptr<DisplayBuffer> display_buffer;124 struct OutputWindow {
125 std::unique_ptr<X11Window> win;
126 std::unique_ptr<DisplayBuffer> display_buffer;
127 };
128 std::unordered_map<DisplayConfigurationOutputId, OutputWindow*> outputs;
129 DisplayConfiguration display_configuration;
120};130};
121131
122}132}
123133
=== modified file 'src/platforms/mesa/server/x11/graphics/display_buffer.cpp'
--- src/platforms/mesa/server/x11/graphics/display_buffer.cpp 2017-01-30 06:36:29 +0000
+++ src/platforms/mesa/server/x11/graphics/display_buffer.cpp 2017-02-16 10:45:38 +0000
@@ -31,16 +31,18 @@
3131
32mgx::DisplayBuffer::DisplayBuffer(::Display* const x_dpy,32mgx::DisplayBuffer::DisplayBuffer(::Display* const x_dpy,
33 Window const win,33 Window const win,
34 geom::Size const sz,34 geometry::Rectangle const geo,
35 EGLContext const shared_context,35 EGLContext const shared_context,
36 std::shared_ptr<AtomicFrame> const& f,36 std::shared_ptr<AtomicFrame> const& f,
37 std::shared_ptr<DisplayReport> const& r,37 std::shared_ptr<DisplayReport> const& r,
38 MirOrientation const o,38 MirOrientation const o,
39 DisplayConfigurationOutputId const output_id,
39 GLConfig const& gl_config)40 GLConfig const& gl_config)
40 : size{sz},41 : geometry{geo},
41 report{r},42 report{r},
42 orientation_{o},43 orientation_{o},
43 transform{mg::transformation(o)},44 transform{mg::transformation(o)},
45 output_id_(output_id),
44 egl{gl_config},46 egl{gl_config},
45 last_frame{f},47 last_frame{f},
46 eglGetSyncValues{nullptr}48 eglGetSyncValues{nullptr}
@@ -89,9 +91,9 @@
89 {91 {
90 case mir_orientation_left:92 case mir_orientation_left:
91 case mir_orientation_right:93 case mir_orientation_right:
92 return {{0,0}, {size.height.as_int(), size.width.as_int()}};94 return {geometry.top_left, {geometry.size.height.as_int(), geometry.size.width.as_int()}};
93 default:95 default:
94 return {{0,0}, size};96 return geometry;
95 }97 }
96}98}
9799
@@ -146,7 +148,7 @@
146 * but this is best-effort. And besides, we don't want Mir reporting all148 * but this is best-effort. And besides, we don't want Mir reporting all
147 * real vsyncs because that would mean the compositor never sleeps.149 * real vsyncs because that would mean the compositor never sleeps.
148 */150 */
149 report->report_vsync(mgx::DisplayConfiguration::the_output_id.as_value(),151 report->report_vsync(output_id_.as_value(),
150 last_frame->load());152 last_frame->load());
151}153}
152154
@@ -165,6 +167,12 @@
165 transform = mg::transformation(orientation_);167 transform = mg::transformation(orientation_);
166}168}
167169
170void mgx::DisplayBuffer::set_geometry(geom::Rectangle const geo)
171{
172 // TODO - resize the window.
173 geometry.top_left = geo.top_left;
174}
175
168mg::NativeDisplayBuffer* mgx::DisplayBuffer::native_display_buffer()176mg::NativeDisplayBuffer* mgx::DisplayBuffer::native_display_buffer()
169{177{
170 return this;178 return this;
171179
=== modified file 'src/platforms/mesa/server/x11/graphics/display_buffer.h'
--- src/platforms/mesa/server/x11/graphics/display_buffer.h 2017-01-30 06:36:29 +0000
+++ src/platforms/mesa/server/x11/graphics/display_buffer.h 2017-02-16 10:45:38 +0000
@@ -22,6 +22,7 @@
2222
23#include "mir/graphics/display_buffer.h"23#include "mir/graphics/display_buffer.h"
24#include "mir/graphics/display.h"24#include "mir/graphics/display.h"
25#include "mir/graphics/display_configuration.h"
25#include "mir/renderer/gl/render_target.h"26#include "mir/renderer/gl/render_target.h"
26#include "egl_helper.h"27#include "egl_helper.h"
2728
@@ -49,11 +50,12 @@
49 DisplayBuffer(50 DisplayBuffer(
50 ::Display* const x_dpy,51 ::Display* const x_dpy,
51 Window const win,52 Window const win,
52 geometry::Size const sz,53 geometry::Rectangle const geometry,
53 EGLContext const shared_context,54 EGLContext const shared_context,
54 std::shared_ptr<AtomicFrame> const& f,55 std::shared_ptr<AtomicFrame> const& f,
55 std::shared_ptr<DisplayReport> const& r,56 std::shared_ptr<DisplayReport> const& r,
56 MirOrientation const o,57 MirOrientation const o,
58 DisplayConfigurationOutputId const output_id,
57 GLConfig const& gl_config);59 GLConfig const& gl_config);
5860
59 geometry::Rectangle view_area() const override;61 geometry::Rectangle view_area() const override;
@@ -63,6 +65,7 @@
63 void bind() override;65 void bind() override;
64 bool overlay(RenderableList const& renderlist) override;66 bool overlay(RenderableList const& renderlist) override;
65 void set_orientation(MirOrientation const new_orientation);67 void set_orientation(MirOrientation const new_orientation);
68 void set_geometry(geometry::Rectangle const geometry);
6669
67 void for_each_display_buffer(70 void for_each_display_buffer(
68 std::function<void(graphics::DisplayBuffer&)> const& f) override;71 std::function<void(graphics::DisplayBuffer&)> const& f) override;
@@ -73,10 +76,11 @@
73 NativeDisplayBuffer* native_display_buffer() override;76 NativeDisplayBuffer* native_display_buffer() override;
7477
75private:78private:
76 geometry::Size const size;79 geometry::Rectangle geometry;
77 std::shared_ptr<DisplayReport> const report;80 std::shared_ptr<DisplayReport> const report;
78 MirOrientation orientation_;81 MirOrientation orientation_;
79 glm::mat2 transform;82 glm::mat2 transform;
83 DisplayConfigurationOutputId const output_id_;
80 helpers::EGLHelper egl;84 helpers::EGLHelper egl;
81 std::shared_ptr<AtomicFrame> const last_frame;85 std::shared_ptr<AtomicFrame> const last_frame;
8286
8387
=== modified file 'src/platforms/mesa/server/x11/graphics/display_configuration.cpp'
--- src/platforms/mesa/server/x11/graphics/display_configuration.cpp 2017-01-18 02:29:37 +0000
+++ src/platforms/mesa/server/x11/graphics/display_configuration.cpp 2017-02-16 10:45:38 +0000
@@ -24,11 +24,23 @@
24namespace mgx = mg::X;24namespace mgx = mg::X;
25namespace geom = mir::geometry;25namespace geom = mir::geometry;
2626
27mg::DisplayConfigurationOutputId const mgx::DisplayConfiguration::the_output_id{1};27mgx::DisplayConfiguration::DisplayConfiguration() :
2828 card{mg::DisplayConfigurationCardId{0}, 1}
29mgx::DisplayConfiguration::DisplayConfiguration(MirPixelFormat pf, geom::Size const pixels, geom::Size const size, const float scale, MirOrientation orientation) :29{
30 configuration{30}
31 the_output_id,31
32mgx::DisplayConfiguration::DisplayConfiguration(DisplayConfiguration const& other)
33 : mg::DisplayConfiguration(),
34 outputs(other.outputs),
35 card(other.card)
36{
37}
38
39mg::DisplayConfigurationOutputId mgx::DisplayConfiguration::add_output(MirPixelFormat pf, geom::Size const pixels, geom::Size const size, const float scale, MirOrientation orientation)
40{
41 static int output_id = 1;
42 DisplayConfigurationOutput output{
43 mg::DisplayConfigurationOutputId(output_id++),
32 mg::DisplayConfigurationCardId{0},44 mg::DisplayConfigurationCardId{0},
33 mg::DisplayConfigurationOutputType::unknown,45 mg::DisplayConfigurationOutputType::unknown,
34 {pf},46 {pf},
@@ -48,16 +60,10 @@
48 mir_subpixel_arrangement_unknown,60 mir_subpixel_arrangement_unknown,
49 {},61 {},
50 mir_output_gamma_unsupported,62 mir_output_gamma_unsupported,
51 {}},63 {}};
52 card{mg::DisplayConfigurationCardId{0}, 1}64 outputs.push_back(output);
53{
54}
5565
56mgx::DisplayConfiguration::DisplayConfiguration(DisplayConfiguration const& other)66 return output.id;
57 : mg::DisplayConfiguration(),
58 configuration(other.configuration),
59 card(other.card)
60{
61}67}
6268
63void mgx::DisplayConfiguration::for_each_card(std::function<void(mg::DisplayConfigurationCard const&)> f) const69void mgx::DisplayConfiguration::for_each_card(std::function<void(mg::DisplayConfigurationCard const&)> f) const
@@ -67,13 +73,16 @@
6773
68void mgx::DisplayConfiguration::for_each_output(std::function<void(mg::DisplayConfigurationOutput const&)> f) const74void mgx::DisplayConfiguration::for_each_output(std::function<void(mg::DisplayConfigurationOutput const&)> f) const
69{75{
70 f(configuration);76 for (auto& output : outputs)
77 f(output);
71}78}
7279
73void mgx::DisplayConfiguration::for_each_output(std::function<void(mg::UserDisplayConfigurationOutput&)> f)80void mgx::DisplayConfiguration::for_each_output(std::function<void(mg::UserDisplayConfigurationOutput&)> f)
74{81{
75 mg::UserDisplayConfigurationOutput user(configuration);82 for (auto& output : outputs) {
76 f(user);83 mg::UserDisplayConfigurationOutput user(output);
84 f(user);
85 }
77}86}
7887
79std::unique_ptr<mg::DisplayConfiguration> mgx::DisplayConfiguration::clone() const88std::unique_ptr<mg::DisplayConfiguration> mgx::DisplayConfiguration::clone() const
8089
=== modified file 'src/platforms/mesa/server/x11/graphics/display_configuration.h'
--- src/platforms/mesa/server/x11/graphics/display_configuration.h 2017-01-18 02:29:37 +0000
+++ src/platforms/mesa/server/x11/graphics/display_configuration.h 2017-02-16 10:45:38 +0000
@@ -33,24 +33,24 @@
33class DisplayConfiguration : public graphics::DisplayConfiguration33class DisplayConfiguration : public graphics::DisplayConfiguration
34{34{
35public:35public:
36 DisplayConfiguration(MirPixelFormat pf,36 DisplayConfiguration();
37 mir::geometry::Size const pixels,
38 mir::geometry::Size const size_mm,
39 float const scale,
40 MirOrientation orientation);
41 DisplayConfiguration(DisplayConfiguration const&);37 DisplayConfiguration(DisplayConfiguration const&);
4238
43 virtual ~DisplayConfiguration() = default;39 virtual ~DisplayConfiguration() = default;
4440
41 DisplayConfigurationOutputId add_output(MirPixelFormat pf,
42 mir::geometry::Size const pixels,
43 mir::geometry::Size const size,
44 const float scale,
45 MirOrientation orientation);
46
45 void for_each_card(std::function<void(DisplayConfigurationCard const&)> f) const override;47 void for_each_card(std::function<void(DisplayConfigurationCard const&)> f) const override;
46 void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const override;48 void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const override;
47 void for_each_output(std::function<void(UserDisplayConfigurationOutput&)> f) override;49 void for_each_output(std::function<void(UserDisplayConfigurationOutput&)> f) override;
48 std::unique_ptr<graphics::DisplayConfiguration> clone() const override;50 std::unique_ptr<graphics::DisplayConfiguration> clone() const override;
4951
50 static DisplayConfigurationOutputId const the_output_id;
51
52private:52private:
53 DisplayConfigurationOutput configuration;53 std::vector<DisplayConfigurationOutput> outputs;
54 DisplayConfigurationCard card;54 DisplayConfigurationCard card;
55};55};
5656
5757
=== modified file 'src/platforms/mesa/server/x11/graphics/graphics.cpp'
--- src/platforms/mesa/server/x11/graphics/graphics.cpp 2017-01-18 02:29:37 +0000
+++ src/platforms/mesa/server/x11/graphics/graphics.cpp 2017-02-16 10:45:38 +0000
@@ -38,6 +38,7 @@
38namespace38namespace
39{39{
40char const* x11_displays_option_name{"x11-displays"};40char const* x11_displays_option_name{"x11-displays"};
41char const* x11_output_count_option_name{"x11-output-count"};
41}42}
4243
43mir::UniqueModulePtr<mg::Platform> create_host_platform(44mir::UniqueModulePtr<mg::Platform> create_host_platform(
@@ -55,8 +56,11 @@
55 if (pos == std::string::npos)56 if (pos == std::string::npos)
56 BOOST_THROW_EXCEPTION(std::runtime_error("Malformed display size option"));57 BOOST_THROW_EXCEPTION(std::runtime_error("Malformed display size option"));
5758
59 auto output_count = options->get<uint>(x11_output_count_option_name);
60
58 return mir::make_module_ptr<mgx::Platform>(61 return mir::make_module_ptr<mgx::Platform>(
59 x11_resources.get_conn(),62 x11_resources.get_conn(),
63 output_count,
60 geom::Size{std::stoi(display_dims_str.substr(0, pos)),64 geom::Size{std::stoi(display_dims_str.substr(0, pos)),
61 std::stoi(display_dims_str.substr(pos+1, display_dims_str.find(':')))},65 std::stoi(display_dims_str.substr(pos+1, display_dims_str.find(':')))},
62 report66 report
@@ -78,6 +82,10 @@
78 (x11_displays_option_name,82 (x11_displays_option_name,
79 boost::program_options::value<std::string>()->default_value("1280x1024"),83 boost::program_options::value<std::string>()->default_value("1280x1024"),
80 "[mir-on-X specific] WIDTHxHEIGHT of \"display\" window.");84 "[mir-on-X specific] WIDTHxHEIGHT of \"display\" window.");
85 config.add_options()
86 (x11_output_count_option_name,
87 boost::program_options::value<uint>()->default_value(1),
88 "[mir-on-X specific] NUMBER of outputs.");
81}89}
8290
83mg::PlatformPriority probe_graphics_platform(mo::ProgramOption const& /*options*/)91mg::PlatformPriority probe_graphics_platform(mo::ProgramOption const& /*options*/)
8492
=== modified file 'src/platforms/mesa/server/x11/graphics/platform.cpp'
--- src/platforms/mesa/server/x11/graphics/platform.cpp 2017-01-18 02:29:37 +0000
+++ src/platforms/mesa/server/x11/graphics/platform.cpp 2017-02-16 10:45:38 +0000
@@ -27,12 +27,14 @@
27namespace geom = mir::geometry;27namespace geom = mir::geometry;
2828
29mgx::Platform::Platform(std::shared_ptr<::Display> const& conn,29mgx::Platform::Platform(std::shared_ptr<::Display> const& conn,
30 uint output_count,
30 geom::Size const size,31 geom::Size const size,
31 std::shared_ptr<mg::DisplayReport> const& report)32 std::shared_ptr<mg::DisplayReport> const& report)
32 : x11_connection{conn},33 : x11_connection{conn},
33 udev{std::make_shared<mir::udev::Context>()},34 udev{std::make_shared<mir::udev::Context>()},
34 drm{std::make_shared<mesa::helpers::DRMHelper>(mesa::helpers::DRMNodeToUse::render)},35 drm{std::make_shared<mesa::helpers::DRMHelper>(mesa::helpers::DRMNodeToUse::render)},
35 report{report},36 report{report},
37 output_count{output_count},
36 size{size}38 size{size}
37{39{
38 if (!x11_connection)40 if (!x11_connection)
@@ -48,11 +50,10 @@
48}50}
4951
50mir::UniqueModulePtr<mg::Display> mgx::Platform::create_display(52mir::UniqueModulePtr<mg::Display> mgx::Platform::create_display(
51 std::shared_ptr<DisplayConfigurationPolicy> const& /*initial_conf_policy*/,53 std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy,
52 std::shared_ptr<GLConfig> const& gl_config)54 std::shared_ptr<GLConfig> const& gl_config)
53{55{
54 return make_module_ptr<mgx::Display>(x11_connection.get(), size, gl_config,56 return make_module_ptr<mgx::Display>(x11_connection.get(), output_count, size, initial_conf_policy, gl_config, report);
55 report);
56}57}
5758
58mir::UniqueModulePtr<mg::PlatformIpcOperations> mgx::Platform::make_ipc_operations() const59mir::UniqueModulePtr<mg::PlatformIpcOperations> mgx::Platform::make_ipc_operations() const
5960
=== modified file 'src/platforms/mesa/server/x11/graphics/platform.h'
--- src/platforms/mesa/server/x11/graphics/platform.h 2017-01-18 02:29:37 +0000
+++ src/platforms/mesa/server/x11/graphics/platform.h 2017-02-16 10:45:38 +0000
@@ -38,6 +38,7 @@
38{38{
39public:39public:
40 explicit Platform(std::shared_ptr<::Display> const& conn,40 explicit Platform(std::shared_ptr<::Display> const& conn,
41 uint output_count,
41 mir::geometry::Size const size,42 mir::geometry::Size const size,
42 std::shared_ptr<DisplayReport> const& report);43 std::shared_ptr<DisplayReport> const& report);
43 ~Platform() = default;44 ~Platform() = default;
@@ -57,6 +58,7 @@
57 std::shared_ptr<mesa::helpers::DRMHelper> const drm;58 std::shared_ptr<mesa::helpers::DRMHelper> const drm;
58 std::shared_ptr<DisplayReport> const report;59 std::shared_ptr<DisplayReport> const report;
59 mesa::helpers::GBMHelper gbm;60 mesa::helpers::GBMHelper gbm;
61 uint output_count;
60 mir::geometry::Size const size;62 mir::geometry::Size const size;
61};63};
6264
6365
=== modified file 'src/platforms/mesa/server/x11/input/input_platform.cpp'
--- src/platforms/mesa/server/x11/input/input_platform.cpp 2017-02-15 07:38:33 +0000
+++ src/platforms/mesa/server/x11/input/input_platform.cpp 2017-02-16 10:45:38 +0000
@@ -28,6 +28,7 @@
2828
29#include <X11/Xutil.h>29#include <X11/Xutil.h>
30#include <X11/Xlib.h>30#include <X11/Xlib.h>
31#include <X11/Xatom.h>
31#include <linux/input.h>32#include <linux/input.h>
32#include <inttypes.h>33#include <inttypes.h>
33#include <signal.h>34#include <signal.h>
@@ -39,7 +40,7 @@
3940
40// Due to a bug in Unity when keyboard is grabbed,41// Due to a bug in Unity when keyboard is grabbed,
41// client cannot be resized. This helps in debugging.42// client cannot be resized. This helps in debugging.
42#define GRAB_KBD43// #define GRAB_KBD
4344
44namespace mi = mir::input;45namespace mi = mir::input;
45namespace geom = mir::geometry;46namespace geom = mir::geometry;
@@ -89,6 +90,41 @@
89{90{
90}91}
9192
93XPoint get_logical_offset_for_window(::Display* display, Window window)
94{
95 XPoint pt{0,0};
96
97 static Atom atom = XInternAtom(display, "WM_LOGICAL_POSITION", False);
98 if (atom != None) {
99 int result;
100 Atom actual_type_return;
101 int actual_format_return;
102 unsigned long bytes_after_return;
103 unsigned char* prop_to_return;
104 unsigned long n_items;
105 result = XGetWindowProperty(display, window, atom,
106 0, (~0L), False, XA_POINT,
107 &actual_type_return,
108 &actual_format_return,
109 &n_items, &bytes_after_return, &prop_to_return);
110 if (result != Success) {
111 mir::log_error("X11 button event - failed to get window logicl position");
112 } else if (n_items*actual_format_return == sizeof(XPoint)*8) {
113 memcpy((unsigned char*)&pt, prop_to_return, sizeof(XPoint));
114 } else {
115 mir::log_error("X11 button event - logical position format error: type=%s format=%d bytes_remaiing=%d, n_items=%d",
116 XGetAtomName(display, actual_type_return),
117 actual_format_return,
118 bytes_after_return,
119 n_items);
120 }
121 } else {
122 mir::log_error("X11 button event - No atom WM_LOGICAL_POSITION");
123 }
124
125 return pt;
126}
127
92void mix::XInputPlatform::process_input_event()128void mix::XInputPlatform::process_input_event()
93{129{
94 while(XPending(x11_connection.get()))130 while(XPending(x11_connection.get()))
@@ -217,11 +253,13 @@
217 std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::milliseconds{xbev.time});253 std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::milliseconds{xbev.time});
218 core_pointer->update_button_state(xbev.state);254 core_pointer->update_button_state(xbev.state);
219255
256 XPoint logical_window_position = get_logical_offset_for_window(xbev.display, xbev.window);
257
220 if (xbev.button >= up && xbev.button <= right)258 if (xbev.button >= up && xbev.button <= right)
221 { // scroll event259 { // scroll event
222 core_pointer->pointer_motion(260 core_pointer->pointer_motion(
223 event_time,261 event_time,
224 geom::Point{xbev.x, xbev.y},262 geom::Point{logical_window_position.x + xbev.x, logical_window_position.y + xbev.y},
225 geom::Displacement{xbev.button == right ? 1 : xbev.button == left ? -1 : 0,263 geom::Displacement{xbev.button == right ? 1 : xbev.button == left ? -1 : 0,
226 xbev.button == up ? 1 : xbev.button == down ? -1 : 0});264 xbev.button == up ? 1 : xbev.button == down ? -1 : 0});
227 }265 }
@@ -231,13 +269,13 @@
231 core_pointer->pointer_press(269 core_pointer->pointer_press(
232 event_time,270 event_time,
233 xbev.button,271 xbev.button,
234 geom::Point{xbev.x, xbev.y},272 geom::Point{logical_window_position.x + xbev.x, logical_window_position.y + xbev.y},
235 geom::Displacement{0, 0});273 geom::Displacement{0, 0});
236 else274 else
237 core_pointer->pointer_release(275 core_pointer->pointer_release(
238 event_time,276 event_time,
239 xbev.button,277 xbev.button,
240 geom::Point{xbev.x, xbev.y},278 geom::Point{logical_window_position.x + xbev.x, logical_window_position.y + xbev.y},
241 geom::Displacement{0, 0});279 geom::Displacement{0, 0});
242 }280 }
243 break;281 break;
@@ -257,9 +295,13 @@
257 xmev.y_root, xmev.state, xmev.is_hint == NotifyNormal ? "no" : "yes", xmev.same_screen);295 xmev.y_root, xmev.state, xmev.is_hint == NotifyNormal ? "no" : "yes", xmev.same_screen);
258#endif296#endif
259297
298 XPoint logical_window_position = get_logical_offset_for_window(xmev.display, xmev.window);
299
260 core_pointer->update_button_state(xmev.state);300 core_pointer->update_button_state(xmev.state);
261 core_pointer->pointer_motion(301 core_pointer->pointer_motion(
262 std::chrono::milliseconds{xmev.time}, geom::Point{xmev.x, xmev.y}, geom::Displacement{0, 0});302 std::chrono::milliseconds{xmev.time},
303 geom::Point{logical_window_position.x + xmev.x, logical_window_position.y + xmev.y},
304 geom::Displacement{0, 0});
263305
264 break;306 break;
265 }307 }

Subscribers

People subscribed via source and target branches