/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qwineventnotifier_p.h"

#ifdef Q_OS_WINRT
#include "qeventdispatcher_winrt_p.h"
#else
#include "qeventdispatcher_win_p.h"
#endif
#include "qcoreapplication.h"

#include <private/qthread_p.h>

QT_BEGIN_NAMESPACE

/*!
    \class QWinEventNotifier
    \inmodule QtCore
    \since 5.0
    \brief The QWinEventNotifier class provides support for the Windows Wait functions.

    The QWinEventNotifier class makes it possible to use the wait
    functions on windows in a asynchronous manner. With this class,
    you can register a HANDLE to an event and get notification when
    that event becomes signalled. The state of the event is not modified
    in the process so if it is a manual reset event you will need to
    reset it after the notification.

    Once you have created a event object using Windows API such as
    CreateEvent() or OpenEvent(), you can create an event notifier to
    monitor the event handle. If the event notifier is enabled, it will
    emit the activated() signal whenever the corresponding event object
    is signalled.

    The setEnabled() function allows you to disable as well as enable the
    event notifier. It is generally advisable to explicitly enable or
    disable the event notifier. A disabled notifier does nothing when the
    event object is signalled (the same effect as not creating the
    event notifier).  Use the isEnabled() function to determine the
    notifier's current status.

    Finally, you can use the setHandle() function to register a new event
    object, and the handle() function to retrieve the event handle.

    \b{Further information:}
    Although the class is called QWinEventNotifier, it can be used for
    certain other objects which are so-called synchronization
    objects, such as Processes, Threads, Waitable timers.

    \warning This class is only available on Windows.
*/

/*!
    \fn void QWinEventNotifier::activated(HANDLE hEvent)

    This signal is emitted whenever the event notifier is enabled and
    the corresponding HANDLE is signalled.

    The state of the event is not modified in the process, so if it is a
    manual reset event, you will need to reset it after the notification.

    The object is passed in the \a hEvent parameter.

    \sa handle()
*/

/*!
    Constructs an event notifier with the given \a parent.
*/

QWinEventNotifier::QWinEventNotifier(QObject *parent)
  : QObject(*new QWinEventNotifierPrivate, parent)
{}

/*!
    Constructs an event notifier with the given \a parent. It enables
    the notifier, and watches for the event \a hEvent.

    The notifier is enabled by default, i.e. it emits the activated() signal
    whenever the corresponding event is signalled. However, it is generally
    advisable to explicitly enable or disable the event notifier.

    \sa setEnabled(), isEnabled()
*/

QWinEventNotifier::QWinEventNotifier(HANDLE hEvent, QObject *parent)
 : QObject(*new QWinEventNotifierPrivate(hEvent, false), parent)
{
    Q_D(QWinEventNotifier);
    QAbstractEventDispatcher *eventDispatcher = d->threadData->eventDispatcher.loadRelaxed();
    if (Q_UNLIKELY(!eventDispatcher)) {
        qWarning("QWinEventNotifier: Can only be used with threads started with QThread");
        return;
    }
    eventDispatcher->registerEventNotifier(this);
    d->enabled = true;
}

/*!
    Destroys this notifier.
*/

QWinEventNotifier::~QWinEventNotifier()
{
    setEnabled(false);
}

/*!
    Register the HANDLE \a hEvent. The old HANDLE will be automatically
    unregistered.

    \b Note: The notifier will be disabled as a side effect and needs
    to be re-enabled.

    \sa handle(), setEnabled()
*/

void QWinEventNotifier::setHandle(HANDLE hEvent)
{
    Q_D(QWinEventNotifier);
    setEnabled(false);
    d->handleToEvent = hEvent;
}

/*!
    Returns the HANDLE that has been registered in the notifier.

    \sa setHandle()
*/

HANDLE  QWinEventNotifier::handle() const
{
    Q_D(const QWinEventNotifier);
    return d->handleToEvent;
}

