diff --git a/src/plugins/platforms/os2/CMakeLists.txt b/src/plugins/platforms/os2/CMakeLists.txt index 6aa1c91bb..4de610249 100644 --- a/src/plugins/platforms/os2/CMakeLists.txt +++ b/src/plugins/platforms/os2/CMakeLists.txt @@ -18,6 +18,7 @@ qt_internal_add_plugin(QOS2IntegrationPlugin qos2keymapper.cpp qos2mime.cpp qos2screen.cpp + qos2services.cpp qos2theme.cpp qos2window.cpp diff --git a/src/plugins/platforms/os2/os2.pro b/src/plugins/platforms/os2/os2.pro index ce1297215..3c15fb5cc 100644 --- a/src/plugins/platforms/os2/os2.pro +++ b/src/plugins/platforms/os2/os2.pro @@ -1,37 +1,39 @@ -TARGET = qos2 - -QT += \ - core-private gui-private \ - eventdispatcher_support-private fontdatabase_support-private - -SOURCES = \ - main.cpp \ - qos2backingstore.cpp \ - qos2clipboard.cpp \ - qos2context.cpp \ - qos2cursor.cpp \ - qos2integration.cpp \ - qos2keymapper.cpp \ - qos2mime.cpp \ - qos2screen.cpp \ - qos2theme.cpp \ - qos2window.cpp - -HEADERS = \ - qos2backingstore.h \ - qos2clipboard.h \ - qos2context.h \ - qos2cursor.h \ - qos2integration.h \ - qos2keymapper.h \ - qos2mime.h \ - qos2screen.h \ - qos2theme.h \ - qos2window.h - -OTHER_FILES += os2.json - -PLUGIN_TYPE = platforms -PLUGIN_CLASS_NAME = QOS2IntegrationPlugin -!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - -load(qt_plugin) +TARGET = qos2 + +QT += \ + core-private gui-private \ + eventdispatcher_support-private fontdatabase_support-private + +SOURCES = \ + main.cpp \ + qos2backingstore.cpp \ + qos2clipboard.cpp \ + qos2context.cpp \ + qos2cursor.cpp \ + qos2integration.cpp \ + qos2keymapper.cpp \ + qos2mime.cpp \ + qos2screen.cpp \ + qos2services.cpp \ + qos2theme.cpp \ + qos2window.cpp + +HEADERS = \ + qos2backingstore.h \ + qos2clipboard.h \ + qos2context.h \ + qos2cursor.h \ + qos2integration.h \ + qos2keymapper.h \ + qos2mime.h \ + qos2screen.h \ + qos2services.h \ + qos2theme.h \ + qos2window.h + +OTHER_FILES += os2.json + +PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QOS2IntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - +load(qt_plugin) diff --git a/src/plugins/platforms/os2/qos2integration.cpp b/src/plugins/platforms/os2/qos2integration.cpp index 1dd2754b2..f03fdf5c4 100644 --- a/src/plugins/platforms/os2/qos2integration.cpp +++ b/src/plugins/platforms/os2/qos2integration.cpp @@ -42,6 +42,7 @@ #include "qos2backingstore.h" #include "qos2keymapper.h" #include "qos2screen.h" +#include "qos2services.h" #include "qos2theme.h" #include "qos2window.h" @@ -89,6 +90,8 @@ QOS2Integration::QOS2Integration(const QStringList ¶mList) #endif mKeyMapper = new QOS2KeyMapper(); + + mplatformServices = new QOS2Services(); } QOS2Integration::~QOS2Integration() @@ -99,6 +102,7 @@ QOS2Integration::~QOS2Integration() delete mClipboard; #endif + delete mplatformServices; QWindowSystemInterface::handleScreenRemoved(mScreen); delete mFontDatabase; @@ -184,6 +188,11 @@ QList QOS2Integration::possibleKeys(const QKeyEvent *e) const return mKeyMapper->possibleKeys(e); } +QPlatformServices *QOS2Integration::services() const +{ + return mplatformServices; +} + void QOS2Integration::beep() const { WinAlarm(HWND_DESKTOP, WA_WARNING); // For QApplication diff --git a/src/plugins/platforms/os2/qos2integration.h b/src/plugins/platforms/os2/qos2integration.h index bc139c71e..91fe9ed60 100644 --- a/src/plugins/platforms/os2/qos2integration.h +++ b/src/plugins/platforms/os2/qos2integration.h @@ -46,6 +46,7 @@ QT_BEGIN_NAMESPACE class QOS2Clipboard; class QOS2KeyMapper; +class QOS2Services; class QOS2Integration : public QPlatformIntegration { @@ -73,12 +74,16 @@ class QOS2Integration : public QPlatformIntegration Qt::KeyboardModifiers queryKeyboardModifiers() const override; QList possibleKeys(const QKeyEvent *e) const override; + QPlatformServices *services() const override; + void beep() const override; // OS/2 specifics QOS2KeyMapper *keyMapper() const { return mKeyMapper; } + //QOS2Services *mplatformServices() const { return mplatformServices; } + static QOS2Integration *instance() { return sInstance; } private: @@ -90,6 +95,8 @@ class QOS2Integration : public QPlatformIntegration QOS2KeyMapper *mKeyMapper = nullptr; + QOS2Services *mplatformServices = nullptr; + static QOS2Integration * sInstance; }; diff --git a/src/plugins/platforms/os2/qos2services.cpp b/src/plugins/platforms/os2/qos2services.cpp new file mode 100644 index 000000000..486b4e7ed --- /dev/null +++ b/src/plugins/platforms/os2/qos2services.cpp @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and 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$ +** +****************************************************************************/ + +#define QT_NO_URL_CAST_FROM_STRING + +#include "qos2services.h" +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +static bool launch(const char* str, int type) +{ + CHAR DefaultExe[CCHMAXPATH] = {0}; + CHAR DefaultDir[CCHMAXPATH] = {0}; + CHAR DefaultParam[CCHMAXPATH] = {0}; + CHAR* p; + const QDir curdir = QDir::current(); + bool dirchanged = false; + QDir newdir = QDir::root(); + + // Browser or Mailto: link + if (type == 0 || type ==1) { + ulong size = sizeof(DefaultExe); + PrfQueryProfileData(HINI_USERPROFILE, "WPURLDEFAULTSETTINGS", + (type == 0 ? "DefaultBrowserExe" : "DefaultMailExe"), DefaultExe, &size); + if (!DefaultExe) { + if (type == 0) + qWarning("A default browser is not designated in WPURLDEFAULTSETTINGS->DefaultBrowserExe in OS2.INI"); + else if (type == 1) + qWarning("A default mail app is not designated in WPURLDEFAULTSETTINGS->DefaultMailExe in OS2.INI"); + return false; + } + size = sizeof(DefaultDir); + PrfQueryProfileData(HINI_USERPROFILE, "WPURLDEFAULTSETTINGS", + (type == 0 ? "DefaultWorkingDir" : "DefaultMailWorkingDir"), DefaultDir, &size); + // Set the directory + if (DefaultDir) { + QString dirstr = QString::fromLatin1(DefaultDir); + if (newdir.setCurrent(dirstr)) { + dirchanged = true; + } + else + qWarning("Cannot find the default working directory"); + } + // Mailto: + if (type == 1) { + size = sizeof(DefaultParam); + PrfQueryProfileData(HINI_USERPROFILE, "WPURLDEFAULTSETTINGS", + "DefaultMailParameters", DefaultParam, &size); + strcat(DefaultParam, " "); + strcat(DefaultParam, str); + } + } + //WinQueryObject doesn't work with forward slashes + if (strstr(str, "file:///")) { + strcpy((char*) str, str + 8); + p = (char*) str; + while (*p) { + if (*p == '/') + *p = '\\'; + p++; + } + } + //Executable file passed Not sure this happens + if (type == 3) { + p = strchr(str, ' '); + p++; + strcpy(DefaultParam, p); + p--; + *p = 0; + qWarning("exe %s param %s\n", str, DefaultParam); + } + //Filename passed + if (type == 2) { + HOBJECT hObject = WinQueryObject(str); + if (hObject != 0) + if (WinOpenObject(hObject, 0 /*OPEN_DEFAULT*/, TRUE)) + return true; + qWarning("WinOpenObject failed"); + } + else { + PID pid = 0; + ULONG ulSessID = 0; + CHAR achObjBuf[256] = {0}; + APIRET rc = NO_ERROR; + STARTDATA startData; + + memset(&startData, 0, sizeof(STARTDATA)); + startData.Length = sizeof(STARTDATA); + startData.Related = SSF_RELATED_INDEPENDENT; + startData.InheritOpt = SSF_INHERTOPT_PARENT; + startData.FgBg = SSF_FGBG_FORE; + startData.PgmControl = SSF_CONTROL_VISIBLE; + startData.TraceOpt = SSF_TRACEOPT_NONE; + startData.PgmTitle = NULL; + startData.PgmName = (type == 3 ? (PSZ) str : DefaultExe); + startData.TermQ = 0; + startData.Environment = NULL; + startData.PgmInputs = (type == 0 ? (PBYTE) str : DefaultParam); + startData.SessionType = SSF_TYPE_PM; + startData.ObjectBuffer = achObjBuf; + startData.ObjectBuffLen = (ULONG) sizeof(achObjBuf); + + rc = DosStartSession(&startData, &ulSessID, &pid); + + if (dirchanged) { + //Set the directory to root since we might have changed drives for the working directory + QString temp = newdir.current().absolutePath(); + + temp.truncate(3); + newdir.setCurrent(temp); + //Reset the current directory to the original + if (!newdir.setCurrent(curdir.absolutePath())) + qWarning("Reseting the current directory failed"); + } + if (!rc) { + return true; + } + else { + qWarning("DosStartSession err %i \n", (int) rc); + } + } + return false; +} + +bool QOS2Services::openUrl(const QUrl &url) +{ + int type = 0; + const QString scheme = url.scheme(); + if (scheme == u"mailto") + type = 1; + return launch((const char *) url.toString().toLatin1(), type); +} +bool QOS2Services::openDocument(const QUrl &url) +{ + int type = 2; + + QString suffix = url.toLocalFile(); + if (suffix.compare(u"exe", Qt::CaseInsensitive)) + type = 3; + return launch((const char *) url.toString().toLatin1(), type); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/os2/qos2services.h b/src/plugins/platforms/os2/qos2services.h new file mode 100644 index 000000000..1cac6c612 --- /dev/null +++ b/src/plugins/platforms/os2/qos2services.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and 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$ +** +****************************************************************************/ + +#ifndef QWINDOWSDESKTOPSERVICES_H +#define QWINDOWSDESKTOPSERVICES_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QOS2Services : public QPlatformServices +{ +public: + bool openUrl(const QUrl &url) override; + bool openDocument(const QUrl &url) override; +}; + +QT_END_NAMESPACE + +#endif // QWINDOWSDESKTOPSERVICES_H