diff options
Diffstat (limited to 'src/compositor/wayland_wrapper')
23 files changed, 3072 insertions, 0 deletions
diff --git a/src/compositor/wayland_wrapper/wayland_wrapper.pri b/src/compositor/wayland_wrapper/wayland_wrapper.pri new file mode 100644 index 000000000..478b39982 --- /dev/null +++ b/src/compositor/wayland_wrapper/wayland_wrapper.pri @@ -0,0 +1,26 @@ +HEADERS += \ + $$PWD/wlcompositor.h \ + $$PWD/wldisplay.h \ + $$PWD/wloutput.h \ + $$PWD/wlshmbuffer.h \ + $$PWD/wlsurface.h \ + $$PWD/wlshell.h \ + $$PWD/wlinputdevice.h \ + $$PWD/wldatadevicemanager.h \ + $$PWD/wldatadevice.h \ + $$PWD/wldataoffer.h \ + $$PWD/wldatasource.h + +SOURCES += \ + $$PWD/wlcompositor.cpp \ + $$PWD/wldisplay.cpp \ + $$PWD/wloutput.cpp \ + $$PWD/wlshmbuffer.cpp \ + $$PWD/wlsurface.cpp \ + $$PWD/wlshell.cpp \ + $$PWD/wlinputdevice.cpp \ + $$PWD/wldatadevicemanager.cpp \ + $$PWD/wldatadevice.cpp \ + $$PWD/wldataoffer.cpp \ + $$PWD/wldatasource.cpp + diff --git a/src/compositor/wayland_wrapper/wlcompositor.cpp b/src/compositor/wayland_wrapper/wlcompositor.cpp new file mode 100644 index 000000000..168094734 --- /dev/null +++ b/src/compositor/wayland_wrapper/wlcompositor.cpp @@ -0,0 +1,428 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#include "wlcompositor.h" + +#include "waylandobject.h" +#include "wldisplay.h" +#include "wlshmbuffer.h" +#include "wlsurface.h" +#include "wlinputdevice.h" +#include "waylandcompositor.h" +#include "wldatadevicemanager.h" +#include "wldatadevice.h" + +#include <QWindow> +#include <QSocketNotifier> +#include <QDebug> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stddef.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> + +#include <sys/mman.h> +#include <sys/select.h> +#include <sys/time.h> + +#include <wayland-server.h> + +#include "hardware_integration/graphicshardwareintegration.h" +#include "waylandwindowmanagerintegration.h" + +namespace Wayland { + +static Compositor *compositor; + +static void shmBufferDestroyed(ShmBuffer *buf) +{ +// if (currentCursor == buf) { +// compositor->qtCompositor()->changeCursor(QImage(), 0, 0); +// currentCursor = 0; +// } +} + +void destroy_surface(struct wl_resource *resource) +{ + Surface *surface = wayland_cast<Surface *>((wl_surface *)resource); + delete surface; +} + +void compositor_create_surface(struct wl_client *client, + struct wl_resource *resource, uint32_t id) +{ + static_cast<Compositor *>(resource->data)->createSurface(client,id); +} + +const static struct wl_compositor_interface compositor_interface = { + compositor_create_surface +}; + +void Compositor::bind_func(struct wl_client *client, void *data, + uint32_t version, uint32_t id) +{ + wl_client_add_object(client,&wl_compositor_interface, &compositor_interface, id,data); +} + + +Compositor *Compositor::instance() +{ + return compositor; +} + +Compositor::Compositor(WaylandCompositor *qt_compositor) + : m_display(new Display) + , m_shell(this) + , m_shm(m_display) + , m_current_frame(0) + , m_last_queued_buf(-1) + , m_qt_compositor(qt_compositor) + , m_orientation(Qt::UnknownOrientation) + , m_pointerFocusSurface(0) + , m_keyFocusSurface(0) + , m_directRenderSurface(0) +#if defined (QT_COMPOSITOR_WAYLAND_GL) + , m_graphics_hw_integration(0) +#endif +{ + compositor = this; + qDebug() << "Compositor instance is" << this; + m_shm.addDestroyCallback(shmBufferDestroyed); + +#if defined (QT_COMPOSITOR_WAYLAND_GL) + QWindow *window = qt_compositor->window(); + if (window && window->surfaceType() != QWindow::RasterSurface) + m_graphics_hw_integration = GraphicsHardwareIntegration::createGraphicsHardwareIntegration(qt_compositor); +#endif + m_windowManagerWaylandProtocol = new WindowManagerServerIntegration(this); + connect(m_windowManagerWaylandProtocol, + SIGNAL(windowPropertyChanged(wl_client*,wl_surface*,QString,QVariant)), + SLOT(windowPropertyChanged(wl_client*,wl_surface*,QString,QVariant))); + + wl_display_add_global(m_display->handle(),&wl_compositor_interface,this,Compositor::bind_func); + + m_input = new InputDevice(this); + + m_data_device_manager = new DataDeviceManager(this); + wl_display_add_global(m_display->handle(),&wl_output_interface,m_output.base(),Output::output_bind_func); + + wl_display_add_global(m_display->handle(), &wl_shell_interface, m_shell.base(), Shell::bind_func); + + + if (wl_display_add_socket(m_display->handle(), qt_compositor->socketName())) { + fprintf(stderr, "Fatal: Failed to open server socket\n"); + exit(EXIT_FAILURE); + } + + m_loop = wl_display_get_event_loop(m_display->handle()); + + int fd = wl_event_loop_get_fd(m_loop); + + QSocketNotifier *sockNot = new QSocketNotifier(fd, QSocketNotifier::Read, this); + connect(sockNot, SIGNAL(activated(int)), this, SLOT(processWaylandEvents())); + + //initialize distancefieldglyphcache here +} + +Compositor::~Compositor() +{ + delete m_input; + delete m_data_device_manager; + + delete m_display; +} + +void Compositor::frameFinished(Surface *surface) +{ + if (surface && m_dirty_surfaces.contains(surface)) { + surface->sendFrameCallback(); + m_dirty_surfaces.remove(surface); + } else if (!surface) { + foreach (Surface *surface, m_dirty_surfaces) + surface->sendFrameCallback(); + m_dirty_surfaces.clear(); + } +} + +void Compositor::createSurface(struct wl_client *client, int id) +{ + Surface *surface = new Surface(client, this); + printf("Compositor::createSurface: %p %d\n", client, id); + + addClientResource(client, &surface->base()->resource, id, &wl_surface_interface, + &Surface::surface_interface, destroy_surface); + + QList<struct wl_client *> prevClientList = clients(); + m_surfaces << surface; + if (!prevClientList.contains(client)) { + m_windowManagerWaylandProtocol->setScreenOrientation(client, m_output.base(), m_orientation); + emit clientAdded(client); + } + + m_qt_compositor->surfaceCreated(surface->handle()); +} + +struct wl_client *Compositor::getClientFromWinId(uint winId) const +{ + Surface *surface = getSurfaceFromWinId(winId); + if (surface) + return surface->base()->resource.client; + + return 0; +} + +Surface *Compositor::getSurfaceFromWinId(uint winId) const +{ + foreach (Surface *surface, m_surfaces) { + if (surface->id() == winId) + return surface; + } + + return 0; +} + +QImage Compositor::image(uint winId) const +{ + printf("Compositor::image(%x)\n", winId); + foreach (Surface *surface, m_surfaces) { + if (surface->id() == winId) { + return surface->image(); + } + } + + return QImage(); +} + +uint Compositor::currentTimeMsecs() +{ + //### we throw away the time information + struct timeval tv; + int ret = gettimeofday(&tv, 0); + if (ret == 0) + return tv.tv_sec*1000 + tv.tv_usec/1000; + return 0; +} + +void Compositor::releaseBuffer(void *bufferHandle) +{ + struct wl_buffer *buffer = static_cast<struct wl_buffer*>(bufferHandle); + if (buffer) { + //qDebug() << "WL_BUFFER_RELEASE" << buffer<< buffer->resource.client; + wl_resource_post_event(&buffer->resource, WL_BUFFER_RELEASE); + } + +} + +void Compositor::processWaylandEvents() +{ + int ret = wl_event_loop_dispatch(m_loop, 0); + if (ret) + fprintf(stderr, "wl_event_loop_dispatch error: %d\n", ret); +} + +void Compositor::windowPropertyChanged(wl_client *client, wl_surface *changedSurface, const QString &name, const QVariant &value) +{ + for(int i = 0; i < m_surfaces.length(); ++i) { + Surface *surface = m_surfaces[i]; + if (surface->clientHandle() == client && surface->base() == changedSurface) { + surface->setWindowProperty(name, value, false); + } + } +} + +void Compositor::surfaceDestroyed(Surface *surface) +{ + m_surfaces.removeOne(surface); + if (m_keyFocusSurface == surface) + setKeyFocus(0); + if (m_pointerFocusSurface == surface) + setPointerFocus(0); + if (m_directRenderSurface == surface) + setDirectRenderSurface(0); +} + +void Compositor::markSurfaceAsDirty(Wayland::Surface *surface) +{ + m_dirty_surfaces.insert(surface); +} + +void Compositor::destroyClientForSurface(Surface *surface) +{ + wl_client *client = surface->base()->resource.client; + + if (client) { + m_windowManagerWaylandProtocol->removeClient(client); + wl_client_destroy(client); + } +} + +void Compositor::setInputFocus(Surface *surface) +{ + setKeyFocus(surface); + setPointerFocus(surface); +} + +void Compositor::setKeyFocus(Surface *surface) +{ + m_input->sendSelectionFocus(surface); + m_keyFocusSurface = surface; + wl_input_device_set_keyboard_focus(m_input->base(), surface ? surface->base() : 0, currentTimeMsecs()); +} + +Surface *Compositor::keyFocus() const +{ + return m_keyFocusSurface; +} + +void Compositor::setPointerFocus(Surface *surface, const QPoint &pos) +{ + m_pointerFocusSurface = surface; + wl_input_device_set_pointer_focus(m_input->base(), surface ? surface->base() : 0, currentTimeMsecs(), pos.x(), pos.y(), pos.x(), pos.y()); +} + +Surface *Compositor::pointerFocus() const +{ + return m_pointerFocusSurface; +} + +QWindow *Compositor::window() const +{ + return m_qt_compositor->window(); +} + +GraphicsHardwareIntegration * Compositor::graphicsHWIntegration() const +{ +#ifdef QT_COMPOSITOR_WAYLAND_GL + return m_graphics_hw_integration; +#else + return 0; +#endif +} + +void Compositor::initializeHardwareIntegration() +{ +#ifdef QT_COMPOSITOR_WAYLAND_GL + if (m_graphics_hw_integration) + m_graphics_hw_integration->initializeHardware(m_display); +#endif +} + +void Compositor::initializeWindowManagerProtocol() +{ + m_windowManagerWaylandProtocol->initialize(m_display); +} + +bool Compositor::setDirectRenderSurface(Surface *surface) +{ +#ifdef QT_COMPOSITOR_WAYLAND_GL + if (m_graphics_hw_integration && m_graphics_hw_integration->setDirectRenderSurface(surface ? surface->handle() : 0)) { + m_directRenderSurface = surface; + return true; + } +#else + Q_UNUSED(surface); +#endif + return false; +} + +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; + if (!list.contains(client)) + list.append(client); + } + return list; +} + +void Compositor::setScreenOrientation(Qt::ScreenOrientation orientation) +{ + m_orientation = orientation; + + QList<struct wl_client*> clientList = clients(); + for (int i = 0; i < clientList.length(); ++i) { + struct wl_client *client = clientList.at(i); + m_windowManagerWaylandProtocol->setScreenOrientation(client, m_output.base(), orientation); + } +} + +void Compositor::setOutputGeometry(const QRect &geometry) +{ + m_output.setGeometry(geometry); +} + +InputDevice* Compositor::defaultInputDevice() +{ + return m_input; +} + +QList<Wayland::Surface *> Compositor::surfacesForClient(wl_client *client) +{ + QList<Wayland::Surface *> ret; + + for (int i=0; i < m_surfaces.count(); ++i) { + if (m_surfaces.at(i)->clientHandle() == client) { + ret.append(m_surfaces.at(i)); + } + } + return ret; +} + +bool Compositor::isDragging() const +{ + return false; +} + +void Compositor::sendDragMoveEvent(const QPoint &global, const QPoint &local, + Surface *surface) +{ +// Drag::instance()->dragMove(global, local, surface); +} + +void Compositor::sendDragEndEvent() +{ +// Drag::instance()->dragEnd(); +} + +} // namespace Wayland diff --git a/src/compositor/wayland_wrapper/wlcompositor.h b/src/compositor/wayland_wrapper/wlcompositor.h new file mode 100644 index 000000000..9aaba776d --- /dev/null +++ b/src/compositor/wayland_wrapper/wlcompositor.h @@ -0,0 +1,172 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#ifndef WL_COMPOSITOR_H +#define WL_COMPOSITOR_H + +#include <QtCore/QSet> + +#include "wloutput.h" +#include "wldisplay.h" +#include "wlshmbuffer.h" +#include "wlshell.h" + +#include <wayland-server.h> + +class WaylandCompositor; +class GraphicsHardwareIntegration; +class WindowManagerServerIntegration; + +namespace Wayland { + +class Surface; +class InputDevice; +class DataDeviceManager; + +class Compositor : public QObject +{ + Q_OBJECT + +public: + Compositor(WaylandCompositor *qt_compositor); + ~Compositor(); + + void frameFinished(Surface *surface = 0); + void setInputFocus(Surface *surface); + void setKeyFocus(Surface *surface); + Surface *keyFocus() const; + void setPointerFocus(Surface *surface, const QPoint &point = QPoint()); + Surface *pointerFocus() const; + + Surface *getSurfaceFromWinId(uint winId) const; + struct wl_client *getClientFromWinId(uint winId) const; + QImage image(uint winId) const; + + InputDevice *inputDevice() { return m_input; } + InputDevice *defaultInputDevice(); + + void createSurface(struct wl_client *client, int id); + void surfaceDestroyed(Surface *surface); + void markSurfaceAsDirty(Surface *surface); + + void destroyClientForSurface(Surface *surface); + + static uint currentTimeMsecs(); + + QWindow *window() const; + + GraphicsHardwareIntegration *graphicsHWIntegration() const; + void initializeHardwareIntegration(); + void initializeWindowManagerProtocol(); + bool setDirectRenderSurface(Surface *surface); + Surface *directRenderSurface() const {return m_directRenderSurface;} + + QList<Surface*> surfacesForClient(wl_client* client); + + WaylandCompositor *qtCompositor() const { return m_qt_compositor; } + + struct wl_display *wl_display() { return m_display->handle(); } + + static Compositor *instance(); + + QList<struct wl_client *> clients() const; + + void setScreenOrientation(Qt::ScreenOrientation orientation); + void setOutputGeometry(const QRect &geometry); + + bool isDragging() const; + void sendDragMoveEvent(const QPoint &global, const QPoint &local, Surface *surface); + void sendDragEndEvent(); + +public slots: + void releaseBuffer(void*); + +signals: + void clientAdded(wl_client *client); + +private slots: + void processWaylandEvents(); + void windowPropertyChanged(wl_client *client, wl_surface *surface, const QString &name, const QVariant &value); + +private: + Display *m_display; + + /* Input */ + InputDevice *m_input; + + /* Output */ + //make this a list of the available screens + Output m_output; + + Shell m_shell; + + /* shm/*/ + ShmHandler m_shm; + + DataDeviceManager *m_data_device_manager; + + QList<Surface *> m_surfaces; + QSet<Surface *> m_dirty_surfaces; + + /* Render state */ + uint32_t m_current_frame; + int m_last_queued_buf; + + wl_event_loop *m_loop; + + WaylandCompositor *m_qt_compositor; + Qt::ScreenOrientation m_orientation; + + Surface *m_pointerFocusSurface; + Surface *m_keyFocusSurface; + Surface *m_directRenderSurface; + +#ifdef QT_COMPOSITOR_WAYLAND_GL + GraphicsHardwareIntegration *m_graphics_hw_integration; +#endif + WindowManagerServerIntegration *m_windowManagerWaylandProtocol; + + static void bind_func(struct wl_client *client, void *data, + uint32_t version, uint32_t id); +}; + +} + +#endif //WL_COMPOSITOR_H diff --git a/src/compositor/wayland_wrapper/wldatadevice.cpp b/src/compositor/wayland_wrapper/wldatadevice.cpp new file mode 100644 index 000000000..e7bdfb434 --- /dev/null +++ b/src/compositor/wayland_wrapper/wldatadevice.cpp @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#include "wldatadevice.h" + +#include "wldatasource.h" +#include "wldataoffer.h" +#include "wldatadevicemanager.h" + +#include <stdlib.h> + +#include <QDebug> + +namespace Wayland { + +void DataDevice::start_drag(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *source, + struct wl_resource *surface, + uint32_t time) +{ + DataDevice *data_device = static_cast<DataDevice *>(resource->data); + DataSource *data_source = static_cast<DataSource *>(source->data); + + +} + +void DataDevice::attach(struct wl_client *client, + struct wl_resource *resource, + uint32_t time, + struct wl_resource *buffer, + int32_t x, + int32_t y) +{ + +} + +void DataDevice::set_selection(struct wl_client *client, + struct wl_resource *data_device_resource, + struct wl_resource *source, + uint32_t time) +{ + DataDevice *data_device = static_cast<DataDevice *>(data_device_resource->data); + DataSource *data_source = static_cast<DataSource *>(source->data); + + data_device->m_data_device_manager->setCurrentSelectionSource(data_source); + +} + +const struct wl_data_device_interface DataDevice::data_device_interface = { + DataDevice::start_drag, + DataDevice::attach, + DataDevice::set_selection +}; + +DataDevice::DataDevice(DataDeviceManager *data_device_manager, struct wl_client *client, uint32_t id) + : m_data_device_manager(data_device_manager) + , m_sent_selection_time(0) +{ + + static int i = 0; + qDebug() << "data device" << ++i; + m_data_device_resource = + wl_client_add_object(client,&wl_data_device_interface,&data_device_interface,id, this); +} + +void DataDevice::sendSelectionFocus() +{ + //do for all clipboards + DataSource *source = m_data_device_manager->currentSelectionSource(); + if (!source){ + return; + } + if (source->time() > m_sent_selection_time) { //this makes sure we don't resend + if (source->client() != m_data_device_resource->client) { //don't send selection to the client that owns the selection + DataOffer *data_offer = m_data_device_manager->currentSelectionSource()->dataOffer(); + wl_resource *client_resource = + data_offer->addDataDeviceResource(m_data_device_resource); + qDebug() << "sending data_offer for source" << source; + wl_resource_post_event(m_data_device_resource,WL_DATA_DEVICE_SELECTION,client_resource); + m_sent_selection_time = source->time(); + } + } +} + +struct wl_resource *DataDevice::dataDeviceResource() const +{ + return m_data_device_resource; +} + +} diff --git a/src/compositor/wayland_wrapper/wldatadevice.h b/src/compositor/wayland_wrapper/wldatadevice.h new file mode 100644 index 000000000..4be777dbf --- /dev/null +++ b/src/compositor/wayland_wrapper/wldatadevice.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#ifndef WLDATADEVICE_H +#define WLDATADEVICE_H + +#include "wldatadevicemanager.h" + +namespace Wayland { + +class DataSource; +class DataDeviceManager; + +class DataDevice +{ +public: + DataDevice(DataDeviceManager *data_device_manager, struct wl_client *client, uint32_t id); + + void createAndSetSelectionSource(struct wl_client *client, uint32_t id, const char *name, uint32_t time); + void sendSelectionFocus(); + + struct wl_resource *dataDeviceResource() const; + + struct wl_display *display() const { return m_data_device_manager->display(); } +private: + DataDeviceManager *m_data_device_manager; + uint32_t m_sent_selection_time; + struct wl_resource *m_data_device_resource; + + static const struct wl_data_device_interface data_device_interface; + static void start_drag(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *source, + struct wl_resource *surface, + uint32_t time); + static void attach(struct wl_client *client, + struct wl_resource *resource, + uint32_t time, + struct wl_resource *buffer, + int32_t x, + int32_t y); + static void set_selection(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *source, + uint32_t time); +}; + +} + +#endif // WLDATADEVICE_H diff --git a/src/compositor/wayland_wrapper/wldatadevicemanager.cpp b/src/compositor/wayland_wrapper/wldatadevicemanager.cpp new file mode 100644 index 000000000..834ef9545 --- /dev/null +++ b/src/compositor/wayland_wrapper/wldatadevicemanager.cpp @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#include "wldatadevicemanager.h" + +#include "wldatadevice.h" +#include "wldatasource.h" +#include "wlinputdevice.h" +#include "wlcompositor.h" +#include "wldataoffer.h" + +#include <QtCore/QDebug> + +namespace Wayland { + +DataDeviceManager::DataDeviceManager(Compositor *compositor) + : m_compositor(compositor) + , m_current_selection_source(0) +{ + wl_display_add_global(compositor->wl_display(), &wl_data_device_manager_interface, base(), DataDeviceManager::bind_func_drag); +} +void DataDeviceManager::setCurrentSelectionSource(DataSource *source) +{ + if (m_current_selection_source) { + if (m_current_selection_source->time() >= source->time()) { + qDebug() << "Trying to set older selection"; + return; + } + } + m_current_selection_source = source; +} + +DataSource *DataDeviceManager::currentSelectionSource() +{ + return m_current_selection_source; +} + +struct wl_display *DataDeviceManager::display() const +{ + return m_compositor->wl_display(); +} + +void DataDeviceManager::bind_func_drag(struct wl_client *client, void *data, uint32_t version, uint32_t id) +{ + wl_client_add_object(client,&wl_data_device_manager_interface,&drag_interface,id,data); +} + +void DataDeviceManager::bind_func_data(struct wl_client *client, void *data, uint32_t version, uint32_t id) +{ +} + +void DataDeviceManager::get_data_device(struct wl_client *client, + struct wl_resource *data_device_manager_resource, + uint32_t id, + struct wl_resource *input_device_resource) +{ + DataDeviceManager *data_device_manager = static_cast<DataDeviceManager *>(data_device_manager_resource->data); + InputDevice *input_device = reinterpret_cast<InputDevice *>(input_device_resource->data); + input_device->clientRequestedDataDevice(data_device_manager,client,id); +} + +void DataDeviceManager::create_data_source(struct wl_client *client, + struct wl_resource *data_device_manager_resource, + uint32_t id) +{ + Q_UNUSED(data_device_manager_resource); + new DataSource(client,id, Compositor::currentTimeMsecs()); +} + +struct wl_data_device_manager_interface DataDeviceManager::drag_interface = { + DataDeviceManager::create_data_source, + DataDeviceManager::get_data_device +}; + +} //namespace diff --git a/src/compositor/wayland_wrapper/wldatadevicemanager.h b/src/compositor/wayland_wrapper/wldatadevicemanager.h new file mode 100644 index 000000000..87398c4cf --- /dev/null +++ b/src/compositor/wayland_wrapper/wldatadevicemanager.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#ifndef WLDATADEVICEMANAGER_H +#define WLDATADEVICEMANAGER_H + +#include "waylandobject.h" + +#include "wlcompositor.h" + +#include <QtCore/QList> +#include <QtCore/QMap> +#include <QtGui/QClipboard> + + +namespace Wayland { + +class Compositor; + +class DataDevice; +class DataSource; + +class DataDeviceManager : public Object<struct wl_object> +{ +public: + DataDeviceManager(Compositor *compositor); + + void setCurrentSelectionSource(DataSource *source); + DataSource *currentSelectionSource(); + + struct wl_display *display() const; +private: + Compositor *m_compositor; + QList<DataDevice *> m_data_device_list; + + DataSource *m_current_selection_source; + + static void bind_func_drag(struct wl_client *client, void *data, + uint32_t version, uint32_t id); + static void bind_func_data(struct wl_client *client, void *data, + uint32_t version, uint32_t id); + static void get_data_device(struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *input_device); + static void create_data_source(struct wl_client *client, + struct wl_resource *resource, + uint32_t id); + static struct wl_data_device_manager_interface drag_interface; +}; + +} +#endif // WLDATADEVICEMANAGER_H diff --git a/src/compositor/wayland_wrapper/wldataoffer.cpp b/src/compositor/wayland_wrapper/wldataoffer.cpp new file mode 100644 index 000000000..882337352 --- /dev/null +++ b/src/compositor/wayland_wrapper/wldataoffer.cpp @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#include "wldataoffer.h" + +#include "wldatadevice.h" + +#include <wayland-server.h> + +#include <sys/time.h> + +#include <QtCore/QDebug> + +namespace Wayland +{ + +DataOffer::DataOffer(DataSource *data_source) + : m_data_source(data_source) +{ + +} + +DataOffer::~DataOffer() +{ +} + +struct wl_resource *DataOffer::addDataDeviceResource(struct wl_resource *data_device_resource) +{ + for (int i = 0; i < m_clients_data_resource.size(); i++) { + if (m_clients_data_resource.at(i)->client == data_device_resource->client) { + qDebug() << "This should not happen, the client tries to add twice to a data offer"; + return 0; + } + } + struct wl_resource *new_object = + wl_client_new_object(data_device_resource->client,&wl_data_offer_interface,&data_interface,this); + wl_resource_post_event(data_device_resource,WL_DATA_DEVICE_DATA_OFFER,new_object); + + m_clients_data_resource.append(new_object); + QList<QByteArray> offer_list = m_data_source->offerList(); + for (int i = 0; i < offer_list.size(); i++) { + wl_resource_post_event(new_object, WL_DATA_OFFER_OFFER, offer_list.at(i).constData()); + } + return new_object; +} + +void DataOffer::removeClient(struct wl_client *client) +{ + for (int i = 0; i < m_clients_data_resource.size(); i++) { + struct wl_resource *resource = m_clients_data_resource.at(i); + if (resource->client == client) { + wl_resource_destroy(resource,Compositor::currentTimeMsecs()); + m_clients_data_resource.removeAt(i); + break; + } + } +} + +const struct wl_data_offer_interface DataOffer::data_interface = { + DataOffer::accept, + DataOffer::receive, + DataOffer::destroy +}; + +void DataOffer::accept(wl_client *client, wl_resource *resource, uint32_t time, const char *type) +{ + +} + +void DataOffer::receive(wl_client *client, wl_resource *resource, const char *mime_type, int32_t fd) +{ + Q_UNUSED(client); + + DataOffer *offer = static_cast<DataOffer *>(resource->data); + offer->m_data_source->postSendEvent(mime_type,fd); + close(fd); +} + +void DataOffer::destroy(wl_client *client, wl_resource *resource) +{ + qDebug() << "dataOFFER DESTROY!"; + DataOffer *data_offer = static_cast<DataOffer *>(resource->data); + data_offer->removeClient(client); + + if (data_offer->m_clients_data_resource.size() == 0) { + delete data_offer; + } +} + + +} diff --git a/src/compositor/wayland_wrapper/wldataoffer.h b/src/compositor/wayland_wrapper/wldataoffer.h new file mode 100644 index 000000000..5db80f62b --- /dev/null +++ b/src/compositor/wayland_wrapper/wldataoffer.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#ifndef WLDATAOFFER_H +#define WLDATAOFFER_H + +#include "wldatasource.h" + +namespace Wayland +{ + +class DataOffer +{ +public: + DataOffer(DataSource *data_source); + ~DataOffer(); + + struct wl_resource *addDataDeviceResource(struct wl_resource *client_resource); + void removeClient(struct wl_client *client); +private: + DataSource *m_data_source; + + QList<struct wl_resource *> m_clients_data_resource; + + static void accept(struct wl_client *client, + struct wl_resource *resource, + uint32_t time, + const char *type); + static void receive(struct wl_client *client, + struct wl_resource *resource, + const char *mime_type, + int32_t fd); + static void destroy(struct wl_client *client, + struct wl_resource *resource); + + static const struct wl_data_offer_interface data_interface; + +}; + +} + +#endif // WLDATAOFFER_H diff --git a/src/compositor/wayland_wrapper/wldatasource.cpp b/src/compositor/wayland_wrapper/wldatasource.cpp new file mode 100644 index 000000000..a3c75ec73 --- /dev/null +++ b/src/compositor/wayland_wrapper/wldatasource.cpp @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#include "wldatasource.h" + +#include "wldataoffer.h" + +#include <wayland-server.h> + +#include "wlcompositor.h" + +#include <QtCore/QDebug> + +namespace Wayland { + + +DataSource::DataSource(struct wl_client *client, uint32_t id, uint32_t time) + : m_time(time) +{ + m_data_source_resource = wl_client_add_object(client, &wl_data_source_interface, &DataSource::data_source_interface,id,this); + m_data_source_resource->destroy = resource_destroy; + m_data_offer = new DataOffer(this); +} + +DataSource::~DataSource() +{ + qDebug() << "destorying source"; + wl_resource_destroy(m_data_source_resource,Compositor::currentTimeMsecs()); +} + +void DataSource::resource_destroy(wl_resource *resource) +{ + DataSource *source = static_cast<DataSource *>(resource->data); + if (source && source->m_data_source_resource == resource) + source->m_data_source_resource = 0; + free(resource); +} + +uint32_t DataSource::time() const +{ + return m_time; +} + +QList<QByteArray> DataSource::offerList() const +{ + return m_offers; +} + +struct wl_data_source_interface DataSource::data_source_interface = { + DataSource::offer, + DataSource::destroy +}; + +void DataSource::offer(struct wl_client *client, + struct wl_resource *resource, + const char *type) +{ + Q_UNUSED(client); + qDebug() << "received offer" << type; + static_cast<DataSource *>(resource->data)->m_offers.append(type); +} + +void DataSource::destroy(struct wl_client *client, + struct wl_resource *resource) +{ + DataSource *self = static_cast<DataSource *>(resource->data); + delete self; +} + +DataOffer * DataSource::dataOffer() const +{ + return m_data_offer; +} + +void DataSource::postSendEvent(const QByteArray mimeType, int fd) +{ + if (m_data_source_resource) { + wl_resource_post_event(m_data_source_resource,WL_DATA_SOURCE_SEND,mimeType.constData(),fd); + } +} + +struct wl_client *DataSource::client() const +{ + if (m_data_source_resource) + return m_data_source_resource->client; + return 0; +} + +} diff --git a/src/compositor/wayland_wrapper/wldatasource.h b/src/compositor/wayland_wrapper/wldatasource.h new file mode 100644 index 000000000..59385ecc3 --- /dev/null +++ b/src/compositor/wayland_wrapper/wldatasource.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#ifndef WLDATASOURCE_H +#define WLDATASOURCE_H + +#include <wayland-server-protocol.h> + +#include <QtCore/QByteArray> +#include <QtCore/QList> + +namespace Wayland { + +class DataOffer; + +class DataSource +{ +public: + DataSource(struct wl_client *client, uint32_t id, uint32_t time); + ~DataSource(); + uint32_t time() const; + QList<QByteArray> offerList() const; + + DataOffer *dataOffer() const; + + void postSendEvent(const QByteArray mimeType,int fd); + struct wl_client *client() const; + +private: + uint32_t m_time; + QList<QByteArray> m_offers; + struct wl_resource *m_data_source_resource; + + DataOffer *m_data_offer; + + static struct wl_data_source_interface data_source_interface; + static void offer(struct wl_client *client, + struct wl_resource *resource, + const char *type); + static void destroy(struct wl_client *client, + struct wl_resource *resource); + static void resource_destroy(struct wl_resource *resource); + +}; + +} + +#endif // WLDATASOURCE_H diff --git a/src/compositor/wayland_wrapper/wldisplay.cpp b/src/compositor/wayland_wrapper/wldisplay.cpp new file mode 100644 index 000000000..4277de166 --- /dev/null +++ b/src/compositor/wayland_wrapper/wldisplay.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#include "wldisplay.h" + +#include <QtCore/QDebug> + +#include <wayland-server-protocol.h> + +namespace Wayland { + +Display::Display() +{ + m_display = wl_display_create(); + + Q_ASSERT(m_display); +} + +Display::~Display() +{ + wl_display_destroy(m_display); +} + +} + diff --git a/src/compositor/wayland_wrapper/wldisplay.h b/src/compositor/wayland_wrapper/wldisplay.h new file mode 100644 index 000000000..5b2e5023d --- /dev/null +++ b/src/compositor/wayland_wrapper/wldisplay.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#ifndef WL_DISPLAY_H +#define WL_DISPLAY_H + +#include <wayland-server.h> + +namespace Wayland { + +class Display +{ +public: + Display(); + ~Display(); + + struct wl_display *handle() const { return m_display; } + struct wl_display *handle() { return m_display; } + +private: + struct wl_display *m_display; +}; + +} + +#endif //WL_DISPLAY_H diff --git a/src/compositor/wayland_wrapper/wlinputdevice.cpp b/src/compositor/wayland_wrapper/wlinputdevice.cpp new file mode 100644 index 000000000..a7ce0d43a --- /dev/null +++ b/src/compositor/wayland_wrapper/wlinputdevice.cpp @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#include "wlinputdevice.h" + +#include "wlshmbuffer.h" +#include "wlcompositor.h" +#include "wldatadevice.h" +#include "wlsurface.h" + +#include <QtCore/QDebug> + +#include "waylandcompositor.h" + +namespace Wayland { + +static ShmBuffer *currentCursor; + +InputDevice::InputDevice(Compositor *compositor) +{ + wl_input_device_init(base()); + wl_display_add_global(compositor->wl_display(),&wl_input_device_interface,this,InputDevice::bind_func); +} + +void InputDevice::clientRequestedDataDevice(DataDeviceManager *data_device_manager, struct wl_client *client, uint32_t id) +{ + for (int i = 0; i < m_data_devices.size(); i++) { + struct wl_resource *data_device_resource = + m_data_devices.at(i)->dataDeviceResource(); + if (data_device_resource->client == client) { + qDebug() << "Client created data device, but already has one; removing the old one!"; + m_data_devices.removeAt(i); + free(data_device_resource); + break; + } + } + DataDevice *dataDevice = new DataDevice(data_device_manager,client,id); + m_data_devices.append(dataDevice); + qDebug("created datadevice %p resource %p", dataDevice, dataDevice->dataDeviceResource()); +} + +void InputDevice::sendSelectionFocus(Surface *surface) +{ + if (!surface) + return; + DataDevice *device = dataDevice(surface->base()->resource.client); + if (device) { + device->sendSelectionFocus(); + } +} + +DataDevice *InputDevice::dataDevice(struct wl_client *client) const +{ + for (int i = 0; i < m_data_devices.size();i++) { + if (m_data_devices.at(i)->dataDeviceResource()->client == client) { + return m_data_devices.at(i); + } + } + return 0; +} + +void InputDevice::bind_func(struct wl_client *client, void *data, + uint32_t version, uint32_t id) +{ + Q_UNUSED(version); + struct wl_resource *resource = wl_client_add_object(client,&wl_input_device_interface ,&input_device_interface,id,data); + + struct wl_input_device *input_device = static_cast<struct wl_input_device *>(data); + resource->destroy = destroy_resource; + wl_list_insert(&input_device->resource_list,&resource->link); +} + +void InputDevice::input_device_attach(struct wl_client *client, + struct wl_resource *device_resource, + uint32_t time, + struct wl_resource *buffer_resource, int32_t x, int32_t y) +{ + Q_UNUSED(client); + Q_UNUSED(time); + + struct wl_input_device *device_base = reinterpret_cast<struct wl_input_device *>(device_resource); + struct wl_buffer *buffer = reinterpret_cast<struct wl_buffer *>(buffer_resource); + qDebug() << "Client input device attach" << client << buffer << x << y; + +// Compositor *compositor = wayland_cast<Compositor *>(device_base->compositor); + ShmBuffer *shmBuffer = static_cast<ShmBuffer *>(buffer->user_data); + if (shmBuffer) { +// compositor->qtCompositor()->changeCursor(shmBuffer->image(), x, y); + currentCursor = shmBuffer; + } +} + +const struct wl_input_device_interface InputDevice::input_device_interface = { + InputDevice::input_device_attach, +}; + +void InputDevice::destroy_resource(wl_resource *resource) +{ + qDebug() << "input device resource destroy" << resource; + InputDevice *input_device = static_cast<InputDevice *>(resource->data); + if (input_device->base()->keyboard_focus_resource == resource) { + input_device->base()->keyboard_focus_resource = 0; + } + if (input_device->base()->pointer_focus_resource == resource) { + input_device->base()->pointer_focus_resource = 0; + } + + input_device->m_data_devices.clear(); + + wl_list_remove(&resource->link); + + free(resource); +} + +} diff --git a/src/compositor/wayland_wrapper/wlinputdevice.h b/src/compositor/wayland_wrapper/wlinputdevice.h new file mode 100644 index 000000000..7ea56a918 --- /dev/null +++ b/src/compositor/wayland_wrapper/wlinputdevice.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#ifndef WLINPUTDEVICE_H +#define WLINPUTDEVICE_H + +#include "waylandobject.h" +#include <QtCore/QList> + +namespace Wayland { + +class Compositor; +class DataDevice; +class Surface; +class DataDeviceManager; + +class InputDevice : public Object<struct wl_input_device> +{ +public: + InputDevice(Compositor *compositor); + + void clientRequestedDataDevice(DataDeviceManager *dndSelection, struct wl_client *client, uint32_t id); + DataDevice *dataDevice(struct wl_client *client) const; + + void sendSelectionFocus(Surface *surface); + + static void bind_func(struct wl_client *client, void *data, + uint32_t version, uint32_t id); + static void input_device_attach(struct wl_client *client, + struct wl_resource *device_base, + uint32_t time, + struct wl_resource *buffer, int32_t x, int32_t y); + const static struct wl_input_device_interface input_device_interface; + static void destroy_resource(struct wl_resource *resource); + +private: + QList<DataDevice *>m_data_devices; + +}; + +} + +#endif // WLINPUTDEVICE_H diff --git a/src/compositor/wayland_wrapper/wloutput.cpp b/src/compositor/wayland_wrapper/wloutput.cpp new file mode 100644 index 000000000..0f61bc051 --- /dev/null +++ b/src/compositor/wayland_wrapper/wloutput.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#include "wloutput.h" +#include <QGuiApplication> +#include <QtGui/QScreen> +#include <QRect> + +namespace Wayland { + +void Output::output_bind_func(struct wl_client *client, void *data, + uint32_t version, uint32_t id) +{ + Q_UNUSED(version); + Output *output = static_cast<Output *>(data); + + struct wl_resource *resource = wl_client_add_object(client,&wl_output_interface,0,id,data); + wl_resource_post_event(resource, WL_OUTPUT_GEOMETRY, 0, 0, + output->size().width(), output->size().height(),0,"",""); + + wl_resource_post_event(resource,WL_OUTPUT_MODE, WL_OUTPUT_MODE_CURRENT|WL_OUTPUT_MODE_PREFERRED, + output->size().width(),output->size().height()); +} + + +Output::Output() + : m_displayId(-1) + , m_numQueued(0) +{ + QScreen *screen = QGuiApplication::primaryScreen(); + m_geometry = QRect(QPoint(0, 0), screen->availableGeometry().size()); +} + +void Output::setGeometry(const QRect &geometry) +{ + m_geometry = geometry; +} + +} // namespace Wayland diff --git a/src/compositor/wayland_wrapper/wloutput.h b/src/compositor/wayland_wrapper/wloutput.h new file mode 100644 index 000000000..84c91a2f5 --- /dev/null +++ b/src/compositor/wayland_wrapper/wloutput.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#ifndef WL_OUTPUT_H +#define WL_OUTPUT_H + +#include "waylandobject.h" + +#include <QtCore/QRect> + +namespace Wayland { + +class Output : public Object<struct wl_object> +{ +public: + Output(); + + void setGeometry(const QRect &geometry); + + int x() const { return m_geometry.x(); } + int y() const { return m_geometry.y(); } + QSize size() const { return m_geometry.size(); } + + static void output_bind_func(struct wl_client *client, void *data, + uint32_t version, uint32_t id); +private: + QRect m_geometry; + int m_displayId; + int m_numQueued; +}; + + +} + +#endif //WL_OUTPUT_H diff --git a/src/compositor/wayland_wrapper/wlshell.cpp b/src/compositor/wayland_wrapper/wlshell.cpp new file mode 100644 index 000000000..e6ab73762 --- /dev/null +++ b/src/compositor/wayland_wrapper/wlshell.cpp @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#include "wlshell.h" + +#include "wlcompositor.h" + +#include "wlcompositor.h" + +#include <QtCore/qglobal.h> +#include <QtCore/QDebug> + +namespace Wayland { + +Shell::Shell(Compositor *compositor) +{ +} + +void Shell::bind_func(struct wl_client *client, void *data, + uint32_t version, uint32_t id) +{ + Q_UNUSED(version); + wl_client_add_object(client,&wl_shell_interface,&shell_interface,id,data); +} + +void Shell::shell_move(struct wl_client *client, + struct wl_resource *shell, + struct wl_resource *surface, + struct wl_resource *input_device, + uint32_t time) +{ + Q_UNUSED(client); + Q_UNUSED(shell); + Q_UNUSED(surface); + Q_UNUSED(input_device); + Q_UNUSED(time); + qDebug() << "shellMove"; +} + +void Shell::shell_resize(struct wl_client *client, + struct wl_resource *shell, + struct wl_resource *surface, + struct wl_resource *input_device, + uint32_t time, + uint32_t edges) +{ + Q_UNUSED(client); + Q_UNUSED(shell); + Q_UNUSED(surface); + Q_UNUSED(input_device); + Q_UNUSED(time); + Q_UNUSED(edges); + qDebug() << "shellResize"; +} + +void Shell::set_toplevel(struct wl_client *client, + struct wl_resource *wl_shell, + struct wl_resource *surface) +{ + Q_UNUSED(client); + Q_UNUSED(wl_shell); + Q_UNUSED(surface); +} + +void Shell::set_transient(struct wl_client *client, + struct wl_resource *wl_shell, + struct wl_resource *surface, + struct wl_resource *parent, + int x, + int y, + uint32_t flags) +{ + Q_UNUSED(client); + Q_UNUSED(wl_shell); + Q_UNUSED(surface); + Q_UNUSED(parent); + Q_UNUSED(x); + Q_UNUSED(y); + Q_UNUSED(flags); +} +void Shell::set_fullscreen(struct wl_client *client, + struct wl_resource *wl_shell, + struct wl_resource *surface) +{ + Q_UNUSED(client); + Q_UNUSED(wl_shell); + Q_UNUSED(surface); +} + +const struct wl_shell_interface Shell::shell_interface = { + shell_move, + shell_resize, + set_toplevel, + set_transient, + set_fullscreen +}; + +} diff --git a/src/compositor/wayland_wrapper/wlshell.h b/src/compositor/wayland_wrapper/wlshell.h new file mode 100644 index 000000000..a748186e8 --- /dev/null +++ b/src/compositor/wayland_wrapper/wlshell.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#ifndef WLSHELL_H +#define WLSHELL_H + +#include "waylandobject.h" + +namespace Wayland { + +class Compositor; + +class Shell : public Object<struct wl_object> +{ +public: + Shell(Compositor *compositor); + + static void bind_func(struct wl_client *client, void *data, + uint32_t version, uint32_t id); + static void shell_move(struct wl_client *client, + struct wl_resource *shell, + struct wl_resource *surface, + struct wl_resource *input_device, + uint32_t time); + static void shell_resize(struct wl_client *client, + struct wl_resource *shell, + struct wl_resource *surface, + struct wl_resource *input_device, + uint32_t time, + uint32_t edges); + static void set_toplevel(struct wl_client *client, + struct wl_resource *shell, + struct wl_resource *surface); + static void set_transient(struct wl_client *client, + struct wl_resource *shell, + struct wl_resource *surface, + struct wl_resource *parent, + int x, + int y, + uint32_t flags); + static void set_fullscreen(struct wl_client *client, + struct wl_resource *shell, + struct wl_resource *surface); + const static struct wl_shell_interface shell_interface; +}; + +} + +#endif // WLSHELL_H diff --git a/src/compositor/wayland_wrapper/wlshmbuffer.cpp b/src/compositor/wayland_wrapper/wlshmbuffer.cpp new file mode 100644 index 000000000..c5126aeaa --- /dev/null +++ b/src/compositor/wayland_wrapper/wlshmbuffer.cpp @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#include "wlshmbuffer.h" + +#include "wldisplay.h" +#include "wlcompositor.h" + +#include <QtCore/QDebug> + +#include <sys/mman.h> + +namespace Wayland { + +ShmBuffer::ShmBuffer(struct wl_buffer *buffer) + : m_buffer(buffer) +{ + m_buffer->user_data = this; + m_data = wl_shm_buffer_get_data(m_buffer); + m_stride = wl_shm_buffer_get_stride(m_buffer); + + damage(); +} + +ShmBuffer::~ShmBuffer() +{ +} + +QImage ShmBuffer::image() const +{ + return m_image; +} + +QSize ShmBuffer::size() const +{ + return QSize(m_buffer->width, m_buffer->height); +} + +void ShmBuffer::damage() +{ + QImage::Format imageFormat = QImage::Format_Invalid; + + imageFormat = QImage::Format_ARGB32_Premultiplied; + + m_image = QImage(static_cast<uchar *>(m_data),m_buffer->width, m_buffer->height,m_stride,imageFormat); + +} + +static ShmHandler *handlerInstance; + +ShmHandler::ShmHandler(Display *display) + : m_display(display) +{ + handlerInstance = this; + m_shm = wl_shm_init(m_display->handle(),&shm_callbacks); +} + +ShmHandler::~ShmHandler() +{ + wl_shm_finish(m_shm); +} + +struct wl_shm_callbacks ShmHandler::shm_callbacks = { + buffer_created_callback, + buffer_damaged_callback, + buffer_destroyed_callback +}; + +void ShmHandler::buffer_created_callback(struct wl_buffer *buffer) +{ + ShmBuffer *newBuffer = new ShmBuffer(buffer); + Q_UNUSED(newBuffer); +} + +void ShmHandler::buffer_damaged_callback(struct wl_buffer *buffer, + int32_t x, int32_t y, + int32_t width, int32_t height) +{ + Q_UNUSED(buffer); + Q_UNUSED(x); + Q_UNUSED(y); + Q_UNUSED(width); + Q_UNUSED(height); + //damage has the responsibillity to update the QImage + //for now we just recrate the entire QImage as we need a new + //hash key for texture uploads + static_cast<ShmBuffer *>(buffer->user_data)->damage(); +} + +void ShmHandler::buffer_destroyed_callback(struct wl_buffer *buffer) +{ + ShmBuffer *shmbuf = static_cast<ShmBuffer *>(buffer->user_data); + for (int i = 0; i < handlerInstance->m_extraCallbacks.count(); ++i) + handlerInstance->m_extraCallbacks.at(i)(shmbuf); + delete shmbuf; +} + +void ShmHandler::addDestroyCallback(DestroyCallback callback) +{ + if (!m_extraCallbacks.contains(callback)) + m_extraCallbacks.append(callback); +} + +} diff --git a/src/compositor/wayland_wrapper/wlshmbuffer.h b/src/compositor/wayland_wrapper/wlshmbuffer.h new file mode 100644 index 000000000..e8092ce2a --- /dev/null +++ b/src/compositor/wayland_wrapper/wlshmbuffer.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#ifndef WL_SHMBUFFER_H +#define WL_SHMBUFFER_H + +#include "waylandobject.h" + +#include <QtCore/QRect> +#include <QtGui/QImage> + + +namespace Wayland { + +class Surface; +class Display; + +class ShmBuffer +{ +public: + ShmBuffer(struct wl_buffer *buffer); + ~ShmBuffer(); + + QImage image() const; + QSize size() const; + + void damage(); + +private: + struct wl_buffer *m_buffer; + int m_stride; + void *m_data; + QImage m_image; +}; + +class ShmHandler +{ +public: + ShmHandler(Display *display); + ~ShmHandler(); + + typedef void (*DestroyCallback)(ShmBuffer *); + void addDestroyCallback(DestroyCallback callback); + +private: + Display *m_display; + struct wl_shm *m_shm; + + static struct wl_shm_callbacks shm_callbacks; + static void buffer_created_callback(struct wl_buffer *buffer); + static void buffer_damaged_callback(struct wl_buffer *buffer, + int32_t x, int32_t y, + int32_t width, int32_t height); + static void buffer_destroyed_callback(struct wl_buffer *buffer); + QList<DestroyCallback> m_extraCallbacks; +}; + +} + +#endif //WL_SHMBUFFER_H diff --git a/src/compositor/wayland_wrapper/wlsurface.cpp b/src/compositor/wayland_wrapper/wlsurface.cpp new file mode 100644 index 000000000..1edbeb7ea --- /dev/null +++ b/src/compositor/wayland_wrapper/wlsurface.cpp @@ -0,0 +1,510 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#include "wlsurface.h" + +#include "waylandsurface.h" + +#include "wlcompositor.h" +#include "wlshmbuffer.h" +#include "wlinputdevice.h" + +#include <QtCore/QDebug> + +#include <wayland-server.h> + +#ifdef Q_OS_LINUX +#include <linux/input.h> +#endif + +#ifdef QT_COMPOSITOR_WAYLAND_GL +#include "hardware_integration/graphicshardwareintegration.h" +#include <QtGui/QPlatformOpenGLContext> +#endif + +#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT +#include "waylandwindowmanagerintegration.h" +#endif + +namespace Wayland { + +const struct wl_surface_interface Surface::surface_interface = { + Surface::surface_destroy, + Surface::surface_attach, + Surface::surface_damage, + Surface::surface_frame +}; + +class SurfacePrivate +{ +public: + SurfacePrivate(struct wl_client *client, Compositor *compositor) + : client(client) + , compositor(compositor) + , textureCreatedForBuffer(false) + , directRenderBuffer(0) + , processId(0) + , previousBuffer(0) + , frame_callback(0) + , surfaceBuffer(0) + , surfaceType(WaylandSurface::Invalid) + + + { +#ifdef QT_COMPOSITOR_WAYLAND_GL + texture_id = 0; +#endif + } + + WaylandSurface::Type type() const { + if (surfaceType == WaylandSurface::Invalid) { + SurfacePrivate *that = const_cast<SurfacePrivate *>(this); + if (qtSurface->handle() == compositor->directRenderSurface()) { + that->surfaceType = WaylandSurface::Direct; + } else if (surfaceBuffer && wl_buffer_is_shm(surfaceBuffer)) { + that->surfaceType = WaylandSurface::Shm; + } else if (surfaceBuffer){ + that->surfaceType = WaylandSurface::Texture; + } + } + return surfaceType; + } + + void attach(struct wl_buffer *buffer) { + bool emitMap = !surfaceBuffer; + if (surfaceBuffer && ! textureCreatedForBuffer && surfaceBuffer != directRenderBuffer) { + qWarning() << "### WaylandSurface::attach() releasing undisplayed buffer ###"; + wl_resource_post_event(&surfaceBuffer->resource, WL_BUFFER_RELEASE); + } + surfaceBuffer = buffer; + surfaceType = WaylandSurface::Invalid; + textureCreatedForBuffer = false; + if (emitMap) { + qtSurface->mapped(QSize(surfaceBuffer->width,surfaceBuffer->height)); + } + } + + inline struct wl_buffer *buffer() const { return surfaceBuffer; } + + static void destroy_frame_callback(struct wl_resource *resource) + { + if (resource->data) + static_cast<SurfacePrivate *>(resource->data)->frame_callback = 0; + delete resource; + } + + struct wl_client *client; + Compositor *compositor; + WaylandSurface *qtSurface; + +#ifdef QT_COMPOSITOR_WAYLAND_GL + GLuint texture_id; +#endif + bool textureCreatedForBuffer; + struct wl_buffer *directRenderBuffer; + qint64 processId; + QByteArray authenticationToken; + QVariantMap windowProperties; + + QPoint lastMousePos; + + struct wl_buffer *previousBuffer; + struct wl_resource *frame_callback; +private: + struct wl_buffer *surfaceBuffer; + WaylandSurface::Type surfaceType; +}; + + +void Surface::surface_destroy(struct wl_client *client, struct wl_resource *surface_resource) +{ + Surface *surface = reinterpret_cast<Surface *>(surface_resource); + wl_resource_destroy(surface_resource,Compositor::currentTimeMsecs()); +} + +void Surface::surface_attach(struct wl_client *client, struct wl_resource *surface, + struct wl_resource *buffer, int x, int y) +{ + Q_UNUSED(client); + Q_UNUSED(x); + Q_UNUSED(y); + reinterpret_cast<Surface *>(surface)->attach(buffer); +} + +void Surface::surface_damage(struct wl_client *client, struct wl_resource *surface, + int32_t x, int32_t y, int32_t width, int32_t height) +{ + Q_UNUSED(client); + reinterpret_cast<Surface *>(surface)->damage(QRect(x, y, width, height)); +} +void Surface::surface_frame(struct wl_client *client, + struct wl_resource *resource, + uint32_t callback) +{ + Surface *surface = reinterpret_cast<Surface *>(resource); + SurfacePrivate *d = surface->d_func(); + d->frame_callback = new struct wl_resource; + d->frame_callback->client = client; + d->frame_callback->object.interface = &wl_callback_interface; + d->frame_callback->object.id = callback; + d->frame_callback->data = d; + d->frame_callback->destroy = SurfacePrivate::destroy_frame_callback; + + wl_client_add_resource(client, d->frame_callback); +} + +Surface::Surface(struct wl_client *client, Compositor *compositor) + : d_ptr(new SurfacePrivate(client,compositor)) +{ + base()->resource.client = client; + d_ptr->qtSurface = new WaylandSurface(this); +} + +Surface::~Surface() +{ + Q_D(Surface); + d->compositor->surfaceDestroyed(this); +#ifdef QT_COMPOSITOR_WAYLAND_GL + if (d->compositor->graphicsHWIntegration()) + glDeleteTextures(1,&d->texture_id); + +#endif + delete d->qtSurface; +} + +WaylandSurface::Type Surface::type() const +{ + Q_D(const Surface); + return d->type(); +} + +bool Surface::isYInverted() const +{ +#ifdef QT_COMPOSITOR_WAYLAND_GL + Q_D(const Surface); + + if (d->compositor->graphicsHWIntegration()) { + if (d->type() == WaylandSurface::Texture) { + //if (textureId()) { + return d->compositor->graphicsHWIntegration()->isYInverted(d->buffer()); + //} + } else if (d->type() == WaylandSurface::Direct) { + return d->compositor->graphicsHWIntegration()->isYInverted(d->buffer()); + } + } +#endif + //shm surfaces are not flipped (in our "world") + return false; +} + +void Surface::damage(const QRect &rect) +{ + Q_D(Surface); + +#ifdef QT_COMPOSITOR_WAYLAND_GL + if (d->compositor->graphicsHWIntegration() && d->type() == WaylandSurface::Direct) { + //should the texture be deleted here, or should we explicitly delete it + //when going into direct mode... + if (d->textureCreatedForBuffer) { + glDeleteTextures(1,&d->texture_id); + d->textureCreatedForBuffer = false; + } + if (d->previousBuffer) { //previousBuffer means previous buffer turned into texture + wl_resource_post_event(&d->previousBuffer->resource,WL_BUFFER_RELEASE); + d->previousBuffer = 0; + } + if (d->compositor->graphicsHWIntegration()->postBuffer(d->buffer())) { + d->directRenderBuffer = d->buffer(); + emit d->qtSurface->damaged(rect); + return; + } + } +#endif + d->directRenderBuffer = 0; + d->compositor->markSurfaceAsDirty(this); + + emit d->qtSurface->damaged(rect); +} + +QImage Surface::image() const +{ + Q_D(const Surface); + if (d->type() == WaylandSurface::Shm) { + ShmBuffer *shmBuffer = static_cast<ShmBuffer *>(d->buffer()->user_data); + return shmBuffer->image(); + } + return QImage(); +} + +#ifdef QT_COMPOSITOR_WAYLAND_GL +GLuint Surface::textureId(QOpenGLContext *context) const +{ + Q_D(const Surface); + if (d->compositor->graphicsHWIntegration() && d->type() == WaylandSurface::Texture + && !d->textureCreatedForBuffer) { + if (d->texture_id) + glDeleteTextures(1,&d->texture_id); + if (d->previousBuffer) { + wl_resource_post_event(&d->previousBuffer->resource,WL_BUFFER_RELEASE); + } + Surface *that = const_cast<Surface *>(this); + GraphicsHardwareIntegration *hwIntegration = d->compositor->graphicsHWIntegration(); + that->d_func()->previousBuffer = d->buffer(); + that->d_func()->texture_id = hwIntegration->createTextureFromBuffer(d->buffer(), context); + that->d_func()->textureCreatedForBuffer = true; + } + return d->texture_id; +} +#endif // QT_COMPOSITOR_WAYLAND_GL + +void Surface::attach(struct wl_resource *buffer) +{ + Q_D(Surface); + d->attach(reinterpret_cast<struct wl_buffer *>(buffer)); +} + +WaylandSurface * Surface::handle() const +{ + Q_D(const Surface); + return d->qtSurface; +} + +wl_client *Surface::clientHandle() const +{ + Q_D(const Surface); + return d->client; +} + +qint64 Surface::processId() const +{ + Q_D(const Surface); + return d->processId; +} + +void Surface::setProcessId(qint64 processId) +{ + Q_D(Surface); + d->processId = processId; +} + +QByteArray Surface::authenticationToken() const +{ + Q_D(const Surface); + return WindowManagerServerIntegration::instance()->managedClient(d->client)->authenticationToken(); +} + +QVariantMap Surface::windowProperties() const +{ + Q_D(const Surface); + return d->windowProperties; +} + +QVariant Surface::windowProperty(const QString &propertyName) const +{ + Q_D(const Surface); + QVariantMap props = d->windowProperties; + return props.value(propertyName); +} + +void Surface::setWindowProperty(const QString &name, const QVariant &value, bool writeUpdateToClient) +{ + Q_D(Surface); + d->windowProperties.insert(name, value); + if (writeUpdateToClient) + WindowManagerServerIntegration::instance()->setWindowProperty(d->client, base(), name, value); +} + +uint32_t toWaylandButton(Qt::MouseButton button) +{ +#ifndef BTN_LEFT +uint32_t BTN_LEFT = 0x110; +uint32_t BTN_RIGHT = 0x111; +uint32_t BTN_MIDDLE = 0x112; +#endif + switch (button) { + case Qt::LeftButton: + return BTN_LEFT; + case Qt::RightButton: + return BTN_RIGHT; + default: + return BTN_MIDDLE; + } + +} + +QPoint Surface::lastMousePos() const +{ + Q_D(const Surface); + return d->lastMousePos; +} + +void Surface::sendMousePressEvent(int x, int y, Qt::MouseButton button) +{ + Q_D(Surface); + sendMouseMoveEvent(x, y); + if (d->client) { + uint32_t time = d->compositor->currentTimeMsecs(); + struct wl_resource *pointer_focus_resource = d->compositor->defaultInputDevice()->base()->pointer_focus_resource; + if (pointer_focus_resource) { + wl_resource_post_event(d->compositor->defaultInputDevice()->base()->pointer_focus_resource, + WL_INPUT_DEVICE_BUTTON, time, toWaylandButton(button), 1); + } + } +} + +void Surface::sendMouseReleaseEvent(int x, int y, Qt::MouseButton button) +{ + Q_D(Surface); + sendMouseMoveEvent(x, y); + if (d->client) { + uint32_t time = d->compositor->currentTimeMsecs(); + struct wl_resource *pointer_focus_resource = d->compositor->defaultInputDevice()->base()->pointer_focus_resource; + if (pointer_focus_resource) { + wl_resource_post_event(pointer_focus_resource, + WL_INPUT_DEVICE_BUTTON, time, toWaylandButton(button), 0); + } + } +} + +void Surface::sendMouseMoveEvent(int x, int y) +{ + Q_D(Surface); + if (d->client) { + d->lastMousePos = QPoint(x, y); + uint32_t time = d->compositor->currentTimeMsecs(); + d->compositor->setPointerFocus(this, QPoint(x, y)); + struct wl_resource *pointer_focus_resource = d->compositor->defaultInputDevice()->base()->pointer_focus_resource; + if (pointer_focus_resource) { + wl_resource_post_event(pointer_focus_resource, + WL_INPUT_DEVICE_MOTION, time, x, y, x, y); + } + } +} + +void Surface::sendKeyPressEvent(uint code) +{ + Q_D(Surface); + if (d->compositor->defaultInputDevice()->base()->keyboard_focus_resource != NULL) { + uint32_t time = d->compositor->currentTimeMsecs(); + wl_resource_post_event(d->compositor->defaultInputDevice()->base()->keyboard_focus_resource, + WL_INPUT_DEVICE_KEY, time, code - 8, 1); + } +} + +void Surface::sendKeyReleaseEvent(uint code) +{ + Q_D(Surface); + if (d->compositor->defaultInputDevice()->base()->keyboard_focus_resource != NULL) { + uint32_t time = d->compositor->currentTimeMsecs(); + wl_resource_post_event(d->compositor->defaultInputDevice()->base()->keyboard_focus_resource, + WL_INPUT_DEVICE_KEY, time, code - 8, 0); + } +} + +void Surface::sendTouchPointEvent(int id, int x, int y, Qt::TouchPointState state) +{ + Q_D(Surface); + uint32_t time = d->compositor->currentTimeMsecs(); + struct wl_resource *resource = d->compositor->defaultInputDevice()->base()->pointer_focus_resource; + switch (state) { + case Qt::TouchPointPressed: + wl_resource_post_event(resource, WL_INPUT_DEVICE_TOUCH_DOWN, time, id, x, y); + break; + case Qt::TouchPointMoved: + wl_resource_post_event(resource, WL_INPUT_DEVICE_TOUCH_MOTION, time, id, x, y); + break; + case Qt::TouchPointReleased: + wl_resource_post_event(resource, WL_INPUT_DEVICE_TOUCH_UP, time, id); + break; + case Qt::TouchPointStationary: + // stationary points are not sent through wayland, the client must cache them + break; + default: + break; + } +} + +void Surface::sendTouchFrameEvent() +{ + Q_D(Surface); + struct wl_resource *resource = d->compositor->defaultInputDevice()->base()->pointer_focus_resource; + wl_resource_post_event(resource, + WL_INPUT_DEVICE_TOUCH_FRAME); +} + +void Surface::sendTouchCancelEvent() +{ + Q_D(Surface); + struct wl_resource *resource = d->compositor->defaultInputDevice()->base()->pointer_focus_resource; + wl_resource_post_event(resource, + WL_INPUT_DEVICE_TOUCH_CANCEL); +} + +void Surface::sendFrameCallback() +{ + Q_D(Surface); + if (d->frame_callback) { + wl_resource_post_event(d->frame_callback,WL_CALLBACK_DONE,Compositor::currentTimeMsecs()); + wl_resource_destroy(d->frame_callback,Compositor::currentTimeMsecs()); + } +} + +void Surface::frameFinished() +{ + Q_D(Surface); + d->compositor->frameFinished(this); +} + +void Surface::setInputFocus() +{ + Q_D(Surface); + d->compositor->setInputFocus(this); +} + +void Surface::sendOnScreenVisibilityChange(bool visible) +{ +#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT + Q_D(Surface); + WindowManagerServerIntegration::instance()->setVisibilityOnScreen(d->client, visible); +#endif +} + +} // namespace Wayland + diff --git a/src/compositor/wayland_wrapper/wlsurface.h b/src/compositor/wayland_wrapper/wlsurface.h new file mode 100644 index 000000000..4d037a26e --- /dev/null +++ b/src/compositor/wayland_wrapper/wlsurface.h @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** This file is part of QtCompositor** +** +** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** +** Contact: Nokia Corporation qt-info@nokia.com +** +** You may use this file under the terms of the BSD license as follows: +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#ifndef WL_SURFACE_H +#define WL_SURFACE_H + +#include "waylandobject.h" +#include "wlshmbuffer.h" +#include "waylandsurface.h" + +#include <QtCore/QRect> +#include <QtGui/QImage> + +#include <QtCore/QTextStream> +#include <QtCore/QMetaType> + +#ifdef QT_COMPOSITOR_WAYLAND_GL +#include <QtGui/QOpenGLContext> +#include <QtGui/qopengl.h> +#endif + +namespace Wayland { + +class Compositor; +class Buffer; + +class SurfacePrivate; + +class Surface : public Object<struct wl_surface> +{ + Q_DECLARE_PRIVATE(Surface) +public: + Surface(struct wl_client *client, Compositor *compositor); + ~Surface(); + + WaylandSurface::Type type() const; + bool isYInverted() const; + + uint id() const { return base()->resource.object.id; } + void attach(struct wl_resource *buffer); + + void damage(const QRect &rect); + + QImage image() const; + +#ifdef QT_COMPOSITOR_WAYLAND_GL + GLuint textureId(QOpenGLContext *context) const; +#endif + + void sendMousePressEvent(int x, int y, Qt::MouseButton button); + void sendMouseReleaseEvent(int x, int y, Qt::MouseButton button); + void sendMouseMoveEvent(int x, int y); + + void sendKeyPressEvent(uint code); + void sendKeyReleaseEvent(uint code); + + void sendTouchPointEvent(int id, int x, int y, Qt::TouchPointState state); + void sendTouchFrameEvent(); + void sendTouchCancelEvent(); + + void sendFrameCallback(); + + void frameFinished(); + void setInputFocus(); + + void sendOnScreenVisibilityChange(bool visible); + + WaylandSurface *handle() const; + wl_client *clientHandle() const; + qint64 processId() const; + void setProcessId(qint64 processId); + QByteArray authenticationToken() const; + void setAuthenticationToken(const QByteArray &authenticationToken); + + QVariantMap windowProperties() const; + QVariant windowProperty(const QString &propertyName) const; + void setWindowProperty(const QString &name, const QVariant &value, bool writeUpdateToClient = true); + + void setSurfaceCreationFinished(bool isCreated); + + QPoint lastMousePos() const; + + static const struct wl_surface_interface surface_interface; +protected: + QScopedPointer<SurfacePrivate> d_ptr; +private: + Q_DISABLE_COPY(Surface) + 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); + +}; + +} + +#endif //WL_SURFACE_H |