/*!
    Returns \c true if the notifier is enabled; otherwise returns \c false.

    \sa setEnabled()
*/

bool QWinEventNotifier::isEnabled() const
{
    Q_D(const QWinEventNotifier);
    return d->enabled;
}

/*!
    If \a enable is true, the notifier is enabled; otherwise the notifier
    is disabled.

    \sa isEnabled(), activated()
*/

void QWinEventNotifier::setEnabled(bool enable)
{
    Q_D(QWinEventNotifier);
    if (d->enabled == enable)                        // no change
        return;
    d->enabled = enable;

    QAbstractEventDispatcher *eventDispatcher = d->threadData->eventDispatcher.loadRelaxed();
    if (!eventDispatcher) { // perhaps application is shutting down
        if (!enable && d->waitHandle != nullptr)
            d->unregisterWaitObject();
        return;
    }
    if (Q_UNLIKELY(thread() != QThread::currentThread())) {
        qWarning("QWinEventNotifier: Event notifiers cannot be enabled or disabled from another thread");
        return;
    }

    if (enable) {
        d->signaledCount = 0;
        eventDispatcher->registerEventNotifier(this);
    } else {
        eventDispatcher->unregisterEventNotifier(this);
    }
}

/*!
    \reimp
*/

bool QWinEventNotifier::event(QEvent * e)
{
    Q_D(QWinEventNotifier);
    if (e->type() == QEvent::ThreadChange) {
        if (d->enabled) {
            QMetaObject::invokeMethod(this, "setEnabled", Qt::QueuedConnection,
                                      Q_ARG(bool, true));
            setEnabled(false);
        }
    }
    QObject::event(e);                        // will activate filters
    if (e->type() == QEvent::WinEventAct) {
        emit activated(d->handleToEvent, QPrivateSignal());
        return true;
    }
    return false;
}

#if defined(Q_OS_WINRT)

bool QWinEventNotifierPrivate::registerWaitObject()
{
    Q_UNIMPLEMENTED();
    return false;
}

void QWinEventNotifierPrivate::unregisterWaitObject()
{
    Q_UNIMPLEMENTED();
}

#else // defined(Q_OS_WINRT)

static void CALLBACK wfsoCallback(void *context, BOOLEAN /*ignore*/)
{
    QWinEventNotifierPrivate *nd = reinterpret_cast<QWinEventNotifierPrivate *>(context);
    QAbstractEventDispatcher *eventDispatcher = nd->threadData->eventDispatcher.loadRelaxed();

    // Happens when Q(Core)Application is destroyed before QWinEventNotifier.
    // https://bugreports.qt.io/browse/QTBUG-70214
    if (!eventDispatcher) { // perhaps application is shutting down
        qWarning("QWinEventNotifier: no event dispatcher, application shutting down? Cannot deliver event.");
        return;
    }

    QEventDispatcherWin32Private *edp = QEventDispatcherWin32Private::get(
                static_cast<QEventDispatcherWin32 *>(eventDispatcher));
    ++nd->signaledCount;
    SetEvent(edp->winEventNotifierActivatedEvent);
}

bool QWinEventNotifierPrivate::registerWaitObject()
{
    if (RegisterWaitForSingleObject(&waitHandle, handleToEvent, wfsoCallback, this,
                                    INFINITE, WT_EXECUTEONLYONCE) == 0) {
        qErrnoWarning("QWinEventNotifier: RegisterWaitForSingleObject failed.");
        return false;
    }
    return true;
}

void QWinEventNotifierPrivate::unregisterWaitObject()
{
    // Unregister the wait handle and wait for pending callbacks to finish.
    if (UnregisterWaitEx(waitHandle, INVALID_HANDLE_VALUE))
        waitHandle = NULL;
    else
        qErrnoWarning("QWinEventNotifier: UnregisterWaitEx failed.");
}

#endif // !defined(Q_OS_WINRT)

QT_END_NAMESPACE
