mirror of
https://github.com/yann64/haikuports.git
synced 2026-05-03 13:38:52 +02:00
4724 lines
135 KiB
Plaintext
4724 lines
135 KiB
Plaintext
From 22c5f614912e3254ee9fb8b4d1eb6ef5de97f2f3 Mon Sep 17 00:00:00 2001
|
|
From: Gerasim Troeglazov <3dEyes@gmail.com>
|
|
Date: Wed, 4 Mar 2020 20:20:54 +1000
|
|
Subject: Add Haiku support
|
|
|
|
|
|
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
|
index d427ad0..73ef023 100644
|
|
--- a/CMakeLists.txt
|
|
+++ b/CMakeLists.txt
|
|
@@ -10,16 +10,17 @@ cmake_policy(SET CMP0091 NEW)
|
|
|
|
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
|
|
|
-include(cmake/validate_special_target.cmake)
|
|
-include(cmake/version.cmake)
|
|
-desktop_app_parse_version(Telegram/build/version)
|
|
-
|
|
project(Telegram
|
|
LANGUAGES C CXX
|
|
VERSION ${desktop_app_version_cmake}
|
|
DESCRIPTION "Official Telegram Desktop messenger"
|
|
HOMEPAGE_URL "https://desktop.telegram.org"
|
|
)
|
|
+
|
|
+include(cmake/validate_special_target.cmake)
|
|
+include(cmake/version.cmake)
|
|
+desktop_app_parse_version(Telegram/build/version)
|
|
+
|
|
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT Telegram)
|
|
|
|
include(cmake/variables.cmake)
|
|
@@ -31,7 +32,7 @@ include(cmake/generate_target.cmake)
|
|
|
|
include(cmake/options.cmake)
|
|
|
|
-include(cmake/external/qt/package.cmake)
|
|
+include(cmake/external.cmake)
|
|
|
|
add_subdirectory(cmake)
|
|
add_subdirectory(Telegram)
|
|
diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt
|
|
index a760408..6dd7fb9 100644
|
|
--- a/Telegram/CMakeLists.txt
|
|
+++ b/Telegram/CMakeLists.txt
|
|
@@ -96,7 +96,7 @@ PRIVATE
|
|
desktop-app::external_zlib
|
|
desktop-app::external_qt
|
|
desktop-app::external_qr_code_generator
|
|
- desktop-app::external_crash_reports
|
|
+# desktop-app::external_crash_reports
|
|
desktop-app::external_auto_updates
|
|
tdesktop::lib_tgvoip
|
|
desktop-app::external_openssl
|
|
@@ -799,6 +799,18 @@ PRIVATE
|
|
platform/win/windows_event_filter.cpp
|
|
platform/win/windows_event_filter.h
|
|
platform/win/wrapper_wrl_implements_h.h
|
|
+ platform/haiku/file_utilities_haiku.cpp
|
|
+ platform/haiku/file_utilities_haiku.h
|
|
+ platform/haiku/haiku_desktop_environment.cpp
|
|
+ platform/haiku/haiku_desktop_environment.h
|
|
+ platform/haiku/launcher_haiku.cpp
|
|
+ platform/haiku/launcher_haiku.h
|
|
+ platform/haiku/main_window_haiku.cpp
|
|
+ platform/haiku/main_window_haiku.h
|
|
+ platform/haiku/notifications_manager_haiku.cpp
|
|
+ platform/haiku/notifications_manager_haiku.h
|
|
+ platform/haiku/specific_haiku.cpp
|
|
+ platform/haiku/specific_haiku.h
|
|
platform/platform_audio.h
|
|
platform/platform_file_utilities.h
|
|
platform/platform_launcher.h
|
|
@@ -1165,7 +1177,7 @@ endif()
|
|
|
|
set_target_properties(Telegram PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${output_folder})
|
|
|
|
-if ((NOT disable_autoupdate OR NOT LINUX) AND NOT build_macstore AND NOT build_winstore)
|
|
+if ((NOT disable_autoupdate OR NOT LINUX OR NOT HAIKU) AND NOT build_macstore AND NOT build_winstore)
|
|
add_executable(Updater WIN32)
|
|
init_target(Updater)
|
|
|
|
diff --git a/Telegram/SourceFiles/calls/calls_call.cpp b/Telegram/SourceFiles/calls/calls_call.cpp
|
|
index bf57bdc..ae79d2f 100644
|
|
--- a/Telegram/SourceFiles/calls/calls_call.cpp
|
|
+++ b/Telegram/SourceFiles/calls/calls_call.cpp
|
|
@@ -5,6 +5,7 @@ the official desktop application for the Telegram messaging service.
|
|
For license and copyright information please follow this link:
|
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
*/
|
|
+
|
|
#include "calls/calls_call.h"
|
|
|
|
#include "main/main_session.h"
|
|
@@ -27,6 +28,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
#define NEED_TO_RESTORE_SLOTS
|
|
#endif // slots
|
|
|
|
+// Don't include SupportDefs.h
|
|
+#ifdef __HAIKU__
|
|
+#define _SUPPORT_DEFS_H
|
|
+typedef int32 status_t;
|
|
+typedef uint32 type_code;
|
|
+#endif
|
|
+
|
|
#include <VoIPController.h>
|
|
#include <VoIPServerConfig.h>
|
|
|
|
diff --git a/Telegram/SourceFiles/core/update_checker.cpp b/Telegram/SourceFiles/core/update_checker.cpp
|
|
index 160571e..842ac9b 100644
|
|
--- a/Telegram/SourceFiles/core/update_checker.cpp
|
|
+++ b/Telegram/SourceFiles/core/update_checker.cpp
|
|
@@ -1512,6 +1512,9 @@ bool checkReadyUpdate() {
|
|
#elif defined Q_OS_LINUX // Q_OS_MAC
|
|
QString curUpdater = (cExeDir() + qsl("Updater"));
|
|
QFileInfo updater(cWorkingDir() + qsl("tupdates/temp/Updater"));
|
|
+#elif defined Q_OS_HAIKU // Q_OS_MAC || Q_OS_WIN
|
|
+ QString curUpdater = (cExeDir() + qsl("Updater"));
|
|
+ QFileInfo updater(cWorkingDir() + qsl("tupdates/temp/Updater"));
|
|
#endif // Q_OS_LINUX
|
|
if (!updater.exists()) {
|
|
QFileInfo current(curUpdater);
|
|
diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp
|
|
index 7fa9f0a..59b9bde 100644
|
|
--- a/Telegram/SourceFiles/data/data_session.cpp
|
|
+++ b/Telegram/SourceFiles/data/data_session.cpp
|
|
@@ -200,7 +200,7 @@ Session::Session(not_null<Main::Session*> session)
|
|
_cache->open(Local::cacheKey());
|
|
_bigFileCache->open(Local::cacheBigFileKey());
|
|
|
|
- if constexpr (Platform::IsLinux()) {
|
|
+ if constexpr (Platform::IsLinux() || Platform::IsHaiku()) {
|
|
const auto wasVersion = Local::oldMapVersion();
|
|
if (wasVersion >= 1007011 && wasVersion < 1007015) {
|
|
_bigFileCache->clear();
|
|
diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp
|
|
index 6df70cd..6c9727c 100644
|
|
--- a/Telegram/SourceFiles/mainwindow.cpp
|
|
+++ b/Telegram/SourceFiles/mainwindow.cpp
|
|
@@ -142,7 +142,7 @@ void MainWindow::createTrayIconMenu() {
|
|
? tr::lng_disable_notifications_from_tray(tr::now)
|
|
: tr::lng_enable_notifications_from_tray(tr::now);
|
|
|
|
- if (Platform::IsLinux()) {
|
|
+ if (Platform::IsLinux() || Platform::IsHaiku()) {
|
|
trayIconMenu->addAction(tr::lng_open_from_tray(tr::now), this, SLOT(showFromTray()));
|
|
}
|
|
trayIconMenu->addAction(tr::lng_minimize_to_tray(tr::now), this, SLOT(minimizeToTray()));
|
|
@@ -593,7 +593,7 @@ void MainWindow::updateTrayMenu(bool force) {
|
|
if (!trayIconMenu || (Platform::IsWindows() && !force)) return;
|
|
|
|
auto actions = trayIconMenu->actions();
|
|
- if (Platform::IsLinux()) {
|
|
+ if (Platform::IsLinux() || Platform::IsHaiku()) {
|
|
auto minimizeAction = actions.at(1);
|
|
minimizeAction->setEnabled(isVisible());
|
|
} else {
|
|
@@ -607,7 +607,7 @@ void MainWindow::updateTrayMenu(bool force) {
|
|
? tr::lng_minimize_to_tray(tr::now)
|
|
: tr::lng_open_from_tray(tr::now));
|
|
}
|
|
- auto notificationAction = actions.at(Platform::IsLinux() ? 2 : 1);
|
|
+ auto notificationAction = actions.at(Platform::IsLinux() || Platform::IsHaiku() ? 2 : 1);
|
|
auto notificationActionText = Global::DesktopNotify()
|
|
? tr::lng_disable_notifications_from_tray(tr::now)
|
|
: tr::lng_enable_notifications_from_tray(tr::now);
|
|
diff --git a/Telegram/SourceFiles/media/audio/media_audio.cpp b/Telegram/SourceFiles/media/audio/media_audio.cpp
|
|
index c1234c4..4a4f89f 100644
|
|
--- a/Telegram/SourceFiles/media/audio/media_audio.cpp
|
|
+++ b/Telegram/SourceFiles/media/audio/media_audio.cpp
|
|
@@ -83,6 +83,7 @@ bool PlaybackErrorHappened() {
|
|
void EnumeratePlaybackDevices() {
|
|
auto deviceNames = QStringList();
|
|
auto devices = alcGetString(nullptr, ALC_DEVICE_SPECIFIER);
|
|
+#ifndef __HAIKU__
|
|
Assert(devices != nullptr);
|
|
while (*devices != 0) {
|
|
auto deviceName8Bit = QByteArray(devices);
|
|
@@ -91,7 +92,7 @@ void EnumeratePlaybackDevices() {
|
|
devices += deviceName8Bit.size() + 1;
|
|
}
|
|
LOG(("Audio Playback Devices: %1").arg(deviceNames.join(';')));
|
|
-
|
|
+#endif
|
|
if (auto device = alcGetString(nullptr, ALC_DEFAULT_DEVICE_SPECIFIER)) {
|
|
LOG(("Audio Playback Default Device: %1").arg(QString::fromLocal8Bit(device)));
|
|
} else {
|
|
diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp
|
|
index df5e243..f825716 100644
|
|
--- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp
|
|
+++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp
|
|
@@ -363,7 +363,7 @@ OverlayWidget::OverlayWidget()
|
|
|
|
hide();
|
|
createWinId();
|
|
- if (Platform::IsLinux()) {
|
|
+ if (Platform::IsLinux() || Platform::IsHaiku()) {
|
|
windowHandle()->setTransientParent(App::wnd()->windowHandle());
|
|
setWindowModality(Qt::WindowModal);
|
|
}
|
|
diff --git a/Telegram/SourceFiles/platform/haiku/file_utilities_haiku.cpp b/Telegram/SourceFiles/platform/haiku/file_utilities_haiku.cpp
|
|
new file mode 100644
|
|
index 0000000..6b37269
|
|
--- /dev/null
|
|
+++ b/Telegram/SourceFiles/platform/haiku/file_utilities_haiku.cpp
|
|
@@ -0,0 +1,131 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2019 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#include "platform/haiku/file_utilities_haiku.h"
|
|
+
|
|
+#include "core/application.h"
|
|
+#include "mainwindow.h"
|
|
+#include "boxes/abstract_box.h"
|
|
+#include "storage/localstorage.h"
|
|
+#include "facades.h"
|
|
+
|
|
+#include <QtCore/QProcess>
|
|
+
|
|
+namespace Platform {
|
|
+namespace File {
|
|
+namespace internal {
|
|
+
|
|
+QByteArray EscapeShell(const QByteArray &content) {
|
|
+ auto result = QByteArray();
|
|
+
|
|
+ auto b = content.constData(), e = content.constEnd();
|
|
+ for (auto ch = b; ch != e; ++ch) {
|
|
+ if (*ch == ' ' || *ch == '"' || *ch == '\'' || *ch == '\\') {
|
|
+ if (result.isEmpty()) {
|
|
+ result.reserve(content.size() * 2);
|
|
+ }
|
|
+ if (ch > b) {
|
|
+ result.append(b, ch - b);
|
|
+ }
|
|
+ result.append('\\');
|
|
+ b = ch;
|
|
+ }
|
|
+ }
|
|
+ if (result.isEmpty()) {
|
|
+ return content;
|
|
+ }
|
|
+
|
|
+ if (e > b) {
|
|
+ result.append(b, e - b);
|
|
+ }
|
|
+ return result;
|
|
+}
|
|
+
|
|
+} // namespace internal
|
|
+
|
|
+void UnsafeShowInFolder(const QString &filepath) {
|
|
+ Ui::hideLayer(anim::type::instant); // Hide mediaview to make other apps visible.
|
|
+ auto absolutePath = QFileInfo(filepath).absoluteFilePath();
|
|
+ QProcess process;
|
|
+ auto command = qsl("open");
|
|
+ auto arguments = QStringList();
|
|
+ arguments << QFileInfo(filepath).absoluteDir().absolutePath();
|
|
+
|
|
+ if (!process.startDetached(command, arguments)) {
|
|
+ LOG(("Failed to launch '%1 %2'").arg(command).arg(arguments.join(' ')));
|
|
+ }
|
|
+}
|
|
+
|
|
+bool UnsafeShowOpenWith(const QString &filepath) {
|
|
+ auto absolutePath = QFileInfo(filepath).absoluteFilePath();
|
|
+
|
|
+ QProcess process;
|
|
+ auto command = qsl("open");
|
|
+ auto arguments = QStringList();
|
|
+ arguments << absolutePath;
|
|
+
|
|
+ if (!process.startDetached(command, arguments)) {
|
|
+ LOG(("Failed to launch '%1 %2'").arg(command).arg(arguments.join(' ')));
|
|
+ return false;
|
|
+ }
|
|
+ return true;
|
|
+}
|
|
+
|
|
+} // namespace File
|
|
+
|
|
+namespace FileDialog {
|
|
+namespace {
|
|
+
|
|
+using Type = ::FileDialog::internal::Type;
|
|
+
|
|
+bool NativeSupported() {
|
|
+ return false;
|
|
+}
|
|
+
|
|
+bool PreviewSupported() {
|
|
+ return false;
|
|
+}
|
|
+
|
|
+
|
|
+
|
|
+} // namespace
|
|
+
|
|
+bool Get(QPointer<QWidget> parent, QStringList &files, QByteArray &remoteContent, const QString &caption, \
|
|
+ const QString &filter, Type type, QString startFile) {
|
|
+ return ::FileDialog::internal::GetDefault(parent, files, remoteContent, caption, filter, type, startFile);
|
|
+}
|
|
+
|
|
+namespace internal {
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+namespace {
|
|
+
|
|
+const char *filterRegExp =
|
|
+"^(.*)\\(([a-zA-Z0-9_.,*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$";
|
|
+
|
|
+// Makes a list of filters from a normal filter string "Image Files (*.png *.jpg)"
|
|
+QStringList cleanFilterList(const QString &filter) {
|
|
+ QRegExp regexp(QString::fromLatin1(filterRegExp));
|
|
+ Q_ASSERT(regexp.isValid());
|
|
+ QString f = filter;
|
|
+ int i = regexp.indexIn(f);
|
|
+ if (i >= 0)
|
|
+ f = regexp.cap(2);
|
|
+ return f.split(QLatin1Char(' '), QString::SkipEmptyParts);
|
|
+}
|
|
+
|
|
+} // namespace
|
|
+
|
|
+
|
|
+
|
|
+} // namespace internal
|
|
+} // namespace FileDialog
|
|
+} // namespace Platform
|
|
diff --git a/Telegram/SourceFiles/platform/haiku/file_utilities_haiku.h b/Telegram/SourceFiles/platform/haiku/file_utilities_haiku.h
|
|
new file mode 100644
|
|
index 0000000..7f186eb
|
|
--- /dev/null
|
|
+++ b/Telegram/SourceFiles/platform/haiku/file_utilities_haiku.h
|
|
@@ -0,0 +1,60 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2019 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include "platform/platform_file_utilities.h"
|
|
+
|
|
+extern "C" {
|
|
+#undef signals
|
|
+#define signals public
|
|
+} // extern "C"
|
|
+
|
|
+namespace Platform {
|
|
+namespace File {
|
|
+namespace internal {
|
|
+
|
|
+QByteArray EscapeShell(const QByteArray &content);
|
|
+
|
|
+} // namespace internal
|
|
+
|
|
+inline QString UrlToLocal(const QUrl &url) {
|
|
+ return ::File::internal::UrlToLocalDefault(url);
|
|
+}
|
|
+
|
|
+inline void UnsafeOpenEmailLink(const QString &email) {
|
|
+ return ::File::internal::UnsafeOpenEmailLinkDefault(email);
|
|
+}
|
|
+
|
|
+inline bool UnsafeShowOpenWithDropdown(const QString &filepath, QPoint menuPosition) {
|
|
+ return false;
|
|
+}
|
|
+
|
|
+inline void UnsafeLaunch(const QString &filepath) {
|
|
+ return ::File::internal::UnsafeLaunchDefault(filepath);
|
|
+}
|
|
+
|
|
+inline void PostprocessDownloaded(const QString &filepath) {
|
|
+}
|
|
+
|
|
+} // namespace File
|
|
+
|
|
+namespace FileDialog {
|
|
+
|
|
+inline void InitLastPath() {
|
|
+ ::FileDialog::internal::InitLastPathDefault();
|
|
+}
|
|
+
|
|
+namespace internal {
|
|
+
|
|
+
|
|
+
|
|
+} // namespace internal
|
|
+} // namespace FileDialog
|
|
+} // namespace Platform
|
|
diff --git a/Telegram/SourceFiles/platform/haiku/haiku_desktop_environment.cpp b/Telegram/SourceFiles/platform/haiku/haiku_desktop_environment.cpp
|
|
new file mode 100644
|
|
index 0000000..a26d082
|
|
--- /dev/null
|
|
+++ b/Telegram/SourceFiles/platform/haiku/haiku_desktop_environment.cpp
|
|
@@ -0,0 +1,60 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2019 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#include "platform/haiku/haiku_desktop_environment.h"
|
|
+
|
|
+namespace Platform {
|
|
+namespace DesktopEnvironment {
|
|
+namespace {
|
|
+
|
|
+QString GetEnv(const char *name) {
|
|
+ auto result = getenv(name);
|
|
+ auto value = result ? QString::fromLatin1(result) : QString();
|
|
+ LOG(("Getting DE, %1: '%2'").arg(name).arg(value));
|
|
+ return value;
|
|
+}
|
|
+
|
|
+Type Compute() {
|
|
+ return Type::Other;
|
|
+}
|
|
+
|
|
+Type ComputeAndLog() {
|
|
+ auto result = Compute();
|
|
+ auto name = [result]() -> QString {
|
|
+ switch (result) {
|
|
+ case Type::Other: return "Other";
|
|
+ }
|
|
+ return QString::number(static_cast<int>(result));
|
|
+ };
|
|
+ LOG(("DE: %1").arg(name()));
|
|
+ return result;
|
|
+}
|
|
+
|
|
+} // namespace
|
|
+
|
|
+// Thanks Chromium.
|
|
+Type Get() {
|
|
+ static const auto result = ComputeAndLog();
|
|
+ return result;
|
|
+}
|
|
+
|
|
+bool TryQtTrayIcon() {
|
|
+ return true;
|
|
+}
|
|
+
|
|
+bool PreferAppIndicatorTrayIcon() {
|
|
+ return false;
|
|
+}
|
|
+
|
|
+bool TryUnityCounter() {
|
|
+ return false;
|
|
+}
|
|
+
|
|
+} // namespace DesktopEnvironment
|
|
+} // namespace Platform
|
|
diff --git a/Telegram/SourceFiles/platform/haiku/haiku_desktop_environment.h b/Telegram/SourceFiles/platform/haiku/haiku_desktop_environment.h
|
|
new file mode 100644
|
|
index 0000000..388d3e1
|
|
--- /dev/null
|
|
+++ b/Telegram/SourceFiles/platform/haiku/haiku_desktop_environment.h
|
|
@@ -0,0 +1,26 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2019 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#pragma once
|
|
+
|
|
+namespace Platform {
|
|
+namespace DesktopEnvironment {
|
|
+
|
|
+enum class Type {
|
|
+ Other
|
|
+};
|
|
+
|
|
+Type Get();
|
|
+
|
|
+bool TryQtTrayIcon();
|
|
+bool PreferAppIndicatorTrayIcon();
|
|
+bool TryUnityCounter();
|
|
+
|
|
+} // namespace DesktopEnvironment
|
|
+} // namespace Platform
|
|
diff --git a/Telegram/SourceFiles/platform/haiku/info_haiku.cpp b/Telegram/SourceFiles/platform/haiku/info_haiku.cpp
|
|
new file mode 100644
|
|
index 0000000..5f5bfe5
|
|
--- /dev/null
|
|
+++ b/Telegram/SourceFiles/platform/haiku/info_haiku.cpp
|
|
@@ -0,0 +1,42 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2019 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#include "platform/haiku/info_haiku.h"
|
|
+
|
|
+namespace Platform {
|
|
+
|
|
+QString DeviceModelPretty() {
|
|
+ return "PC";
|
|
+}
|
|
+
|
|
+QString SystemVersionPretty() {
|
|
+ return "Haiku";
|
|
+}
|
|
+
|
|
+QString SystemCountry() {
|
|
+ return QString();
|
|
+}
|
|
+
|
|
+QString SystemLanguage() {
|
|
+ return QString();
|
|
+}
|
|
+
|
|
+QDate WhenSystemBecomesOutdated() {
|
|
+ return QDate();
|
|
+}
|
|
+
|
|
+int AutoUpdateVersion() {
|
|
+ return 2;
|
|
+}
|
|
+
|
|
+QString AutoUpdateKey() {
|
|
+ return "haiku";
|
|
+}
|
|
+
|
|
+} // namespace Platform
|
|
diff --git a/Telegram/SourceFiles/platform/haiku/info_haiku.h b/Telegram/SourceFiles/platform/haiku/info_haiku.h
|
|
new file mode 100644
|
|
index 0000000..fad7c7c
|
|
--- /dev/null
|
|
+++ b/Telegram/SourceFiles/platform/haiku/info_haiku.h
|
|
@@ -0,0 +1,44 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2019 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include "platform/platform_info.h"
|
|
+
|
|
+namespace Platform {
|
|
+
|
|
+inline constexpr bool IsHaiku() {
|
|
+ return true;
|
|
+}
|
|
+
|
|
+inline constexpr bool IsWindows() { return false; }
|
|
+inline constexpr bool IsWindowsStoreBuild() { return false; }
|
|
+inline bool IsWindowsXPOrGreater() { return false; }
|
|
+inline bool IsWindowsVistaOrGreater() { return false; }
|
|
+inline bool IsWindows7OrGreater() { return false; }
|
|
+inline bool IsWindows8OrGreater() { return false; }
|
|
+inline bool IsWindows8Point1OrGreater() { return false; }
|
|
+inline bool IsWindows10OrGreater() { return false; }
|
|
+inline constexpr bool IsMac() { return false; }
|
|
+inline constexpr bool IsMacOldBuild() { return false; }
|
|
+inline constexpr bool IsMacStoreBuild() { return false; }
|
|
+inline bool IsMac10_6OrGreater() { return false; }
|
|
+inline bool IsMac10_7OrGreater() { return false; }
|
|
+inline bool IsMac10_8OrGreater() { return false; }
|
|
+inline bool IsMac10_9OrGreater() { return false; }
|
|
+inline bool IsMac10_10OrGreater() { return false; }
|
|
+inline bool IsMac10_11OrGreater() { return false; }
|
|
+inline bool IsMac10_12OrGreater() { return false; }
|
|
+inline bool IsMac10_13OrGreater() { return false; }
|
|
+inline bool IsMac10_14OrGreater() { return false; }
|
|
+inline constexpr bool IsLinux() { return false; }
|
|
+inline constexpr bool IsLinux32Bit() { return false; }
|
|
+inline constexpr bool IsLinux64Bit() { return false; }
|
|
+
|
|
+} // namespace Platform
|
|
diff --git a/Telegram/SourceFiles/platform/haiku/launcher_haiku.cpp b/Telegram/SourceFiles/platform/haiku/launcher_haiku.cpp
|
|
new file mode 100644
|
|
index 0000000..0b5e892
|
|
--- /dev/null
|
|
+++ b/Telegram/SourceFiles/platform/haiku/launcher_haiku.cpp
|
|
@@ -0,0 +1,61 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2019 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#include "platform/haiku/launcher_haiku.h"
|
|
+
|
|
+#include "core/crash_reports.h"
|
|
+
|
|
+#include <sys/stat.h>
|
|
+#include <sys/types.h>
|
|
+#include <cstdlib>
|
|
+#include <unistd.h>
|
|
+#include <dirent.h>
|
|
+#include <pwd.h>
|
|
+
|
|
+namespace Platform {
|
|
+namespace {
|
|
+
|
|
+class Arguments {
|
|
+public:
|
|
+ void push(QByteArray argument) {
|
|
+ argument.append(char(0));
|
|
+ _argumentValues.push_back(argument);
|
|
+ _arguments.push_back(_argumentValues.back().data());
|
|
+ }
|
|
+
|
|
+ char **result() {
|
|
+ _arguments.push_back(nullptr);
|
|
+ return _arguments.data();
|
|
+ }
|
|
+
|
|
+private:
|
|
+ std::vector<QByteArray> _argumentValues;
|
|
+ std::vector<char*> _arguments;
|
|
+
|
|
+};
|
|
+
|
|
+QString DeviceModel() {
|
|
+ return "PC";
|
|
+}
|
|
+
|
|
+QString SystemVersion() {
|
|
+ return "Haiku";
|
|
+}
|
|
+
|
|
+} // namespace
|
|
+
|
|
+Launcher::Launcher(int argc, char *argv[])
|
|
+: Core::Launcher(argc, argv, DeviceModel(), SystemVersion()) {
|
|
+}
|
|
+
|
|
+bool Launcher::launchUpdater(UpdaterLaunch action) {
|
|
+ return false;
|
|
+}
|
|
+
|
|
+} // namespace
|
|
diff --git a/Telegram/SourceFiles/platform/haiku/launcher_haiku.h b/Telegram/SourceFiles/platform/haiku/launcher_haiku.h
|
|
new file mode 100644
|
|
index 0000000..45d4cf8
|
|
--- /dev/null
|
|
+++ b/Telegram/SourceFiles/platform/haiku/launcher_haiku.h
|
|
@@ -0,0 +1,25 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2019 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include "core/launcher.h"
|
|
+
|
|
+namespace Platform {
|
|
+
|
|
+class Launcher : public Core::Launcher {
|
|
+public:
|
|
+ Launcher(int argc, char *argv[]);
|
|
+
|
|
+private:
|
|
+ bool launchUpdater(UpdaterLaunch action) override;
|
|
+
|
|
+};
|
|
+
|
|
+} // namespace Platform
|
|
diff --git a/Telegram/SourceFiles/platform/haiku/main_window_haiku.cpp b/Telegram/SourceFiles/platform/haiku/main_window_haiku.cpp
|
|
new file mode 100644
|
|
index 0000000..c603575
|
|
--- /dev/null
|
|
+++ b/Telegram/SourceFiles/platform/haiku/main_window_haiku.cpp
|
|
@@ -0,0 +1,134 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2019 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#include "platform/haiku/main_window_haiku.h"
|
|
+
|
|
+#include "styles/style_window.h"
|
|
+#include "platform/platform_notifications_manager.h"
|
|
+#include "window/notifications_manager.h"
|
|
+#include "mainwindow.h"
|
|
+#include "base/crc32hash.h"
|
|
+#include "core/application.h"
|
|
+#include "lang/lang_keys.h"
|
|
+#include "storage/localstorage.h"
|
|
+#include "ui/widgets/popup_menu.h"
|
|
+#include "window/themes/window_theme.h"
|
|
+#include "history/history.h"
|
|
+#include "facades.h"
|
|
+#include "app.h"
|
|
+
|
|
+#include <QtWidgets/QDesktopWidget>
|
|
+#include <QtWidgets/QStyleFactory>
|
|
+#include <QtWidgets/QApplication>
|
|
+#include <QtGui/QWindow>
|
|
+#include <qpa/qplatformnativeinterface.h>
|
|
+
|
|
+namespace Platform {
|
|
+
|
|
+MainWindow::MainWindow(not_null<Window::Controller*> controller)
|
|
+: Window::MainWindow(controller) {
|
|
+ connect(&_psCheckStatusIconTimer, SIGNAL(timeout()), this, SLOT(psStatusIconCheck()));
|
|
+ _psCheckStatusIconTimer.setSingleShot(false);
|
|
+
|
|
+ connect(&_psUpdateIndicatorTimer, SIGNAL(timeout()), this, SLOT(psUpdateIndicator()));
|
|
+ _psUpdateIndicatorTimer.setSingleShot(true);
|
|
+}
|
|
+
|
|
+bool MainWindow::hasTrayIcon() const {
|
|
+ return true;
|
|
+}
|
|
+
|
|
+void MainWindow::psStatusIconCheck() {
|
|
+ if (cSupportTray() || !--_psCheckStatusIconLeft) {
|
|
+ _psCheckStatusIconTimer.stop();
|
|
+ return;
|
|
+ }
|
|
+}
|
|
+
|
|
+void MainWindow::psShowTrayMenu() {
|
|
+}
|
|
+
|
|
+void MainWindow::psTrayMenuUpdated() {
|
|
+}
|
|
+
|
|
+void MainWindow::psSetupTrayIcon() {
|
|
+ if (!trayIcon) {
|
|
+ trayIcon = new QSystemTrayIcon(this);
|
|
+
|
|
+ auto icon = QIcon(App::pixmapFromImageInPlace(Core::App().logoNoMargin()));
|
|
+
|
|
+ trayIcon->setIcon(icon);
|
|
+ trayIcon->setToolTip(AppName.utf8());
|
|
+ connect(trayIcon, SIGNAL(messageClicked()), this, SLOT(showFromTray()));
|
|
+ attachToTrayIcon(trayIcon);
|
|
+ App::wnd()->updateTrayMenu();
|
|
+ }
|
|
+ updateIconCounters();
|
|
+
|
|
+ trayIcon->show();
|
|
+}
|
|
+
|
|
+void MainWindow::workmodeUpdated(DBIWorkMode mode) {
|
|
+ psSetupTrayIcon();
|
|
+ if (mode == dbiwmWindowOnly) {
|
|
+ if (trayIcon) {
|
|
+ trayIcon->setContextMenu(0);
|
|
+ delete trayIcon;
|
|
+ trayIcon = nullptr;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+void MainWindow::psUpdateIndicator() {
|
|
+}
|
|
+
|
|
+void MainWindow::unreadCounterChangedHook() {
|
|
+ setWindowTitle(titleText());
|
|
+ updateIconCounters();
|
|
+}
|
|
+
|
|
+void MainWindow::updateIconCounters() {
|
|
+ const auto counter = Core::App().unreadBadge();
|
|
+ const auto muted = Core::App().unreadBadgeMuted();
|
|
+ auto &bg = (muted ? st::trayCounterBgMute : st::trayCounterBg);
|
|
+ auto &fg = st::trayCounterFg;
|
|
+ if (trayIcon) {
|
|
+ QIcon icon;
|
|
+ icon.addPixmap(App::pixmapFromImageInPlace(iconWithCounter(16, counter, bg, fg, true)));
|
|
+ icon.addPixmap(App::pixmapFromImageInPlace(iconWithCounter(32, counter, bg, fg, true)));
|
|
+ trayIcon->setIcon(icon);
|
|
+ }
|
|
+}
|
|
+
|
|
+void MainWindow::LibsLoaded() {
|
|
+}
|
|
+
|
|
+void MainWindow::psCreateTrayIcon() {
|
|
+
|
|
+}
|
|
+
|
|
+void MainWindow::psFirstShow() {
|
|
+ psCreateTrayIcon();
|
|
+ psUpdateMargins();
|
|
+ bool showShadows = true;
|
|
+ show();
|
|
+ setPositionInited();
|
|
+}
|
|
+
|
|
+void MainWindow::psInitSysMenu() {
|
|
+}
|
|
+
|
|
+void MainWindow::psUpdateMargins() {
|
|
+}
|
|
+
|
|
+MainWindow::~MainWindow() {
|
|
+}
|
|
+
|
|
+} // namespace Platform
|
|
diff --git a/Telegram/SourceFiles/platform/haiku/main_window_haiku.h b/Telegram/SourceFiles/platform/haiku/main_window_haiku.h
|
|
new file mode 100644
|
|
index 0000000..36ab559
|
|
--- /dev/null
|
|
+++ b/Telegram/SourceFiles/platform/haiku/main_window_haiku.h
|
|
@@ -0,0 +1,69 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2019 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include "platform/platform_main_window.h"
|
|
+#include "base/flags.h"
|
|
+
|
|
+#include <QtCore/QTimer>
|
|
+
|
|
+namespace Platform {
|
|
+
|
|
+class MainWindow : public Window::MainWindow {
|
|
+ Q_OBJECT
|
|
+
|
|
+public:
|
|
+ explicit MainWindow(not_null<Window::Controller*> controller);
|
|
+
|
|
+ void psFirstShow();
|
|
+ void psInitSysMenu();
|
|
+ void psUpdateMargins();
|
|
+
|
|
+ void psRefreshTaskbarIcon() {
|
|
+ }
|
|
+
|
|
+ virtual QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) = 0;
|
|
+
|
|
+ static void LibsLoaded();
|
|
+
|
|
+ ~MainWindow();
|
|
+
|
|
+public slots:
|
|
+ void psShowTrayMenu();
|
|
+
|
|
+ void psStatusIconCheck();
|
|
+ void psUpdateIndicator();
|
|
+
|
|
+protected:
|
|
+ void unreadCounterChangedHook() override;
|
|
+
|
|
+ bool hasTrayIcon() const override;
|
|
+
|
|
+ void workmodeUpdated(DBIWorkMode mode) override;
|
|
+
|
|
+ QSystemTrayIcon *trayIcon = nullptr;
|
|
+ QMenu *trayIconMenu = nullptr;
|
|
+
|
|
+ void psTrayMenuUpdated();
|
|
+ void psSetupTrayIcon();
|
|
+
|
|
+ virtual void placeSmallCounter(QImage &img, int size, int count, style::color bg, const QPoint &shift, style::color color) = 0;
|
|
+
|
|
+private:
|
|
+ void updateIconCounters();
|
|
+ void psCreateTrayIcon();
|
|
+
|
|
+ QTimer _psCheckStatusIconTimer;
|
|
+ int _psCheckStatusIconLeft = 100;
|
|
+
|
|
+ QTimer _psUpdateIndicatorTimer;
|
|
+};
|
|
+
|
|
+} // namespace Platform
|
|
diff --git a/Telegram/SourceFiles/platform/haiku/notifications_haiku_gate.cpp b/Telegram/SourceFiles/platform/haiku/notifications_haiku_gate.cpp
|
|
new file mode 100644
|
|
index 0000000..b2df521
|
|
--- /dev/null
|
|
+++ b/Telegram/SourceFiles/platform/haiku/notifications_haiku_gate.cpp
|
|
@@ -0,0 +1,63 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2019 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#include <Application.h>
|
|
+#include <OS.h>
|
|
+
|
|
+#include <stdlib.h>
|
|
+#include <stdio.h>
|
|
+
|
|
+#define APPSIGNATURE "application/x-vnd.tg-notify-gate"
|
|
+#define NOTIFY_PORT_NAME "tg_notify"
|
|
+#define NOTIFY_MESSAGE 'TGNF'
|
|
+
|
|
+typedef struct notify_msg
|
|
+{
|
|
+ uint64 peerId;
|
|
+ int32 msgId;
|
|
+} notify_msg;
|
|
+
|
|
+class SimpleLauncherApp : public BApplication {
|
|
+ public:
|
|
+ SimpleLauncherApp(int argc, char **argv);
|
|
+ void ArgvReceived(int32 argc, char **argv);
|
|
+ virtual void ReadyToRun();
|
|
+};
|
|
+
|
|
+SimpleLauncherApp::SimpleLauncherApp(int argc, char **argv) : BApplication(APPSIGNATURE)
|
|
+{
|
|
+}
|
|
+
|
|
+void
|
|
+SimpleLauncherApp::ArgvReceived(int32 argc, char **argv)
|
|
+{
|
|
+ if (argc==2) {
|
|
+ notify_msg message;
|
|
+ sscanf(argv[1], "%lld %d", &message.peerId, &message.msgId);
|
|
+ if (message.peerId != 0 && message.msgId != 0) {
|
|
+ port_id portId = find_port(NOTIFY_PORT_NAME);
|
|
+ if (portId > 0) {
|
|
+ write_port(portId, NOTIFY_MESSAGE, &message, sizeof(message));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+SimpleLauncherApp::ReadyToRun()
|
|
+{
|
|
+ Quit();
|
|
+}
|
|
+
|
|
+int main(int argc, char **argv)
|
|
+{
|
|
+ SimpleLauncherApp application(argc, argv);
|
|
+ application.Run();
|
|
+ return 0;
|
|
+}
|
|
diff --git a/Telegram/SourceFiles/platform/haiku/notifications_haiku_gate.rdef b/Telegram/SourceFiles/platform/haiku/notifications_haiku_gate.rdef
|
|
new file mode 100644
|
|
index 0000000..b6f3490
|
|
--- /dev/null
|
|
+++ b/Telegram/SourceFiles/platform/haiku/notifications_haiku_gate.rdef
|
|
@@ -0,0 +1,13 @@
|
|
+resource app_flags B_MULTIPLE_LAUNCH | B_BACKGROUND_APP;
|
|
+
|
|
+resource app_version {
|
|
+ major = 0,
|
|
+ middle = 0,
|
|
+ minor = 1,
|
|
+ variety = B_APPV_FINAL,
|
|
+ internal = 0,
|
|
+ short_info = "tg-notify-gate",
|
|
+ long_info = "Telegram native notifications gate"
|
|
+};
|
|
+
|
|
+resource app_signature "application/x-vnd.tg-notify-gate";
|
|
diff --git a/Telegram/SourceFiles/platform/haiku/notifications_manager_haiku.cpp b/Telegram/SourceFiles/platform/haiku/notifications_manager_haiku.cpp
|
|
new file mode 100644
|
|
index 0000000..774487f
|
|
--- /dev/null
|
|
+++ b/Telegram/SourceFiles/platform/haiku/notifications_manager_haiku.cpp
|
|
@@ -0,0 +1,222 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2019 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#ifdef __x86_64__
|
|
+#define int64 XXX
|
|
+#define uint64 YYY
|
|
+#else
|
|
+#define int32 XXX
|
|
+#define uint32 YYY
|
|
+#endif
|
|
+
|
|
+#include <stdio.h>
|
|
+#include <unistd.h>
|
|
+#include <sys/stat.h>
|
|
+#include <fcntl.h>
|
|
+
|
|
+#include <SupportDefs.h>
|
|
+#include <Notification.h>
|
|
+#include <Bitmap.h>
|
|
+#include <TranslationUtils.h>
|
|
+#include <Entry.h>
|
|
+#include <OS.h>
|
|
+
|
|
+#include "platform/haiku/notifications_manager_haiku.h"
|
|
+
|
|
+#include "window/notifications_utilities.h"
|
|
+#include "history/history.h"
|
|
+#include "lang/lang_keys.h"
|
|
+
|
|
+#define DeclareReadOnlyVar(Type, Name) const Type &Name();
|
|
+#define DeclareRefVar(Type, Name) DeclareReadOnlyVar(Type, Name) \
|
|
+ Type &Ref##Name();
|
|
+#define DeclareVar(Type, Name) DeclareRefVar(Type, Name) \
|
|
+ void Set##Name(const Type &Name);
|
|
+
|
|
+namespace Global {
|
|
+ DeclareVar(bool, NativeNotifications);
|
|
+}
|
|
+
|
|
+#include <QProcess>
|
|
+#include <QThread>
|
|
+#include <QObject>
|
|
+#include <QString>
|
|
+#include <QStringList>
|
|
+
|
|
+namespace Platform {
|
|
+namespace Notifications {
|
|
+namespace {
|
|
+
|
|
+} // namespace
|
|
+
|
|
+bool Supported() {
|
|
+ return true;
|
|
+}
|
|
+
|
|
+std::unique_ptr<Window::Notifications::Manager> Create(Window::Notifications::System *system) {
|
|
+ if (Global::NativeNotifications() && Supported()) {
|
|
+ auto result = std::make_unique<Manager>(system);
|
|
+ if (result->init()) {
|
|
+ return std::move(result);
|
|
+ }
|
|
+ }
|
|
+ return nullptr;
|
|
+}
|
|
+
|
|
+void Finish() {
|
|
+}
|
|
+
|
|
+NotifyReader::NotifyReader()
|
|
+{
|
|
+ portId = create_port(NOTIFY_MESSAGE_DEEP, NOTIFY_PORT_NAME);
|
|
+}
|
|
+
|
|
+NotifyReader::~NotifyReader()
|
|
+{
|
|
+ if (portId >= B_OK)
|
|
+ delete_port(portId);
|
|
+}
|
|
+
|
|
+void NotifyReader::run()
|
|
+{
|
|
+ notify_msg message;
|
|
+ int32 code;
|
|
+
|
|
+ while (true) {
|
|
+ ssize_t bytesRead = read_port(portId, &code, &message, sizeof(message));
|
|
+ if (bytesRead == B_BAD_PORT_ID)
|
|
+ break;
|
|
+ if (bytesRead < (ssize_t)sizeof(message) || code != NOTIFY_MESSAGE)
|
|
+ continue;
|
|
+ if (message.peerId != 0 && message.msgId != 0)
|
|
+ notificationActivated(message.peerId, message.msgId);
|
|
+ }
|
|
+}
|
|
+
|
|
+Manager::Private::Private(Manager *instance, Type type)
|
|
+: _guarded(std::make_shared<Manager*>(instance))
|
|
+, _cachedUserpics(type) {
|
|
+ _weak = _guarded;
|
|
+}
|
|
+
|
|
+bool Manager::Private::init() {
|
|
+ portReaderThread = new QThread;
|
|
+ portReader = new NotifyReader();
|
|
+ portReader->moveToThread(portReaderThread);
|
|
+ connect(portReaderThread, SIGNAL(started()), portReader, SLOT(run()));
|
|
+ qRegisterMetaType<PeerId>("PeerId");
|
|
+ qRegisterMetaType<MsgId>("MsgId");
|
|
+ connect(portReader, SIGNAL(notificationActivated(PeerId, MsgId)), \
|
|
+ this, SLOT(notificationActivatedSlot(PeerId, MsgId)));
|
|
+ portReaderThread->start();
|
|
+ return true;
|
|
+}
|
|
+
|
|
+Manager::Private::~Private() {
|
|
+ clearAll();
|
|
+}
|
|
+
|
|
+void Manager::Private::clearAll() {
|
|
+}
|
|
+
|
|
+void Manager::Private::clearFromHistory(History *history) {
|
|
+}
|
|
+
|
|
+void Manager::Private::beforeNotificationActivated(PeerId peerId, MsgId msgId) {
|
|
+}
|
|
+
|
|
+void Manager::Private::afterNotificationActivated(PeerId peerId, MsgId msgId) {
|
|
+}
|
|
+
|
|
+void Manager::Private::clearNotification(PeerId peerId, MsgId msgId) {
|
|
+}
|
|
+
|
|
+bool Manager::Private::showNotification(PeerData *peer, MsgId msgId, const QString &title, \
|
|
+ const QString &subtitle, const QString &msg, bool hideNameAndPhoto, bool hideReplyButton) {
|
|
+ auto titleText = title;
|
|
+ auto subtitleText = subtitle;
|
|
+ auto msgText = msg;
|
|
+
|
|
+ const auto key = hideNameAndPhoto
|
|
+ ? InMemoryKey()
|
|
+ : peer->userpicUniqueKey();
|
|
+
|
|
+ auto userpicPath = _cachedUserpics.get(key, peer);
|
|
+ BBitmap *icon = BTranslationUtils::GetBitmapFile(userpicPath.toUtf8().data());
|
|
+ QString args = QString("%1 %2").arg(peer->id).arg(msgId);
|
|
+ BNotification notify(B_INFORMATION_NOTIFICATION);
|
|
+ if (icon)
|
|
+ notify.SetIcon(icon);
|
|
+ notify.SetGroup("Telegram");
|
|
+ notify.SetTitle(titleText.toUtf8().data());
|
|
+ notify.SetContent(msgText.toUtf8().data());
|
|
+ entry_ref ref;
|
|
+ BEntry entry(NOTIFY_GATE_NAME);
|
|
+ entry.GetRef(&ref);
|
|
+ notify.SetOnClickFile(&ref);
|
|
+ notify.AddOnClickArg(BString(args.toUtf8().data()));
|
|
+ notify.Send();
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+void Manager::Private::notificationActivatedSlot(PeerId _peerId, MsgId _msgId)
|
|
+{
|
|
+ qDebug() << _peerId << _msgId;
|
|
+ performOnMainQueue([peerId = _peerId, msgId = _msgId](Manager *manager) {
|
|
+ manager->notificationActivated(peerId, msgId);
|
|
+ });
|
|
+}
|
|
+
|
|
+Manager::Manager(Window::Notifications::System *system) : NativeManager(system)
|
|
+, _private(std::make_unique<Private>(this, Private::Type::Rounded)) {
|
|
+}
|
|
+
|
|
+bool Manager::init() {
|
|
+ return _private->init();
|
|
+}
|
|
+
|
|
+void Manager::clearNotification(PeerId peerId, MsgId msgId) {
|
|
+ _private->clearNotification(peerId, msgId);
|
|
+}
|
|
+
|
|
+Manager::~Manager() = default;
|
|
+
|
|
+void Manager::doShowNativeNotification(
|
|
+ not_null<PeerData*> peer,
|
|
+ MsgId msgId,
|
|
+ const QString &title,
|
|
+ const QString &subtitle,
|
|
+ const QString &msg,
|
|
+ bool hideNameAndPhoto,
|
|
+ bool hideReplyButton) {
|
|
+ _private->showNotification(
|
|
+ peer,
|
|
+ msgId,
|
|
+ title,
|
|
+ subtitle,
|
|
+ msg,
|
|
+ hideNameAndPhoto,
|
|
+ hideReplyButton);
|
|
+}
|
|
+
|
|
+void Manager::doClearAllFast() {
|
|
+ _private->clearAll();
|
|
+}
|
|
+
|
|
+void Manager::doClearFromHistory(not_null<History*> history) {
|
|
+ _private->clearFromHistory(history);
|
|
+}
|
|
+
|
|
+bool Manager::hasActionsSupport() const {
|
|
+ return _private->hasActionsSupport();
|
|
+}
|
|
+
|
|
+} // namespace Notifications
|
|
+} // namespace Platform
|
|
diff --git a/Telegram/SourceFiles/platform/haiku/notifications_manager_haiku.h b/Telegram/SourceFiles/platform/haiku/notifications_manager_haiku.h
|
|
new file mode 100644
|
|
index 0000000..e2218b8
|
|
--- /dev/null
|
|
+++ b/Telegram/SourceFiles/platform/haiku/notifications_manager_haiku.h
|
|
@@ -0,0 +1,127 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2019 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include "platform/platform_notifications_manager.h"
|
|
+#include "window/notifications_utilities.h"
|
|
+
|
|
+#include <QProcess>
|
|
+#include <QThread>
|
|
+#include <QObject>
|
|
+
|
|
+#define NOTIFY_MESSAGE_DEEP 16
|
|
+#define NOTIFY_PORT_NAME "tg_notify"
|
|
+#define NOTIFY_GATE_NAME "/bin/tg-notify-gate"
|
|
+#define NOTIFY_MESSAGE 'TGNF'
|
|
+
|
|
+typedef struct notify_msg
|
|
+{
|
|
+ uint64 peerId;
|
|
+ int32 msgId;
|
|
+} notify_msg;
|
|
+
|
|
+namespace Platform {
|
|
+namespace Notifications {
|
|
+
|
|
+inline bool SkipAudio() {
|
|
+ return false;
|
|
+}
|
|
+
|
|
+inline bool SkipToast() {
|
|
+ return false;
|
|
+}
|
|
+
|
|
+inline void FlashBounce() {
|
|
+}
|
|
+
|
|
+void Finish();
|
|
+
|
|
+class NotifyReader:public QObject {
|
|
+ Q_OBJECT
|
|
+public:
|
|
+ NotifyReader();
|
|
+ ~NotifyReader();
|
|
+public slots:
|
|
+ void run();
|
|
+signals:
|
|
+ void notificationActivated(PeerId peerId, MsgId msgId);
|
|
+private:
|
|
+ int32 portId;
|
|
+};
|
|
+
|
|
+
|
|
+class Manager : public Window::Notifications::NativeManager {
|
|
+public:
|
|
+ Manager(Window::Notifications::System *system);
|
|
+
|
|
+ bool init();
|
|
+
|
|
+ void clearNotification(PeerId peerId, MsgId msgId);
|
|
+
|
|
+ ~Manager();
|
|
+
|
|
+protected:
|
|
+ void doShowNativeNotification(
|
|
+ not_null<PeerData*> peer,
|
|
+ MsgId msgId,
|
|
+ const QString &title,
|
|
+ const QString &subtitle,
|
|
+ const QString &msg,
|
|
+ bool hideNameAndPhoto,
|
|
+ bool hideReplyButton) override;
|
|
+ void doClearAllFast() override;
|
|
+ void doClearFromHistory(not_null<History*> history) override;
|
|
+
|
|
+ bool hasActionsSupport() const;
|
|
+
|
|
+private:
|
|
+ class Private;
|
|
+ const std::unique_ptr<Private> _private;
|
|
+};
|
|
+
|
|
+class Manager::Private : public QObject {
|
|
+ Q_OBJECT
|
|
+public:
|
|
+ using Type = Window::Notifications::CachedUserpics::Type;
|
|
+ explicit Private(Manager *instance, Type type);
|
|
+ bool init();
|
|
+
|
|
+ bool showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, \
|
|
+ const QString &msg, bool hideNameAndPhoto, bool hideReplyButton);
|
|
+ void clearAll();
|
|
+ void clearFromHistory(History *history);
|
|
+ void beforeNotificationActivated(PeerId peerId, MsgId msgId);
|
|
+ void afterNotificationActivated(PeerId peerId, MsgId msgId);
|
|
+ void clearNotification(PeerId peerId, MsgId msgId);
|
|
+
|
|
+ bool hasActionsSupport() const {
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ void performOnMainQueue(FnMut<void(Manager *manager)> task) {
|
|
+ const auto weak = _weak;
|
|
+ crl::on_main(weak, [=, task = std::move(task)]() mutable {
|
|
+ task(*weak.lock());
|
|
+ });
|
|
+ }
|
|
+
|
|
+ ~Private();
|
|
+public slots:
|
|
+ void notificationActivatedSlot(PeerId peerId, MsgId msgId);
|
|
+private:
|
|
+ Window::Notifications::CachedUserpics _cachedUserpics;
|
|
+ std::shared_ptr<Manager*> _guarded;
|
|
+ std::weak_ptr<Manager*> _weak;
|
|
+ QThread *portReaderThread;
|
|
+ NotifyReader *portReader;
|
|
+};
|
|
+
|
|
+} // namespace Notifications
|
|
+} // namespace Platform
|
|
diff --git a/Telegram/SourceFiles/platform/haiku/specific_haiku.cpp b/Telegram/SourceFiles/platform/haiku/specific_haiku.cpp
|
|
new file mode 100644
|
|
index 0000000..bd68563
|
|
--- /dev/null
|
|
+++ b/Telegram/SourceFiles/platform/haiku/specific_haiku.cpp
|
|
@@ -0,0 +1,254 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2019 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#include "platform/haiku/specific_haiku.h"
|
|
+
|
|
+#include "lang/lang_keys.h"
|
|
+#include "mainwidget.h"
|
|
+#include "mainwindow.h"
|
|
+#include "storage/localstorage.h"
|
|
+#include "platform/haiku/file_utilities_haiku.h"
|
|
+
|
|
+#include <QtWidgets/QApplication>
|
|
+#include <QtWidgets/QDesktopWidget>
|
|
+#include <QtCore/QStandardPaths>
|
|
+#include <QtCore/QProcess>
|
|
+#include <QtCore/QVersionNumber>
|
|
+#include <qpa/qplatformnativeinterface.h>
|
|
+
|
|
+#include <sys/stat.h>
|
|
+#include <sys/types.h>
|
|
+#include <cstdlib>
|
|
+#include <unistd.h>
|
|
+#include <dirent.h>
|
|
+#include <pwd.h>
|
|
+
|
|
+#include <iostream>
|
|
+
|
|
+#include <qpa/qplatformnativeinterface.h>
|
|
+
|
|
+using namespace Platform;
|
|
+
|
|
+using Platform::File::internal::EscapeShell;
|
|
+
|
|
+namespace Platform {
|
|
+
|
|
+QString CurrentExecutablePath(int argc, char *argv[]) {
|
|
+ return argc ? QFile::decodeName(argv[0]) : QString();
|
|
+}
|
|
+
|
|
+QString SingleInstanceLocalServerName(const QString &hash) {
|
|
+ return QStandardPaths::writableLocation(QStandardPaths::TempLocation)
|
|
+ + '/' + hash + '-' + cGUIDStr();
|
|
+}
|
|
+
|
|
+} // namespace Platform
|
|
+
|
|
+namespace {
|
|
+
|
|
+QRect _monitorRect;
|
|
+auto _monitorLastGot = 0LL;
|
|
+
|
|
+} // namespace
|
|
+
|
|
+QRect psDesktopRect() {
|
|
+ auto tnow = crl::now();
|
|
+ if (tnow > _monitorLastGot + 1000LL || tnow < _monitorLastGot) {
|
|
+ _monitorLastGot = tnow;
|
|
+ _monitorRect = QApplication::desktop()->availableGeometry(App::wnd());
|
|
+ }
|
|
+ return _monitorRect;
|
|
+}
|
|
+
|
|
+void psShowOverAll(QWidget *w, bool canFocus) {
|
|
+ w->show();
|
|
+}
|
|
+
|
|
+void psBringToBack(QWidget *w) {
|
|
+ w->hide();
|
|
+}
|
|
+
|
|
+void psWriteDump() {
|
|
+}
|
|
+
|
|
+bool _removeDirectory(const QString &path) { // from http://stackoverflow.com/questions/2256945/removing-a-non-empty-directory-programmatically-in-c-or-c
|
|
+ QByteArray pathRaw = QFile::encodeName(path);
|
|
+ DIR *d = opendir(pathRaw.constData());
|
|
+ if (!d) return false;
|
|
+
|
|
+ while (struct dirent *p = readdir(d)) {
|
|
+ /* Skip the names "." and ".." as we don't want to recurse on them. */
|
|
+ if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, "..")) continue;
|
|
+
|
|
+ QString fname = path + '/' + p->d_name;
|
|
+ QByteArray fnameRaw = QFile::encodeName(fname);
|
|
+ struct stat statbuf;
|
|
+ if (!stat(fnameRaw.constData(), &statbuf)) {
|
|
+ if (S_ISDIR(statbuf.st_mode)) {
|
|
+ if (!_removeDirectory(fname)) {
|
|
+ closedir(d);
|
|
+ return false;
|
|
+ }
|
|
+ } else {
|
|
+ if (unlink(fnameRaw.constData())) {
|
|
+ closedir(d);
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ closedir(d);
|
|
+
|
|
+ return !rmdir(pathRaw.constData());
|
|
+}
|
|
+
|
|
+void psDeleteDir(const QString &dir) {
|
|
+ _removeDirectory(dir);
|
|
+}
|
|
+
|
|
+namespace {
|
|
+
|
|
+auto _lastUserAction = 0LL;
|
|
+
|
|
+} // namespace
|
|
+
|
|
+void psActivateProcess(uint64 pid) {
|
|
+// objc_activateProgram();
|
|
+}
|
|
+
|
|
+
|
|
+QString psAppDataPath() {
|
|
+ return QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + '/';
|
|
+}
|
|
+
|
|
+QString psDownloadPath() {
|
|
+ return QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + '/' + AppName.utf8() + '/';
|
|
+}
|
|
+
|
|
+void psDoCleanup() {
|
|
+ try {
|
|
+ psAutoStart(false, true);
|
|
+ psSendToMenu(false, true);
|
|
+ } catch (...) {
|
|
+ }
|
|
+}
|
|
+
|
|
+int psCleanup() {
|
|
+ psDoCleanup();
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void psDoFixPrevious() {
|
|
+}
|
|
+
|
|
+int psFixPrevious() {
|
|
+ psDoFixPrevious();
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+namespace Platform {
|
|
+
|
|
+void start() {
|
|
+}
|
|
+
|
|
+void finish() {
|
|
+}
|
|
+
|
|
+void SetApplicationIcon(const QIcon &icon) {
|
|
+ qApp->setWindowIcon(icon);
|
|
+}
|
|
+
|
|
+void RegisterCustomScheme() {
|
|
+}
|
|
+
|
|
+PermissionStatus GetPermissionStatus(PermissionType type){
|
|
+ return PermissionStatus::Granted;
|
|
+}
|
|
+
|
|
+void RequestPermission(PermissionType type, Fn<void(PermissionStatus)> resultCallback){
|
|
+ resultCallback(PermissionStatus::Granted);
|
|
+}
|
|
+
|
|
+void OpenSystemSettingsForPermission(PermissionType type){
|
|
+}
|
|
+
|
|
+bool OpenSystemSettings(SystemSettingsType type) {
|
|
+ if (type == SystemSettingsType::Audio) {
|
|
+ auto options = std::vector<QString>();
|
|
+ const auto add = [&](const char *option) {
|
|
+ options.emplace_back(option);
|
|
+ };
|
|
+ add("Media");
|
|
+ return ranges::find_if(options, [](const QString &command) {
|
|
+ return QProcess::startDetached(command);
|
|
+ }) != end(options);
|
|
+ }
|
|
+ return true;
|
|
+}
|
|
+
|
|
+namespace ThirdParty {
|
|
+
|
|
+void start() {
|
|
+}
|
|
+
|
|
+void finish() {
|
|
+}
|
|
+
|
|
+} // namespace ThirdParty
|
|
+
|
|
+} // namespace Platform
|
|
+
|
|
+namespace {
|
|
+
|
|
+bool _psRunCommand(const QByteArray &command) {
|
|
+ auto result = system(command.constData());
|
|
+ if (result) {
|
|
+ DEBUG_LOG(("App Error: command failed, code: %1, command (in utf8): %2").arg(result).arg(command.constData()));
|
|
+ return false;
|
|
+ }
|
|
+ DEBUG_LOG(("App Info: command succeeded, command (in utf8): %1").arg(command.constData()));
|
|
+ return true;
|
|
+}
|
|
+
|
|
+} // namespace
|
|
+
|
|
+void psRegisterCustomScheme() {
|
|
+}
|
|
+
|
|
+void psNewVersion() {
|
|
+ Platform::RegisterCustomScheme();
|
|
+}
|
|
+
|
|
+bool _execUpdater(bool update = true, const QString &crashreport = QString()) {
|
|
+ return false;
|
|
+}
|
|
+
|
|
+void psExecUpdater() {
|
|
+}
|
|
+
|
|
+void psExecTelegram(const QString &crashreport) {
|
|
+ _execUpdater(false, crashreport);
|
|
+}
|
|
+
|
|
+bool psShowOpenWithMenu(int x, int y, const QString &file) {
|
|
+ return false;
|
|
+}
|
|
+
|
|
+void psAutoStart(bool start, bool silent) {
|
|
+}
|
|
+
|
|
+void psSendToMenu(bool send, bool silent) {
|
|
+}
|
|
+
|
|
+void psUpdateOverlayed(QWidget *widget) {
|
|
+}
|
|
+
|
|
+bool psLaunchMaps(const Data::LocationPoint &point) {
|
|
+ return false;
|
|
+}
|
|
diff --git a/Telegram/SourceFiles/platform/haiku/specific_haiku.h b/Telegram/SourceFiles/platform/haiku/specific_haiku.h
|
|
new file mode 100644
|
|
index 0000000..c674859
|
|
--- /dev/null
|
|
+++ b/Telegram/SourceFiles/platform/haiku/specific_haiku.h
|
|
@@ -0,0 +1,114 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2019 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include <signal.h>
|
|
+
|
|
+namespace Data {
|
|
+class LocationPoint;
|
|
+} // namespace Data
|
|
+
|
|
+namespace Platform {
|
|
+
|
|
+inline void SetWatchingMediaKeys(bool watching) {
|
|
+}
|
|
+
|
|
+inline void IgnoreApplicationActivationRightNow() {
|
|
+}
|
|
+
|
|
+inline void InitOnTopPanel(QWidget *panel) {
|
|
+}
|
|
+
|
|
+inline void DeInitOnTopPanel(QWidget *panel) {
|
|
+}
|
|
+
|
|
+inline void ReInitOnTopPanel(QWidget *panel) {
|
|
+}
|
|
+
|
|
+QString CurrentExecutablePath(int argc, char *argv[]);
|
|
+
|
|
+QString SingleInstanceLocalServerName(const QString &hash);
|
|
+
|
|
+inline std::optional<crl::time> LastUserInputTime() {
|
|
+ return std::nullopt;
|
|
+}
|
|
+
|
|
+} // namespace Platform
|
|
+
|
|
+inline QString psServerPrefix() {
|
|
+ return qsl("/tmp/");
|
|
+}
|
|
+inline void psCheckLocalSocket(const QString &serverName) {
|
|
+ QFile address(serverName);
|
|
+ if (address.exists()) {
|
|
+ address.remove();
|
|
+ }
|
|
+}
|
|
+
|
|
+void psWriteDump();
|
|
+
|
|
+void psDeleteDir(const QString &dir);
|
|
+
|
|
+QStringList psInitLogs();
|
|
+void psClearInitLogs();
|
|
+
|
|
+void psActivateProcess(uint64 pid = 0);
|
|
+QString psLocalServerPrefix();
|
|
+QString psAppDataPath();
|
|
+QString psDownloadPath();
|
|
+void psAutoStart(bool start, bool silent = false);
|
|
+void psSendToMenu(bool send, bool silent = false);
|
|
+
|
|
+QRect psDesktopRect();
|
|
+void psShowOverAll(QWidget *w, bool canFocus = true);
|
|
+void psBringToBack(QWidget *w);
|
|
+
|
|
+int psCleanup();
|
|
+int psFixPrevious();
|
|
+
|
|
+void psExecUpdater();
|
|
+void psExecTelegram(const QString &arg = QString());
|
|
+
|
|
+void psNewVersion();
|
|
+
|
|
+void psUpdateOverlayed(QWidget *widget);
|
|
+inline QByteArray psDownloadPathBookmark(const QString &path) {
|
|
+ return QByteArray();
|
|
+}
|
|
+inline QByteArray psPathBookmark(const QString &path) {
|
|
+ return QByteArray();
|
|
+}
|
|
+inline void psDownloadPathEnableAccess() {
|
|
+}
|
|
+
|
|
+class PsFileBookmark {
|
|
+public:
|
|
+ PsFileBookmark(const QByteArray &bookmark) {
|
|
+ }
|
|
+ bool check() const {
|
|
+ return true;
|
|
+ }
|
|
+ bool enable() const {
|
|
+ return true;
|
|
+ }
|
|
+ void disable() const {
|
|
+ }
|
|
+ const QString &name(const QString &original) const {
|
|
+ return original;
|
|
+ }
|
|
+ QByteArray bookmark() const {
|
|
+ return QByteArray();
|
|
+ }
|
|
+
|
|
+};
|
|
+
|
|
+//ool linuxMoveFile(const char *from, const char *to);
|
|
+
|
|
+bool psLaunchMaps(const Data::LocationPoint &point);
|
|
diff --git a/Telegram/SourceFiles/platform/platform_audio.h b/Telegram/SourceFiles/platform/platform_audio.h
|
|
index 7705b2e..b65a843 100644
|
|
--- a/Telegram/SourceFiles/platform/platform_audio.h
|
|
+++ b/Telegram/SourceFiles/platform/platform_audio.h
|
|
@@ -19,7 +19,7 @@ void DeInit();
|
|
|
|
// Platform dependent implementations.
|
|
|
|
-#if defined Q_OS_MAC || defined Q_OS_LINUX
|
|
+#if defined Q_OS_MAC || defined Q_OS_LINUX || defined Q_OS_HAIKU
|
|
namespace Platform {
|
|
namespace Audio {
|
|
|
|
diff --git a/Telegram/SourceFiles/platform/platform_file_utilities.h b/Telegram/SourceFiles/platform/platform_file_utilities.h
|
|
index 68b1058..f9b05d9 100644
|
|
--- a/Telegram/SourceFiles/platform/platform_file_utilities.h
|
|
+++ b/Telegram/SourceFiles/platform/platform_file_utilities.h
|
|
@@ -45,8 +45,10 @@ bool Get(
|
|
|
|
#ifdef Q_OS_MAC
|
|
#include "platform/mac/file_utilities_mac.h"
|
|
-#elif defined Q_OS_LINUX // Q_OS_MAC
|
|
+#elif defined Q_OS_HAIKU // Q_OS_MAC
|
|
+#include "platform/haiku/file_utilities_haiku.h"
|
|
+#elif defined Q_OS_LINUX // Q_OS_MAC || Q_OS_HAIKU
|
|
#include "platform/linux/file_utilities_linux.h"
|
|
-#elif defined Q_OS_WINRT || defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX
|
|
+#elif defined Q_OS_WINRT || defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX || Q_OS_HAIKU
|
|
#include "platform/win/file_utilities_win.h"
|
|
-#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT || Q_OS_WIN
|
|
+#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT || Q_OS_WIN || Q_OS_HAIKU
|
|
diff --git a/Telegram/SourceFiles/platform/platform_launcher.h b/Telegram/SourceFiles/platform/platform_launcher.h
|
|
index 27180d0..d82bda6 100644
|
|
--- a/Telegram/SourceFiles/platform/platform_launcher.h
|
|
+++ b/Telegram/SourceFiles/platform/platform_launcher.h
|
|
@@ -23,8 +23,10 @@ namespace Platform {
|
|
|
|
#ifdef Q_OS_MAC
|
|
#include "platform/mac/launcher_mac.h"
|
|
-#elif defined Q_OS_LINUX // Q_OS_MAC
|
|
+#elif defined Q_OS_HAIKU // Q_OS_MAC
|
|
+#include "platform/haiku/launcher_haiku.h"
|
|
+#elif defined Q_OS_LINUX // Q_OS_MAC || Q_OS_HAIKU
|
|
#include "platform/linux/launcher_linux.h"
|
|
-#elif defined Q_OS_WINRT || defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX
|
|
+#elif defined Q_OS_WINRT || defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX || Q_OS_HAIKU
|
|
#include "platform/win/launcher_win.h"
|
|
-#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT || Q_OS_WIN
|
|
+#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT || Q_OS_WIN || Q_OS_HAIKU
|
|
diff --git a/Telegram/SourceFiles/platform/platform_main_window.h b/Telegram/SourceFiles/platform/platform_main_window.h
|
|
index 33277c9..2d6ba7d 100644
|
|
--- a/Telegram/SourceFiles/platform/platform_main_window.h
|
|
+++ b/Telegram/SourceFiles/platform/platform_main_window.h
|
|
@@ -19,8 +19,10 @@ class MainWindow;
|
|
|
|
#ifdef Q_OS_MAC
|
|
#include "platform/mac/main_window_mac.h"
|
|
-#elif defined Q_OS_LINUX // Q_OS_MAC
|
|
+#elif defined Q_OS_HAIKU // Q_OS_MAC
|
|
+#include "platform/haiku/main_window_haiku.h"
|
|
+#elif defined Q_OS_LINUX // Q_OS_MAC || Q_OS_HAIKU
|
|
#include "platform/linux/main_window_linux.h"
|
|
-#elif defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX
|
|
+#elif defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX || Q_OS_HAIKU
|
|
#include "platform/win/main_window_win.h"
|
|
-#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WIN
|
|
+#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WIN || Q_OS_HAIKU
|
|
diff --git a/Telegram/SourceFiles/platform/platform_notifications_manager.h b/Telegram/SourceFiles/platform/platform_notifications_manager.h
|
|
index 692f4b4..30a9570 100644
|
|
--- a/Telegram/SourceFiles/platform/platform_notifications_manager.h
|
|
+++ b/Telegram/SourceFiles/platform/platform_notifications_manager.h
|
|
@@ -26,8 +26,10 @@ void FlashBounce();
|
|
|
|
#ifdef Q_OS_MAC
|
|
#include "platform/mac/notifications_manager_mac.h"
|
|
-#elif defined Q_OS_LINUX // Q_OS_MAC
|
|
+#elif defined Q_OS_HAIKU // Q_OS_MAC
|
|
+#include "platform/haiku/notifications_manager_haiku.h"
|
|
+#elif defined Q_OS_LINUX // Q_OS_MAC || Q_OS_LINUX
|
|
#include "platform/linux/notifications_manager_linux.h"
|
|
-#elif defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX
|
|
+#elif defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX || Q_OS_LINUX
|
|
#include "platform/win/notifications_manager_win.h"
|
|
-#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WIN
|
|
+#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WIN || Q_OS_LINUX
|
|
diff --git a/Telegram/SourceFiles/platform/platform_specific.h b/Telegram/SourceFiles/platform/platform_specific.h
|
|
index f5650f9..599c839 100644
|
|
--- a/Telegram/SourceFiles/platform/platform_specific.h
|
|
+++ b/Telegram/SourceFiles/platform/platform_specific.h
|
|
@@ -51,8 +51,10 @@ void finish();
|
|
|
|
#ifdef Q_OS_MAC
|
|
#include "platform/mac/specific_mac.h"
|
|
-#elif defined Q_OS_LINUX // Q_OS_MAC
|
|
+#elif defined Q_OS_HAIKU // Q_OS_MAC
|
|
+#include "platform/haiku/specific_haiku.h"
|
|
+#elif defined Q_OS_LINUX // Q_OS_MAC || Q_OS_HAIKU
|
|
#include "platform/linux/specific_linux.h"
|
|
-#elif defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX
|
|
+#elif defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX || Q_OS_HAIKU
|
|
#include "platform/win/specific_win.h"
|
|
-#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WIN
|
|
+#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WIN || Q_OS_HAIKU
|
|
diff --git a/Telegram/SourceFiles/platform/platform_window_title.h b/Telegram/SourceFiles/platform/platform_window_title.h
|
|
index 6aea663..a5c46ef 100644
|
|
--- a/Telegram/SourceFiles/platform/platform_window_title.h
|
|
+++ b/Telegram/SourceFiles/platform/platform_window_title.h
|
|
@@ -26,7 +26,7 @@ void PreviewWindowFramePaint(QImage &preview, const style::palette &palette, QRe
|
|
#include "platform/mac/window_title_mac.h"
|
|
#elif defined Q_OS_WIN // Q_OS_MAC
|
|
#include "platform/win/window_title_win.h"
|
|
-#elif defined Q_OS_WINRT || defined Q_OS_LINUX // Q_OS_MAC || Q_OS_WIN
|
|
+#elif defined Q_OS_WINRT || defined Q_OS_LINUX || defined(Q_OS_HAIKU) // Q_OS_MAC || Q_OS_WIN
|
|
|
|
namespace Platform {
|
|
|
|
@@ -44,4 +44,4 @@ inline void PreviewWindowFramePaint(QImage &preview, const style::palette &palet
|
|
|
|
} // namespace Platform
|
|
|
|
-#endif // Q_OS_MAC || Q_OS_WIN || Q_OS_WINRT || Q_OS_LINUX
|
|
+#endif // Q_OS_MAC || Q_OS_WIN || Q_OS_WINRT || Q_OS_LINUX || Q_OS_HAIKU
|
|
diff --git a/Telegram/SourceFiles/settings/settings_calls.cpp b/Telegram/SourceFiles/settings/settings_calls.cpp
|
|
index 56acbb9..ef16c47 100644
|
|
--- a/Telegram/SourceFiles/settings/settings_calls.cpp
|
|
+++ b/Telegram/SourceFiles/settings/settings_calls.cpp
|
|
@@ -5,6 +5,7 @@ the official desktop application for the Telegram messaging service.
|
|
For license and copyright information please follow this link:
|
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
*/
|
|
+
|
|
#include "settings/settings_calls.h"
|
|
|
|
#include "settings/settings_common.h"
|
|
@@ -31,6 +32,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
#define NEED_TO_RESTORE_SLOTS
|
|
#endif // slots
|
|
|
|
+// Don't include SupportDefs.h
|
|
+#ifdef __HAIKU__
|
|
+#define _SUPPORT_DEFS_H
|
|
+typedef int32 status_t;
|
|
+typedef uint32 type_code;
|
|
+#endif
|
|
+
|
|
#include <VoIPController.h>
|
|
|
|
#ifdef NEED_TO_RESTORE_SLOTS
|
|
diff --git a/Telegram/SourceFiles/settings/settings_notifications.cpp b/Telegram/SourceFiles/settings/settings_notifications.cpp
|
|
index 9ec30eb..53152ee 100644
|
|
--- a/Telegram/SourceFiles/settings/settings_notifications.cpp
|
|
+++ b/Telegram/SourceFiles/settings/settings_notifications.cpp
|
|
@@ -622,7 +622,7 @@ void SetupNotificationsContent(
|
|
return QString();
|
|
} else if (Platform::IsWindows()) {
|
|
return tr::lng_settings_use_windows(tr::now);
|
|
- } else if (Platform::IsLinux()) {
|
|
+ } else if (Platform::IsLinux() || Platform::IsHaiku()) {
|
|
return tr::lng_settings_use_native_notifications(tr::now);
|
|
}
|
|
return QString();
|
|
diff --git a/Telegram/SourceFiles/window/main_window.cpp b/Telegram/SourceFiles/window/main_window.cpp
|
|
index 50b9564..c85e35e 100644
|
|
--- a/Telegram/SourceFiles/window/main_window.cpp
|
|
+++ b/Telegram/SourceFiles/window/main_window.cpp
|
|
@@ -117,7 +117,7 @@ QIcon CreateOfficialIcon(Main::Account *account) {
|
|
|
|
QIcon CreateIcon(Main::Account *account) {
|
|
auto result = CreateOfficialIcon(account);
|
|
- if (Platform::IsLinux()) {
|
|
+ if (Platform::IsLinux() || Platform::IsHaiku()) {
|
|
return QIcon::fromTheme("telegram", result);
|
|
}
|
|
return result;
|
|
diff --git a/Telegram/ThirdParty/libtgvoip/VoIPController.cpp b/Telegram/ThirdParty/libtgvoip/VoIPController.cpp
|
|
index 88a8260..dfc6478 100644
|
|
--- a/Telegram/ThirdParty/libtgvoip/VoIPController.cpp
|
|
+++ b/Telegram/ThirdParty/libtgvoip/VoIPController.cpp
|
|
@@ -8,6 +8,9 @@
|
|
#include <unistd.h>
|
|
#include <sys/time.h>
|
|
#endif
|
|
+#ifdef __HAIKU__
|
|
+#include <OS.h>
|
|
+#endif
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <wchar.h>
|
|
@@ -3009,6 +3012,10 @@ double VoIPController::GetCurrentTime(){
|
|
struct timespec ts;
|
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
return ts.tv_sec+(double)ts.tv_nsec/1000000000.0;
|
|
+#elif defined(__HAIKU__)
|
|
+ struct timeval tm;
|
|
+ gettimeofday(&tm, NULL);
|
|
+ return tm.tv_sec+(double)tm.tv_usec/1000000.0;
|
|
#elif defined(__APPLE__)
|
|
static pthread_once_t token = PTHREAD_ONCE_INIT;
|
|
pthread_once(&token, &initMachTimestart);
|
|
diff --git a/Telegram/ThirdParty/libtgvoip/audio/AudioIO.cpp b/Telegram/ThirdParty/libtgvoip/audio/AudioIO.cpp
|
|
index 2c16ca7..e00c731 100644
|
|
--- a/Telegram/ThirdParty/libtgvoip/audio/AudioIO.cpp
|
|
+++ b/Telegram/ThirdParty/libtgvoip/audio/AudioIO.cpp
|
|
@@ -39,6 +39,9 @@
|
|
#ifndef WITHOUT_PULSE
|
|
#include "../os/linux/AudioPulse.h"
|
|
#endif
|
|
+#elif defined(__HAIKU__)
|
|
+#include "../os/haiku/AudioInputHaiku.h"
|
|
+#include "../os/haiku/AudioOutputHaiku.h"
|
|
#else
|
|
#error "Unsupported operating system"
|
|
#endif
|
|
@@ -65,6 +68,8 @@ AudioIO* AudioIO::Create(std::string inputDevice, std::string outputDevice){
|
|
return new ContextlessAudioIO<AudioInputWave, AudioOutputWave>(inputDevice, outputDevice);
|
|
#endif
|
|
return new ContextlessAudioIO<AudioInputWASAPI, AudioOutputWASAPI>(inputDevice, outputDevice);
|
|
+#elif defined(__HAIKU__)
|
|
+ return new ContextlessAudioIO<AudioInputHaiku, AudioOutputHaiku>();
|
|
#elif defined(__linux__)
|
|
#ifndef WITHOUT_ALSA
|
|
#ifndef WITHOUT_PULSE
|
|
diff --git a/Telegram/ThirdParty/libtgvoip/audio/AudioInput.cpp b/Telegram/ThirdParty/libtgvoip/audio/AudioInput.cpp
|
|
index 4d5b573..239406c 100644
|
|
--- a/Telegram/ThirdParty/libtgvoip/audio/AudioInput.cpp
|
|
+++ b/Telegram/ThirdParty/libtgvoip/audio/AudioInput.cpp
|
|
@@ -33,6 +33,8 @@
|
|
#ifndef WITHOUT_PULSE
|
|
#include "../os/linux/AudioPulse.h"
|
|
#endif
|
|
+#elif defined(__HAIKU__)
|
|
+#include "../os/haiku/AudioInputHaiku.h"
|
|
#else
|
|
#error "Unsupported operating system"
|
|
#endif
|
|
diff --git a/Telegram/ThirdParty/libtgvoip/audio/AudioOutput.cpp b/Telegram/ThirdParty/libtgvoip/audio/AudioOutput.cpp
|
|
index dc7b61a..b075925 100644
|
|
--- a/Telegram/ThirdParty/libtgvoip/audio/AudioOutput.cpp
|
|
+++ b/Telegram/ThirdParty/libtgvoip/audio/AudioOutput.cpp
|
|
@@ -37,6 +37,8 @@
|
|
#include "../os/linux/AudioOutputPulse.h"
|
|
#include "../os/linux/AudioPulse.h"
|
|
#endif
|
|
+#elif defined(__HAIKU__)
|
|
+#include "../os/haiku/AudioOutputHaiku.h"
|
|
#else
|
|
#error "Unsupported operating system"
|
|
#endif
|
|
diff --git a/Telegram/ThirdParty/libtgvoip/os/haiku/AudioInputHaiku.cpp b/Telegram/ThirdParty/libtgvoip/os/haiku/AudioInputHaiku.cpp
|
|
new file mode 100644
|
|
index 0000000..7cce3e3
|
|
--- /dev/null
|
|
+++ b/Telegram/ThirdParty/libtgvoip/os/haiku/AudioInputHaiku.cpp
|
|
@@ -0,0 +1,276 @@
|
|
+//
|
|
+// libtgvoip is free and unencumbered public domain software.
|
|
+// For more information, see http://unlicense.org or the UNLICENSE file
|
|
+// you should have received with this source code distribution.
|
|
+//
|
|
+
|
|
+#include <stdlib.h>
|
|
+#include <stdio.h>
|
|
+#include <assert.h>
|
|
+#include <dlfcn.h>
|
|
+#include "AudioInputHaiku.h"
|
|
+#include "../../logging.h"
|
|
+#include "../../audio/Resampler.h"
|
|
+#include "../../VoIPController.h"
|
|
+
|
|
+#include "RingBuffer.h"
|
|
+
|
|
+using namespace tgvoip::audio;
|
|
+
|
|
+void RecordData(void* cookie, bigtime_t timestamp, void* data, size_t size, const media_format &format)
|
|
+{
|
|
+ AudioInputHaiku *audioInput = (AudioInputHaiku*)cookie;
|
|
+ if (!audioInput->IsRecording())
|
|
+ return;
|
|
+
|
|
+ if (format.u.raw_audio.format == media_raw_audio_format::B_AUDIO_SHORT &&
|
|
+ format.u.raw_audio.channel_count == 1) {
|
|
+ audioInput->fRingBuffer->Write((unsigned char*)data, size);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ uint32 bytesPerSample = 2;
|
|
+ switch (format.u.raw_audio.format) {
|
|
+ case media_raw_audio_format::B_AUDIO_CHAR:
|
|
+ bytesPerSample = 1;
|
|
+ break;
|
|
+ case media_raw_audio_format::B_AUDIO_SHORT:
|
|
+ bytesPerSample = 2;
|
|
+ break;
|
|
+ case media_raw_audio_format::B_AUDIO_INT:
|
|
+ bytesPerSample = 4;
|
|
+ break;
|
|
+ case media_raw_audio_format::B_AUDIO_FLOAT:
|
|
+ bytesPerSample = 4;
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ int frames = size / (format.u.raw_audio.channel_count * bytesPerSample);
|
|
+ int16_t *dst = audioInput->workBuffer;
|
|
+
|
|
+ if (format.u.raw_audio.format == media_raw_audio_format::B_AUDIO_CHAR) {
|
|
+ unsigned char* src=reinterpret_cast<unsigned char*>(data);
|
|
+ for (int n=0; n < frames; n++) {
|
|
+ int32_t value = 0;
|
|
+ for (int j=0; j < format.u.raw_audio.channel_count; j++, src++) {
|
|
+ value += ((int32_t)(*src) - INT8_MAX) * UINT8_MAX;
|
|
+ }
|
|
+ value /= format.u.raw_audio.channel_count;
|
|
+ dst[n] = (int16_t)value;
|
|
+ }
|
|
+ } else if (format.u.raw_audio.format == media_raw_audio_format::B_AUDIO_SHORT) {
|
|
+ int16_t* src=reinterpret_cast<int16_t*>(data);
|
|
+ for (int n=0; n < frames; n++) {
|
|
+ int32_t value = 0;
|
|
+ for (int j=0; j < format.u.raw_audio.channel_count; j++, src++) {
|
|
+ value += *src;
|
|
+ }
|
|
+ value /= format.u.raw_audio.channel_count;
|
|
+ dst[n] = (int16_t)value;
|
|
+ }
|
|
+ } else if (format.u.raw_audio.format == media_raw_audio_format::B_AUDIO_INT) {
|
|
+ int32_t* src=reinterpret_cast<int32_t*>(data);
|
|
+ for (int n=0; n < frames; n++) {
|
|
+ int64_t value = 0;
|
|
+ for (int j=0; j < format.u.raw_audio.channel_count; j++, src++) {
|
|
+ value += (int64_t)(*src);
|
|
+ }
|
|
+ value /= format.u.raw_audio.channel_count;
|
|
+ dst[n] = (int16_t)(value / (UINT16_MAX + 1));
|
|
+ }
|
|
+ } else if (format.u.raw_audio.format == media_raw_audio_format::B_AUDIO_FLOAT) {
|
|
+ float* src=reinterpret_cast<float*>(data);
|
|
+ for (int n=0; n < frames; n++) {
|
|
+ float value = 0;
|
|
+ for (int j=0; j < format.u.raw_audio.channel_count; j++, src++) {
|
|
+ value += *src;
|
|
+ }
|
|
+ value /= format.u.raw_audio.channel_count;
|
|
+ dst[n] = (int16_t)(value*INT16_MAX);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if(format.u.raw_audio.frame_rate != audioInput->tgFrameRate) {
|
|
+ size_t len = tgvoip::audio::Resampler::Convert(dst, audioInput->convertBuffer,
|
|
+ frames, frames, audioInput->tgFrameRate, format.u.raw_audio.frame_rate) * audioInput->tgBytesPerSample;
|
|
+ audioInput->fRingBuffer->Write((unsigned char*)audioInput->convertBuffer, len);
|
|
+ } else {
|
|
+ audioInput->fRingBuffer->Write((unsigned char*)dst, frames * audioInput->tgBytesPerSample);
|
|
+ }
|
|
+}
|
|
+
|
|
+void NotifyRecordData(void * cookie, BMediaRecorder::notification code, ...)
|
|
+{
|
|
+ AudioInputHaiku *audioInput = (AudioInputHaiku*)cookie;
|
|
+ if (code == BMediaRecorder::B_WILL_STOP) {
|
|
+ if (audioInput->IsRecording()) {
|
|
+ audioInput->Stop();
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+AudioInputHaiku::AudioInputHaiku()
|
|
+{
|
|
+ fRecorder = NULL;
|
|
+ fRingBuffer = NULL;
|
|
+ isRecording = false;
|
|
+
|
|
+ tgFrameRate = 48000;
|
|
+ tgChannelsCount = 1;
|
|
+ tgBytesPerSample = 2;
|
|
+
|
|
+ status_t error;
|
|
+
|
|
+ fRoster = BMediaRoster::Roster(&error);
|
|
+ if (!fRoster) {
|
|
+ failed=true;
|
|
+ return;
|
|
+ }
|
|
+ error = fRoster->GetAudioInput(&fAudioInputNode);
|
|
+ if (error < B_OK) {
|
|
+ failed=true;
|
|
+ return;
|
|
+ }
|
|
+ error = fRoster->GetAudioMixer(&fAudioMixerNode);
|
|
+ if (error < B_OK) {
|
|
+ failed=true;
|
|
+ return;
|
|
+ }
|
|
+ fRecorder = new BMediaRecorder("Telegram", B_MEDIA_RAW_AUDIO);
|
|
+ if (fRecorder->InitCheck() < B_OK) {
|
|
+ failed=true;
|
|
+ return;
|
|
+ }
|
|
+ media_format output_format;
|
|
+ output_format.type = B_MEDIA_RAW_AUDIO;
|
|
+ output_format.u.raw_audio = media_raw_audio_format::wildcard;
|
|
+ output_format.u.raw_audio.channel_count = 1;
|
|
+ fRecorder->SetAcceptedFormat(output_format);
|
|
+
|
|
+ const int maxInputCount = 64;
|
|
+ dormant_node_info dni[maxInputCount];
|
|
+
|
|
+ int32 real_count = maxInputCount;
|
|
+
|
|
+ error = fRoster->GetDormantNodes(dni, &real_count, 0, &output_format, 0, B_BUFFER_PRODUCER | B_PHYSICAL_INPUT);
|
|
+ if (real_count > maxInputCount)
|
|
+ real_count = maxInputCount;
|
|
+ char selected_name[B_MEDIA_NAME_LENGTH] = "Default input";
|
|
+
|
|
+ for (int i = 0; i < real_count; i++) {
|
|
+ media_node_id ni[12];
|
|
+ int32 ni_count = 12;
|
|
+ error = fRoster->GetInstancesFor(dni[i].addon, dni[i].flavor_id, ni, &ni_count);
|
|
+ if (error == B_OK) {
|
|
+ for (int j = 0; j < ni_count; j++) {
|
|
+ if (ni[j] == fAudioInputNode.node) {
|
|
+ strcpy(selected_name, dni[i].name);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ media_output audioOutput;
|
|
+ if (!fRecorder->IsConnected()) {
|
|
+ int32 count = 0;
|
|
+ error = fRoster->GetFreeOutputsFor(fAudioInputNode, &audioOutput, 1, &count, B_MEDIA_RAW_AUDIO);
|
|
+ if (error < B_OK) {
|
|
+ failed=true;
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (count < 1) {
|
|
+ failed=true;
|
|
+ return;
|
|
+ }
|
|
+ fRecordFormat.u.raw_audio = audioOutput.format.u.raw_audio;
|
|
+ } else {
|
|
+ fRecordFormat.u.raw_audio = fRecorder->AcceptedFormat().u.raw_audio;
|
|
+ }
|
|
+ fRecordFormat.type = B_MEDIA_RAW_AUDIO;
|
|
+
|
|
+ error = fRecorder->SetHooks(RecordData, NotifyRecordData, this);
|
|
+ if (error < B_OK) {
|
|
+ failed=true;
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (!fRecorder->IsConnected()) {
|
|
+ error = fRecorder->Connect(fAudioInputNode, &audioOutput, &fRecordFormat);
|
|
+ if (error < B_OK) {
|
|
+ fRecorder->SetHooks(NULL, NULL, NULL);
|
|
+ failed=true;
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ fRingBuffer = new RingBuffer(BUFFER_SIZE * 2 * 3);
|
|
+ if (fRingBuffer->InitCheck() != B_OK) {
|
|
+ failed=true;
|
|
+ return;
|
|
+ }
|
|
+}
|
|
+
|
|
+AudioInputHaiku::~AudioInputHaiku(){
|
|
+ if (fRecorder != NULL) {
|
|
+ if (fRecorder->InitCheck() == B_OK) {
|
|
+ if (fRecorder->IsConnected())
|
|
+ fRecorder->Disconnect();
|
|
+ }
|
|
+ delete fRecorder;
|
|
+ }
|
|
+ if (fRingBuffer != NULL)
|
|
+ delete fRingBuffer;
|
|
+}
|
|
+
|
|
+void AudioInputHaiku::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
|
|
+ tgFrameRate = sampleRate;
|
|
+ tgChannelsCount = channels;
|
|
+ tgBytesPerSample = bitsPerSample / 8;
|
|
+}
|
|
+
|
|
+bool AudioInputHaiku::IsRecording(){
|
|
+ return isRecording;
|
|
+}
|
|
+
|
|
+void AudioInputHaiku::Start(){
|
|
+ if(failed || isRecording)
|
|
+ return;
|
|
+
|
|
+ isRecording=true;
|
|
+
|
|
+ thread = new Thread(std::bind(&AudioInputHaiku::RunThread, this));
|
|
+ thread->SetName("AudioInputHaiku");
|
|
+ thread->Start();
|
|
+
|
|
+ fRecorder->Start();
|
|
+}
|
|
+
|
|
+void AudioInputHaiku::Stop(){
|
|
+ if(!isRecording)
|
|
+ return;
|
|
+
|
|
+ isRecording=false;
|
|
+
|
|
+ fRecorder->Stop();
|
|
+
|
|
+ thread->Join();
|
|
+ delete thread;
|
|
+ thread=NULL;
|
|
+}
|
|
+
|
|
+void AudioInputHaiku::RunThread(){
|
|
+ unsigned char buffer[BUFFER_SIZE*2];
|
|
+ while (isRecording){
|
|
+ if (fRingBuffer->GetReadAvailable() >= sizeof(buffer)) {
|
|
+ int readed = fRingBuffer->Read(buffer, sizeof(buffer));
|
|
+ if (readed < sizeof(buffer))
|
|
+ memset(buffer + readed, 0, sizeof(buffer) - readed);
|
|
+ InvokeCallback(buffer, sizeof(buffer));
|
|
+ } else
|
|
+ snooze(100);
|
|
+ }
|
|
+}
|
|
diff --git a/Telegram/ThirdParty/libtgvoip/os/haiku/AudioInputHaiku.h b/Telegram/ThirdParty/libtgvoip/os/haiku/AudioInputHaiku.h
|
|
new file mode 100644
|
|
index 0000000..1c63afe
|
|
--- /dev/null
|
|
+++ b/Telegram/ThirdParty/libtgvoip/os/haiku/AudioInputHaiku.h
|
|
@@ -0,0 +1,66 @@
|
|
+//
|
|
+// libtgvoip is free and unencumbered public domain software.
|
|
+// For more information, see http://unlicense.org or the UNLICENSE file
|
|
+// you should have received with this source code distribution.
|
|
+//
|
|
+
|
|
+#ifndef LIBTGVOIP_AUDIOINPUTHAIKU_H
|
|
+#define LIBTGVOIP_AUDIOINPUTHAIKU_H
|
|
+
|
|
+#include "../../audio/AudioInput.h"
|
|
+#include "../../threading.h"
|
|
+
|
|
+#include <OS.h>
|
|
+#include <MediaFile.h>
|
|
+#include <MediaNode.h>
|
|
+#include <MediaRecorder.h>
|
|
+#include <MediaTrack.h>
|
|
+#include <MediaRoster.h>
|
|
+#include <TimeSource.h>
|
|
+#include <NodeInfo.h>
|
|
+#include <MediaAddOn.h>
|
|
+
|
|
+#include "RingBuffer.h"
|
|
+
|
|
+#define BUFFER_SIZE 960
|
|
+
|
|
+namespace tgvoip{
|
|
+namespace audio{
|
|
+
|
|
+class AudioInputHaiku : public AudioInput{
|
|
+
|
|
+public:
|
|
+ AudioInputHaiku();
|
|
+ virtual ~AudioInputHaiku();
|
|
+ virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels);
|
|
+ virtual void Start();
|
|
+ virtual void Stop();
|
|
+ virtual bool IsRecording();
|
|
+
|
|
+ RingBuffer *fRingBuffer;
|
|
+ int16_t workBuffer[BUFFER_SIZE * 64];
|
|
+ int16_t convertBuffer[BUFFER_SIZE * 64];
|
|
+
|
|
+ uint32 tgFrameRate;
|
|
+ uint32 tgChannelsCount;
|
|
+ uint32 tgBytesPerSample;
|
|
+
|
|
+private:
|
|
+ void RunThread();
|
|
+
|
|
+ bool isConfigured;
|
|
+ bool isRecording;
|
|
+
|
|
+ BMediaRoster * fRoster;
|
|
+ BMediaRecorder * fRecorder;
|
|
+ media_format fRecordFormat;
|
|
+ media_node fAudioInputNode;
|
|
+ media_node fAudioMixerNode;
|
|
+
|
|
+ Thread* thread;
|
|
+};
|
|
+
|
|
+}
|
|
+}
|
|
+
|
|
+#endif //LIBTGVOIP_AUDIOINPUTHAIKU_H
|
|
diff --git a/Telegram/ThirdParty/libtgvoip/os/haiku/AudioOutputHaiku.cpp b/Telegram/ThirdParty/libtgvoip/os/haiku/AudioOutputHaiku.cpp
|
|
new file mode 100644
|
|
index 0000000..2fca8a1
|
|
--- /dev/null
|
|
+++ b/Telegram/ThirdParty/libtgvoip/os/haiku/AudioOutputHaiku.cpp
|
|
@@ -0,0 +1,99 @@
|
|
+//
|
|
+// libtgvoip is free and unencumbered public domain software.
|
|
+// For more information, see http://unlicense.org or the UNLICENSE file
|
|
+// you should have received with this source code distribution.
|
|
+//
|
|
+
|
|
+
|
|
+#include <assert.h>
|
|
+#include <dlfcn.h>
|
|
+#include "AudioOutputHaiku.h"
|
|
+#include "../../logging.h"
|
|
+#include "../../VoIPController.h"
|
|
+
|
|
+#define BUFFER_SIZE 960
|
|
+
|
|
+using namespace tgvoip::audio;
|
|
+
|
|
+static void playerProc(void *cookie, void *buffer, size_t len, const media_raw_audio_format &format)
|
|
+{
|
|
+ AudioOutputHaiku *obj = (AudioOutputHaiku*)cookie;
|
|
+ obj->InvokeCallback((unsigned char*)buffer, len);
|
|
+}
|
|
+
|
|
+
|
|
+AudioOutputHaiku::AudioOutputHaiku(){
|
|
+ soundPlayer = NULL;
|
|
+ isPlaying = false;
|
|
+ isConfigured = false;
|
|
+ Configure(48000, 16, 1);
|
|
+ return;
|
|
+}
|
|
+
|
|
+AudioOutputHaiku::~AudioOutputHaiku(){
|
|
+ if (isConfigured) {
|
|
+ if (soundPlayer != NULL) {
|
|
+ soundPlayer->Stop();
|
|
+ delete soundPlayer;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+void AudioOutputHaiku::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
|
|
+ media_raw_audio_format mediaKitFormat = {
|
|
+ (float)sampleRate,
|
|
+ (uint32)channels,
|
|
+ media_raw_audio_format::B_AUDIO_SHORT,
|
|
+ B_MEDIA_LITTLE_ENDIAN,
|
|
+ (uint32)BUFFER_SIZE * (bitsPerSample / 8) * channels
|
|
+ };
|
|
+
|
|
+ switch (bitsPerSample) {
|
|
+ case 8:
|
|
+ mediaKitFormat.format = media_raw_audio_format::B_AUDIO_CHAR;
|
|
+ break;
|
|
+ case 16:
|
|
+ mediaKitFormat.format = media_raw_audio_format::B_AUDIO_SHORT;
|
|
+ break;
|
|
+ case 32:
|
|
+ mediaKitFormat.format = media_raw_audio_format::B_AUDIO_INT;
|
|
+ break;
|
|
+ default:
|
|
+ mediaKitFormat.format = media_raw_audio_format::B_AUDIO_SHORT;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ soundPlayer = new BSoundPlayer(&mediaKitFormat, "Telegram", playerProc, NULL, (void*)this);
|
|
+
|
|
+ if(soundPlayer->InitCheck() != B_OK) {
|
|
+ delete soundPlayer;
|
|
+ soundPlayer = NULL;
|
|
+ isPlaying = false;
|
|
+ failed = true;
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ isConfigured = true;
|
|
+}
|
|
+
|
|
+void AudioOutputHaiku::Start(){
|
|
+ if(soundPlayer == NULL || isPlaying)
|
|
+ return;
|
|
+
|
|
+ soundPlayer->Start();
|
|
+ soundPlayer->SetHasData(true);
|
|
+
|
|
+ isPlaying=true;
|
|
+}
|
|
+
|
|
+void AudioOutputHaiku::Stop(){
|
|
+ if(!isPlaying)
|
|
+ return;
|
|
+
|
|
+ soundPlayer->Stop();
|
|
+ isPlaying=false;
|
|
+}
|
|
+
|
|
+bool AudioOutputHaiku::IsPlaying(){
|
|
+ return isPlaying;
|
|
+}
|
|
diff --git a/Telegram/ThirdParty/libtgvoip/os/haiku/AudioOutputHaiku.h b/Telegram/ThirdParty/libtgvoip/os/haiku/AudioOutputHaiku.h
|
|
new file mode 100644
|
|
index 0000000..91f2521
|
|
--- /dev/null
|
|
+++ b/Telegram/ThirdParty/libtgvoip/os/haiku/AudioOutputHaiku.h
|
|
@@ -0,0 +1,35 @@
|
|
+//
|
|
+// libtgvoip is free and unencumbered public domain software.
|
|
+// For more information, see http://unlicense.org or the UNLICENSE file
|
|
+// you should have received with this source code distribution.
|
|
+//
|
|
+
|
|
+#ifndef LIBTGVOIP_AUDIOOUTPUTHAIKU_H
|
|
+#define LIBTGVOIP_AUDIOOUTPUTHAIKU_H
|
|
+
|
|
+#include "../../audio/AudioOutput.h"
|
|
+#include "../../threading.h"
|
|
+
|
|
+#include <SoundPlayer.h>
|
|
+
|
|
+namespace tgvoip{
|
|
+namespace audio{
|
|
+
|
|
+class AudioOutputHaiku : public AudioOutput{
|
|
+public:
|
|
+ AudioOutputHaiku();
|
|
+ virtual ~AudioOutputHaiku();
|
|
+ virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels);
|
|
+ virtual void Start();
|
|
+ virtual void Stop();
|
|
+ virtual bool IsPlaying() override;
|
|
+private:
|
|
+ bool isPlaying;
|
|
+ bool isConfigured;
|
|
+ BSoundPlayer *soundPlayer;
|
|
+};
|
|
+
|
|
+}
|
|
+}
|
|
+
|
|
+#endif //LIBTGVOIP_AUDIOOUTPUTHAIKU_H
|
|
diff --git a/Telegram/ThirdParty/libtgvoip/os/haiku/RingBuffer.cpp b/Telegram/ThirdParty/libtgvoip/os/haiku/RingBuffer.cpp
|
|
new file mode 100644
|
|
index 0000000..6c94933
|
|
--- /dev/null
|
|
+++ b/Telegram/ThirdParty/libtgvoip/os/haiku/RingBuffer.cpp
|
|
@@ -0,0 +1,136 @@
|
|
+//
|
|
+// libtgvoip is free and unencumbered public domain software.
|
|
+// For more information, see http://unlicense.org or the UNLICENSE file
|
|
+// you should have received with this source code distribution.
|
|
+//
|
|
+
|
|
+#include <stdio.h>
|
|
+#include <stdlib.h>
|
|
+#include <string.h>
|
|
+#include <OS.h>
|
|
+
|
|
+#include "RingBuffer.h"
|
|
+
|
|
+RingBuffer::RingBuffer( int size )
|
|
+{
|
|
+ initialized = false;
|
|
+ Buffer = new unsigned char[size];
|
|
+ if(Buffer!=NULL) {
|
|
+ memset( Buffer, 0, size );
|
|
+ BufferSize = size;
|
|
+ } else {
|
|
+ BufferSize = 0;
|
|
+ }
|
|
+ reader = 0;
|
|
+ writer = 0;
|
|
+ writeBytesAvailable = size;
|
|
+ if((locker=create_sem(1,"locker")) >= B_OK) {
|
|
+ initialized = true;
|
|
+ } else {
|
|
+ if(Buffer!=NULL) {
|
|
+ delete[] Buffer;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+RingBuffer::~RingBuffer( )
|
|
+{
|
|
+ if(initialized) {
|
|
+ delete[] Buffer;
|
|
+ delete_sem(locker);
|
|
+ }
|
|
+}
|
|
+
|
|
+bool
|
|
+RingBuffer::Empty( void )
|
|
+{
|
|
+ memset( Buffer, 0, BufferSize );
|
|
+ reader = 0;
|
|
+ writer = 0;
|
|
+ writeBytesAvailable = BufferSize;
|
|
+ return true;
|
|
+}
|
|
+
|
|
+int
|
|
+RingBuffer::Read( unsigned char *data, int size )
|
|
+{
|
|
+ acquire_sem(locker);
|
|
+
|
|
+ if( data == 0 || size <= 0 || writeBytesAvailable == BufferSize ) {
|
|
+ release_sem(locker);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ int readBytesAvailable = BufferSize - writeBytesAvailable;
|
|
+
|
|
+ if( size > readBytesAvailable ) {
|
|
+ size = readBytesAvailable;
|
|
+ }
|
|
+
|
|
+ if(size > BufferSize - reader) {
|
|
+ int len = BufferSize - reader;
|
|
+ memcpy(data, Buffer + reader, len);
|
|
+ memcpy(data + len, Buffer, size-len);
|
|
+ } else {
|
|
+ memcpy(data, Buffer + reader, size);
|
|
+ }
|
|
+
|
|
+ reader = (reader + size) % BufferSize;
|
|
+ writeBytesAvailable += size;
|
|
+
|
|
+ release_sem(locker);
|
|
+ return size;
|
|
+}
|
|
+
|
|
+int
|
|
+RingBuffer::Write( unsigned char *data, int size )
|
|
+{
|
|
+ acquire_sem(locker);
|
|
+
|
|
+ if( data == 0 || size <= 0 || writeBytesAvailable == 0 ) {
|
|
+ release_sem(locker);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ if( size > writeBytesAvailable ) {
|
|
+ size = writeBytesAvailable;
|
|
+ }
|
|
+
|
|
+ if(size > BufferSize - writer) {
|
|
+ int len = BufferSize - writer;
|
|
+ memcpy(Buffer + writer, data, len);
|
|
+ memcpy(Buffer, data+len, size-len);
|
|
+ } else {
|
|
+ memcpy(Buffer + writer, data, size);
|
|
+ }
|
|
+
|
|
+ writer = (writer + size) % BufferSize;
|
|
+ writeBytesAvailable -= size;
|
|
+
|
|
+ release_sem(locker);
|
|
+ return size;
|
|
+}
|
|
+
|
|
+int
|
|
+RingBuffer::GetSize( void )
|
|
+{
|
|
+ return BufferSize;
|
|
+}
|
|
+
|
|
+int
|
|
+RingBuffer::GetWriteAvailable( void )
|
|
+{
|
|
+ return writeBytesAvailable;
|
|
+}
|
|
+
|
|
+int
|
|
+RingBuffer::GetReadAvailable( void )
|
|
+{
|
|
+ return BufferSize - writeBytesAvailable;
|
|
+}
|
|
+
|
|
+status_t
|
|
+RingBuffer::InitCheck( void )
|
|
+{
|
|
+ return initialized?B_OK:B_ERROR;
|
|
+}
|
|
diff --git a/Telegram/ThirdParty/libtgvoip/os/haiku/RingBuffer.h b/Telegram/ThirdParty/libtgvoip/os/haiku/RingBuffer.h
|
|
new file mode 100644
|
|
index 0000000..01f6096
|
|
--- /dev/null
|
|
+++ b/Telegram/ThirdParty/libtgvoip/os/haiku/RingBuffer.h
|
|
@@ -0,0 +1,37 @@
|
|
+//
|
|
+// libtgvoip is free and unencumbered public domain software.
|
|
+// For more information, see http://unlicense.org or the UNLICENSE file
|
|
+// you should have received with this source code distribution.
|
|
+//
|
|
+
|
|
+#ifndef __RING_BUFFER_H__
|
|
+#define __RING_BUFFER_H__
|
|
+
|
|
+#include <OS.h>
|
|
+
|
|
+class RingBuffer {
|
|
+
|
|
+public:
|
|
+ RingBuffer(int size);
|
|
+ ~RingBuffer();
|
|
+ int Read( unsigned char* dataPtr, int numBytes );
|
|
+ int Write( unsigned char *dataPtr, int numBytes );
|
|
+
|
|
+ bool Empty( void );
|
|
+ int GetSize( );
|
|
+ int GetWriteAvailable( );
|
|
+ int GetReadAvailable( );
|
|
+ status_t InitCheck( );
|
|
+private:
|
|
+ unsigned char *Buffer;
|
|
+ int BufferSize;
|
|
+ int reader;
|
|
+ int writer;
|
|
+ int writeBytesAvailable;
|
|
+
|
|
+ sem_id locker;
|
|
+
|
|
+ bool initialized;
|
|
+};
|
|
+
|
|
+#endif
|
|
diff --git a/Telegram/ThirdParty/libtgvoip/os/posix/NetworkSocketPosix.cpp b/Telegram/ThirdParty/libtgvoip/os/posix/NetworkSocketPosix.cpp
|
|
index 78e0583..81bf9fc 100644
|
|
--- a/Telegram/ThirdParty/libtgvoip/os/posix/NetworkSocketPosix.cpp
|
|
+++ b/Telegram/ThirdParty/libtgvoip/os/posix/NetworkSocketPosix.cpp
|
|
@@ -248,12 +248,13 @@ void NetworkSocketPosix::Open(){
|
|
}
|
|
int flag=0;
|
|
int res=setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag));
|
|
+#ifndef __HAIKU__
|
|
if(res<0){
|
|
LOGE("error enabling dual stack socket: %d / %s", errno, strerror(errno));
|
|
failed=true;
|
|
return;
|
|
}
|
|
-
|
|
+#endif
|
|
SetMaxPriority();
|
|
fcntl(fd, F_SETFL, O_NONBLOCK);
|
|
|
|
@@ -403,6 +404,8 @@ std::string NetworkSocketPosix::GetLocalInterfaceInfo(IPv4Address *v4addr, IPv6A
|
|
if(didAttach){
|
|
sharedJVM->DetachCurrentThread();
|
|
}
|
|
+#elif defined(__HAIKU__)
|
|
+ return name;
|
|
#else
|
|
struct ifaddrs* interfaces;
|
|
if(!getifaddrs(&interfaces)){
|
|
diff --git a/Telegram/ThirdParty/libtgvoip/threading.h b/Telegram/ThirdParty/libtgvoip/threading.h
|
|
old mode 100755
|
|
new mode 100644
|
|
index f6163e9..23e6b48
|
|
--- a/Telegram/ThirdParty/libtgvoip/threading.h
|
|
+++ b/Telegram/ThirdParty/libtgvoip/threading.h
|
|
@@ -9,7 +9,7 @@
|
|
|
|
#include <functional>
|
|
|
|
-#if defined(_POSIX_THREADS) || defined(_POSIX_VERSION) || defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
|
|
+#if defined(_POSIX_THREADS) || defined(_POSIX_VERSION) || defined(__unix__) || defined(__unix) || defined(__HAIKU__) || (defined(__APPLE__) && defined(__MACH__))
|
|
|
|
#include <pthread.h>
|
|
#include <semaphore.h>
|
|
@@ -92,6 +92,7 @@ namespace tgvoip{
|
|
static void* ActualEntryPoint(void* arg){
|
|
Thread* self=reinterpret_cast<Thread*>(arg);
|
|
if(self->name){
|
|
+#ifndef __HAIKU__
|
|
#if !defined(__APPLE__) && !defined(__gnu_hurd__)
|
|
pthread_setname_np(self->thread, self->name);
|
|
#elif !defined(__gnu_hurd__)
|
|
@@ -100,6 +101,7 @@ namespace tgvoip{
|
|
DarwinSpecific::SetCurrentThreadPriority(DarwinSpecific::THREAD_PRIO_USER_INTERACTIVE);
|
|
}
|
|
#endif
|
|
+#endif //__HAIKU__
|
|
}
|
|
self->entry();
|
|
return NULL;
|
|
diff --git a/Telegram/ThirdParty/libtgvoip/webrtc_dsp/rtc_base/logging_webrtc.cc b/Telegram/ThirdParty/libtgvoip/webrtc_dsp/rtc_base/logging_webrtc.cc
|
|
old mode 100755
|
|
new mode 100644
|
|
index a8d1522..991241b
|
|
--- a/Telegram/ThirdParty/libtgvoip/webrtc_dsp/rtc_base/logging_webrtc.cc
|
|
+++ b/Telegram/ThirdParty/libtgvoip/webrtc_dsp/rtc_base/logging_webrtc.cc
|
|
@@ -28,6 +28,10 @@
|
|
static const int kMaxLogLineSize = 1024 - 60;
|
|
#endif // WEBRTC_MAC && !defined(WEBRTC_IOS) || WEBRTC_ANDROID
|
|
|
|
+#if defined(WEBRTC_HAIKU)
|
|
+#include <OS.h>
|
|
+#endif
|
|
+
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
@@ -120,7 +124,12 @@ LogMessage::LogMessage(const char* file,
|
|
|
|
if (thread_) {
|
|
PlatformThreadId id = CurrentThreadId();
|
|
+#if defined(WEBRTC_HAIKU)
|
|
+ thread_id tid = get_pthread_thread_id(id);
|
|
+ print_stream_ << "[" << tid << "] ";
|
|
+#else
|
|
print_stream_ << "[" << id << "] ";
|
|
+#endif
|
|
}
|
|
|
|
if (file != nullptr) {
|
|
diff --git a/Telegram/ThirdParty/libtgvoip/webrtc_dsp/rtc_base/platform_file.h b/Telegram/ThirdParty/libtgvoip/webrtc_dsp/rtc_base/platform_file.h
|
|
old mode 100755
|
|
new mode 100644
|
|
diff --git a/Telegram/ThirdParty/libtgvoip/webrtc_dsp/rtc_base/platform_thread_types.cc b/Telegram/ThirdParty/libtgvoip/webrtc_dsp/rtc_base/platform_thread_types.cc
|
|
index 70cf237..e48948e 100644
|
|
--- a/Telegram/ThirdParty/libtgvoip/webrtc_dsp/rtc_base/platform_thread_types.cc
|
|
+++ b/Telegram/ThirdParty/libtgvoip/webrtc_dsp/rtc_base/platform_thread_types.cc
|
|
@@ -20,6 +20,8 @@ namespace rtc {
|
|
PlatformThreadId CurrentThreadId() {
|
|
#if defined(WEBRTC_WIN)
|
|
return GetCurrentThreadId();
|
|
+#elif defined(WEBRTC_HAIKU)
|
|
+ return pthread_self();
|
|
#elif defined(WEBRTC_POSIX)
|
|
#if defined(WEBRTC_MAC) || defined(WEBRTC_IOS)
|
|
return pthread_mach_thread_np(pthread_self());
|
|
diff --git a/Telegram/ThirdParty/libtgvoip/webrtc_dsp/rtc_base/platform_thread_types.h b/Telegram/ThirdParty/libtgvoip/webrtc_dsp/rtc_base/platform_thread_types.h
|
|
index 0bc42eb..c87cde9 100644
|
|
--- a/Telegram/ThirdParty/libtgvoip/webrtc_dsp/rtc_base/platform_thread_types.h
|
|
+++ b/Telegram/ThirdParty/libtgvoip/webrtc_dsp/rtc_base/platform_thread_types.h
|
|
@@ -35,6 +35,9 @@ typedef DWORD PlatformThreadRef;
|
|
#elif defined(WEBRTC_FUCHSIA)
|
|
typedef zx_handle_t PlatformThreadId;
|
|
typedef zx_handle_t PlatformThreadRef;
|
|
+#elif defined(WEBRTC_HAIKU)
|
|
+typedef pthread_t PlatformThreadId;
|
|
+typedef pthread_t PlatformThreadRef;
|
|
#elif defined(WEBRTC_POSIX)
|
|
typedef pid_t PlatformThreadId;
|
|
typedef pthread_t PlatformThreadRef;
|
|
diff --git a/Telegram/cmake/lib_tgvoip.cmake b/Telegram/cmake/lib_tgvoip.cmake
|
|
index 215ac73..c247275 100644
|
|
--- a/Telegram/cmake/lib_tgvoip.cmake
|
|
+++ b/Telegram/cmake/lib_tgvoip.cmake
|
|
@@ -120,6 +120,14 @@ else()
|
|
os/linux/AudioPulse.cpp
|
|
os/linux/AudioPulse.h
|
|
|
|
+ # Haiku
|
|
+ os/haiku/AudioInputHaiku.cpp
|
|
+ os/haiku/AudioInputHaiku.h
|
|
+ os/haiku/AudioOutputHaiku.cpp
|
|
+ os/haiku/AudioOutputHaiku.h
|
|
+ os/haiku/RingBuffer.cpp
|
|
+ os/haiku/RingBuffer.h
|
|
+
|
|
# POSIX
|
|
os/posix/NetworkSocketPosix.cpp
|
|
os/posix/NetworkSocketPosix.h
|
|
@@ -762,6 +770,20 @@ else()
|
|
TGVOIP_NO_OSX_PRIVATE_API
|
|
)
|
|
endif()
|
|
+ elseif (HAIKU)
|
|
+ target_compile_options(lib_tgvoip
|
|
+ PRIVATE
|
|
+ -Wno-unknown-pragmas
|
|
+ -Wno-error=sequence-point
|
|
+ -Wno-error=unused-result
|
|
+ -mmmx
|
|
+ -msse2
|
|
+ )
|
|
+ target_compile_definitions(lib_tgvoip
|
|
+ PUBLIC
|
|
+ WEBRTC_POSIX
|
|
+ WEBRTC_HAIKU
|
|
+ )
|
|
else()
|
|
target_compile_options(lib_tgvoip
|
|
PRIVATE
|
|
diff --git a/Telegram/lib_base/CMakeLists.txt b/Telegram/lib_base/CMakeLists.txt
|
|
index e4ea6be..a728127 100644
|
|
--- a/Telegram/lib_base/CMakeLists.txt
|
|
+++ b/Telegram/lib_base/CMakeLists.txt
|
|
@@ -56,6 +56,18 @@ PRIVATE
|
|
base/platform/win/base_url_scheme_win.cpp
|
|
base/platform/win/base_url_scheme_win.h
|
|
base/platform/win/base_windows_h.h
|
|
+ base/platform/haiku/base_file_utilities_haiku.cpp
|
|
+ base/platform/haiku/base_file_utilities_haiku.h
|
|
+ base/platform/haiku/base_info_haiku.cpp
|
|
+ base/platform/haiku/base_info_haiku.h
|
|
+ base/platform/haiku/base_last_input_haiku.cpp
|
|
+ base/platform/haiku/base_last_input_haiku.h
|
|
+ base/platform/haiku/base_layout_switch_haiku.cpp
|
|
+ base/platform/haiku/base_layout_switch_haiku.h
|
|
+ base/platform/haiku/base_process_haiku.cpp
|
|
+ base/platform/haiku/base_process_haiku.h
|
|
+ base/platform/haiku/base_url_scheme_haiku.cpp
|
|
+ base/platform/haiku/base_url_scheme_haiku.h
|
|
base/platform/base_platform_info.h
|
|
base/platform/base_platform_last_input.h
|
|
base/platform/base_platform_layout_switch.h
|
|
@@ -143,7 +155,7 @@ PUBLIC
|
|
desktop-app::lib_crl
|
|
desktop-app::external_qt
|
|
desktop-app::external_openssl
|
|
- desktop-app::external_crash_reports
|
|
+# desktop-app::external_crash_reports
|
|
desktop-app::external_variant
|
|
desktop-app::external_ranges
|
|
desktop-app::external_gsl
|
|
diff --git a/Telegram/lib_base/base/crash_report_writer.cpp b/Telegram/lib_base/base/crash_report_writer.cpp
|
|
index 963a720..d67d6c3 100644
|
|
--- a/Telegram/lib_base/base/crash_report_writer.cpp
|
|
+++ b/Telegram/lib_base/base/crash_report_writer.cpp
|
|
@@ -107,6 +107,8 @@ const char *PlatformString() {
|
|
return "Linux32Bit";
|
|
} else if (Platform::IsLinux64Bit()) {
|
|
return "Linux64bit";
|
|
+ } else if (Platform::IsHaiku()) {
|
|
+ return "Haiku";
|
|
}
|
|
Unexpected("Platform in CrashReports::PlatformString.");
|
|
}
|
|
@@ -243,7 +245,7 @@ void SignalHandler(int signum) {
|
|
ReportingThreadId = nullptr;
|
|
}
|
|
|
|
-bool SetSignalHandlers = Platform::IsLinux() || Platform::IsMac();
|
|
+bool SetSignalHandlers = Platform::IsLinux() || Platform::IsMac() || Platform::IsHaiku();
|
|
bool CrashLogged = false;
|
|
|
|
#ifdef USE_BREAKPAD
|
|
diff --git a/Telegram/lib_base/base/platform/base_platform_file_utilities.h b/Telegram/lib_base/base/platform/base_platform_file_utilities.h
|
|
index d9ec560..e5076b5 100644
|
|
--- a/Telegram/lib_base/base/platform/base_platform_file_utilities.h
|
|
+++ b/Telegram/lib_base/base/platform/base_platform_file_utilities.h
|
|
@@ -22,8 +22,10 @@ void RemoveQuarantine(const QString &path);
|
|
|
|
#ifdef Q_OS_MAC
|
|
#include "base/platform/mac/base_file_utilities_mac.h"
|
|
-#elif defined Q_OS_LINUX // Q_OS_MAC
|
|
+#elif defined Q_OS_HAIKU // Q_OS_MAC
|
|
+#include "base/platform/haiku/base_file_utilities_haiku.h"
|
|
+#elif defined Q_OS_LINUX // Q_OS_MAC || Q_OS_LINUX
|
|
#include "base/platform/linux/base_file_utilities_linux.h"
|
|
-#elif defined Q_OS_WINRT || defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX
|
|
+#elif defined Q_OS_WINRT || defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX || Q_OS_HAIKU
|
|
#include "base/platform/win/base_file_utilities_win.h"
|
|
-#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT || Q_OS_WIN
|
|
+#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT || Q_OS_WIN || Q_OS_HAIKU
|
|
diff --git a/Telegram/lib_base/base/platform/base_platform_info.h b/Telegram/lib_base/base/platform/base_platform_info.h
|
|
index 37b0b76..d7a5a2c 100644
|
|
--- a/Telegram/lib_base/base/platform/base_platform_info.h
|
|
+++ b/Telegram/lib_base/base/platform/base_platform_info.h
|
|
@@ -46,6 +46,8 @@ namespace Platform {
|
|
[[nodiscard]] constexpr bool IsLinux32Bit();
|
|
[[nodiscard]] constexpr bool IsLinux64Bit();
|
|
|
|
+[[nodiscard]] constexpr bool IsHaiku();
|
|
+
|
|
void Start(QJsonObject settings);
|
|
void Finish();
|
|
|
|
@@ -53,8 +55,10 @@ void Finish();
|
|
|
|
#ifdef Q_OS_MAC
|
|
#include "base/platform/mac/base_info_mac.h"
|
|
-#elif defined Q_OS_LINUX // Q_OS_MAC
|
|
+#elif defined Q_OS_HAIKU // Q_OS_MAC
|
|
+#include "base/platform/haiku/base_info_haiku.h"
|
|
+#elif defined Q_OS_LINUX // Q_OS_MAC || Q_OS_LINUX
|
|
#include "base/platform/linux/base_info_linux.h"
|
|
-#elif defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX
|
|
+#elif defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX || Q_OS_HAIKU
|
|
#include "base/platform/win/base_info_win.h"
|
|
-#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WIN
|
|
+#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WIN || Q_OS_HAIKU
|
|
diff --git a/Telegram/lib_base/base/platform/haiku/base_file_utilities_haiku.cpp b/Telegram/lib_base/base/platform/haiku/base_file_utilities_haiku.cpp
|
|
new file mode 100644
|
|
index 0000000..2e18272
|
|
--- /dev/null
|
|
+++ b/Telegram/lib_base/base/platform/haiku/base_file_utilities_haiku.cpp
|
|
@@ -0,0 +1,77 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2020 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#include "base/platform/haiku/base_file_utilities_haiku.h"
|
|
+
|
|
+#include "base/platform/base_platform_file_utilities.h"
|
|
+#include "base/algorithm.h"
|
|
+
|
|
+#include <QtCore/QProcess>
|
|
+#include <QtCore/QFileInfo>
|
|
+#include <QtCore/QDir>
|
|
+
|
|
+#include <sys/types.h>
|
|
+#include <sys/stat.h>
|
|
+#include <unistd.h>
|
|
+#include <dirent.h>
|
|
+
|
|
+namespace base::Platform {
|
|
+
|
|
+bool ShowInFolder(const QString &filepath) {
|
|
+ const auto absolutePath = QFileInfo(filepath).absoluteFilePath();
|
|
+ QProcess process;
|
|
+ auto command = QString("open");
|
|
+ auto arguments = QStringList();
|
|
+ arguments << QFileInfo(filepath).absoluteDir().absolutePath();
|
|
+ return process.startDetached(command, arguments);
|
|
+}
|
|
+
|
|
+QString CurrentExecutablePath(int argc, char *argv[]) {
|
|
+ return argc ? QFile::decodeName(argv[0]) : QString();
|
|
+}
|
|
+
|
|
+void RemoveQuarantine(const QString &path) {
|
|
+}
|
|
+
|
|
+bool DeleteDirectory(QString path) {
|
|
+ if (path.endsWith('/')) {
|
|
+ path.chop(1);
|
|
+ }
|
|
+ const auto pathRaw = QFile::encodeName(path);
|
|
+ const auto d = opendir(pathRaw.constData());
|
|
+ if (!d) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ while (struct dirent *p = readdir(d)) {
|
|
+ if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, ".."))
|
|
+ continue;
|
|
+ const auto fname = path + '/' + p->d_name;
|
|
+ const auto encoded = QFile::encodeName(fname);
|
|
+ struct stat statbuf;
|
|
+ if (!stat(encoded.constData(), &statbuf)) {
|
|
+ if (S_ISDIR(statbuf.st_mode)) {
|
|
+ if (!DeleteDirectory(fname)) {
|
|
+ closedir(d);
|
|
+ return false;
|
|
+ }
|
|
+ } else {
|
|
+ if (unlink(encoded.constData())) {
|
|
+ closedir(d);
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ closedir(d);
|
|
+
|
|
+ return !rmdir(pathRaw.constData());
|
|
+}
|
|
+
|
|
+} // namespace base::Platform
|
|
diff --git a/Telegram/lib_base/base/platform/haiku/base_file_utilities_haiku.h b/Telegram/lib_base/base/platform/haiku/base_file_utilities_haiku.h
|
|
new file mode 100644
|
|
index 0000000..3b2d42b
|
|
--- /dev/null
|
|
+++ b/Telegram/lib_base/base/platform/haiku/base_file_utilities_haiku.h
|
|
@@ -0,0 +1,20 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2020 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include <QtCore/QString>
|
|
+
|
|
+namespace base::Platform {
|
|
+
|
|
+inline QString FileNameFromUserString(QString name) {
|
|
+ return name;
|
|
+}
|
|
+
|
|
+} // namespace base::Platform
|
|
diff --git a/Telegram/lib_base/base/platform/haiku/base_info_haiku.cpp b/Telegram/lib_base/base/platform/haiku/base_info_haiku.cpp
|
|
new file mode 100644
|
|
index 0000000..cce9d25
|
|
--- /dev/null
|
|
+++ b/Telegram/lib_base/base/platform/haiku/base_info_haiku.cpp
|
|
@@ -0,0 +1,75 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2020 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#include "base/platform/haiku/base_info_haiku.h"
|
|
+
|
|
+#include <QtCore/QJsonObject>
|
|
+#include <QtCore/QLocale>
|
|
+#include <QtCore/QFile>
|
|
+#include <QtCore/QProcess>
|
|
+#include <QtCore/QVersionNumber>
|
|
+#include <QtCore/QDate>
|
|
+
|
|
+namespace Platform {
|
|
+namespace {
|
|
+
|
|
+void FallbackFontConfig(
|
|
+ const QString &from,
|
|
+ const QString &to,
|
|
+ bool overwrite) {
|
|
+}
|
|
+
|
|
+} // namespace
|
|
+
|
|
+QString DeviceModelPretty() {
|
|
+ return "PC";
|
|
+}
|
|
+
|
|
+QString SystemVersionPretty() {
|
|
+ return "Haiku";
|
|
+}
|
|
+
|
|
+QString SystemCountry() {
|
|
+ return QLocale::system().name().split('_').last();
|
|
+}
|
|
+
|
|
+QString SystemLanguage() {
|
|
+ const auto system = QLocale::system();
|
|
+ const auto languages = system.uiLanguages();
|
|
+ return languages.isEmpty()
|
|
+ ? system.name().split('_').first()
|
|
+ : languages.front();
|
|
+}
|
|
+
|
|
+QDate WhenSystemBecomesOutdated() {
|
|
+ return QDate();
|
|
+}
|
|
+
|
|
+int AutoUpdateVersion() {
|
|
+ return 2;
|
|
+}
|
|
+
|
|
+QString AutoUpdateKey() {
|
|
+ return "haiku";
|
|
+}
|
|
+
|
|
+void Start(QJsonObject options) {
|
|
+ const auto from = options.value("custom_font_config_src").toString();
|
|
+ const auto to = options.value("custom_font_config_dst").toString();
|
|
+ if (!from.isEmpty() && !to.isEmpty()) {
|
|
+ const auto keep = options.value("custom_font_config_keep").toInt();
|
|
+ const auto overwrite = (keep != 1);
|
|
+ FallbackFontConfig(from, to, overwrite);
|
|
+ }
|
|
+}
|
|
+
|
|
+void Finish() {
|
|
+}
|
|
+
|
|
+} // namespace Platform
|
|
diff --git a/Telegram/lib_base/base/platform/haiku/base_info_haiku.h b/Telegram/lib_base/base/platform/haiku/base_info_haiku.h
|
|
new file mode 100644
|
|
index 0000000..a3a44e4
|
|
--- /dev/null
|
|
+++ b/Telegram/lib_base/base/platform/haiku/base_info_haiku.h
|
|
@@ -0,0 +1,42 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2020 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include "base/platform/base_platform_info.h"
|
|
+
|
|
+namespace Platform {
|
|
+
|
|
+inline constexpr bool IsHaiku() { return true;}
|
|
+
|
|
+inline constexpr bool IsLinux() { return false;}
|
|
+inline constexpr bool IsLinux32Bit() { return false; }
|
|
+inline constexpr bool IsLinux64Bit() { return false; }
|
|
+inline constexpr bool IsWindows() { return false; }
|
|
+inline constexpr bool IsWindowsStoreBuild() { return false; }
|
|
+inline bool IsWindowsXPOrGreater() { return false; }
|
|
+inline bool IsWindowsVistaOrGreater() { return false; }
|
|
+inline bool IsWindows7OrGreater() { return false; }
|
|
+inline bool IsWindows8OrGreater() { return false; }
|
|
+inline bool IsWindows8Point1OrGreater() { return false; }
|
|
+inline bool IsWindows10OrGreater() { return false; }
|
|
+inline constexpr bool IsMac() { return false; }
|
|
+inline constexpr bool IsOSXBuild() { return false; }
|
|
+inline constexpr bool IsMacStoreBuild() { return false; }
|
|
+inline bool IsMac10_6OrGreater() { return false; }
|
|
+inline bool IsMac10_7OrGreater() { return false; }
|
|
+inline bool IsMac10_8OrGreater() { return false; }
|
|
+inline bool IsMac10_9OrGreater() { return false; }
|
|
+inline bool IsMac10_10OrGreater() { return false; }
|
|
+inline bool IsMac10_11OrGreater() { return false; }
|
|
+inline bool IsMac10_12OrGreater() { return false; }
|
|
+inline bool IsMac10_13OrGreater() { return false; }
|
|
+inline bool IsMac10_14OrGreater() { return false; }
|
|
+
|
|
+} // namespace Platform
|
|
diff --git a/Telegram/lib_base/base/platform/haiku/base_last_input_haiku.cpp b/Telegram/lib_base/base/platform/haiku/base_last_input_haiku.cpp
|
|
new file mode 100644
|
|
index 0000000..8fa3e9f
|
|
--- /dev/null
|
|
+++ b/Telegram/lib_base/base/platform/haiku/base_last_input_haiku.cpp
|
|
@@ -0,0 +1,20 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2020 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#include "base/platform/haiku/base_last_input_haiku.h"
|
|
+
|
|
+#include <optional>
|
|
+
|
|
+namespace base::Platform {
|
|
+
|
|
+std::optional<crl::time> LastUserInputTime() {
|
|
+ return std::nullopt;
|
|
+}
|
|
+
|
|
+} // namespace base::Platform
|
|
diff --git a/Telegram/lib_base/base/platform/haiku/base_last_input_haiku.h b/Telegram/lib_base/base/platform/haiku/base_last_input_haiku.h
|
|
new file mode 100644
|
|
index 0000000..a24adad
|
|
--- /dev/null
|
|
+++ b/Telegram/lib_base/base/platform/haiku/base_last_input_haiku.h
|
|
@@ -0,0 +1,11 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2020 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#pragma once
|
|
+
|
|
diff --git a/Telegram/lib_base/base/platform/haiku/base_layout_switch_haiku.cpp b/Telegram/lib_base/base/platform/haiku/base_layout_switch_haiku.cpp
|
|
new file mode 100644
|
|
index 0000000..533b8ea
|
|
--- /dev/null
|
|
+++ b/Telegram/lib_base/base/platform/haiku/base_layout_switch_haiku.cpp
|
|
@@ -0,0 +1,18 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2020 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#include "base/platform/haiku/base_layout_switch_haiku.h"
|
|
+
|
|
+namespace base::Platform {
|
|
+
|
|
+bool SwitchKeyboardLayoutToEnglish() {
|
|
+ return false;
|
|
+}
|
|
+
|
|
+} // namespace base::Platform
|
|
diff --git a/Telegram/lib_base/base/platform/haiku/base_layout_switch_haiku.h b/Telegram/lib_base/base/platform/haiku/base_layout_switch_haiku.h
|
|
new file mode 100644
|
|
index 0000000..a24adad
|
|
--- /dev/null
|
|
+++ b/Telegram/lib_base/base/platform/haiku/base_layout_switch_haiku.h
|
|
@@ -0,0 +1,11 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2020 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#pragma once
|
|
+
|
|
diff --git a/Telegram/lib_base/base/platform/haiku/base_process_haiku.cpp b/Telegram/lib_base/base/platform/haiku/base_process_haiku.cpp
|
|
new file mode 100644
|
|
index 0000000..6e88f99
|
|
--- /dev/null
|
|
+++ b/Telegram/lib_base/base/platform/haiku/base_process_haiku.cpp
|
|
@@ -0,0 +1,20 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2020 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#include "base/platform/haiku/base_process_haiku.h"
|
|
+
|
|
+namespace base::Platform {
|
|
+
|
|
+void ActivateProcessWindow(int64 pid, WId windowId) {
|
|
+}
|
|
+
|
|
+void ActivateThisProcessWindow(WId windowId) {
|
|
+}
|
|
+
|
|
+} // namespace base::Platform
|
|
diff --git a/Telegram/lib_base/base/platform/haiku/base_process_haiku.h b/Telegram/lib_base/base/platform/haiku/base_process_haiku.h
|
|
new file mode 100644
|
|
index 0000000..4d0bce3
|
|
--- /dev/null
|
|
+++ b/Telegram/lib_base/base/platform/haiku/base_process_haiku.h
|
|
@@ -0,0 +1,12 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2020 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include "base/platform/base_platform_process.h"
|
|
diff --git a/Telegram/lib_base/base/platform/haiku/base_url_scheme_haiku.cpp b/Telegram/lib_base/base/platform/haiku/base_url_scheme_haiku.cpp
|
|
new file mode 100644
|
|
index 0000000..2aec193
|
|
--- /dev/null
|
|
+++ b/Telegram/lib_base/base/platform/haiku/base_url_scheme_haiku.cpp
|
|
@@ -0,0 +1,74 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2020 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#include "base/platform/haiku/base_url_scheme_haiku.h"
|
|
+
|
|
+#include <QtCore/QDir>
|
|
+#include <QtCore/QTextStream>
|
|
+#include <QtCore/QCoreApplication>
|
|
+#include <unistd.h>
|
|
+#include <dirent.h>
|
|
+#include <pwd.h>
|
|
+
|
|
+namespace base::Platform {
|
|
+namespace {
|
|
+
|
|
+[[nodiscard]] QString GetHomeDir() {
|
|
+ const auto result = QDir::homePath();
|
|
+
|
|
+ if (result != QDir::rootPath()) {
|
|
+ return result + '/';
|
|
+ }
|
|
+
|
|
+ struct passwd *pw = getpwuid(getuid());
|
|
+ return (pw && pw->pw_dir && strlen(pw->pw_dir))
|
|
+ ? (QFile::decodeName(pw->pw_dir) + '/')
|
|
+ : QString();
|
|
+}
|
|
+
|
|
+bool RunShellCommand(const QByteArray &command) {
|
|
+ return (system(command.constData()) == 0);
|
|
+}
|
|
+
|
|
+[[nodiscard]] QByteArray EscapeShell(const QByteArray &content) {
|
|
+ auto result = QByteArray();
|
|
+
|
|
+ auto b = content.constData(), e = content.constEnd();
|
|
+ for (auto ch = b; ch != e; ++ch) {
|
|
+ if (*ch == ' ' || *ch == '"' || *ch == '\'' || *ch == '\\') {
|
|
+ if (result.isEmpty()) {
|
|
+ result.reserve(content.size() * 2);
|
|
+ }
|
|
+ if (ch > b) {
|
|
+ result.append(b, ch - b);
|
|
+ }
|
|
+ result.append('\\');
|
|
+ b = ch;
|
|
+ }
|
|
+ }
|
|
+ if (result.isEmpty()) {
|
|
+ return content;
|
|
+ }
|
|
+
|
|
+ if (e > b) {
|
|
+ result.append(b, e - b);
|
|
+ }
|
|
+ return result;
|
|
+}
|
|
+
|
|
+} // namespace
|
|
+
|
|
+bool CheckUrlScheme(const UrlSchemeDescriptor &descriptor) {
|
|
+ return false;
|
|
+}
|
|
+
|
|
+void RegisterUrlScheme(const UrlSchemeDescriptor &descriptor) { }
|
|
+void UnregisterUrlScheme(const UrlSchemeDescriptor &descriptor) { }
|
|
+
|
|
+} // namespace base::Platform
|
|
diff --git a/Telegram/lib_base/base/platform/haiku/base_url_scheme_haiku.h b/Telegram/lib_base/base/platform/haiku/base_url_scheme_haiku.h
|
|
new file mode 100644
|
|
index 0000000..6402509
|
|
--- /dev/null
|
|
+++ b/Telegram/lib_base/base/platform/haiku/base_url_scheme_haiku.h
|
|
@@ -0,0 +1,12 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2018-2020 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include "base/platform/base_platform_url_scheme.h"
|
|
diff --git a/Telegram/lib_crl/CMakeLists.txt b/Telegram/lib_crl/CMakeLists.txt
|
|
index 5e8f33f..bc87ddb 100644
|
|
--- a/Telegram/lib_crl/CMakeLists.txt
|
|
+++ b/Telegram/lib_crl/CMakeLists.txt
|
|
@@ -32,6 +32,7 @@ PRIVATE
|
|
crl/dispatch/crl_dispatch_semaphore.h
|
|
crl/mac/crl_mac_time.cpp
|
|
crl/linux/crl_linux_time.cpp
|
|
+ crl/haiku/crl_haiku_time.cpp
|
|
crl/qt/crl_qt_async.cpp
|
|
crl/qt/crl_qt_async.h
|
|
crl/qt/crl_qt_guards.h
|
|
diff --git a/Telegram/lib_crl/crl/haiku/crl_haiku_time.cpp b/Telegram/lib_crl/crl/haiku/crl_haiku_time.cpp
|
|
new file mode 100644
|
|
index 0000000..f682740
|
|
--- /dev/null
|
|
+++ b/Telegram/lib_crl/crl/haiku/crl_haiku_time.cpp
|
|
@@ -0,0 +1,44 @@
|
|
+// This file is part of Desktop App Toolkit,
|
|
+// a set of libraries for developing nice desktop applications.
|
|
+//
|
|
+// For license and copyright information please follow this link:
|
|
+// https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+//
|
|
+#include <crl/crl_time.h>
|
|
+
|
|
+#ifdef CRL_USE_LINUX_TIME
|
|
+
|
|
+#include <time.h>
|
|
+
|
|
+namespace crl::details {
|
|
+
|
|
+void init() {
|
|
+}
|
|
+
|
|
+inner_time_type current_value() {
|
|
+ timespec ts;
|
|
+ clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
+ const auto seconds = inner_time_type(ts.tv_sec);
|
|
+ const auto milliseconds = inner_time_type(ts.tv_nsec) / 1000000;
|
|
+ return seconds * 1000 + milliseconds;
|
|
+}
|
|
+
|
|
+time convert(inner_time_type value) {
|
|
+ return time(value);
|
|
+}
|
|
+
|
|
+inner_profile_type current_profile_value() {
|
|
+ timespec ts;
|
|
+ clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
+ const auto seconds = inner_profile_type(ts.tv_sec);
|
|
+ const auto milliseconds = inner_profile_type(ts.tv_nsec) / 1000;
|
|
+ return seconds * 1000000 + milliseconds;
|
|
+}
|
|
+
|
|
+profile_time convert_profile(inner_profile_type value) {
|
|
+ return profile_time(value);
|
|
+}
|
|
+
|
|
+} // namespace crl::details
|
|
+
|
|
+#endif // CRL_USE_LINUX_TIME
|
|
diff --git a/Telegram/lib_spellcheck/CMakeLists.txt b/Telegram/lib_spellcheck/CMakeLists.txt
|
|
index 349211f..a326222 100644
|
|
--- a/Telegram/lib_spellcheck/CMakeLists.txt
|
|
+++ b/Telegram/lib_spellcheck/CMakeLists.txt
|
|
@@ -44,6 +44,10 @@ if (system_spellchecker)
|
|
spellcheck/platform/mac/spellcheck_mac.mm
|
|
spellcheck/platform/win/spellcheck_win.cpp
|
|
spellcheck/platform/win/spellcheck_win.h
|
|
+ spellcheck/platform/haiku/haiku_enchant.cpp
|
|
+ spellcheck/platform/haiku/haiku_enchant.h
|
|
+ spellcheck/platform/haiku/spellcheck_haiku.cpp
|
|
+ spellcheck/platform/haiku/spellcheck_haiku.h
|
|
)
|
|
else()
|
|
nice_target_sources(lib_spellcheck ${src_loc}
|
|
@@ -73,7 +77,7 @@ PUBLIC
|
|
desktop-app::lib_ui
|
|
)
|
|
|
|
-if (LINUX AND use_enchant)
|
|
+if ((LINUX OR HAIKU) AND use_enchant)
|
|
find_package(PkgConfig REQUIRED)
|
|
|
|
pkg_search_module(ENCHANT REQUIRED enchant-2 enchant)
|
|
diff --git a/Telegram/lib_spellcheck/spellcheck/platform/haiku/haiku_enchant.cpp b/Telegram/lib_spellcheck/spellcheck/platform/haiku/haiku_enchant.cpp
|
|
new file mode 100644
|
|
index 0000000..cc3db6a
|
|
--- /dev/null
|
|
+++ b/Telegram/lib_spellcheck/spellcheck/platform/haiku/haiku_enchant.cpp
|
|
@@ -0,0 +1,229 @@
|
|
+/* enchant
|
|
+ * Copyright (C) 2003 Dom Lachowicz
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
+ */
|
|
+
|
|
+#include <enchant-2/enchant.h>
|
|
+#include <dlfcn.h>
|
|
+#include "spellcheck/platform/haiku/haiku_enchant.h"
|
|
+
|
|
+namespace {
|
|
+
|
|
+struct {
|
|
+ //decltype (enchant_broker_describe) * broker_describe;
|
|
+ //decltype (enchant_broker_dict_exists) * broker_dict_exists;
|
|
+ decltype (enchant_broker_free) * broker_free;
|
|
+ decltype (enchant_broker_free_dict) * broker_free_dict;
|
|
+ decltype (enchant_broker_get_error) * broker_get_error;
|
|
+ decltype (enchant_broker_init) * broker_init;
|
|
+ decltype (enchant_broker_list_dicts) * broker_list_dicts;
|
|
+ decltype (enchant_broker_request_dict) * broker_request_dict;
|
|
+ //decltype (enchant_broker_request_pwl_dict) * broker_request_pwl_dict;
|
|
+ decltype (enchant_broker_set_ordering) * broker_set_ordering;
|
|
+ decltype (enchant_dict_add) * dict_add;
|
|
+ decltype (enchant_dict_add_to_session) * dict_add_to_session;
|
|
+ decltype (enchant_dict_check) * dict_check;
|
|
+ decltype (enchant_dict_describe) * dict_describe;
|
|
+ decltype (enchant_dict_free_string_list) * dict_free_string_list;
|
|
+ decltype (enchant_dict_get_error) * dict_get_error;
|
|
+ decltype (enchant_dict_is_added) * dict_is_added;
|
|
+ //decltype (enchant_dict_is_removed) * dict_is_removed;
|
|
+ decltype (enchant_dict_remove) * dict_remove;
|
|
+ decltype (enchant_dict_remove_from_session) * dict_remove_from_session;
|
|
+ //decltype (enchant_dict_store_replacement) * dict_store_replacement;
|
|
+ decltype (enchant_dict_suggest) * dict_suggest;
|
|
+} f_enchant;
|
|
+
|
|
+} // anonymous namespace
|
|
+
|
|
+enchant::Exception::Exception (const char * ex)
|
|
+ : std::exception (), m_ex ("") {
|
|
+ if (ex)
|
|
+ m_ex = ex;
|
|
+}
|
|
+
|
|
+enchant::Exception::~Exception () = default;
|
|
+
|
|
+const char * enchant::Exception::what () const noexcept {
|
|
+ return m_ex.c_str();
|
|
+}
|
|
+
|
|
+enchant::Dict::Dict (EnchantDict * dict, EnchantBroker * broker)
|
|
+ : m_dict (dict), m_broker (broker) {
|
|
+ f_enchant.dict_describe (m_dict, s_describe_fn, this);
|
|
+}
|
|
+
|
|
+enchant::Dict::~Dict () {
|
|
+ f_enchant.broker_free_dict (m_broker, m_dict);
|
|
+}
|
|
+
|
|
+bool enchant::Dict::check (const std::string & utf8word) {
|
|
+ int val;
|
|
+
|
|
+ val = f_enchant.dict_check (m_dict, utf8word.c_str(), utf8word.size());
|
|
+ if (val == 0)
|
|
+ return true;
|
|
+ else if (val > 0)
|
|
+ return false;
|
|
+ else {
|
|
+ throw enchant::Exception (f_enchant.dict_get_error (m_dict));
|
|
+ }
|
|
+
|
|
+ return false; // never reached
|
|
+}
|
|
+
|
|
+void enchant::Dict::suggest (const std::string & utf8word,
|
|
+ std::vector<std::string> & out_suggestions) {
|
|
+ size_t n_suggs;
|
|
+ char ** suggs;
|
|
+
|
|
+ out_suggestions.clear ();
|
|
+
|
|
+ suggs = f_enchant.dict_suggest (m_dict, utf8word.c_str(),
|
|
+ utf8word.size(), &n_suggs);
|
|
+
|
|
+ if (suggs && n_suggs) {
|
|
+ out_suggestions.reserve(n_suggs);
|
|
+
|
|
+ for (size_t i = 0; i < n_suggs; i++) {
|
|
+ out_suggestions.push_back (suggs[i]);
|
|
+ }
|
|
+
|
|
+ f_enchant.dict_free_string_list (m_dict, suggs);
|
|
+ }
|
|
+}
|
|
+
|
|
+void enchant::Dict::add (const std::string & utf8word) {
|
|
+ f_enchant.dict_add (m_dict, utf8word.c_str(), utf8word.size());
|
|
+}
|
|
+
|
|
+void enchant::Dict::add_to_session (const std::string & utf8word) {
|
|
+ f_enchant.dict_add_to_session (m_dict, utf8word.c_str(), utf8word.size());
|
|
+}
|
|
+
|
|
+bool enchant::Dict::is_added (const std::string & utf8word) {
|
|
+ return f_enchant.dict_is_added (m_dict, utf8word.c_str(),
|
|
+ utf8word.size());
|
|
+}
|
|
+
|
|
+void enchant::Dict::remove (const std::string & utf8word) {
|
|
+ f_enchant.dict_remove (m_dict, utf8word.c_str(), utf8word.size());
|
|
+}
|
|
+
|
|
+void enchant::Dict::remove_from_session (const std::string & utf8word) {
|
|
+ f_enchant.dict_remove_from_session (m_dict, utf8word.c_str(),
|
|
+ utf8word.size());
|
|
+}
|
|
+
|
|
+//bool enchant::Dict::is_removed (const std::string & utf8word) {
|
|
+// return f_enchant.dict_is_removed (m_dict, utf8word.c_str(),
|
|
+// utf8word.size());
|
|
+//}
|
|
+
|
|
+//void enchant::Dict::store_replacement (const std::string & utf8bad,
|
|
+// const std::string & utf8good) {
|
|
+// f_enchant.dict_store_replacement (m_dict,
|
|
+// utf8bad.c_str(), utf8bad.size(),
|
|
+// utf8good.c_str(), utf8good.size());
|
|
+//}
|
|
+
|
|
+enchant::Broker::Broker ()
|
|
+ : m_broker (f_enchant.broker_init ())
|
|
+ {
|
|
+ }
|
|
+
|
|
+enchant::Broker::~Broker () {
|
|
+ f_enchant.broker_free (m_broker);
|
|
+}
|
|
+
|
|
+enchant::Dict * enchant::Broker::request_dict (const std::string & lang) {
|
|
+ EnchantDict * dict = f_enchant.broker_request_dict (m_broker, lang.c_str());
|
|
+
|
|
+ if (!dict) {
|
|
+ throw enchant::Exception (f_enchant.broker_get_error (m_broker));
|
|
+ return 0; // never reached
|
|
+ }
|
|
+
|
|
+ return new Dict (dict, m_broker);
|
|
+}
|
|
+
|
|
+//enchant::Dict * enchant::Broker::request_pwl_dict (const std::string & pwl) {
|
|
+// EnchantDict * dict = f_enchant.broker_request_pwl_dict (m_broker, pwl.c_str());
|
|
+//
|
|
+// if (!dict) {
|
|
+// throw enchant::Exception (f_enchant.broker_get_error (m_broker));
|
|
+// return 0; // never reached
|
|
+// }
|
|
+//
|
|
+// return new Dict (dict, m_broker);
|
|
+//}
|
|
+
|
|
+//bool enchant::Broker::dict_exists (const std::string & lang) {
|
|
+// if (f_enchant.broker_dict_exists (m_broker, lang.c_str()))
|
|
+// return true;
|
|
+// return false;
|
|
+//}
|
|
+
|
|
+void enchant::Broker::set_ordering (const std::string & tag, const std::string & ordering) {
|
|
+ f_enchant.broker_set_ordering (m_broker, tag.c_str(), ordering.c_str());
|
|
+}
|
|
+
|
|
+//void enchant::Broker::describe (EnchantBrokerDescribeFn fn, void * user_data) {
|
|
+// f_enchant.broker_describe (m_broker, fn, user_data);
|
|
+//}
|
|
+
|
|
+void enchant::Broker::list_dicts (EnchantDictDescribeFn fn, void * user_data) {
|
|
+ f_enchant.broker_list_dicts (m_broker, fn, user_data);
|
|
+}
|
|
+
|
|
+#define GET_SYMBOL_enchant(func_name) do { \
|
|
+ typedef decltype (enchant_ ## func_name) * Fp; \
|
|
+ f_enchant.func_name = reinterpret_cast<Fp> ( dlsym (handle, "enchant_" # func_name)); \
|
|
+ if (!f_enchant.func_name) { \
|
|
+ return false; \
|
|
+ } \
|
|
+} while(0)
|
|
+
|
|
+bool enchant::loader::do_explicit_linking () {
|
|
+ static enum { NotLoadedYet, LoadSuccessful, LoadFailed = -1 } load_status;
|
|
+ if (load_status == NotLoadedYet) {
|
|
+ load_status = LoadFailed;
|
|
+ void * handle = dlopen ("libenchant.so.1", RTLD_NOW)
|
|
+ ?: dlopen ("libenchant-2.so.2", RTLD_NOW)
|
|
+ ?: dlopen ("libenchant.so.2", RTLD_NOW);
|
|
+ if (!handle) {
|
|
+ // logs ?
|
|
+ return false;
|
|
+ }
|
|
+ //GET_SYMBOL_enchant (broker_describe);
|
|
+ //GET_SYMBOL_enchant (broker_dict_exists);
|
|
+ GET_SYMBOL_enchant (broker_free);
|
|
+ GET_SYMBOL_enchant (broker_free_dict);
|
|
+ GET_SYMBOL_enchant (broker_get_error);
|
|
+ GET_SYMBOL_enchant (broker_init);
|
|
+ GET_SYMBOL_enchant (broker_list_dicts);
|
|
+ GET_SYMBOL_enchant (broker_request_dict);
|
|
+ //GET_SYMBOL_enchant (broker_request_pwl_dict);
|
|
+ GET_SYMBOL_enchant (broker_set_ordering);
|
|
+ GET_SYMBOL_enchant (dict_add);
|
|
+ GET_SYMBOL_enchant (dict_add_to_session);
|
|
+ GET_SYMBOL_enchant (dict_check);
|
|
+ GET_SYMBOL_enchant (dict_describe);
|
|
+ GET_SYMBOL_enchant (dict_free_string_list);
|
|
+ GET_SYMBOL_enchant (dict_get_error);
|
|
+ GET_SYMBOL_enchant (dict_is_added);
|
|
+ //GET_SYMBOL_enchant (dict_is_removed);
|
|
+ GET_SYMBOL_enchant (dict_remove);
|
|
+ GET_SYMBOL_enchant (dict_remove_from_session);
|
|
+ //GET_SYMBOL_enchant (dict_store_replacement);
|
|
+ GET_SYMBOL_enchant (dict_suggest);
|
|
+ load_status = LoadSuccessful;
|
|
+ }
|
|
+ return load_status == LoadSuccessful;
|
|
+}
|
|
+
|
|
+// vi: ts=8 sw=8
|
|
diff --git a/Telegram/lib_spellcheck/spellcheck/platform/haiku/haiku_enchant.h b/Telegram/lib_spellcheck/spellcheck/platform/haiku/haiku_enchant.h
|
|
new file mode 100644
|
|
index 0000000..f73f860
|
|
--- /dev/null
|
|
+++ b/Telegram/lib_spellcheck/spellcheck/platform/haiku/haiku_enchant.h
|
|
@@ -0,0 +1,151 @@
|
|
+/* enchant
|
|
+ * Copyright (C) 2003 Dom Lachowicz
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
+ */
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include <string>
|
|
+#include <vector>
|
|
+#include <exception>
|
|
+
|
|
+#ifndef ENCHANT_H
|
|
+typedef struct str_enchant_broker EnchantBroker;
|
|
+typedef struct str_enchant_dict EnchantDict;
|
|
+
|
|
+typedef void (*EnchantBrokerDescribeFn) (const char * const provider_name,
|
|
+ const char * const provider_desc,
|
|
+ const char * const provider_dll_file,
|
|
+ void * user_data);
|
|
+
|
|
+typedef void (*EnchantDictDescribeFn) (const char * const lang_tag,
|
|
+ const char * const provider_name,
|
|
+ const char * const provider_desc,
|
|
+ const char * const provider_file,
|
|
+ void * user_data);
|
|
+#endif // !ENCHANT_H
|
|
+
|
|
+namespace enchant
|
|
+{
|
|
+ class Broker;
|
|
+
|
|
+ class Exception : public std::exception
|
|
+ {
|
|
+ public:
|
|
+ explicit Exception (const char * ex);
|
|
+ virtual ~Exception () noexcept;
|
|
+ virtual const char * what () const noexcept;
|
|
+
|
|
+ private:
|
|
+ std::string m_ex;
|
|
+ };
|
|
+
|
|
+ class Dict
|
|
+ {
|
|
+ friend class enchant::Broker;
|
|
+
|
|
+ public:
|
|
+
|
|
+ ~Dict ();
|
|
+
|
|
+ bool check (const std::string & utf8word);
|
|
+ void suggest (const std::string & utf8word,
|
|
+ std::vector<std::string> & out_suggestions);
|
|
+
|
|
+ std::vector<std::string> suggest (const std::string & utf8word) {
|
|
+ std::vector<std::string> result;
|
|
+ suggest (utf8word, result);
|
|
+ return result;
|
|
+ }
|
|
+
|
|
+ void add (const std::string & utf8word);
|
|
+ void add_to_session (const std::string & utf8word);
|
|
+ bool is_added (const std::string & utf8word);
|
|
+ void remove (const std::string & utf8word);
|
|
+ void remove_from_session (const std::string & utf8word);
|
|
+ bool is_removed (const std::string & utf8word);
|
|
+ void store_replacement (const std::string & utf8bad,
|
|
+ const std::string & utf8good);
|
|
+
|
|
+ const std::string & get_lang () const {
|
|
+ return m_lang;
|
|
+ }
|
|
+
|
|
+ const std::string & get_provider_name () const {
|
|
+ return m_provider_name;
|
|
+ }
|
|
+
|
|
+ const std::string & get_provider_desc () const {
|
|
+ return m_provider_desc;
|
|
+ }
|
|
+
|
|
+ const std::string & get_provider_file () const {
|
|
+ return m_provider_file;
|
|
+ }
|
|
+
|
|
+ private:
|
|
+
|
|
+ void * _private[5];
|
|
+
|
|
+ static void s_describe_fn (const char * const lang,
|
|
+ const char * const provider_name,
|
|
+ const char * const provider_desc,
|
|
+ const char * const provider_file,
|
|
+ void * user_data) {
|
|
+ enchant::Dict * dict = static_cast<enchant::Dict *> (user_data);
|
|
+
|
|
+ dict->m_lang = lang;
|
|
+ dict->m_provider_name = provider_name;
|
|
+ dict->m_provider_desc = provider_desc;
|
|
+ dict->m_provider_file = provider_file;
|
|
+ }
|
|
+
|
|
+ Dict (EnchantDict * dict, EnchantBroker * broker);
|
|
+
|
|
+ Dict () = delete;
|
|
+ Dict (const Dict & rhs) = delete;
|
|
+ Dict& operator=(const Dict & rhs) = delete;
|
|
+
|
|
+ EnchantDict * m_dict;
|
|
+ EnchantBroker * m_broker;
|
|
+
|
|
+ std::string m_lang;
|
|
+ std::string m_provider_name;
|
|
+ std::string m_provider_desc;
|
|
+ std::string m_provider_file;
|
|
+ };
|
|
+
|
|
+ class Broker
|
|
+ {
|
|
+
|
|
+ public:
|
|
+
|
|
+ Broker ();
|
|
+ ~Broker ();
|
|
+
|
|
+ Dict * request_dict (const std::string & lang);
|
|
+ Dict * request_pwl_dict (const std::string & pwl);
|
|
+ bool dict_exists (const std::string & lang);
|
|
+ void set_ordering (const std::string & tag, const std::string & ordering);
|
|
+ void describe (EnchantBrokerDescribeFn fn, void * user_data = nullptr);
|
|
+ void list_dicts (EnchantDictDescribeFn fn, void * user_data = nullptr);
|
|
+
|
|
+ private:
|
|
+
|
|
+ void * _private[5];
|
|
+
|
|
+ Broker (const Broker & rhs) = delete;
|
|
+ Broker& operator=(const Broker & rhs) = delete;
|
|
+
|
|
+ EnchantBroker * m_broker;
|
|
+ };
|
|
+
|
|
+ namespace loader {
|
|
+ bool do_explicit_linking ();
|
|
+ }
|
|
+
|
|
+}
|
|
diff --git a/Telegram/lib_spellcheck/spellcheck/platform/haiku/spellcheck_haiku.cpp b/Telegram/lib_spellcheck/spellcheck/platform/haiku/spellcheck_haiku.cpp
|
|
new file mode 100644
|
|
index 0000000..d73aadc
|
|
--- /dev/null
|
|
+++ b/Telegram/lib_spellcheck/spellcheck/platform/haiku/spellcheck_haiku.cpp
|
|
@@ -0,0 +1,276 @@
|
|
+// This file is part of Desktop App Toolkit,
|
|
+// a set of libraries for developing nice desktop applications.
|
|
+//
|
|
+// Author: Nicholas Guriev <guriev-ns@ya.ru>, public domain, 2019
|
|
+// License: CC0, https://creativecommons.org/publicdomain/zero/1.0/legalcode
|
|
+
|
|
+#include <set>
|
|
+#include <QLocale>
|
|
+
|
|
+#include "spellcheck/spellcheck_utils.h"
|
|
+#include "spellcheck/platform/haiku/haiku_enchant.h"
|
|
+
|
|
+#include "spellcheck/platform/haiku/spellcheck_haiku.h"
|
|
+#include "base/integration.h"
|
|
+
|
|
+namespace Platform::Spellchecker {
|
|
+namespace {
|
|
+
|
|
+constexpr auto kHspell = "hspell";
|
|
+constexpr auto kMySpell = "myspell";
|
|
+constexpr auto kHunspell = "hunspell";
|
|
+constexpr auto kOrdering = "hspell,aspell,hunspell,myspell";
|
|
+constexpr auto kMaxValidators = 10;
|
|
+constexpr auto kMaxMySpellCount = 3;
|
|
+constexpr auto kMaxWordLength = 15;
|
|
+
|
|
+using DictPtr = std::unique_ptr<enchant::Dict>;
|
|
+
|
|
+auto CheckProvider(DictPtr &validator, const std::string &provider) {
|
|
+ auto p = validator->get_provider_name();
|
|
+ std::transform(begin(p), end(p), begin(p), ::tolower);
|
|
+ return (p.find(provider) == 0); // startsWith.
|
|
+}
|
|
+
|
|
+auto IsHebrew(const QString &word) {
|
|
+ // Words with mixed scripts will be automatically ignored,
|
|
+ // so this check should be fine.
|
|
+ return ::Spellchecker::WordScript(&word) == QChar::Script_Hebrew;
|
|
+}
|
|
+
|
|
+class EnchantSpellChecker {
|
|
+public:
|
|
+ auto knownLanguages();
|
|
+ bool checkSpelling(const QString &word);
|
|
+ auto findSuggestions(const QString &word);
|
|
+ void addWord(const QString &wordToAdd);
|
|
+ void ignoreWord(const QString &word);
|
|
+ void removeWord(const QString &word);
|
|
+ bool isWordInDictionary(const QString &word);
|
|
+ static EnchantSpellChecker *instance();
|
|
+
|
|
+private:
|
|
+ EnchantSpellChecker();
|
|
+ EnchantSpellChecker(const EnchantSpellChecker&) = delete;
|
|
+ EnchantSpellChecker& operator =(const EnchantSpellChecker&) = delete;
|
|
+
|
|
+ std::unique_ptr<enchant::Broker> _brokerHandle;
|
|
+ std::vector<DictPtr> _validators;
|
|
+
|
|
+ std::vector<not_null<enchant::Dict*>> _hspells;
|
|
+};
|
|
+
|
|
+EnchantSpellChecker::EnchantSpellChecker() {
|
|
+ std::set<std::string> langs;
|
|
+ _brokerHandle = std::make_unique<enchant::Broker>();
|
|
+ _brokerHandle->list_dicts([](
|
|
+ const char *language,
|
|
+ const char *provider,
|
|
+ const char *description,
|
|
+ const char *filename,
|
|
+ void *our_payload) {
|
|
+ static_cast<decltype(langs)*>(our_payload)->insert(language);
|
|
+ }, &langs);
|
|
+ _validators.reserve(langs.size());
|
|
+ try {
|
|
+ std::string langTag = QLocale::system().name().toStdString();
|
|
+ _brokerHandle->set_ordering(langTag, kOrdering);
|
|
+ _validators.push_back(DictPtr(_brokerHandle->request_dict(langTag)));
|
|
+ langs.erase(langTag);
|
|
+ } catch (const enchant::Exception &e) {
|
|
+ // no first dictionary found
|
|
+ }
|
|
+ auto mySpellCount = 0;
|
|
+ for (const std::string &language : langs) {
|
|
+ try {
|
|
+ _brokerHandle->set_ordering(language, kOrdering);
|
|
+ auto validator = DictPtr(_brokerHandle->request_dict(language));
|
|
+ if (!validator) {
|
|
+ continue;
|
|
+ }
|
|
+ if (CheckProvider(validator, kHspell)) {
|
|
+ _hspells.push_back(validator.get());
|
|
+ }
|
|
+ if (CheckProvider(validator, kMySpell)
|
|
+ || CheckProvider(validator, kHunspell)) {
|
|
+ if (mySpellCount > kMaxMySpellCount) {
|
|
+ continue;
|
|
+ } else {
|
|
+ mySpellCount++;
|
|
+ }
|
|
+ }
|
|
+ _validators.push_back(std::move(validator));
|
|
+ if (_validators.size() > kMaxValidators) {
|
|
+ break;
|
|
+ }
|
|
+ } catch (const enchant::Exception &e) {
|
|
+ base::Integration::Instance().logMessage(QString("Catch after request_dict: ") + e.what());
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+EnchantSpellChecker *EnchantSpellChecker::instance() {
|
|
+ static EnchantSpellChecker capsule;
|
|
+ return &capsule;
|
|
+}
|
|
+
|
|
+auto EnchantSpellChecker::knownLanguages() {
|
|
+ return _validators | ranges::views::transform([](const auto &validator) {
|
|
+ return QString(validator->get_lang().c_str());
|
|
+ }) | ranges::to_vector;
|
|
+}
|
|
+
|
|
+bool EnchantSpellChecker::checkSpelling(const QString &word) {
|
|
+ auto w = word.toStdString();
|
|
+
|
|
+ if (IsHebrew(word) && _hspells.size()) {
|
|
+ return ranges::any_of(_hspells, [&](const auto &validator) {
|
|
+ return validator->check(w);
|
|
+ });
|
|
+ }
|
|
+ return ranges::any_of(_validators, [&](const auto &validator) {
|
|
+ // Hspell is the spell checker that only checks words in Hebrew.
|
|
+ // It returns 'true' for any non-Hebrew word,
|
|
+ // so we should skip Hspell if a word is not in Hebrew.
|
|
+ if (ranges::find_if(_hspells, [&](auto &v) {
|
|
+ return v == validator.get();
|
|
+ }) != _hspells.end()) {
|
|
+ return false;
|
|
+ }
|
|
+ if (validator->get_lang().find("uk") == 0) {
|
|
+ return false;
|
|
+ }
|
|
+ try {
|
|
+ return validator->check(w);
|
|
+ } catch (const enchant::Exception &e) {
|
|
+ base::Integration::Instance().logMessage(QString("Catch after check '") + word + "': " + e.what());
|
|
+ return true;
|
|
+ }
|
|
+ }) || _validators.empty();
|
|
+}
|
|
+
|
|
+auto EnchantSpellChecker::findSuggestions(const QString &word) {
|
|
+ const auto wordScript = ::Spellchecker::WordScript(&word);
|
|
+ auto w = word.toStdString();
|
|
+ std::vector<QString> result;
|
|
+ if (!_validators.size()) {
|
|
+ return result;
|
|
+ }
|
|
+
|
|
+ const auto convertSuggestions = [&](auto suggestions) {
|
|
+ for (const auto &replacement : suggestions) {
|
|
+ if (result.size() >= kMaxSuggestions) {
|
|
+ break;
|
|
+ }
|
|
+ if (!replacement.empty()) {
|
|
+ result.push_back(replacement.c_str());
|
|
+ }
|
|
+ }
|
|
+ };
|
|
+
|
|
+ if (word.size() >= kMaxWordLength) {
|
|
+ // The first element is the validator of the system language.
|
|
+ auto *v = _validators[0].get();
|
|
+ const auto lang = QString::fromStdString(v->get_lang());
|
|
+ if (wordScript == ::Spellchecker::LocaleToScriptCode(lang)) {
|
|
+ convertSuggestions(v->suggest(w));
|
|
+ }
|
|
+ return result;
|
|
+ }
|
|
+
|
|
+ if (IsHebrew(word) && _hspells.size()) {
|
|
+ for (const auto &h : _hspells) {
|
|
+ convertSuggestions(h->suggest(w));
|
|
+ if (result.size()) {
|
|
+ return result;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ for (const auto &validator : _validators) {
|
|
+ const auto lang = QString::fromStdString(validator->get_lang());
|
|
+ if (wordScript != ::Spellchecker::LocaleToScriptCode(lang)) {
|
|
+ continue;
|
|
+ }
|
|
+ convertSuggestions(validator->suggest(w));
|
|
+ if (!result.empty()) {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ return result;
|
|
+}
|
|
+
|
|
+void EnchantSpellChecker::addWord(const QString &wordToAdd) {
|
|
+ auto word = wordToAdd.toStdString();
|
|
+ auto &&first = _validators.at(0);
|
|
+ first->add(word);
|
|
+ first->add_to_session(word);
|
|
+}
|
|
+
|
|
+void EnchantSpellChecker::ignoreWord(const QString &word) {
|
|
+ _validators.at(0)->add_to_session(word.toStdString());
|
|
+}
|
|
+
|
|
+void EnchantSpellChecker::removeWord(const QString &word) {
|
|
+ auto w = word.toStdString();
|
|
+ for (const auto &validator : _validators) {
|
|
+ validator->remove_from_session(w);
|
|
+ validator->remove(w);
|
|
+ }
|
|
+}
|
|
+
|
|
+bool EnchantSpellChecker::isWordInDictionary(const QString &word) {
|
|
+ auto w = word.toStdString();
|
|
+ return ranges::any_of(_validators, [&w](const auto &validator) {
|
|
+ return validator->is_added(w);
|
|
+ });
|
|
+}
|
|
+
|
|
+} // namespace
|
|
+
|
|
+void Init() {
|
|
+}
|
|
+
|
|
+bool IsAvailable() {
|
|
+ static auto Available = enchant::loader::do_explicit_linking();
|
|
+ return Available;
|
|
+}
|
|
+
|
|
+void KnownLanguages(std::vector<QString> *langCodes) {
|
|
+ *langCodes = EnchantSpellChecker::instance()->knownLanguages();
|
|
+}
|
|
+
|
|
+bool CheckSpelling(const QString &wordToCheck) {
|
|
+ return EnchantSpellChecker::instance()->checkSpelling(wordToCheck);
|
|
+}
|
|
+
|
|
+void FillSuggestionList(
|
|
+ const QString &wrongWord,
|
|
+ std::vector<QString> *variants) {
|
|
+ *variants = EnchantSpellChecker::instance()->findSuggestions(wrongWord);
|
|
+}
|
|
+
|
|
+void AddWord(const QString &word) {
|
|
+ EnchantSpellChecker::instance()->addWord(word);
|
|
+}
|
|
+
|
|
+void RemoveWord(const QString &word) {
|
|
+ EnchantSpellChecker::instance()->removeWord(word);
|
|
+}
|
|
+
|
|
+void IgnoreWord(const QString &word) {
|
|
+ EnchantSpellChecker::instance()->ignoreWord(word);
|
|
+}
|
|
+
|
|
+bool IsWordInDictionary(const QString &wordToCheck) {
|
|
+ return EnchantSpellChecker::instance()->isWordInDictionary(wordToCheck);
|
|
+}
|
|
+
|
|
+void CheckSpellingText(
|
|
+ const QString &text,
|
|
+ MisspelledWords *misspelledWords) {
|
|
+ *misspelledWords = ::Spellchecker::RangesFromText(
|
|
+ text,
|
|
+ ::Spellchecker::CheckSkipAndSpell);
|
|
+}
|
|
+
|
|
+} // namespace Platform::Spellchecker
|
|
diff --git a/Telegram/lib_spellcheck/spellcheck/platform/haiku/spellcheck_haiku.h b/Telegram/lib_spellcheck/spellcheck/platform/haiku/spellcheck_haiku.h
|
|
new file mode 100644
|
|
index 0000000..49d672c
|
|
--- /dev/null
|
|
+++ b/Telegram/lib_spellcheck/spellcheck/platform/haiku/spellcheck_haiku.h
|
|
@@ -0,0 +1,13 @@
|
|
+// This file is part of Desktop App Toolkit,
|
|
+// a set of libraries for developing nice desktop applications.
|
|
+//
|
|
+// For license and copyright information please follow this link:
|
|
+// https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+//
|
|
+#pragma once
|
|
+
|
|
+#include "spellcheck/platform/platform_spellcheck.h"
|
|
+
|
|
+namespace Platform::Spellchecker {
|
|
+
|
|
+} // namespace Platform::Spellchecker
|
|
diff --git a/Telegram/lib_spellcheck/spellcheck/platform/platform_spellcheck.h b/Telegram/lib_spellcheck/spellcheck/platform/platform_spellcheck.h
|
|
index c3b8199..fdccb8e 100644
|
|
--- a/Telegram/lib_spellcheck/spellcheck/platform/platform_spellcheck.h
|
|
+++ b/Telegram/lib_spellcheck/spellcheck/platform/platform_spellcheck.h
|
|
@@ -40,6 +40,8 @@ void UpdateLanguages(std::vector<int> languages);
|
|
#include "spellcheck/platform/mac/spellcheck_mac.h"
|
|
#elif defined Q_OS_WIN // Q_OS_MAC
|
|
#include "spellcheck/platform/win/spellcheck_win.h"
|
|
-#elif defined Q_OS_WINRT || defined Q_OS_LINUX // Q_OS_MAC || Q_OS_WIN
|
|
+#elif defined Q_OS_HAIKU // Q_OS_MAC || Q_OS_WIN
|
|
+#include "spellcheck/platform/haiku/spellcheck_haiku.h"
|
|
+#elif defined Q_OS_WINRT || defined Q_OS_LINUX // Q_OS_MAC || Q_OS_WIN || Q_OS_HAIKU
|
|
#include "spellcheck/platform/linux/spellcheck_linux.h"
|
|
-#endif // Q_OS_MAC || Q_OS_WIN || Q_OS_WINRT || Q_OS_LINUX
|
|
+#endif // Q_OS_MAC || Q_OS_WIN || Q_OS_WINRT || Q_OS_LINUX || defined Q_OS_HAIKU
|
|
diff --git a/Telegram/lib_ui/CMakeLists.txt b/Telegram/lib_ui/CMakeLists.txt
|
|
index 88c28e6..53599c6 100644
|
|
--- a/Telegram/lib_ui/CMakeLists.txt
|
|
+++ b/Telegram/lib_ui/CMakeLists.txt
|
|
@@ -84,6 +84,10 @@ PRIVATE
|
|
ui/platform/win/ui_window_win.h
|
|
ui/platform/win/ui_utility_win.cpp
|
|
ui/platform/win/ui_utility_win.h
|
|
+ ui/platform/haiku/ui_window_haiku.cpp
|
|
+ ui/platform/haiku/ui_window_haiku.h
|
|
+ ui/platform/haiku/ui_utility_haiku.cpp
|
|
+ ui/platform/haiku/ui_utility_haiku.h
|
|
ui/platform/ui_platform_window.h
|
|
ui/platform/ui_platform_utility.h
|
|
ui/style/style_core.cpp
|
|
diff --git a/Telegram/lib_ui/ui/platform/haiku/ui_utility_haiku.cpp b/Telegram/lib_ui/ui/platform/haiku/ui_utility_haiku.cpp
|
|
new file mode 100644
|
|
index 0000000..fef675e
|
|
--- /dev/null
|
|
+++ b/Telegram/lib_ui/ui/platform/haiku/ui_utility_haiku.cpp
|
|
@@ -0,0 +1,35 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2019-2020 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#include "ui/platform/linux/ui_utility_linux.h"
|
|
+
|
|
+#include "base/flat_set.h"
|
|
+#include "ui/ui_log.h"
|
|
+
|
|
+#include <QtCore/QPoint>
|
|
+#include <QtWidgets/QApplication>
|
|
+#include <QtWidgets/QDesktopWidget>
|
|
+#include <qpa/qplatformnativeinterface.h>
|
|
+
|
|
+namespace Ui {
|
|
+namespace Platform {
|
|
+
|
|
+bool IsApplicationActive() {
|
|
+ return QApplication::activeWindow() != nullptr;
|
|
+}
|
|
+
|
|
+bool TranslucentWindowsSupported(QPoint globalPosition) {
|
|
+ return false;
|
|
+}
|
|
+
|
|
+void IgnoreAllActivation(not_null<QWidget*> widget) {
|
|
+}
|
|
+
|
|
+} // namespace Platform
|
|
+} // namespace Ui
|
|
diff --git a/Telegram/lib_ui/ui/platform/haiku/ui_utility_haiku.h b/Telegram/lib_ui/ui/platform/haiku/ui_utility_haiku.h
|
|
new file mode 100644
|
|
index 0000000..c1419cb
|
|
--- /dev/null
|
|
+++ b/Telegram/lib_ui/ui/platform/haiku/ui_utility_haiku.h
|
|
@@ -0,0 +1,44 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2019-2020 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#pragma once
|
|
+
|
|
+class QPainter;
|
|
+class QPaintEvent;
|
|
+
|
|
+namespace Ui {
|
|
+namespace Platform {
|
|
+
|
|
+inline void StartTranslucentPaint(QPainter &p, gsl::span<const QRect> rects) {
|
|
+}
|
|
+
|
|
+inline void InitOnTopPanel(not_null<QWidget*> panel) {
|
|
+}
|
|
+
|
|
+inline void DeInitOnTopPanel(not_null<QWidget*> panel) {
|
|
+}
|
|
+
|
|
+inline void ReInitOnTopPanel(not_null<QWidget*> panel) {
|
|
+}
|
|
+
|
|
+inline void UpdateOverlayed(not_null<QWidget*> widget) {
|
|
+}
|
|
+
|
|
+inline void ShowOverAll(not_null<QWidget*> widget, bool canFocus) {
|
|
+}
|
|
+
|
|
+inline void BringToBack(not_null<QWidget*> widget) {
|
|
+}
|
|
+
|
|
+inline constexpr bool UseMainQueueGeneric() {
|
|
+ return true;
|
|
+}
|
|
+
|
|
+} // namespace Platform
|
|
+} // namespace Ui
|
|
diff --git a/Telegram/lib_ui/ui/platform/haiku/ui_window_haiku.cpp b/Telegram/lib_ui/ui/platform/haiku/ui_window_haiku.cpp
|
|
new file mode 100644
|
|
index 0000000..e7a032f
|
|
--- /dev/null
|
|
+++ b/Telegram/lib_ui/ui/platform/haiku/ui_window_haiku.cpp
|
|
@@ -0,0 +1,21 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2019-2020 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#include "ui/platform/haiku/ui_window_haiku.h"
|
|
+
|
|
+namespace Ui {
|
|
+namespace Platform {
|
|
+
|
|
+std::unique_ptr<BasicWindowHelper> CreateWindowHelper(
|
|
+ not_null<RpWidget*> window) {
|
|
+ return nullptr;
|
|
+}
|
|
+
|
|
+} // namespace Platform
|
|
+} // namespace Ui
|
|
diff --git a/Telegram/lib_ui/ui/platform/haiku/ui_window_haiku.h b/Telegram/lib_ui/ui/platform/haiku/ui_window_haiku.h
|
|
new file mode 100644
|
|
index 0000000..ecb1277
|
|
--- /dev/null
|
|
+++ b/Telegram/lib_ui/ui/platform/haiku/ui_window_haiku.h
|
|
@@ -0,0 +1,12 @@
|
|
+/*
|
|
+This file is part of Telegram Desktop for Haiku,
|
|
+
|
|
+For license and copyright information please follow this link:
|
|
+https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+
|
|
+Copyright (c) 2019-2020 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+*/
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include "ui/platform/ui_platform_window.h"
|
|
diff --git a/Telegram/lib_ui/ui/platform/ui_platform_utility.h b/Telegram/lib_ui/ui/platform/ui_platform_utility.h
|
|
index 4398ed7..0b03e4e 100644
|
|
--- a/Telegram/lib_ui/ui/platform/ui_platform_utility.h
|
|
+++ b/Telegram/lib_ui/ui/platform/ui_platform_utility.h
|
|
@@ -37,8 +37,10 @@ void DrainMainQueue(); // Needed only if UseMainQueueGeneric() is false.
|
|
|
|
#ifdef Q_OS_MAC
|
|
#include "ui/platform/mac/ui_utility_mac.h"
|
|
-#elif defined Q_OS_LINUX // Q_OS_MAC
|
|
+#elif defined Q_OS_HAIKU // Q_OS_MAC
|
|
+#include "ui/platform/haiku/ui_utility_haiku.h"
|
|
+#elif defined Q_OS_LINUX // Q_OS_MAC || Q_OS_HAIKU
|
|
#include "ui/platform/linux/ui_utility_linux.h"
|
|
-#elif defined Q_OS_WINRT || defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX
|
|
+#elif defined Q_OS_WINRT || defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX || Q_OS_HAIKU
|
|
#include "ui/platform/win/ui_utility_win.h"
|
|
-#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT || Q_OS_WIN
|
|
+#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT || Q_OS_WIN || Q_OS_HAIKU
|
|
diff --git a/cmake/external.cmake b/cmake/external.cmake
|
|
new file mode 100644
|
|
index 0000000..a6c28f1
|
|
--- /dev/null
|
|
+++ b/cmake/external.cmake
|
|
@@ -0,0 +1,102 @@
|
|
+find_package(OpenAL REQUIRED)
|
|
+find_package(OpenSSL REQUIRED)
|
|
+find_package(PkgConfig REQUIRED)
|
|
+find_package(Threads REQUIRED)
|
|
+
|
|
+pkg_check_modules(FFMPEG REQUIRED
|
|
+ libavcodec
|
|
+ libavformat
|
|
+ libavutil
|
|
+ libswscale
|
|
+ libswresample
|
|
+)
|
|
+pkg_check_modules(LZ4 REQUIRED liblz4)
|
|
+pkg_check_modules(OPUS REQUIRED opus)
|
|
+pkg_check_modules(ZLIB REQUIRED minizip zlib)
|
|
+
|
|
+find_package(Qt5 REQUIRED COMPONENTS Core DBus Gui Network Widgets)
|
|
+get_target_property(QTCORE_INCLUDE_DIRS Qt5::Core INTERFACE_INCLUDE_DIRECTORIES)
|
|
+list(GET QTCORE_INCLUDE_DIRS 0 QT_INCLUDE_DIR)
|
|
+
|
|
+foreach(qt_module IN ITEMS QtCore QtGui)
|
|
+ list(APPEND QT_PRIVATE_INCLUDE_DIRS
|
|
+ ${QT_INCLUDE_DIR}/${qt_module}/${Qt5_VERSION}
|
|
+ ${QT_INCLUDE_DIR}/${qt_module}/${Qt5_VERSION}/${qt_module}
|
|
+ )
|
|
+endforeach()
|
|
+message(STATUS "Using Qt private include directories: ${QT_PRIVATE_INCLUDE_DIRS}")
|
|
+
|
|
+set(QT_PLUGINS
|
|
+ QGenericEnginePlugin
|
|
+ QGifPlugin
|
|
+ QJpegPlugin
|
|
+ QWebpPlugin
|
|
+)
|
|
+
|
|
+foreach(qt_plugin IN ITEMS ${QT_PLUGINS})
|
|
+ get_target_property(qt_plugin_loc Qt5::${qt_plugin} LOCATION)
|
|
+ list(APPEND QT_PLUGIN_DIRS ${qt_plugin_loc})
|
|
+endforeach()
|
|
+message(STATUS "Using Qt plugins: ${QT_PLUGIN_DIRS}")
|
|
+
|
|
+set(OPENAL_DEFINITIONS
|
|
+ AL_ALEXT_PROTOTYPES
|
|
+ AL_LIBTYPE_STATIC
|
|
+)
|
|
+set(QT_DEFINITIONS
|
|
+ _REENTRANT
|
|
+ QT_CORE_LIB
|
|
+ QT_GUI_LIB
|
|
+ QT_NETWORK_LIB
|
|
+ QT_PLUGIN
|
|
+ QT_STATICPLUGIN
|
|
+ QT_WIDGETS_LIB
|
|
+)
|
|
+
|
|
+if (HAIKU)
|
|
+ list(APPEND QT_DEFINITIONS Q_OS_HAIKU)
|
|
+endif()
|
|
+
|
|
+set(OPENAL_INCLUDE_DIRS ${OPENAL_INCLUDE_DIR})
|
|
+set(QT_INCLUDE_DIRS ${QT_PRIVATE_INCLUDE_DIRS})
|
|
+
|
|
+set(OPENAL_LIBRARIES ${OPENAL_LIBRARY})
|
|
+set(OPENSSL_LIBRARIES
|
|
+ OpenSSL::Crypto
|
|
+ OpenSSL::SSL
|
|
+)
|
|
+set(QT_LIBRARIES
|
|
+ Qt5::Network
|
|
+ Qt5::Widgets Threads::Threads root be media network translation
|
|
+)
|
|
+
|
|
+set(EXTERNAL_LIBS ffmpeg lz4 openal openssl opus qt zlib)
|
|
+
|
|
+if(NOT DESKTOP_APP_DISABLE_CRASH_REPORTS)
|
|
+ pkg_check_modules(CRASH_REPORTS REQUIRED breakpad-client)
|
|
+ list(APPEND EXTERNAL_LIBS crash_reports)
|
|
+endif()
|
|
+
|
|
+foreach(LIB IN ITEMS ${EXTERNAL_LIBS})
|
|
+ add_library(external_${LIB} INTERFACE IMPORTED GLOBAL)
|
|
+ add_library(desktop-app::external_${LIB} ALIAS external_${LIB})
|
|
+ string(TOUPPER ${LIB} LIB_U)
|
|
+
|
|
+ if(DEFINED ${LIB_U}_DEFINITIONS)
|
|
+ target_compile_definitions(
|
|
+ external_${LIB} INTERFACE ${${LIB_U}_DEFINITIONS}
|
|
+ )
|
|
+ endif()
|
|
+
|
|
+ if(DEFINED ${LIB_U}_INCLUDE_DIRS)
|
|
+ target_include_directories(
|
|
+ external_${LIB} SYSTEM INTERFACE ${${LIB_U}_INCLUDE_DIRS}
|
|
+ )
|
|
+ endif()
|
|
+
|
|
+ if(DEFINED ${LIB_U}_LIBRARIES)
|
|
+ target_link_libraries(
|
|
+ external_${LIB} INTERFACE ${${LIB_U}_LIBRARIES}
|
|
+ )
|
|
+ endif()
|
|
+endforeach()
|
|
diff --git a/cmake/external/CMakeLists.txt b/cmake/external/CMakeLists.txt
|
|
index 9c69674..55b22d4 100644
|
|
--- a/cmake/external/CMakeLists.txt
|
|
+++ b/cmake/external/CMakeLists.txt
|
|
@@ -5,22 +5,22 @@
|
|
# https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
|
|
add_subdirectory(auto_updates)
|
|
-add_subdirectory(crash_reports)
|
|
+#add_subdirectory(crash_reports)
|
|
if (LINUX AND NOT DESKTOP_APP_DISABLE_DBUS_INTEGRATION)
|
|
add_subdirectory(dbusmenu_qt)
|
|
endif()
|
|
add_subdirectory(expected)
|
|
-add_subdirectory(ffmpeg)
|
|
+#add_subdirectory(ffmpeg)
|
|
add_subdirectory(gsl)
|
|
if (add_hunspell_library)
|
|
add_subdirectory(hunspell)
|
|
endif()
|
|
add_subdirectory(iconv)
|
|
-add_subdirectory(lz4)
|
|
-add_subdirectory(openal)
|
|
-add_subdirectory(openssl)
|
|
-add_subdirectory(opus)
|
|
-add_subdirectory(qt)
|
|
+#add_subdirectory(lz4)
|
|
+#add_subdirectory(openal)
|
|
+#add_subdirectory(openssl)
|
|
+#add_subdirectory(opus)
|
|
+#add_subdirectory(qt)
|
|
add_subdirectory(qr_code_generator)
|
|
add_subdirectory(ranges)
|
|
add_subdirectory(rlottie)
|
|
@@ -32,4 +32,3 @@ if (LINUX AND NOT DESKTOP_APP_DISABLE_DBUS_INTEGRATION)
|
|
endif()
|
|
add_subdirectory(variant)
|
|
add_subdirectory(xxhash)
|
|
-add_subdirectory(zlib)
|
|
diff --git a/cmake/nice_target_sources.cmake b/cmake/nice_target_sources.cmake
|
|
index 2ac58d4..6aed2b8 100644
|
|
--- a/cmake/nice_target_sources.cmake
|
|
+++ b/cmake/nice_target_sources.cmake
|
|
@@ -15,6 +15,7 @@ function(nice_target_sources target_name src_loc)
|
|
set(not_win_sources "")
|
|
set(not_mac_sources "")
|
|
set(not_linux_sources "")
|
|
+ set(not_haiku_sources "")
|
|
foreach (entry ${list})
|
|
if (${entry} STREQUAL "PRIVATE" OR ${entry} STREQUAL "PUBLIC" OR ${entry} STREQUAL "INTERFACE")
|
|
set(writing_now ${entry})
|
|
@@ -23,12 +24,19 @@ function(nice_target_sources target_name src_loc)
|
|
if (${entry} MATCHES "(^|/)win/" OR ${entry} MATCHES "(^|/)winrc/" OR ${entry} MATCHES "(^|/)windows/" OR ${entry} MATCHES "[_\\/]win\\.")
|
|
list(APPEND not_mac_sources ${full_name})
|
|
list(APPEND not_linux_sources ${full_name})
|
|
+ list(APPEND not_haiku_sources ${full_name})
|
|
elseif (${entry} MATCHES "(^|/)mac/" OR ${entry} MATCHES "(^|/)darwin/" OR ${entry} MATCHES "(^|/)osx/" OR ${entry} MATCHES "[_\\/]mac\\." OR ${entry} MATCHES "[_\\/]darwin\\." OR ${entry} MATCHES "[_\\/]osx\\.")
|
|
list(APPEND not_win_sources ${full_name})
|
|
list(APPEND not_linux_sources ${full_name})
|
|
+ list(APPEND not_haiku_sources ${full_name})
|
|
elseif (${entry} MATCHES "(^|/)linux/" OR ${entry} MATCHES "[_\\/]linux\\.")
|
|
list(APPEND not_win_sources ${full_name})
|
|
list(APPEND not_mac_sources ${full_name})
|
|
+ list(APPEND not_haiku_sources ${full_name})
|
|
+ elseif (${entry} MATCHES "(^|/)haiku/" OR ${entry} MATCHES "[_\\/]haiku\\.")
|
|
+ list(APPEND not_win_sources ${full_name})
|
|
+ list(APPEND not_mac_sources ${full_name})
|
|
+ list(APPEND not_linux_sources ${full_name})
|
|
elseif (${entry} MATCHES "(^|/)posix/" OR ${entry} MATCHES "[_\\/]posix\\.")
|
|
list(APPEND not_win_sources ${full_name})
|
|
endif()
|
|
@@ -64,6 +72,9 @@ function(nice_target_sources target_name src_loc)
|
|
elseif (APPLE)
|
|
set_source_files_properties(${not_mac_sources} PROPERTIES HEADER_FILE_ONLY TRUE)
|
|
set_source_files_properties(${not_mac_sources} PROPERTIES SKIP_AUTOGEN TRUE)
|
|
+ elseif (HAIKU)
|
|
+ set_source_files_properties(${not_haiku_sources} PROPERTIES HEADER_FILE_ONLY TRUE)
|
|
+ set_source_files_properties(${not_haiku_sources} PROPERTIES SKIP_AUTOGEN TRUE)
|
|
elseif (LINUX)
|
|
set_source_files_properties(${not_linux_sources} PROPERTIES HEADER_FILE_ONLY TRUE)
|
|
set_source_files_properties(${not_linux_sources} PROPERTIES SKIP_AUTOGEN TRUE)
|
|
diff --git a/cmake/options.cmake b/cmake/options.cmake
|
|
index 46186c6..822a6f0 100644
|
|
--- a/cmake/options.cmake
|
|
+++ b/cmake/options.cmake
|
|
@@ -44,6 +44,8 @@ if (WIN32)
|
|
include(cmake/options_win.cmake)
|
|
elseif (APPLE)
|
|
include(cmake/options_mac.cmake)
|
|
+elseif (HAIKU)
|
|
+ include(cmake/options_haiku.cmake)
|
|
elseif (LINUX)
|
|
include(cmake/options_linux.cmake)
|
|
else()
|
|
diff --git a/cmake/options_haiku.cmake b/cmake/options_haiku.cmake
|
|
new file mode 100644
|
|
index 0000000..063f1ce
|
|
--- /dev/null
|
|
+++ b/cmake/options_haiku.cmake
|
|
@@ -0,0 +1,30 @@
|
|
+# This file is part of Telegram Desktop for Haiku
|
|
+# For license and copyright information please follow this link:
|
|
+# https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
+# Copyright (c) 2019 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+
|
|
+target_compile_options(common_options
|
|
+INTERFACE
|
|
+ $<IF:$<CONFIG:Debug>,,-Ofast -fno-strict-aliasing>
|
|
+ -fPIC
|
|
+ -mmmx
|
|
+ -msse2
|
|
+ -Wno-unused-variable
|
|
+ -Wno-unused-parameter
|
|
+ -Wno-unused-function
|
|
+ -Wno-switch
|
|
+ -Wno-comment
|
|
+ -Wno-unused-but-set-variable
|
|
+ -Wno-missing-field-initializers
|
|
+ -Wno-sign-compare
|
|
+ -Wno-attributes
|
|
+ -Wno-parentheses
|
|
+ -Wno-stringop-overflow
|
|
+ -Wno-maybe-uninitialized
|
|
+ -Wno-error=class-memaccess
|
|
+ -Wno-deprecated-declarations
|
|
+)
|
|
+target_link_options(common_options
|
|
+INTERFACE
|
|
+ $<IF:$<CONFIG:Debug>,,-Ofast>
|
|
+)
|
|
diff --git a/cmake/variables.cmake b/cmake/variables.cmake
|
|
index 3c71216..891d428 100644
|
|
--- a/cmake/variables.cmake
|
|
+++ b/cmake/variables.cmake
|
|
@@ -57,6 +57,7 @@ set(build_osx 0)
|
|
set(build_macstore 0)
|
|
set(build_winstore 0)
|
|
set(build_linux32 0)
|
|
+set(build_haiku 0)
|
|
|
|
if (WIN32)
|
|
if (DESKTOP_APP_SPECIAL_TARGET STREQUAL "uwp")
|
|
@@ -68,6 +69,12 @@ elseif (APPLE)
|
|
elseif (DESKTOP_APP_SPECIAL_TARGET STREQUAL "macstore")
|
|
set(build_macstore 1)
|
|
endif()
|
|
+elseif (HAIKU)
|
|
+ set(build_haiku 1)
|
|
+ set(DESKTOP_APP_USE_GLIBC_WRAPS OFF)
|
|
+ set(CMAKE_AR gcc-ar)
|
|
+ set(CMAKE_RANLIB gcc-ranlib)
|
|
+ set(CMAKE_NM gcc-nm)
|
|
else()
|
|
if (CMAKE_SIZEOF_VOID_P EQUAL 4)
|
|
set(build_linux32 1)
|
|
@@ -88,8 +95,8 @@ else()
|
|
endif()
|
|
endif()
|
|
|
|
-if (NOT APPLE OR build_osx)
|
|
- get_filename_component(libs_loc "../Libraries" REALPATH)
|
|
+if (NOT APPLE OR build_osx OR build_haiku)
|
|
+ get_filename_component(libs_loc "Telegram/ThirdParty" REALPATH)
|
|
else()
|
|
get_filename_component(libs_loc "../Libraries/macos" REALPATH)
|
|
endif()
|
|
--
|
|
2.24.1
|
|
|
|
|
|
From d281bb0103254dd6ce94234780ceae101068ec08 Mon Sep 17 00:00:00 2001
|
|
From: Gerasim Troeglazov <3dEyes@gmail.com>
|
|
Date: Wed, 4 Mar 2020 21:47:43 +1000
|
|
Subject: Fix tray menu
|
|
|
|
|
|
diff --git a/Telegram/SourceFiles/platform/haiku/main_window_haiku.cpp b/Telegram/SourceFiles/platform/haiku/main_window_haiku.cpp
|
|
index c603575..20eaf46 100644
|
|
--- a/Telegram/SourceFiles/platform/haiku/main_window_haiku.cpp
|
|
+++ b/Telegram/SourceFiles/platform/haiku/main_window_haiku.cpp
|
|
@@ -52,12 +52,18 @@ void MainWindow::psStatusIconCheck() {
|
|
}
|
|
|
|
void MainWindow::psShowTrayMenu() {
|
|
+ _trayIconMenuEmbed->popup(QCursor::pos());
|
|
}
|
|
|
|
void MainWindow::psTrayMenuUpdated() {
|
|
}
|
|
|
|
void MainWindow::psSetupTrayIcon() {
|
|
+ if (!_trayIconMenuEmbed) {
|
|
+ _trayIconMenuEmbed = new Ui::PopupMenu(nullptr, trayIconMenu);
|
|
+ _trayIconMenuEmbed->deleteOnHide(false);
|
|
+ }
|
|
+
|
|
if (!trayIcon) {
|
|
trayIcon = new QSystemTrayIcon(this);
|
|
|
|
@@ -75,13 +81,14 @@ void MainWindow::psSetupTrayIcon() {
|
|
}
|
|
|
|
void MainWindow::workmodeUpdated(DBIWorkMode mode) {
|
|
- psSetupTrayIcon();
|
|
if (mode == dbiwmWindowOnly) {
|
|
if (trayIcon) {
|
|
trayIcon->setContextMenu(0);
|
|
- delete trayIcon;
|
|
- trayIcon = nullptr;
|
|
+ trayIcon->deleteLater();
|
|
}
|
|
+ trayIcon = 0;
|
|
+ } else {
|
|
+ psSetupTrayIcon();
|
|
}
|
|
}
|
|
|
|
@@ -129,6 +136,7 @@ void MainWindow::psUpdateMargins() {
|
|
}
|
|
|
|
MainWindow::~MainWindow() {
|
|
+ delete _trayIconMenuEmbed;
|
|
}
|
|
|
|
} // namespace Platform
|
|
diff --git a/Telegram/SourceFiles/platform/haiku/main_window_haiku.h b/Telegram/SourceFiles/platform/haiku/main_window_haiku.h
|
|
index 36ab559..90940c3 100644
|
|
--- a/Telegram/SourceFiles/platform/haiku/main_window_haiku.h
|
|
+++ b/Telegram/SourceFiles/platform/haiku/main_window_haiku.h
|
|
@@ -4,12 +4,13 @@ This file is part of Telegram Desktop for Haiku,
|
|
For license and copyright information please follow this link:
|
|
https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
|
|
-Copyright (c) 2018-2019 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
+Copyright (c) 2018-2020 Gerasim Troeglazov, 3dEyes@gmail.com
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "platform/platform_main_window.h"
|
|
+#include "ui/widgets/popup_menu.h"
|
|
#include "base/flags.h"
|
|
|
|
#include <QtCore/QTimer>
|
|
@@ -60,6 +61,8 @@ private:
|
|
void updateIconCounters();
|
|
void psCreateTrayIcon();
|
|
|
|
+ Ui::PopupMenu *_trayIconMenuEmbed = nullptr;
|
|
+
|
|
QTimer _psCheckStatusIconTimer;
|
|
int _psCheckStatusIconLeft = 100;
|
|
|
|
--
|
|
2.24.1
|
|
|