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
1=== modified file 'src/platforms/mesa/server/x11/graphics/display.cpp'
2--- src/platforms/mesa/server/x11/graphics/display.cpp 2017-02-15 07:38:33 +0000
3+++ src/platforms/mesa/server/x11/graphics/display.cpp 2017-02-16 10:45:38 +0000
4@@ -18,12 +18,12 @@
5
6 #include "mir/graphics/platform.h"
7 #include "mir/graphics/display_report.h"
8+#include "mir/graphics/display_configuration_policy.h"
9 #include "mir/graphics/egl_error.h"
10 #include "mir/graphics/virtual_output.h"
11 #include "mir/renderer/gl/context.h"
12 #include "mir/graphics/gl_config.h"
13 #include "mir/graphics/atomic_frame.h"
14-#include "display_configuration.h"
15 #include "display.h"
16 #include "display_buffer.h"
17
18@@ -107,7 +107,7 @@
19
20 mgx::X11Window::X11Window(::Display* x_dpy,
21 EGLDisplay egl_dpy,
22- geom::Size const size,
23+ geom::Rectangle const& geometry,
24 EGLConfig const egl_cfg)
25 : x_dpy{x_dpy}
26 {
27@@ -157,7 +157,7 @@
28 auto mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
29
30 win = XCreateWindow(x_dpy, root, 0, 0,
31- size.width.as_int(), size.height.as_int(),
32+ geometry.size.width.as_int(), geometry.size.height.as_int(),
33 0, visInfo->depth, InputOutput,
34 visInfo->visual, mask, &attr);
35
36@@ -170,12 +170,12 @@
37 // TODO: Due to a bug, resize doesn't work after XGrabKeyboard under Unity.
38 // For now, make window unresizeable.
39 // http://stackoverflow.com/questions/14555703/x11-unable-to-move-window-after-xgrabkeyboard
40- sizehints.base_width = size.width.as_int();
41- sizehints.base_height = size.height.as_int();
42- sizehints.min_width = size.width.as_int();
43- sizehints.min_height = size.height.as_int();
44- sizehints.max_width = size.width.as_int();
45- sizehints.max_height = size.height.as_int();
46+ sizehints.base_width = geometry.size.width.as_int();
47+ sizehints.base_height = geometry.size.height.as_int();
48+ sizehints.min_width = geometry.size.width.as_int();
49+ sizehints.min_height = geometry.size.height.as_int();
50+ sizehints.max_width = geometry.size.width.as_int();
51+ sizehints.max_height = geometry.size.height.as_int();
52 sizehints.flags = PSize | PMinSize | PMaxSize;
53
54 XSetNormalHints(x_dpy, win, &sizehints);
55@@ -198,12 +198,16 @@
56
57 Atom wmDeleteMessage = XInternAtom(x_dpy, "WM_DELETE_WINDOW", False);
58 XSetWMProtocols(x_dpy, win, &wmDeleteMessage, 1);
59+
60+ wmLogicalPosition = XInternAtom(x_dpy, "WM_LOGICAL_POSITION", False);
61+ XPoint pt{(short)geometry.top_left.x.as_int(), (short)geometry.top_left.y.as_int()};
62+ XChangeProperty(x_dpy, win, wmLogicalPosition, XA_POINT, 16, PropModeReplace, (unsigned char *) &pt, 2);
63 }
64
65 XMapWindow(x_dpy, win);
66
67 XEvent xev;
68- do
69+ do
70 {
71 XNextEvent(x_dpy, &xev);
72 }
73@@ -225,8 +229,16 @@
74 return r_mask;
75 }
76
77+void mgx::X11Window::set_geometry(mir::geometry::Rectangle const& geometry)
78+{
79+ XPoint pt{(short)geometry.top_left.x.as_int(), (short)geometry.top_left.y.as_int()};
80+ XChangeProperty(x_dpy, win, wmLogicalPosition, XA_POINT, 16, PropModeReplace, (unsigned char *) &pt, 2);
81+}
82+
83 mgx::Display::Display(::Display* x_dpy,
84+ uint requested_output_count,
85 geom::Size const requested_size,
86+ std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy,
87 std::shared_ptr<GLConfig> const& gl_config,
88 std::shared_ptr<DisplayReport> const& report)
89 : shared_egl{*gl_config},
90@@ -235,50 +247,63 @@
91 gl_config{gl_config},
92 pixel_width{get_pixel_width(x_dpy)},
93 pixel_height{get_pixel_height(x_dpy)},
94- scale{1.0f},
95 report{report},
96- orientation{mir_orientation_normal},
97 last_frame{std::make_shared<AtomicFrame>()}
98 {
99 shared_egl.setup(x_dpy);
100
101- win = std::make_unique<X11Window>(x_dpy,
102- shared_egl.display(),
103- actual_size,
104- shared_egl.config());
105-
106- auto red_mask = win->red_mask();
107- pf = (red_mask == 0xFF0000 ? mir_pixel_format_argb_8888
108- : mir_pixel_format_abgr_8888);
109-
110- display_buffer = std::make_unique<mgx::DisplayBuffer>(
111- x_dpy,
112- *win,
113- actual_size,
114- shared_egl.context(),
115- last_frame,
116- report,
117- orientation,
118- *gl_config);
119-
120+ for (uint i = 0; i < requested_output_count; i++) {
121+ auto win = std::make_unique<X11Window>(x_dpy,
122+ shared_egl.display(),
123+ geom::Rectangle{{0,0}, actual_size},
124+ shared_egl.config());
125+
126+ auto red_mask = win->red_mask();
127+ pf = (red_mask == 0xFF0000 ? mir_pixel_format_argb_8888
128+ : mir_pixel_format_abgr_8888);
129+
130+ auto output_id = display_configuration.add_output(pf,
131+ actual_size,
132+ geom::Size{actual_size.width * pixel_width, actual_size.height * pixel_height},
133+ 1.0f,
134+ mir_orientation_normal);
135+
136+ auto display_buffer = std::make_unique<mgx::DisplayBuffer>(x_dpy,
137+ *win,
138+ geom::Rectangle{{0,0}, actual_size},
139+ shared_egl.context(),
140+ last_frame,
141+ report,
142+ mir_orientation_normal,
143+ output_id,
144+ *gl_config);
145+
146+ outputs.insert({ output_id, new OutputWindow{std::move(win), std::move(display_buffer)} });
147+ }
148 shared_egl.make_current();
149
150+ initial_conf_policy->apply_to(display_configuration);
151+ configure(display_configuration);
152+
153 report->report_successful_display_construction();
154 }
155
156 mgx::Display::~Display() noexcept
157 {
158+ for (auto output: outputs) {
159+ delete output.second;
160+ }
161 }
162
163 void mgx::Display::for_each_display_sync_group(std::function<void(mg::DisplaySyncGroup&)> const& f)
164 {
165- f(*display_buffer);
166+ for (const auto& output : outputs)
167+ f(*(output.second->display_buffer));
168 }
169
170 std::unique_ptr<mg::DisplayConfiguration> mgx::Display::configuration() const
171 {
172- return std::make_unique<mgx::DisplayConfiguration>(
173- pf, actual_size, geom::Size{actual_size.width * pixel_width, actual_size.height * pixel_height}, scale, orientation);
174+ return display_configuration.clone();
175 }
176
177 void mgx::Display::configure(mg::DisplayConfiguration const& new_configuration)
178@@ -289,18 +314,30 @@
179 std::logic_error("Invalid or inconsistent display configuration"));
180 }
181
182- MirOrientation o = mir_orientation_normal;
183- float new_scale = scale;
184-
185- new_configuration.for_each_output([&](DisplayConfigurationOutput const& conf_output)
186+ new_configuration.for_each_output([&](DisplayConfigurationOutput const& new_conf_output)
187 {
188- o = conf_output.orientation;
189- new_scale = conf_output.scale;
190+ display_configuration.for_each_output([&](UserDisplayConfigurationOutput& current_conf_output)
191+ {
192+ if (current_conf_output.id == new_conf_output.id) {
193+
194+ current_conf_output.scale = new_conf_output.scale;
195+ current_conf_output.orientation = new_conf_output.orientation;
196+ current_conf_output.top_left = new_conf_output.top_left;
197+ current_conf_output.used = new_conf_output.used;
198+ current_conf_output.power_mode = new_conf_output.power_mode;
199+ current_conf_output.form_factor = new_conf_output.form_factor;
200+ // TODO - current_mode_index for sizing.
201+
202+ auto search = outputs.find(new_conf_output.id);
203+ if(search != outputs.end()) {
204+ auto output = search->second;
205+ output->display_buffer->set_orientation(new_conf_output.orientation);
206+ output->display_buffer->set_geometry(new_conf_output.extents());
207+ output->win->set_geometry(new_conf_output.extents());
208+ }
209+ }
210+ });
211 });
212-
213- orientation = o;
214- display_buffer->set_orientation(orientation);
215- scale = new_scale;
216 }
217
218 void mgx::Display::register_configuration_change_handler(
219
220=== modified file 'src/platforms/mesa/server/x11/graphics/display.h'
221--- src/platforms/mesa/server/x11/graphics/display.h 2017-02-15 07:38:33 +0000
222+++ src/platforms/mesa/server/x11/graphics/display.h 2017-02-16 10:45:38 +0000
223@@ -24,12 +24,14 @@
224 #include "mir/renderer/gl/context_source.h"
225 #include "mir_toolkit/common.h"
226 #include "egl_helper.h"
227+#include "display_configuration.h"
228
229 #include <X11/Xlib.h>
230 #include <X11/Xutil.h>
231 #include <EGL/egl.h>
232
233 #include <memory>
234+#include <unordered_map>
235
236 namespace mir
237 {
238@@ -39,6 +41,7 @@
239 class AtomicFrame;
240 class GLConfig;
241 class DisplayReport;
242+class DisplayConfigurationPolicy;
243
244 namespace X
245 {
246@@ -50,15 +53,18 @@
247 public:
248 X11Window(::Display* const x_dpy,
249 EGLDisplay egl_dpy,
250- geometry::Size const size,
251+ mir::geometry::Rectangle const& geometry,
252 EGLConfig const egl_cfg);
253 ~X11Window();
254
255 operator Window() const;
256 unsigned long red_mask() const;
257
258+ void set_geometry(mir::geometry::Rectangle const& geometry);
259+
260 private:
261 ::Display* const x_dpy;
262+ ::Atom wmLogicalPosition;
263 Window win;
264 unsigned long r_mask;
265 };
266@@ -69,7 +75,9 @@
267 {
268 public:
269 explicit Display(::Display* x_dpy,
270+ uint requested_output_count,
271 geometry::Size const requested_size,
272+ std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy,
273 std::shared_ptr<GLConfig> const& gl_config,
274 std::shared_ptr<DisplayReport> const& report);
275 ~Display() noexcept;
276@@ -110,13 +118,15 @@
277 std::shared_ptr<GLConfig> const gl_config;
278 float pixel_width;
279 float pixel_height;
280- float scale;
281- std::unique_ptr<X11Window> win;
282 MirPixelFormat pf;
283 std::shared_ptr<DisplayReport> const report;
284- MirOrientation orientation; //TODO: keep entire current display configuration
285 std::shared_ptr<AtomicFrame> last_frame;
286- std::unique_ptr<DisplayBuffer> display_buffer;
287+ struct OutputWindow {
288+ std::unique_ptr<X11Window> win;
289+ std::unique_ptr<DisplayBuffer> display_buffer;
290+ };
291+ std::unordered_map<DisplayConfigurationOutputId, OutputWindow*> outputs;
292+ DisplayConfiguration display_configuration;
293 };
294
295 }
296
297=== modified file 'src/platforms/mesa/server/x11/graphics/display_buffer.cpp'
298--- src/platforms/mesa/server/x11/graphics/display_buffer.cpp 2017-01-30 06:36:29 +0000
299+++ src/platforms/mesa/server/x11/graphics/display_buffer.cpp 2017-02-16 10:45:38 +0000
300@@ -31,16 +31,18 @@
301
302 mgx::DisplayBuffer::DisplayBuffer(::Display* const x_dpy,
303 Window const win,
304- geom::Size const sz,
305+ geometry::Rectangle const geo,
306 EGLContext const shared_context,
307 std::shared_ptr<AtomicFrame> const& f,
308 std::shared_ptr<DisplayReport> const& r,
309 MirOrientation const o,
310+ DisplayConfigurationOutputId const output_id,
311 GLConfig const& gl_config)
312- : size{sz},
313+ : geometry{geo},
314 report{r},
315 orientation_{o},
316 transform{mg::transformation(o)},
317+ output_id_(output_id),
318 egl{gl_config},
319 last_frame{f},
320 eglGetSyncValues{nullptr}
321@@ -89,9 +91,9 @@
322 {
323 case mir_orientation_left:
324 case mir_orientation_right:
325- return {{0,0}, {size.height.as_int(), size.width.as_int()}};
326+ return {geometry.top_left, {geometry.size.height.as_int(), geometry.size.width.as_int()}};
327 default:
328- return {{0,0}, size};
329+ return geometry;
330 }
331 }
332
333@@ -146,7 +148,7 @@
334 * but this is best-effort. And besides, we don't want Mir reporting all
335 * real vsyncs because that would mean the compositor never sleeps.
336 */
337- report->report_vsync(mgx::DisplayConfiguration::the_output_id.as_value(),
338+ report->report_vsync(output_id_.as_value(),
339 last_frame->load());
340 }
341
342@@ -165,6 +167,12 @@
343 transform = mg::transformation(orientation_);
344 }
345
346+void mgx::DisplayBuffer::set_geometry(geom::Rectangle const geo)
347+{
348+ // TODO - resize the window.
349+ geometry.top_left = geo.top_left;
350+}
351+
352 mg::NativeDisplayBuffer* mgx::DisplayBuffer::native_display_buffer()
353 {
354 return this;
355
356=== modified file 'src/platforms/mesa/server/x11/graphics/display_buffer.h'
357--- src/platforms/mesa/server/x11/graphics/display_buffer.h 2017-01-30 06:36:29 +0000
358+++ src/platforms/mesa/server/x11/graphics/display_buffer.h 2017-02-16 10:45:38 +0000
359@@ -22,6 +22,7 @@
360
361 #include "mir/graphics/display_buffer.h"
362 #include "mir/graphics/display.h"
363+#include "mir/graphics/display_configuration.h"
364 #include "mir/renderer/gl/render_target.h"
365 #include "egl_helper.h"
366
367@@ -49,11 +50,12 @@
368 DisplayBuffer(
369 ::Display* const x_dpy,
370 Window const win,
371- geometry::Size const sz,
372+ geometry::Rectangle const geometry,
373 EGLContext const shared_context,
374 std::shared_ptr<AtomicFrame> const& f,
375 std::shared_ptr<DisplayReport> const& r,
376 MirOrientation const o,
377+ DisplayConfigurationOutputId const output_id,
378 GLConfig const& gl_config);
379
380 geometry::Rectangle view_area() const override;
381@@ -63,6 +65,7 @@
382 void bind() override;
383 bool overlay(RenderableList const& renderlist) override;
384 void set_orientation(MirOrientation const new_orientation);
385+ void set_geometry(geometry::Rectangle const geometry);
386
387 void for_each_display_buffer(
388 std::function<void(graphics::DisplayBuffer&)> const& f) override;
389@@ -73,10 +76,11 @@
390 NativeDisplayBuffer* native_display_buffer() override;
391
392 private:
393- geometry::Size const size;
394+ geometry::Rectangle geometry;
395 std::shared_ptr<DisplayReport> const report;
396 MirOrientation orientation_;
397 glm::mat2 transform;
398+ DisplayConfigurationOutputId const output_id_;
399 helpers::EGLHelper egl;
400 std::shared_ptr<AtomicFrame> const last_frame;
401
402
403=== modified file 'src/platforms/mesa/server/x11/graphics/display_configuration.cpp'
404--- src/platforms/mesa/server/x11/graphics/display_configuration.cpp 2017-01-18 02:29:37 +0000
405+++ src/platforms/mesa/server/x11/graphics/display_configuration.cpp 2017-02-16 10:45:38 +0000
406@@ -24,11 +24,23 @@
407 namespace mgx = mg::X;
408 namespace geom = mir::geometry;
409
410-mg::DisplayConfigurationOutputId const mgx::DisplayConfiguration::the_output_id{1};
411-
412-mgx::DisplayConfiguration::DisplayConfiguration(MirPixelFormat pf, geom::Size const pixels, geom::Size const size, const float scale, MirOrientation orientation) :
413- configuration{
414- the_output_id,
415+mgx::DisplayConfiguration::DisplayConfiguration() :
416+ card{mg::DisplayConfigurationCardId{0}, 1}
417+{
418+}
419+
420+mgx::DisplayConfiguration::DisplayConfiguration(DisplayConfiguration const& other)
421+ : mg::DisplayConfiguration(),
422+ outputs(other.outputs),
423+ card(other.card)
424+{
425+}
426+
427+mg::DisplayConfigurationOutputId mgx::DisplayConfiguration::add_output(MirPixelFormat pf, geom::Size const pixels, geom::Size const size, const float scale, MirOrientation orientation)
428+{
429+ static int output_id = 1;
430+ DisplayConfigurationOutput output{
431+ mg::DisplayConfigurationOutputId(output_id++),
432 mg::DisplayConfigurationCardId{0},
433 mg::DisplayConfigurationOutputType::unknown,
434 {pf},
435@@ -48,16 +60,10 @@
436 mir_subpixel_arrangement_unknown,
437 {},
438 mir_output_gamma_unsupported,
439- {}},
440- card{mg::DisplayConfigurationCardId{0}, 1}
441-{
442-}
443+ {}};
444+ outputs.push_back(output);
445
446-mgx::DisplayConfiguration::DisplayConfiguration(DisplayConfiguration const& other)
447- : mg::DisplayConfiguration(),
448- configuration(other.configuration),
449- card(other.card)
450-{
451+ return output.id;
452 }
453
454 void mgx::DisplayConfiguration::for_each_card(std::function<void(mg::DisplayConfigurationCard const&)> f) const
455@@ -67,13 +73,16 @@
456
457 void mgx::DisplayConfiguration::for_each_output(std::function<void(mg::DisplayConfigurationOutput const&)> f) const
458 {
459- f(configuration);
460+ for (auto& output : outputs)
461+ f(output);
462 }
463
464 void mgx::DisplayConfiguration::for_each_output(std::function<void(mg::UserDisplayConfigurationOutput&)> f)
465 {
466- mg::UserDisplayConfigurationOutput user(configuration);
467- f(user);
468+ for (auto& output : outputs) {
469+ mg::UserDisplayConfigurationOutput user(output);
470+ f(user);
471+ }
472 }
473
474 std::unique_ptr<mg::DisplayConfiguration> mgx::DisplayConfiguration::clone() const
475
476=== modified file 'src/platforms/mesa/server/x11/graphics/display_configuration.h'
477--- src/platforms/mesa/server/x11/graphics/display_configuration.h 2017-01-18 02:29:37 +0000
478+++ src/platforms/mesa/server/x11/graphics/display_configuration.h 2017-02-16 10:45:38 +0000
479@@ -33,24 +33,24 @@
480 class DisplayConfiguration : public graphics::DisplayConfiguration
481 {
482 public:
483- DisplayConfiguration(MirPixelFormat pf,
484- mir::geometry::Size const pixels,
485- mir::geometry::Size const size_mm,
486- float const scale,
487- MirOrientation orientation);
488+ DisplayConfiguration();
489 DisplayConfiguration(DisplayConfiguration const&);
490
491 virtual ~DisplayConfiguration() = default;
492
493+ DisplayConfigurationOutputId add_output(MirPixelFormat pf,
494+ mir::geometry::Size const pixels,
495+ mir::geometry::Size const size,
496+ const float scale,
497+ MirOrientation orientation);
498+
499 void for_each_card(std::function<void(DisplayConfigurationCard const&)> f) const override;
500 void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const override;
501 void for_each_output(std::function<void(UserDisplayConfigurationOutput&)> f) override;
502 std::unique_ptr<graphics::DisplayConfiguration> clone() const override;
503
504- static DisplayConfigurationOutputId const the_output_id;
505-
506 private:
507- DisplayConfigurationOutput configuration;
508+ std::vector<DisplayConfigurationOutput> outputs;
509 DisplayConfigurationCard card;
510 };
511
512
513=== modified file 'src/platforms/mesa/server/x11/graphics/graphics.cpp'
514--- src/platforms/mesa/server/x11/graphics/graphics.cpp 2017-01-18 02:29:37 +0000
515+++ src/platforms/mesa/server/x11/graphics/graphics.cpp 2017-02-16 10:45:38 +0000
516@@ -38,6 +38,7 @@
517 namespace
518 {
519 char const* x11_displays_option_name{"x11-displays"};
520+char const* x11_output_count_option_name{"x11-output-count"};
521 }
522
523 mir::UniqueModulePtr<mg::Platform> create_host_platform(
524@@ -55,8 +56,11 @@
525 if (pos == std::string::npos)
526 BOOST_THROW_EXCEPTION(std::runtime_error("Malformed display size option"));
527
528+ auto output_count = options->get<uint>(x11_output_count_option_name);
529+
530 return mir::make_module_ptr<mgx::Platform>(
531 x11_resources.get_conn(),
532+ output_count,
533 geom::Size{std::stoi(display_dims_str.substr(0, pos)),
534 std::stoi(display_dims_str.substr(pos+1, display_dims_str.find(':')))},
535 report
536@@ -78,6 +82,10 @@
537 (x11_displays_option_name,
538 boost::program_options::value<std::string>()->default_value("1280x1024"),
539 "[mir-on-X specific] WIDTHxHEIGHT of \"display\" window.");
540+ config.add_options()
541+ (x11_output_count_option_name,
542+ boost::program_options::value<uint>()->default_value(1),
543+ "[mir-on-X specific] NUMBER of outputs.");
544 }
545
546 mg::PlatformPriority probe_graphics_platform(mo::ProgramOption const& /*options*/)
547
548=== modified file 'src/platforms/mesa/server/x11/graphics/platform.cpp'
549--- src/platforms/mesa/server/x11/graphics/platform.cpp 2017-01-18 02:29:37 +0000
550+++ src/platforms/mesa/server/x11/graphics/platform.cpp 2017-02-16 10:45:38 +0000
551@@ -27,12 +27,14 @@
552 namespace geom = mir::geometry;
553
554 mgx::Platform::Platform(std::shared_ptr<::Display> const& conn,
555+ uint output_count,
556 geom::Size const size,
557 std::shared_ptr<mg::DisplayReport> const& report)
558 : x11_connection{conn},
559 udev{std::make_shared<mir::udev::Context>()},
560 drm{std::make_shared<mesa::helpers::DRMHelper>(mesa::helpers::DRMNodeToUse::render)},
561 report{report},
562+ output_count{output_count},
563 size{size}
564 {
565 if (!x11_connection)
566@@ -48,11 +50,10 @@
567 }
568
569 mir::UniqueModulePtr<mg::Display> mgx::Platform::create_display(
570- std::shared_ptr<DisplayConfigurationPolicy> const& /*initial_conf_policy*/,
571+ std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy,
572 std::shared_ptr<GLConfig> const& gl_config)
573 {
574- return make_module_ptr<mgx::Display>(x11_connection.get(), size, gl_config,
575- report);
576+ return make_module_ptr<mgx::Display>(x11_connection.get(), output_count, size, initial_conf_policy, gl_config, report);
577 }
578
579 mir::UniqueModulePtr<mg::PlatformIpcOperations> mgx::Platform::make_ipc_operations() const
580
581=== modified file 'src/platforms/mesa/server/x11/graphics/platform.h'
582--- src/platforms/mesa/server/x11/graphics/platform.h 2017-01-18 02:29:37 +0000
583+++ src/platforms/mesa/server/x11/graphics/platform.h 2017-02-16 10:45:38 +0000
584@@ -38,6 +38,7 @@
585 {
586 public:
587 explicit Platform(std::shared_ptr<::Display> const& conn,
588+ uint output_count,
589 mir::geometry::Size const size,
590 std::shared_ptr<DisplayReport> const& report);
591 ~Platform() = default;
592@@ -57,6 +58,7 @@
593 std::shared_ptr<mesa::helpers::DRMHelper> const drm;
594 std::shared_ptr<DisplayReport> const report;
595 mesa::helpers::GBMHelper gbm;
596+ uint output_count;
597 mir::geometry::Size const size;
598 };
599
600
601=== modified file 'src/platforms/mesa/server/x11/input/input_platform.cpp'
602--- src/platforms/mesa/server/x11/input/input_platform.cpp 2017-02-15 07:38:33 +0000
603+++ src/platforms/mesa/server/x11/input/input_platform.cpp 2017-02-16 10:45:38 +0000
604@@ -28,6 +28,7 @@
605
606 #include <X11/Xutil.h>
607 #include <X11/Xlib.h>
608+#include <X11/Xatom.h>
609 #include <linux/input.h>
610 #include <inttypes.h>
611 #include <signal.h>
612@@ -39,7 +40,7 @@
613
614 // Due to a bug in Unity when keyboard is grabbed,
615 // client cannot be resized. This helps in debugging.
616-#define GRAB_KBD
617+// #define GRAB_KBD
618
619 namespace mi = mir::input;
620 namespace geom = mir::geometry;
621@@ -89,6 +90,41 @@
622 {
623 }
624
625+XPoint get_logical_offset_for_window(::Display* display, Window window)
626+{
627+ XPoint pt{0,0};
628+
629+ static Atom atom = XInternAtom(display, "WM_LOGICAL_POSITION", False);
630+ if (atom != None) {
631+ int result;
632+ Atom actual_type_return;
633+ int actual_format_return;
634+ unsigned long bytes_after_return;
635+ unsigned char* prop_to_return;
636+ unsigned long n_items;
637+ result = XGetWindowProperty(display, window, atom,
638+ 0, (~0L), False, XA_POINT,
639+ &actual_type_return,
640+ &actual_format_return,
641+ &n_items, &bytes_after_return, &prop_to_return);
642+ if (result != Success) {
643+ mir::log_error("X11 button event - failed to get window logicl position");
644+ } else if (n_items*actual_format_return == sizeof(XPoint)*8) {
645+ memcpy((unsigned char*)&pt, prop_to_return, sizeof(XPoint));
646+ } else {
647+ mir::log_error("X11 button event - logical position format error: type=%s format=%d bytes_remaiing=%d, n_items=%d",
648+ XGetAtomName(display, actual_type_return),
649+ actual_format_return,
650+ bytes_after_return,
651+ n_items);
652+ }
653+ } else {
654+ mir::log_error("X11 button event - No atom WM_LOGICAL_POSITION");
655+ }
656+
657+ return pt;
658+}
659+
660 void mix::XInputPlatform::process_input_event()
661 {
662 while(XPending(x11_connection.get()))
663@@ -217,11 +253,13 @@
664 std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::milliseconds{xbev.time});
665 core_pointer->update_button_state(xbev.state);
666
667+ XPoint logical_window_position = get_logical_offset_for_window(xbev.display, xbev.window);
668+
669 if (xbev.button >= up && xbev.button <= right)
670 { // scroll event
671 core_pointer->pointer_motion(
672 event_time,
673- geom::Point{xbev.x, xbev.y},
674+ geom::Point{logical_window_position.x + xbev.x, logical_window_position.y + xbev.y},
675 geom::Displacement{xbev.button == right ? 1 : xbev.button == left ? -1 : 0,
676 xbev.button == up ? 1 : xbev.button == down ? -1 : 0});
677 }
678@@ -231,13 +269,13 @@
679 core_pointer->pointer_press(
680 event_time,
681 xbev.button,
682- geom::Point{xbev.x, xbev.y},
683+ geom::Point{logical_window_position.x + xbev.x, logical_window_position.y + xbev.y},
684 geom::Displacement{0, 0});
685 else
686 core_pointer->pointer_release(
687 event_time,
688 xbev.button,
689- geom::Point{xbev.x, xbev.y},
690+ geom::Point{logical_window_position.x + xbev.x, logical_window_position.y + xbev.y},
691 geom::Displacement{0, 0});
692 }
693 break;
694@@ -257,9 +295,13 @@
695 xmev.y_root, xmev.state, xmev.is_hint == NotifyNormal ? "no" : "yes", xmev.same_screen);
696 #endif
697
698+ XPoint logical_window_position = get_logical_offset_for_window(xmev.display, xmev.window);
699+
700 core_pointer->update_button_state(xmev.state);
701 core_pointer->pointer_motion(
702- std::chrono::milliseconds{xmev.time}, geom::Point{xmev.x, xmev.y}, geom::Displacement{0, 0});
703+ std::chrono::milliseconds{xmev.time},
704+ geom::Point{logical_window_position.x + xmev.x, logical_window_position.y + xmev.y},
705+ geom::Displacement{0, 0});
706
707 break;
708 }

Subscribers

People subscribed via source and target branches