diff options
126 files changed, 4090 insertions, 2518 deletions
@@ -17,7 +17,7 @@ make To build the QtWayland module you need the external dependencies: xkbcommon 0.2.0 - http://xkbcommon.org/ -wayland 1.0.3 - http://wayland.freedesktop.org/ +wayland 1.1.0 - http://wayland.freedesktop.org/ We hang out at #qt-labs and #qt-lighthouse on freenode if you have any questions diff --git a/config.tests/egl/egl.pro b/config.tests/egl/egl.pro index f95e3c76..e96672e5 100644 --- a/config.tests/egl/egl.pro +++ b/config.tests/egl/egl.pro @@ -1,6 +1,8 @@ TARGET = egl QT = core +!contains(QT_CONFIG, opengles2):error("wayland_egl support currently requires Qt configured with OpenGL ES2") + !contains(QT_CONFIG, no-pkg-config) { CONFIG += link_pkgconfig PKGCONFIG += egl diff --git a/config.tests/wayland_egl/wayland_egl.pro b/config.tests/wayland_egl/wayland_egl.pro index 76d92b18..0db9b04f 100644 --- a/config.tests/wayland_egl/wayland_egl.pro +++ b/config.tests/wayland_egl/wayland_egl.pro @@ -1,6 +1,8 @@ TARGET = wayland_egl QT = core +!contains(QT_CONFIG, opengles2):error("wayland_egl support currently requires Qt configured with OpenGL ES2") + !contains(QT_CONFIG, no-pkg-config) { CONFIG += link_pkgconfig PKGCONFIG += wayland-egl diff --git a/config.tests/wayland_scanner/wayland_scanner.pro b/config.tests/wayland_scanner/wayland_scanner.pro index 57edd5b2..300e439e 100644 --- a/config.tests/wayland_scanner/wayland_scanner.pro +++ b/config.tests/wayland_scanner/wayland_scanner.pro @@ -1,5 +1,6 @@ TARGET = wayland_scanner -QT = core + +isEmpty(QMAKE_WAYLAND_SCANNER):error("QMAKE_WAYLAND_SCANNER not defined for this mkspec") !contains(QT_CONFIG, no-pkg-config) { CONFIG += link_pkgconfig @@ -11,5 +12,12 @@ QT = core # Input SOURCES += main.cpp -WAYLANDSOURCES += scanner-test.xml +wayland-check-header.name = wayland ${QMAKE_FILE_BASE} +wayland-check-header.input = WAYLANDCHECKSOURCES +wayland-check-header.variable_out = HEADERS +wayland-check-header.output = wayland-${QMAKE_FILE_BASE}-client-protocol$${first(QMAKE_EXT_H)} +wayland-check-header.commands = $$QMAKE_WAYLAND_SCANNER client-header < ${QMAKE_FILE_IN} > ${QMAKE_FILE_OUT} +silent:wayland-client-header.commands = @echo Wayland scanner check header ${QMAKE_FILE_IN} && $$wayland-check-header.commands +QMAKE_EXTRA_COMPILERS += wayland-check-header +WAYLANDCHECKSOURCES = scanner-test.xml diff --git a/examples/qwindow-compositor/qwindowcompositor.cpp b/examples/qwindow-compositor/qwindowcompositor.cpp index 09522ae2..c184d590 100644 --- a/examples/qwindow-compositor/qwindowcompositor.cpp +++ b/examples/qwindow-compositor/qwindowcompositor.cpp @@ -166,6 +166,11 @@ void QWindowCompositor::surfaceDamaged(const QRect &rect) surfaceDamaged(surface, rect); } +void QWindowCompositor::surfacePosChanged() +{ + m_renderScheduler.start(0); +} + void QWindowCompositor::surfaceDamaged(QWaylandSurface *surface, const QRect &rect) { Q_UNUSED(surface) @@ -180,6 +185,7 @@ void QWindowCompositor::surfaceCreated(QWaylandSurface *surface) connect(surface, SIGNAL(unmapped()), this, SLOT(surfaceUnmapped())); connect(surface, SIGNAL(damaged(const QRect &)), this, SLOT(surfaceDamaged(const QRect &))); connect(surface, SIGNAL(extendedSurfaceReady()), this, SLOT(sendExpose())); + connect(surface, SIGNAL(posChanged()), this, SLOT(surfacePosChanged())); m_renderScheduler.start(0); } diff --git a/examples/qwindow-compositor/qwindowcompositor.h b/examples/qwindow-compositor/qwindowcompositor.h index 7ad2faf6..85da612a 100644 --- a/examples/qwindow-compositor/qwindowcompositor.h +++ b/examples/qwindow-compositor/qwindowcompositor.h @@ -62,6 +62,7 @@ private slots: void surfaceMapped(); void surfaceUnmapped(); void surfaceDamaged(const QRect &rect); + void surfacePosChanged(); void render(); protected: diff --git a/qtwayland.pro b/qtwayland.pro index 2886cff2..02e8c146 100644 --- a/qtwayland.pro +++ b/qtwayland.pro @@ -16,8 +16,7 @@ load(qt_parts) } !config_xkbcommon { - warning("QtWayland requires xkbcommon 0.2.0 or higher") - SUBDIRS = + warning("No xkbcommon 0.2.0 or higher found, disabling support for it") } !config_wayland_scanner { diff --git a/src/3rdparty/protocol/README b/src/3rdparty/protocol/README new file mode 100644 index 00000000..d37bad09 --- /dev/null +++ b/src/3rdparty/protocol/README @@ -0,0 +1 @@ +wayland.xml from wayland version defined in qtwayland/README diff --git a/src/3rdparty/protocol/wayland.xml b/src/3rdparty/protocol/wayland.xml new file mode 100644 index 00000000..3bce022c --- /dev/null +++ b/src/3rdparty/protocol/wayland.xml @@ -0,0 +1,1608 @@ +<?xml version="1.0" encoding="UTF-8"?> +<protocol name="wayland"> + + <copyright> + Copyright © 2008-2011 Kristian Høgsberg + Copyright © 2010-2011 Intel Corporation + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that copyright notice and this permission + notice appear in supporting documentation, and that the name of + the copyright holders not be used in advertising or publicity + pertaining to distribution of the software without specific, + written prior permission. The copyright holders make no + representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied + warranty. + + THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + THIS SOFTWARE. + </copyright> + + <interface name="wl_display" version="1"> + <description summary="core global object"> + The core global object. This is a special singleton object. It + is used for internal Wayland protocol features. + </description> + + <request name="sync"> + <description summary="asynchronous roundtrip"> + The sync request asks the server to emit the 'done' event + on the returned wl_callback object. Since requests are + handled in-order and events are delivered in-order, this can + used as a barrier to ensure all previous requests and the + resulting events have been handled. + + The object returned by this request will be destroyed by the + compositor after the callback is fired and as such the client must not + attempt to use it after that point. + </description> + <arg name="callback" type="new_id" interface="wl_callback"/> + </request> + + <request name="get_registry"> + <description summary="get global registry object"> + This request creates a registry object that allows the client + to list and bind the global objects available from the + compositor. + </description> + <arg name="callback" type="new_id" interface="wl_registry"/> + </request> + + <event name="error"> + <description summary="fatal error event"> + The error event is sent out when a fatal (non-recoverable) + error has occurred. The object_id argument is the object + where the error occurred, most often in response to a request + to that object. The code identifies the error and is defined + by the object interface. As such, each interface defines its + own set of error codes. The message is an brief description + of the error, for (debugging) convenience. + </description> + <arg name="object_id" type="object"/> + <arg name="code" type="uint"/> + <arg name="message" type="string"/> + </event> + + <enum name="error"> + <description summary="global error values"> + These errors are global and can be emitted in response to any + server request. + </description> + <entry name="invalid_object" value="0" + summary="server couldn't find object"/> + <entry name="invalid_method" value="1" + summary="method doesn't exist on the specified interface"/> + <entry name="no_memory" value="2" + summary="server is out of memory"/> + </enum> + + <event name="delete_id"> + <description summary="acknowledge object ID deletion"> + This event is used internally by the object ID management + logic. When a client deletes an object, the server will send + this event to acknowledge that it has seen the delete request. + When the client receive this event, it will know that it can + safely reuse the object ID. + </description> + <arg name="id" type="uint" /> + </event> + </interface> + + <interface name="wl_registry" version="1"> + <description summary="global registry object"> + The global registry object. The server has a number of global + objects that are available to all clients. These objects + typically represent an actual object in the server (for example, + an input device) or they are singleton objects that provide + extension functionality. + + When a client creates a registry object, the registry object + will emit a global event for each global currently in the + registry. Globals come and go as a result of device or + monitor hotplugs, reconfiguration or other events, and the + registry will send out global and global_remove events to + keep the client up to date with the changes. To mark the end + of the initial burst of events, the client can use the + wl_display.sync request immediately after calling + wl_display.get_registry. + + A client can bind to a global object by using the bind + request. This creates a client-side handle that lets the object + emit events to the client and lets the client invoke requests on + the object. + </description> + + <request name="bind"> + <description summary="bind an object to the display"> + Binds a new, client-created object to the server using the + specified name as the identifier. + </description> + <arg name="name" type="uint" summary="unique name for the object"/> + <arg name="id" type="new_id"/> + </request> + + <event name="global"> + <description summary="announce global object"> + Notify the client of global objects. + + The event notifies the client that a global object with + the given name is now available, and it implements the + given version of the given interface. + </description> + <arg name="name" type="uint"/> + <arg name="interface" type="string"/> + <arg name="version" type="uint"/> + </event> + + <event name="global_remove"> + <description summary="announce removal of global object"> + Notify the client of removed global objects. + + This event notifies the client that the global identified + by name is no longer available. If the client bound to + the global using the bind request, the client should now + destroy that object. + + The object remains valid and requests to the object will be + ignored until the client destroys it, to avoid races between + the global going away and a client sending a request to it. + </description> + <arg name="name" type="uint"/> + </event> + </interface> + + <interface name="wl_callback" version="1"> + <description summary="callback object"> + Clients can handle the 'done' event to get notified when + the related request is done. + </description> + <event name="done"> + <description summary="done event"> + Notify the client when the related request is done. + </description> + <arg name="serial" type="uint" summary="serial of the event"/> + </event> + </interface> + + <interface name="wl_compositor" version="2"> + <description summary="the compositor singleton"> + A compositor. This object is a singleton global. The + compositor is in charge of combining the contents of multiple + surfaces into one displayable output. + </description> + + <request name="create_surface"> + <description summary="create new surface"> + Ask the compositor to create a new surface. + </description> + <arg name="id" type="new_id" interface="wl_surface"/> + </request> + + <request name="create_region"> + <description summary="create new region"> + Ask the compositor to create a new region. + </description> + <arg name="id" type="new_id" interface="wl_region"/> + </request> + </interface> + + <interface name="wl_shm_pool" version="1"> + <description summary="a shared memory pool"> + The wl_shm_pool object encapsulates a piece of memory shared + between the compositor and client. Through the wl_shm_pool + object, the client can allocate shared memory wl_buffer objects. + All objects created through the same pool share the same + underlying mapped memory. Reusing the mapped memory avoids the + setup/teardown overhead and is useful when interactively resizing + a surface or for many small buffers. + </description> + + <request name="create_buffer"> + <description summary="create a buffer from the pool"> + Create a wl_buffer object from the pool. + + The buffer is created offset bytes into the pool and has + width and height as specified. The stride arguments specifies + the number of bytes from beginning of one row to the beginning + of the next. The format is the pixel format of the buffer and + must be one of those advertised through the wl_shm.format event. + + A buffer will keep a reference to the pool it was created from + so it is valid to destroy the pool immediately after creating + a buffer from it. + </description> + + <arg name="id" type="new_id" interface="wl_buffer"/> + <arg name="offset" type="int"/> + <arg name="width" type="int"/> + <arg name="height" type="int"/> + <arg name="stride" type="int"/> + <arg name="format" type="uint"/> + </request> + + <request name="destroy" type="destructor"> + <description summary="destroy the pool"> + Destroy the shared memory pool. + + The mmapped memory will be released when all + buffers that have been created from this pool + are gone. + </description> + </request> + + <request name="resize"> + <description summary="change the size of the pool mapping"> + This request will cause the server to remap the backing memory + for the pool from the file descriptor passed when the pool was + created, but using the new size. + </description> + + <arg name="size" type="int"/> + </request> + </interface> + + <interface name="wl_shm" version="1"> + <description summary="shared memory support"> + A global singleton object that provides support for shared + memory. + + Clients can create wl_shm_pool objects using the create_pool + request. + + At connection setup time, the wl_shm object emits one or more + format events to inform clients about the valid pixel formats + that can be used for buffers. + </description> + + <enum name="error"> + <description summary="wl_shm error values"> + These errors can be emitted in response to wl_shm requests. + </description> + <entry name="invalid_format" value="0" summary="buffer format is not known"/> + <entry name="invalid_stride" value="1" summary="invalid size or stride during pool or buffer creation"/> + <entry name="invalid_fd" value="2" summary="mmapping the file descriptor failed"/> + </enum> + + <enum name="format"> + <description summary="pixel formats"> + This describes the memory layout of an individual pixel. + </description> + <entry name="argb8888" value="0" summary="32-bit ARGB format"/> + <entry name="xrgb8888" value="1" summary="32-bit RGB format"/> + </enum> + + <request name="create_pool"> + <description summary="create a shm pool"> + Create a new wl_shm_pool object. + + The pool can be used to create shared memory based buffer + objects. The server will mmap size bytes of the passed file + descriptor, to use as backing memory for the pool. + </description> + + <arg name="id" type="new_id" interface="wl_shm_pool"/> + <arg name="fd" type="fd"/> + <arg name="size" type="int"/> + </request> + + <event name="format"> + <description summary="pixel format description"> + Informs the client about a valid pixel format that + can be used for buffers. Known formats include + argb8888 and xrgb8888. + </description> + <arg name="format" type="uint"/> + </event> + </interface> + + <interface name="wl_buffer" version="1"> + <description summary="content for a wl_surface"> + A buffer provides the content for a wl_surface. Buffers are + created through factory interfaces such as wl_drm, wl_shm or + similar. It has a width and a height and can be attached to a + wl_surface, but the mechanism by which a client provides and + updates the contents is defined by the buffer factory interface. + </description> + + <request name="destroy" type="destructor"> + <description summary="destroy a buffer"> + Destroy a buffer. If and how you need to release the backing + storage is defined by the buffer factory interface. + + For possible side-effects to a surface, see wl_surface.attach. + </description> + </request> + + <event name="release"> + <description summary="compositor releases buffer"> + Sent when this wl_buffer is no longer used by the compositor. + The client is now free to re-use or destroy this buffer and its + backing storage. + + If a client receives a release event before the frame callback + requested in the same wl_surface.commit that attaches this + wl_buffer to a surface, then the client is immediately free to + re-use the buffer and its backing storage, and does not need a + second buffer for the next surface content update. Typically + this is possible, when the compositor maintains a copy of the + wl_surface contents, e.g. as a GL texture. This is an important + optimization for GL(ES) compositors with wl_shm clients. + </description> + </event> + </interface> + + + <interface name="wl_data_offer" version="1"> + <description summary="offer to transfer data"> + A wl_data_offer represents a piece of data offered for transfer + by another client (the source client). It is used by the + copy-and-paste and drag-and-drop mechanisms. The offer + describes the different mime types that the data can be + converted to and provides the mechanism for transferring the + data directly from the source client. + </description> + + <request name="accept"> + <description summary="accept one of the offered mime types"> + Indicate that the client can accept the given mime type, or + NULL for not accepted. + + Used for feedback during drag-and-drop. + </description> + + <arg name="serial" type="uint"/> + <arg name="mime_type" type="string" allow-null="true"/> + </request> + + <request name="receive"> + <description summary="request that the data is transferred"> + To transfer the offered data, the client issues this request + and indicates the mime type it wants to receive. The transfer + happens through the passed file descriptor (typically created + with the pipe system call). The source client writes the data + in the mime type representation requested and then closes the + file descriptor. + + The receiving client reads from the read end of the pipe until + EOF and the closes its end, at which point the transfer is + complete. + </description> + <arg name="mime_type" type="string"/> + <arg name="fd" type="fd"/> + </request> + + <request name="destroy" type="destructor"> + <description summary="destroy data offer"> + Destroy the data offer. + </description> + </request> + + <event name="offer"> + <description summary="advertise offered mime type"> + Sent immediately after creating the wl_data_offer object. One + event per offered mime type. + </description> + + <arg name="mime_type" type="string"/> + </event> + </interface> + + <interface name="wl_data_source" version="1"> + <description summary="offer to transfer data"> + The wl_data_source object is the source side of a wl_data_offer. + It is created by the source client in a data transfer and + provides a way to describe the offered data and a way to respond + to requests to transfer the data. + </description> + + <request name="offer"> + <description summary="add an offered mime type"> + This request adds a mime type to the set of mime types + advertised to targets. Can be called several times to offer + multiple types. + </description> + <arg name="mime_type" type="string"/> + </request> + + <request name="destroy" type="destructor"> + <description summary="destroy the data source"> + Destroy the data source. + </description> + </request> + + <event name="target"> + <description summary="a target accepts an offered mime type"> + Sent when a target accepts pointer_focus or motion events. If + a target does not accept any of the offered types, type is NULL. + + Used for feedback during drag-and-drop. + </description> + + <arg name="mime_type" type="string" allow-null="true"/> + </event> + + <event name="send"> + <description summary="send the data"> + Request for data from the client. Send the data as the + specified mime type over the passed file descriptor, then + close it. + </description> + + <arg name="mime_type" type="string"/> + <arg name="fd" type="fd"/> + </event> + + <event name="cancelled"> + <description summary="selection was cancelled"> + This data source has been replaced by another data source. + The client should clean up and destroy this data source. + </description> + </event> + + </interface> + + <interface name="wl_data_device" version="1"> + <description summary="data transfer device"> + There is one wl_data_device per seat which can be obtained + from the global wl_data_device_manager singleton. + + A wl_data_device provides access to inter-client data transfer + mechanisms such as copy-and-paste and drag-and-drop. + </description> + <request name="start_drag"> + <description summary="start drag-and-drop operation"> + This request asks the compositor to start a drag-and-drop + operation on behalf of the client. + + The source argument is the data source that provides the data + for the eventual data transfer. If source is NULL, enter, leave + and motion events are sent only to the client that initiated the + drag and the client is expected to handle the data passing + internally. + + The origin surface is the surface where the drag originates and + the client must have an active implicit grab that matches the + serial. + + The icon surface is an optional (can be NULL) surface that + provides an icon to be moved around with the cursor. Initially, + the top-left corner of the icon surface is placed at the cursor + hotspot, but subsequent wl_surface.attach request can move the + relative position. Attach requests must be confirmed with + wl_surface.commit as usual. + + The current and pending input regions of the icon wl_surface are + cleared, and wl_surface.set_input_region is ignored until the + wl_surface is no longer used as the icon surface. When the use + as an icon ends, the the current and pending input regions + become undefined, and the wl_surface is unmapped. + </description> + <arg name="source" type="object" interface="wl_data_source" allow-null="true"/> + <arg name="origin" type="object" interface="wl_surface"/> + <arg name="icon" type="object" interface="wl_surface" allow-null="true"/> + <arg name="serial" type="uint" summary="serial of the implicit grab on the origin"/> + </request> + + <request name="set_selection"> + <description summary="copy data to the selection"> + This request asks the compositor to set the selection + to the data from the source on behalf of the client. + + To unset the selection, set the source to NULL. + </description> + <arg name="source" type="object" interface="wl_data_source" allow-null="true"/> + <arg name="serial" type="uint" summary="serial of the event that triggered this request"/> + </request> + + <event name="data_offer"> + <description summary="introduce a new wl_data_offer"> + The data_offer event introduces a new wl_data_offer object, + which will subsequently be used in either the + data_device.enter event (for drag-and-drop) or the + data_device.selection event (for selections). Immediately + following the data_device_data_offer event, the new data_offer + object will send out data_offer.offer events to describe the + mime types it offers. + </description> + + <arg name="id" type="new_id" interface="wl_data_offer"/> + </event> + + <event name="enter"> + <description summary="initiate drag-and-drop session"> + This event is sent when an active drag-and-drop pointer enters + a surface owned by the client. The position of the pointer at + enter time is provided by the x an y arguments, in surface + local coordinates. + </description> + + <arg name="serial" type="uint"/> + <arg name="surface" type="object" interface="wl_surface"/> + <arg name="x" type="fixed"/> + <arg name="y" type="fixed"/> + <arg name="id" type="object" interface="wl_data_offer" allow-null="true"/> + </event> + + <event name="leave"> + <description summary="end drag-and-drop session"> + This event is sent when the drag-and-drop pointer leaves the + surface and the session ends. The client must destroy the + wl_data_offer introduced at enter time at this point. + </description> + </event> + + <event name="motion"> + <description summary="drag-and-drop session motion"> + This event is sent when the drag-and-drop pointer moves within + the currently focused surface. The new position of the pointer + is provided by the x an y arguments, in surface local + coordinates. + </description> + <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> + <arg name="x" type="fixed"/> + <arg name="y" type="fixed"/> + </event> + + <event name="drop"> + <description summary="end drag-and-drag session successfully"> + The event is sent when a drag-and-drop operation is ended + because the implicit grab is removed. + </description> + </event> + + <event name="selection"> + <description summary="advertise new selection"> + The selection event is sent out to notify the client of a new + wl_data_offer for the selection for this device. The + data_device.data_offer and the data_offer.offer events are + sent out immediately before this event to introduce the data + offer object. The selection event is sent to a client + immediately before receiving keyboard focus and when a new + selection is set while the client has keyboard focus. The + data_offer is valid until a new data_offer or NULL is received + or until the client loses keyboard focus. + </description> + <arg name="id" type="object" interface="wl_data_offer" allow-null="true"/> + </event> + </interface> + + <interface name="wl_data_device_manager" version="1"> + <description summary="data transfer interface"> + The wl_data_device_manager is a a singleton global object that + provides access to inter-client data transfer mechanisms such as + copy-and-paste and drag-and-drop. These mechanisms are tied to + a wl_seat and this interface lets a client get a wl_data_device + corresponding to a wl_seat. + </description> + + <request name="create_data_source"> + <description summary="create a new data source"> + Create a new data source. + </description> + <arg name="id" type="new_id" interface="wl_data_source"/> + </request> + + <request name="get_data_device"> + <description summary="create a new data device"> + Create a new data device for a given seat. + </description> + <arg name="id" type="new_id" interface="wl_data_device"/> + <arg name="seat" type="object" interface="wl_seat"/> + </request> + </interface> + + <interface name="wl_shell" version="1"> + <description summary="create desktop-style surfaces"> + This interface is implemented by servers that provide + desktop-style user interfaces. + + It allows clients to associate a wl_shell_surface with + a basic surface. + </description> + + <request name="get_shell_surface"> + <description summary="create a shell surface from a surface"> + Create a shell surface for an existing surface. + + Only one shell surface can be associated with a given surface. + </description> + <arg name="id" type="new_id" interface="wl_shell_surface"/> + <arg name="surface" type="object" interface="wl_surface"/> + </request> + </interface> + + <interface name="wl_shell_surface" version="1"> + + <description summary="desktop-style metadata interface"> + An interface that may be implemented by a wl_surface, for + implementations that provide a desktop-style user interface. + + It provides requests to treat surfaces like toplevel, fullscreen + or popup windows, move, resize or maximize them, associate + metadata like title and class, etc. + + On the server side the object is automatically destroyed when + the related wl_surface is destroyed. On client side, + wl_shell_surface_destroy() must be called before destroying + the wl_surface object. + </description> + + <request name="pong"> + <description summary="respond to a ping event"> + A client must respond to a ping event with a pong request or + the client may be deemed unresponsive. + </description> + <arg name="serial" type="uint" summary="serial of the ping event"/> + </request> + + <request name="move"> + <description summary="start an interactive move"> + Start a pointer-driven move of the surface. + + This request must be used in response to a button press event. + The server may ignore move requests depending on the state of + the surface (e.g. fullscreen or maximized). + </description> + <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/> + <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/> + </request> + + <enum name="resize"> + <description summary="edge values for resizing"> + These values are used to indicate which edge of a surface + is being dragged in a resize operation. The server may + use this information to adapt its behavior, e.g. choose + an appropriate cursor image. + </description> + <entry name="none" value="0"/> + <entry name="top" value="1"/> + <entry name="bottom" value="2"/> + <entry name="left" value="4"/> + <entry name="top_left" value="5"/> + <entry name="bottom_left" value="6"/> + <entry name="right" value="8"/> + <entry name="top_right" value="9"/> + <entry name="bottom_right" value="10"/> + </enum> + + <request name="resize"> + <description summary="start an interactive resize"> + Start a pointer-driven resizing of the surface. + + This request must be used in response to a button press event. + The server may ignore resize requests depending on the state of + the surface (e.g. fullscreen or maximized). + </description> + <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/> + <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/> + <arg name="edges" type="uint" summary="which edge or corner is being dragged"/> + </request> + + <request name="set_toplevel"> + <description summary="make the surface a toplevel surface"> + Map the surface as a toplevel surface. + + A toplevel surface is not fullscreen, maximized or transient. + </description> + </request> + + <enum name="transient"> + <description summary="details of transient behaviour"> + These flags specify details of the expected behaviour + of transient surfaces. Used in the set_transient request. + </description> + <entry name="inactive" value="0x1" summary="do not set keyboard focus"/> + </enum> + + <request name="set_transient"> + <description summary="make the surface a transient surface"> + Map the surface relative to an existing surface. + + The x and y arguments specify the locations of the upper left + corner of the surface relative to the upper left corner of the + parent surface. + + The flags argument controls details of the transient behaviour. + </description> + + <arg name="parent" type="object" interface="wl_surface"/> + <arg name="x" type="int"/> + <arg name="y" type="int"/> + <arg name="flags" type="uint"/> + </request> + + <enum name="fullscreen_method"> + <description summary="different method to set the surface fullscreen"> + Hints to indicate to the compositor how to deal with a conflict + between the dimensions of the surface and the dimensions of the + output. The compositor is free to ignore this parameter. + </description> + <entry name="default" value="0" summary="no preference, apply default policy"/> + <entry name="scale" value="1" summary="scale, preserve the surface's aspect ratio and center on output"/> + <entry name="driver" value="2" summary="switch output mode to the smallest mode that can fit the surface, add black borders to compensate size mismatch"/> + <entry name="fill" value="3" summary="no scaling, center on output and add black borders to compensate size mismatch"/> + </enum> + + <request name="set_fullscreen"> + <description summary="make the surface a fullscreen surface"> + Map the surface as a fullscreen surface. + + If an output parameter is given then the surface will be made + fullscreen on that output. If the client does not specify the + output then the compositor will apply its policy - usually + choosing the output on which the surface has the biggest surface + area. + + The client may specify a method to resolve a size conflict + between the output size and the surface size - this is provided + through the method parameter. + + The framerate parameter is used only when the method is set + to "driver", to indicate the preferred framerate. A value of 0 + indicates that the app does not care about framerate. The + framerate is specified in mHz, that is framerate of 60000 is 60Hz. + + The compositor must reply to this request with a configure event + with the dimensions for the output on which the surface will + be made fullscreen. + </description> + <arg name="method" type="uint"/> + <arg name="framerate" type="uint"/> + <arg name="output" type="object" interface="wl_output" allow-null="true"/> + </request> + + <request name="set_popup"> + <description summary="make the surface a popup surface"> + Map the surface as a popup. + + A popup surface is a transient surface with an added pointer + grab. + + An existing implicit grab will be changed to owner-events mode, + and the popup grab will continue after the implicit grab ends + (i.e. releasing the mouse button does not cause the popup to + be unmapped). + + The popup grab continues until the window is destroyed or a + mouse button is pressed in any other clients window. A click + in any of the clients surfaces is reported as normal, however, + clicks in other clients surfaces will be discarded and trigger + the callback. + </description> + + <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/> + <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/> + <arg name="parent" type="object" interface="wl_surface"/> + <arg name="x" type="int"/> + <arg name="y" type="int"/> + <arg name="flags" type="uint"/> + </request> + + <request name="set_maximized"> + <description summary="make the surface a maximized surface"> + Map the surface as a maximized surface. + + If an output parameter is given then the surface will be + maximized on that output. If the client does not specify the + output then the compositor will apply its policy - usually + choosing the output on which the surface has the biggest surface + area. + + The compositor will reply with a configure event telling + the expected new surface size. The operation is completed + on the next buffer attach to this surface. + + A maximized surface typically fills the entire output it is + bound to, except for desktop element such as panels. This is + the main difference between a maximized shell surface and a + fullscreen shell surface. + + The details depend on the compositor implementation. + </description> + <arg name="output" type="object" interface="wl_output" allow-null="true"/> + </request> + + <request name="set_title"> + <description summary="set surface title"> + Set a short title for the surface. + + This string may be used to identify the surface in a task bar, + window list, or other user interface elements provided by the + compositor. + + The string must be encoded in UTF-8. + </description> + <arg name="title" type="string"/> + </request> + + <request name="set_class"> + <description summary="set surface class"> + Set a class for the surface. + + The surface class identifies the general class of applications + to which the surface belongs. A common convention is to use + the file name (full path if non-standard location) of the + applications .desktop file as the class. + </description> + <arg name="class_" type="string"/> + </request> + + <event name="ping"> + <description summary="ping client"> + Ping a client to check if it is receiving events and sending + requests. A client is expected to reply with a pong request. + </description> + <arg name="serial" type="uint"/> + </event> + + <event name="configure"> + <description summary="suggest resize"> + The configure event asks the client to resize its surface. + + The size is a hint, in the sense that the client is free to + ignore it if it doesn't resize, pick a smaller size (to + satisfy aspect ratio or resize in steps of NxM pixels). + + The edges parameter provides a hint about how the surface + was resized. The client may use this information to decide + how to adjust its content to the new size (e.g. a scrolling + area might adjust its content position to leave the viewable + content unmoved). + + The client is free to dismiss all but the last configure + event it received. + </description> + + <arg name="edges" type="uint"/> + <arg name="width" type="int"/> + <arg name="height" type="int"/> + </event> + + <event name="popup_done"> + <description summary="popup interaction is done"> + The popup_done event is sent out when a popup grab is broken, + that is, when the users clicks a surface that doesn't belong + to the client owning the popup surface. + </description> + </event> + </interface> + + <interface name="wl_surface" version="2"> + <description summary="an onscreen surface"> + A surface is a rectangular area that is displayed on the screen. + It has a location, size and pixel contents. + + Surfaces are also used for some special purposes, e.g. as + cursor images for pointers, drag icons, etc. + </description> + + <request name="destroy" type="destructor"> + <description summary="delete surface"> + Deletes the surface and invalidates its object ID. + </description> + </request> + + <request name="attach"> + <description summary="set the surface contents"> + Set a buffer as the content of this surface. + + The x and y arguments specify the location of the new pending + buffer's upper left corner, relative to the current buffer's + upper left corner. In other words, the x and y, and the width + and height of the wl_buffer together define in which directions + the surface's size changes. + + Surface contents are double-buffered state, see wl_surface.commit. + + The initial surface contents are void; there is no content. + wl_surface.attach assigns the given wl_buffer as the pending + wl_buffer. wl_surface.commit makes the pending wl_buffer the new + surface contents, and the size of the surface becomes the size of + the wl_buffer, as described above. After commit, there is no + pending buffer until the next attach. + + Committing a pending wl_buffer allows the compositor to read the + pixels in the wl_buffer. The compositor may access the pixels at + any time after the wl_surface.commit request. When the compositor + will not access the pixels anymore, it will send the + wl_buffer.release event. Only after receiving wl_buffer.release, + the client may re-use the wl_buffer. A wl_buffer that has been + attached and then replaced by another attach instead of committed + will not receive a release event, and is not used by the + compositor. + + Destroying the wl_buffer after wl_buffer.release does not change + the surface contents. However, if the client destroys the + wl_buffer before receiving wl_buffer.release, the surface + contents become undefined immediately. + + Only if wl_surface.attach is sent with a NULL wl_buffer, the + following wl_surface.commit will remove the surface content. + </description> + + <arg name="buffer" type="object" interface="wl_buffer" allow-null="true"/> + <arg name="x" type="int"/> + <arg name="y" type="int"/> + </request> + + <request name="damage"> + <description summary="mark part of the surface damaged"> + This request is used to describe the regions where the pending + buffer is different from the current surface contents, and where + the surface therefore needs to be repainted. The pending buffer + must be set by wl_surface.attach before sending damage. The + compositor ignores the parts of the damage that fall outside of + the surface. + + Damage is double-buffered state, see wl_surface.commit. + + The initial value for pending damage is empty: no damage. + wl_surface.damage adds pending damage: the new pending damage + is the union of old pending damage and the given rectangle. + + wl_surface.commit assigns pending damage as the current damage, + and clears pending damage. The server will clear the current + damage as it repaints the surface. + </description> + + <arg name="x" type="int"/> + <arg name="y" type="int"/> + <arg name="width" type="int"/> + <arg name="height" type="int"/> + </request> + + <request name="frame"> + <description summary="request repaint feedback"> + Request notification when the next frame is displayed. Useful + for throttling redrawing operations, and driving animations. + The frame request will take effect on the next wl_surface.commit. + The notification will only be posted for one frame unless + requested again. + + A server should avoid signalling the frame callbacks if the + surface is not visible in any way, e.g. the surface is off-screen, + or completely obscured by other opaque surfaces. + + A client can request a frame callback even without an attach, + damage, or any other state changes. wl_surface.commit triggers a + display update, so the callback event will arrive after the next + output refresh where the surface is visible. + + The object returned by this request will be destroyed by the + compositor after the callback is fired and as such the client must not + attempt to use it after that point. + </description> + + <arg name="callback" type="new_id" interface="wl_callback"/> + </request> + + <request name="set_opaque_region"> + <description summary="set opaque region"> + This request sets the region of the surface that contains + opaque content. + + The opaque region is an optimization hint for the compositor + that lets it optimize out redrawing of content behind opaque + regions. Setting an opaque region is not required for correct + behaviour, but marking transparent content as opaque will result + in repaint artifacts. + + The compositor ignores the parts of the opaque region that fall + outside of the surface. + + Opaque region is double-buffered state, see wl_surface.commit. + + wl_surface.set_opaque_region changes the pending opaque region. + wl_surface.commit copies the pending region to the current region. + Otherwise, the pending and current regions are never changed. + + The initial value for opaque region is empty. Setting the pending + opaque region has copy semantics, and the wl_region object can be + destroyed immediately. A NULL wl_region causes the pending opaque + region to be set to empty. + </description> + + <arg name="region" type="object" interface="wl_region" allow-null="true"/> + </request> + + <request name="set_input_region"> + <description summary="set input region"> + This request sets the region of the surface that can receive + pointer and touch events. + + Input events happening outside of this region will try the next + surface in the server surface stack. The compositor ignores the + parts of the input region that fall outside of the surface. + + Input region is double-buffered state, see wl_surface.commit. + + wl_surface.set_input_region changes the pending input region. + wl_surface.commit copies the pending region to the current region. + Otherwise the pending and current regions are never changed, + except cursor and icon surfaces are special cases, see + wl_pointer.set_cursor and wl_data_device.start_drag. + + The initial value for input region is infinite. That means the + whole surface will accept input. Setting the pending input region + has copy semantics, and the wl_region object can be destroyed + immediately. A NULL wl_region causes the input region to be set + to infinite. + </description> + + <arg name="region" type="object" interface="wl_region" allow-null="true"/> + </request> + + <request name="commit"> + <description summary="commit pending surface state"> + Surface state (input, opaque, and damage regions, attached buffers, + etc.) is double-buffered. Protocol requests modify the pending + state, as opposed to current state in use by the compositor. Commit + request atomically applies all pending state, replacing the current + state. After commit, the new pending state is as documented for each + related request. + + On commit, a pending wl_buffer is applied first, all other state + second. This means that all coordinates in double-buffered state are + relative to the new wl_buffer coming into use, except for + wl_surface.attach itself. If there is no pending wl_buffer, the + coordinates are relative to the current surface contents. + + All requests that need a commit to become effective are documented + to affect double-buffered state. + + Other interfaces may add further double-buffered surface state. + </description> + </request> + + <event name="enter"> + <description summary="surface enters an output"> + This is emitted whenever a surface's creation, movement, or resizing + results in some part of it being within the scanout region of an + output. + + Note that a surface may be overlapping with zero or more outputs. + </description> + <arg name="output" type="object" interface="wl_output"/> + </event> + + <event name="leave"> + <description summary="surface leaves an output"> + This is emitted whenever a surface's creation, movement, or resizing + results in it no longer having any part of it within the scanout region + of an output. + </description> + <arg name="output" type="object" interface="wl_output"/> + </event> + + <!-- Version 2 additions --> + + <request name="set_buffer_transform" since="2"> + <description summary="sets the buffer transformation"> + This request sets an optional transformation on how the compositor + interprets the contents of the buffer attached to the surface. The + accepted values for the transform parameter are the values for + wl_output.transform. + + Buffer transform is double-buffered state, see wl_surface.commit. + + A newly created surface has its buffer transformation set to normal. + + The purpose of this request is to allow clients to render content + according to the output transform, thus permiting the compositor to + use certain optimizations even if the display is rotated. Using + hardware overlays and scanning out a client buffer for fullscreen + surfaces are examples of such optmizations. Those optimizations are + highly dependent on the compositor implementation, so the use of this + request should be considered on a case-by-case basis. + + Note that if the transform value includes 90 or 270 degree rotation, + the width of the buffer will become the surface height and the height + of the buffer will become the surface width. + </description> + <arg name="transform" type="int"/> + </request> + </interface> + + <interface name="wl_seat" version="1"> + <description summary="group of input devices"> + A seat is a group of keyboards, pointer and touch devices. This + object is published as a global during start up, or when such a + device is hot plugged. A seat typically has a pointer and + maintains a keyboard focus and a pointer focus. + </description> + + <enum name="capability"> + <description summary="seat capability bitmask"> + This is a bitmask of capabilities this seat has; if a member is + set, then it is present on the seat. + </description> + <entry name="pointer" value="1" summary="The seat has pointer devices"/> + <entry name="keyboard" value="2" summary="The seat has one or more keyboards"/> + <entry name="touch" value="4" summary="The seat has touch devices"/> + </enum> + + <event name="capabilities"> + <description summary="seat capabilities changed"> + This is emitted whenever a seat gains or loses the pointer, + keyboard or touch capabilities. The argument is a capability + enum containing the complete set of capabilities this seat has. + </description> + <arg name="capabilities" type="uint"/> + </event> + + <request name="get_pointer"> + <description summary="return pointer object"> + The ID provided will be initialized to the wl_pointer interface + for this seat. + + This request only takes effect if the seat has the pointer + capability. + </description> + <arg name="id" type="new_id" interface="wl_pointer"/> + </request> + + <request name="get_keyboard"> + <description summary="return keyboard object"> + The ID provided will be initialized to the wl_keyboard interface + for this seat. + + This request only takes effect if the seat has the keyboard + capability. + </description> + <arg name="id" type="new_id" interface="wl_keyboard"/> + </request> + + <request name="get_touch"> + <description summary="return touch object"> + The ID provided will be initialized to the wl_touch interface + for this seat. + + This request only takes effect if the seat has the touch + capability. + </description> + <arg name="id" type="new_id" interface="wl_touch"/> + </request> + </interface> + + <interface name="wl_pointer" version="1"> + <description summary="pointer input device"> + The wl_pointer interface represents one or more input devices, + such as mice, which control the pointer location and pointer_focus + of a seat. + + The wl_pointer interface generates motion, enter and leave + events for the surfaces that the pointer is located over, + and button and axis events for button presses, button releases + and scrolling. + </description> + + <request name="set_cursor"> + <description summary="set the pointer surface"> + Set the pointer surface, i.e., the surface that contains the + pointer image (cursor). This request only takes effect if the pointer + focus for this device is one of the requesting client's surfaces + or the surface parameter is the current pointer surface. If + there was a previous surface set with this request it is + replaced. If surface is NULL, the pointer image is hidden. + + The parameters hotspot_x and hotspot_y define the position of + the pointer surface relative to the pointer location. Its + top-left corner is always at (x, y) - (hotspot_x, hotspot_y), + where (x, y) are the coordinates of the pointer location. + + On surface.attach requests to the pointer surface, hotspot_x + and hotspot_y are decremented by the x and y parameters + passed to the request. Attach must be confirmed by + wl_surface.commit as usual. + + The hotspot can also be updated by passing the currently set + pointer surface to this request with new values for hotspot_x + and hotspot_y. + + The current and pending input regions of the wl_surface are + cleared, and wl_surface.set_input_region is ignored until the + wl_surface is no longer used as the cursor. When the use as a + cursor ends, the current and pending input regions become + undefined, and the wl_surface is unmapped. + </description> + + <arg name="serial" type="uint" summary="serial of the enter event"/> + <arg name="surface" type="object" interface="wl_surface" allow-null="true"/> + <arg name="hotspot_x" type="int" summary="x coordinate in surface-relative coordinates"/> + <arg name="hotspot_y" type="int" summary="y coordinate in surface-relative coordinates"/> + </request> + + <event name="enter"> + <description summary="enter event"> + Notification that this seat's pointer is focused on a certain + surface. + + When an seat's focus enters a surface, the pointer image + is undefined and a client should respond to this event by setting + an appropriate pointer image with the set_cursor request. + </description> + + <arg name="serial" type="uint"/> + <arg name="surface" type="object" interface="wl_surface"/> + <arg name="surface_x" type="fixed" summary="x coordinate in surface-relative coordinates"/> + <arg name="surface_y" type="fixed" summary="y coordinate in surface-relative coordinates"/> + </event> + + <event name="leave"> + <description summary="leave event"> + Notification that this seat's pointer is no longer focused on + a certain surface. + + The leave notification is sent before the enter notification + for the new focus. + </description> + <arg name="serial" type="uint"/> + <arg name="surface" type="object" interface="wl_surface"/> + </event> + + <event name="motion"> + <description summary="pointer motion event"> + Notification of pointer location change. The arguments + surface_x and surface_y are the location relative to the + focused surface. + </description> + + <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> + <arg name="surface_x" type="fixed" summary="x coordinate in surface-relative coordinates"/> + <arg name="surface_y" type="fixed" summary="y coordinate in surface-relative coordinates"/> + </event> + + <enum name="button_state"> + <description summary="physical button state"> + Describes the physical state of a button which provoked the button + event. + </description> + <entry name="released" value="0" summary="The button is not pressed"/> + <entry name="pressed" value="1" summary="The button is pressed"/> + </enum> + + <event name="button"> + <description summary="pointer button event"> + Mouse button click and release notifications. + + The location of the click is given by the last motion or + enter event. + The time argument is a timestamp with millisecond + granularity, with an undefined base. + </description> + + <arg name="serial" type="uint"/> + <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> + <arg name="button" type="uint"/> + <arg name="state" type="uint"/> + </event> + + <enum name="axis"> + <description summary="axis types"> + Describes the axis types of scroll events. + </description> + <entry name="vertical_scroll" value="0"/> + <entry name="horizontal_scroll" value="1"/> + </enum> + + <event name="axis"> + <description summary="axis event"> + Scroll and other axis notifications. + + For scroll events (vertical and horizontal scroll axes), the + value parameter is the length of a vector along the specified + axis in a coordinate space identical to those of motion events, + representing a relative movement along the specified axis. + + For devices that support movements non-parallel to axes multiple + axis events will be emitted. + + When applicable, for example for touch pads, the server can + choose to emit scroll events where the motion vector is + equivalent to a motion event vector. + + When applicable, clients can transform its view relative to the + scroll distance. + </description> + + <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> + <arg name="axis" type="uint"/> + <arg name="value" type="fixed"/> + </event> + </interface> + + <interface name="wl_keyboard" version="1"> + <description summary="keyboard input device"> + The wl_keyboard interface represents one or more keyboards + associated with a seat. + </description> + + <enum name="keymap_format"> + <description summary="keyboard mapping format"> + This specifies the format of the keymap provided to the + client with the wl_keyboard.keymap event. + </description> + <entry name="xkb_v1" value="1" summary="libxkbcommon compatible"/> + </enum> + + <event name="keymap"> + <description summary="keyboard mapping"> + This event provides a file descriptor to the client which can be + memory-mapped to provide a keyboard mapping description. + </description> + <arg name="format" type="uint"/> + <arg name="fd" type="fd"/> + <arg name="size" type="uint"/> + </event> + + <event name="enter"> + <description summary="enter event"> + Notification that this seat's keyboard focus is on a certain + surface. + </description> + <arg name="serial" type="uint"/> + <arg name="surface" type="object" interface="wl_surface"/> + <arg name="keys" type="array" summary="the currently pressed keys"/> + </event> + + <event name="leave"> + <description summary="leave event"> + Notification that this seat's keyboard focus is no longer on + a certain surface. + + The leave notification is sent before the enter notification + for the new focus. + </description> + <arg name="serial" type="uint"/> + <arg name="surface" type="object" interface="wl_surface"/> + </event> + + <enum name="key_state"> + <description summary="physical key state"> + Describes the physical state of a key which provoked the key event. + </description> + <entry name="released" value="0" summary="key is not pressed"/> + <entry name="pressed" value="1" summary="key is pressed"/> + </enum> + + <event name="key"> + <description summary="key event"> + A key was pressed or released. + The time argument is a timestamp with millisecond + granularity, with an undefined base. + </description> + + <arg name="serial" type="uint"/> + <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> + <arg name="key" type="uint"/> + <arg name="state" type="uint"/> + </event> + + <event name="modifiers"> + <description summary="modifier and group state"> + Notifies clients that the modifier and/or group state has + changed, and it should update its local state. + </description> + + <arg name="serial" type="uint"/> + <arg name="mods_depressed" type="uint"/> + <arg name="mods_latched" type="uint"/> + <arg name="mods_locked" type="uint"/> + <arg name="group" type="uint"/> + </event> + </interface> + + <interface name="wl_touch" version="1"> + <description summary="touchscreen input device"> + The wl_touch interface represents a touchscreen + associated with a seat. + + Touch interactions can consist of one or more contacts. + For each contact, a series of events is generated, starting + with a down event, followed by zero or more motion events, + and ending with an up event. Events relating to the same + contact point can be identified by the ID of the sequence. + </description> + + <event name="down"> + <description summary="touch down event and beginning of a touch sequence"> + A new touch point has appeared on the surface. This touch point is + assigned a unique @id. Future events from this touchpoint reference + this ID. The ID ceases to be valid after a touch up event and may be + re-used in the future. + </description> + <arg name="serial" type="uint"/> + <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> + <arg name="surface" type="object" interface="wl_surface"/> + <arg name="id" type="int" summary="the unique ID of this touch point"/> + <arg name="x" type="fixed" summary="x coordinate in surface-relative coordinates"/> + <arg name="y" type="fixed" summary="y coordinate in surface-relative coordinates"/> + </event> + + <event name="up"> + <description summary="end of a touch event sequence"> + The touch point has disappeared. No further events will be sent for + this touchpoint and the touch point's ID is released and may be + re-used in a future touch down event. + </description> + <arg name="serial" type="uint"/> + <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> + <arg name="id" type="int" summary="the unique ID of this touch point"/> + </event> + + <event name="motion"> + <description summary="update of touch point coordinates"> + A touchpoint has changed coordinates. + </description> + <arg name="time" type="uint" summary="timestamp with millisecond granularity"/> + <arg name="id" type="int" summary="the unique ID of this touch point"/> + <arg name="x" type="fixed" summary="x coordinate in surface-relative coordinates"/> + <arg name="y" type="fixed" summary="y coordinate in surface-relative coordinates"/> + </event> + + <event name="frame"> + <description summary="end of touch frame event"> + Indicates the end of a contact point list. + </description> + </event> + + <event name="cancel"> + <description summary="touch session cancelled"> + Sent if the compositor decides the touch stream is a global + gesture. No further events are sent to the clients from that + particular gesture. Touch cancellation applies to all touch points + currently active on this client's surface. The client is + responsible for finalizing the touch points, future touch points on + this surface may re-use the touch point ID. + </description> + </event> + </interface> + + <interface name="wl_output" version="1"> + <description summary="compositor output region"> + An output describes part of the compositor geometry. The + compositor works in the 'compositor coordinate system' and an + output corresponds to rectangular area in that space that is + actually visible. This typically corresponds to a monitor that + displays part of the compositor space. This object is published + as global during start up, or when a monitor is hotplugged. + </description> + + <enum name="subpixel"> + <description summary="subpixel geometry information"> + This enumeration describes how the physical + pixels on an output are layed out. + </description> + <entry name="unknown" value="0"/> + <entry name="none" value="1"/> + <entry name="horizontal_rgb" value="2"/> + <entry name="horizontal_bgr" value="3"/> + <entry name="vertical_rgb" value="4"/> + <entry name="vertical_bgr" value="5"/> + </enum> + + <enum name="transform"> + <description summary="transform from framebuffer to output"> + This describes the transform that a compositor will apply to a + surface to compensate for the rotation or mirroring of an + output device. + + The flipped values correspond to an initial flip around a + vertical axis followed by rotation. + + The purpose is mainly to allow clients render accordingly and + tell the compositor, so that for fullscreen surfaces, the + compositor will still be able to scan out directly from client + surfaces. + </description> + + <entry name="normal" value="0"/> + <entry name="90" value="1"/> + <entry name="180" value="2"/> + <entry name="270" value="3"/> + <entry name="flipped" value="4"/> + <entry name="flipped_90" value="5"/> + <entry name="flipped_180" value="6"/> + <entry name="flipped_270" value="7"/> + </enum> + + <event name="geometry"> + <description summary="properties of the output"> + The geometry event describes geometric properties of the output. + The event is sent when binding to the output object and whenever + any of the properties change. + </description> + <arg name="x" type="int" + summary="x position within the global compositor space"/> + <arg name="y" type="int" + summary="y position within the global compositor space"/> + <arg name="physical_width" type="int" + summary="width in millimeters of the output"/> + <arg name="physical_height" type="int" + summary="height in millimeters of the output"/> + <arg name="subpixel" type="int" + summary="subpixel orientation of the output"/> + <arg name="make" type="string" + summary="textual description of the manufacturer"/> + <arg name="model" type="string" + summary="textual description of the model"/> + <arg name="transform" type="int" + summary="transform that maps framebuffer to output"/> + </event> + + <enum name="mode"> + <description summary="mode information"> + These flags describe properties of an output mode. + They are used in the flags bitfield of the mode event. + </description> + <entry name="current" value="0x1" + summary="indicates this is the current mode"/> + <entry name="preferred" value="0x2" + summary="indicates this is the preferred mode"/> + </enum> + + <event name="mode"> + <description summary="advertise available modes for the output"> + The mode event describes an available mode for the output. + + The event is sent when binding to the output object and there + will always be one mode, the current mode. The event is sent + again if an output changes mode, for the mode that is now + current. In other words, the current mode is always the last + mode that was received with the current flag set. + </description> + <arg name="flags" type="uint" summary="bitfield of mode flags"/> + <arg name="width" type="int" summary="width of the mode in pixels"/> + <arg name="height" type="int" summary="height of the mode in pixels"/> + <arg name="refresh" type="int" summary="vertical refresh rate in mHz"/> + </event> + </interface> + + <interface name="wl_region" version="1"> + <description summary="region interface"> + A region object describes an area. + + Region objects are used to describe the opaque and input + regions of a surface. + </description> + + <request name="destroy" type="destructor"> + <description summary="destroy region"> + Destroy the region. This will invalidate the object ID. + </description> + </request> + + <request name="add"> + <description summary="add rectangle to region"> + Add the specified rectangle to the region. + </description> + + <arg name="x" type="int"/> + <arg name="y" type="int"/> + <arg name="width" type="int"/> + <arg name="height" type="int"/> + </request> + + <request name="subtract"> + <description summary="subtract rectangle from region"> + Subtract the specified rectangle from the region. + </description> + + <arg name="x" type="int"/> + <arg name="y" type="int"/> + <arg name="width" type="int"/> + <arg name="height" type="int"/> + </request> + + </interface> + +</protocol> diff --git a/src/compositor/compositor.pro b/src/compositor/compositor.pro index 8a2fa01e..8dc485ff 100644 --- a/src/compositor/compositor.pro +++ b/src/compositor/compositor.pro @@ -18,6 +18,7 @@ DEFINES += QT_WAYLAND_WINDOWMANAGER_SUPPORT INCLUDEPATH += ../shared HEADERS += ../shared/qwaylandmimehelper.h SOURCES += ../shared/qwaylandmimehelper.cpp +HEADERS += qwayland-server-wayland.h include ($$PWD/global/global.pri) include ($$PWD/wayland_wrapper/wayland_wrapper.pri) diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index f9716925..7f0813a4 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -227,25 +227,10 @@ void QWaylandSurface::setSurfaceItem(QWaylandSurfaceItem *surfaceItem) qint64 QWaylandSurface::processId() const { Q_D(const QWaylandSurface); - WindowManagerServerIntegration *wmIntegration = d->surface->compositor()->windowManagerIntegration(); - if (!wmIntegration) { - return 0; - } - - WaylandManagedClient *mcl = wmIntegration->managedClient(d->surface->base()->resource.client); - return mcl ? mcl->processId() : 0; -} - -QByteArray QWaylandSurface::authenticationToken() const -{ - Q_D(const QWaylandSurface); - WindowManagerServerIntegration *wmIntegration = d->surface->compositor()->windowManagerIntegration(); - if (!wmIntegration) { - return QByteArray(); - } - - WaylandManagedClient *mcl = wmIntegration->managedClient(d->surface->base()->resource.client); - return mcl ? mcl->authenticationToken() : QByteArray(); + struct wl_client *client = static_cast<struct wl_client *>(this->client()); + pid_t pid; + wl_client_get_credentials(client,&pid, 0,0); + return pid; } QVariantMap QWaylandSurface::windowProperties() const diff --git a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp index 5089ce5f..a6f425a8 100644 --- a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp +++ b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp @@ -381,6 +381,7 @@ void QWaylandSurfaceItem::updateTexture() } m_provider->t = texture; + emit m_provider->textureChanged(); m_provider->smooth = smooth(); } diff --git a/src/compositor/global/qwaylandobject.h b/src/compositor/global/qwaylandobject.h index 6d93297a..9b345039 100644 --- a/src/compositor/global/qwaylandobject.h +++ b/src/compositor/global/qwaylandobject.h @@ -60,38 +60,8 @@ public: const T *base() const { return this; } T *base() { return this; } - - template <typename Implementation> - void addClientResource(wl_client *client, - wl_resource *resource, - int id, const struct wl_interface *interface, - Implementation implementation, - void (*destroy)(struct wl_resource *resource)) - { - resource->object.id = id; - resource->object.interface = interface; - resource->object.implementation = (void (**)(void))implementation; - resource->data = this; - resource->destroy = destroy; - - wl_client_add_resource(client, resource); - } }; -template <typename T> -T *resolve(wl_resource *from) -{ - Object<typename T::Base> *object = reinterpret_cast<Object<typename T::Base> *>(from->data); - return static_cast<T *>(object); -} - -template <typename T> -T *wayland_cast(typename T::Base *from) -{ - Object<typename T::Base> *object = reinterpret_cast<Object<typename T::Base> *>(from); - return static_cast<T *>(object); -} - } QT_END_NAMESPACE diff --git a/src/compositor/global/qwaylandresourcecollection.cpp b/src/compositor/global/qwaylandresourcecollection.cpp index 6433474a..cc20e628 100644 --- a/src/compositor/global/qwaylandresourcecollection.cpp +++ b/src/compositor/global/qwaylandresourcecollection.cpp @@ -46,6 +46,17 @@ QT_BEGIN_NAMESPACE namespace QtWayland { +struct wl_resource *resourceForClient(const struct wl_list *list, struct wl_client *client) +{ + struct wl_resource *resource; + wl_list_for_each(resource, list, link) { + if (resource->client == client) { + return resource; + } + } + return 0; +} + ResourceCollection::ResourceCollection() { wl_list_init(&client_resources); @@ -66,14 +77,7 @@ void ResourceCollection::registerResource(struct wl_resource *resource) struct wl_resource *ResourceCollection::resourceForClient(wl_client *client) const { - struct wl_resource *resource; - wl_list_for_each(resource,&client_resources, link) { - if (resource->client == client) { - return resource; - } - } - return 0; - + return QtWayland::resourceForClient(&client_resources, client); } bool ResourceCollection::resourceListIsEmpty() const diff --git a/src/compositor/global/qwaylandresourcecollection.h b/src/compositor/global/qwaylandresourcecollection.h index cfc1c32c..61df0f1d 100644 --- a/src/compositor/global/qwaylandresourcecollection.h +++ b/src/compositor/global/qwaylandresourcecollection.h @@ -49,6 +49,8 @@ QT_BEGIN_NAMESPACE namespace QtWayland { +struct wl_resource *resourceForClient(const struct wl_list *list, struct wl_client *client); + class ResourceCollection { public: diff --git a/src/compositor/wayland_wrapper/qwlcompositor.cpp b/src/compositor/wayland_wrapper/qwlcompositor.cpp index 26defc0b..0f2fedc4 100644 --- a/src/compositor/wayland_wrapper/qwlcompositor.cpp +++ b/src/compositor/wayland_wrapper/qwlcompositor.cpp @@ -176,8 +176,7 @@ Compositor::Compositor(QWaylandCompositor *qt_compositor) wl_display_init_shm(m_display->handle()); - m_output_global = new OutputGlobal(); - wl_display_add_global(m_display->handle(),&wl_output_interface, m_output_global, OutputGlobal::output_bind_func); + m_output_global = new OutputGlobal(m_display->handle()); m_shell = new Shell(); wl_display_add_global(m_display->handle(), &wl_shell_interface, m_shell, Shell::bind_func); @@ -251,7 +250,7 @@ struct wl_client *Compositor::getClientFromWinId(uint winId) const { Surface *surface = getSurfaceFromWinId(winId); if (surface) - return surface->base()->resource.client; + return surface->resource()->client(); return 0; } @@ -332,12 +331,9 @@ void Compositor::destroyClient(WaylandClient *c) if (!client) return; - if (m_windowManagerIntegration->managedClient(client)) { - m_windowManagerIntegration->sendQuitMessage(client); - m_windowManagerIntegration->removeClient(client); - } else { - wl_client_destroy(client); - } + m_windowManagerIntegration->sendQuitMessage(client); + + wl_client_destroy(client); } QWindow *Compositor::window() const @@ -415,7 +411,7 @@ QList<struct wl_client *> Compositor::clients() const { QList<struct wl_client *> list; foreach (Surface *surface, m_surfaces) { - struct wl_client *client = surface->base()->resource.client; + struct wl_client *client = surface->resource()->client(); if (!list.contains(client)) list.append(client); } @@ -426,8 +422,8 @@ Qt::ScreenOrientations Compositor::orientationUpdateMaskForClient(wl_client *cli { Output *output = m_output_global->outputForClient(client); Q_ASSERT(output); - if (output->extendedOutput()) - return output->extendedOutput()->orientationUpdateMask(); + if (output->extendedOutput) + return output->extendedOutput->orientationUpdateMask; return 0; } @@ -440,9 +436,8 @@ void Compositor::setScreenOrientation(Qt::ScreenOrientation orientation) struct wl_client *client = clientList.at(i); Output *output = m_output_global->outputForClient(client); Q_ASSERT(output); - if (output->extendedOutput()){ - output->extendedOutput()->sendOutputOrientation(orientation); - } + if (output->extendedOutput) + output->extendedOutput->sendOutputOrientation(orientation); } } @@ -492,7 +487,7 @@ QList<QtWayland::Surface *> Compositor::surfacesForClient(wl_client *client) QList<QtWayland::Surface *> ret; for (int i=0; i < m_surfaces.count(); ++i) { - if (m_surfaces.at(i)->base()->resource.client == client) { + if (m_surfaces.at(i)->resource()->client() == client) { ret.append(m_surfaces.at(i)); } } @@ -505,7 +500,7 @@ wl_resource *Compositor::resourceForSurface(wl_list *resourceList, Surface *surf return 0; wl_resource *r; - wl_client *surfaceClient = surface->base()->resource.client; + wl_client *surfaceClient = surface->resource()->client(); wl_list_for_each(r, resourceList, link) { if (r->client == surfaceClient) diff --git a/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp b/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp index f89dbc31..c27aa514 100644 --- a/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp +++ b/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp @@ -208,7 +208,7 @@ void DataDeviceManager::get_data_device(struct wl_client *client, struct wl_resource *input_device_resource) { DataDeviceManager *data_device_manager = static_cast<DataDeviceManager *>(data_device_manager_resource->data); - InputDevice *input_device = resolve<InputDevice>(input_device_resource); + InputDevice *input_device = InputDevice::fromSeatResource(input_device_resource); input_device->clientRequestedDataDevice(data_device_manager,client,id); } @@ -243,7 +243,7 @@ void DataDeviceManager::overrideSelection(const QMimeData &mimeData) Surface *focusSurface = dev->keyboardFocus(); if (focusSurface) offerFromCompositorToClient( - dev->dataDevice(focusSurface->base()->resource.client)->dataDeviceResource()); + dev->dataDevice(focusSurface->resource()->client())->dataDeviceResource()); } bool DataDeviceManager::offerFromCompositorToClient(wl_resource *clientDataDeviceResource) diff --git a/src/compositor/wayland_wrapper/qwlextendedoutput.cpp b/src/compositor/wayland_wrapper/qwlextendedoutput.cpp index 8249f272..e376e0b4 100644 --- a/src/compositor/wayland_wrapper/qwlextendedoutput.cpp +++ b/src/compositor/wayland_wrapper/qwlextendedoutput.cpp @@ -49,74 +49,45 @@ QT_BEGIN_NAMESPACE namespace QtWayland { OutputExtensionGlobal::OutputExtensionGlobal(Compositor *compositor) - : m_compositor(compositor) -{ - wl_display_add_global(compositor->wl_display(), - &wl_output_extension_interface, - this, - OutputExtensionGlobal::bind_func); -} - -void OutputExtensionGlobal::bind_func(wl_client *client, void *data, uint32_t version, uint32_t id) + : QtWaylandServer::qt_output_extension(compositor->wl_display()) + , m_compositor(compositor) { - Q_UNUSED(version); - wl_client_add_object(client,&wl_output_extension_interface,&output_extension_interface,id,data); } -void OutputExtensionGlobal::get_extended_output(wl_client *client, wl_resource *output_extension_resource, uint32_t id, wl_resource *output_resource) +void OutputExtensionGlobal::output_extension_get_extended_output(qt_output_extension::Resource *resource, uint32_t id, wl_resource *output_resource) { - OutputExtensionGlobal *output_extension = static_cast<OutputExtensionGlobal *>(output_extension_resource->data); - Output *output = static_cast<Output *>(output_resource->data); - new ExtendedOutput(client,id,output,output_extension->m_compositor); -} + Output *output = static_cast<Output *>(OutputGlobal::Resource::fromResource(output_resource)); + Q_ASSERT(output->extendedOutput == 0); -const struct wl_output_extension_interface OutputExtensionGlobal::output_extension_interface = { - OutputExtensionGlobal::get_extended_output -}; + ExtendedOutput *extendedOutput = static_cast<ExtendedOutput *>(qt_extended_output::add(resource->client(), id)); -ExtendedOutput::ExtendedOutput(struct wl_client *client, uint32_t id, Output *output, Compositor *compositor) - : m_output(output) - , m_compositor(compositor) -{ - static const struct wl_extended_output_interface extended_output_interface = { - set_orientation_update_mask - }; - Q_ASSERT(m_output->extendedOutput() == 0); - m_output->setExtendedOutput(this); - m_extended_output_resource = wl_client_add_object(client,&wl_extended_output_interface,&extended_output_interface,id,this); - m_extended_output_resource->destroy = ExtendedOutput::destroy_resource; - - sendOutputOrientation(m_compositor->screenOrientation()); -} + Q_ASSERT(!output->extendedOutput); + output->extendedOutput = extendedOutput; + extendedOutput->output = output; -void ExtendedOutput::destroy_resource(wl_resource *resource) -{ - ExtendedOutput *output = static_cast<ExtendedOutput *>(resource->data); - delete output; - free(resource); + extendedOutput->sendOutputOrientation(m_compositor->screenOrientation()); } -void ExtendedOutput::set_orientation_update_mask(struct wl_client *client, - struct wl_resource *resource, - int32_t orientation_update_mask) +void OutputExtensionGlobal::extended_output_set_orientation_update_mask(qt_extended_output::Resource *resource, + int32_t orientation_update_mask) { - ExtendedOutput *output = static_cast<ExtendedOutput *>(resource->data); + ExtendedOutput *output = static_cast<ExtendedOutput *>(resource); Qt::ScreenOrientations mask = 0; - if (orientation_update_mask & WL_EXTENDED_OUTPUT_ROTATION_PORTRAITORIENTATION) + if (orientation_update_mask & QT_EXTENDED_OUTPUT_ROTATION_PORTRAITORIENTATION) mask |= Qt::PortraitOrientation; - if (orientation_update_mask & WL_EXTENDED_OUTPUT_ROTATION_LANDSCAPEORIENTATION) + if (orientation_update_mask & QT_EXTENDED_OUTPUT_ROTATION_LANDSCAPEORIENTATION) mask |= Qt::LandscapeOrientation; - if (orientation_update_mask & WL_EXTENDED_OUTPUT_ROTATION_INVERTEDPORTRAITORIENTATION) + if (orientation_update_mask & QT_EXTENDED_OUTPUT_ROTATION_INVERTEDPORTRAITORIENTATION) mask |= Qt::InvertedPortraitOrientation; - if (orientation_update_mask & WL_EXTENDED_OUTPUT_ROTATION_INVERTEDLANDSCAPEORIENTATION) + if (orientation_update_mask & QT_EXTENDED_OUTPUT_ROTATION_INVERTEDLANDSCAPEORIENTATION) mask |= Qt::InvertedLandscapeOrientation; - Qt::ScreenOrientations oldMask = output->m_orientationUpdateMask; - output->m_orientationUpdateMask = mask; + Qt::ScreenOrientations oldMask = output->orientationUpdateMask; + output->orientationUpdateMask = mask; if (mask != oldMask) { - QList<Surface*> surfaces = output->m_compositor->surfacesForClient(client); + QList<Surface*> surfaces = m_compositor->surfacesForClient(resource->client()); foreach (Surface *surface, surfaces) { if (surface->waylandSurface()) emit surface->waylandSurface()->orientationUpdateMaskChanged(); @@ -126,24 +97,25 @@ void ExtendedOutput::set_orientation_update_mask(struct wl_client *client, void ExtendedOutput::sendOutputOrientation(Qt::ScreenOrientation orientation) { - int sendOpperation; + int sendOperation; switch (orientation) { case Qt::PortraitOrientation: - sendOpperation = WL_EXTENDED_OUTPUT_ROTATION_PORTRAITORIENTATION; + sendOperation = QT_EXTENDED_OUTPUT_ROTATION_PORTRAITORIENTATION; break; case Qt::LandscapeOrientation: - sendOpperation = WL_EXTENDED_OUTPUT_ROTATION_LANDSCAPEORIENTATION; + sendOperation = QT_EXTENDED_OUTPUT_ROTATION_LANDSCAPEORIENTATION; break; case Qt::InvertedPortraitOrientation: - sendOpperation = WL_EXTENDED_OUTPUT_ROTATION_INVERTEDPORTRAITORIENTATION; + sendOperation = QT_EXTENDED_OUTPUT_ROTATION_INVERTEDPORTRAITORIENTATION; break; case Qt::InvertedLandscapeOrientation: - sendOpperation = WL_EXTENDED_OUTPUT_ROTATION_INVERTEDLANDSCAPEORIENTATION; + sendOperation = QT_EXTENDED_OUTPUT_ROTATION_INVERTEDLANDSCAPEORIENTATION; break; default: - sendOpperation = WL_EXTENDED_OUTPUT_ROTATION_PORTRAITORIENTATION; + sendOperation = QT_EXTENDED_OUTPUT_ROTATION_PORTRAITORIENTATION; } - wl_extended_output_send_set_screen_rotation(m_extended_output_resource, sendOpperation); + + extended_output->send_set_screen_rotation(handle, sendOperation); } } diff --git a/src/compositor/wayland_wrapper/qwlextendedoutput_p.h b/src/compositor/wayland_wrapper/qwlextendedoutput_p.h index 46c56beb..d1704b8c 100644 --- a/src/compositor/wayland_wrapper/qwlextendedoutput_p.h +++ b/src/compositor/wayland_wrapper/qwlextendedoutput_p.h @@ -42,12 +42,13 @@ #define WLEXTENDEDOUTPUT_H #include "wayland-server.h" -#include "wayland-output-extension-server-protocol.h" #include <QtCompositor/qwaylandexport.h> #include <QtCore/qnamespace.h> +#include <qwayland-server-output-extension.h> + QT_BEGIN_NAMESPACE namespace QtWayland { @@ -55,46 +56,36 @@ namespace QtWayland { class Compositor; class Output; -class OutputExtensionGlobal +class ExtendedOutput : public QtWaylandServer::qt_extended_output::Resource { public: - OutputExtensionGlobal(Compositor *compositor); + ExtendedOutput() : output(0) {} -private: - Compositor *m_compositor; - - static void bind_func(struct wl_client *client, void *data, - uint32_t version, uint32_t id); - static void get_extended_output(struct wl_client *client, - struct wl_resource *output_extension_resource, - uint32_t id, - struct wl_resource *output_resource); - static const struct wl_output_extension_interface output_extension_interface; + void sendOutputOrientation(Qt::ScreenOrientation orientation); + Output *output; + Qt::ScreenOrientations orientationUpdateMask; }; -class ExtendedOutput +class OutputExtensionGlobal : public QtWaylandServer::qt_output_extension, public QtWaylandServer::qt_extended_output { public: - ExtendedOutput(struct wl_client *client, uint32_t id, Output *output, Compositor *compositor); - - Qt::ScreenOrientations orientationUpdateMask() { return m_orientationUpdateMask; } + OutputExtensionGlobal(Compositor *compositor); - void sendOutputOrientation(Qt::ScreenOrientation orientation); +private: + Compositor *m_compositor; - static void destroy_resource(wl_resource *resource); + qt_extended_output::Resource *extended_output_allocate() Q_DECL_OVERRIDE { return new ExtendedOutput; } - static void set_orientation_update_mask(struct wl_client *client, - struct wl_resource *resource, - int32_t orientation_update_mask); + void extended_output_set_orientation_update_mask(qt_extended_output::Resource *resource, + int32_t orientation_update_mask) Q_DECL_OVERRIDE; -private: - struct wl_resource *m_extended_output_resource; - Output *m_output; - Compositor *m_compositor; - Qt::ScreenOrientations m_orientationUpdateMask; + void output_extension_get_extended_output(qt_output_extension::Resource *resource, + uint32_t id, + struct wl_resource *output_resource) Q_DECL_OVERRIDE; }; + } QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlextendedsurface.cpp b/src/compositor/wayland_wrapper/qwlextendedsurface.cpp index 5cbff270..19df7eb2 100644 --- a/src/compositor/wayland_wrapper/qwlextendedsurface.cpp +++ b/src/compositor/wayland_wrapper/qwlextendedsurface.cpp @@ -51,7 +51,7 @@ SurfaceExtensionGlobal::SurfaceExtensionGlobal(Compositor *compositor) : m_compositor(compositor) { wl_display_add_global(m_compositor->wl_display(), - &wl_surface_extension_interface, + &qt_surface_extension_interface, this, SurfaceExtensionGlobal::bind_func); } @@ -60,10 +60,10 @@ void SurfaceExtensionGlobal::bind_func(struct wl_client *client, void *data, uint32_t version, uint32_t id) { Q_UNUSED(version); - wl_client_add_object(client, &wl_surface_extension_interface,&surface_extension_interface,id,data); + wl_client_add_object(client, &qt_surface_extension_interface,&surface_extension_interface,id,data); } -const struct wl_surface_extension_interface SurfaceExtensionGlobal::surface_extension_interface = { +const struct qt_surface_extension_interface SurfaceExtensionGlobal::surface_extension_interface = { SurfaceExtensionGlobal::get_extended_surface }; @@ -73,7 +73,7 @@ void SurfaceExtensionGlobal::get_extended_surface(struct wl_client *client, struct wl_resource *surface_resource) { Q_UNUSED(surface_extension_resource); - Surface *surface = resolve<Surface>(surface_resource); + Surface *surface = Surface::fromResource(surface_resource); new ExtendedSurface(client,id,surface); } @@ -84,7 +84,7 @@ ExtendedSurface::ExtendedSurface(struct wl_client *client, uint32_t id, Surface { Q_ASSERT(surface->extendedSurface() == 0); m_extended_surface_resource = wl_client_add_object(client, - &wl_extended_surface_interface, + &qt_extended_surface_interface, &extended_surface_interface, id, this); @@ -105,14 +105,14 @@ void ExtendedSurface::sendGenericProperty(const QString &name, const QVariant &v data.size = byteValue.size(); data.data = (void*) byteValue.constData(); data.alloc = 0; - wl_extended_surface_send_set_generic_property(m_extended_surface_resource, qPrintable(name), &data); + qt_extended_surface_send_set_generic_property(m_extended_surface_resource, qPrintable(name), &data); } void ExtendedSurface::sendOnScreenVisibility(bool visible) { int32_t visibleInt = visible; - wl_extended_surface_send_onscreen_visibility(m_extended_surface_resource, visibleInt); + qt_extended_surface_send_onscreen_visibility(m_extended_surface_resource, visibleInt); } @@ -131,10 +131,10 @@ void ExtendedSurface::update_generic_property(wl_client *client, wl_resource *ex static Qt::ScreenOrientation screenOrientationFromWaylandOrientation(int32_t orientation) { switch (orientation) { - case WL_EXTENDED_SURFACE_ORIENTATION_PORTRAITORIENTATION: return Qt::PortraitOrientation; - case WL_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION: return Qt::InvertedPortraitOrientation; - case WL_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION: return Qt::LandscapeOrientation; - case WL_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION: return Qt::InvertedLandscapeOrientation; + case QT_EXTENDED_SURFACE_ORIENTATION_PORTRAITORIENTATION: return Qt::PortraitOrientation; + case QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION: return Qt::InvertedPortraitOrientation; + case QT_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION: return Qt::LandscapeOrientation; + case QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION: return Qt::InvertedLandscapeOrientation; default: return Qt::PrimaryOrientation; } } @@ -191,7 +191,7 @@ void ExtendedSurface::set_window_flags(wl_client *client, wl_resource *resource, extended_surface->setWindowFlags(QWaylandSurface::WindowFlags(flags)); } -const struct wl_extended_surface_interface ExtendedSurface::extended_surface_interface = { +const struct qt_extended_surface_interface ExtendedSurface::extended_surface_interface = { ExtendedSurface::update_generic_property, ExtendedSurface::set_content_orientation, ExtendedSurface::set_window_flags diff --git a/src/compositor/wayland_wrapper/qwlextendedsurface_p.h b/src/compositor/wayland_wrapper/qwlextendedsurface_p.h index 6dc60efb..db9a2e8a 100644 --- a/src/compositor/wayland_wrapper/qwlextendedsurface_p.h +++ b/src/compositor/wayland_wrapper/qwlextendedsurface_p.h @@ -72,7 +72,7 @@ private: struct wl_resource *resource, uint32_t id, struct wl_resource *surface); - static const struct wl_surface_extension_interface surface_extension_interface; + static const struct qt_surface_extension_interface surface_extension_interface; }; @@ -128,7 +128,7 @@ private: int32_t flags); void setWindowFlags(QWaylandSurface::WindowFlags flags); - static const struct wl_extended_surface_interface extended_surface_interface; + static const struct qt_extended_surface_interface extended_surface_interface; }; } diff --git a/src/compositor/wayland_wrapper/qwlinputdevice.cpp b/src/compositor/wayland_wrapper/qwlinputdevice.cpp index 8591de25..e75d9833 100644 --- a/src/compositor/wayland_wrapper/qwlinputdevice.cpp +++ b/src/compositor/wayland_wrapper/qwlinputdevice.cpp @@ -65,15 +65,12 @@ QT_BEGIN_NAMESPACE namespace QtWayland { InputDevice::InputDevice(QWaylandInputDevice *handle, Compositor *compositor) - : m_handle(handle) + : QtWaylandServer::wl_seat(compositor->wl_display()) + , m_handle(handle) , m_compositor(compositor) { - wl_seat_init(base()); + wl_seat_init(&m_seat); initDevices(); - wl_display_add_global(compositor->wl_display(), - &wl_seat_interface, - this, - InputDevice::bind_func); #ifndef QT_NO_WAYLAND_XKB xkb_rule_names xkb_names; @@ -150,13 +147,13 @@ InputDevice::~InputDevice() void InputDevice::initDevices() { wl_pointer_init(&m_device_interfaces.pointer); - wl_seat_set_pointer(base(), &m_device_interfaces.pointer); + wl_seat_set_pointer(&m_seat, &m_device_interfaces.pointer); wl_keyboard_init(&m_device_interfaces.keyboard); - wl_seat_set_keyboard(base(), &m_device_interfaces.keyboard); + wl_seat_set_keyboard(&m_seat, &m_device_interfaces.keyboard); wl_touch_init(&m_device_interfaces.touch); - wl_seat_set_touch(base(), &m_device_interfaces.touch); + wl_seat_set_touch(&m_seat, &m_device_interfaces.touch); } void InputDevice::releaseDevices() @@ -196,129 +193,71 @@ const wl_touch *InputDevice::touchDevice() const return &m_device_interfaces.touch; } -void InputDevice::destroy_resource(wl_resource *resource) +void InputDevice::seat_destroy_resource(wl_seat::Resource *resource) { - InputDevice *input_device = static_cast<InputDevice *>(resource->data); - if (input_device->keyboardDevice()->focus_resource == resource) { - input_device->keyboardDevice()->focus_resource = 0; - } - if (input_device->pointerDevice()->focus_resource == resource) { - input_device->pointerDevice()->focus_resource = 0; - } + if (keyboardDevice()->focus_resource == resource->handle) + keyboardDevice()->focus_resource = 0; - input_device->cleanupDataDeviceForClient(resource->client, true); + if (pointerDevice()->focus_resource == resource->handle) + pointerDevice()->focus_resource = 0; - wl_list_remove(&resource->link); - - free(resource); + cleanupDataDeviceForClient(resource->client(), true); } -void InputDevice::bind_func(struct wl_client *client, void *data, - uint32_t version, uint32_t id) +void InputDevice::seat_bind_resource(wl_seat::Resource *resource) { - Q_UNUSED(version); - struct wl_resource *resource = wl_client_add_object(client, - &wl_seat_interface, - &seat_interface, - id, - data); - - struct wl_seat *seat = static_cast<struct wl_seat *>(data); - resource->destroy = destroy_resource; - wl_list_insert(&seat->base_resource_list, &resource->link); + wl_list_insert(&m_seat.base_resource_list, &resource->handle->link); uint32_t caps = WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_KEYBOARD; if (!QTouchDevice::devices().isEmpty()) caps |= WL_SEAT_CAPABILITY_TOUCH; - wl_seat_send_capabilities(resource, caps); + wl_seat::send_capabilities(resource->handle, caps); } -const struct wl_pointer_interface InputDevice::pointer_interface = { - InputDevice::set_cursor -}; - -void InputDevice::set_cursor(wl_client *client, wl_resource *resource, - uint32_t serial, wl_resource *surface_resource, - int32_t hotspot_x, int32_t hotspot_y) +void InputDevice::pointer_set_cursor(wl_pointer::Resource *resource, + uint32_t serial, wl_resource *surface_resource, + int32_t hotspot_x, int32_t hotspot_y) { - Q_UNUSED(client); + Q_UNUSED(resource); Q_UNUSED(serial); - wl_pointer *pointer = reinterpret_cast<wl_pointer *>(resource->data); - InputDevice *inputDevice = wayland_cast<InputDevice>(pointer->seat); - QtWayland::Surface *surface = reinterpret_cast<QtWayland::Surface *>(surface_resource->data); + QtWayland::Surface *surface = QtWayland::Surface::fromResource(surface_resource); surface->setCursorSurface(true); - inputDevice->m_compositor->waylandCompositor()->setCursorSurface(surface->waylandSurface(), hotspot_x, hotspot_y); + m_compositor->waylandCompositor()->setCursorSurface(surface->waylandSurface(), hotspot_x, hotspot_y); } -const struct wl_seat_interface InputDevice::seat_interface = { - get_pointer, - get_keyboard, - get_touch -}; - -void InputDevice::destroy_device_resource(wl_resource *resource) +void InputDevice::seat_get_pointer(wl_seat::Resource *resource, uint32_t id) { - wl_list_remove(&resource->link); - free(resource); + ::wl_pointer *pointer = pointerDevice(); + wl_pointer::add(&pointer->resource_list, resource->client(), id); } -void InputDevice::get_pointer(struct wl_client *client, - struct wl_resource *resource, - uint32_t id) +void InputDevice::seat_get_keyboard(wl_seat::Resource *resource, uint32_t id) { - InputDevice *inputDevice = static_cast<InputDevice *>(resource->data); - wl_pointer *pointer = inputDevice->pointerDevice(); - wl_resource *clientResource = wl_client_add_object(client, - &wl_pointer_interface, - &pointer_interface, - id, - pointer); - wl_list_insert(&pointer->resource_list, &clientResource->link); - clientResource->destroy = InputDevice::destroy_device_resource; + ::wl_keyboard *keyboard = keyboardDevice(); + wl_keyboard::add(&keyboard->resource_list, resource->client(), id); } -void InputDevice::get_keyboard(struct wl_client *client, - struct wl_resource *resource, - uint32_t id) +void InputDevice::keyboard_bind_resource(wl_keyboard::Resource *resource) { - InputDevice *inputDevice = static_cast<InputDevice *>(resource->data); - wl_keyboard *keyboard = inputDevice->keyboardDevice(); - wl_resource *clientResource = wl_client_add_object(client, - &wl_keyboard_interface, - 0, - id, - keyboard); - wl_list_insert(&keyboard->resource_list, &clientResource->link); - clientResource->destroy = InputDevice::destroy_device_resource; - #ifndef QT_NO_WAYLAND_XKB - wl_keyboard_send_keymap(clientResource, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, - inputDevice->m_keymap_fd, inputDevice->m_keymap_size); + wl_keyboard::send_keymap(resource->handle, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, + m_keymap_fd, m_keymap_size); #endif } -void InputDevice::get_touch(struct wl_client *client, - struct wl_resource *resource, - uint32_t id) +void InputDevice::seat_get_touch(wl_seat::Resource *resource, uint32_t id) { - InputDevice *inputDevice = static_cast<InputDevice *>(resource->data); - wl_touch *touch = inputDevice->touchDevice(); - wl_resource *clientResource = wl_client_add_object(client, - &wl_touch_interface, - 0, - id, - touch); - wl_list_insert(&touch->resource_list, &clientResource->link); - clientResource->destroy = InputDevice::destroy_device_resource; + ::wl_touch *touch = touchDevice(); + wl_touch::add(&touch->resource_list, resource->client(), id); } void InputDevice::sendMousePressEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos) { sendMouseMoveEvent(localPos,globalPos); - wl_pointer *pointer = pointerDevice(); + ::wl_pointer *pointer = pointerDevice(); pointer->button_count++; uint32_t time = m_compositor->currentTimeMsecs(); const struct wl_pointer_grab_interface *interface = pointer->grab->interface; @@ -328,7 +267,7 @@ void InputDevice::sendMousePressEvent(Qt::MouseButton button, const QPointF &loc void InputDevice::sendMouseReleaseEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos) { sendMouseMoveEvent(localPos,globalPos); - wl_pointer *pointer = pointerDevice(); + ::wl_pointer *pointer = pointerDevice(); pointer->button_count--; uint32_t time = m_compositor->currentTimeMsecs(); const struct wl_pointer_grab_interface *interface = pointer->grab->interface; @@ -339,7 +278,7 @@ void InputDevice::sendMouseMoveEvent(const QPointF &localPos, const QPointF &glo { Q_UNUSED(globalPos); uint32_t time = m_compositor->currentTimeMsecs(); - wl_pointer *pointer = pointerDevice(); + ::wl_pointer *pointer = pointerDevice(); const struct wl_pointer_grab_interface *interface = pointer->grab->interface; pointer->x = wl_fixed_from_double(globalPos.x()); pointer->y = wl_fixed_from_double(globalPos.y()); @@ -356,7 +295,7 @@ void InputDevice::sendMouseMoveEvent(Surface *surface, const QPointF &localPos, void InputDevice::sendMouseWheelEvent(Qt::Orientation orientation, int delta) { - wl_pointer *pointer = pointerDevice(); + ::wl_pointer *pointer = pointerDevice(); struct wl_resource *resource = pointer->focus_resource; if (!resource) return; @@ -376,7 +315,7 @@ void InputDevice::updateModifierState(uint code, int state) uint32_t mods_locked = xkb_state_serialize_mods(m_state, (xkb_state_component)XKB_STATE_LATCHED); uint32_t group = xkb_state_serialize_group(m_state, (xkb_state_component)XKB_STATE_EFFECTIVE); - wl_keyboard *keyboard = keyboardDevice(); + ::wl_keyboard *keyboard = keyboardDevice(); if (mods_depressed == keyboard->modifiers.mods_depressed && mods_latched == keyboard->modifiers.mods_latched @@ -401,7 +340,7 @@ void InputDevice::updateModifierState(uint code, int state) void InputDevice::sendKeyModifiers(wl_resource *resource) { - wl_keyboard *keyboard = keyboardDevice(); + ::wl_keyboard *keyboard = keyboardDevice(); uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); wl_keyboard_send_modifiers(resource, serial, keyboard->modifiers.mods_depressed, keyboard->modifiers.mods_latched, keyboard->modifiers.mods_locked, keyboard->modifiers.group); @@ -409,7 +348,7 @@ void InputDevice::sendKeyModifiers(wl_resource *resource) void InputDevice::sendKeyPressEvent(uint code) { - wl_keyboard *keyboard = keyboardDevice(); + ::wl_keyboard *keyboard = keyboardDevice(); if (keyboard->focus_resource) { uint32_t time = m_compositor->currentTimeMsecs(); uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); @@ -421,7 +360,7 @@ void InputDevice::sendKeyPressEvent(uint code) void InputDevice::sendKeyReleaseEvent(uint code) { - wl_keyboard *keyboard = keyboardDevice(); + ::wl_keyboard *keyboard = keyboardDevice(); if (keyboard->focus_resource) { uint32_t time = m_compositor->currentTimeMsecs(); uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); @@ -435,7 +374,7 @@ void InputDevice::sendTouchPointEvent(int id, double x, double y, Qt::TouchPoint { uint32_t time = m_compositor->currentTimeMsecs(); uint32_t serial = 0; - wl_touch *touch = touchDevice(); + ::wl_touch *touch = touchDevice(); wl_resource *resource = touch->focus_resource; if (!resource) return; @@ -461,7 +400,7 @@ void InputDevice::sendTouchPointEvent(int id, double x, double y, Qt::TouchPoint void InputDevice::sendTouchFrameEvent() { - wl_touch *touch = touchDevice(); + ::wl_touch *touch = touchDevice(); wl_resource *resource = touch->focus_resource; if (resource) wl_touch_send_frame(resource); @@ -469,7 +408,7 @@ void InputDevice::sendTouchFrameEvent() void InputDevice::sendTouchCancelEvent() { - wl_touch *touch = touchDevice(); + ::wl_touch *touch = touchDevice(); wl_resource *resource = touch->focus_resource; if (resource) wl_touch_send_cancel(resource); @@ -525,7 +464,7 @@ void InputDevice::sendFullTouchEvent(QTouchEvent *event) Surface *InputDevice::keyboardFocus() const { - return wayland_cast<Surface>(keyboardDevice()->focus); + return static_cast<Surface *>(keyboardDevice()->focus); } /*! @@ -537,31 +476,30 @@ bool InputDevice::setKeyboardFocus(Surface *surface) return false; sendSelectionFocus(surface); - wl_keyboard_set_focus(keyboardDevice(), surface ? surface->base() : 0); + wl_keyboard_set_focus(keyboardDevice(), surface); return true; } Surface *InputDevice::mouseFocus() const { - return wayland_cast<Surface>(pointerDevice()->focus); + return static_cast<Surface *>(pointerDevice()->focus); } void InputDevice::setMouseFocus(Surface *surface, const QPointF &localPos, const QPointF &globalPos) { - wl_pointer *pointer = pointerDevice(); + ::wl_pointer *pointer = pointerDevice(); pointer->x = wl_fixed_from_double(globalPos.x()); pointer->y = wl_fixed_from_double(globalPos.y()); - pointer->current = surface ? surface->base() : 0; + pointer->current = surface; pointer->current_x = wl_fixed_from_double(localPos.x()); pointer->current_y = wl_fixed_from_double(localPos.y()); - pointer->grab->interface->focus(pointer->grab, - surface ? surface->base() : 0, + pointer->grab->interface->focus(pointer->grab, surface, wl_fixed_from_double(localPos.x()), wl_fixed_from_double(localPos.y())); // We have no separate touch focus management so make it match the pointer focus always. // No wl_touch_set_focus() is available so set it manually. - wl_touch *touch = touchDevice(); - touch->focus = surface ? surface->base() : 0; + ::wl_touch *touch = touchDevice(); + touch->focus = surface; touch->focus_resource = Compositor::resourceForSurface(&touch->resource_list, surface); } @@ -590,7 +528,7 @@ void InputDevice::sendSelectionFocus(Surface *surface) { if (!surface) return; - DataDevice *device = dataDevice(surface->base()->resource.client); + DataDevice *device = dataDevice(surface->resource()->client()); if (device) { device->sendSelectionFocus(); } diff --git a/src/compositor/wayland_wrapper/qwlinputdevice_p.h b/src/compositor/wayland_wrapper/qwlinputdevice_p.h index 9365fa9d..fd1b0fb4 100644 --- a/src/compositor/wayland_wrapper/qwlinputdevice_p.h +++ b/src/compositor/wayland_wrapper/qwlinputdevice_p.h @@ -41,8 +41,6 @@ #ifndef WLINPUTDEVICE_H #define WLINPUTDEVICE_H -#include <QtCompositor/qwaylandobject.h> - #include <stdint.h> #include <QtCore/QList> @@ -52,6 +50,8 @@ #include <xkbcommon/xkbcommon.h> #endif +#include <qwayland-server-wayland.h> + QT_BEGIN_NAMESPACE class QKeyEvent; @@ -65,7 +65,7 @@ class DataDevice; class Surface; class DataDeviceManager; -class InputDevice : public Object<struct wl_seat> +class InputDevice : public QtWaylandServer::wl_seat, public QtWaylandServer::wl_pointer, public QtWaylandServer::wl_keyboard, public QtWaylandServer::wl_touch { public: InputDevice(QWaylandInputDevice *handle, Compositor *compositor); @@ -100,12 +100,18 @@ public: Compositor *compositor() const; QWaylandInputDevice *handle() const; - wl_pointer *pointerDevice(); - wl_keyboard *keyboardDevice(); - wl_touch *touchDevice(); - const wl_pointer *pointerDevice() const; - const wl_keyboard *keyboardDevice() const; - const wl_touch *touchDevice() const; + ::wl_pointer *pointerDevice(); + ::wl_keyboard *keyboardDevice(); + ::wl_touch *touchDevice(); + + const ::wl_pointer *pointerDevice() const; + const ::wl_keyboard *keyboardDevice() const; + const ::wl_touch *touchDevice() const; + + static InputDevice *fromSeatResource(struct ::wl_resource *resource) + { + return static_cast<InputDevice *>(wl_seat::Resource::fromResource(resource)->seat); + } private: void initDevices(); @@ -117,12 +123,15 @@ private: QWaylandInputDevice *m_handle; Compositor *m_compositor; QList<DataDevice *> m_data_devices; + struct { - wl_pointer pointer; - wl_keyboard keyboard; - wl_touch touch; + ::wl_pointer pointer; + ::wl_keyboard keyboard; + ::wl_touch touch; } m_device_interfaces; + ::wl_seat m_seat; + #ifndef QT_NO_WAYLAND_XKB struct xkb_keymap *m_keymap; struct xkb_state *m_state; @@ -133,30 +142,24 @@ private: uint32_t toWaylandButton(Qt::MouseButton button); - static void bind_func(struct wl_client *client, void *data, - uint32_t version, uint32_t id); - - static void set_cursor(struct wl_client *client, - struct wl_resource *device_base, - uint32_t serial, - struct wl_resource *surface, - int32_t hotspot_x, - int32_t hotspot_y); - const static struct wl_pointer_interface pointer_interface; - - static void get_pointer(struct wl_client *client, - struct wl_resource *resource, - uint32_t id); - static void get_keyboard(struct wl_client *client, - struct wl_resource *resource, - uint32_t id); - static void get_touch(struct wl_client *client, - struct wl_resource *resource, - uint32_t id); - const static struct wl_seat_interface seat_interface; - - static void destroy_resource(wl_resource *resource); - static void destroy_device_resource(wl_resource *resource); + void seat_bind_resource(wl_seat::Resource *resource) Q_DECL_OVERRIDE; + + void pointer_set_cursor(wl_pointer::Resource *resource, + uint32_t serial, + struct wl_resource *surface, + int32_t hotspot_x, + int32_t hotspot_y) Q_DECL_OVERRIDE; + + void keyboard_bind_resource(wl_keyboard::Resource *resource) Q_DECL_OVERRIDE; + + void seat_get_pointer(wl_seat::Resource *resource, + uint32_t id) Q_DECL_OVERRIDE; + void seat_get_keyboard(wl_seat::Resource *resource, + uint32_t id) Q_DECL_OVERRIDE; + void seat_get_touch(wl_seat::Resource *resource, + uint32_t id) Q_DECL_OVERRIDE; + + void seat_destroy_resource(wl_seat::Resource *resource) Q_DECL_OVERRIDE; }; } diff --git a/src/compositor/wayland_wrapper/qwloutput.cpp b/src/compositor/wayland_wrapper/qwloutput.cpp index f248dccd..bb516f8c 100644 --- a/src/compositor/wayland_wrapper/qwloutput.cpp +++ b/src/compositor/wayland_wrapper/qwloutput.cpp @@ -44,12 +44,15 @@ #include <QtGui/QScreen> #include <QRect> +#include "qwaylandresourcecollection.h" + QT_BEGIN_NAMESPACE namespace QtWayland { -OutputGlobal::OutputGlobal() - : m_displayId(-1) +OutputGlobal::OutputGlobal(struct ::wl_display *display) + : QtWaylandServer::wl_output(display) + , m_displayId(-1) , m_numQueued(0) { QScreen *screen = QGuiApplication::primaryScreen(); @@ -59,7 +62,15 @@ OutputGlobal::OutputGlobal() OutputGlobal::~OutputGlobal() { - qDeleteAll(m_outputs); +} + +void OutputGlobal::output_bind_resource(Resource *resource) +{ + wl_output_send_geometry(resource->handle, 0, 0, + size().width(), size().height(), 0, "", "", 0); + + wl_output_send_mode(resource->handle, WL_OUTPUT_MODE_CURRENT|WL_OUTPUT_MODE_PREFERRED, + size().width(), size().height(), refreshRate()); } void OutputGlobal::setGeometry(const QRect &geometry) @@ -74,53 +85,7 @@ void OutputGlobal::setRefreshRate(int rate) Output *OutputGlobal::outputForClient(wl_client *client) const { - return static_cast<Output *>(resourceForClient(client)->data); -} - -void OutputGlobal::output_bind_func(struct wl_client *client, void *data, - uint32_t version, uint32_t id) -{ - Q_UNUSED(version); - OutputGlobal *output_global = static_cast<OutputGlobal *>(data); - - Output *output = new Output(output_global,client,version,id); - output_global->registerResource(output->handle()); - output_global->m_outputs.append(output); -} - - - -Output::Output(OutputGlobal *outputGlobal, wl_client *client, uint32_t version, uint32_t id) - : m_output_global(outputGlobal) - , m_extended_output(0) -{ - Q_UNUSED(version); - m_output_resource = wl_client_add_object(client,&wl_output_interface,0,id,this); - wl_output_send_geometry(m_output_resource, 0, 0, - m_output_global->size().width(), m_output_global->size().height(),0,"","",0); - - wl_output_send_mode(m_output_resource, WL_OUTPUT_MODE_CURRENT|WL_OUTPUT_MODE_PREFERRED, - m_output_global->size().width(), m_output_global->size().height(), m_output_global->refreshRate()); - -} - -Output::~Output() -{ -} - -ExtendedOutput *Output::extendedOutput() const -{ - return m_extended_output; -} - -void Output::setExtendedOutput(ExtendedOutput *extendedOutput) -{ - m_extended_output = extendedOutput; -} - -wl_resource *Output::handle() const -{ - return m_output_resource; + return static_cast<Output *>(resourceForClient(resourceList(), client)->data); } } // namespace Wayland diff --git a/src/compositor/wayland_wrapper/qwloutput_p.h b/src/compositor/wayland_wrapper/qwloutput_p.h index 11341737..514d3e9f 100644 --- a/src/compositor/wayland_wrapper/qwloutput_p.h +++ b/src/compositor/wayland_wrapper/qwloutput_p.h @@ -41,22 +41,27 @@ #ifndef WL_OUTPUT_H #define WL_OUTPUT_H -#include <QtCompositor/qwaylandresourcecollection.h> - #include <QtCore/QRect> #include <QtCore/QList> +#include <qwayland-server-wayland.h> + QT_BEGIN_NAMESPACE namespace QtWayland { -class Output; class ExtendedOutput; -class OutputGlobal : public ResourceCollection +struct Output : public QtWaylandServer::wl_output::Resource +{ + Output() : extendedOutput(0) {} + ExtendedOutput *extendedOutput; +}; + +class OutputGlobal : public QtWaylandServer::wl_output { public: - OutputGlobal(); + OutputGlobal(struct ::wl_display *display); ~OutputGlobal(); void setGeometry(const QRect &geometry); @@ -71,21 +76,21 @@ public: Output *outputForClient(struct wl_client *client) const; - static void output_bind_func(struct wl_client *client, void *data, - uint32_t version, uint32_t id); + void output_bind_resource(Resource *resource) Q_DECL_OVERRIDE; + Resource *output_allocate() Q_DECL_OVERRIDE { return new Output; } + private: QRect m_geometry; int m_refreshRate; int m_displayId; int m_numQueued; - QList<Output *> m_outputs; }; - +#if 0 class Output { public: - Output(OutputGlobal *outputGlobal, wl_client *client, uint32_t version, uint32_t id); + Output(OutputGlobal *outputGlobal, struct ::wl_resource *resource); ~Output(); OutputGlobal *outputGlobal() const; @@ -98,8 +103,8 @@ private: struct wl_resource *m_output_resource; OutputGlobal *m_output_global; ExtendedOutput *m_extended_output; - }; +#endif } diff --git a/src/compositor/wayland_wrapper/qwlqtkey.cpp b/src/compositor/wayland_wrapper/qwlqtkey.cpp index a6fea9f2..6ced2788 100644 --- a/src/compositor/wayland_wrapper/qwlqtkey.cpp +++ b/src/compositor/wayland_wrapper/qwlqtkey.cpp @@ -43,68 +43,35 @@ #include <QKeyEvent> #include <QWindow> +#include "qwaylandresourcecollection.h" + QT_BEGIN_NAMESPACE namespace QtWayland { -static void dummy(wl_client *, wl_resource *) -{ -} - -const struct wl_qtkey_extension_interface QtKeyExtensionGlobal::qtkey_interface = { - dummy -}; - QtKeyExtensionGlobal::QtKeyExtensionGlobal(Compositor *compositor) - : m_compositor(compositor) + : QtWaylandServer::qt_key_extension(compositor->wl_display()) + , m_compositor(compositor) { - wl_display_add_global(compositor->wl_display(), - &wl_qtkey_extension_interface, - this, - QtKeyExtensionGlobal::bind_func); -} - -QtKeyExtensionGlobal::~QtKeyExtensionGlobal() -{ -} - -void QtKeyExtensionGlobal::destroy_resource(wl_resource *resource) -{ - QtKeyExtensionGlobal *self = static_cast<QtKeyExtensionGlobal *>(resource->data); - self->m_resources.removeOne(resource); - free(resource); -} - -void QtKeyExtensionGlobal::bind_func(wl_client *client, void *data, uint32_t version, uint32_t id) -{ - Q_UNUSED(version); - wl_resource *resource = wl_client_add_object(client, &wl_qtkey_extension_interface, &qtkey_interface, id, data); - resource->destroy = destroy_resource; - QtKeyExtensionGlobal *self = static_cast<QtKeyExtensionGlobal *>(resource->data); - self->m_resources.append(resource); } bool QtKeyExtensionGlobal::postQtKeyEvent(QKeyEvent *event, Surface *surface) { - wl_client *surfaceClient = surface->base()->resource.client; - uint32_t time = m_compositor->currentTimeMsecs(); - const int rescount = m_resources.count(); + wl_client *surfaceClient = surface->resource()->client(); - for (int res = 0; res < rescount; ++res) { - wl_resource *target = m_resources.at(res); - if (target->client != surfaceClient) - continue; - - QByteArray textUtf8 = event->text().toUtf8(); + uint32_t time = m_compositor->currentTimeMsecs(); - wl_qtkey_extension_send_qtkey(target, - time, event->type(), event->key(), event->modifiers(), - event->nativeScanCode(), - event->nativeVirtualKey(), - event->nativeModifiers(), - textUtf8.constData(), - event->isAutoRepeat(), - event->count()); + struct wl_resource *target = resourceForClient(resourceList(), surfaceClient); + + if (target) { + send_qtkey(target, + time, event->type(), event->key(), event->modifiers(), + event->nativeScanCode(), + event->nativeVirtualKey(), + event->nativeModifiers(), + event->text(), + event->isAutoRepeat(), + event->count()); return true; } diff --git a/src/compositor/wayland_wrapper/qwlqtkey_p.h b/src/compositor/wayland_wrapper/qwlqtkey_p.h index bb98f9b8..012ef388 100644 --- a/src/compositor/wayland_wrapper/qwlqtkey_p.h +++ b/src/compositor/wayland_wrapper/qwlqtkey_p.h @@ -42,9 +42,11 @@ #define WLQTKEY_H #include <private/qwlcompositor_p.h> -#include "wayland-qtkey-extension-server-protocol.h" + #include "wayland-util.h" +#include "qwayland-server-qtkey-extension.h" + QT_BEGIN_NAMESPACE class Compositor; @@ -53,24 +55,15 @@ class QKeyEvent; namespace QtWayland { -class QtKeyExtensionGlobal +class QtKeyExtensionGlobal : public QtWaylandServer::qt_key_extension { public: QtKeyExtensionGlobal(Compositor *compositor); - ~QtKeyExtensionGlobal(); bool postQtKeyEvent(QKeyEvent *event, Surface *surface); private: - static void bind_func(struct wl_client *client, void *data, - uint32_t version, uint32_t id); - - static void destroy_resource(wl_resource *resource); - - static const struct wl_qtkey_extension_interface qtkey_interface; - Compositor *m_compositor; - QList<wl_resource *> m_resources; }; } diff --git a/src/compositor/wayland_wrapper/qwlregion.cpp b/src/compositor/wayland_wrapper/qwlregion.cpp index c9e45252..69f38240 100644 --- a/src/compositor/wayland_wrapper/qwlregion.cpp +++ b/src/compositor/wayland_wrapper/qwlregion.cpp @@ -46,45 +46,38 @@ QT_BEGIN_NAMESPACE namespace QtWayland { -void destroy_region(struct wl_resource *resource) +Region::Region(struct wl_client *client, uint32_t id) + : QtWaylandServer::wl_region(client, id) { - delete resolve<Region>(resource); } -Region::Region(struct wl_client *client, uint32_t id) +Region::~Region() { - addClientResource(client, base(), id, &wl_region_interface, - ®ion_interface, destroy_region); } -Region::~Region() +Region *Region::fromResource(struct ::wl_resource *resource) { + return static_cast<Region *>(Resource::fromResource(resource)->region); } -const struct wl_region_interface Region::region_interface = { - region_destroy, - region_add, - region_subtract -}; +void Region::region_destroy_resource(Resource *) +{ + delete this; +} -void Region::region_destroy(wl_client *client, wl_resource *region) +void Region::region_destroy(Resource *resource) { - Q_UNUSED(client); - wl_resource_destroy(region); + wl_resource_destroy(resource->handle); } -void Region::region_add(wl_client *client, wl_resource *region, - int32_t x, int32_t y, int32_t w, int32_t h) +void Region::region_add(Resource *, int32_t x, int32_t y, int32_t w, int32_t h) { - Q_UNUSED(client); - resolve<Region>(region)->m_region += QRect(x, y, w, h); + m_region += QRect(x, y, w, h); } -void Region::region_subtract(wl_client *client, wl_resource *region, - int32_t x, int32_t y, int32_t w, int32_t h) +void Region::region_subtract(Resource *, int32_t x, int32_t y, int32_t w, int32_t h) { - Q_UNUSED(client); - resolve<Region>(region)->m_region -= QRect(x, y, w, h); + m_region -= QRect(x, y, w, h); } } diff --git a/src/compositor/wayland_wrapper/qwlregion_p.h b/src/compositor/wayland_wrapper/qwlregion_p.h index 2002e737..f905d96b 100644 --- a/src/compositor/wayland_wrapper/qwlregion_p.h +++ b/src/compositor/wayland_wrapper/qwlregion_p.h @@ -42,38 +42,38 @@ #define WL_REGION_H #include <QtCompositor/qwaylandexport.h> -#include <QtCompositor/qwaylandobject.h> #include <QRegion> #include <wayland-util.h> +#include "qwayland-server-wayland.h" QT_BEGIN_NAMESPACE namespace QtWayland { -class Q_COMPOSITOR_EXPORT Region : public Object<wl_resource> +class Q_COMPOSITOR_EXPORT Region : public QtWaylandServer::wl_region { public: Region(struct wl_client *client, uint32_t id); ~Region(); - uint id() const { return base()->object.id; } + static Region *fromResource(struct ::wl_resource *resource); - QRegion region() const { return m_region; } + uint id() const { return resource()->handle->object.id; } - static const struct wl_region_interface region_interface; + QRegion region() const { return m_region; } private: Q_DISABLE_COPY(Region) QRegion m_region; - static void region_destroy(wl_client *client, wl_resource *region); - static void region_add(wl_client *client, wl_resource *region, - int32_t x, int32_t y, int32_t w, int32_t h); - static void region_subtract(wl_client *client, wl_resource *region, - int32_t x, int32_t y, int32_t w, int32_t h); + void region_destroy_resource(Resource *) Q_DECL_OVERRIDE; + + void region_destroy(Resource *resource) Q_DECL_OVERRIDE; + void region_add(Resource *resource, int32_t x, int32_t y, int32_t w, int32_t h) Q_DECL_OVERRIDE; + void region_subtract(Resource *resource, int32_t x, int32_t y, int32_t w, int32_t h) Q_DECL_OVERRIDE; }; } diff --git a/src/compositor/wayland_wrapper/qwlshellsurface.cpp b/src/compositor/wayland_wrapper/qwlshellsurface.cpp index f8d6e0c5..903b4259 100644 --- a/src/compositor/wayland_wrapper/qwlshellsurface.cpp +++ b/src/compositor/wayland_wrapper/qwlshellsurface.cpp @@ -69,7 +69,7 @@ void Shell::get_shell_surface(struct wl_client *client, struct wl_resource *surface_super) { Q_UNUSED(shell_resource); - Surface *surface = resolve<Surface>(surface_super); + Surface *surface = Surface::fromResource(surface_super); new ShellSurface(client,id,surface); } @@ -78,20 +78,20 @@ const struct wl_shell_interface Shell::shell_interface = { }; ShellSurface::ShellSurface(wl_client *client, uint32_t id, Surface *surface) - : m_surface(surface) + : wl_shell_surface(client, id) + , m_surface(surface) , m_resizeGrabber(0) , m_moveGrabber(0) , m_transientParent(0) , m_xOffset(0) , m_yOffset(0) { - m_shellSurface = wl_client_add_object(client,&wl_shell_surface_interface,&shell_surface_interface,id,this); surface->setShellSurface(this); } void ShellSurface::sendConfigure(uint32_t edges, int32_t width, int32_t height) { - wl_shell_surface_send_configure(m_shellSurface,edges,width,height); + send_configure(edges, width, height); } Surface *ShellSurface::surface() const @@ -148,103 +148,102 @@ void ShellSurface::setOffset(const QPointF &offset) m_yOffset = offset.y(); } -void ShellSurface::move(struct wl_client *client, - struct wl_resource *shell_surface_resource, +void ShellSurface::shell_surface_destroy_resource(Resource *) +{ + delete this; +} + +void ShellSurface::shell_surface_move(Resource *resource, struct wl_resource *input_device_super, uint32_t time) { - Q_UNUSED(client); + Q_UNUSED(resource); Q_UNUSED(time); - ShellSurface *self = static_cast<ShellSurface *>(shell_surface_resource->data); - InputDevice *input_device = static_cast<InputDevice *>(input_device_super->data); - if (self->m_resizeGrabber || self->m_moveGrabber) { + + if (m_resizeGrabber || m_moveGrabber) { qDebug() << "invalid state"; return; } - self->m_moveGrabber = new ShellSurfaceMoveGrabber(self); - wl_pointer *pointer = input_device->pointerDevice(); - self->m_moveGrabber->base()->x = pointer->x; - self->m_moveGrabber->base()->y = pointer->y; - self->m_moveGrabber->offset_x = wl_fixed_to_int(pointer->x) - self->surface()->pos().x(); - self->m_moveGrabber->offset_y = wl_fixed_to_int(pointer->y) - self->surface()->pos().y(); + InputDevice *input_device = InputDevice::fromSeatResource(input_device_super); + ::wl_pointer *pointer = input_device->pointerDevice(); - wl_pointer_start_grab(pointer, self->m_moveGrabber->base()); + m_moveGrabber = new ShellSurfaceMoveGrabber(this); + m_moveGrabber->base()->x = pointer->x; + m_moveGrabber->base()->y = pointer->y; + m_moveGrabber->offset_x = wl_fixed_to_int(pointer->x) - surface()->pos().x(); + m_moveGrabber->offset_y = wl_fixed_to_int(pointer->y) - surface()->pos().y(); + + wl_pointer_start_grab(pointer, m_moveGrabber->base()); } -void ShellSurface::resize(struct wl_client *client, - struct wl_resource *shell_surface_resource, +void ShellSurface::shell_surface_resize(Resource *resource, struct wl_resource *input_device_super, uint32_t time, uint32_t edges) { - Q_UNUSED(shell_surface_resource); - Q_UNUSED(client); + Q_UNUSED(resource); Q_UNUSED(time); Q_UNUSED(edges); - ShellSurface *self = static_cast<ShellSurface *>(shell_surface_resource->data); - InputDevice *input_device = static_cast<InputDevice *>(input_device_super->data); - if (self->m_moveGrabber || self->m_resizeGrabber) { + + if (m_moveGrabber || m_resizeGrabber) { qDebug() << "invalid state2"; return; } - self->m_resizeGrabber = new ShellSurfaceResizeGrabber(self); - wl_pointer *pointer = input_device->pointerDevice(); - self->m_resizeGrabber->base()->x = pointer->x; - self->m_resizeGrabber->base()->y = pointer->y; - self->m_resizeGrabber->resize_edges = wl_shell_surface_resize(edges); - self->m_resizeGrabber->width = self->surface()->size().width(); - self->m_resizeGrabber->height = self->surface()->size().height(); - wl_pointer_start_grab(pointer, self->m_resizeGrabber->base()); + m_resizeGrabber = new ShellSurfaceResizeGrabber(this); + + InputDevice *input_device = InputDevice::fromSeatResource(input_device_super); + ::wl_pointer *pointer = input_device->pointerDevice(); + + m_resizeGrabber->base()->x = pointer->x; + m_resizeGrabber->base()->y = pointer->y; + m_resizeGrabber->resize_edges = wl_shell_surface_resize(edges); + m_resizeGrabber->width = surface()->size().width(); + m_resizeGrabber->height = surface()->size().height(); + + wl_pointer_start_grab(pointer, m_resizeGrabber->base()); } -void ShellSurface::set_toplevel(struct wl_client *client, - struct wl_resource *shell_surface_resource) +void ShellSurface::shell_surface_set_toplevel(Resource *resource) { - Q_UNUSED(client); - ShellSurface *self = static_cast<ShellSurface *>(shell_surface_resource->data); - self->m_transientParent = 0; - self->m_xOffset = 0; - self->m_yOffset = 0; + Q_UNUSED(resource); + m_transientParent = 0; + m_xOffset = 0; + m_yOffset = 0; } -void ShellSurface::set_transient(struct wl_client *client, - struct wl_resource *shell_surface_resource, +void ShellSurface::shell_surface_set_transient(Resource *resource, struct wl_resource *parent_surface_resource, int x, int y, uint32_t flags) { - Q_UNUSED(client); + Q_UNUSED(resource); Q_UNUSED(flags); - ShellSurface *shell_surface = static_cast<ShellSurface *>(shell_surface_resource->data); - Surface *parent_surface = static_cast<Surface *>(parent_surface_resource->data); - shell_surface->m_transientParent = parent_surface->shellSurface(); - shell_surface->m_xOffset = x; - shell_surface->m_yOffset = y; + Surface *parent_surface = Surface::fromResource(parent_surface_resource); + m_transientParent = parent_surface->shellSurface(); + m_xOffset = x; + m_yOffset = y; if (flags & WL_SHELL_SURFACE_TRANSIENT_INACTIVE) - shell_surface->surface()->setTransientInactive(true); + surface()->setTransientInactive(true); } -void ShellSurface::set_fullscreen(struct wl_client *client, - struct wl_resource *shell_surface_resource, +void ShellSurface::shell_surface_set_fullscreen(Resource *resource, uint32_t method, uint32_t framerate, struct wl_resource *output) { - Q_UNUSED(client); - Q_UNUSED(shell_surface_resource); + Q_UNUSED(resource); Q_UNUSED(method); Q_UNUSED(framerate); Q_UNUSED(output); } -void ShellSurface::set_popup(wl_client *client, wl_resource *resource, wl_resource *input_device, uint32_t time, wl_resource *parent, int32_t x, int32_t y, uint32_t flags) +void ShellSurface::shell_surface_set_popup(Resource *resource, wl_resource *input_device, uint32_t time, wl_resource *parent, int32_t x, int32_t y, uint32_t flags) { - Q_UNUSED(client); Q_UNUSED(resource); Q_UNUSED(input_device); Q_UNUSED(time); @@ -254,55 +253,34 @@ void ShellSurface::set_popup(wl_client *client, wl_resource *resource, wl_resour Q_UNUSED(flags); } -void ShellSurface::set_maximized(struct wl_client *client, - struct wl_resource *shell_surface_resource, +void ShellSurface::shell_surface_set_maximized(Resource *resource, struct wl_resource *output) { - Q_UNUSED(client); - Q_UNUSED(shell_surface_resource); + Q_UNUSED(resource); Q_UNUSED(output); } -void ShellSurface::pong(struct wl_client *client, - struct wl_resource *resource, +void ShellSurface::shell_surface_pong(Resource *resource, uint32_t serial) { - Q_UNUSED(client); Q_UNUSED(resource); Q_UNUSED(serial); } -void ShellSurface::set_title(struct wl_client *client, - struct wl_resource *resource, - const char *title) +void ShellSurface::shell_surface_set_title(Resource *resource, + const QString &title) { - Q_UNUSED(client); - ShellSurface *self = static_cast<ShellSurface *>(resource->data); - self->surface()->setTitle(QString::fromUtf8(title)); + Q_UNUSED(resource); + surface()->setTitle(title); } -void ShellSurface::set_class(struct wl_client *client, - struct wl_resource *resource, - const char *class_) +void ShellSurface::shell_surface_set_class(Resource *resource, + const QString &className) { - Q_UNUSED(client); - ShellSurface *self = static_cast<ShellSurface *>(resource->data); - self->surface()->setClassName(QString::fromUtf8(class_)); + Q_UNUSED(resource); + surface()->setClassName(className); } -const struct wl_shell_surface_interface ShellSurface::shell_surface_interface = { - ShellSurface::pong, - ShellSurface::move, - ShellSurface::resize, - ShellSurface::set_toplevel, - ShellSurface::set_transient, - ShellSurface::set_fullscreen, - ShellSurface::set_popup, - ShellSurface::set_maximized, - ShellSurface::set_title, - ShellSurface::set_class -}; - Qt::MouseButton toQtButton(uint32_t button) { #ifndef BTN_LEFT @@ -326,7 +304,7 @@ ShellSurfaceGrabber::ShellSurfaceGrabber(ShellSurface *shellSurface, const struc : shell_surface(shellSurface) { base()->interface = interface; - base()->focus = shell_surface->surface()->base(); + base()->focus = shell_surface->surface(); } ShellSurfaceGrabber::~ShellSurfaceGrabber() @@ -450,7 +428,7 @@ void ShellSurfaceMoveGrabber::motion(wl_pointer_grab *grab, uint32_t time, int32 shell_surface->surface()->setPos(pos); if (shell_surface->transientParent()) shell_surface->setOffset(pos - shell_surface->transientParent()->surface()->pos()); - shell_surface->surface()->damage(QRect(QPoint(0,0),shell_surface->surface()->size())); + } void ShellSurfaceMoveGrabber::button(wl_pointer_grab *grab, uint32_t time, uint32_t button, uint32_t state) diff --git a/src/compositor/wayland_wrapper/qwlshellsurface_p.h b/src/compositor/wayland_wrapper/qwlshellsurface_p.h index 1bb0c4e4..4c296a97 100644 --- a/src/compositor/wayland_wrapper/qwlshellsurface_p.h +++ b/src/compositor/wayland_wrapper/qwlshellsurface_p.h @@ -41,11 +41,12 @@ #ifndef WLSHELLSURFACE_H #define WLSHELLSURFACE_H -#include <QtCompositor/qwaylandobject.h> - #include <wayland-server.h> +#include <qwaylandobject.h> #include <QPoint> +#include <qwayland-server-wayland.h> + QT_BEGIN_NAMESPACE namespace QtWayland { @@ -72,7 +73,7 @@ private: }; -class ShellSurface +class ShellSurface : public QtWaylandServer::wl_shell_surface { public: ShellSurface(struct wl_client *client, uint32_t id, Surface *surface); @@ -89,7 +90,6 @@ public: void setOffset(const QPointF &offset); private: - struct wl_resource *m_shellSurface; Surface *m_surface; ShellSurfaceResizeGrabber *m_resizeGrabber; @@ -100,53 +100,43 @@ private: int32_t m_xOffset; int32_t m_yOffset; - static void move(struct wl_client *client, - struct wl_resource *shell_surface_resource, - struct wl_resource *input_device_super, - uint32_t time); - static void resize(struct wl_client *client, - struct wl_resource *shell_surface_resource, - struct wl_resource *input_device, - uint32_t time, - uint32_t edges); - static void set_toplevel(struct wl_client *client, - struct wl_resource *shell_surface_resource); - static void set_transient(struct wl_client *client, - struct wl_resource *shell_surface_resource, - struct wl_resource *parent_surface_resource, - int x, - int y, - uint32_t flags); - static void set_fullscreen(struct wl_client *client, - struct wl_resource *shell_surface_resource, - uint32_t method, - uint32_t framerate, - struct wl_resource *output); - static void set_popup(struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *input_device, - uint32_t time, - struct wl_resource *parent, - int32_t x, - int32_t y, - uint32_t flags); - static void set_maximized(struct wl_client *client, - struct wl_resource *shell_surface_resource, - struct wl_resource *output); - static void pong(struct wl_client *client, - struct wl_resource *resource, - uint32_t serial); - static void set_title(struct wl_client *client, - struct wl_resource *resource, - const char *title); - static void set_class(struct wl_client *client, - struct wl_resource *resource, - const char *class_); - - static const struct wl_shell_surface_interface shell_surface_interface; + void shell_surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; + + void shell_surface_move(Resource *resource, + struct wl_resource *input_device_super, + uint32_t time) Q_DECL_OVERRIDE; + void shell_surface_resize(Resource *resource, + struct wl_resource *input_device, + uint32_t time, + uint32_t edges) Q_DECL_OVERRIDE; + void shell_surface_set_toplevel(Resource *resource) Q_DECL_OVERRIDE; + void shell_surface_set_transient(Resource *resource, + struct wl_resource *parent_surface_resource, + int x, + int y, + uint32_t flags) Q_DECL_OVERRIDE; + void shell_surface_set_fullscreen(Resource *resource, + uint32_t method, + uint32_t framerate, + struct wl_resource *output) Q_DECL_OVERRIDE; + void shell_surface_set_popup(Resource *resource, + struct wl_resource *input_device, + uint32_t time, + struct wl_resource *parent, + int32_t x, + int32_t y, + uint32_t flags) Q_DECL_OVERRIDE; + void shell_surface_set_maximized(Resource *resource, + struct wl_resource *output) Q_DECL_OVERRIDE; + void shell_surface_pong(Resource *resource, + uint32_t serial) Q_DECL_OVERRIDE; + void shell_surface_set_title(Resource *resource, + const QString &title) Q_DECL_OVERRIDE; + void shell_surface_set_class(Resource *resource, + const QString &class_) Q_DECL_OVERRIDE; }; -class ShellSurfaceGrabber : public Object<wl_pointer_grab> +class ShellSurfaceGrabber : public Object<struct ::wl_pointer_grab> { public: ShellSurfaceGrabber(ShellSurface *shellSurface, const struct wl_pointer_grab_interface *interface); diff --git a/src/compositor/wayland_wrapper/qwlsubsurface.cpp b/src/compositor/wayland_wrapper/qwlsubsurface.cpp index f482cde6..145f86ab 100644 --- a/src/compositor/wayland_wrapper/qwlsubsurface.cpp +++ b/src/compositor/wayland_wrapper/qwlsubsurface.cpp @@ -51,7 +51,7 @@ SubSurfaceExtensionGlobal::SubSurfaceExtensionGlobal(Compositor *compositor) : m_compositor(compositor) { wl_display_add_global(m_compositor->wl_display(), - &wl_sub_surface_extension_interface, + &qt_sub_surface_extension_interface, this, SubSurfaceExtensionGlobal::bind_func); } @@ -59,17 +59,17 @@ SubSurfaceExtensionGlobal::SubSurfaceExtensionGlobal(Compositor *compositor) void SubSurfaceExtensionGlobal::bind_func(wl_client *client, void *data, uint32_t version, uint32_t id) { Q_UNUSED(version); - wl_client_add_object(client, &wl_sub_surface_extension_interface,&sub_surface_extension_interface,id,data); + wl_client_add_object(client, &qt_sub_surface_extension_interface,&sub_surface_extension_interface,id,data); } void SubSurfaceExtensionGlobal::get_sub_surface_aware_surface(wl_client *client, wl_resource *sub_surface_extension_resource, uint32_t id, wl_resource *surface_resource) { Q_UNUSED(sub_surface_extension_resource); - Surface *surface = resolve<Surface>(surface_resource); + Surface *surface = Surface::fromResource(surface_resource); new SubSurface(client,id,surface); } -const struct wl_sub_surface_extension_interface SubSurfaceExtensionGlobal::sub_surface_extension_interface = { +const struct qt_sub_surface_extension_interface SubSurfaceExtensionGlobal::sub_surface_extension_interface = { SubSurfaceExtensionGlobal::get_sub_surface_aware_surface }; @@ -79,7 +79,7 @@ SubSurface::SubSurface(wl_client *client, uint32_t id, Surface *surface) { surface->setSubSurface(this); m_sub_surface_resource = wl_client_add_object(client, - &wl_sub_surface_interface, + &qt_sub_surface_interface, &sub_surface_interface, id, this); @@ -178,7 +178,7 @@ void SubSurface::lower(wl_client *client, wl_resource *sub_surface_parent_resour Q_UNUSED(sub_surface_child_resource); } -const struct wl_sub_surface_interface SubSurface::sub_surface_interface = { +const struct qt_sub_surface_interface SubSurface::sub_surface_interface = { SubSurface::attach_sub_surface, SubSurface::move_sub_surface, SubSurface::raise, diff --git a/src/compositor/wayland_wrapper/qwlsubsurface_p.h b/src/compositor/wayland_wrapper/qwlsubsurface_p.h index 4fb80d61..6f6ad120 100644 --- a/src/compositor/wayland_wrapper/qwlsubsurface_p.h +++ b/src/compositor/wayland_wrapper/qwlsubsurface_p.h @@ -69,7 +69,7 @@ private: uint32_t id, struct wl_resource *surface_resource); - static const struct wl_sub_surface_extension_interface sub_surface_extension_interface; + static const struct qt_sub_surface_extension_interface sub_surface_extension_interface; }; class SubSurface @@ -113,7 +113,7 @@ private: static void lower(struct wl_client *client, struct wl_resource *sub_surface_parent_resource, struct wl_resource *sub_surface_child_resource); - static const struct wl_sub_surface_interface sub_surface_interface; + static const struct qt_sub_surface_interface sub_surface_interface; }; inline Surface *SubSurface::surface() const diff --git a/src/compositor/wayland_wrapper/qwlsurface.cpp b/src/compositor/wayland_wrapper/qwlsurface.cpp index e61b30fc..85dfddb4 100644 --- a/src/compositor/wayland_wrapper/qwlsurface.cpp +++ b/src/compositor/wayland_wrapper/qwlsurface.cpp @@ -71,15 +71,11 @@ QT_BEGIN_NAMESPACE namespace QtWayland { -void destroy_surface(struct wl_resource *resource) -{ - Surface *surface = resolve<Surface>(resource); - surface->compositor()->surfaceDestroyed(surface); - delete surface; -} +static bool QT_WAYLAND_PRINT_BUFFERING_WARNINGS = qEnvironmentVariableIsSet("QT_WAYLAND_PRINT_BUFFERING_WARNINGS"); Surface::Surface(struct wl_client *client, uint32_t id, Compositor *compositor) - : m_compositor(compositor) + : QtWaylandServer::wl_surface(client, &base()->resource, id) + , m_compositor(compositor) , m_waylandSurface(new QWaylandSurface(this)) , m_backBuffer(0) , m_frontBuffer(0) @@ -91,11 +87,9 @@ Surface::Surface(struct wl_client *client, uint32_t id, Compositor *compositor) , m_isCursorSurface(false) { wl_list_init(&m_frame_callback_list); - addClientResource(client, &base()->resource, id, &wl_surface_interface, - &Surface::surface_interface, destroy_surface); - for (int i = 0; i < buffer_pool_size; i++) { + + for (int i = 0; i < buffer_pool_size; i++) m_bufferPool[i] = new SurfaceBuffer(this); - } } Surface::~Surface() @@ -103,7 +97,6 @@ Surface::~Surface() delete m_waylandSurface; delete m_extendedSurface; delete m_subSurface; - delete m_shellSurface; for (int i = 0; i < buffer_pool_size; i++) { if (!m_bufferPool[i]->pageFlipperHasBuffer()) @@ -111,6 +104,11 @@ Surface::~Surface() } } +Surface *Surface::fromResource(struct ::wl_resource *resource) +{ + return static_cast<Surface *>(Resource::fromResource(resource)->surface); +} + QWaylandSurface::Type Surface::type() const { SurfaceBuffer *surfaceBuffer = currentSurfaceBuffer(); @@ -200,14 +198,7 @@ QImage Surface::image() const { SurfaceBuffer *surfacebuffer = currentSurfaceBuffer(); if (surfacebuffer && !surfacebuffer->isDestroyed() && type() == QWaylandSurface::Shm) { - struct wl_buffer *buffer = surfacebuffer->waylandBufferHandle(); - int stride = wl_shm_buffer_get_stride(buffer); - uint format = wl_shm_buffer_get_format(buffer); - (void) format; - void *data = wl_shm_buffer_get_data(buffer); - const uchar *char_data = static_cast<const uchar *>(data); - QImage img(char_data, buffer->width, buffer->height, stride, QImage::Format_ARGB32_Premultiplied); - return img; + return surfacebuffer->image(); } return QImage(); } @@ -308,14 +299,19 @@ bool Surface::advanceBufferQueue() //do we have another buffer in the queue //and does it have a valid damage rect + if (m_backBuffer && !m_backBuffer->isDisplayed()) + return true; if (m_bufferQueue.size()) { int width = 0; int height = 0; - if (m_backBuffer) { + if (m_backBuffer && m_backBuffer->waylandBufferHandle()) { width = m_backBuffer->width(); height = m_backBuffer->height(); } + if (!m_bufferQueue.first()->isComitted()) + return false; + m_backBuffer = m_bufferQueue.takeFirst(); while (m_backBuffer && m_backBuffer->isDestroyed()) { m_backBuffer->disown(); @@ -358,6 +354,7 @@ void Surface::doUpdate() { sendFrameCallback(); } else { SurfaceBuffer *surfaceBuffer = currentSurfaceBuffer(); + if (surfaceBuffer) { if (surfaceBuffer->damageRect().isValid()) { m_compositor->markSurfaceAsDirty(this); @@ -393,7 +390,8 @@ bool Surface::postBuffer() { m_compositor->setDirectRenderingActive(true); return true; } else { - qDebug() << "could not post buffer"; + if (QT_WAYLAND_PRINT_BUFFERING_WARNINGS) + qWarning() << "could not post buffer"; } } } @@ -402,27 +400,23 @@ bool Surface::postBuffer() { return false; } -void Surface::commit() -{ - if (!m_bufferQueue.isEmpty() && !m_backBuffer) - advanceBufferQueue(); - - doUpdate(); -} - void Surface::attach(struct wl_buffer *buffer) { SurfaceBuffer *last = m_bufferQueue.size()?m_bufferQueue.last():0; if (last) { - if (last->waylandBufferHandle() == buffer) + if (last->waylandBufferHandle() == buffer) { + if (QT_WAYLAND_PRINT_BUFFERING_WARNINGS) + qWarning() << "attaching already attached buffer"; return; - if (!last->damageRect().isValid() || isCursorSurface() ){ + } + if (!last->damageRect().isValid() || !last->isComitted() || isCursorSurface() ){ last->disown(); m_bufferQueue.takeLast(); } } - m_bufferQueue << createSurfaceBuffer(buffer); + SurfaceBuffer *surfBuf = createSurfaceBuffer(buffer); + m_bufferQueue << surfBuf; if (!buffer) { InputDevice *inputDevice = m_compositor->defaultInputDevice(); @@ -435,73 +429,78 @@ void Surface::attach(struct wl_buffer *buffer) void Surface::damage(const QRect &rect) { - SurfaceBuffer *surfaceBuffer = m_bufferQueue.isEmpty() ? currentSurfaceBuffer() : m_bufferQueue.last(); - if (surfaceBuffer) + if (m_bufferQueue.empty()) { + if (QT_WAYLAND_PRINT_BUFFERING_WARNINGS) + qWarning() << "Surface::damage() null buffer"; + return; + } + SurfaceBuffer *surfaceBuffer = m_bufferQueue.last(); + if (surfaceBuffer->isComitted()) { + if (QT_WAYLAND_PRINT_BUFFERING_WARNINGS) + qWarning("Surface::damage() on a committed surface"); + } else{ surfaceBuffer->setDamage(rect); - else - qWarning() << "Surface::damage() null buffer"; + } } -const struct wl_surface_interface Surface::surface_interface = { - Surface::surface_destroy, - Surface::surface_attach, - Surface::surface_damage, - Surface::surface_frame, - Surface::surface_set_opaque_region, - Surface::surface_set_input_region, - Surface::surface_commit -}; +void Surface::surface_destroy_resource(Resource *) +{ + compositor()->surfaceDestroyed(this); + delete this; +} -void Surface::surface_destroy(struct wl_client *, struct wl_resource *surface_resource) +void Surface::surface_destroy(Resource *resource) { - wl_resource_destroy(surface_resource); + wl_resource_destroy(resource->handle); } -void Surface::surface_attach(struct wl_client *client, struct wl_resource *surface, - struct wl_resource *buffer, int x, int y) +void Surface::surface_attach(Resource *, struct wl_resource *buffer, int x, int y) { - Q_UNUSED(client); Q_UNUSED(x); Q_UNUSED(y); - resolve<Surface>(surface)->attach(buffer ? reinterpret_cast<wl_buffer *>(buffer->data) : 0); + + attach(buffer ? reinterpret_cast<wl_buffer *>(buffer->data) : 0); } -void Surface::surface_damage(struct wl_client *client, struct wl_resource *surface, - int32_t x, int32_t y, int32_t width, int32_t height) +void Surface::surface_damage(Resource *, int32_t x, int32_t y, int32_t width, int32_t height) { - Q_UNUSED(client); - resolve<Surface>(surface)->damage(QRect(x, y, width, height)); + damage(QRect(x, y, width, height)); } -void Surface::surface_frame(struct wl_client *client, - struct wl_resource *resource, - uint32_t callback) +void Surface::surface_frame(Resource *resource, uint32_t callback) { - Surface *surface = resolve<Surface>(resource); - struct wl_resource *frame_callback = wl_client_add_object(client,&wl_callback_interface,0,callback,surface); - wl_list_insert(&surface->m_frame_callback_list,&frame_callback->link); + struct wl_resource *frame_callback = wl_client_add_object(resource->client(), &wl_callback_interface, 0, callback, this); + wl_list_insert(&m_frame_callback_list, &frame_callback->link); } -void Surface::surface_set_opaque_region(struct wl_client *client, struct wl_resource *surfaceResource, - struct wl_resource *region) +void Surface::surface_set_opaque_region(Resource *, struct wl_resource *region) { - Q_UNUSED(client); - Surface *surface = resolve<Surface>(surfaceResource); - surface->m_opaqueRegion = region ? resolve<Region>(region)->region() : QRegion(); + m_opaqueRegion = region ? Region::fromResource(region)->region() : QRegion(); } -void Surface::surface_set_input_region(struct wl_client *client, struct wl_resource *surfaceResource, - struct wl_resource *region) +void Surface::surface_set_input_region(Resource *, struct wl_resource *region) { - Q_UNUSED(client); - Surface *surface = resolve<Surface>(surfaceResource); - surface->m_inputRegion = region ? resolve<Region>(region)->region() : QRegion(QRect(QPoint(), surface->size())); + m_inputRegion = region ? Region::fromResource(region)->region() : QRegion(QRect(QPoint(), size())); } -void Surface::surface_commit(wl_client *client, wl_resource *resource) +void Surface::surface_commit(Resource *) { - Q_UNUSED(client); - resolve<Surface>(resource)->commit(); + if (m_bufferQueue.empty()) { + if (QT_WAYLAND_PRINT_BUFFERING_WARNINGS) + qWarning("Commit on invalid surface"); + return; + } + + SurfaceBuffer *surfaceBuffer = m_bufferQueue.last(); + if (surfaceBuffer->isComitted()) { + if (QT_WAYLAND_PRINT_BUFFERING_WARNINGS) + qWarning("Committing buffer that has already been committed"); + } else { + surfaceBuffer->setCommitted(); + } + + advanceBufferQueue(); + doUpdate(); } void Surface::setClassName(const QString &className) diff --git a/src/compositor/wayland_wrapper/qwlsurface_p.h b/src/compositor/wayland_wrapper/qwlsurface_p.h index 21b1ae74..0a4413ae 100644 --- a/src/compositor/wayland_wrapper/qwlsurface_p.h +++ b/src/compositor/wayland_wrapper/qwlsurface_p.h @@ -42,12 +42,11 @@ #define WL_SURFACE_H #include <QtCompositor/qwaylandexport.h> +#include <QtCompositor/qwaylandobject.h> #include <private/qwlsurfacebuffer_p.h> #include <QtCompositor/qwaylandsurface.h> -#include <QtCompositor/qwaylandobject.h> - #include <QtCore/QRect> #include <QtGui/QImage> @@ -61,6 +60,8 @@ #include <wayland-util.h> +#include "qwayland-server-wayland.h" + QT_BEGIN_NAMESPACE class QTouchEvent; @@ -73,18 +74,22 @@ class ExtendedSurface; class SubSurface; class ShellSurface; -class Q_COMPOSITOR_EXPORT Surface : public Object<struct wl_surface> +class Q_COMPOSITOR_EXPORT Surface : public Object<struct ::wl_surface>, public QtWaylandServer::wl_surface { public: Surface(struct wl_client *client, uint32_t id, Compositor *compositor); ~Surface(); + static Surface *fromResource(struct ::wl_resource *resource); + QWaylandSurface::Type type() const; bool isYInverted() const; bool visible() const; - uint id() const { return base()->resource.object.id; } + uint id() const { return ::wl_surface::resource.object.id; } + + using QtWaylandServer::wl_surface::resource; QPointF pos() const; QPointF nonAdjustedPos() const; @@ -121,10 +126,6 @@ public: Compositor *compositor() const; - void damage(const QRect &rect); - - static const struct wl_surface_interface surface_interface; - QString className() const { return m_className; } void setClassName(const QString &className); @@ -171,27 +172,29 @@ private: bool m_isCursorSurface; inline SurfaceBuffer *currentSurfaceBuffer() const; + void damage(const QRect &rect); bool advanceBufferQueue(); void doUpdate(); SurfaceBuffer *createSurfaceBuffer(struct wl_buffer *buffer); void frameFinishedInternal(); bool postBuffer(); - void commit(); void attach(struct wl_buffer *buffer); - static void surface_destroy(struct wl_client *client, struct wl_resource *_surface); - static void surface_attach(struct wl_client *client, struct wl_resource *surface, - struct wl_resource *buffer, int x, int y); - static void surface_damage(struct wl_client *client, struct wl_resource *_surface, - int32_t x, int32_t y, int32_t width, int32_t height); - static void surface_frame(struct wl_client *client, struct wl_resource *resource, - uint32_t callback); - static void surface_set_opaque_region(struct wl_client *client, struct wl_resource *resource, - struct wl_resource *region); - static void surface_set_input_region(struct wl_client *client, struct wl_resource *resource, - struct wl_resource *region); - static void surface_commit(struct wl_client *client, struct wl_resource *resource); + void surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; + + void surface_destroy(Resource *resource) Q_DECL_OVERRIDE; + void surface_attach(Resource *resource, + struct wl_resource *buffer, int x, int y) Q_DECL_OVERRIDE; + void surface_damage(Resource *resource, + int32_t x, int32_t y, int32_t width, int32_t height) Q_DECL_OVERRIDE; + void surface_frame(Resource *resource, + uint32_t callback) Q_DECL_OVERRIDE; + void surface_set_opaque_region(Resource *resource, + struct wl_resource *region) Q_DECL_OVERRIDE; + void surface_set_input_region(Resource *resource, + struct wl_resource *region) Q_DECL_OVERRIDE; + void surface_commit(Resource *resource) Q_DECL_OVERRIDE; }; diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp index cebe105b..064d7be7 100644 --- a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp +++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp @@ -59,6 +59,7 @@ SurfaceBuffer::SurfaceBuffer(Surface *surface) , m_surface(surface) , m_compositor(surface->compositor()) , m_buffer(0) + , m_committed(false) , m_is_registered_for_buffer(false) , m_surface_has_buffer(false) , m_page_flipper_has_buffer(false) @@ -67,6 +68,7 @@ SurfaceBuffer::SurfaceBuffer(Surface *surface) , m_guard(0) , m_is_shm_resolved(false) , m_is_shm(false) + , m_image(0) { } @@ -81,6 +83,7 @@ void SurfaceBuffer::initialize(wl_buffer *buffer) m_buffer = buffer; m_texture = 0; m_guard = 0; + m_committed = false; m_is_registered_for_buffer = true; m_surface_has_buffer = true; m_page_flipper_has_buffer = false; @@ -118,8 +121,10 @@ void SurfaceBuffer::destructBufferState() } m_buffer = 0; m_handle = 0; + m_committed = false; m_is_registered_for_buffer = false; m_is_displayed = false; + m_image = QImage(); } bool SurfaceBuffer::isShmBuffer() const @@ -175,10 +180,13 @@ void SurfaceBuffer::setDisplayed() void SurfaceBuffer::setDamage(const QRect &rect) { - if (m_damageRect.isValid()) { + if (m_damageRect.isValid()) { m_damageRect = m_damageRect.united(rect); + } else { + m_damageRect = rect; } - m_damageRect = rect; + m_image = QImage(); + } void SurfaceBuffer::destroyTexture() @@ -186,9 +194,11 @@ void SurfaceBuffer::destroyTexture() #ifdef QT_COMPOSITOR_WAYLAND_GL if (m_texture) { Q_ASSERT(m_guard); + /* When QOpenGLSharedResourceGuard is freed, destroyTexture might be reentered + to cause double free. So clear m_texture first. */ + m_texture = 0; m_guard->free(); m_guard = 0; - m_texture = 0; } #endif } @@ -227,6 +237,24 @@ void *SurfaceBuffer::handle() const return m_handle; } +QImage SurfaceBuffer::image() +{ + /* This api may be available on non-shm buffer. But be sure about it's format. */ + if (!m_buffer || !isShmBuffer()) + return QImage(); + + if (m_image.isNull()) + { + const uchar *data = static_cast<const uchar *>(wl_shm_buffer_get_data(m_buffer)); + int stride = wl_shm_buffer_get_stride(m_buffer); + int width = m_buffer->width; + int height = m_buffer->height; + m_image = QImage(data, width, height, stride, QImage::Format_ARGB32_Premultiplied); + } + + return m_image; +} + void SurfaceBuffer::destroy_listener_callback(wl_listener *listener, void *data) { Q_UNUSED(data); diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h b/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h index dda33544..2595f1fd 100644 --- a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h +++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h @@ -45,6 +45,7 @@ #include <QtGui/qopengl.h> #include <QtGui/private/qopenglcontext_p.h> #include <qpa/qplatformscreenpageflipper.h> +#include <QImage> #include <wayland-server.h> @@ -90,6 +91,8 @@ public: void setDisplayed(); + inline bool isComitted() const { return m_committed; } + inline void setCommitted() { m_committed = true; } inline bool isDisplayed() const { return m_is_displayed; } inline QRect damageRect() const { return m_damageRect; } @@ -107,12 +110,14 @@ public: void handleDisplayed(); void *handle() const; + QImage image(); private: Surface *m_surface; Compositor *m_compositor; struct wl_buffer *m_buffer; struct surface_buffer_destroy_listener m_destroy_listener; QRect m_damageRect; + bool m_committed; bool m_is_registered_for_buffer; bool m_surface_has_buffer; bool m_page_flipper_has_buffer; @@ -129,6 +134,8 @@ private: bool m_is_shm_resolved; bool m_is_shm; + QImage m_image; + static void destroy_listener_callback(wl_listener *listener, void *data); }; diff --git a/src/compositor/wayland_wrapper/qwltouch.cpp b/src/compositor/wayland_wrapper/qwltouch.cpp index 458c74bf..7142c985 100644 --- a/src/compositor/wayland_wrapper/qwltouch.cpp +++ b/src/compositor/wayland_wrapper/qwltouch.cpp @@ -51,7 +51,7 @@ static void dummy(wl_client *, wl_resource *) { } -const struct wl_touch_extension_interface TouchExtensionGlobal::touch_interface = { +const struct qt_touch_extension_interface TouchExtensionGlobal::touch_interface = { dummy }; @@ -65,7 +65,7 @@ TouchExtensionGlobal::TouchExtensionGlobal(Compositor *compositor) m_rawdata_ptr = static_cast<float *>(wl_array_add(&m_rawdata_array, maxRawPos * sizeof(float) * 2)); wl_display_add_global(compositor->wl_display(), - &wl_touch_extension_interface, + &qt_touch_extension_interface, this, TouchExtensionGlobal::bind_func); } @@ -85,11 +85,11 @@ void TouchExtensionGlobal::destroy_resource(wl_resource *resource) void TouchExtensionGlobal::bind_func(wl_client *client, void *data, uint32_t version, uint32_t id) { Q_UNUSED(version); - wl_resource *resource = wl_client_add_object(client, &wl_touch_extension_interface, &touch_interface, id, data); + wl_resource *resource = wl_client_add_object(client, &qt_touch_extension_interface, &touch_interface, id, data); resource->destroy = destroy_resource; TouchExtensionGlobal *self = static_cast<TouchExtensionGlobal *>(resource->data); self->m_resources.append(resource); - wl_touch_extension_send_configure(resource, self->m_flags); + qt_touch_extension_send_configure(resource, self->m_flags); } static inline int toFixed(qreal f) @@ -105,7 +105,7 @@ bool TouchExtensionGlobal::postTouchEvent(QTouchEvent *event, Surface *surface) return false; QPointF surfacePos = surface->pos(); - wl_client *surfaceClient = surface->base()->resource.client; + wl_client *surfaceClient = surface->resource()->client(); uint32_t time = m_compositor->currentTimeMsecs(); const int rescount = m_resources.count(); @@ -162,7 +162,7 @@ bool TouchExtensionGlobal::postTouchEvent(QTouchEvent *event, Surface *surface) } } - wl_touch_extension_send_touch(target, + qt_touch_extension_send_touch(target, time, id, state, x, y, nx, ny, w, h, pressure, vx, vy, diff --git a/src/compositor/wayland_wrapper/qwltouch_p.h b/src/compositor/wayland_wrapper/qwltouch_p.h index 09c9a089..955aa5f8 100644 --- a/src/compositor/wayland_wrapper/qwltouch_p.h +++ b/src/compositor/wayland_wrapper/qwltouch_p.h @@ -69,7 +69,7 @@ private: static void destroy_resource(wl_resource *resource); - static const struct wl_touch_extension_interface touch_interface; + static const struct qt_touch_extension_interface touch_interface; Compositor *m_compositor; int m_flags; diff --git a/src/compositor/wayland_wrapper/wayland_wrapper.pri b/src/compositor/wayland_wrapper/wayland_wrapper.pri index 9bfe957e..c425e2e5 100644 --- a/src/compositor/wayland_wrapper/wayland_wrapper.pri +++ b/src/compositor/wayland_wrapper/wayland_wrapper.pri @@ -1,10 +1,11 @@ -WAYLANDSOURCES += \ +WAYLANDSERVERSOURCES += \ ../extensions/surface-extension.xml \ ../extensions/sub-surface-extension.xml \ ../extensions/output-extension.xml \ ../extensions/touch-extension.xml \ ../extensions/qtkey-extension.xml \ - ../extensions/windowmanager.xml + ../extensions/windowmanager.xml \ + ../3rdparty/protocol/wayland.xml HEADERS += \ wayland_wrapper/qwlcompositor_p.h \ diff --git a/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp b/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp index ea16da31..e607d636 100644 --- a/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp +++ b/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp @@ -61,45 +61,11 @@ WindowManagerServerIntegration::WindowManagerServerIntegration(QWaylandComposito WindowManagerServerIntegration::~WindowManagerServerIntegration() { - qDeleteAll(m_managedClients); } void WindowManagerServerIntegration::initialize(QtWayland::Display *waylandDisplay) { - wl_display_add_global(waylandDisplay->handle(),&wl_windowmanager_interface,this,WindowManagerServerIntegration::bind_func); -} - -void WindowManagerServerIntegration::removeClient(wl_client *client) -{ - WaylandManagedClient *managedClient = m_managedClients.take(client); - delete managedClient; -} - -WaylandManagedClient *WindowManagerServerIntegration::managedClient(wl_client *client) const -{ - return m_managedClients.value(client, 0); -} - -void WindowManagerServerIntegration::mapClientToProcess(wl_client *client, uint32_t processId) -{ - WaylandManagedClient *managedClient = m_managedClients.value(client); - if (!managedClient) - managedClient = new WaylandManagedClient; - managedClient->m_processId = processId; - m_managedClients.insert(client, managedClient); -} - -void WindowManagerServerIntegration::authenticateWithToken(wl_client *client, const char *token) -{ - Q_ASSERT(token != 0 && *token != 0); - - WaylandManagedClient *managedClient = m_managedClients.value(client); - if (!managedClient) - managedClient = new WaylandManagedClient; - managedClient->m_authenticationToken = QByteArray(token); - m_managedClients.insert(client, managedClient); - - emit clientAuthenticated(client); + wl_display_add_global(waylandDisplay->handle(),&qt_windowmanager_interface,this,WindowManagerServerIntegration::bind_func); } void WindowManagerServerIntegration::setShowIsFullScreen(bool value) @@ -107,7 +73,7 @@ void WindowManagerServerIntegration::setShowIsFullScreen(bool value) m_showIsFullScreen = value; struct wl_resource *resource; wl_list_for_each(resource,&client_resources, link) { - wl_windowmanager_send_hints(resource, int32_t(m_showIsFullScreen)); + qt_windowmanager_send_hints(resource, int32_t(m_showIsFullScreen)); } } @@ -116,7 +82,7 @@ void WindowManagerServerIntegration::sendQuitMessage(wl_client *client) struct wl_resource *resource; wl_list_for_each(resource, &client_resources, link) { if (resource->client == client) { - wl_windowmanager_send_quit(resource); + qt_windowmanager_send_quit(resource); return; } } @@ -136,39 +102,20 @@ void WindowManagerServerIntegration::bind_func(struct wl_client *client, void *d WindowManagerServerIntegrationClientData *clientData = new WindowManagerServerIntegrationClientData; clientData->integration = static_cast<WindowManagerServerIntegration *>(data); - wl_resource *resource = wl_client_add_object(client,&wl_windowmanager_interface,&windowmanager_interface,id,clientData); + wl_resource *resource = wl_client_add_object(client,&qt_windowmanager_interface,&windowmanager_interface,id,clientData); resource->destroy = WindowManagerServerIntegration::destroy_resource; clientData->integration->registerResource(resource); - wl_windowmanager_send_hints(resource, int32_t(clientData->integration->m_showIsFullScreen)); + qt_windowmanager_send_hints(resource, int32_t(clientData->integration->m_showIsFullScreen)); } void WindowManagerServerIntegration::destroy_resource(wl_resource *resource) { WindowManagerServerIntegrationClientData *data = static_cast<WindowManagerServerIntegrationClientData *>(resource->data); - WindowManagerServerIntegration *window_mgr = data->integration; - - window_mgr->removeClient(resource->client); delete data; free(resource); } -void WindowManagerServerIntegration::map_client_to_process(struct wl_client *client, - struct wl_resource *window_mgr_resource, - uint32_t process_id) -{ - WindowManagerServerIntegration *window_mgr = static_cast<WindowManagerServerIntegrationClientData *>(window_mgr_resource->data)->integration; - window_mgr->mapClientToProcess(client,process_id); -} - -void WindowManagerServerIntegration::authenticate_with_token(struct wl_client *client, - struct wl_resource *window_mgr_resource, - const char *wl_authentication_token) -{ - WindowManagerServerIntegration *window_mgr = static_cast<WindowManagerServerIntegrationClientData *>(window_mgr_resource->data)->integration; - window_mgr->authenticateWithToken(client,wl_authentication_token); -} - void WindowManagerServerIntegration::open_url(struct wl_client *client, struct wl_resource *window_mgr_resource, uint32_t remaining, @@ -185,30 +132,8 @@ void WindowManagerServerIntegration::open_url(struct wl_client *client, } } -const struct wl_windowmanager_interface WindowManagerServerIntegration::windowmanager_interface = { - WindowManagerServerIntegration::map_client_to_process, - WindowManagerServerIntegration::authenticate_with_token, +const struct qt_windowmanager_interface WindowManagerServerIntegration::windowmanager_interface = { WindowManagerServerIntegration::open_url }; - -/// /// -/// / WaylandManagedClient -/// /// - -WaylandManagedClient::WaylandManagedClient() - : m_processId(0) -{ -} - -qint64 WaylandManagedClient::processId() const -{ - return m_processId; -} - -QByteArray WaylandManagedClient::authenticationToken() const -{ - return m_authenticationToken; -} - QT_END_NAMESPACE diff --git a/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.h b/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.h index afae39dc..10a29a47 100644 --- a/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.h +++ b/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.h @@ -72,24 +72,13 @@ public: ~WindowManagerServerIntegration(); void initialize(QtWayland::Display *waylandDisplay); - void removeClient(wl_client *client); - - WaylandManagedClient *managedClient(wl_client *client) const; void setShowIsFullScreen(bool value); void sendQuitMessage(wl_client *client); -signals: - void clientAuthenticated(wl_client *client); - -private: - void mapClientToProcess(wl_client *client, uint32_t processId); - void authenticateWithToken(wl_client *client, const char *token); - private: bool m_showIsFullScreen; QWaylandCompositor *m_compositor; - QMap<wl_client*, WaylandManagedClient*> m_managedClients; static void bind_func(struct wl_client *client, void *data, uint32_t version, uint32_t id); @@ -105,22 +94,7 @@ private: struct wl_resource *window_mgr_resource, uint32_t remaining, const char *url); - static const struct wl_windowmanager_interface windowmanager_interface; -}; - - -class WaylandManagedClient -{ -public: - WaylandManagedClient(); - qint64 processId() const; - QByteArray authenticationToken() const; - -private: - qint64 m_processId; - QByteArray m_authenticationToken; - - friend class WindowManagerServerIntegration; + static const struct qt_windowmanager_interface windowmanager_interface; }; QT_END_NAMESPACE diff --git a/src/extensions/brcm.xml b/src/extensions/brcm.xml index 862026d0..4c8e188d 100644 --- a/src/extensions/brcm.xml +++ b/src/extensions/brcm.xml @@ -39,7 +39,7 @@ $QT_END_LICENSE$ </copyright> - <interface name="wl_brcm" version="1"> + <interface name="qt_brcm" version="1"> <!-- Create a wayland buffer wrapping a global image. --> <request name="create_buffer"> diff --git a/src/extensions/output-extension.xml b/src/extensions/output-extension.xml index 0ca8214e..07aa1102 100644 --- a/src/extensions/output-extension.xml +++ b/src/extensions/output-extension.xml @@ -38,14 +38,14 @@ $QT_END_LICENSE$ </copyright> - <interface name="wl_output_extension" version="1"> + <interface name="qt_output_extension" version="1"> <request name="get_extended_output"> - <arg name="id" type="new_id" interface="wl_extended_output"/> + <arg name="id" type="new_id" interface="qt_extended_output"/> <arg name="output" type="object" interface="wl_output"/> </request> </interface> - <interface name="wl_extended_output" version="1"> + <interface name="qt_extended_output" version="1"> <enum name="rotation"> <entry name="PortraitOrientation" value="1"/> <entry name="LandscapeOrientation" value="2"/> diff --git a/src/extensions/qtkey-extension.xml b/src/extensions/qtkey-extension.xml index fc4d14da..1d0db59d 100644 --- a/src/extensions/qtkey-extension.xml +++ b/src/extensions/qtkey-extension.xml @@ -1,4 +1,4 @@ -<protocol name="key_extension"> +<protocol name="qtkey_extension"> <copyright> Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). @@ -38,7 +38,7 @@ $QT_END_LICENSE$ </copyright> - <interface name="wl_qtkey_extension" version="1"> + <interface name="qt_key_extension" version="1"> <event name="qtkey"> <description summary="qtkey event"> Serialized QKeyEvent diff --git a/src/extensions/sub-surface-extension.xml b/src/extensions/sub-surface-extension.xml index 41f1816e..0a6dcfbc 100644 --- a/src/extensions/sub-surface-extension.xml +++ b/src/extensions/sub-surface-extension.xml @@ -38,32 +38,32 @@ $QT_END_LICENSE$ </copyright> - <interface name="wl_sub_surface_extension" version="1"> + <interface name="qt_sub_surface_extension" version="1"> <request name="get_sub_surface_aware_surface"> - <arg name="id" type="new_id" interface="wl_sub_surface"/> + <arg name="id" type="new_id" interface="qt_sub_surface"/> <arg name="surface" type="object" interface="wl_surface"/> </request> </interface> - <interface name="wl_sub_surface" version="1"> + <interface name="qt_sub_surface" version="1"> <request name="attach_sub_surface"> - <arg name="sub_surface" type="object" interface="wl_sub_surface"/> + <arg name="sub_surface" type="object" interface="qt_sub_surface"/> <arg name="x" type="int"/> <arg name="y" type="int"/> </request> <request name="move_sub_surface"> - <arg name="sub_surface" type="object" interface="wl_sub_surface"/> + <arg name="sub_surface" type="object" interface="qt_sub_surface"/> <arg name="x" type="int"/> <arg name="y" type="int"/> </request> <request name="raise"> - <arg name="sub_surface" type="object" interface="wl_sub_surface"/> + <arg name="sub_surface" type="object" interface="qt_sub_surface"/> </request> <request name="lower"> - <arg name="sub_surface" type="object" interface="wl_sub_surface"/> + <arg name="sub_surface" type="object" interface="qt_sub_surface"/> </request> </interface> </protocol> diff --git a/src/extensions/surface-extension.xml b/src/extensions/surface-extension.xml index c99f63b6..269b4390 100644 --- a/src/extensions/surface-extension.xml +++ b/src/extensions/surface-extension.xml @@ -38,14 +38,14 @@ $QT_END_LICENSE$ </copyright> - <interface name="wl_surface_extension" version="1"> + <interface name="qt_surface_extension" version="1"> <request name="get_extended_surface"> - <arg name="id" type="new_id" interface="wl_extended_surface"/> + <arg name="id" type="new_id" interface="qt_extended_surface"/> <arg name="surface" type="object" interface="wl_surface"/> </request> </interface> - <interface name="wl_extended_surface" version="1"> + <interface name="qt_extended_surface" version="1"> <event name="onscreen_visibility"> <arg name="visible" type="int"/> </event> diff --git a/src/extensions/touch-extension.xml b/src/extensions/touch-extension.xml index 1efb8930..92aefc67 100644 --- a/src/extensions/touch-extension.xml +++ b/src/extensions/touch-extension.xml @@ -38,7 +38,7 @@ $QT_END_LICENSE$ </copyright> - <interface name="wl_touch_extension" version="1"> + <interface name="qt_touch_extension" version="1"> <event name="touch"> <arg name="time" type="uint" /> <arg name="id" type="uint" /> diff --git a/src/extensions/windowmanager.xml b/src/extensions/windowmanager.xml index 71fb2723..e03bc3ad 100644 --- a/src/extensions/windowmanager.xml +++ b/src/extensions/windowmanager.xml @@ -1,4 +1,4 @@ -<protocol name="wayland_windowmanager"> +<protocol name="windowmanager"> <copyright> Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). @@ -38,13 +38,7 @@ $QT_END_LICENSE$ </copyright> - <interface name="wl_windowmanager" version="1"> - <request name="map_client_to_process"> - <arg name="processid" type="uint" /> - </request> - <request name="authenticate_with_token"> - <arg name="processid" type="string" /> - </request> + <interface name="qt_windowmanager" version="1"> <request name="open_url"> <description summary="client requests a url to be opened"> If remaining is not 0 this is a multipart request, and diff --git a/src/extensions/xcomposite.xml b/src/extensions/xcomposite.xml index 47a91087..e7eb2b85 100644 --- a/src/extensions/xcomposite.xml +++ b/src/extensions/xcomposite.xml @@ -39,7 +39,7 @@ $QT_END_LICENSE$ </copyright> - <interface name="wl_xcomposite" version="1"> + <interface name="qt_xcomposite" version="1"> <!-- Create a wayland buffer for X Window. --> <request name="create_buffer"> diff --git a/src/plugins/platforms/qwayland-brcm-egl/qwayland-brcm-egl.pro b/src/plugins/platforms/qwayland-brcm-egl/qwayland-brcm-egl.pro index bdd948ac..2e5a66e9 100644 --- a/src/plugins/platforms/qwayland-brcm-egl/qwayland-brcm-egl.pro +++ b/src/plugins/platforms/qwayland-brcm-egl/qwayland-brcm-egl.pro @@ -17,4 +17,4 @@ HEADERS += qwaylandbrcmeglintegration.h \ qwaylandbrcmglcontext.h \ qwaylandbrcmeglwindow.h -WAYLANDSOURCES += ../../../extensions/brcm.xml +WAYLANDCLIENTSOURCES += ../../../extensions/brcm.xml diff --git a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.cpp b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.cpp index 2bd5732d..c5712d65 100644 --- a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.cpp +++ b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.cpp @@ -59,10 +59,10 @@ QWaylandBrcmEglIntegration::QWaylandBrcmEglIntegration(QWaylandDisplay *waylandD waylandDisplay->addRegistryListener(wlDisplayHandleGlobal, this); } -void QWaylandBrcmEglIntegration::wlDisplayHandleGlobal(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version) +void QWaylandBrcmEglIntegration::wlDisplayHandleGlobal(void *data, struct wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); - if (strcmp(interface, "wl_brcm") == 0) { + if (interface == "wl_brcm") { QWaylandBrcmEglIntegration *integration = static_cast<QWaylandBrcmEglIntegration *>(data); integration->m_waylandBrcm = static_cast<struct wl_brcm *>(wl_registry_bind(registry, id, &wl_brcm_interface, 1)); } diff --git a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.h b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.h index c7cb41b6..fd971ffb 100644 --- a/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.h +++ b/src/plugins/platforms/qwayland-brcm-egl/qwaylandbrcmeglintegration.h @@ -81,7 +81,7 @@ public: PFNEGLDESTROYGLOBALIMAGEBRCMPROC eglDestroyGlobalImageBRCM; private: - static void wlDisplayHandleGlobal(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version); + static void wlDisplayHandleGlobal(void *data, struct wl_registry *registry, uint32_t id, const QString &interface, uint32_t version); struct wl_display *m_waylandDisplay; struct wl_brcm *m_waylandBrcm; diff --git a/src/plugins/platforms/qwayland-egl/qwayland-egl.pro b/src/plugins/platforms/qwayland-egl/qwayland-egl.pro index cdebf9bb..339f9461 100644 --- a/src/plugins/platforms/qwayland-egl/qwayland-egl.pro +++ b/src/plugins/platforms/qwayland-egl/qwayland-egl.pro @@ -16,11 +16,9 @@ OTHER_FILES += \ SOURCES += qwaylandeglintegration.cpp \ qwaylandglcontext.cpp \ qwaylandeglwindow.cpp \ - qwaylandegldecoration.cpp \ main.cpp HEADERS += qwaylandeglintegration.h \ qwaylandglcontext.h \ qwaylandeglwindow.h \ - qwaylandegldecoration.h \ qwaylandeglinclude.h diff --git a/src/plugins/platforms/qwayland-egl/qwaylandegldecoration.cpp b/src/plugins/platforms/qwayland-egl/qwaylandegldecoration.cpp deleted file mode 100644 index 7724f283..00000000 --- a/src/plugins/platforms/qwayland-egl/qwaylandegldecoration.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwaylandegldecoration.h" - -#include "qwaylandeglwindow.h" - -#include <QtGui/QPainter> -#include <QtGui/QOpenGLPaintDevice> - -QT_USE_NAMESPACE - -QWaylandEglDecoration::QWaylandEglDecoration(QWaylandEglWindow *window) - : QWaylandDecoration(window) -{ -} - -QWaylandEglDecoration::~QWaylandEglDecoration() -{ -} - -void QWaylandEglDecoration::paintDecoration() -{ - glClearColor(backgroundColor().redF(), backgroundColor().greenF(), backgroundColor().blueF(), backgroundColor().alphaF()); - glClear(GL_COLOR_BUFFER_BIT); - - QOpenGLPaintDevice device(window()->frameGeometry().size()); - paint(&device); -} diff --git a/src/plugins/platforms/qwayland-egl/qwaylandegldecoration.h b/src/plugins/platforms/qwayland-egl/qwaylandegldecoration.h deleted file mode 100644 index 3039b728..00000000 --- a/src/plugins/platforms/qwayland-egl/qwaylandegldecoration.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWAYLANDEGLDECORATION_H -#define QWAYLANDEGLDECORATION_H - -#include "qwaylanddecoration.h" - -QT_BEGIN_NAMESPACE - -class QWaylandEglWindow; - -class QWaylandEglDecoration : public QWaylandDecoration -{ -public: - QWaylandEglDecoration(QWaylandEglWindow *window); - ~QWaylandEglDecoration(); - - void paintDecoration(); - -}; - -QT_END_NAMESPACE - -#endif // QWAYLANDEGLDECORATION_H diff --git a/src/plugins/platforms/qwayland-egl/qwaylandeglwindow.cpp b/src/plugins/platforms/qwayland-egl/qwaylandeglwindow.cpp index 6edf7483..9c39ec95 100644 --- a/src/plugins/platforms/qwayland-egl/qwaylandeglwindow.cpp +++ b/src/plugins/platforms/qwayland-egl/qwaylandeglwindow.cpp @@ -43,7 +43,6 @@ #include "qwaylandscreen.h" #include "qwaylandglcontext.h" -#include "qwaylandegldecoration.h" #include <QtPlatformSupport/private/qeglconvenience_p.h> @@ -67,7 +66,7 @@ QWaylandEglWindow::QWaylandEglWindow(QWindow *window) , m_eglConfig(0) , m_contentFBO(0) , m_resize(false) - , m_format(window->format()) + , m_format(window->requestedFormat()) { setGeometry(window->geometry()); } @@ -89,25 +88,26 @@ QWaylandWindow::WindowType QWaylandEglWindow::windowType() const return QWaylandWindow::Egl; } -void QWaylandEglWindow::redraw() +void QWaylandEglWindow::setGeometry(const QRect &rect) { createDecoration(); QMargins margins = frameMargins(); - QSize sizeWithMargins = geometry().size() + QSize(margins.left() + margins.right(), margins.top() + margins.bottom()); + QSize sizeWithMargins = rect.size() + QSize(margins.left() + margins.right(), margins.top() + margins.bottom()); if (m_waylandEglWindow) { int current_width, current_height; wl_egl_window_get_attached_size(m_waylandEglWindow,¤t_width,¤t_height); if (current_width != sizeWithMargins.width() || current_height != sizeWithMargins.height()) { - waitForFrameSync(); wl_egl_window_resize(m_waylandEglWindow, sizeWithMargins.width(), sizeWithMargins.height(), mOffset.x(), mOffset.y()); mOffset = QPoint(); m_resize = true; } } else { - m_waylandEglWindow = wl_egl_window_create(mSurface, sizeWithMargins.width(), sizeWithMargins.height()); + m_waylandEglWindow = wl_egl_window_create(wl_surface(), sizeWithMargins.width(), sizeWithMargins.height()); } + + QWaylandWindow::setGeometry(rect); } QRect QWaylandEglWindow::contentsRect() const @@ -125,10 +125,11 @@ QSurfaceFormat QWaylandEglWindow::format() const EGLSurface QWaylandEglWindow::eglSurface() const { if (!m_waylandEglWindow) { - const_cast<QWaylandEglWindow *>(this)->createDecoration(); + QWaylandEglWindow *self = const_cast<QWaylandEglWindow *>(this); + self->createDecoration(); QMargins margins = frameMargins(); QSize sizeWithMargins = geometry().size() + QSize(margins.left() + margins.right(), margins.top() + margins.bottom()); - m_waylandEglWindow = wl_egl_window_create(mSurface, sizeWithMargins.width(), sizeWithMargins.height()); + m_waylandEglWindow = wl_egl_window_create(self->wl_surface(), sizeWithMargins.width(), sizeWithMargins.height()); } if (!m_eglSurface) { @@ -170,8 +171,3 @@ void QWaylandEglWindow::bindContentFBO() m_contentFBO->bind(); } } - -void QWaylandEglWindow::createDecorationInstance() -{ - new QWaylandEglDecoration(this); -} diff --git a/src/plugins/platforms/qwayland-egl/qwaylandeglwindow.h b/src/plugins/platforms/qwayland-egl/qwaylandeglwindow.h index dfc5a26d..f973547a 100644 --- a/src/plugins/platforms/qwayland-egl/qwaylandeglwindow.h +++ b/src/plugins/platforms/qwayland-egl/qwaylandeglwindow.h @@ -58,6 +58,7 @@ public: ~QWaylandEglWindow(); WindowType windowType() const; + virtual void setGeometry(const QRect &rect); QRect contentsRect() const; EGLSurface eglSurface() const; @@ -68,11 +69,6 @@ public: void bindContentFBO(); - void redraw(); - -protected: - void createDecorationInstance(); - private: QWaylandEglIntegration *m_eglIntegration; mutable struct wl_egl_window *m_waylandEglWindow; diff --git a/src/plugins/platforms/qwayland-egl/qwaylandglcontext.cpp b/src/plugins/platforms/qwayland-egl/qwaylandglcontext.cpp index 4d8017dc..e28f0d17 100644 --- a/src/plugins/platforms/qwayland-egl/qwaylandglcontext.cpp +++ b/src/plugins/platforms/qwayland-egl/qwaylandglcontext.cpp @@ -49,6 +49,7 @@ #include <QDebug> #include <QtPlatformSupport/private/qeglconvenience_p.h> #include <QtGui/private/qopenglcontext_p.h> +#include <QtGui/private/qopengltexturecache_p.h> #include <qpa/qplatformopenglcontext.h> #include <QtGui/QSurfaceFormat> @@ -62,6 +63,8 @@ QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat , m_config(q_configFromGLFormat(m_eglDisplay, format, true)) , m_format(q_glFormatFromConfig(m_eglDisplay, m_config)) , m_blitProgram(0) + , m_textureCache(0) + , m_currentOnSurface(0) { m_shareEGLContext = share ? static_cast<QWaylandGLContext *>(share)->eglContext() : EGL_NO_CONTEXT; @@ -83,18 +86,29 @@ QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat QWaylandGLContext::~QWaylandGLContext() { delete m_blitProgram; + delete m_textureCache; eglDestroyContext(m_eglDisplay, m_context); } bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface) { QWaylandEglWindow *window = static_cast<QWaylandEglWindow *>(surface); + if (m_currentOnSurface != window) { + if (m_currentOnSurface) { + QWaylandWindow *oldWindow = m_currentOnSurface; + m_currentOnSurface = 0; + oldWindow->resizeMutex()->unlock(); + } + window->resizeMutex()->lock(); + m_currentOnSurface = window; + } + EGLSurface eglSurface = window->eglSurface(); - if (!eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_context)) + if (!eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_context)) { + qWarning("QEGLPlatformContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this); + m_currentOnSurface->resizeMutex()->unlock(); return false; - - // FIXME: remove this as soon as https://codereview.qt-project.org/#change,38879 is merged - QOpenGLContextPrivate::setCurrentContext(context()); + } window->bindContentFBO(); @@ -104,16 +118,21 @@ bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface) void QWaylandGLContext::doneCurrent() { eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (m_currentOnSurface) { + QWaylandWindow *window = m_currentOnSurface; + m_currentOnSurface = 0; + window->resizeMutex()->unlock(); + } } void QWaylandGLContext::swapBuffers(QPlatformSurface *surface) { QWaylandEglWindow *window = static_cast<QWaylandEglWindow *>(surface); + EGLSurface eglSurface = window->eglSurface(); if (window->decoration()) { makeCurrent(surface); - if (!m_blitProgram) { m_blitProgram = new QOpenGLShaderProgram(); m_blitProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, "attribute vec4 position;\n\ @@ -124,7 +143,7 @@ void QWaylandGLContext::swapBuffers(QPlatformSurface *surface) gl_Position = position;\n\ outTexCoords = texCoords.xy;\n\ }"); - m_blitProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, "varying vec2 outTexCoords;\n\ + m_blitProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, "varying highp vec2 outTexCoords;\n\ uniform sampler2D texture;\n\ void main()\n\ {\n\ @@ -137,23 +156,28 @@ void QWaylandGLContext::swapBuffers(QPlatformSurface *surface) } } + if (!m_textureCache) { + m_textureCache = new QOpenGLTextureCache(this->context()); + } + glDisable(GL_DEPTH_TEST); + glDisable(GL_BLEND); glBindFramebuffer(GL_FRAMEBUFFER, 0); - if (window->decoration()) - window->decoration()->paintDecoration(); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, window->contentTexture()); - QRect r = window->contentsRect(); - glViewport(r.x(), r.y(), r.width(), r.height()); - static const GLfloat squareVertices[] = { -1.f, -1.f, 1.0f, -1.f, -1.f, 1.0f, - 1.0f, 1.0f, + 1.0f, 1.0f }; + + static const GLfloat inverseSquareVertices[] = { + -1.f, 1.f, + 1.f, 1.f, + -1.f, -1.f, + 1.f, -1.f + }; + static const GLfloat textureVertices[] = { 0.0f, 0.0f, 1.0f, 0.0f, @@ -161,25 +185,44 @@ void QWaylandGLContext::swapBuffers(QPlatformSurface *surface) 1.0f, 1.0f, }; - m_blitProgram->bind(); - m_blitProgram->setUniformValue("texture", 0); m_blitProgram->enableAttributeArray("position"); m_blitProgram->enableAttributeArray("texCoords"); - m_blitProgram->setAttributeArray("position", squareVertices, 2); m_blitProgram->setAttributeArray("texCoords", textureVertices, 2); m_blitProgram->bind(); + glActiveTexture(GL_TEXTURE0); + //Draw Decoration + m_blitProgram->setAttributeArray("position", inverseSquareVertices, 2); + QImage decorationImage = window->decoration()->contentImage(); + m_textureCache->bindTexture(context(), decorationImage); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + QRect windowRect = window->window()->frameGeometry(); + glViewport(0, 0, windowRect.width(), windowRect.height()); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + //Draw Content + m_blitProgram->setAttributeArray("position", squareVertices, 2); + glBindTexture(GL_TEXTURE_2D, window->contentTexture()); + QRect r = window->contentsRect(); + glViewport(r.x(), r.y(), r.width(), r.height()); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + //Cleanup m_blitProgram->disableAttributeArray("position"); m_blitProgram->disableAttributeArray("texCoords"); m_blitProgram->release(); } eglSwapBuffers(m_eglDisplay, eglSurface); + if (m_currentOnSurface == window) { + m_currentOnSurface = 0; + window->resizeMutex()->unlock(); + } + } GLuint QWaylandGLContext::defaultFramebufferObject(QPlatformSurface *surface) const diff --git a/src/plugins/platforms/qwayland-egl/qwaylandglcontext.h b/src/plugins/platforms/qwayland-egl/qwaylandglcontext.h index 696a0b91..b4216830 100644 --- a/src/plugins/platforms/qwayland-egl/qwaylandglcontext.h +++ b/src/plugins/platforms/qwayland-egl/qwaylandglcontext.h @@ -53,6 +53,7 @@ QT_BEGIN_NAMESPACE class QWaylandWindow; class QWaylandGLWindowSurface; class QOpenGLShaderProgram; +class QOpenGLTextureCache; class QWaylandGLContext : public QPlatformOpenGLContext { public: @@ -84,6 +85,9 @@ private: EGLConfig m_config; QSurfaceFormat m_format; QOpenGLShaderProgram *m_blitProgram; + QOpenGLTextureCache *m_textureCache; + + QWaylandWindow *m_currentOnSurface; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwayland-xcomposite-egl.pro b/src/plugins/platforms/qwayland-xcomposite-egl/qwayland-xcomposite-egl.pro index b691ec9d..e41cf59b 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwayland-xcomposite-egl.pro +++ b/src/plugins/platforms/qwayland-xcomposite-egl/qwayland-xcomposite-egl.pro @@ -6,6 +6,10 @@ include (../xcomposite_share/xcomposite_share.pri) OTHER_FILES += qwayland-xcomposite-egl.json +contains(DEFINES, QT_WAYLAND_WINDOWMANAGER_SUPPORT) { + WAYLANDCLIENTSOURCES += ../../../extensions/windowmanager.xml +} + !contains(QT_CONFIG, no-pkg-config) { CONFIG += link_pkgconfig PKGCONFIG += xcomposite egl x11 diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglcontext.cpp b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglcontext.cpp index 42139ef1..635e47c0 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglcontext.cpp +++ b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglcontext.cpp @@ -51,7 +51,7 @@ QT_USE_NAMESPACE QWaylandXCompositeEGLContext::QWaylandXCompositeEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display) - : QEGLPlatformContext(format, share, display) + : QEGLPlatformContext(format, share, display, q_configFromGLFormat(display, format, true, EGL_WINDOW_BIT | EGL_PIXMAP_BIT), EGL_OPENGL_ES_API) { } diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.cpp b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.cpp index 992c2dcf..c2ea9a93 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.cpp +++ b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.cpp @@ -105,27 +105,27 @@ QWaylandDisplay * QWaylandXCompositeEGLIntegration::waylandDisplay() const { return mWaylandDisplay; } -wl_xcomposite * QWaylandXCompositeEGLIntegration::waylandXComposite() const +qt_xcomposite * QWaylandXCompositeEGLIntegration::waylandXComposite() const { return mWaylandComposite; } -const struct wl_xcomposite_listener QWaylandXCompositeEGLIntegration::xcomposite_listener = { +const struct qt_xcomposite_listener QWaylandXCompositeEGLIntegration::xcomposite_listener = { QWaylandXCompositeEGLIntegration::rootInformation }; -void QWaylandXCompositeEGLIntegration::wlDisplayHandleGlobal(void *data, wl_registry *registry, uint32_t id, const char *interface, uint32_t version) +void QWaylandXCompositeEGLIntegration::wlDisplayHandleGlobal(void *data, wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); - if (strcmp(interface, "wl_xcomposite") == 0) { + if (interface == "wl_xcomposite") { QWaylandXCompositeEGLIntegration *integration = static_cast<QWaylandXCompositeEGLIntegration *>(data); - integration->mWaylandComposite = static_cast<struct wl_xcomposite *>(wl_registry_bind(registry,id,&wl_xcomposite_interface,1)); - wl_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration); + integration->mWaylandComposite = static_cast<struct qt_xcomposite *>(wl_registry_bind(registry,id,&qt_xcomposite_interface,1)); + qt_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration); } } -void QWaylandXCompositeEGLIntegration::rootInformation(void *data, wl_xcomposite *xcomposite, const char *display_name, uint32_t root_window) +void QWaylandXCompositeEGLIntegration::rootInformation(void *data, qt_xcomposite *xcomposite, const char *display_name, uint32_t root_window) { Q_UNUSED(xcomposite); QWaylandXCompositeEGLIntegration *integration = static_cast<QWaylandXCompositeEGLIntegration *>(data); diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.h b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.h index d3015ab5..d7d1d491 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.h +++ b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglintegration.h @@ -75,16 +75,18 @@ public: QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const; QWaylandDisplay *waylandDisplay() const; - struct wl_xcomposite *waylandXComposite() const; + struct qt_xcomposite *waylandXComposite() const; Display *xDisplay() const; EGLDisplay eglDisplay() const; int screen() const; Window rootWindow() const; + bool supportsThreadedOpenGL() const { return true; } + private: QWaylandDisplay *mWaylandDisplay; - struct wl_xcomposite *mWaylandComposite; + struct qt_xcomposite *mWaylandComposite; Display *mDisplay; EGLDisplay mEglDisplay; @@ -92,11 +94,11 @@ private: Window mRootWindow; static void wlDisplayHandleGlobal(void *data, struct wl_registry *registry, uint32_t id, - const char *interface, uint32_t version); + const QString &interface, uint32_t version); - static const struct wl_xcomposite_listener xcomposite_listener; + static const struct qt_xcomposite_listener xcomposite_listener; static void rootInformation(void *data, - struct wl_xcomposite *xcomposite, + struct qt_xcomposite *xcomposite, const char *display_name, uint32_t root_window); }; diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.cpp b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.cpp index d4743941..f1768991 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.cpp +++ b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.cpp @@ -49,7 +49,10 @@ #include <X11/extensions/Xcomposite.h> #include "qwaylandxcompositeeglintegration.h" + +#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT #include "windowmanager_integration/qwaylandwindowmanagerintegration.h" +#endif #include <QtCore/QDebug> @@ -63,7 +66,6 @@ QWaylandXCompositeEGLWindow::QWaylandXCompositeEGLWindow(QWindow *window, QWayla , m_xWindow(0) , m_config(q_configFromGLFormat(glxIntegration->eglDisplay(), window->format(), true, EGL_WINDOW_BIT | EGL_PIXMAP_BIT)) , m_surface(0) - , m_waitingForSync(false) { } @@ -134,14 +136,6 @@ void QWaylandXCompositeEGLWindow::createEglSurface() (uint32_t)m_xWindow, size); attach(m_buffer, 0, 0); - - m_waitingForSync = true; - struct wl_callback *callback = wl_display_sync(m_glxIntegration->waylandDisplay()->wl_display()); - wl_callback_add_listener(callback,&m_callback_listener,&m_waitingForSync); - - m_glxIntegration->waylandDisplay()->flushRequests(); - while (m_waitingForSync) - m_glxIntegration->waylandDisplay()->blockingReadEvents(); } void QWaylandXCompositeEGLWindow::requestActivateWindow() @@ -152,17 +146,3 @@ void QWaylandXCompositeEGLWindow::requestActivateWindow() QWaylandWindow::requestActivateWindow(); } - -const struct wl_callback_listener QWaylandXCompositeEGLWindow::m_callback_listener = { - QWaylandXCompositeEGLWindow::done -}; - -void QWaylandXCompositeEGLWindow::done(void *data, - struct wl_callback *callback, - uint32_t time) -{ - Q_UNUSED(time); - bool *waitingForSync = static_cast<bool *>(data); - *waitingForSync=false; - wl_callback_destroy(callback); -} diff --git a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.h b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.h index 895ac28f..98f0ed73 100644 --- a/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.h +++ b/src/plugins/platforms/qwayland-xcomposite-egl/qwaylandxcompositeeglwindow.h @@ -71,12 +71,6 @@ private: Window m_xWindow; EGLConfig m_config; EGLSurface m_surface; - - bool m_waitingForSync; - static const struct wl_callback_listener m_callback_listener; - static void done(void *data, - struct wl_callback *wl_callback, - uint32_t time); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxcontext.cpp b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxcontext.cpp index 28643690..bc3167b9 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxcontext.cpp +++ b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxcontext.cpp @@ -54,10 +54,10 @@ QWaylandXCompositeGLXContext::QWaylandXCompositeGLXContext(const QSurfaceFormat { qDebug("creating XComposite-GLX context"); GLXContext shareContext = share ? static_cast<QWaylandXCompositeGLXContext *>(share)->m_context : 0; - GLXFBConfig config = qglx_findConfig(display, screen, format); + GLXFBConfig config = qglx_findConfig(display, screen, format, GLX_WINDOW_BIT | GLX_PIXMAP_BIT); XVisualInfo *visualInfo = glXGetVisualFromFBConfig(display, config); m_context = glXCreateContext(display, visualInfo, shareContext, true); - m_format = qglx_surfaceFormatFromGLXFBConfig(display, config, m_context); + qglx_surfaceFormatFromGLXFBConfig(&m_format, display, config, m_context); } bool QWaylandXCompositeGLXContext::makeCurrent(QPlatformSurface *surface) diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.cpp b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.cpp index 56554236..e3316d96 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.cpp +++ b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.cpp @@ -112,10 +112,10 @@ const struct wl_xcomposite_listener QWaylandXCompositeGLXIntegration::xcomposite QWaylandXCompositeGLXIntegration::rootInformation }; -void QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal(void *data, wl_registry *registry, uint32_t id, const char *interface, uint32_t version) +void QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal(void *data, wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); - if (strcmp(interface, "wl_xcomposite") == 0) { + if (interface == "wl_xcomposite") { qDebug("XComposite-GLX: got wl_xcomposite global"); QWaylandXCompositeGLXIntegration *integration = static_cast<QWaylandXCompositeGLXIntegration *>(data); integration->mWaylandComposite = static_cast<struct wl_xcomposite *>(wl_registry_bind(registry, id, &wl_xcomposite_interface, 1)); diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.h b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.h index 8bbbab89..066295c1 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.h +++ b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxintegration.h @@ -76,6 +76,8 @@ public: int screen() const; Window rootWindow() const; + bool supportsThreadedOpenGL() const { return true; } + private: QWaylandDisplay *mWaylandDisplay; struct wl_xcomposite *mWaylandComposite; @@ -85,7 +87,7 @@ private: Window mRootWindow; static void wlDisplayHandleGlobal(void *data, struct wl_registry *registry, uint32_t id, - const char *interface, uint32_t version); + const QString &interface, uint32_t version); static const struct wl_xcomposite_listener xcomposite_listener; static void rootInformation(void *data, diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxwindow.cpp b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxwindow.cpp index 1ffb5b87..c142a363 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxwindow.cpp +++ b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxwindow.cpp @@ -57,7 +57,6 @@ QWaylandXCompositeGLXWindow::QWaylandXCompositeGLXWindow(QWindow *window, QWayla , m_xWindow(0) , m_config(qglx_findConfig(glxIntegration->xDisplay(), glxIntegration->screen(), window->format(), GLX_WINDOW_BIT | GLX_PIXMAP_BIT)) , m_buffer(0) - , m_syncCallback(0) { } @@ -87,22 +86,6 @@ Window QWaylandXCompositeGLXWindow::xWindow() const return m_xWindow; } -void QWaylandXCompositeGLXWindow::waitForSync() -{ - if (!m_syncCallback) { - struct wl_display *dpy = m_glxIntegration->waylandDisplay()->wl_display(); - m_syncCallback = wl_display_sync(dpy); - wl_callback_add_listener(m_syncCallback, &sync_callback_listener, this); - } - m_glxIntegration->waylandDisplay()->flushRequests(); - while (m_syncCallback) - m_glxIntegration->waylandDisplay()->readEvents(); -} - -const struct wl_callback_listener QWaylandXCompositeGLXWindow::sync_callback_listener = { - QWaylandXCompositeGLXWindow::sync_function -}; - void QWaylandXCompositeGLXWindow::createSurface() { QSize size(geometry().size()); @@ -136,15 +119,4 @@ void QWaylandXCompositeGLXWindow::createSurface() (uint32_t)m_xWindow, size); attach(m_buffer, 0, 0); - waitForSync(); -} - -void QWaylandXCompositeGLXWindow::sync_function(void *data, struct wl_callback *callback, uint32_t time) -{ - Q_UNUSED(time); - QWaylandXCompositeGLXWindow *that = static_cast<QWaylandXCompositeGLXWindow *>(data); - if (that->m_syncCallback != callback) - return; - that->m_syncCallback = 0; - wl_callback_destroy(callback); } diff --git a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxwindow.h b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxwindow.h index fa16c36d..b436cbbe 100644 --- a/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxwindow.h +++ b/src/plugins/platforms/qwayland-xcomposite-glx/qwaylandxcompositeglxwindow.h @@ -71,12 +71,6 @@ private: GLXFBConfig m_config; QWaylandBuffer *m_buffer; - - void waitForSync(); - wl_callback *m_syncCallback; - - static const struct wl_callback_listener sync_callback_listener; - static void sync_function(void *data, struct wl_callback *wl_callback, uint32_t time); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandcursor.cpp b/src/plugins/platforms/wayland_common/qwaylandcursor.cpp index d4823950..9ea1836b 100644 --- a/src/plugins/platforms/wayland_common/qwaylandcursor.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandcursor.cpp @@ -57,7 +57,15 @@ QWaylandCursor::QWaylandCursor(QWaylandScreen *screen) : mDisplay(screen->display()) { //TODO: Make wl_cursor_theme_load arguments configurable here - mCursorTheme = wl_cursor_theme_load("default", 32, mDisplay->shm()); + QByteArray cursorTheme = qgetenv("XCURSOR_THEME"); + if (cursorTheme.isEmpty()) + cursorTheme = QByteArray("default"); + QByteArray cursorSizeFromEnv = qgetenv("XCURSOR_SIZE"); + bool hasCursorSize = false; + int cursorSize = cursorSizeFromEnv.toInt(&hasCursorSize); + if (!hasCursorSize || cursorSize <= 0) + cursorSize = 32; + mCursorTheme = wl_cursor_theme_load(cursorTheme, cursorSize, mDisplay->shm()); initCursorMap(); } diff --git a/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp b/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp index d4ba6179..901069c5 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp @@ -86,7 +86,7 @@ void QWaylandDataDeviceManager::enter(void *data, return; data_device_manager->m_drag_last_event_time = time; - data_device_manager->m_drag_current_event_window = static_cast<QWaylandWindow *>(wl_surface_get_user_data(surface)); + data_device_manager->m_drag_current_event_window = QWaylandWindow::fromWlSurface(surface); if (!surface) return; QWaylandDataOffer *offer = static_cast<QWaylandDataOffer *>(wl_data_offer_get_user_data(id)); @@ -261,7 +261,7 @@ void QWaylandDataDeviceManager::createAndSetDrag(QDrag *drag) p.drawPixmap(0,0,pixmap); } - m_drag_icon_surface = wl_compositor_create_surface(m_display->wl_compositor()); + m_drag_icon_surface = m_display->compositor()->create_surface(); wl_surface_attach(m_drag_icon_surface, m_drag_icon_buffer->buffer(), -drag->hotSpot().x(), -drag->hotSpot().y()); wl_data_device_start_drag(transfer_device, m_drag_data_source->handle(), m_drag_surface, m_drag_icon_surface, QWaylandDisplay::currentTimeMillisec()); diff --git a/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp b/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp index 11baeeb6..f5f79ae6 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp @@ -46,6 +46,7 @@ #include "qwaylandinputdevice.h" #include <QtGui/QGuiApplication> +#include <QtGui/QImage> #include <QtGui/QCursor> #include <QtGui/QPainter> #include <QtGui/QPalette> @@ -124,6 +125,8 @@ static const char * const qt_normalizeup_xpm[] = { QWaylandDecoration::QWaylandDecoration(QWaylandWindow *window) : m_window(window->window()) , m_wayland_window(window) + , m_isDirty(true) + , m_decorationContentImage(0) , m_margins(3,30,3,3) , m_hasSetCursor(false) , m_mouseButtons(Qt::NoButton) @@ -144,6 +147,26 @@ QWaylandDecoration::~QWaylandDecoration() m_wayland_window->setDecoration(0); } +const QImage &QWaylandDecoration::contentImage() +{ + if (m_isDirty) { + //Update the decoration backingstore + + m_decorationContentImage = QImage(window()->frameGeometry().size(), QImage::Format_ARGB32_Premultiplied); + m_decorationContentImage.fill(Qt::transparent); + this->paint(&m_decorationContentImage); + + m_isDirty = false; + } + + return m_decorationContentImage; +} + +void QWaylandDecoration::update() +{ + m_isDirty = true; +} + void QWaylandDecoration::paint(QPaintDevice *device) { QRect surfaceRect(QPoint(), window()->frameGeometry().size()); diff --git a/src/plugins/platforms/wayland_common/qwaylanddecoration.h b/src/plugins/platforms/wayland_common/qwaylanddecoration.h index 0ad9b030..14755699 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddecoration.h +++ b/src/plugins/platforms/wayland_common/qwaylanddecoration.h @@ -48,6 +48,7 @@ #include <QtGui/QCursor> #include <QtGui/QColor> #include <QtGui/QStaticText> +#include <QtGui/QImage> #include <wayland-client.h> @@ -68,7 +69,8 @@ public: QWaylandDecoration(QWaylandWindow *window); virtual ~QWaylandDecoration(); - virtual void paintDecoration() = 0; + void update(); + bool isDirty() const; bool handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,Qt::MouseButtons b,Qt::KeyboardModifiers mods); void restoreMouseCursor(); @@ -79,6 +81,7 @@ public: QMargins margins() const; QWindow *window() const; QWaylandWindow *waylandWindow() const; + const QImage &contentImage(); void setForegroundColor(const QColor &c); inline QColor foregroundColor() const; @@ -107,6 +110,9 @@ private: QWindow *m_window; QWaylandWindow *m_wayland_window; + bool m_isDirty; + QImage m_decorationContentImage; + QMargins m_margins; bool m_hasSetCursor; Qt::CursorShape m_cursorShape; @@ -117,6 +123,11 @@ private: QStaticText m_windowTitle; }; +inline bool QWaylandDecoration::isDirty() const +{ + return m_isDirty; +} + inline QMargins QWaylandDecoration::margins() const { return m_margins; diff --git a/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp b/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp index 0e4fb588..bb056c96 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp @@ -48,7 +48,6 @@ #include "qwaylandinputdevice.h" #include "qwaylandclipboard.h" #include "qwaylanddatadevicemanager.h" -#include "qwaylandshell.h" #ifdef QT_WAYLAND_GL_SUPPORT #include "qwaylandglintegration.h" @@ -73,7 +72,7 @@ QT_USE_NAMESPACE struct wl_surface *QWaylandDisplay::createSurface(void *handle) { - struct wl_surface * surface = wl_compositor_create_surface(mCompositor); + struct wl_surface *surface = mCompositor.create_surface(); wl_surface_set_user_data(surface, handle); return surface; } @@ -104,11 +103,7 @@ void QWaylandDisplay::setLastKeyboardFocusInputDevice(QWaylandInputDevice *devic static QWaylandDisplay *display = 0; -const struct wl_registry_listener QWaylandDisplay::registryListener = { - QWaylandDisplay::displayHandleGlobal -}; - -QWaylandDisplay::QWaylandDisplay(void) +QWaylandDisplay::QWaylandDisplay() : mLastKeyboardFocusInputDevice(0) , mDndSelectionHandler(0) , mWindowExtension(0) @@ -131,9 +126,10 @@ QWaylandDisplay::QWaylandDisplay(void) //Create a new even queue for the QtGui thread mEventQueue = wl_display_create_queue(mDisplay); - mRegistry = wl_display_get_registry(mDisplay); - wl_proxy_set_queue((struct wl_proxy *)mRegistry, mEventQueue); - wl_registry_add_listener(mRegistry, ®istryListener, this); + struct ::wl_registry *registry = wl_display_get_registry(mDisplay); + wl_proxy_set_queue((struct wl_proxy *)registry, mEventQueue); + + init(registry); QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher; connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(flushRequests())); @@ -144,7 +140,7 @@ QWaylandDisplay::QWaylandDisplay(void) #endif #ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT - mWindowManagerIntegration = QWaylandWindowManagerIntegration::createIntegration(this); + mWindowManagerIntegration = new QWaylandWindowManagerIntegration(this); #endif blockingReadEvents(); @@ -170,27 +166,10 @@ QWaylandDisplay::~QWaylandDisplay(void) delete mEventThreadObject; } -void QWaylandDisplay::createNewScreen(struct wl_output *output) -{ - QWaylandScreen *waylandScreen = new QWaylandScreen(this,output); - mScreens.append(waylandScreen); -} - -void QWaylandDisplay::scheduleRedraw(QWaylandWindow *window) -{ - if (!mWindows.contains(window)) - mWindows << window; -} - void QWaylandDisplay::flushRequests() { wl_display_dispatch_queue_pending(mDisplay, mEventQueue); wl_display_flush(mDisplay); - - foreach (QWaylandWindow *w, mWindows) { - w->redraw(); - } - mWindows.clear(); } void QWaylandDisplay::blockingReadEvents() @@ -208,51 +187,12 @@ QWaylandScreen *QWaylandDisplay::screenForOutput(struct wl_output *output) const return 0; } -void QWaylandDisplay::outputHandleGeometry(void *data, - struct wl_output *output, - int32_t x, int32_t y, - int32_t physicalWidth, - int32_t physicalHeight, - int subpixel, - const char *make, const char *model, - int32_t transform) -{ - Q_UNUSED(subpixel); - Q_UNUSED(make); - Q_UNUSED(model); - Q_UNUSED(transform); - QWaylandDisplay *waylandDisplay = static_cast<QWaylandDisplay *>(data); - QRect outputRect = QRect(x, y, physicalWidth, physicalHeight); - waylandDisplay->screenForOutput(output)->setGeometry(outputRect); -} - -void QWaylandDisplay::mode(void *data, - struct wl_output *output, - uint32_t flags, - int width, - int height, - int refresh) -{ - QWaylandDisplay *waylandDisplay = static_cast<QWaylandDisplay *>(data); - - if (flags & WL_OUTPUT_MODE_CURRENT) { - QWaylandScreen *screen = waylandDisplay->screenForOutput(output); - if (screen) - screen->handleMode(QSize(width, height), refresh); - } -} - void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data) { Listener l = { listener, data }; mRegistryListeners.append(l); } -const struct wl_output_listener QWaylandDisplay::outputListener = { - QWaylandDisplay::outputHandleGeometry, - QWaylandDisplay::mode -}; - void QWaylandDisplay::waitForScreens() { flushRequests(); @@ -260,53 +200,41 @@ void QWaylandDisplay::waitForScreens() blockingReadEvents(); } -void QWaylandDisplay::displayHandleGlobal(void *data, - struct wl_registry *registry, - uint32_t id, - const char *interface, - uint32_t version) -{ - Q_UNUSED(registry); - QWaylandDisplay *that = static_cast<QWaylandDisplay *>(data); - that->displayHandleGlobal(id, QByteArray(interface), version); -} - -void QWaylandDisplay::displayHandleGlobal(uint32_t id, - const QByteArray &interface, - uint32_t version) +void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); + struct ::wl_registry *registry = object(); + if (interface == "wl_output") { - struct wl_output *output = static_cast<struct wl_output *>(wl_registry_bind(mRegistry,id,&wl_output_interface,1)); - createNewScreen(output); - wl_output_add_listener(output, &outputListener, this); + mScreens.append(new QWaylandScreen(this, id)); } else if (interface == "wl_compositor") { - mCompositor = static_cast<struct wl_compositor *>(wl_registry_bind(mRegistry, id,&wl_compositor_interface,1)); + mCompositor.init(registry, id); } else if (interface == "wl_shm") { - mShm = static_cast<struct wl_shm *>(wl_registry_bind(mRegistry, id, &wl_shm_interface,1)); + mShm = static_cast<struct wl_shm *>(wl_registry_bind(registry, id, &wl_shm_interface,1)); } else if (interface == "wl_shell"){ - mShell = new QWaylandShell(this,id,version); + mShell = new QtWayland::wl_shell(registry, id); } else if (interface == "wl_seat") { QWaylandInputDevice *inputDevice = new QWaylandInputDevice(this, id); mInputDevices.append(inputDevice); } else if (interface == "wl_data_device_manager") { mDndSelectionHandler = new QWaylandDataDeviceManager(this, id); } else if (interface == "wl_output_extension") { - mOutputExtension = new QWaylandOutputExtension(this,id); + mOutputExtension = new QtWayland::qt_output_extension(registry, id); + foreach (QPlatformScreen *screen, screens()) + static_cast<QWaylandScreen *>(screen)->createExtendedOutput(); } else if (interface == "wl_surface_extension") { - mWindowExtension = new QWaylandSurfaceExtension(this,id); + mWindowExtension = new QtWayland::qt_surface_extension(registry, id); } else if (interface == "wl_sub_surface_extension") { - mSubSurfaceExtension = new QWaylandSubSurfaceExtension(this,id); + mSubSurfaceExtension = new QtWayland::qt_sub_surface_extension(registry, id); } else if (interface == "wl_touch_extension") { mTouchExtension = new QWaylandTouchExtension(this, id); } else if (interface == "wl_qtkey_extension") { mQtKeyExtension = new QWaylandQtKeyExtension(this, id); } - foreach (Listener l, mRegistryListeners) { - (*l.listener)(l.data, mRegistry, id, interface, version); - } + foreach (Listener l, mRegistryListeners) + (*l.listener)(l.data, registry, id, interface, version); } uint32_t QWaylandDisplay::currentTimeMillisec() diff --git a/src/plugins/platforms/wayland_common/qwaylanddisplay.h b/src/plugins/platforms/wayland_common/qwaylanddisplay.h index 637e05b9..bb26be69 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddisplay.h +++ b/src/plugins/platforms/wayland_common/qwaylanddisplay.h @@ -48,6 +48,7 @@ #include <QtCore/QWaitCondition> #include <wayland-client.h> +#include <qwayland-wayland.h> QT_BEGIN_NAMESPACE @@ -60,22 +61,25 @@ class QWaylandScreen; class QWaylandGLIntegration; class QWaylandWindowManagerIntegration; class QWaylandDataDeviceManager; -class QWaylandShell; -class QWaylandSurfaceExtension; -class QWaylandSubSurfaceExtension; -class QWaylandOutputExtension; class QWaylandTouchExtension; class QWaylandQtKeyExtension; class QWaylandWindow; class QWaylandEventThread; +namespace QtWayland { + class qt_output_extension; + class qt_shell; + class qt_sub_surface_extension; + class qt_surface_extension; +} + typedef void (*RegistryListener)(void *data, struct wl_registry *registry, uint32_t id, - const char *interface, + const QString &interface, uint32_t version); -class QWaylandDisplay : public QObject { +class QWaylandDisplay : public QObject, public QtWayland::wl_registry { Q_OBJECT public: @@ -100,10 +104,12 @@ public: struct wl_display *wl_display() const { return mDisplay; } struct wl_event_queue *wl_event_queue() const { return mEventQueue; } - struct wl_registry *wl_registry() const { return mRegistry; } - struct wl_compositor *wl_compositor() const { return mCompositor; } + struct ::wl_registry *wl_registry() { return object(); } + + const struct wl_compositor *wl_compositor() const { return mCompositor.object(); } + QtWayland::wl_compositor *compositor() { return &mCompositor; } - QWaylandShell *shell() const { return mShell; } + QtWayland::wl_shell *shell() { return mShell; } QList<QWaylandInputDevice *> inputDevices() const { return mInputDevices; } @@ -112,9 +118,9 @@ public: QWaylandDataDeviceManager *dndSelectionHandler() const { return mDndSelectionHandler; } - QWaylandSurfaceExtension *windowExtension() const { return mWindowExtension; } - QWaylandSubSurfaceExtension *subSurfaceExtension() const { return mSubSurfaceExtension; } - QWaylandOutputExtension *outputExtension() const { return mOutputExtension; } + QtWayland::qt_surface_extension *windowExtension() const { return mWindowExtension; } + QtWayland::qt_sub_surface_extension *subSurfaceExtension() const { return mSubSurfaceExtension; } + QtWayland::qt_output_extension *outputExtension() const { return mOutputExtension; } QWaylandTouchExtension *touchExtension() const { return mTouchExtension; } /* wl_registry_add_listener does not add but rather sets a listener, so this function is used @@ -127,18 +133,12 @@ public: void forceRoundTrip(); - void scheduleRedraw(QWaylandWindow *window); - public slots: - void createNewScreen(struct wl_output *output); void blockingReadEvents(); void flushRequests(); private: void waitForScreens(); - void displayHandleGlobal(uint32_t id, - const QByteArray &interface, - uint32_t version); struct Listener { RegistryListener listener; @@ -147,21 +147,19 @@ private: struct wl_display *mDisplay; struct wl_event_queue *mEventQueue; - struct wl_registry *mRegistry; - struct wl_compositor *mCompositor; + QtWayland::wl_compositor mCompositor; struct wl_shm *mShm; QThread *mEventThread; QWaylandEventThread *mEventThreadObject; - QWaylandShell *mShell; + QtWayland::wl_shell *mShell; QList<QPlatformScreen *> mScreens; QList<QWaylandInputDevice *> mInputDevices; QList<Listener> mRegistryListeners; - QList<QWaylandWindow *> mWindows; QWaylandInputDevice *mLastKeyboardFocusInputDevice; QWaylandDataDeviceManager *mDndSelectionHandler; - QWaylandSurfaceExtension *mWindowExtension; - QWaylandSubSurfaceExtension *mSubSurfaceExtension; - QWaylandOutputExtension *mOutputExtension; + QtWayland::qt_surface_extension *mWindowExtension; + QtWayland::qt_sub_surface_extension *mSubSurfaceExtension; + QtWayland::qt_output_extension *mOutputExtension; QWaylandTouchExtension *mTouchExtension; QWaylandQtKeyExtension *mQtKeyExtension; @@ -170,28 +168,7 @@ private: int mWritableNotificationFd; bool mScreensInitialized; - static const struct wl_registry_listener registryListener; - static const struct wl_output_listener outputListener; - - static void displayHandleGlobal(void *data, - struct wl_registry *registry, - uint32_t id, - const char *interface, - uint32_t version); - static void outputHandleGeometry(void *data, - struct wl_output *output, - int32_t x, int32_t y, - int32_t width, int32_t height, - int subpixel, - const char *make, - const char *model, - int32_t transform); - static void mode(void *data, - struct wl_output *wl_output, - uint32_t flags, - int width, - int height, - int refresh); + void registry_global(uint32_t id, const QString &interface, uint32_t version) Q_DECL_OVERRIDE; #ifdef QT_WAYLAND_GL_SUPPORT QWaylandGLIntegration *mEglIntegration; diff --git a/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp b/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp index 7b6f9f3c..24b264e2 100644 --- a/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp @@ -43,44 +43,17 @@ #include "qwaylandscreen.h" -#include "wayland-output-extension-client-protocol.h" - #include <qpa/qwindowsysteminterface.h> #include <QtCore/QDebug> QT_USE_NAMESPACE -QWaylandOutputExtension::QWaylandOutputExtension(QWaylandDisplay *display, uint32_t id) -{ - m_output_extension = static_cast<struct wl_output_extension *>( - wl_registry_bind(display->wl_registry(), id, &wl_output_extension_interface, 1)); - - QList<QPlatformScreen *> platformScreens = display->screens(); - for (int i = 0; i < platformScreens.size(); i++) { - QWaylandScreen *waylandScreen = static_cast<QWaylandScreen *>(platformScreens.at(i)); - if (!waylandScreen->extendedOutput()) { - QWaylandExtendedOutput *extendedOutput = getExtendedOutput(waylandScreen); - waylandScreen->setExtendedOutput(extendedOutput); - qDebug() << "extended output enabled"; - } - } -} - -QWaylandExtendedOutput *QWaylandOutputExtension::getExtendedOutput(QWaylandScreen *screen) -{ - qDebug() << "getExtendedOutput"; - struct wl_extended_output *extended_output = - wl_output_extension_get_extended_output(m_output_extension,screen->output()); - return new QWaylandExtendedOutput(screen,extended_output); -} - -QWaylandExtendedOutput::QWaylandExtendedOutput(QWaylandScreen *screen, wl_extended_output *extended_output) - : m_extended_output(extended_output) +QWaylandExtendedOutput::QWaylandExtendedOutput(QWaylandScreen *screen, ::qt_extended_output *extended_output) + : QtWayland::qt_extended_output(extended_output) , m_screen(screen) , m_orientation(m_screen->orientation()) { - wl_extended_output_add_listener(m_extended_output,&extended_output_listener,this); } Qt::ScreenOrientation QWaylandExtendedOutput::currentOrientation() const @@ -92,40 +65,34 @@ void QWaylandExtendedOutput::setOrientationUpdateMask(Qt::ScreenOrientations ori { int mask = 0; if (orientations & Qt::PortraitOrientation) - mask |= WL_EXTENDED_OUTPUT_ROTATION_PORTRAITORIENTATION; + mask |= QT_EXTENDED_OUTPUT_ROTATION_PORTRAITORIENTATION; if (orientations & Qt::LandscapeOrientation) - mask |= WL_EXTENDED_OUTPUT_ROTATION_LANDSCAPEORIENTATION; + mask |= QT_EXTENDED_OUTPUT_ROTATION_LANDSCAPEORIENTATION; if (orientations & Qt::InvertedPortraitOrientation) - mask |= WL_EXTENDED_OUTPUT_ROTATION_INVERTEDPORTRAITORIENTATION; + mask |= QT_EXTENDED_OUTPUT_ROTATION_INVERTEDPORTRAITORIENTATION; if (orientations & Qt::InvertedLandscapeOrientation) - mask |= WL_EXTENDED_OUTPUT_ROTATION_INVERTEDLANDSCAPEORIENTATION; - wl_extended_output_set_orientation_update_mask(m_extended_output, mask); + mask |= QT_EXTENDED_OUTPUT_ROTATION_INVERTEDLANDSCAPEORIENTATION; + set_orientation_update_mask(mask); } -void QWaylandExtendedOutput::set_screen_rotation(void *data, wl_extended_output *wl_extended_output, int32_t rotation) +void QWaylandExtendedOutput::extended_output_set_screen_rotation(int32_t rotation) { - Q_UNUSED(wl_extended_output); - QWaylandExtendedOutput *extended_output = static_cast<QWaylandExtendedOutput *>(data); switch (rotation) { - case WL_EXTENDED_OUTPUT_ROTATION_PORTRAITORIENTATION: - extended_output->m_orientation = Qt::PortraitOrientation; + case QT_EXTENDED_OUTPUT_ROTATION_PORTRAITORIENTATION: + m_orientation = Qt::PortraitOrientation; break; - case WL_EXTENDED_OUTPUT_ROTATION_LANDSCAPEORIENTATION: - extended_output->m_orientation = Qt::LandscapeOrientation; + case QT_EXTENDED_OUTPUT_ROTATION_LANDSCAPEORIENTATION: + m_orientation = Qt::LandscapeOrientation; break; - case WL_EXTENDED_OUTPUT_ROTATION_INVERTEDPORTRAITORIENTATION: - extended_output->m_orientation = Qt::InvertedPortraitOrientation; + case QT_EXTENDED_OUTPUT_ROTATION_INVERTEDPORTRAITORIENTATION: + m_orientation = Qt::InvertedPortraitOrientation; break; - case WL_EXTENDED_OUTPUT_ROTATION_INVERTEDLANDSCAPEORIENTATION: - extended_output->m_orientation = Qt::InvertedLandscapeOrientation; + case QT_EXTENDED_OUTPUT_ROTATION_INVERTEDLANDSCAPEORIENTATION: + m_orientation = Qt::InvertedLandscapeOrientation; break; default: - extended_output->m_orientation = Qt::PortraitOrientation; + m_orientation = Qt::PortraitOrientation; break; } - QWindowSystemInterface::handleScreenOrientationChange(extended_output->m_screen->screen(), extended_output->m_orientation); + QWindowSystemInterface::handleScreenOrientationChange(m_screen->screen(), m_orientation); } - -const struct wl_extended_output_listener QWaylandExtendedOutput::extended_output_listener = { - QWaylandExtendedOutput::set_screen_rotation -}; diff --git a/src/plugins/platforms/wayland_common/qwaylandextendedoutput.h b/src/plugins/platforms/wayland_common/qwaylandextendedoutput.h index 780f5702..dd9ce6a8 100644 --- a/src/plugins/platforms/wayland_common/qwaylandextendedoutput.h +++ b/src/plugins/platforms/wayland_common/qwaylandextendedoutput.h @@ -43,38 +43,25 @@ #define QWAYLANDEXTENDEDOUTPUT_H #include "qwaylanddisplay.h" +#include "qwayland-output-extension.h" QT_BEGIN_NAMESPACE class QWaylandExtendedOutput; -class QWaylandOutputExtension +class QWaylandExtendedOutput : public QtWayland::qt_extended_output { public: - QWaylandOutputExtension(QWaylandDisplay *display, uint32_t id); - - QWaylandExtendedOutput* getExtendedOutput(QWaylandScreen *screen); -private: - struct wl_output_extension *m_output_extension; -}; - -class QWaylandExtendedOutput -{ -public: - QWaylandExtendedOutput(QWaylandScreen *screen, struct wl_extended_output *extended_output); + QWaylandExtendedOutput(QWaylandScreen *screen, struct ::qt_extended_output *extended_output); Qt::ScreenOrientation currentOrientation() const; void setOrientationUpdateMask(Qt::ScreenOrientations mask); private: - struct wl_extended_output *m_extended_output; + void extended_output_set_screen_rotation(int32_t rotation) Q_DECL_OVERRIDE; + QWaylandScreen *m_screen; Qt::ScreenOrientation m_orientation; - - static void set_screen_rotation(void *data, - struct wl_extended_output *wl_extended_output, - int32_t rotation); - static const struct wl_extended_output_listener extended_output_listener; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp b/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp index 82b294b0..46280bcf 100644 --- a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp @@ -44,7 +44,6 @@ #include "qwaylandwindow.h" #include "wayland-client.h" -#include "wayland-surface-extension-client-protocol.h" #include "qwaylanddisplay.h" @@ -56,65 +55,41 @@ QT_USE_NAMESPACE -QWaylandSurfaceExtension::QWaylandSurfaceExtension(QWaylandDisplay *display, uint32_t id) -{ - m_surface_extension = static_cast<struct wl_surface_extension *>( - wl_registry_bind(display->wl_registry(), id, &wl_surface_extension_interface, 1)); -} - -QWaylandExtendedSurface *QWaylandSurfaceExtension::getExtendedWindow(QWaylandWindow *window) -{ - struct wl_surface *surface = window->wl_surface(); - Q_ASSERT(surface); - struct wl_extended_surface *extended_surface = - wl_surface_extension_get_extended_surface(m_surface_extension,surface); - - return new QWaylandExtendedSurface(window,extended_surface); -} - - -QWaylandExtendedSurface::QWaylandExtendedSurface(QWaylandWindow *window, struct wl_extended_surface *extended_surface) - : m_window(window) - , m_extended_surface(extended_surface) +QWaylandExtendedSurface::QWaylandExtendedSurface(QWaylandWindow *window, struct ::qt_extended_surface *extended_surface) + : QtWayland::qt_extended_surface(extended_surface) + , m_window(window) , m_exposed(true) { - wl_extended_surface_add_listener(m_extended_surface,&QWaylandExtendedSurface::extended_surface_listener,this); } void QWaylandExtendedSurface::updateGenericProperty(const QString &name, const QVariant &value) { - QByteArray byteValue; QDataStream ds(&byteValue, QIODevice::WriteOnly); ds << value; - struct wl_array data; - data.size = byteValue.size(); - data.data = (void*)byteValue.constData(); - data.alloc = 0; - - wl_extended_surface_update_generic_property(m_extended_surface,qPrintable(name),&data); + update_generic_property(name, byteValue); - m_properties.insert(name,value); + m_properties.insert(name, value); QWaylandNativeInterface *nativeInterface = static_cast<QWaylandNativeInterface *>( QGuiApplication::platformNativeInterface()); - nativeInterface->emitWindowPropertyChanged(m_window,name); + nativeInterface->emitWindowPropertyChanged(m_window, name); } static int32_t waylandRotationFromScreenOrientation(Qt::ScreenOrientation orientation) { switch (orientation) { - case Qt::PortraitOrientation: return WL_EXTENDED_SURFACE_ORIENTATION_PORTRAITORIENTATION; - case Qt::InvertedPortraitOrientation: return WL_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION; - case Qt::LandscapeOrientation: return WL_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION; - case Qt::InvertedLandscapeOrientation: return WL_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION; - default: return WL_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION; + case Qt::PortraitOrientation: return QT_EXTENDED_SURFACE_ORIENTATION_PORTRAITORIENTATION; + case Qt::InvertedPortraitOrientation: return QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION; + case Qt::LandscapeOrientation: return QT_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION; + case Qt::InvertedLandscapeOrientation: return QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION; + default: return QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION; } } void QWaylandExtendedSurface::setContentOrientation(Qt::ScreenOrientation orientation) { - wl_extended_surface_set_content_orientation(m_extended_surface, waylandRotationFromScreenOrientation(orientation)); + set_content_orientation(waylandRotationFromScreenOrientation(orientation)); } QVariantMap QWaylandExtendedSurface::properties() const @@ -132,59 +107,43 @@ QVariant QWaylandExtendedSurface::property(const QString &name, const QVariant & return m_properties.value(name,defaultValue); } -void QWaylandExtendedSurface::onscreen_visibility(void *data, wl_extended_surface *wl_extended_surface, int32_t visible) +void QWaylandExtendedSurface::extended_surface_onscreen_visibility(int32_t visible) { - QWaylandExtendedSurface *extendedWindow = static_cast<QWaylandExtendedSurface *>(data); - Q_UNUSED(extendedWindow); - Q_UNUSED(wl_extended_surface); - // Do not send events when the state is not changing... - if (visible == extendedWindow->m_window->isExposed()) + if (visible == m_exposed) return; - extendedWindow->m_exposed = visible; - QWaylandWindow *w = extendedWindow->m_window; + m_exposed = visible; + QWaylandWindow *w = m_window; QWindowSystemInterface::handleExposeEvent(w->window(), visible ? QRegion(w->geometry()) : QRegion()); - QWindowSystemInterface::flushWindowSystemEvents(); } -void QWaylandExtendedSurface::set_generic_property(void *data, wl_extended_surface *wl_extended_surface, const char *name, wl_array *value) +void QWaylandExtendedSurface::extended_surface_set_generic_property(const QString &name, wl_array *value) { - Q_UNUSED(wl_extended_surface); - - QWaylandExtendedSurface *extended_window = static_cast<QWaylandExtendedSurface *>(data); + QByteArray data = QByteArray::fromRawData(static_cast<char *>(value->data), value->size); QVariant variantValue; - QByteArray baValue = QByteArray((const char*)value->data, value->size); - QDataStream ds(&baValue, QIODevice::ReadOnly); + QDataStream ds(data); ds >> variantValue; - QString qstring_name = QString::fromLatin1(name); - extended_window->m_properties.insert(qstring_name,variantValue); + m_properties.insert(name, variantValue); QWaylandNativeInterface *nativeInterface = static_cast<QWaylandNativeInterface *>( - QGuiApplication::platformNativeInterface()); - nativeInterface->emitWindowPropertyChanged(extended_window->m_window,QString::fromLatin1(name)); + QGuiApplication::platformNativeInterface()); + nativeInterface->emitWindowPropertyChanged(m_window, name); } Qt::WindowFlags QWaylandExtendedSurface::setWindowFlags(Qt::WindowFlags flags) { uint wlFlags = 0; - if (flags & Qt::WindowStaysOnTopHint) wlFlags |= WL_EXTENDED_SURFACE_WINDOWFLAG_STAYSONTOP; - if (flags & Qt::WindowOverridesSystemGestures) wlFlags |= WL_EXTENDED_SURFACE_WINDOWFLAG_OVERRIDESSYSTEMGESTURES; - wl_extended_surface_set_window_flags(m_extended_surface, wlFlags); + if (flags & Qt::WindowStaysOnTopHint) wlFlags |= QT_EXTENDED_SURFACE_WINDOWFLAG_STAYSONTOP; + if (flags & Qt::WindowOverridesSystemGestures) wlFlags |= QT_EXTENDED_SURFACE_WINDOWFLAG_OVERRIDESSYSTEMGESTURES; - return flags & ( - Qt::WindowStaysOnTopHint - | Qt::WindowOverridesSystemGestures - ); -} + set_window_flags(wlFlags); -const struct wl_extended_surface_listener QWaylandExtendedSurface::extended_surface_listener = { - QWaylandExtendedSurface::onscreen_visibility, - QWaylandExtendedSurface::set_generic_property -}; + return flags & (Qt::WindowStaysOnTopHint | Qt::WindowOverridesSystemGestures); +} diff --git a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h b/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h index 940d9ab7..9dbebaf4 100644 --- a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h +++ b/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h @@ -46,31 +46,22 @@ #include <QtCore/QVariant> #include <wayland-client.h> +#include <qwayland-surface-extension.h> QT_BEGIN_NAMESPACE class QWaylandDisplay; class QWaylandWindow; -class QWaylandExtendedSurface; -class QWaylandSurfaceExtension +class QWaylandExtendedSurface : public QtWayland::qt_extended_surface { public: - QWaylandSurfaceExtension(QWaylandDisplay *display, uint32_t id); - - QWaylandExtendedSurface *getExtendedWindow(QWaylandWindow *window); -private: - struct wl_surface_extension *m_surface_extension; -}; - -class QWaylandExtendedSurface -{ -public: - QWaylandExtendedSurface(QWaylandWindow *window, struct wl_extended_surface *extended_surface); + QWaylandExtendedSurface(QWaylandWindow *window, struct ::qt_extended_surface *extended_surface); void setContentOrientation(Qt::ScreenOrientation orientation); void updateGenericProperty(const QString &name, const QVariant &value); + QVariantMap properties() const; QVariant property(const QString &name); QVariant property(const QString &name, const QVariant &defaultValue); @@ -80,22 +71,12 @@ public: bool isExposed() const { return m_exposed; } private: - QWaylandWindow *m_window; - struct wl_extended_surface *m_extended_surface; + void extended_surface_onscreen_visibility(int32_t visible) Q_DECL_OVERRIDE; + void extended_surface_set_generic_property(const QString &name, wl_array *value) Q_DECL_OVERRIDE; + QWaylandWindow *m_window; QVariantMap m_properties; - static void onscreen_visibility(void *data, - struct wl_extended_surface *wl_extended_surface, - int32_t visible); - - static void set_generic_property(void *data, - struct wl_extended_surface *wl_extended_surface, - const char *name, - struct wl_array *value); - - static const struct wl_extended_surface_listener extended_surface_listener; - bool m_exposed; }; diff --git a/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp index 9820854d..62cbdf36 100644 --- a/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp @@ -66,7 +66,8 @@ QT_USE_NAMESPACE QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id) - : mQDisplay(display) + : QtWayland::wl_seat(display->wl_registry(), id) + , mQDisplay(display) , mDisplay(display->wl_display()) , mCaps(0) , mTransferDevice(0) @@ -81,10 +82,6 @@ QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id) , mXkbState(0) #endif { - mSeat = static_cast<struct wl_seat *>(wl_registry_bind(display->wl_registry(), id, &wl_seat_interface, 1)); - wl_seat_add_listener(mSeat, &seatListener, this); - wl_seat_set_user_data(mSeat, this); - #ifndef QT_NO_WAYLAND_XKB xkb_rule_names names; names.rules = strdup("evdev"); @@ -122,59 +119,26 @@ QWaylandInputDevice::~QWaylandInputDevice() #endif } -const struct wl_seat_listener QWaylandInputDevice::seatListener = { - QWaylandInputDevice::seat_capabilities -}; - -const struct wl_pointer_listener QWaylandInputDevice::pointerListener = { - QWaylandInputDevice::pointer_enter, - QWaylandInputDevice::pointer_leave, - QWaylandInputDevice::pointer_motion, - QWaylandInputDevice::pointer_button, - QWaylandInputDevice::pointer_axis -}; - -const struct wl_keyboard_listener QWaylandInputDevice::keyboardListener = { - QWaylandInputDevice::keyboard_keymap, - QWaylandInputDevice::keyboard_enter, - QWaylandInputDevice::keyboard_leave, - QWaylandInputDevice::keyboard_key, - QWaylandInputDevice::keyboard_modifiers -}; - -const struct wl_touch_listener QWaylandInputDevice::touchListener = { - QWaylandInputDevice::touch_down, - QWaylandInputDevice::touch_up, - QWaylandInputDevice::touch_motion, - QWaylandInputDevice::touch_frame, - QWaylandInputDevice::touch_cancel -}; - -void QWaylandInputDevice::seat_capabilities(void *data, struct wl_seat *seat, uint32_t caps) +void QWaylandInputDevice::seat_capabilities(uint32_t caps) { - QWaylandInputDevice *self = static_cast<QWaylandInputDevice *>(data); - self->mCaps = caps; + mCaps = caps; - if (caps & WL_SEAT_CAPABILITY_KEYBOARD) { - self->mDeviceInterfaces.keyboard = wl_seat_get_keyboard(seat); - wl_keyboard_add_listener(self->mDeviceInterfaces.keyboard, &keyboardListener, self); - } + if (caps & WL_SEAT_CAPABILITY_KEYBOARD) + QtWayland::wl_keyboard::init(get_keyboard()); if (caps & WL_SEAT_CAPABILITY_POINTER) { - self->mDeviceInterfaces.pointer = wl_seat_get_pointer(seat); - self->mDeviceInterfaces.pointerSurface = self->mQDisplay->createSurface(self); - wl_pointer_add_listener(self->mDeviceInterfaces.pointer, &pointerListener, self); + QtWayland::wl_pointer::init(get_pointer()); + pointerSurface = mQDisplay->createSurface(this); } if (caps & WL_SEAT_CAPABILITY_TOUCH) { - self->mDeviceInterfaces.touch = wl_seat_get_touch(seat); - wl_touch_add_listener(self->mDeviceInterfaces.touch, &touchListener, self); - - if (!self->mTouchDevice) { - self->mTouchDevice = new QTouchDevice; - self->mTouchDevice->setType(QTouchDevice::TouchScreen); - self->mTouchDevice->setCapabilities(QTouchDevice::Position); - QWindowSystemInterface::registerTouchDevice(self->mTouchDevice); + QtWayland::wl_touch::init(get_touch()); + + if (!mTouchDevice) { + mTouchDevice = new QTouchDevice; + mTouchDevice->setType(QTouchDevice::TouchScreen); + mTouchDevice->setCapabilities(QTouchDevice::Position); + QWindowSystemInterface::registerTouchDevice(mTouchDevice); } } } @@ -189,7 +153,7 @@ void QWaylandInputDevice::handleWindowDestroyed(QWaylandWindow *window) void QWaylandInputDevice::setTransferDevice(struct wl_data_device *device) { - mTransferDevice = device; + mTransferDevice = device; } struct wl_data_device *QWaylandInputDevice::transferDevice() const @@ -206,51 +170,37 @@ void QWaylandInputDevice::removeMouseButtonFromState(Qt::MouseButton button) void QWaylandInputDevice::setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image) { if (mCaps & WL_SEAT_CAPABILITY_POINTER) { - wl_pointer_set_cursor(mDeviceInterfaces.pointer, mEnterSerial, mDeviceInterfaces.pointerSurface, - image->hotspot_x, image->hotspot_y); - wl_surface_attach(mDeviceInterfaces.pointerSurface, buffer, 0, 0); - wl_surface_damage(mDeviceInterfaces.pointerSurface, 0, 0, image->width, image->height); - wl_surface_commit(mDeviceInterfaces.pointerSurface); + set_cursor(mEnterSerial, pointerSurface, + image->hotspot_x, image->hotspot_y); + wl_surface_attach(pointerSurface, buffer, 0, 0); + wl_surface_damage(pointerSurface, 0, 0, image->width, image->height); + wl_surface_commit(pointerSurface); } } -void QWaylandInputDevice::pointer_enter(void *data, - struct wl_pointer *pointer, - uint32_t serial, struct wl_surface *surface, +void QWaylandInputDevice::pointer_enter(uint32_t serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy) { - Q_UNUSED(pointer); Q_UNUSED(sx); Q_UNUSED(sy); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; if (!surface) return; QGuiApplication::setOverrideCursor(QCursor(Qt::ArrowCursor)); - QWaylandWindow *window = (QWaylandWindow *) wl_surface_get_user_data(surface); + QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); window->handleMouseEnter(); - window->handleMouse(inputDevice, - inputDevice->mTime, - inputDevice->mSurfacePos, - inputDevice->mGlobalPos, - inputDevice->mButtons, - Qt::NoModifier); - inputDevice->mPointerFocus = window; - - inputDevice->mTime = QWaylandDisplay::currentTimeMillisec(); - inputDevice->mSerial = serial; - inputDevice->mEnterSerial = serial; + window->handleMouse(this, mTime, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); + mPointerFocus = window; + + mTime = QWaylandDisplay::currentTimeMillisec(); + mSerial = serial; + mEnterSerial = serial; } -void QWaylandInputDevice::pointer_leave(void *data, - struct wl_pointer *pointer, - uint32_t time, struct wl_surface *surface) +void QWaylandInputDevice::pointer_leave(uint32_t time, struct wl_surface *surface) { - Q_UNUSED(pointer); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - // The event may arrive after destroying the window, indicated by // a null surface. if (!surface) @@ -258,24 +208,20 @@ void QWaylandInputDevice::pointer_leave(void *data, QGuiApplication::restoreOverrideCursor(); - QWaylandWindow *window = (QWaylandWindow *) wl_surface_get_user_data(surface); + QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); window->handleMouseLeave(); - inputDevice->mPointerFocus = 0; - inputDevice->mButtons = Qt::NoButton; + mPointerFocus = 0; + mButtons = Qt::NoButton; - inputDevice->mTime = time; + mTime = time; } -void QWaylandInputDevice::pointer_motion(void *data, - struct wl_pointer *pointer, - uint32_t time, - wl_fixed_t surface_x, wl_fixed_t surface_y) +void QWaylandInputDevice::pointer_motion(uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { - Q_UNUSED(pointer); Q_UNUSED(surface_x); Q_UNUSED(surface_y); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - QWaylandWindow *window = inputDevice->mPointerFocus; + + QWaylandWindow *window = mPointerFocus; if (window == NULL) { // We destroyed the pointer focus surface, but the server @@ -288,27 +234,18 @@ void QWaylandInputDevice::pointer_motion(void *data, QPointF global = window->window()->mapToGlobal(pos.toPoint()); global += delta; - inputDevice->mSurfacePos = pos; - inputDevice->mGlobalPos = global; - inputDevice->mTime = time; + mSurfacePos = pos; + mGlobalPos = global; + mTime = time; - window->handleMouse(inputDevice, - time, - inputDevice->mSurfacePos, - inputDevice->mGlobalPos, - inputDevice->mButtons, - Qt::NoModifier); + window->handleMouse(this, time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); } -void QWaylandInputDevice::pointer_button(void *data, - struct wl_pointer *pointer, - uint32_t serial, uint32_t time, +void QWaylandInputDevice::pointer_button(uint32_t serial, uint32_t time, uint32_t button, uint32_t state) { - Q_UNUSED(pointer); Q_UNUSED(serial); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - QWaylandWindow *window = inputDevice->mPointerFocus; + QWaylandWindow *window = mPointerFocus; Qt::MouseButton qt_button; // translate from kernel (input.h) 'button' to corresponding Qt:MouseButton. @@ -334,32 +271,20 @@ void QWaylandInputDevice::pointer_button(void *data, } if (state) - inputDevice->mButtons |= qt_button; + mButtons |= qt_button; else - inputDevice->mButtons &= ~qt_button; + mButtons &= ~qt_button; - inputDevice->mTime = time; - inputDevice->mSerial = serial; + mTime = time; + mSerial = serial; - if (window) { - window->handleMouse(inputDevice, - time, - inputDevice->mSurfacePos, - inputDevice->mGlobalPos, - inputDevice->mButtons, - Qt::NoModifier); - } + if (window) + window->handleMouse(this, time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); } -void QWaylandInputDevice::pointer_axis(void *data, - struct wl_pointer *pointer, - uint32_t time, - uint32_t axis, - int32_t value) +void QWaylandInputDevice::pointer_axis(uint32_t time, uint32_t axis, int32_t value) { - Q_UNUSED(pointer); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - QWaylandWindow *window = inputDevice->mPointerFocus; + QWaylandWindow *window = mPointerFocus; QPoint pixelDelta; QPoint angleDelta; @@ -375,10 +300,8 @@ void QWaylandInputDevice::pointer_axis(void *data, } QWindowSystemInterface::handleWheelEvent(window->window(), - time, - inputDevice->mSurfacePos, - inputDevice->mGlobalPos, - pixelDelta, + time, mSurfacePos, + mGlobalPos, pixelDelta, angleDelta); } @@ -497,71 +420,49 @@ static uint32_t translateKey(uint32_t sym, char *string, size_t size) #endif // QT_NO_WAYLAND_XKB -void QWaylandInputDevice::keyboard_keymap(void *data, - struct wl_keyboard *keyboard, - uint32_t format, - int32_t fd, - uint32_t size) +void QWaylandInputDevice::keyboard_keymap(uint32_t format, int32_t fd, uint32_t size) { - Q_UNUSED(data); - Q_UNUSED(keyboard); Q_UNUSED(format); Q_UNUSED(fd); Q_UNUSED(size); } -void QWaylandInputDevice::keyboard_enter(void *data, - struct wl_keyboard *keyboard, - uint32_t time, - struct wl_surface *surface, - struct wl_array *keys) +void QWaylandInputDevice::keyboard_enter(uint32_t time, struct wl_surface *surface, struct wl_array *keys) { - Q_UNUSED(keyboard); Q_UNUSED(time); Q_UNUSED(keys); if (!surface) return; - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - QWaylandWindow *window = (QWaylandWindow *) wl_surface_get_user_data(surface); - inputDevice->mKeyboardFocus = window; - inputDevice->mQDisplay->setLastKeyboardFocusInputDevice(inputDevice); + QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); + mKeyboardFocus = window; + mQDisplay->setLastKeyboardFocusInputDevice(this); QWindowSystemInterface::handleWindowActivated(window->window()); } -void QWaylandInputDevice::keyboard_leave(void *data, - struct wl_keyboard *keyboard, - uint32_t time, - struct wl_surface *surface) +void QWaylandInputDevice::keyboard_leave(uint32_t time, struct wl_surface *surface) { - Q_UNUSED(keyboard); Q_UNUSED(time); Q_UNUSED(surface); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - inputDevice->mKeyboardFocus = NULL; - inputDevice->mQDisplay->setLastKeyboardFocusInputDevice(0); + mKeyboardFocus = NULL; + mQDisplay->setLastKeyboardFocusInputDevice(0); } -void QWaylandInputDevice::keyboard_key(void *data, - struct wl_keyboard *keyboard, - uint32_t serial, uint32_t time, - uint32_t key, uint32_t state) +void QWaylandInputDevice::keyboard_key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state) { - Q_UNUSED(keyboard); Q_UNUSED(serial); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - QWaylandWindow *window = inputDevice->mKeyboardFocus; + QWaylandWindow *window = mKeyboardFocus; #ifndef QT_NO_WAYLAND_XKB - if (!inputDevice->mXkbMap) + if (!mXkbMap) return; uint32_t code = key + 8; bool isDown = state != 0; const xkb_keysym_t *syms; - uint32_t numSyms = xkb_key_get_syms(inputDevice->mXkbState, code, &syms); - xkb_state_update_key(inputDevice->mXkbState, code, + uint32_t numSyms = xkb_key_get_syms(mXkbState, code, &syms); + xkb_state_update_key(mXkbState, code, isDown ? XKB_KEY_DOWN : XKB_KEY_UP); if (!window) { @@ -572,7 +473,7 @@ void QWaylandInputDevice::keyboard_key(void *data, if (numSyms == 1) { xkb_keysym_t sym = syms[0]; - Qt::KeyboardModifiers modifiers = translateModifiers(inputDevice->mXkbState); + Qt::KeyboardModifiers modifiers = translateModifiers(mXkbState); QEvent::Type type = isDown ? QEvent::KeyPress : QEvent::KeyRelease; char s[2]; @@ -597,24 +498,20 @@ void QWaylandInputDevice::keyboard_key(void *data, #endif } -void QWaylandInputDevice::keyboard_modifiers(void *data, - struct wl_keyboard *keyboard, - uint32_t serial, +void QWaylandInputDevice::keyboard_modifiers(uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) { - Q_UNUSED(keyboard); Q_UNUSED(serial); #ifndef QT_NO_WAYLAND_XKB - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - if (inputDevice->mXkbState) - xkb_state_update_mask(inputDevice->mXkbState, + if (mXkbState) + xkb_state_update_mask(mXkbState, mods_depressed, mods_latched, mods_locked, 0, 0, group); #else - Q_UNUSED(data); + Q_UNUSED(serial); Q_UNUSED(mods_depressed); Q_UNUSED(mods_latched); Q_UNUSED(mods_locked); @@ -622,70 +519,43 @@ void QWaylandInputDevice::keyboard_modifiers(void *data, #endif } -void QWaylandInputDevice::touch_down(void *data, - struct wl_touch *touch, - uint32_t serial, +void QWaylandInputDevice::touch_down(uint32_t serial, uint32_t time, struct wl_surface *surface, int32_t id, wl_fixed_t x, wl_fixed_t y) { - Q_UNUSED(touch); Q_UNUSED(serial); Q_UNUSED(time); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - inputDevice->mTouchFocus = static_cast<QWaylandWindow *>(wl_surface_get_user_data(surface)); - inputDevice->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointPressed); + mTouchFocus = QWaylandWindow::fromWlSurface(surface); + handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointPressed); } -void QWaylandInputDevice::touch_up(void *data, - struct wl_touch *touch, - uint32_t serial, - uint32_t time, - int32_t id) +void QWaylandInputDevice::touch_up(uint32_t serial, uint32_t time, int32_t id) { - Q_UNUSED(touch); Q_UNUSED(serial); Q_UNUSED(time); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - inputDevice->mTouchFocus = 0; - inputDevice->handleTouchPoint(id, 0, 0, Qt::TouchPointReleased); + mTouchFocus = 0; + handleTouchPoint(id, 0, 0, Qt::TouchPointReleased); } -void QWaylandInputDevice::touch_motion(void *data, - struct wl_touch *touch, - uint32_t time, - int32_t id, - wl_fixed_t x, - wl_fixed_t y) +void QWaylandInputDevice::touch_motion(uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y) { - Q_UNUSED(touch); Q_UNUSED(time); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - inputDevice->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointMoved); + handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointMoved); } -void QWaylandInputDevice::touch_frame(void *data, struct wl_touch *touch) +void QWaylandInputDevice::touch_cancel() { - Q_UNUSED(touch); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - inputDevice->handleTouchFrame(); -} - -void QWaylandInputDevice::touch_cancel(void *data, struct wl_touch *touch) -{ - Q_UNUSED(touch); - QWaylandInputDevice *self = static_cast<QWaylandInputDevice *>(data); - - self->mPrevTouchPoints.clear(); - self->mTouchPoints.clear(); + mPrevTouchPoints.clear(); + mTouchPoints.clear(); - QWaylandTouchExtension *touchExt = self->mQDisplay->touchExtension(); + QWaylandTouchExtension *touchExt = mQDisplay->touchExtension(); if (touchExt) touchExt->touchCanceled(); - QWindowSystemInterface::handleTouchCancelEvent(0, self->mTouchDevice); + QWindowSystemInterface::handleTouchCancelEvent(0, mTouchDevice); } void QWaylandInputDevice::handleTouchPoint(int id, double x, double y, Qt::TouchPointState state) @@ -726,7 +596,7 @@ void QWaylandInputDevice::handleTouchPoint(int id, double x, double y, Qt::Touch mTouchPoints.append(tp); } -void QWaylandInputDevice::handleTouchFrame() +void QWaylandInputDevice::touch_frame() { // Copy all points, that are in the previous but not in the current list, as stationary. for (int i = 0; i < mPrevTouchPoints.count(); ++i) { diff --git a/src/plugins/platforms/wayland_common/qwaylandinputdevice.h b/src/plugins/platforms/wayland_common/qwaylandinputdevice.h index 71634382..c0e57a90 100644 --- a/src/plugins/platforms/wayland_common/qwaylandinputdevice.h +++ b/src/plugins/platforms/wayland_common/qwaylandinputdevice.h @@ -52,6 +52,8 @@ #include <wayland-client.h> +#include "qwayland-wayland.h" + #ifndef QT_NO_WAYLAND_XKB struct xkb_context; struct xkb_keymap; @@ -63,14 +65,15 @@ QT_BEGIN_NAMESPACE class QWaylandWindow; class QWaylandDisplay; -class QWaylandInputDevice { +class QWaylandInputDevice : public QtWayland::wl_pointer, public QtWayland::wl_keyboard, public QtWayland::wl_touch, public QtWayland::wl_seat +{ public: QWaylandInputDevice(QWaylandDisplay *display, uint32_t id); ~QWaylandInputDevice(); uint32_t capabilities() const { return mCaps; } - struct wl_seat *wl_seat() const { return mSeat; } + struct ::wl_seat *wl_seat() { return QtWayland::wl_seat::object(); } void setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image); void handleWindowDestroyed(QWaylandWindow *window); @@ -86,15 +89,9 @@ private: QWaylandDisplay *mQDisplay; struct wl_display *mDisplay; - struct wl_seat *mSeat; uint32_t mCaps; - struct { - struct wl_pointer *pointer; - struct wl_surface *pointerSurface; - struct wl_keyboard *keyboard; - struct wl_touch *touch; - } mDeviceInterfaces; + struct wl_surface *pointerSurface; struct wl_data_device *mTransferDevice; QWaylandWindow *mPointerFocus; @@ -108,91 +105,53 @@ private: uint32_t mSerial; uint32_t mEnterSerial; - static const struct wl_seat_listener seatListener; - - static void seat_capabilities(void *data, - struct wl_seat *seat, - uint32_t caps); - - static const struct wl_pointer_listener pointerListener; - - static void pointer_enter(void *data, - struct wl_pointer *pointer, - uint32_t serial, struct wl_surface *surface, - wl_fixed_t sx, wl_fixed_t sy); - static void pointer_leave(void *data, - struct wl_pointer *pointer, - uint32_t time, struct wl_surface *surface); - static void pointer_motion(void *data, - struct wl_pointer *pointer, - uint32_t time, - wl_fixed_t sx, wl_fixed_t sy); - static void pointer_button(void *data, - struct wl_pointer *pointer, - uint32_t serial, uint32_t time, - uint32_t button, uint32_t state); - static void pointer_axis(void *data, - struct wl_pointer *pointer, - uint32_t time, - uint32_t axis, - wl_fixed_t value); - - static const struct wl_keyboard_listener keyboardListener; - - static void keyboard_keymap(void *data, - struct wl_keyboard *keyboard, - uint32_t format, - int32_t fd, - uint32_t size); - static void keyboard_enter(void *data, - struct wl_keyboard *keyboard, - uint32_t time, - struct wl_surface *surface, - struct wl_array *keys); - static void keyboard_leave(void *data, - struct wl_keyboard *keyboard, - uint32_t time, - struct wl_surface *surface); - static void keyboard_key(void *data, - struct wl_keyboard *keyboard, - uint32_t serial, uint32_t time, - uint32_t key, uint32_t state); - static void keyboard_modifiers(void *data, - struct wl_keyboard *keyboard, - uint32_t serial, - uint32_t mods_depressed, - uint32_t mods_latched, - uint32_t mods_locked, - uint32_t group); - - static const struct wl_touch_listener touchListener; - - static void touch_down(void *data, - struct wl_touch *touch, - uint32_t serial, - uint32_t time, - struct wl_surface *surface, - int32_t id, - wl_fixed_t x, - wl_fixed_t y); - static void touch_up(void *data, - struct wl_touch *touch, - uint32_t serial, - uint32_t time, - int32_t id); - static void touch_motion(void *data, - struct wl_touch *touch, - uint32_t time, - int32_t id, - wl_fixed_t x, - wl_fixed_t y); - static void touch_frame(void *data, - struct wl_touch *touch); - static void touch_cancel(void *data, - struct wl_touch *touch); + void seat_capabilities(uint32_t caps) Q_DECL_OVERRIDE; + + void pointer_enter(uint32_t serial, struct wl_surface *surface, + wl_fixed_t sx, wl_fixed_t sy) Q_DECL_OVERRIDE; + void pointer_leave(uint32_t time, struct wl_surface *surface); + void pointer_motion(uint32_t time, + wl_fixed_t sx, wl_fixed_t sy) Q_DECL_OVERRIDE; + void pointer_button(uint32_t serial, uint32_t time, + uint32_t button, uint32_t state) Q_DECL_OVERRIDE; + void pointer_axis(uint32_t time, + uint32_t axis, + wl_fixed_t value) Q_DECL_OVERRIDE; + + void keyboard_keymap(uint32_t format, + int32_t fd, + uint32_t size) Q_DECL_OVERRIDE; + void keyboard_enter(uint32_t time, + struct wl_surface *surface, + struct wl_array *keys) Q_DECL_OVERRIDE; + void keyboard_leave(uint32_t time, + struct wl_surface *surface) Q_DECL_OVERRIDE; + void keyboard_key(uint32_t serial, uint32_t time, + uint32_t key, uint32_t state) Q_DECL_OVERRIDE; + void keyboard_modifiers(uint32_t serial, + uint32_t mods_depressed, + uint32_t mods_latched, + uint32_t mods_locked, + uint32_t group) Q_DECL_OVERRIDE; + + void touch_down(uint32_t serial, + uint32_t time, + struct wl_surface *surface, + int32_t id, + wl_fixed_t x, + wl_fixed_t y) Q_DECL_OVERRIDE; + void touch_up(uint32_t serial, + uint32_t time, + int32_t id) Q_DECL_OVERRIDE; + void touch_motion(uint32_t time, + int32_t id, + wl_fixed_t x, + wl_fixed_t y) Q_DECL_OVERRIDE; + void touch_frame() Q_DECL_OVERRIDE; + void touch_cancel() Q_DECL_OVERRIDE; void handleTouchPoint(int id, double x, double y, Qt::TouchPointState state); - void handleTouchFrame(); + QList<QWindowSystemInterface::TouchPoint> mTouchPoints; QList<QWindowSystemInterface::TouchPoint> mPrevTouchPoints; QTouchDevice *mTouchDevice; diff --git a/src/plugins/platforms/wayland_common/qwaylandintegration.cpp b/src/plugins/platforms/wayland_common/qwaylandintegration.cpp index 7aaef546..c3a479a2 100644 --- a/src/plugins/platforms/wayland_common/qwaylandintegration.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandintegration.cpp @@ -84,8 +84,7 @@ QWaylandIntegration::QWaylandIntegration() #endif { QGuiApplicationPrivate::instance()->setEventDispatcher(mEventDispatcher); - //Disable desktop settings for wayland clients for now - QGuiApplicationPrivate::obey_desktop_settings = false; + QGuiApplication::setDesktopSettingsAware(false); mDisplay = new QWaylandDisplay(); mClipboard = new QWaylandClipboard(mDisplay); mDrag = new QWaylandDrag(mDisplay); diff --git a/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp b/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp index f5829b27..31d25c0f 100644 --- a/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp @@ -64,7 +64,7 @@ void *QWaylandNativeInterface::nativeResourceForIntegration(const QByteArray &re if (lowerCaseResource == "display") return m_integration->display()->wl_display(); if (lowerCaseResource == "compositor") - return m_integration->display()->wl_compositor(); + return const_cast<wl_compositor *>(m_integration->display()->wl_compositor()); return 0; } @@ -76,7 +76,7 @@ void *QWaylandNativeInterface::nativeResourceForWindow(const QByteArray &resourc if (lowerCaseResource == "display") return m_integration->display()->wl_display(); if (lowerCaseResource == "compositor") - return m_integration->display()->wl_compositor(); + return const_cast<wl_compositor *>(m_integration->display()->wl_compositor()); if (lowerCaseResource == "surface") { return ((QWaylandWindow *) window->handle())->wl_surface(); } diff --git a/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp b/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp index 76d91c79..d9f2071e 100644 --- a/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp @@ -42,34 +42,26 @@ #include "qwaylandqtkey.h" #include "qwaylandinputdevice.h" -#include "wayland-qtkey-extension-client-protocol.h" - QT_USE_NAMESPACE QWaylandQtKeyExtension::QWaylandQtKeyExtension(QWaylandDisplay *display, uint32_t id) - : m_display(display) + : QtWayland::qt_key_extension(display->wl_registry(), id) + , m_display(display) { - m_qtkey = static_cast<struct wl_qtkey_extension *>(wl_registry_bind(display->wl_registry(), id, &wl_qtkey_extension_interface, 1)); - wl_qtkey_extension_add_listener(m_qtkey, &qtkey_listener, this); } -void QWaylandQtKeyExtension::handle_qtkey(void *data, - struct wl_qtkey_extension *ext, - uint32_t time, - uint32_t type, - uint32_t key, - uint32_t modifiers, - uint32_t nativeScanCode, - uint32_t nativeVirtualKey, - uint32_t nativeModifiers, - const char *text, - uint32_t autorep, - uint32_t count) +void QWaylandQtKeyExtension::key_extension_qtkey(uint32_t time, + uint32_t type, + uint32_t key, + uint32_t modifiers, + uint32_t nativeScanCode, + uint32_t nativeVirtualKey, + uint32_t nativeModifiers, + const QString &text, + uint32_t autorep, + uint32_t count) { - Q_UNUSED(ext); - QWaylandQtKeyExtension *self = static_cast<QWaylandQtKeyExtension *>(data); - - QList<QWaylandInputDevice *> inputDevices = self->m_display->inputDevices(); + QList<QWaylandInputDevice *> inputDevices = m_display->inputDevices(); if (inputDevices.isEmpty()) { qWarning("wl_qtkey_extension: handle_qtkey: No input device"); return; @@ -85,11 +77,6 @@ void QWaylandQtKeyExtension::handle_qtkey(void *data, QWindow *window = win->window(); QWindowSystemInterface::handleExtendedKeyEvent(window, time, QEvent::Type(type), key, Qt::KeyboardModifiers(modifiers), - nativeScanCode, nativeVirtualKey, nativeModifiers, QString::fromUtf8(text), + nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count); } - -const struct wl_qtkey_extension_listener QWaylandQtKeyExtension::qtkey_listener = { - QWaylandQtKeyExtension::handle_qtkey -}; - diff --git a/src/plugins/platforms/wayland_common/qwaylandqtkey.h b/src/plugins/platforms/wayland_common/qwaylandqtkey.h index adcce613..17b758cf 100644 --- a/src/plugins/platforms/wayland_common/qwaylandqtkey.h +++ b/src/plugins/platforms/wayland_common/qwaylandqtkey.h @@ -45,33 +45,28 @@ #include "qwaylanddisplay.h" #include <qpa/qwindowsysteminterface.h> -class wl_qtkey_extension; +#include "qwayland-qtkey-extension.h" QT_BEGIN_NAMESPACE -class QWaylandQtKeyExtension +class QWaylandQtKeyExtension : public QtWayland::qt_key_extension { public: QWaylandQtKeyExtension(QWaylandDisplay *display, uint32_t id); private: QWaylandDisplay *m_display; - wl_qtkey_extension *m_qtkey; - static const struct wl_qtkey_extension_listener qtkey_listener; - - static void handle_qtkey(void *data, - struct wl_qtkey_extension *ext, - uint32_t time, - uint32_t type, - uint32_t key, - uint32_t modifiers, - uint32_t nativeScanCode, - uint32_t nativeVirtualKey, - uint32_t nativeModifiers, - const char *text, - uint32_t autorep, - uint32_t count); + void key_extension_qtkey(uint32_t time, + uint32_t type, + uint32_t key, + uint32_t modifiers, + uint32_t nativeScanCode, + uint32_t nativeVirtualKey, + uint32_t nativeModifiers, + const QString &text, + uint32_t autorep, + uint32_t count) Q_DECL_OVERRIDE; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandscreen.cpp b/src/plugins/platforms/wayland_common/qwaylandscreen.cpp index 8393058f..1cb1b9cf 100644 --- a/src/plugins/platforms/wayland_common/qwaylandscreen.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandscreen.cpp @@ -49,20 +49,17 @@ QT_USE_NAMESPACE -QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, struct wl_output *output) - : QPlatformScreen() +QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, uint32_t id) + : QtWayland::wl_output(waylandDisplay->wl_registry(), id) , mWaylandDisplay(waylandDisplay) - , mOutput(output) , mExtendedOutput(0) , mDepth(32) , mRefreshRate(60000) , mFormat(QImage::Format_ARGB32_Premultiplied) , mWaylandCursor(new QWaylandCursor(this)) { - //maybe the global is sent after the first screen? - if (waylandDisplay->outputExtension()) { - mExtendedOutput = waylandDisplay->outputExtension()->getExtendedOutput(this); - } + // handle case of output extension global being sent after outputs + createExtendedOutput(); } QWaylandScreen::~QWaylandScreen() @@ -75,15 +72,6 @@ QWaylandDisplay * QWaylandScreen::display() const return mWaylandDisplay; } -void QWaylandScreen::setGeometry(const QRect &geom) -{ - if (mGeometry == geom) - return; - - mGeometry = geom; - QWindowSystemInterface::handleScreenGeometryChange(screen(), mGeometry); -} - QRect QWaylandScreen::geometry() const { return mGeometry; @@ -127,10 +115,11 @@ QWaylandExtendedOutput *QWaylandScreen::extendedOutput() const return mExtendedOutput; } -void QWaylandScreen::setExtendedOutput(QWaylandExtendedOutput *extendedOutput) +void QWaylandScreen::createExtendedOutput() { - Q_ASSERT(!mExtendedOutput); - mExtendedOutput = extendedOutput; + QtWayland::qt_output_extension *extension = mWaylandDisplay->outputExtension(); + if (!mExtendedOutput && extension) + mExtendedOutput = new QWaylandExtendedOutput(this, extension->get_extended_output(output())); } QWaylandScreen * QWaylandScreen::waylandScreenFromWindow(QWindow *window) @@ -139,15 +128,41 @@ QWaylandScreen * QWaylandScreen::waylandScreenFromWindow(QWindow *window) return static_cast<QWaylandScreen *>(platformScreen); } -void QWaylandScreen::handleMode(const QSize &size, int refreshRate) +void QWaylandScreen::output_mode(uint32_t flags, int width, int height, int refresh) { + if (!(flags & WL_OUTPUT_MODE_CURRENT)) + return; + + QSize size(width, height); + if (size != mGeometry.size()) { mGeometry.setSize(size); QWindowSystemInterface::handleScreenGeometryChange(screen(), mGeometry); } - if (refreshRate != mRefreshRate) { - mRefreshRate = refreshRate; + if (refresh != mRefreshRate) { + mRefreshRate = refresh; QWindowSystemInterface::handleScreenRefreshRateChange(screen(), mRefreshRate); } } + +void QWaylandScreen::output_geometry(int32_t x, int32_t y, + int32_t width, int32_t height, + int subpixel, + const QString &make, + const QString &model, + int32_t transform) +{ + Q_UNUSED(subpixel); + Q_UNUSED(make); + Q_UNUSED(model); + Q_UNUSED(transform); + + QRect geom(x, y, width, height); + + if (mGeometry == geom) + return; + + mGeometry = geom; + QWindowSystemInterface::handleScreenGeometryChange(screen(), mGeometry); +} diff --git a/src/plugins/platforms/wayland_common/qwaylandscreen.h b/src/plugins/platforms/wayland_common/qwaylandscreen.h index 3d4b2948..005f25ee 100644 --- a/src/plugins/platforms/wayland_common/qwaylandscreen.h +++ b/src/plugins/platforms/wayland_common/qwaylandscreen.h @@ -44,16 +44,18 @@ #include <qpa/qplatformscreen.h> +#include <qwayland-wayland.h> + QT_BEGIN_NAMESPACE class QWaylandDisplay; class QWaylandCursor; class QWaylandExtendedOutput; -class QWaylandScreen : public QPlatformScreen +class QWaylandScreen : public QPlatformScreen, QtWayland::wl_output { public: - QWaylandScreen(QWaylandDisplay *waylandDisplay, struct wl_output *output); + QWaylandScreen(QWaylandDisplay *waylandDisplay, uint32_t id); ~QWaylandScreen(); QWaylandDisplay *display() const; @@ -69,20 +71,23 @@ public: QPlatformCursor *cursor() const; - wl_output *output() const { return mOutput; } + ::wl_output *output() { return object(); } QWaylandExtendedOutput *extendedOutput() const; - void setExtendedOutput(QWaylandExtendedOutput *extendedOutput); + void createExtendedOutput(); static QWaylandScreen *waylandScreenFromWindow(QWindow *window); - void handleMode(const QSize &size, int refreshRate); - - void setGeometry(const QRect &geom); - private: + void output_mode(uint32_t flags, int width, int height, int refresh) Q_DECL_OVERRIDE; + void output_geometry(int32_t x, int32_t y, + int32_t width, int32_t height, + int subpixel, + const QString &make, + const QString &model, + int32_t transform) Q_DECL_OVERRIDE; + QWaylandDisplay *mWaylandDisplay; - struct wl_output *mOutput; QWaylandExtendedOutput *mExtendedOutput; QRect mGeometry; int mDepth; diff --git a/src/plugins/platforms/wayland_common/qwaylandshell.cpp b/src/plugins/platforms/wayland_common/qwaylandshell.cpp deleted file mode 100644 index 9c37235c..00000000 --- a/src/plugins/platforms/wayland_common/qwaylandshell.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the config.tests of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwaylandshell.h" - -#include "qwaylandshellsurface.h" -#include "qwaylandwindow.h" - -QT_USE_NAMESPACE - -QWaylandShell::QWaylandShell(QWaylandDisplay *display, uint32_t id, uint32_t version) - : m_display(display) -{ - Q_UNUSED(version) - m_shell = static_cast<struct wl_shell *>(wl_registry_bind(m_display->wl_registry(), id, &wl_shell_interface, 1)); -} - -QWaylandShellSurface *QWaylandShell::getShellSurface(QWaylandWindow *window) -{ - Q_ASSERT(window->wl_surface()); - struct wl_shell_surface *shell_surface = wl_shell_get_shell_surface(m_shell,window->wl_surface()); - return new QWaylandShellSurface(shell_surface,window); -} diff --git a/src/plugins/platforms/wayland_common/qwaylandshell.h b/src/plugins/platforms/wayland_common/qwaylandshell.h deleted file mode 100644 index 3c2014f6..00000000 --- a/src/plugins/platforms/wayland_common/qwaylandshell.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the config.tests of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWAYLANDSHELL_H -#define QWAYLANDSHELL_H - -#include "qwaylanddisplay.h" - -QT_BEGIN_NAMESPACE - -class QWaylandWindow; -class QWaylandShellSurface; - -class QWaylandShell -{ -public: - QWaylandShell(QWaylandDisplay *display, uint32_t id, uint32_t version); - - QWaylandShellSurface *getShellSurface(QWaylandWindow *window); - -private: - struct wl_shell *m_shell; - - QWaylandDisplay *m_display; -}; - -QT_END_NAMESPACE - -#endif // QWAYLANDSHELL_H diff --git a/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp b/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp index 890552c2..98689073 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp @@ -51,46 +51,44 @@ QT_USE_NAMESPACE -QWaylandShellSurface::QWaylandShellSurface(struct wl_shell_surface *shell_surface, QWaylandWindow *window) - : m_shell_surface(shell_surface) +QWaylandShellSurface::QWaylandShellSurface(struct ::wl_shell_surface *shell_surface, QWaylandWindow *window) + : QtWayland::wl_shell_surface(shell_surface) , m_window(window) , m_maximized(false) , m_fullscreen(false) { - wl_shell_surface_add_listener(m_shell_surface,&m_shell_surface_listener,this); } QWaylandShellSurface::~QWaylandShellSurface() { - wl_shell_surface_destroy(m_shell_surface); + wl_shell_surface_destroy(object()); } void QWaylandShellSurface::resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges) { - wl_shell_surface_resize(m_shell_surface,inputDevice->wl_seat(), - inputDevice->serial(), - edges); + resize(inputDevice->wl_seat(), + inputDevice->serial(), + edges); } void QWaylandShellSurface::move(QWaylandInputDevice *inputDevice) { - wl_shell_surface_move(m_shell_surface, - inputDevice->wl_seat(), - inputDevice->serial()); + move(inputDevice->wl_seat(), + inputDevice->serial()); } void QWaylandShellSurface::setMaximized() { m_maximized = true; m_size = m_window->window()->geometry().size(); - wl_shell_surface_set_maximized(m_shell_surface, 0); + set_maximized(0); } void QWaylandShellSurface::setFullscreen() { m_fullscreen = true; m_size = m_window->window()->geometry().size(); - wl_shell_surface_set_fullscreen(m_shell_surface, 0, 0, 0); + set_fullscreen(0, 0, 0); } void QWaylandShellSurface::setNormal() @@ -110,7 +108,7 @@ void QWaylandShellSurface::setMinimized() void QWaylandShellSurface::setTopLevel() { - wl_shell_surface_set_toplevel(m_shell_surface); + set_toplevel(); } void QWaylandShellSurface::updateTransientParent(QWindow *parent) @@ -134,11 +132,10 @@ void QWaylandShellSurface::updateTransientParent(QWindow *parent) || wf.testFlag(Qt::WindowTransparentForInput)) flags |= WL_SHELL_SURFACE_TRANSIENT_INACTIVE; - wl_shell_surface_set_transient(m_shell_surface, - parent_wayland_window->wl_surface(), - transientPos.x(), - transientPos.y(), - flags); + set_transient(parent_wayland_window->wl_surface(), + transientPos.x(), + transientPos.y(), + flags); } void QWaylandShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial) @@ -155,52 +152,34 @@ void QWaylandShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top()); } - wl_shell_surface_set_popup(m_shell_surface, device->wl_seat(), serial, + wl_shell_surface_set_popup(object(), device->wl_seat(), serial, parent_wayland_window->wl_surface(), transientPos.x(), transientPos.y(), 0); } -void QWaylandShellSurface::setClassName(const char *_class) +void QWaylandShellSurface::setClassName(const char *className) { - wl_shell_surface_set_class(m_shell_surface, _class); + set_class(className); } void QWaylandShellSurface::setTitle(const char *title) { - wl_shell_surface_set_title(m_shell_surface, title); + set_title(title); } -void QWaylandShellSurface::ping(void *data, - struct wl_shell_surface *wl_shell_surface, - uint32_t serial) +void QWaylandShellSurface::shell_surface_ping(uint32_t serial) { - Q_UNUSED(data); - wl_shell_surface_pong(wl_shell_surface, serial); + pong(serial); } -void QWaylandShellSurface::configure(void *data, - wl_shell_surface *wl_shell_surface, - uint32_t edges, - int32_t width, - int32_t height) +void QWaylandShellSurface::shell_surface_configure(uint32_t edges, + int32_t width, + int32_t height) { - Q_UNUSED(wl_shell_surface); - QWaylandShellSurface *shell_surface = static_cast<QWaylandShellSurface *>(data); - shell_surface->m_window->configure(edges, width, height); + m_window->configure(edges, width, height); } -void QWaylandShellSurface::popup_done(void *data, - struct wl_shell_surface *wl_shell_surface) +void QWaylandShellSurface::shell_surface_popup_done() { - Q_UNUSED(data); - Q_UNUSED(wl_shell_surface); - - QWaylandShellSurface *shell_surface = static_cast<QWaylandShellSurface *>(data); - QCoreApplication::postEvent(shell_surface->m_window->window(), new QCloseEvent()); + QCoreApplication::postEvent(m_window->window(), new QCloseEvent()); } - -const wl_shell_surface_listener QWaylandShellSurface::m_shell_surface_listener = { - QWaylandShellSurface::ping, - QWaylandShellSurface::configure, - QWaylandShellSurface::popup_done -}; diff --git a/src/plugins/platforms/wayland_common/qwaylandshellsurface.h b/src/plugins/platforms/wayland_common/qwaylandshellsurface.h index e9061f0b..9e886cf0 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshellsurface.h +++ b/src/plugins/platforms/wayland_common/qwaylandshellsurface.h @@ -46,19 +46,24 @@ #include <wayland-client.h> +#include "qwayland-wayland.h" + QT_BEGIN_NAMESPACE class QWaylandWindow; class QWaylandInputDevice; class QWindow; -class QWaylandShellSurface +class QWaylandShellSurface : public QtWayland::wl_shell_surface { public: - QWaylandShellSurface(struct wl_shell_surface *shell_surface, QWaylandWindow *window); + QWaylandShellSurface(struct ::wl_shell_surface *shell_surface, QWaylandWindow *window); ~QWaylandShellSurface(); + using QtWayland::wl_shell_surface::resize; void resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges); + + using QtWayland::wl_shell_surface::move; void move(QWaylandInputDevice *inputDevice); private: @@ -71,29 +76,20 @@ private: void updateTransientParent(QWindow *parent); void setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial); - struct wl_shell_surface *handle() const { return m_shell_surface; } - void setClassName(const char *_class); void setTitle(const char *title); - struct wl_shell_surface *m_shell_surface; QWaylandWindow *m_window; bool m_maximized; bool m_fullscreen; QSize m_size; - static void ping(void *data, - struct wl_shell_surface *wl_shell_surface, - uint32_t serial); - static void configure(void *data, - struct wl_shell_surface *wl_shell_surface, - uint32_t edges, - int32_t width, - int32_t height); - static void popup_done(void *data, - struct wl_shell_surface *wl_shell_surface); - static const struct wl_shell_surface_listener m_shell_surface_listener; + void shell_surface_ping(uint32_t serial) Q_DECL_OVERRIDE; + void shell_surface_configure(uint32_t edges, + int32_t width, + int32_t height) Q_DECL_OVERRIDE; + void shell_surface_popup_done() Q_DECL_OVERRIDE; friend class QWaylandWindow; }; diff --git a/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp b/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp index b444d2b2..93161a3f 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp @@ -192,6 +192,9 @@ void QWaylandShmBackingStore::flush(QWindow *window, const QRegion ®ion, cons Q_UNUSED(offset); Q_ASSERT(waylandWindow()->windowType() == QWaylandWindow::Shm); + if (windowDecoration() && windowDecoration()->isDirty()) + updateDecorations(); + mFrontBuffer = mBackBuffer; if (mFrameCallback) { @@ -199,7 +202,7 @@ void QWaylandShmBackingStore::flush(QWindow *window, const QRegion ®ion, cons return; } - mFrameCallback = wl_surface_frame(waylandWindow()->wl_surface()); + mFrameCallback = waylandWindow()->frame(); wl_callback_add_listener(mFrameCallback,&frameCallbackListener,this); QMargins margins = windowDecorationMargins(); @@ -222,6 +225,7 @@ void QWaylandShmBackingStore::flush(QWindow *window, const QRegion ®ion, cons } } mFrontBufferIsDirty = false; + waylandWindow()->doResize(); } void QWaylandShmBackingStore::resize(const QSize &size, const QRegion &) @@ -245,8 +249,8 @@ void QWaylandShmBackingStore::resize(const QSize &size) mBackBuffer = new QWaylandShmBuffer(mDisplay, sizeWithMargins, format); - if (windowDecoration()) - windowDecoration()->paintDecoration(); + if (windowDecoration() && window()->isVisible()) + windowDecoration()->update(); } QImage *QWaylandShmBackingStore::entireSurface() const @@ -254,6 +258,36 @@ QImage *QWaylandShmBackingStore::entireSurface() const return mBackBuffer->image(); } +void QWaylandShmBackingStore::updateDecorations() +{ + QPainter decorationPainter(entireSurface()); + decorationPainter.setCompositionMode(QPainter::CompositionMode_Source); + QImage sourceImage = windowDecoration()->contentImage(); + QRect target; + //Top + target.setX(0); + target.setY(0); + target.setWidth(sourceImage.width()); + target.setHeight(windowDecorationMargins().top()); + decorationPainter.drawImage(target, sourceImage, target); + + //Left + target.setWidth(windowDecorationMargins().left()); + target.setHeight(sourceImage.height()); + decorationPainter.drawImage(target, sourceImage, target); + + //Right + target.setX(sourceImage.width() - windowDecorationMargins().right()); + decorationPainter.drawImage(target, sourceImage, target); + + //Bottom + target.setX(0); + target.setY(sourceImage.height() - windowDecorationMargins().bottom()); + target.setWidth(sourceImage.width()); + target.setHeight(windowDecorationMargins().bottom()); + decorationPainter.drawImage(target, sourceImage, target); +} + void QWaylandShmBackingStore::done(void *data, wl_callback *callback, uint32_t time) { Q_UNUSED(time); @@ -269,7 +303,8 @@ void QWaylandShmBackingStore::done(void *data, wl_callback *callback, uint32_t t delete window->attached(); } - window->attachOffset(self->mFrontBuffer); + if (window->attached() != self->mFrontBuffer) + window->attachOffset(self->mFrontBuffer); if (self->mFrontBufferIsDirty && !self->mPainting) { self->mFrontBufferIsDirty = false; @@ -284,3 +319,4 @@ const struct wl_callback_listener QWaylandShmBackingStore::frameCallbackListener }; QT_END_NAMESPACE + diff --git a/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.h b/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.h index 1eadb5ed..60117342 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.h +++ b/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.h @@ -94,6 +94,8 @@ public: void iterateBuffer(); private: + void updateDecorations(); + QWaylandDisplay *mDisplay; QWaylandShmBuffer *mFrontBuffer; QWaylandShmBuffer *mBackBuffer; diff --git a/src/plugins/platforms/wayland_common/qwaylandshmdecoration.cpp b/src/plugins/platforms/wayland_common/qwaylandshmdecoration.cpp deleted file mode 100644 index e6af4ab4..00000000 --- a/src/plugins/platforms/wayland_common/qwaylandshmdecoration.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwaylandshmdecoration.h" - -#include "qwaylandshmwindow.h" -#include "qwaylandshmbackingstore.h" - -QT_USE_NAMESPACE - -QWaylandShmDecoration::QWaylandShmDecoration(QWaylandShmWindow *window) - : QWaylandDecoration(window) -{ - -} - -QWaylandShmDecoration::~QWaylandShmDecoration() -{ -} - -void QWaylandShmDecoration::paintDecoration() -{ - QWaylandShmBackingStore *bs = static_cast<QWaylandShmWindow *>(waylandWindow())->backingStore(); - if (bs) { - paint(bs->entireSurface()); - } -} diff --git a/src/plugins/platforms/wayland_common/qwaylandshmdecoration.h b/src/plugins/platforms/wayland_common/qwaylandshmdecoration.h deleted file mode 100644 index 567e8755..00000000 --- a/src/plugins/platforms/wayland_common/qwaylandshmdecoration.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWAYLANDSHMDECORATION_H -#define QWAYLANDSHMDECORATION_H - -#include "qwaylanddecoration.h" - -QT_BEGIN_NAMESPACE - -class QWaylandShmWindow; - -class QWaylandShmDecoration : public QWaylandDecoration -{ -public: - QWaylandShmDecoration(QWaylandShmWindow *window); - ~QWaylandShmDecoration(); - - void paintDecoration(); - -}; - -QT_END_NAMESPACE - -#endif // QWAYLANDSHMDECORATION_H diff --git a/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp b/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp index ad2fd9a2..f4a0ede0 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp @@ -42,7 +42,6 @@ #include "qwaylandshmwindow.h" #include "qwaylandbuffer.h" -#include "qwaylandshmdecoration.h" #include <QtCore/QVector> @@ -70,9 +69,3 @@ void QWaylandShmWindow::setBackingStore(QWaylandShmBackingStore *backingStore) { mBackingStore = backingStore; } - -void QWaylandShmWindow::createDecorationInstance() -{ - new QWaylandShmDecoration(this); -} - diff --git a/src/plugins/platforms/wayland_common/qwaylandshmwindow.h b/src/plugins/platforms/wayland_common/qwaylandshmwindow.h index f28e1d50..ffd11c94 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshmwindow.h +++ b/src/plugins/platforms/wayland_common/qwaylandshmwindow.h @@ -61,9 +61,6 @@ public: void setBackingStore(QWaylandShmBackingStore *backingStore); QWaylandShmBackingStore *backingStore() const; -protected: - void createDecorationInstance(); - private: QWaylandShmBackingStore *mBackingStore; }; diff --git a/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp b/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp index 0ec955a8..99713bb6 100644 --- a/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp @@ -43,42 +43,23 @@ #include "qwaylandwindow.h" -#include "wayland-sub-surface-extension-client-protocol.h" - #include <QtCore/QDebug> QT_USE_NAMESPACE -QWaylandSubSurfaceExtension::QWaylandSubSurfaceExtension(QWaylandDisplay *display, uint32_t id) -{ - m_sub_surface_extension = static_cast<struct wl_sub_surface_extension *>( - wl_registry_bind(display->wl_registry(), id, &wl_sub_surface_extension_interface, 1)); -} - -QWaylandSubSurface *QWaylandSubSurfaceExtension::getSubSurfaceAwareWindow(QWaylandWindow *window) -{ - struct wl_surface *surface = window->wl_surface(); - Q_ASSERT(surface); - struct wl_sub_surface *sub_surface = - wl_sub_surface_extension_get_sub_surface_aware_surface(m_sub_surface_extension,surface); - - return new QWaylandSubSurface(window,sub_surface); - -} - -QWaylandSubSurface::QWaylandSubSurface(QWaylandWindow *window, struct wl_sub_surface *sub_surface) - : m_window(window) - , m_sub_surface(sub_surface) +QWaylandSubSurface::QWaylandSubSurface(QWaylandWindow *window, struct ::qt_sub_surface *sub_surface) + : QtWayland::qt_sub_surface(sub_surface) + , m_window(window) { } void QWaylandSubSurface::setParent(const QWaylandWindow *parent) { - QWaylandSubSurface *parentSurface = parent? parent->subSurfaceWindow():0; + QWaylandSubSurface *parentSurface = parent ? parent->subSurfaceWindow() : 0; if (parentSurface) { int x = m_window->geometry().x() + parent->frameMargins().left(); int y = m_window->geometry().y() + parent->frameMargins().top(); - wl_sub_surface_attach_sub_surface(parentSurface->m_sub_surface,m_sub_surface,x,y); + parentSurface->attach_sub_surface(object(), x, y); } } diff --git a/src/plugins/platforms/wayland_common/qwaylandsubsurface.h b/src/plugins/platforms/wayland_common/qwaylandsubsurface.h index e594050e..10290d8c 100644 --- a/src/plugins/platforms/wayland_common/qwaylandsubsurface.h +++ b/src/plugins/platforms/wayland_common/qwaylandsubsurface.h @@ -46,34 +46,24 @@ #include <QtCore/qglobal.h> +#include <qwayland-sub-surface-extension.h> + QT_BEGIN_NAMESPACE class QWaylandDisplay; class QWaylandWindow; class QWaylandSubSurface; -class QWaylandSubSurfaceExtension -{ -public: - QWaylandSubSurfaceExtension(QWaylandDisplay *display, uint32_t id); - - QWaylandSubSurface *getSubSurfaceAwareWindow(QWaylandWindow *window); -private: - struct wl_sub_surface_extension *m_sub_surface_extension; -}; - -class QWaylandSubSurface +class QWaylandSubSurface : public QtWayland::qt_sub_surface { public: - QWaylandSubSurface(QWaylandWindow *window, struct wl_sub_surface *sub_surface); + QWaylandSubSurface(QWaylandWindow *window, struct ::qt_sub_surface *sub_surface); void setParent(const QWaylandWindow *parent); - void adjustPositionOfChildren(); private: QWaylandWindow *m_window; - struct wl_sub_surface *m_sub_surface; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandtouch.cpp b/src/plugins/platforms/wayland_common/qwaylandtouch.cpp index 26f57d57..b19165d6 100644 --- a/src/plugins/platforms/wayland_common/qwaylandtouch.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandtouch.cpp @@ -42,20 +42,17 @@ #include "qwaylandtouch.h" #include "qwaylandinputdevice.h" -#include "wayland-touch-extension-client-protocol.h" - QT_USE_NAMESPACE QWaylandTouchExtension::QWaylandTouchExtension(QWaylandDisplay *display, uint32_t id) - : mDisplay(display), + : QtWayland::qt_touch_extension(display->wl_registry(), id), + mDisplay(display), mTouchDevice(0), mPointsLeft(0), mFlags(0), mMouseSourceId(-1), mInputDevice(0) { - mTouch = static_cast<struct wl_touch_extension *>(wl_registry_bind(display->wl_registry(), id, &wl_touch_extension_interface, 1)); - wl_touch_extension_add_listener(mTouch, &touch_listener, this); } void QWaylandTouchExtension::registerDevice(int caps) @@ -71,53 +68,50 @@ static inline qreal fromFixed(int f) return f / qreal(10000); } -void QWaylandTouchExtension::handle_touch(void *data, wl_touch_extension *ext, uint32_t time, - uint32_t id, uint32_t state, int32_t x, int32_t y, - int32_t normalized_x, int32_t normalized_y, - int32_t width, int32_t height, uint32_t pressure, - int32_t velocity_x, int32_t velocity_y, - uint32_t flags, wl_array *rawdata) +void QWaylandTouchExtension::touch_extension_touch(uint32_t time, + uint32_t id, uint32_t state, int32_t x, int32_t y, + int32_t normalized_x, int32_t normalized_y, + int32_t width, int32_t height, uint32_t pressure, + int32_t velocity_x, int32_t velocity_y, + uint32_t flags, wl_array *rawdata) { - Q_UNUSED(ext); - QWaylandTouchExtension *self = static_cast<QWaylandTouchExtension *>(data); - - if (!self->mInputDevice) { - QList<QWaylandInputDevice *> inputDevices = self->mDisplay->inputDevices(); + if (!mInputDevice) { + QList<QWaylandInputDevice *> inputDevices = mDisplay->inputDevices(); if (inputDevices.isEmpty()) { qWarning("wl_touch_extension: handle_touch: No input devices"); return; } - self->mInputDevice = inputDevices.first(); + mInputDevice = inputDevices.first(); } - QWaylandWindow *win = self->mInputDevice->mTouchFocus; + QWaylandWindow *win = mInputDevice->mTouchFocus; if (!win) - win = self->mInputDevice->mPointerFocus; + win = mInputDevice->mPointerFocus; if (!win) - win = self->mInputDevice->mKeyboardFocus; + win = mInputDevice->mKeyboardFocus; if (!win || !win->window()) { qWarning("wl_touch_extension: handle_touch: No pointer focus"); return; } - self->mTargetWindow = win->window(); + mTargetWindow = win->window(); QWindowSystemInterface::TouchPoint tp; tp.id = id; tp.state = Qt::TouchPointState(int(state & 0xFFFF)); int sentPointCount = state >> 16; - if (!self->mPointsLeft) { + if (!mPointsLeft) { Q_ASSERT(sentPointCount > 0); - self->mPointsLeft = sentPointCount; + mPointsLeft = sentPointCount; } tp.flags = QTouchEvent::TouchPoint::InfoFlags(int(flags & 0xFFFF)); - if (!self->mTouchDevice) - self->registerDevice(flags >> 16); + if (!mTouchDevice) + registerDevice(flags >> 16); tp.area = QRectF(0, 0, fromFixed(width), fromFixed(height)); // Got surface-relative coords but need a (virtual) screen position. QPointF relPos = QPointF(fromFixed(x), fromFixed(y)); QPointF delta = relPos - relPos.toPoint(); - tp.area.moveCenter(self->mTargetWindow->mapToGlobal(relPos.toPoint()) + delta); + tp.area.moveCenter(mTargetWindow->mapToGlobal(relPos.toPoint()) + delta); tp.normalPosition.setX(fromFixed(normalized_x)); tp.normalPosition.setY(fromFixed(normalized_y)); @@ -135,11 +129,11 @@ void QWaylandTouchExtension::handle_touch(void *data, wl_touch_extension *ext, u } } - self->mTouchPoints.append(tp); - self->mTimestamp = time; + mTouchPoints.append(tp); + mTimestamp = time; - if (!--self->mPointsLeft) - self->sendTouchEvent(); + if (!--mPointsLeft) + sendTouchEvent(); } void QWaylandTouchExtension::sendTouchEvent() @@ -173,7 +167,7 @@ void QWaylandTouchExtension::sendTouchEvent() for (int i = 0; i < mTouchPoints.count(); ++i) states |= mTouchPoints.at(i).state; - if (mFlags & WL_TOUCH_EXTENSION_FLAGS_MOUSE_FROM_TOUCH) { + if (mFlags & QT_TOUCH_EXTENSION_FLAGS_MOUSE_FROM_TOUCH) { if (states == Qt::TouchPointPressed) mMouseSourceId = mTouchPoints.first().id; for (int i = 0; i < mTouchPoints.count(); ++i) { @@ -207,14 +201,7 @@ void QWaylandTouchExtension::touchCanceled() QWindowSystemInterface::handleMouseEvent(mTargetWindow, mTimestamp, mLastMouseLocal, mLastMouseGlobal, Qt::NoButton); } -void QWaylandTouchExtension::handle_configure(void *data, wl_touch_extension *ext, uint32_t flags) +void QWaylandTouchExtension::touch_extension_configure(uint32_t flags) { - Q_UNUSED(ext); - QWaylandTouchExtension *self = static_cast<QWaylandTouchExtension *>(data); - self->mFlags = flags; + mFlags = flags; } - -const struct wl_touch_extension_listener QWaylandTouchExtension::touch_listener = { - QWaylandTouchExtension::handle_touch, - QWaylandTouchExtension::handle_configure -}; diff --git a/src/plugins/platforms/wayland_common/qwaylandtouch.h b/src/plugins/platforms/wayland_common/qwaylandtouch.h index 9762af22..3762209d 100644 --- a/src/plugins/platforms/wayland_common/qwaylandtouch.h +++ b/src/plugins/platforms/wayland_common/qwaylandtouch.h @@ -45,11 +45,11 @@ #include "qwaylanddisplay.h" #include <qpa/qwindowsysteminterface.h> -class wl_touch_extension; +#include <qwayland-touch-extension.h> QT_BEGIN_NAMESPACE -class QWaylandTouchExtension +class QWaylandTouchExtension : public QtWayland::qt_touch_extension { public: QWaylandTouchExtension(QWaylandDisplay *display, uint32_t id); @@ -60,28 +60,22 @@ private: void registerDevice(int caps); QWaylandDisplay *mDisplay; - wl_touch_extension *mTouch; - static const struct wl_touch_extension_listener touch_listener; - static void handle_touch(void *data, - struct wl_touch_extension *ext, - uint32_t time, - uint32_t id, - uint32_t state, - int32_t x, - int32_t y, - int32_t normalized_x, - int32_t normalized_y, - int32_t width, - int32_t height, - uint32_t pressure, - int32_t velocity_x, - int32_t velocity_y, - uint32_t flags, - struct wl_array *rawdata); - static void handle_configure(void *data, - struct wl_touch_extension *ext, - uint32_t flags); + void touch_extension_touch(uint32_t time, + uint32_t id, + uint32_t state, + int32_t x, + int32_t y, + int32_t normalized_x, + int32_t normalized_y, + int32_t width, + int32_t height, + uint32_t pressure, + int32_t velocity_x, + int32_t velocity_y, + uint32_t flags, + struct wl_array *rawdata) Q_DECL_OVERRIDE; + void touch_extension_configure(uint32_t flags) Q_DECL_OVERRIDE; void sendTouchEvent(); diff --git a/src/plugins/platforms/wayland_common/qwaylandwindow.cpp b/src/plugins/platforms/wayland_common/qwaylandwindow.cpp index b71176d4..66622210 100644 --- a/src/plugins/platforms/wayland_common/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandwindow.cpp @@ -45,7 +45,6 @@ #include "qwaylanddisplay.h" #include "qwaylandinputdevice.h" #include "qwaylandscreen.h" -#include "qwaylandshell.h" #include "qwaylandshellsurface.h" #include "qwaylandextendedsurface.h" #include "qwaylandsubsurface.h" @@ -66,9 +65,9 @@ QT_USE_NAMESPACE QWaylandWindow::QWaylandWindow(QWindow *window) - : QPlatformWindow(window) + : QObject() + , QPlatformWindow(window) , mDisplay(QWaylandScreen::waylandScreenFromWindow(window)->display()) - , mSurface(mDisplay->createSurface(this)) , mShellSurface(0) , mExtendedWindow(0) , mSubSurfaceWindow(0) @@ -78,50 +77,51 @@ QWaylandWindow::QWaylandWindow(QWindow *window) , mBuffer(0) , mWaitingForFrameSync(false) , mFrameCallback(0) + , mResizeExposedSent(false) , mSentInitialResize(false) , mMouseDevice(0) , mMouseSerial(0) , mState(Qt::WindowNoState) { + init(mDisplay->createSurface(static_cast<QtWayland::wl_surface *>(this))); + static WId id = 1; mWindowId = id++; - if (mDisplay->shell()) - mShellSurface = mDisplay->shell()->getShellSurface(this); + if (mDisplay->shell() && !(window->flags() & Qt::BypassWindowManagerHint)) + mShellSurface = new QWaylandShellSurface(mDisplay->shell()->get_shell_surface(wl_surface()), this); if (mDisplay->windowExtension()) - mExtendedWindow = mDisplay->windowExtension()->getExtendedWindow(this); + mExtendedWindow = new QWaylandExtendedSurface(this, mDisplay->windowExtension()->get_extended_surface(wl_surface())); if (mDisplay->subSurfaceExtension()) - mSubSurfaceWindow = mDisplay->subSurfaceExtension()->getSubSurfaceAwareWindow(this); + mSubSurfaceWindow = new QWaylandSubSurface(this, mDisplay->subSurfaceExtension()->get_sub_surface_aware_surface(wl_surface())); -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT - mDisplay->windowManagerIntegration()->mapClientToProcess(qApp->applicationPid()); - mDisplay->windowManagerIntegration()->authenticateWithToken(); -#endif - - // Set surface class to the .desktop file name (obtained from executable name) - QFileInfo exeFileInfo(qApp->applicationFilePath()); - QString className = exeFileInfo.baseName() + QLatin1String(".desktop"); - mShellSurface->setClassName(className.toUtf8().constData()); + if (mShellSurface) { + // Set surface class to the .desktop file name (obtained from executable name) + QFileInfo exeFileInfo(qApp->applicationFilePath()); + QString className = exeFileInfo.baseName() + QLatin1String(".desktop"); + mShellSurface->setClassName(className.toUtf8().constData()); + } - if (parent() && mSubSurfaceWindow) { - mSubSurfaceWindow->setParent(static_cast<const QWaylandWindow *>(parent())); + if (QPlatformWindow::parent() && mSubSurfaceWindow) { + mSubSurfaceWindow->setParent(static_cast<const QWaylandWindow *>(QPlatformWindow::parent())); } else if (window->transientParent()) { - if (window->type() != Qt::Popup) { + if (window->transientParent() && mShellSurface) mShellSurface->updateTransientParent(window->transientParent()); - } - } else { + } else if (mShellSurface) { mShellSurface->setTopLevel(); } setWindowFlags(window->flags()); + setGeometry(window->geometry()); + } QWaylandWindow::~QWaylandWindow() { - if (mSurface) { + if (isInitialized()) { delete mShellSurface; delete mExtendedWindow; - wl_surface_destroy(mSurface); + destroy(); } QList<QWaylandInputDevice *> inputDevices = mDisplay->inputDevices(); @@ -129,6 +129,11 @@ QWaylandWindow::~QWaylandWindow() inputDevices.at(i)->handleWindowDestroyed(this); } +QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface) +{ + return static_cast<QWaylandWindow *>(static_cast<QtWayland::wl_surface *>(wl_surface_get_user_data(surface))); +} + WId QWaylandWindow::winId() const { return mWindowId; @@ -148,9 +153,9 @@ void QWaylandWindow::setWindowTitle(const QString &title) QByteArray titleUtf8 = title.toUtf8(); mShellSurface->setTitle(titleUtf8.constData()); } - if (mWindowDecoration && window()->isVisible()) { - mWindowDecoration->paintDecoration(); - } + + if (mWindowDecoration && window()->isVisible()) + mWindowDecoration->update(); } void QWaylandWindow::setWindowIcon(const QIcon &icon) @@ -158,21 +163,25 @@ void QWaylandWindow::setWindowIcon(const QIcon &icon) mWindowIcon = icon; if (mWindowDecoration && window()->isVisible()) - mWindowDecoration->paintDecoration(); + mWindowDecoration->update(); } void QWaylandWindow::setGeometry(const QRect &rect) { QPlatformWindow::setGeometry(rect); - mDisplay->scheduleRedraw(this); + if (shellSurface() && window()->transientParent()) + shellSurface()->updateTransientParent(window()->transientParent()); + + if (mWindowDecoration && window()->isVisible()) + mWindowDecoration->update(); } void QWaylandWindow::setVisible(bool visible) { if (visible) { if (mBuffer) - wl_surface_attach(mSurface, mBuffer->buffer(), 0, 0); + attach(mBuffer->buffer(), 0, 0); if (window()->type() == Qt::Popup && transientParent()) { QWaylandWindow *parent = transientParent(); @@ -184,7 +193,6 @@ void QWaylandWindow::setVisible(bool visible) if (!mSentInitialResize) { QWindowSystemInterface::handleGeometryChange(window(), geometry()); - QWindowSystemInterface::flushWindowSystemEvents(); mSentInitialResize = true; } @@ -194,7 +202,7 @@ void QWaylandWindow::setVisible(bool visible) // QWaylandShmBackingStore::beginPaint(). } else { QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); - wl_surface_attach(mSurface, 0,0,0); + attach(static_cast<QWaylandBuffer *>(0), 0, 0); } damage(QRect(QPoint(0,0),geometry().size())); } @@ -212,46 +220,57 @@ bool QWaylandWindow::isExposed() const void QWaylandWindow::configure(uint32_t edges, int32_t width, int32_t height) { - Q_UNUSED(edges); + mConfigure.edges |= edges; + mConfigure.width = width; + mConfigure.height = height; - int widthWithoutMargins = qMax(width-(frameMargins().left() +frameMargins().right()),1); - int heightWithoutMargins = qMax(height-(frameMargins().top()+frameMargins().bottom()),1); + if (!mResizeExposedSent) { + mResizeExposedSent = true; + QMetaObject::invokeMethod(this, "doResize", Qt::QueuedConnection); + } +} + +void QWaylandWindow::doResize() +{ + mResizeExposedSent = false; + if (mConfigure.isEmpty()) { + return; + } + + int widthWithoutMargins = qMax(mConfigure.width-(frameMargins().left() +frameMargins().right()),1); + int heightWithoutMargins = qMax(mConfigure.height-(frameMargins().top()+frameMargins().bottom()),1); widthWithoutMargins = qMax(widthWithoutMargins, window()->minimumSize().width()); heightWithoutMargins = qMax(heightWithoutMargins, window()->minimumSize().height()); - QRect geometry = QRect(0,0, - widthWithoutMargins, heightWithoutMargins); + QRect geometry = QRect(0,0, widthWithoutMargins, heightWithoutMargins); int x = 0; int y = 0; QSize size = this->geometry().size(); - if (edges == WL_SHELL_SURFACE_RESIZE_LEFT || edges == WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT || - edges == WL_SHELL_SURFACE_RESIZE_TOP_LEFT) { + if (mConfigure.edges & WL_SHELL_SURFACE_RESIZE_LEFT) { x = size.width() - geometry.width(); } - if (edges == WL_SHELL_SURFACE_RESIZE_TOP || edges == WL_SHELL_SURFACE_RESIZE_TOP_LEFT || - edges == WL_SHELL_SURFACE_RESIZE_TOP_RIGHT) { + if (mConfigure.edges & WL_SHELL_SURFACE_RESIZE_TOP) { y = size.height() - geometry.height(); } mOffset += QPoint(x, y); + mResizeLock.lock(); setGeometry(geometry); + mResizeLock.unlock(); + + mConfigure.clear(); QWindowSystemInterface::handleGeometryChange(window(), geometry); + QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry)); QWindowSystemInterface::flushWindowSystemEvents(); } -void QWaylandWindow::redraw() -{ - -} - void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y) { mBuffer = buffer; - if (window()->isVisible()) { - wl_surface_attach(mSurface, mBuffer->buffer(), x, y); - } + if (window()->isVisible()) + attach(mBuffer->buffer(), x, y); } void QWaylandWindow::attachOffset(QWaylandBuffer *buffer) @@ -270,14 +289,13 @@ void QWaylandWindow::damage(const QRect &rect) //We have to do sync stuff before calling damage, or we might //get a frame callback before we get the timestamp if (!mWaitingForFrameSync) { - mFrameCallback = wl_surface_frame(mSurface); + mFrameCallback = frame(); wl_callback_add_listener(mFrameCallback,&QWaylandWindow::callbackListener,this); mWaitingForFrameSync = true; } - wl_surface_damage(mSurface, - rect.x(), rect.y(), rect.width(), rect.height()); - wl_surface_commit(mSurface); + damage(rect.x(), rect.y(), rect.width(), rect.height()); + commit(); } const wl_callback_listener QWaylandWindow::callbackListener = { @@ -297,8 +315,11 @@ void QWaylandWindow::frameCallback(void *data, struct wl_callback *callback, uin } } +QMutex QWaylandWindow::mFrameSyncMutex; + void QWaylandWindow::waitForFrameSync() { + QMutexLocker locker(&mFrameSyncMutex); if (!mWaitingForFrameSync) return; mDisplay->flushRequests(); @@ -384,14 +405,14 @@ bool QWaylandWindow::createDecoration() default: break; } - if (window()->flags() & Qt::FramelessWindowHint || isFullscreen()) { + if (window()->flags() & Qt::FramelessWindowHint || isFullscreen()) + decoration = false; + if (window()->flags() & Qt::BypassWindowManagerHint) decoration = false; - } if (decoration) { - if (!mWindowDecoration) { - createDecorationInstance(); - } + if (!mWindowDecoration) + mWindowDecoration = new QWaylandDecoration(this); } else { delete mWindowDecoration; mWindowDecoration = 0; @@ -416,8 +437,8 @@ void QWaylandWindow::setDecoration(QWaylandDecoration *decoration) QWaylandWindow *QWaylandWindow::topLevelWindow() { QWaylandWindow *w = this; - while (w->parent()) { - w = static_cast<QWaylandWindow *>(w->parent()); + while (w->QPlatformWindow::parent()) { + w = static_cast<QWaylandWindow *>(w->QPlatformWindow::parent()); } return w; } diff --git a/src/plugins/platforms/wayland_common/qwaylandwindow.h b/src/plugins/platforms/wayland_common/qwaylandwindow.h index 172728c9..3cd891f6 100644 --- a/src/plugins/platforms/wayland_common/qwaylandwindow.h +++ b/src/plugins/platforms/wayland_common/qwaylandwindow.h @@ -43,12 +43,15 @@ #define QWAYLANDWINDOW_H #include <QtCore/QWaitCondition> +#include <QtCore/QMutex> #include <QtGui/QIcon> #include <qpa/qplatformwindow.h> #include "qwaylanddisplay.h" +#include "qwayland-wayland.h" + struct wl_egl_window; QT_BEGIN_NAMESPACE @@ -60,9 +63,30 @@ class QWaylandExtendedSurface; class QWaylandSubSurface; class QWaylandDecoration; -class QWaylandWindow : public QPlatformWindow +class QWaylandWindowConfigure { public: + QWaylandWindowConfigure() + : width(0) + , height(0) + , edges(0) + { } + + void clear() + { width = height = edges = 0; } + + bool isEmpty() const + { return !height || !width; } + + int width; + int height; + uint32_t edges; +}; + +class QWaylandWindow : public QObject, public QPlatformWindow, public QtWayland::wl_surface +{ + Q_OBJECT +public: enum WindowType { Shm, Egl @@ -85,18 +109,24 @@ public: void configure(uint32_t edges, int32_t width, int32_t height); + using QtWayland::wl_surface::attach; void attach(QWaylandBuffer *buffer, int x, int y); void attachOffset(QWaylandBuffer *buffer); QWaylandBuffer *attached() const; QPoint attachOffset() const; + using QtWayland::wl_surface::damage; void damage(const QRect &rect); void waitForFrameSync(); QMargins frameMargins() const; - struct wl_surface *wl_surface() const { return mSurface; } + // TODO: remove? + struct ::wl_surface *wl_surface() { return object(); } + const struct ::wl_surface *wl_surface() const { return object(); } + + static QWaylandWindow *fromWlSurface(::wl_surface *surface); QWaylandShellSurface *shellSurface() const; QWaylandExtendedSurface *extendedWindow() const; @@ -124,19 +154,21 @@ public: bool createDecoration(); - virtual void redraw(); - inline bool isMaximized() const { return mState == Qt::WindowMaximized; } inline bool isFullscreen() const { return mState == Qt::WindowFullScreen; } QWaylandWindow *topLevelWindow(); QWaylandWindow *transientParent() const; + QMutex *resizeMutex() { return &mResizeLock; } + +public slots: + void doResize(); + protected: virtual void createDecorationInstance() {} QWaylandDisplay *mDisplay; - struct wl_surface *mSurface; QWaylandShellSurface *mShellSurface; QWaylandExtendedSurface *mExtendedWindow; QWaylandSubSurface *mSubSurfaceWindow; @@ -151,6 +183,10 @@ protected: struct wl_callback *mFrameCallback; QWaitCondition mFrameSyncWait; + QMutex mResizeLock; + QWaylandWindowConfigure mConfigure; + bool mResizeExposedSent; + bool mSentInitialResize; QPoint mOffset; @@ -171,6 +207,7 @@ private: static const wl_callback_listener callbackListener; static void frameCallback(void *data, struct wl_callback *wl_callback, uint32_t time); + static QMutex mFrameSyncMutex; }; inline QIcon QWaylandWindow::windowIcon() const diff --git a/src/plugins/platforms/wayland_common/wayland_common.pri b/src/plugins/platforms/wayland_common/wayland_common.pri index e3a380ea..cc956a72 100644 --- a/src/plugins/platforms/wayland_common/wayland_common.pri +++ b/src/plugins/platforms/wayland_common/wayland_common.pri @@ -1,28 +1,10 @@ -QT += core-private gui-private platformsupport-private -CONFIG += link_pkgconfig qpa/genericunixfontdatabase +#This file(wayland_common.pri) is included from .pro files of GL integrations. -!equals(QT_WAYLAND_GL_CONFIG, nogl) { - DEFINES += QT_WAYLAND_GL_SUPPORT -} +include ($$PWD/wayland_common_share.pri) -config_xkbcommon { - !contains(QT_CONFIG, no-pkg-config) { - PKGCONFIG += xkbcommon - } else { - LIBS += -lxkbcommon - } -} else { - DEFINES += QT_NO_WAYLAND_XKB -} - -INCLUDEPATH += $$PWD $$PWD/../../../shared - -!contains(QT_CONFIG, no-pkg-config) { - PKGCONFIG += wayland-client wayland-cursor -} else { - LIBS += -lwayland-client -lwayland-cursor -} +INCLUDEPATH += $$PWD staticlib = $$shadowed($$PWD)/$${QMAKE_PREFIX_STATICLIB}wayland_common.$${QMAKE_EXTENSION_STATICLIB} LIBS += $$staticlib PRE_TARGETDEPS += $$staticlib + diff --git a/src/plugins/platforms/wayland_common/wayland_common.pro b/src/plugins/platforms/wayland_common/wayland_common.pro index 5c992b3c..4a1b0e88 100644 --- a/src/plugins/platforms/wayland_common/wayland_common.pro +++ b/src/plugins/platforms/wayland_common/wayland_common.pro @@ -1,22 +1,9 @@ TEMPLATE = lib CONFIG += staticlib -CONFIG += link_pkgconfig qpa/genericunixfontdatabase - -QT += core-private gui-private platformsupport-private - +include ($$PWD/wayland_common_share.pri) include (windowmanager_integration/windowmanager_integration.pri) -!equals(QT_WAYLAND_GL_CONFIG, nogl) { - DEFINES += QT_WAYLAND_GL_SUPPORT -} - -!config_xkbcommon { - DEFINES += QT_NO_WAYLAND_XKB -} - -INCLUDEPATH += ../../../shared - SOURCES += qwaylandintegration.cpp \ qwaylandnativeinterface.cpp \ qwaylandshmbackingstore.cpp \ @@ -31,7 +18,6 @@ SOURCES += qwaylandintegration.cpp \ qwaylanddataoffer.cpp \ qwaylanddatadevicemanager.cpp \ qwaylanddatasource.cpp \ - qwaylandshell.cpp \ qwaylandshellsurface.cpp \ qwaylandextendedoutput.cpp \ qwaylandextendedsurface.cpp \ @@ -40,7 +26,6 @@ SOURCES += qwaylandintegration.cpp \ qwaylandqtkey.cpp \ ../../../shared/qwaylandmimehelper.cpp \ qwaylanddecoration.cpp \ - qwaylandshmdecoration.cpp \ qwaylandeventthread.cpp HEADERS += qwaylandintegration.h \ @@ -58,7 +43,6 @@ HEADERS += qwaylandintegration.h \ qwaylanddataoffer.h \ qwaylanddatadevicemanager.h \ qwaylanddatasource.h \ - qwaylandshell.h \ qwaylandshellsurface.h \ qwaylandextendedoutput.h \ qwaylandextendedsurface.h \ @@ -67,7 +51,6 @@ HEADERS += qwaylandintegration.h \ qwaylandqtkey.h \ ../../../shared/qwaylandmimehelper.h \ qwaylanddecoration.h \ - qwaylandshmdecoration.h \ qwaylandeventthread.h contains(DEFINES, QT_WAYLAND_GL_SUPPORT) { @@ -75,9 +58,13 @@ contains(DEFINES, QT_WAYLAND_GL_SUPPORT) { HEADERS += qwaylandglintegration.h } -WAYLANDSOURCES += \ +WAYLANDCLIENTSOURCES += \ ../../../extensions/surface-extension.xml \ ../../../extensions/sub-surface-extension.xml \ ../../../extensions/output-extension.xml \ ../../../extensions/touch-extension.xml \ - ../../../extensions/qtkey-extension.xml + ../../../extensions/qtkey-extension.xml \ + +PLUGIN_TYPE = platforms + +load(qt_common) diff --git a/src/plugins/platforms/wayland_common/wayland_common_share.pri b/src/plugins/platforms/wayland_common/wayland_common_share.pri new file mode 100644 index 00000000..a9a990b4 --- /dev/null +++ b/src/plugins/platforms/wayland_common/wayland_common_share.pri @@ -0,0 +1,26 @@ +QT += core-private gui-private platformsupport-private +CONFIG += link_pkgconfig qpa/genericunixfontdatabase + +!equals(QT_WAYLAND_GL_CONFIG, nogl) { + DEFINES += QT_WAYLAND_GL_SUPPORT +} + +config_xkbcommon { + !contains(QT_CONFIG, no-pkg-config) { + PKGCONFIG += xkbcommon + } else { + LIBS += -lxkbcommon + } +} else { + DEFINES += QT_NO_WAYLAND_XKB +} + +!contains(QT_CONFIG, no-pkg-config) { + PKGCONFIG += wayland-client wayland-cursor +} else { + LIBS += -lwayland-client -lwayland-cursor +} + +INCLUDEPATH += $$PWD/../../../shared + +WAYLANDCLIENTSOURCES += ../../../3rdparty/protocol/wayland.xml diff --git a/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.cpp b/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.cpp index 68a7fdfa..673400bd 100644 --- a/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.cpp +++ b/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.cpp @@ -40,7 +40,6 @@ ****************************************************************************/ #include "qwaylandwindowmanagerintegration.h" -#include "wayland-windowmanager-client-protocol.h" #include "qwaylandscreen.h" #include "qwaylandwindow.h" @@ -62,7 +61,6 @@ public: QWaylandWindowManagerIntegrationPrivate(QWaylandDisplay *waylandDisplay); bool m_blockPropertyUpdates; QWaylandDisplay *m_waylandDisplay; - struct wl_windowmanager *m_waylandWindowManager; QHash<QWindow*, QVariantMap> m_queuedProperties; bool m_showIsFullScreen; }; @@ -70,23 +68,14 @@ public: QWaylandWindowManagerIntegrationPrivate::QWaylandWindowManagerIntegrationPrivate(QWaylandDisplay *waylandDisplay) : m_blockPropertyUpdates(false) , m_waylandDisplay(waylandDisplay) - , m_waylandWindowManager(0) , m_showIsFullScreen(false) { } -QWaylandWindowManagerIntegration *QWaylandWindowManagerIntegration::m_instance = 0; - -QWaylandWindowManagerIntegration *QWaylandWindowManagerIntegration::createIntegration(QWaylandDisplay *waylandDisplay) -{ - return new QWaylandWindowManagerIntegration(waylandDisplay); -} - QWaylandWindowManagerIntegration::QWaylandWindowManagerIntegration(QWaylandDisplay *waylandDisplay) : d_ptr(new QWaylandWindowManagerIntegrationPrivate(waylandDisplay)) { - m_instance = this; waylandDisplay->addRegistryListener(&wlHandleListenerGlobal, this); } @@ -95,83 +84,41 @@ QWaylandWindowManagerIntegration::~QWaylandWindowManagerIntegration() } -QWaylandWindowManagerIntegration *QWaylandWindowManagerIntegration::instance() -{ - return m_instance; -} - -struct wl_windowmanager *QWaylandWindowManagerIntegration::windowManager() const -{ - Q_D(const QWaylandWindowManagerIntegration); - return d->m_waylandWindowManager; -} - bool QWaylandWindowManagerIntegration::showIsFullScreen() const { Q_D(const QWaylandWindowManagerIntegration); return d->m_showIsFullScreen; } -void QWaylandWindowManagerIntegration::wlHandleListenerGlobal(void *data, wl_registry *registry, uint32_t id, const char *interface, uint32_t version) +void QWaylandWindowManagerIntegration::wlHandleListenerGlobal(void *data, wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); - if (strcmp(interface, "wl_windowmanager") == 0) { - QWaylandWindowManagerIntegration *integration = static_cast<QWaylandWindowManagerIntegration *>(data); - integration->d_ptr->m_waylandWindowManager = - static_cast<struct wl_windowmanager *>(wl_registry_bind(registry, id, &wl_windowmanager_interface, 1)); - wl_windowmanager_add_listener(integration->d_ptr->m_waylandWindowManager, &windowmanager_listener, integration); - } + if (interface == "wl_windowmanager") + static_cast<QWaylandWindowManagerIntegration *>(data)->init(registry, id); } -const struct wl_windowmanager_listener QWaylandWindowManagerIntegration::windowmanager_listener = { - QWaylandWindowManagerIntegration::handle_hints, - QWaylandWindowManagerIntegration::handle_quit -}; - -void QWaylandWindowManagerIntegration::handle_hints(void *data, wl_windowmanager *ext, int32_t showIsFullScreen) +void QWaylandWindowManagerIntegration::windowmanager_hints(int32_t showIsFullScreen) { - Q_UNUSED(ext); - QWaylandWindowManagerIntegration *self = static_cast<QWaylandWindowManagerIntegration *>(data); - self->d_func()->m_showIsFullScreen = showIsFullScreen; + Q_D(QWaylandWindowManagerIntegration); + d->m_showIsFullScreen = showIsFullScreen; } -void QWaylandWindowManagerIntegration::handle_quit(void *data, wl_windowmanager *ext) +void QWaylandWindowManagerIntegration::windowmanager_quit() { - Q_UNUSED(data); - Q_UNUSED(ext); QGuiApplication::quit(); } -void QWaylandWindowManagerIntegration::mapClientToProcess(long long processId) -{ - Q_D(QWaylandWindowManagerIntegration); - if (d->m_waylandWindowManager) - wl_windowmanager_map_client_to_process(d->m_waylandWindowManager, (uint32_t) processId); -} - -void QWaylandWindowManagerIntegration::authenticateWithToken(const QByteArray &token) -{ - Q_D(QWaylandWindowManagerIntegration); - QByteArray authToken = token; - if (authToken.isEmpty()) - authToken = qgetenv("WL_AUTHENTICATION_TOKEN"); - - if (d->m_waylandWindowManager && !authToken.isEmpty()) { - wl_windowmanager_authenticate_with_token(d->m_waylandWindowManager, authToken.constData()); - } -} void QWaylandWindowManagerIntegration::openUrl_helper(const QUrl &url) { - Q_D(QWaylandWindowManagerIntegration); - if (d->m_waylandWindowManager) { + if (isInitialized()) { QByteArray data = url.toString().toUtf8(); static const int chunkSize = 128; while (!data.isEmpty()) { QByteArray chunk = data.left(chunkSize); data = data.mid(chunkSize); - wl_windowmanager_open_url(d->m_waylandWindowManager, !data.isEmpty(), chunk.constData()); + open_url(!data.isEmpty(), QString::fromUtf8(chunk)); } } } diff --git a/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.h b/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.h index 9145401d..0982632d 100644 --- a/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.h +++ b/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.h @@ -49,27 +49,22 @@ #include "qwaylanddisplay.h" #include <qpa/qplatformservices.h> +#include "qwayland-windowmanager.h" + QT_BEGIN_NAMESPACE class QWaylandWindow; class QWaylandWindowManagerIntegrationPrivate; -class QWaylandWindowManagerIntegration : public QObject, public QPlatformServices +class QWaylandWindowManagerIntegration : public QObject, public QPlatformServices, public QtWayland::qt_windowmanager { Q_OBJECT Q_DECLARE_PRIVATE(QWaylandWindowManagerIntegration) public: explicit QWaylandWindowManagerIntegration(QWaylandDisplay *waylandDisplay); virtual ~QWaylandWindowManagerIntegration(); - static QWaylandWindowManagerIntegration *createIntegration(QWaylandDisplay *waylandDisplay); - struct wl_windowmanager *windowManager() const; - - static QWaylandWindowManagerIntegration *instance(); - void mapSurfaceToProcess(struct wl_surface *surface, long long processId); - void mapClientToProcess(long long processId); - void authenticateWithToken(const QByteArray &token = QByteArray()); bool openUrl(const QUrl &url); bool openDocument(const QUrl &url); @@ -77,17 +72,12 @@ public: private: static void wlHandleListenerGlobal(void *data, wl_registry *registry, uint32_t id, - const char *interface, uint32_t version); + const QString &interface, uint32_t version); QScopedPointer<QWaylandWindowManagerIntegrationPrivate> d_ptr; - static QWaylandWindowManagerIntegration *m_instance; - - static const struct wl_windowmanager_listener windowmanager_listener; - static void handle_hints(void *data, - struct wl_windowmanager *ext, - int32_t showIsFullScreen); - static void handle_quit(void *data, struct wl_windowmanager *ext); + void windowmanager_hints(int32_t showIsFullScreen) Q_DECL_OVERRIDE; + void windowmanager_quit() Q_DECL_OVERRIDE; void openUrl_helper(const QUrl &url); }; diff --git a/src/plugins/platforms/wayland_common/windowmanager_integration/windowmanager_integration.pri b/src/plugins/platforms/wayland_common/windowmanager_integration/windowmanager_integration.pri index 57905ad9..9228358e 100644 --- a/src/plugins/platforms/wayland_common/windowmanager_integration/windowmanager_integration.pri +++ b/src/plugins/platforms/wayland_common/windowmanager_integration/windowmanager_integration.pri @@ -2,7 +2,7 @@ DEFINES += QT_WAYLAND_WINDOWMANAGER_SUPPORT contains(DEFINES, QT_WAYLAND_WINDOWMANAGER_SUPPORT) { - WAYLANDSOURCES += $$PWD/../../../../extensions/windowmanager.xml + WAYLANDCLIENTSOURCES += $$PWD/../../../../extensions/windowmanager.xml HEADERS += \ $$PWD/qwaylandwindowmanagerintegration.h diff --git a/src/plugins/platforms/xcomposite_share/qwaylandxcompositebuffer.cpp b/src/plugins/platforms/xcomposite_share/qwaylandxcompositebuffer.cpp index 55fe3fbe..3e18eaef 100644 --- a/src/plugins/platforms/xcomposite_share/qwaylandxcompositebuffer.cpp +++ b/src/plugins/platforms/xcomposite_share/qwaylandxcompositebuffer.cpp @@ -46,10 +46,10 @@ QT_USE_NAMESPACE -QWaylandXCompositeBuffer::QWaylandXCompositeBuffer(wl_xcomposite *xcomposite, uint32_t window, const QSize &size) +QWaylandXCompositeBuffer::QWaylandXCompositeBuffer(qt_xcomposite *xcomposite, uint32_t window, const QSize &size) :mSize(size) { - mBuffer = wl_xcomposite_create_buffer(xcomposite, + mBuffer = qt_xcomposite_create_buffer(xcomposite, window, size.width(), size.height()); diff --git a/src/plugins/platforms/xcomposite_share/qwaylandxcompositebuffer.h b/src/plugins/platforms/xcomposite_share/qwaylandxcompositebuffer.h index d621fa47..e7001241 100644 --- a/src/plugins/platforms/xcomposite_share/qwaylandxcompositebuffer.h +++ b/src/plugins/platforms/xcomposite_share/qwaylandxcompositebuffer.h @@ -45,7 +45,7 @@ #include "qwaylandbuffer.h" #include <stdint.h> -struct wl_xcomposite; +struct qt_xcomposite; struct wl_visual; QT_BEGIN_NAMESPACE @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE class QWaylandXCompositeBuffer : public QWaylandBuffer { public: - QWaylandXCompositeBuffer(struct wl_xcomposite *xcomposite, + QWaylandXCompositeBuffer(qt_xcomposite *xcomposite, uint32_t window, const QSize &size); diff --git a/src/plugins/platforms/xcomposite_share/xcomposite_share.pri b/src/plugins/platforms/xcomposite_share/xcomposite_share.pri index 190fa469..77d56f4c 100644 --- a/src/plugins/platforms/xcomposite_share/xcomposite_share.pri +++ b/src/plugins/platforms/xcomposite_share/xcomposite_share.pri @@ -1,6 +1,6 @@ INCLUDEPATH += $$PWD -WAYLANDSOURCES += $$PWD/../../../extensions/xcomposite.xml +WAYLANDCLIENTSOURCES += $$PWD/../../../extensions/xcomposite.xml HEADERS += \ $$PWD/qwaylandxcompositebuffer.h diff --git a/src/plugins/waylandcompositors/brcm-egl/brcm-egl.pro b/src/plugins/waylandcompositors/brcm-egl/brcm-egl.pro index c397c613..4dcfbaf9 100644 --- a/src/plugins/waylandcompositors/brcm-egl/brcm-egl.pro +++ b/src/plugins/waylandcompositors/brcm-egl/brcm-egl.pro @@ -19,4 +19,4 @@ HEADERS += \ OTHER_FILES += brcm-egl.json -WAYLANDSOURCES += $$PWD/../../../extensions/brcm.xml +WAYLANDSERVERSOURCES += $$PWD/../../../extensions/brcm.xml $$PWD/../../../3rdparty/protocol/wayland.xml diff --git a/src/plugins/waylandcompositors/wayland-egl/wayland-egl.pro b/src/plugins/waylandcompositors/wayland-egl/wayland-egl.pro index cc980be3..73095639 100644 --- a/src/plugins/waylandcompositors/wayland-egl/wayland-egl.pro +++ b/src/plugins/waylandcompositors/wayland-egl/wayland-egl.pro @@ -5,6 +5,8 @@ QT = compositor compositor-private core-private gui-private OTHER_FILES += wayland-egl.json +WAYLANDSERVERSOURCES += $$PWD/../../../3rdparty/protocol/wayland.xml + !contains(QT_CONFIG, no-pkg-config) { CONFIG += link_pkgconfig PKGCONFIG += wayland-egl egl diff --git a/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.cpp b/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.cpp index 0c291bb1..72f2fbc2 100644 --- a/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.cpp +++ b/src/plugins/waylandcompositors/xcomposite-egl/xcompositeeglintegration.cpp @@ -68,11 +68,6 @@ QVector<EGLint> eglbuildSpec() return spec; } - -struct wl_xcomposite_interface XCompositeHandler::xcomposite_interface = { - XCompositeHandler::create_buffer -}; - XCompositeEglIntegration::XCompositeEglIntegration() : QWaylandGraphicsHardwareIntegration() , mDisplay(0) @@ -80,7 +75,7 @@ XCompositeEglIntegration::XCompositeEglIntegration() } -void XCompositeEglIntegration::initializeHardware(QtWayland::Display *waylandDisplay) +void XCompositeEglIntegration::initializeHardware(QtWayland::Display *) { QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); if (nativeInterface) { @@ -94,13 +89,12 @@ void XCompositeEglIntegration::initializeHardware(QtWayland::Display *waylandDis qFatal("Platform integration doesn't have native interface"); } mScreen = XDefaultScreen(mDisplay); - XCompositeHandler *handler = new XCompositeHandler(m_compositor->handle(),mDisplay,m_compositor->window()); - wl_display_add_global(waylandDisplay->handle(),&wl_xcomposite_interface,handler,XCompositeHandler::xcomposite_bind_func); + new XCompositeHandler(m_compositor->handle(), mDisplay); } GLuint XCompositeEglIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpenGLContext *) { - XCompositeBuffer *compositorBuffer = QtWayland::wayland_cast<XCompositeBuffer>(buffer); + XCompositeBuffer *compositorBuffer = static_cast<XCompositeBuffer *>(buffer); Pixmap pixmap = XCompositeNameWindowPixmap(mDisplay, compositorBuffer->window()); QVector<EGLint> eglConfigSpec = eglbuildSpec(); @@ -143,6 +137,6 @@ GLuint XCompositeEglIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpe bool XCompositeEglIntegration::isYInverted(wl_buffer *buffer) const { - XCompositeBuffer *compositorBuffer = QtWayland::wayland_cast<XCompositeBuffer>(buffer); + XCompositeBuffer *compositorBuffer = static_cast<XCompositeBuffer *>(buffer); return compositorBuffer->isYInverted(); } diff --git a/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.cpp b/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.cpp index 1ad8aa97..41d29120 100644 --- a/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.cpp +++ b/src/plugins/waylandcompositors/xcomposite-glx/xcompositeglxintegration.cpp @@ -72,10 +72,6 @@ QVector<int> qglx_buildSpec() } -struct wl_xcomposite_interface XCompositeHandler::xcomposite_interface = { - XCompositeHandler::create_buffer -}; - XCompositeGLXIntegration::XCompositeGLXIntegration() : QWaylandGraphicsHardwareIntegration() , mDisplay(0) @@ -88,7 +84,7 @@ XCompositeGLXIntegration::~XCompositeGLXIntegration() delete mHandler; } -void XCompositeGLXIntegration::initializeHardware(QtWayland::Display *waylandDisplay) +void XCompositeGLXIntegration::initializeHardware(QtWayland::Display *) { QPlatformNativeInterface *nativeInterface = QGuiApplicationPrivate::platformIntegration()->nativeInterface(); if (nativeInterface) { @@ -100,8 +96,7 @@ void XCompositeGLXIntegration::initializeHardware(QtWayland::Display *waylandDis } mScreen = XDefaultScreen(mDisplay); - mHandler = new XCompositeHandler(m_compositor->handle(),mDisplay,m_compositor->window()); - wl_display_add_global(waylandDisplay->handle(),&wl_xcomposite_interface,mHandler,XCompositeHandler::xcomposite_bind_func); + mHandler = new XCompositeHandler(m_compositor->handle(), mDisplay); QOpenGLContext *glContext = new QOpenGLContext(); glContext->create(); @@ -118,9 +113,9 @@ void XCompositeGLXIntegration::initializeHardware(QtWayland::Display *waylandDis delete glContext; } -GLuint XCompositeGLXIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpenGLContext *) +GLuint XCompositeGLXIntegration::createTextureFromBuffer(struct ::wl_buffer *buffer, QOpenGLContext *) { - XCompositeBuffer *compositorBuffer = QtWayland::wayland_cast<XCompositeBuffer>(buffer); + XCompositeBuffer *compositorBuffer = static_cast<XCompositeBuffer *>(buffer); Pixmap pixmap = XCompositeNameWindowPixmap(mDisplay, compositorBuffer->window()); QVector<int> glxConfigSpec = qglx_buildSpec(); @@ -153,6 +148,5 @@ GLuint XCompositeGLXIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpe bool XCompositeGLXIntegration::isYInverted(wl_buffer *buffer) const { - XCompositeBuffer *compositorBuffer = QtWayland::wayland_cast<XCompositeBuffer>(buffer); - return compositorBuffer->isYInverted(); + return static_cast<XCompositeBuffer *>(buffer)->isYInverted(); } diff --git a/src/plugins/waylandcompositors/xcomposite_share/xcomposite_share.pri b/src/plugins/waylandcompositors/xcomposite_share/xcomposite_share.pri index 631ddaf2..7e0bc457 100644 --- a/src/plugins/waylandcompositors/xcomposite_share/xcomposite_share.pri +++ b/src/plugins/waylandcompositors/xcomposite_share/xcomposite_share.pri @@ -1,6 +1,6 @@ INCLUDEPATH += $$PWD -WAYLANDSOURCES += $$PWD/../../../extensions/xcomposite.xml +WAYLANDSERVERSOURCES += $$PWD/../../../extensions/xcomposite.xml $$PWD/../../../3rdparty/protocol/wayland.xml HEADERS += \ $$PWD/xcompositebuffer.h \ diff --git a/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.cpp b/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.cpp index 4644cf29..d7196b79 100644 --- a/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.cpp +++ b/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.cpp @@ -42,13 +42,21 @@ QT_USE_NAMESPACE -XCompositeBuffer::XCompositeBuffer(QtWayland::Compositor *compositor, Window window, const QSize &size) +XCompositeBuffer::XCompositeBuffer(Window window, const QSize &size, + struct ::wl_client *client, uint32_t id) : mWindow(window) , mInvertedY(false) { - Q_UNUSED(compositor); base()->height = size.height(); base()->width = size.width(); + + base()->resource.object.id = id; + base()->resource.object.interface = &::wl_buffer_interface; + base()->resource.object.implementation = (void (**)(void))&buffer_interface; + base()->resource.data = base(); + wl_client_add_resource(client, &base()->resource); + + base()->resource.destroy = delete_resource; } struct wl_buffer_interface XCompositeBuffer::buffer_interface = { @@ -63,7 +71,7 @@ void XCompositeBuffer::buffer_interface_destroy(wl_client *client, wl_resource * void XCompositeBuffer::delete_resource(struct wl_resource *resource) { - delete reinterpret_cast<XCompositeBuffer *>(resource); + delete static_cast<XCompositeBuffer *>(static_cast<wl_buffer *>(resource->data)); } Window XCompositeBuffer::window() diff --git a/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.h b/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.h index bbcfe2bd..2a42aeb1 100644 --- a/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.h +++ b/src/plugins/waylandcompositors/xcomposite_share/xcompositebuffer.h @@ -58,7 +58,8 @@ QT_BEGIN_NAMESPACE class XCompositeBuffer : public QtWayland::Object<struct wl_buffer> { public: - XCompositeBuffer(QtWayland::Compositor *compositor, Window window, const QSize &size); + XCompositeBuffer(Window window, const QSize &size, + struct ::wl_client *client, uint32_t id); Window window(); @@ -67,12 +68,13 @@ public: bool isYInverted() const { return mInvertedY; } void setInvertedY(bool inverted) { mInvertedY = inverted; } + private: Window mWindow; bool mInvertedY; static void buffer_interface_destroy(struct wl_client *client, - struct wl_resource *buffer); + struct wl_resource *buffer); }; QT_END_NAMESPACE diff --git a/src/plugins/waylandcompositors/xcomposite_share/xcompositehandler.cpp b/src/plugins/waylandcompositors/xcomposite_share/xcompositehandler.cpp index 73196315..10a76075 100644 --- a/src/plugins/waylandcompositors/xcomposite_share/xcompositehandler.cpp +++ b/src/plugins/waylandcompositors/xcomposite_share/xcompositehandler.cpp @@ -47,51 +47,30 @@ QT_USE_NAMESPACE -XCompositeHandler::XCompositeHandler(QtWayland::Compositor *compositor, Display *display, QWindow *window) - : mCompositor(compositor) - , mwindow(window) - , mDisplay(display) +XCompositeHandler::XCompositeHandler(QtWayland::Compositor *compositor, Display *display) + : QtWaylandServer::qt_xcomposite(compositor->wl_display()) { - mCompositor->window()->create(); + compositor->window()->create(); - mFakeRootWindow = new QWindow(mCompositor->window()); + mFakeRootWindow = new QWindow(compositor->window()); mFakeRootWindow->setGeometry(QRect(-1,-1,1,1)); mFakeRootWindow->create(); mFakeRootWindow->show(); - int composite_event_base, composite_error_base; - if (XCompositeQueryExtension(mDisplay, &composite_event_base, &composite_error_base)) { - } else { + int composite_event_base, composite_error_base; + if (!XCompositeQueryExtension(display, &composite_event_base, &composite_error_base)) qFatal("XComposite required"); - } -} -void XCompositeHandler::createBuffer(struct wl_client *client, uint32_t id, Window window, const QSize &size) -{ - XCompositeBuffer *buffer = new XCompositeBuffer(mCompositor, window, size); - buffer->addClientResource(client, &buffer->base()->resource, - id,&wl_buffer_interface, - &XCompositeBuffer::buffer_interface, - XCompositeBuffer::delete_resource); + mDisplayString = QString::fromLocal8Bit(XDisplayString(display)); } -void XCompositeHandler::xcomposite_bind_func(struct wl_client *client, void *data, uint32_t version, uint32_t id) +void XCompositeHandler::xcomposite_bind_resource(Resource *resource) { - Q_UNUSED(version); - XCompositeHandler *handler = static_cast<XCompositeHandler *>(data); - wl_resource *resource = wl_client_add_object(client,&wl_xcomposite_interface,&xcomposite_interface,id,handler); - const char *displayString = XDisplayString(handler->mDisplay); - wl_resource_post_event(resource, WL_XCOMPOSITE_ROOT, displayString, handler->mFakeRootWindow->winId()); + send_root(resource->handle, mDisplayString, mFakeRootWindow->winId()); } -void XCompositeHandler::create_buffer(struct wl_client *client, - struct wl_resource *xcomposite, - uint32_t id, - uint32_t x_window, - int32_t width, - int32_t height) +void XCompositeHandler::xcomposite_create_buffer(Resource *resource, uint32_t id, uint32_t window, + int32_t width, int32_t height) { - Window window = (Window)x_window; - XCompositeHandler *that = reinterpret_cast<XCompositeHandler *>(xcomposite); - that->createBuffer(client, id, window, QSize(width,height)); + new XCompositeBuffer(Window(window), QSize(width, height), resource->client(), id); } diff --git a/src/plugins/waylandcompositors/xcomposite_share/xcompositehandler.h b/src/plugins/waylandcompositors/xcomposite_share/xcompositehandler.h index e85f3565..678ad446 100644 --- a/src/plugins/waylandcompositors/xcomposite_share/xcompositehandler.h +++ b/src/plugins/waylandcompositors/xcomposite_share/xcompositehandler.h @@ -42,33 +42,27 @@ #define XCOMPOSITEHANDLER_H #include <QtCompositor/private/qwlcompositor_p.h> -#include <QtCompositor/qwaylandobject.h> #include "xlibinclude.h" +#include "qwayland-server-xcomposite.h" +#include <wayland-server.h> + QT_BEGIN_NAMESPACE -class XCompositeHandler : public QtWayland::Object<struct wl_object> +class XCompositeHandler : public QtWaylandServer::qt_xcomposite { public: - XCompositeHandler(QtWayland::Compositor *compositor, Display *display, QWindow *window); - void createBuffer(struct wl_client *client, uint32_t id, Window window, const QSize &size); - - static void xcomposite_bind_func(struct wl_client *client, void *data, uint32_t version, uint32_t id); - static struct wl_xcomposite_interface xcomposite_interface; + XCompositeHandler(QtWayland::Compositor *compositor, Display *display); private: - QtWayland::Compositor *mCompositor; - QWindow *mwindow; QWindow *mFakeRootWindow; - Display *mDisplay; - static void create_buffer(struct wl_client *client, - struct wl_resource *xcomposite, - uint32_t id, - uint32_t x_window, - int32_t width, - int32_t height); + QString mDisplayString; + + void xcomposite_bind_resource(Resource *resource) Q_DECL_OVERRIDE; + void xcomposite_create_buffer(Resource *resource, uint32_t id, uint32_t x_window, + int32_t width, int32_t height) Q_DECL_OVERRIDE; }; diff --git a/src/qtwaylandscanner/qtwaylandscanner.cpp b/src/qtwaylandscanner/qtwaylandscanner.cpp new file mode 100644 index 00000000..6f1516f4 --- /dev/null +++ b/src/qtwaylandscanner/qtwaylandscanner.cpp @@ -0,0 +1,1065 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QCoreApplication> +#include <QFile> +#include <QXmlStreamReader> + +enum Option { + ClientHeader, + ServerHeader, + ClientCode, + ServerCode +} option; + +bool isServerSide() +{ + return option == ServerHeader || option == ServerCode; +} + +QByteArray protocolName; + +bool parseOption(const char *str, Option *option) +{ + if (str == QLatin1String("client-header")) + *option = ClientHeader; + else if (str == QLatin1String("server-header")) + *option = ServerHeader; + else if (str == QLatin1String("client-code")) + *option = ClientCode; + else if (str == QLatin1String("server-code")) + *option = ServerCode; + else + return false; + + return true; +} + +struct WaylandEnumEntry { + QByteArray name; + int value; + QByteArray summary; +}; + +struct WaylandEnum { + QByteArray name; + + QList<WaylandEnumEntry> entries; +}; + +struct WaylandArgument { + QByteArray name; + QByteArray type; + QByteArray interface; + QByteArray summary; + bool allowNull; +}; + +struct WaylandEvent { + bool request; + QByteArray name; + QList<WaylandArgument> arguments; +}; + +struct WaylandInterface { + QByteArray name; + int version; + + QList<WaylandEnum> enums; + QList<WaylandEvent> events; + QList<WaylandEvent> requests; +}; + +QByteArray byteArrayValue(const QXmlStreamReader &xml, const char *name) +{ + if (xml.attributes().hasAttribute(name)) + return xml.attributes().value(name).toUtf8(); + return QByteArray(); +} + +int intValue(const QXmlStreamReader &xml, const char *name, int defaultValue = 0) +{ + bool ok; + int result = byteArrayValue(xml, name).toInt(&ok); + return ok ? result : defaultValue; +} + +bool boolValue(const QXmlStreamReader &xml, const char *name) +{ + return byteArrayValue(xml, name) == "true"; +} + +WaylandEvent readEvent(QXmlStreamReader &xml, bool request) +{ + WaylandEvent event; + event.request = request; + event.name = byteArrayValue(xml, "name"); + while (xml.readNextStartElement()) { + if (xml.name() == "arg") { + WaylandArgument argument; + argument.name = byteArrayValue(xml, "name"); + argument.type = byteArrayValue(xml, "type"); + argument.interface = byteArrayValue(xml, "interface"); + argument.summary = byteArrayValue(xml, "summary"); + argument.allowNull = boolValue(xml, "allowNull"); + event.arguments << argument; + } + + xml.skipCurrentElement(); + } + return event; +} + +WaylandEnum readEnum(QXmlStreamReader &xml) +{ + WaylandEnum result; + result.name = byteArrayValue(xml, "name"); + + while (xml.readNextStartElement()) { + if (xml.name() == "entry") { + WaylandEnumEntry entry; + entry.name = byteArrayValue(xml, "name"); + entry.value = intValue(xml, "value"); + entry.summary = byteArrayValue(xml, "summary"); + result.entries << entry; + } + + xml.skipCurrentElement(); + } + + return result; +} + +WaylandInterface readInterface(QXmlStreamReader &xml) +{ + WaylandInterface interface; + interface.name = byteArrayValue(xml, "name"); + interface.version = intValue(xml, "name", 1); + + while (xml.readNextStartElement()) { + if (xml.name() == "event") + interface.events << readEvent(xml, false); + else if (xml.name() == "request") + interface.requests << readEvent(xml, true); + else if (xml.name() == "enum") + interface.enums << readEnum(xml); + else + xml.skipCurrentElement(); + } + + return interface; +} + +QByteArray waylandToCType(const QByteArray &waylandType, const QByteArray &interface) +{ + if (waylandType == "string") + return "const char *"; + else if (waylandType == "int") + return "int32_t"; + else if (waylandType == "uint") + return "uint32_t"; + else if (waylandType == "fixed") + return "wl_fixed_t"; + else if (waylandType == "fd") + return "int32_t"; + else if (waylandType == "array") + return "wl_array *"; + else if (waylandType == "object" || waylandType == "new_id") + return isServerSide() ? "struct ::wl_resource *" : interface.isEmpty() ? "struct ::wl_object *" : "struct ::" + interface + " *"; + return waylandType; +} + +QByteArray waylandToQtType(const QByteArray &waylandType, const QByteArray &interface, bool cStyleArray) +{ + if (waylandType == "string") + return "const QString &"; + else if (waylandType == "array") + return cStyleArray ? "wl_array *" : "const QByteArray &"; + else + return waylandToCType(waylandType, interface); +} + +const WaylandArgument *newIdArgument(const QList<WaylandArgument> &arguments) +{ + for (int i = 0; i < arguments.size(); ++i) { + if (arguments.at(i).type == "new_id") + return &arguments.at(i); + } + return 0; +} + +void printEvent(const WaylandEvent &e, const char *interfaceName, bool omitNames = false, bool withResource = false) +{ + printf("%s(", e.name.constData()); + bool needsComma = false; + if (isServerSide()) { + if (e.request) { + printf("Resource *%s", omitNames ? "" : "resource"); + needsComma = true; + } else if (withResource) { + printf("struct ::wl_resource *%s", omitNames ? "" : "resource"); + needsComma = true; + } + } + for (int i = 0; i < e.arguments.size(); ++i) { + const WaylandArgument &a = e.arguments.at(i); + bool isNewId = a.type == "new_id"; + if (isNewId && !isServerSide() && (a.interface.isEmpty() != e.request)) + continue; + if (needsComma) + printf(", "); + needsComma = true; + if (isNewId) { + if (isServerSide()) { + if (e.request) { + printf("uint32_t"); + if (!omitNames) + printf(" %s", a.name.constData()); + continue; + } + } else { + if (e.request) { + printf("const struct ::wl_interface *%s, uint32_t%s", omitNames ? "" : "interface", omitNames ? "" : " version"); + continue; + } + + printf("struct ::%s *%s, ", interfaceName, omitNames ? "" : "object"); + } + } + + QByteArray qtType = waylandToQtType(a.type, a.interface, e.request == isServerSide()); + printf("%s%s%s", qtType.constData(), qtType.endsWith("&") || qtType.endsWith("*") ? "" : " ", omitNames ? "" : a.name.constData()); + } + printf(")"); +} + +void printEventHandlerSignature(const WaylandEvent &e, const char *interfaceName, bool deepIndent = true) +{ + const char *indent = deepIndent ? " " : ""; + printf("handle_%s(\n", e.name.constData()); + if (isServerSide()) { + printf(" %s::wl_client *client,\n", indent); + printf(" %sstruct wl_resource *resource", indent); + } else { + printf(" %svoid *data,\n", indent); + printf(" %sstruct ::%s *object", indent, interfaceName); + } + for (int i = 0; i < e.arguments.size(); ++i) { + printf(",\n"); + const WaylandArgument &a = e.arguments.at(i); + bool isNewId = a.type == "new_id"; + if (isServerSide() && isNewId) { + printf(" %suint32_t %s", indent, a.name.constData()); + } else { + QByteArray cType = waylandToCType(a.type, a.interface); + printf(" %s%s%s%s", indent, cType.constData(), cType.endsWith("*") ? "" : " ", a.name.constData()); + } + } + printf(")"); +} + +void printEnums(const QList<WaylandEnum> &enums) +{ + for (int i = 0; i < enums.size(); ++i) { + printf("\n"); + const WaylandEnum &e = enums.at(i); + printf(" enum %s {\n", e.name.constData()); + for (int i = 0; i < e.entries.size(); ++i) { + const WaylandEnumEntry &entry = e.entries.at(i); + printf(" %s_%s = %d", e.name.constData(), entry.name.constData(), entry.value); + if (i < e.entries.size() - 1) + printf(","); + if (!entry.summary.isNull()) + printf(" // %s", entry.summary.constData()); + printf("\n"); + } + printf(" };\n"); + } +} + +QByteArray stripInterfaceName(const QByteArray &name) +{ + if (name.startsWith("qt_") || name.startsWith("wl_")) + return name.mid(3); + + return name; +} + +bool ignoreInterface(const QByteArray &name) +{ + return name == "wl_display" + || (isServerSide() && name == "wl_registry"); +} + +void process(QXmlStreamReader &xml) +{ + if (!xml.readNextStartElement()) + return; + + if (xml.name() != "protocol") { + xml.raiseError(QStringLiteral("The file is not a wayland protocol file.")); + return; + } + + protocolName = byteArrayValue(xml, "name"); + + if (protocolName.isEmpty()) { + xml.raiseError(QStringLiteral("Missing protocol name.")); + return; + } + + QList<WaylandInterface> interfaces; + + while (xml.readNextStartElement()) { + if (xml.name() == "interface") + interfaces << readInterface(xml); + else + xml.skipCurrentElement(); + } + + if (xml.hasError()) + return; + + if (option == ServerHeader) { + QByteArray inclusionGuard = "QT_WAYLAND_SERVER_" + protocolName.toUpper(); + printf("#ifndef %s\n", inclusionGuard.constData()); + printf("#define %s\n", inclusionGuard.constData()); + printf("\n"); + printf("#include \"wayland-server.h\"\n"); + printf("#include \"wayland-server-protocol.h\"\n"); + printf("#include \"wayland-%s-server-protocol.h\"\n", QByteArray(protocolName).replace('_', '-').constData()); + printf("#include <QByteArray>\n"); + printf("#include <QString>\n"); + printf("\n"); + printf("QT_BEGIN_NAMESPACE\n"); + printf("\n"); + printf("namespace QtWaylandServer {\n"); + + for (int j = 0; j < interfaces.size(); ++j) { + const WaylandInterface &interface = interfaces.at(j); + + if (ignoreInterface(interface.name)) + continue; + + const char *interfaceName = interface.name.constData(); + + QByteArray stripped = stripInterfaceName(interface.name); + const char *interfaceNameStripped = stripped.constData(); + + printf(" class %s\n {\n", interfaceName); + printf(" public:\n"); + printf(" %s(struct ::wl_client *client, struct ::wl_resource *resource, int id);\n", interfaceName); + printf(" %s(struct ::wl_client *client, int id);\n", interfaceName); + printf(" %s(struct ::wl_display *display);\n", interfaceName); + printf(" %s();\n", interfaceName); + printf("\n"); + printf(" virtual ~%s();\n", interfaceName); + printf("\n"); + printf(" class Resource\n"); + printf(" {\n"); + printf(" public:\n"); + printf(" Resource() : %s(0), handle(0) {}\n", interfaceNameStripped); + printf(" virtual ~Resource() {}\n"); + printf("\n"); + printf(" %s *%s;\n", interfaceName, interfaceNameStripped); + printf(" struct ::wl_resource *handle;\n"); + printf("\n"); + printf(" struct ::wl_client *client() const { return handle->client; }\n"); + printf("\n"); + printf(" static Resource *fromResource(struct ::wl_resource *resource) { return static_cast<Resource *>(resource->data); }\n"); + printf(" };\n"); + printf("\n"); + printf(" void init(struct ::wl_client *client, struct ::wl_resource *resource, int id);\n"); + printf(" void init(struct ::wl_client *client, int id);\n"); + printf(" void init(struct ::wl_display *display);\n"); + printf("\n"); + printf(" Resource *add(struct ::wl_client *client, int id);\n"); + printf(" Resource *add(struct wl_list *resource_list, struct ::wl_client *client, int id);\n"); + printf("\n"); + printf(" Resource *resource() { return m_resource; }\n"); + printf(" const Resource *resource() const { return m_resource; }\n"); + printf("\n"); + printf(" struct ::wl_list *resourceList() { return &m_resource_list; }\n"); + printf(" const struct ::wl_list *resourceList() const { return &m_resource_list; }\n"); + printf("\n"); + printf(" bool isGlobal() const { return m_global != 0; }\n"); + printf(" bool isResource() const { return m_resource != 0; }\n"); + + printEnums(interface.enums); + + bool hasEvents = !interface.events.isEmpty(); + + if (hasEvents) { + printf("\n"); + foreach (const WaylandEvent &e, interface.events) { + printf(" void send_"); + printEvent(e, interfaceName); + printf(";\n"); + printf(" void send_"); + printEvent(e, interfaceName, false, true); + printf(";\n"); + } + } + + printf("\n"); + printf(" protected:\n"); + printf(" virtual Resource *%s_allocate();\n", interfaceNameStripped); + printf("\n"); + printf(" virtual void %s_bind_resource(Resource *resource);\n", interfaceNameStripped); + printf(" virtual void %s_destroy_resource(Resource *resource);\n", interfaceNameStripped); + + bool hasRequests = !interface.requests.isEmpty(); + + if (hasRequests) { + printf("\n"); + foreach (const WaylandEvent &e, interface.requests) { + printf(" virtual void %s_", interfaceNameStripped); + printEvent(e, interfaceName); + printf(";\n"); + } + } + + printf("\n"); + printf(" private:\n"); + printf(" static void bind_func(struct ::wl_client *client, void *data, uint32_t version, uint32_t id);\n"); + printf(" static void destroy_func(struct ::wl_resource *client_resource);\n"); + printf("\n"); + printf(" Resource *bind(struct ::wl_client *client, struct ::wl_resource *resource, uint32_t id);\n"); + + if (hasRequests) { + printf("\n"); + printf(" static const struct ::%s_interface m_%s_interface;\n", interfaceName, interfaceName); + + printf("\n"); + for (int i = 0; i < interface.requests.size(); ++i) { + const WaylandEvent &e = interface.requests.at(i); + printf(" static void "); + + printEventHandlerSignature(e, interfaceName); + printf(";\n"); + } + } + + printf("\n"); + printf(" Resource *m_resource;\n"); + printf(" bool m_ownResource;\n"); + printf(" struct ::wl_list m_resource_list;\n"); + printf(" struct ::wl_global *m_global;\n"); + printf(" };\n"); + + if (j < interfaces.size() - 1) + printf("\n"); + } + + printf("}\n"); + printf("\n"); + printf("QT_END_NAMESPACE\n"); + printf("\n"); + printf("#endif\n"); + } + + if (option == ServerCode) { + printf("#include \"qwayland-server-%s.h\"\n", QByteArray(protocolName).replace('_', '-').constData()); + printf("\n"); + printf("QT_BEGIN_NAMESPACE\n"); + printf("\n"); + printf("namespace QtWaylandServer {\n"); + + bool needsNewLine = false; + for (int j = 0; j < interfaces.size(); ++j) { + const WaylandInterface &interface = interfaces.at(j); + + if (ignoreInterface(interface.name)) + continue; + + if (needsNewLine) + printf("\n"); + + needsNewLine = true; + + const char *interfaceName = interface.name.constData(); + + QByteArray stripped = stripInterfaceName(interface.name); + const char *interfaceNameStripped = stripped.constData(); + + printf(" %s::%s(struct ::wl_client *client, struct ::wl_resource *resource, int id)\n", interfaceName, interfaceName); + printf(" : m_resource(0)\n"); + printf(" , m_ownResource(false)\n"); + printf(" , m_global(0)\n"); + printf(" {\n"); + printf(" wl_list_init(&m_resource_list);\n"); + printf(" init(client, resource, id);\n"); + printf(" }\n"); + printf("\n"); + + printf(" %s::%s(struct ::wl_client *client, int id)\n", interfaceName, interfaceName); + printf(" : m_resource(0)\n"); + printf(" , m_ownResource(true)\n"); + printf(" , m_global(0)\n"); + printf(" {\n"); + printf(" wl_list_init(&m_resource_list);\n"); + printf(" init(client, id);\n"); + printf(" }\n"); + printf("\n"); + + printf(" %s::%s(struct ::wl_display *display)\n", interfaceName, interfaceName); + printf(" : m_resource(0)\n"); + printf(" , m_ownResource(true)\n"); + printf(" , m_global(0)\n"); + printf(" {\n"); + printf(" wl_list_init(&m_resource_list);\n"); + printf(" init(display);\n"); + printf(" }\n"); + printf("\n"); + + printf(" %s::%s()\n", interfaceName, interfaceName); + printf(" : m_resource(0)\n"); + printf(" , m_global(0)\n"); + printf(" {\n"); + printf(" wl_list_init(&m_resource_list);\n"); + printf(" }\n"); + printf("\n"); + + printf(" %s::~%s()\n", interfaceName, interfaceName); + printf(" {\n"); + printf(" }\n"); + printf("\n"); + + printf(" void %s::init(struct ::wl_client *client, struct ::wl_resource *resource, int id)\n", interfaceName); + printf(" {\n"); + printf(" m_resource = bind(client, resource, id);\n"); + printf(" }\n"); + printf("\n"); + + printf(" void %s::init(struct ::wl_client *client, int id)\n", interfaceName); + printf(" {\n"); + printf(" m_resource = bind(client, 0, id);\n"); + printf(" }\n"); + printf("\n"); + + printf(" %s::Resource *%s::add(struct ::wl_client *client, int id)\n", interfaceName, interfaceName); + printf(" {\n"); + printf(" return add(&m_resource_list, client, id);\n"); + printf(" }\n"); + printf("\n"); + + printf(" %s::Resource *%s::add(struct wl_list *resource_list, struct ::wl_client *client, int id)\n", interfaceName, interfaceName); + printf(" {\n"); + printf(" Resource *resource = bind(client, 0, id);\n"); + printf(" wl_list_insert(resource_list, &resource->handle->link);\n"); + printf(" return resource;\n"); + printf(" }\n"); + printf("\n"); + + printf(" void %s::init(struct ::wl_display *display)\n", interfaceName); + printf(" {\n"); + printf(" m_global = wl_display_add_global(display, &::%s_interface, this, bind_func);\n", interfaceName); + printf(" }\n"); + printf("\n"); + + printf(" %s::Resource *%s::%s_allocate()\n", interfaceName, interfaceName, interfaceNameStripped); + printf(" {\n"); + printf(" return new Resource;\n"); + printf(" }\n"); + printf("\n"); + + printf(" void %s::%s_bind_resource(Resource *)\n", interfaceName, interfaceNameStripped); + printf(" {\n"); + printf(" }\n"); + printf("\n"); + + printf(" void %s::%s_destroy_resource(Resource *)\n", interfaceName, interfaceNameStripped); + printf(" {\n"); + printf(" }\n"); + printf("\n"); + + printf(" void %s::bind_func(struct ::wl_client *client, void *data, uint32_t version, uint32_t id)\n", interfaceName); + printf(" {\n"); + printf(" Q_UNUSED(version);\n"); + printf(" static_cast<%s *>(data)->bind(client, 0, id);\n", interfaceName); + printf(" }\n"); + printf("\n"); + + printf(" void %s::destroy_func(struct ::wl_resource *client_resource)\n", interfaceName); + printf(" {\n"); + printf(" Resource *resource = Resource::fromResource(client_resource);\n"); + printf(" %s *that = resource->%s;\n", interfaceName, interfaceNameStripped); + printf(" bool ownResource = that->m_ownResource;\n"); + printf(" that->%s_destroy_resource(resource);\n", interfaceNameStripped); + printf(" if (client_resource->link.next)\n"); + printf(" wl_list_remove(&client_resource->link);\n"); + printf(" delete resource;\n"); + printf(" if (ownResource)\n"); + printf(" free(client_resource);\n"); + printf(" }\n"); + printf("\n"); + + bool hasRequests = !interface.requests.isEmpty(); + + QByteArray interfaceMember = hasRequests ? "&m_" + interface.name + "_interface" : QByteArray("0"); + + printf(" %s::Resource *%s::bind(struct ::wl_client *client, struct ::wl_resource *handle, uint32_t id)\n", interfaceName, interfaceName); + printf(" {\n"); + printf(" Resource *resource = %s_allocate();\n", interfaceNameStripped); + printf(" resource->%s = this;\n", interfaceNameStripped); + printf("\n"); + printf(" if (handle) {\n"); + printf(" handle->object.id = id;\n"); + printf(" handle->object.interface = &::%s_interface;\n", interfaceName); + printf(" handle->object.implementation = (void (**)(void))%s;\n", interfaceMember.constData()); + printf(" handle->data = resource;\n"); + printf(" wl_client_add_resource(client, handle);\n"); + printf(" } else {\n"); + printf(" handle = wl_client_add_object(client, &::%s_interface, %s, id, resource);\n", interfaceName, interfaceMember.constData()); + printf(" }\n"); + printf("\n"); + printf(" handle->destroy = destroy_func;\n"); + printf(" resource->handle = handle;\n"); + printf(" %s_bind_resource(resource);\n", interfaceNameStripped); + printf(" wl_list_init(&resource->handle->link);\n"); + printf(" return resource;\n"); + printf(" }\n"); + + if (hasRequests) { + printf("\n"); + printf(" const struct ::%s_interface %s::m_%s_interface = {", interfaceName, interfaceName, interfaceName); + for (int i = 0; i < interface.requests.size(); ++i) { + if (i > 0) + printf(","); + printf("\n"); + const WaylandEvent &e = interface.requests.at(i); + printf(" %s::handle_%s", interfaceName, e.name.constData()); + } + printf("\n"); + printf(" };\n"); + + foreach (const WaylandEvent &e, interface.requests) { + printf("\n"); + printf(" void %s::%s_", interfaceName, interfaceNameStripped); + printEvent(e, interfaceName, true); + printf("\n"); + printf(" {\n"); + printf(" }\n"); + } + printf("\n"); + + for (int i = 0; i < interface.requests.size(); ++i) { + printf("\n"); + printf(" void %s::", interfaceName); + + const WaylandEvent &e = interface.requests.at(i); + printEventHandlerSignature(e, interfaceName, false); + + printf("\n"); + printf(" {\n"); + printf(" Q_UNUSED(client);\n"); + printf(" Resource *r = Resource::fromResource(resource);\n"); + printf(" static_cast<%s *>(r->%s)->%s_%s(\n", interfaceName, interfaceNameStripped, interfaceNameStripped, e.name.constData()); + printf(" r"); + for (int i = 0; i < e.arguments.size(); ++i) { + printf(",\n"); + const WaylandArgument &a = e.arguments.at(i); + QByteArray cType = waylandToCType(a.type, a.interface); + QByteArray qtType = waylandToQtType(a.type, a.interface, e.request); + const char *argumentName = a.name.constData(); + if (cType == qtType) + printf(" %s", argumentName); + else if (a.type == "string") + printf(" QString::fromUtf8(%s)", argumentName); + } + printf(");\n"); + printf(" }\n"); + } + } + + for (int i = 0; i < interface.events.size(); ++i) { + printf("\n"); + const WaylandEvent &e = interface.events.at(i); + printf(" void %s::send_", interfaceName); + printEvent(e, interfaceName); + printf("\n"); + printf(" {\n"); + printf(" send_%s(\n", e.name.constData()); + printf(" m_resource->handle"); + for (int i = 0; i < e.arguments.size(); ++i) { + const WaylandArgument &a = e.arguments.at(i); + printf(",\n"); + printf(" %s", a.name.constData()); + } + printf(");\n"); + printf(" }\n"); + printf("\n"); + + printf(" void %s::send_", interfaceName); + printEvent(e, interfaceName, false, true); + printf("\n"); + printf(" {\n"); + + for (int i = 0; i < e.arguments.size(); ++i) { + const WaylandArgument &a = e.arguments.at(i); + if (a.type != "array") + continue; + QByteArray array = a.name + "_data"; + const char *arrayName = array.constData(); + const char *variableName = a.name.constData(); + printf(" struct wl_array %s;\n", arrayName); + printf(" %s.size = %s.size();\n", arrayName, variableName); + printf(" %s.data = static_cast<void *>(const_cast<char *>(%s.constData()));\n", arrayName, variableName); + printf(" %s.alloc = 0;\n", arrayName); + printf("\n"); + } + + printf(" %s_send_%s(\n", interfaceName, e.name.constData()); + printf(" resource"); + + for (int i = 0; i < e.arguments.size(); ++i) { + const WaylandArgument &a = e.arguments.at(i); + printf(",\n"); + QByteArray cType = waylandToCType(a.type, a.interface); + QByteArray qtType = waylandToQtType(a.type, a.interface, e.request); + if (a.type == "string") + printf(" %s.toUtf8().constData()", a.name.constData()); + else if (a.type == "array") + printf(" &%s_data", a.name.constData()); + else if (cType == qtType) + printf(" %s", a.name.constData()); + } + + printf(");\n"); + printf(" }\n"); + printf("\n"); + } + } + printf("}\n"); + printf("\n"); + printf("QT_END_NAMESPACE\n"); + } + + if (option == ClientHeader) { + QByteArray inclusionGuard = "QT_WAYLAND_" + protocolName.toUpper(); + printf("#ifndef %s\n", inclusionGuard.constData()); + printf("#define %s\n", inclusionGuard.constData()); + printf("\n"); + printf("#include \"wayland-%s-client-protocol.h\"\n", QByteArray(protocolName).replace('_', '-').constData()); + printf("#include <QByteArray>\n"); + printf("#include <QString>\n"); + printf("\n"); + printf("QT_BEGIN_NAMESPACE\n"); + printf("\n"); + printf("namespace QtWayland {\n"); + for (int j = 0; j < interfaces.size(); ++j) { + const WaylandInterface &interface = interfaces.at(j); + + if (ignoreInterface(interface.name)) + continue; + + const char *interfaceName = interface.name.constData(); + + QByteArray stripped = stripInterfaceName(interface.name); + const char *interfaceNameStripped = stripped.constData(); + + printf(" class %s\n {\n", interfaceName); + printf(" public:\n"); + printf(" %s(struct ::wl_registry *registry, int id);\n", interfaceName); + printf(" %s(struct ::%s *object);\n", interfaceName, interfaceName); + printf(" %s();\n", interfaceName); + printf("\n"); + printf(" virtual ~%s();\n", interfaceName); + printf("\n"); + printf(" void init(struct ::wl_registry *registry, int id);\n"); + printf(" void init(struct ::%s *object);\n", interfaceName); + printf("\n"); + printf(" struct ::%s *object() { return m_%s; }\n", interfaceName, interfaceName); + printf(" const struct ::%s *object() const { return m_%s; }\n", interfaceName, interfaceName); + printf("\n"); + printf(" bool isInitialized() const;\n"); + + printEnums(interface.enums); + + if (!interface.requests.isEmpty()) { + printf("\n"); + foreach (const WaylandEvent &e, interface.requests) { + const WaylandArgument *new_id = newIdArgument(e.arguments); + printf(" %s", new_id ? (new_id->interface.isEmpty() ? "void *" : "struct ::" + new_id->interface + " *").constData() : "void "); + printEvent(e, interfaceName); + printf(";\n"); + } + } + + bool hasEvents = !interface.events.isEmpty(); + + if (hasEvents) { + printf("\n"); + printf(" protected:\n"); + foreach (const WaylandEvent &e, interface.events) { + printf(" virtual void %s_", interfaceNameStripped); + printEvent(e, interfaceName); + printf(";\n"); + } + } + + printf("\n"); + printf(" private:\n"); + if (hasEvents) { + printf(" void init_listener();\n"); + printf(" static const struct %s_listener m_%s_listener;\n", interfaceName, interfaceName); + for (int i = 0; i < interface.events.size(); ++i) { + const WaylandEvent &e = interface.events.at(i); + printf(" static void "); + + printEventHandlerSignature(e, interfaceName); + printf(";\n"); + } + } + printf(" struct ::%s *m_%s;\n", interfaceName, interfaceName); + printf(" };\n"); + + if (j < interfaces.size() - 1) + printf("\n"); + } + printf("}\n"); + printf("\n"); + printf("QT_END_NAMESPACE\n"); + printf("\n"); + printf("#endif\n"); + } + + if (option == ClientCode) { + printf("#include \"qwayland-%s.h\"\n", QByteArray(protocolName).replace('_', '-').constData()); + printf("\n"); + printf("QT_BEGIN_NAMESPACE\n"); + printf("\n"); + printf("namespace QtWayland {\n"); + for (int j = 0; j < interfaces.size(); ++j) { + const WaylandInterface &interface = interfaces.at(j); + + if (ignoreInterface(interface.name)) + continue; + + const char *interfaceName = interface.name.constData(); + + QByteArray stripped = stripInterfaceName(interface.name); + const char *interfaceNameStripped = stripped.constData(); + + bool hasEvents = !interface.events.isEmpty(); + + printf(" %s::%s(struct ::wl_registry *registry, int id)\n", interfaceName, interfaceName); + printf(" {\n"); + printf(" init(registry, id);\n"); + printf(" }\n"); + printf("\n"); + + printf(" %s::%s(struct ::%s *obj)\n", interfaceName, interfaceName, interfaceName); + printf(" : m_%s(obj)\n", interfaceName); + printf(" {\n"); + if (hasEvents) + printf(" init_listener();\n"); + printf(" }\n"); + printf("\n"); + + printf(" %s::%s()\n", interfaceName, interfaceName); + printf(" : m_%s(0)\n", interfaceName); + printf(" {\n"); + printf(" }\n"); + printf("\n"); + + printf(" %s::~%s()\n", interfaceName, interfaceName); + printf(" {\n"); + printf(" }\n"); + printf("\n"); + + printf(" void %s::init(struct ::wl_registry *registry, int id)\n", interfaceName); + printf(" {\n"); + printf(" m_%s = static_cast<struct ::%s *>(wl_registry_bind(registry, id, &%s_interface, %d));\n", interfaceName, interfaceName, interfaceName, interface.version); + if (hasEvents) + printf(" init_listener();\n"); + printf(" }\n"); + printf("\n"); + + printf(" void %s::init(struct ::%s *obj)\n", interfaceName, interfaceName); + printf(" {\n"); + printf(" m_%s = obj;\n", interfaceName); + if (hasEvents) + printf(" init_listener();\n"); + printf(" }\n"); + printf("\n"); + + printf(" bool %s::isInitialized() const\n", interfaceName); + printf(" {\n"); + printf(" return m_%s != 0;\n", interfaceName); + printf(" }\n"); + + for (int i = 0; i < interface.requests.size(); ++i) { + printf("\n"); + const WaylandEvent &e = interface.requests.at(i); + const WaylandArgument *new_id = newIdArgument(e.arguments); + printf(" %s%s::", new_id ? (new_id->interface.isEmpty() ? "void *" : "struct ::" + new_id->interface + " *").constData() : "void ", interfaceName); + printEvent(e, interfaceName); + printf("\n"); + printf(" {\n"); + for (int i = 0; i < e.arguments.size(); ++i) { + const WaylandArgument &a = e.arguments.at(i); + if (a.type != "array") + continue; + QByteArray array = a.name + "_data"; + const char *arrayName = array.constData(); + const char *variableName = a.name.constData(); + printf(" struct wl_array %s;\n", arrayName); + printf(" %s.size = %s.size();\n", arrayName, variableName); + printf(" %s.data = static_cast<void *>(const_cast<char *>(%s.constData()));\n", arrayName, variableName); + printf(" %s.alloc = 0;\n", arrayName); + printf("\n"); + } + int actualArgumentCount = new_id ? e.arguments.size() - 1 : e.arguments.size(); + printf(" %s%s_%s(\n", new_id ? "return " : "", interfaceName, e.name.constData()); + printf(" m_%s%s", interfaceName, actualArgumentCount > 0 ? "," : ""); + bool needsComma = false; + for (int i = 0; i < e.arguments.size(); ++i) { + const WaylandArgument &a = e.arguments.at(i); + bool isNewId = a.type == "new_id"; + if (isNewId && !a.interface.isEmpty()) + continue; + if (needsComma) + printf(","); + needsComma = true; + printf("\n"); + if (isNewId) { + printf(" interface,\n"); + printf(" version"); + } else { + QByteArray cType = waylandToCType(a.type, a.interface); + QByteArray qtType = waylandToQtType(a.type, a.interface, e.request); + if (a.type == "string") + printf(" %s.toUtf8().constData()", a.name.constData()); + else if (a.type == "array") + printf(" &%s_data", a.name.constData()); + else if (cType == qtType) + printf(" %s", a.name.constData()); + } + } + printf(");\n"); + printf(" }\n"); + } + + if (hasEvents) { + printf("\n"); + for (int i = 0; i < interface.events.size(); ++i) { + const WaylandEvent &e = interface.events.at(i); + printf(" void %s::%s_", interfaceName, interfaceNameStripped); + printEvent(e, interfaceName, true); + printf("\n"); + printf(" {\n"); + printf(" }\n"); + printf("\n"); + printf(" void %s::", interfaceName); + printEventHandlerSignature(e, interfaceName, false); + printf("\n"); + printf(" {\n"); + if (!newIdArgument(e.arguments)) + printf(" Q_UNUSED(object);\n"); + printf(" static_cast<%s *>(data)->%s_%s(", interfaceName, interfaceNameStripped, e.name.constData()); + for (int i = 0; i < e.arguments.size(); ++i) { + printf("\n"); + const WaylandArgument &a = e.arguments.at(i); + QByteArray cType = waylandToCType(a.type, a.interface); + QByteArray qtType = waylandToQtType(a.type, a.interface, e.request); + const char *argumentName = a.name.constData(); + if (a.type == "new_id") + printf(" object,\n"); + if (a.type == "string") + printf(" QString::fromUtf8(%s)", argumentName); + else + printf(" %s", argumentName); + + if (i < e.arguments.size() - 1) + printf(","); + } + printf(");\n"); + + printf(" }\n"); + printf("\n"); + } + printf(" const struct %s_listener %s::m_%s_listener = {\n", interfaceName, interfaceName, interfaceName); + for (int i = 0; i < interface.events.size(); ++i) { + const WaylandEvent &e = interface.events.at(i); + printf(" %s::handle_%s%s\n", interfaceName, e.name.constData(), i < interface.events.size() - 1 ? "," : ""); + } + printf(" };\n"); + printf("\n"); + + printf(" void %s::init_listener()\n", interfaceName); + printf(" {\n"); + printf(" %s_add_listener(m_%s, &m_%s_listener, this);\n", interfaceName, interfaceName, interfaceName); + printf(" }\n"); + } + + if (j < interfaces.size() - 1) + printf("\n"); + } + printf("}\n"); + printf("\n"); + printf("QT_END_NAMESPACE\n"); + } +} + +int main(int argc, char **argv) +{ + if (argc <= 2 || !parseOption(argv[1], &option)) { + fprintf(stderr, "Usage: %s [client-header|server-header|client-code|server-code] specfile\n", argv[0]); + return 1; + } + + QCoreApplication app(argc, argv); + + QFile file(argv[2]); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + fprintf(stderr, "Unable to open file %s\n", argv[2]); + return 1; + } + + QXmlStreamReader xml(&file); + process(xml); + + if (xml.hasError()) { + fprintf(stderr, "XML error: %s\nLine %lld, column %lld\n", xml.errorString().toLocal8Bit().constData(), xml.lineNumber(), xml.columnNumber()); + return 1; + } +} diff --git a/src/qtwaylandscanner/qtwaylandscanner.pro b/src/qtwaylandscanner/qtwaylandscanner.pro new file mode 100644 index 00000000..ac2d07b7 --- /dev/null +++ b/src/qtwaylandscanner/qtwaylandscanner.pro @@ -0,0 +1,6 @@ +option(host_build) + +SOURCES += qtwaylandscanner.cpp + +load(qt_tool) + diff --git a/src/src.pro b/src/src.pro index a12622d5..ac4e62aa 100644 --- a/src/src.pro +++ b/src/src.pro @@ -1,6 +1,8 @@ TEMPLATE=subdirs CONFIG+=ordered +SUBDIRS += qtwaylandscanner + #Don't build QtCompositor API unless explicitly enabled contains(CONFIG, wayland-compositor) { SUBDIRS += compositor |