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