Files
haikuports/net-im/telegram-desktop/patches/telegram_desktop-1.9.3.patchset
Gerasim Troeglazov c666391e6b Telegram: bump version
2020-01-06 18:27:12 +10:00

4345 lines
125 KiB
Plaintext

From b14000c6453f734aeafac45f964a11cc37e8f7a7 Mon Sep 17 00:00:00 2001
From: Gerasim Troeglazov <3dEyes@gmail.com>
Date: Mon, 6 Jan 2020 17:46:10 +1000
Subject: Add Haiku support
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ff9adc6..af7e2c9 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/variables.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/variables.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/nice_target_sources.cmake)
@@ -30,7 +31,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 d8c623a..8ee842a 100644
--- a/Telegram/CMakeLists.txt
+++ b/Telegram/CMakeLists.txt
@@ -697,60 +697,18 @@ PRIVATE
passport/passport_panel_form.h
passport/passport_panel_password.cpp
passport/passport_panel_password.h
- platform/linux/linux_desktop_environment.cpp
- platform/linux/linux_desktop_environment.h
- platform/linux/linux_gdk_helper.cpp
- platform/linux/linux_gdk_helper.h
- platform/linux/linux_libs.cpp
- platform/linux/linux_libs.h
- platform/linux/file_utilities_linux.cpp
- platform/linux/file_utilities_linux.h
- platform/linux/launcher_linux.cpp
- platform/linux/launcher_linux.h
- platform/linux/main_window_linux.cpp
- platform/linux/main_window_linux.h
- platform/linux/notifications_manager_linux.cpp
- platform/linux/notifications_manager_linux.h
- platform/linux/specific_linux.cpp
- platform/linux/specific_linux.h
- platform/mac/file_utilities_mac.mm
- platform/mac/file_utilities_mac.h
- platform/mac/launcher_mac.mm
- platform/mac/launcher_mac.h
- platform/mac/mac_iconv_helper.c
- platform/mac/main_window_mac.mm
- platform/mac/main_window_mac.h
- platform/mac/notifications_manager_mac.mm
- platform/mac/notifications_manager_mac.h
- platform/mac/specific_mac.mm
- platform/mac/specific_mac.h
- platform/mac/specific_mac_p.mm
- platform/mac/specific_mac_p.h
- platform/mac/window_title_mac.mm
- platform/mac/window_title_mac.h
- platform/mac/mac_touchbar.h
- platform/mac/mac_touchbar.mm
- platform/win/audio_win.cpp
- platform/win/audio_win.h
- platform/win/file_utilities_win.cpp
- platform/win/file_utilities_win.h
- platform/win/launcher_win.cpp
- platform/win/launcher_win.h
- platform/win/main_window_win.cpp
- platform/win/main_window_win.h
- platform/win/notifications_manager_win.cpp
- platform/win/notifications_manager_win.h
- platform/win/specific_win.cpp
- platform/win/specific_win.h
- platform/win/window_title_win.cpp
- platform/win/window_title_win.h
- platform/win/windows_app_user_model_id.cpp
- platform/win/windows_app_user_model_id.h
- platform/win/windows_dlls.cpp
- platform/win/windows_dlls.h
- 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
@@ -937,6 +895,7 @@ PRIVATE
observer_peer.cpp
observer_peer.h
qt_static_plugins.cpp
+ qt_functions.cpp
settings.cpp
settings.h
)
@@ -1097,7 +1056,6 @@ source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/Telegram PREFIX Resources FILES ${
target_include_directories(Telegram
PRIVATE
${src_loc}
- ${third_party_loc}/minizip
)
target_compile_definitions(Telegram
@@ -1118,7 +1076,7 @@ endif()
set_target_properties(Telegram PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${output_folder})
-if (NOT build_macstore AND NOT build_winstore)
+if (False)
add_executable(Updater WIN32)
init_target(Updater)
@@ -1157,3 +1115,9 @@ if (NOT build_macstore AND NOT build_winstore)
set_target_properties(Packer PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${output_folder})
endif()
endif()
+
+set_target_properties(Telegram PROPERTIES
+ OUTPUT_NAME "telegram-desktop"
+)
+
+install(TARGETS Telegram RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/Telegram/SourceFiles/calls/calls_call.cpp b/Telegram/SourceFiles/calls/calls_call.cpp
index bf57bdc..01f7cc4 100644
--- a/Telegram/SourceFiles/calls/calls_call.cpp
+++ b/Telegram/SourceFiles/calls/calls_call.cpp
@@ -27,6 +27,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#define NEED_TO_RESTORE_SLOTS
#endif // slots
+#ifdef __x86_64__
+#define int64 XXX
+#define uint64 YYY
+#else
+#define int32 XXX
+#define uint32 YYY
+#endif
+
#include <VoIPController.h>
#include <VoIPServerConfig.h>
diff --git a/Telegram/SourceFiles/core/launcher.cpp b/Telegram/SourceFiles/core/launcher.cpp
index 2547342..a94c354 100644
--- a/Telegram/SourceFiles/core/launcher.cpp
+++ b/Telegram/SourceFiles/core/launcher.cpp
@@ -278,6 +278,13 @@ int Launcher::exec() {
Platform::start();
Ui::DisableCustomScaling();
+#if defined(Q_OS_HAIKU)
+ QCoreApplication::addLibraryPath("/boot/system/add-ons/Qt5");
+ QCoreApplication::addLibraryPath("/boot/system/add-ons/x86/Qt5");
+// setenv("QT_STYLE_OVERRIDE", "qwerty", false);
+// unsetenv("QT_QPA_PLATFORMTHEME");
+#endif
+
auto result = executeApplication();
DEBUG_LOG(("Telegram finished, result: %1").arg(result));
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/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/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..cda837b
--- /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(str_const_toString(AppName));
+ 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..200bc1c
--- /dev/null
+++ b/Telegram/SourceFiles/platform/haiku/specific_haiku.cpp
@@ -0,0 +1,249 @@
+/*
+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();
+}
+
+} // 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) + '/' + str_const_toString(AppName) + '/';
+}
+
+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..b59c98d
--- /dev/null
+++ b/Telegram/SourceFiles/platform/haiku/specific_haiku.h
@@ -0,0 +1,115 @@
+/*
+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 StartTranslucentPaint(QPainter &p, QPaintEvent *e) {
+}
+
+inline void InitOnTopPanel(QWidget *panel) {
+}
+
+inline void DeInitOnTopPanel(QWidget *panel) {
+}
+
+inline void ReInitOnTopPanel(QWidget *panel) {
+}
+
+QString CurrentExecutablePath(int argc, char *argv[]);
+
+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/qt_functions.cpp b/Telegram/SourceFiles/qt_functions.cpp
new file mode 100644
index 0000000..8817342
--- /dev/null
+++ b/Telegram/SourceFiles/qt_functions.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file contains some parts of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/private/qtextengine_p.h>
+
+/* TODO: find a dynamic library with these symbols. */
+
+/* Debian maintainer: this function is taken from qfiledialog.cpp */
+/*
+ Makes a list of filters from ;;-separated text.
+ Used by the mac and windows implementations
+*/
+QStringList qt_make_filter_list(const QString &filter)
+{
+ QString f(filter);
+
+ if (f.isEmpty())
+ return QStringList();
+
+ QString sep(QLatin1String(";;"));
+ int i = f.indexOf(sep, 0);
+ if (i == -1) {
+ if (f.indexOf(QLatin1Char('\n'), 0) != -1) {
+ sep = QLatin1Char('\n');
+ i = f.indexOf(sep, 0);
+ }
+ }
+
+ return f.split(sep);
+}
+
+/* Debian maintainer: this constructor is taken from qtextengine.cpp for TextPainter::drawLine */
+QTextItemInt::QTextItemInt(const QGlyphLayout &g, QFont *font, const QChar *chars_, int numChars, QFontEngine *fe, const QTextCharFormat &format)
+ : flags(0), justified(false), underlineStyle(QTextCharFormat::NoUnderline), charFormat(format),
+ num_chars(numChars), chars(chars_), logClusters(0), f(font), glyphs(g), fontEngine(fe)
+{
+}
+
+/* Debian maintainer: this method is also taken from qtextengine.cpp */
+// Fix up flags and underlineStyle with given info
+void QTextItemInt::initWithScriptItem(const QScriptItem &si)
+{
+ // explicitly initialize flags so that initFontAttributes can be called
+ // multiple times on the same TextItem
+ flags = 0;
+ if (si.analysis.bidiLevel %2)
+ flags |= QTextItem::RightToLeft;
+ ascent = si.ascent;
+ descent = si.descent;
+
+ if (charFormat.hasProperty(QTextFormat::TextUnderlineStyle)) {
+ underlineStyle = charFormat.underlineStyle();
+ } else if (charFormat.boolProperty(QTextFormat::FontUnderline)
+ || f->d->underline) {
+ underlineStyle = QTextCharFormat::SingleUnderline;
+ }
+
+ // compat
+ if (underlineStyle == QTextCharFormat::SingleUnderline)
+ flags |= QTextItem::Underline;
+
+ if (f->d->overline || charFormat.fontOverline())
+ flags |= QTextItem::Overline;
+ if (f->d->strikeOut || charFormat.fontStrikeOut())
+ flags |= QTextItem::StrikeOut;
+}
diff --git a/Telegram/SourceFiles/qt_static_plugins.cpp b/Telegram/SourceFiles/qt_static_plugins.cpp
index cc1a767..c1b5859 100644
--- a/Telegram/SourceFiles/qt_static_plugins.cpp
+++ b/Telegram/SourceFiles/qt_static_plugins.cpp
@@ -7,26 +7,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include <QtCore/QtPlugin>
-Q_IMPORT_PLUGIN(QWebpPlugin)
#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
-Q_IMPORT_PLUGIN(QJpegPlugin)
-Q_IMPORT_PLUGIN(QGifPlugin)
#endif // Qt 5.8.0
#ifdef Q_OS_WIN
-Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)
#elif defined Q_OS_MAC // Q_OS_WIN
-Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin)
-Q_IMPORT_PLUGIN(QGenericEnginePlugin)
#elif defined Q_OS_LINUX // Q_OS_WIN | Q_OS_MAC
-Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)
-Q_IMPORT_PLUGIN(QConnmanEnginePlugin)
-Q_IMPORT_PLUGIN(QGenericEnginePlugin)
-Q_IMPORT_PLUGIN(QNetworkManagerEnginePlugin)
-Q_IMPORT_PLUGIN(QComposePlatformInputContextPlugin)
-Q_IMPORT_PLUGIN(QIbusPlatformInputContextPlugin)
-Q_IMPORT_PLUGIN(QFcitxPlatformInputContextPlugin)
-Q_IMPORT_PLUGIN(QHimePlatformInputContextPlugin)
-Q_IMPORT_PLUGIN(NimfInputContextPlugin)
#endif // Q_OS_WIN | Q_OS_MAC | Q_OS_LINUX
diff --git a/Telegram/SourceFiles/settings/settings_calls.cpp b/Telegram/SourceFiles/settings/settings_calls.cpp
index 31d16e3..9eb64e8 100644
--- a/Telegram/SourceFiles/settings/settings_calls.cpp
+++ b/Telegram/SourceFiles/settings/settings_calls.cpp
@@ -31,6 +31,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#define NEED_TO_RESTORE_SLOTS
#endif // slots
+#ifdef __x86_64__
+#define int64 XXX
+#define uint64 YYY
+#else
+#define int32 XXX
+#define uint32 YYY
+#endif
+
#include <VoIPController.h>
#ifdef NEED_TO_RESTORE_SLOTS
diff --git a/Telegram/ThirdParty/libtgvoip/VoIPController.cpp b/Telegram/ThirdParty/libtgvoip/VoIPController.cpp
index b7eecdb..ea65861 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>
@@ -3057,6 +3060,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 dae647a..4bab98c 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 458e8a5..1890350 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 52eef76..c480dfb 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 52a09ff..f26ff21
--- 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 38fa632..daf50a7 100644
--- a/Telegram/cmake/lib_tgvoip.cmake
+++ b/Telegram/cmake/lib_tgvoip.cmake
@@ -68,45 +68,13 @@ PRIVATE
json11.cpp
json11.hpp
- # Windows
- os/windows/NetworkSocketWinsock.cpp
- os/windows/NetworkSocketWinsock.h
- os/windows/AudioInputWave.cpp
- os/windows/AudioInputWave.h
- os/windows/AudioOutputWave.cpp
- os/windows/AudioOutputWave.h
- os/windows/AudioOutputWASAPI.cpp
- os/windows/AudioOutputWASAPI.h
- os/windows/AudioInputWASAPI.cpp
- os/windows/AudioInputWASAPI.h
- os/windows/WindowsSpecific.cpp
- os/windows/WindowsSpecific.h
-
- # macOS
- os/darwin/AudioInputAudioUnit.cpp
- os/darwin/AudioInputAudioUnit.h
- os/darwin/AudioOutputAudioUnit.cpp
- os/darwin/AudioOutputAudioUnit.h
- os/darwin/AudioInputAudioUnitOSX.cpp
- os/darwin/AudioInputAudioUnitOSX.h
- os/darwin/AudioOutputAudioUnitOSX.cpp
- os/darwin/AudioOutputAudioUnitOSX.h
- os/darwin/AudioUnitIO.cpp
- os/darwin/AudioUnitIO.h
- os/darwin/DarwinSpecific.mm
- os/darwin/DarwinSpecific.h
-
- # Linux
- os/linux/AudioInputALSA.cpp
- os/linux/AudioInputALSA.h
- os/linux/AudioOutputALSA.cpp
- os/linux/AudioOutputALSA.h
- os/linux/AudioOutputPulse.cpp
- os/linux/AudioOutputPulse.h
- os/linux/AudioInputPulse.cpp
- os/linux/AudioInputPulse.h
- 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
@@ -176,8 +144,6 @@ PRIVATE
webrtc_dsp/rtc_base/sanitizer.h
webrtc_dsp/rtc_base/scoped_ref_ptr.h
webrtc_dsp/rtc_base/logging.h
- webrtc_dsp/rtc_base/logging_mac.h
- webrtc_dsp/rtc_base/logging_mac.mm
webrtc_dsp/rtc_base/timeutils.h
webrtc_dsp/rtc_base/atomicops.h
webrtc_dsp/rtc_base/stringencode.cc
@@ -212,7 +178,6 @@ PRIVATE
webrtc_dsp/rtc_base/type_traits.h
webrtc_dsp/rtc_base/platform_file.h
webrtc_dsp/rtc_base/refcounter.h
- webrtc_dsp/rtc_base/logging_mac.h
webrtc_dsp/rtc_base/thread_checker.h
webrtc_dsp/rtc_base/race_checker.h
webrtc_dsp/rtc_base/refcountedobject.h
@@ -749,6 +714,20 @@ elseif (APPLE)
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 68473e8..300d977 100644
--- a/Telegram/lib_base/CMakeLists.txt
+++ b/Telegram/lib_base/CMakeLists.txt
@@ -17,45 +17,18 @@ get_filename_component(src_loc . REALPATH)
target_precompile_headers(lib_base PRIVATE ${src_loc}/base/base_pch.h)
nice_target_sources(lib_base ${src_loc}
PRIVATE
- base/platform/linux/base_file_utilities_linux.cpp
- base/platform/linux/base_file_utilities_linux.h
- base/platform/linux/base_info_linux.cpp
- base/platform/linux/base_info_linux.h
- base/platform/linux/base_last_input_linux.cpp
- base/platform/linux/base_last_input_linux.h
- base/platform/linux/base_layout_switch_linux.cpp
- base/platform/linux/base_layout_switch_linux.h
- base/platform/linux/base_process_linux.cpp
- base/platform/linux/base_process_linux.h
- base/platform/linux/base_url_scheme_linux.cpp
- base/platform/linux/base_url_scheme_linux.h
- base/platform/mac/base_file_utilities_mac.h
- base/platform/mac/base_file_utilities_mac.mm
- base/platform/mac/base_info_mac.h
- base/platform/mac/base_info_mac.mm
- base/platform/mac/base_last_input_mac.h
- base/platform/mac/base_last_input_mac.mm
- base/platform/mac/base_layout_switch_mac.h
- base/platform/mac/base_layout_switch_mac.mm
- base/platform/mac/base_process_mac.h
- base/platform/mac/base_process_mac.mm
- base/platform/mac/base_url_scheme_mac.h
- base/platform/mac/base_url_scheme_mac.mm
- base/platform/mac/base_utilities_mac.h
- base/platform/mac/base_utilities_mac.mm
- base/platform/win/base_file_utilities_win.cpp
- base/platform/win/base_file_utilities_win.h
- base/platform/win/base_info_win.cpp
- base/platform/win/base_info_win.h
- base/platform/win/base_last_input_win.cpp
- base/platform/win/base_last_input_win.h
- base/platform/win/base_layout_switch_win.cpp
- base/platform/win/base_layout_switch_win.h
- base/platform/win/base_process_win.cpp
- base/platform/win/base_process_win.h
- 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
@@ -83,7 +56,6 @@ PRIVATE
base/base_file_utilities.cpp
base/base_file_utilities.h
base/file_lock.h
- base/file_lock_win.cpp
base/file_lock_posix.cpp
base/flat_map.h
base/flat_set.h
@@ -142,17 +114,12 @@ PUBLIC
desktop-app::lib_crl
desktop-app::external_qt
desktop-app::external_openssl
- desktop-app::external_crash_reports
desktop-app::external_variant
desktop-app::external_ranges
desktop-app::external_gsl
desktop-app::external_expected
)
-if (DESKTOP_APP_USE_GLIBC_WRAPS)
- target_link_libraries(lib_base PUBLIC desktop-app::linux_glibc_wraps)
-endif()
-
target_precompile_headers(lib_base_crash_report_writer PRIVATE ${src_loc}/base/base_pch.h)
nice_target_sources(lib_base_crash_report_writer ${src_loc}
PRIVATE
diff --git a/Telegram/lib_base/base/build_config.h b/Telegram/lib_base/base/build_config.h
index a02c9b0..cffaec4 100644
--- a/Telegram/lib_base/base/build_config.h
+++ b/Telegram/lib_base/base/build_config.h
@@ -12,9 +12,11 @@
#if defined(__APPLE__)
#define OS_MAC 1
-#elif defined(__linux__) // __APPLE__
+#elif defined(__HAIKU__) // __APPLE__
+#define OS_HAIKU 1
+#elif defined(__linux__) // __APPLE__ || __HAIKU__
#define OS_LINUX 1
-#elif defined(_WIN32) // __APPLE__ || __linux__
+#elif defined(_WIN32) // __APPLE__ || __HAIKU__ || __linux__
#define OS_WIN 1
#else // __APPLE__ || __linux__ || _WIN32
#error Please add support for your platform in base/build_config.h
@@ -22,9 +24,9 @@
// For access to standard POSIXish features, use OS_POSIX instead of a
// more specific macro.
-#if defined(OS_MAC) || defined(OS_LINUX)
+#if defined(OS_MAC) || defined(OS_LINUX) || defined(OS_HAIKU)
#define OS_POSIX 1
-#endif // OS_MAC || OS_LINUX
+#endif // OS_MAC || OS_LINUX || OS_HAIKU
// Compiler detection.
#if defined(__clang__)
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..b3bcd43 100644
--- a/Telegram/lib_base/base/platform/base_platform_info.h
+++ b/Telegram/lib_base/base/platform/base_platform_info.h
@@ -53,8 +53,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..f1936d9
--- /dev/null
+++ b/Telegram/lib_base/base/platform/haiku/base_file_utilities_haiku.cpp
@@ -0,0 +1,118 @@
+/*
+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 "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;
+ process.start(
+ "xdg-mime",
+ QStringList() << "query" << "default" << "inode/directory");
+ process.waitForFinished();
+ auto output = QString::fromLatin1(process.readLine().simplified());
+ auto command = QString("xdg-open");
+ auto arguments = QStringList();
+ if (output == qstr("dolphin.desktop")
+ || output == qstr("org.kde.dolphin.desktop")) {
+ command = "dolphin";
+ arguments << "--select" << absolutePath;
+ } else if (output == qstr("nautilus.desktop")
+ || output == qstr("org.gnome.Nautilus.desktop")
+ || output == qstr("nautilus-folder-handler.desktop")) {
+ command = "nautilus";
+ arguments << absolutePath;
+ } else if (output == qstr("nemo.desktop")) {
+ command = "nemo";
+ arguments << "--no-desktop" << absolutePath;
+ } else if (output == qstr("konqueror.desktop")
+ || output == qstr("kfmclient_dir.desktop")) {
+ command = "konqueror";
+ arguments << "--select" << absolutePath;
+ } else {
+ arguments << QFileInfo(filepath).absoluteDir().absolutePath();
+ }
+ return process.startDetached(command, arguments);
+}
+
+QString CurrentExecutablePath(int argc, char *argv[]) {
+ constexpr auto kMaxPath = 1024;
+ char result[kMaxPath] = { 0 };
+ auto count = readlink("/proc/self/exe", result, kMaxPath);
+ if (count > 0) {
+ auto filename = QFile::decodeName(result);
+ auto deletedPostfix = qstr(" (deleted)");
+ if (filename.endsWith(deletedPostfix)
+ && !QFileInfo(filename).exists()) {
+ filename.chop(deletedPostfix.size());
+ }
+ return filename;
+ }
+
+ // Fallback to the first command line argument.
+ return argc ? QFile::decodeName(argv[0]) : QString();
+}
+
+void RemoveQuarantine(const QString &path) {
+}
+
+// From http://stackoverflow.com/questions/2256945/removing-a-non-empty-directory-programmatically-in-c-or-c
+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)) {
+ // Skip the names "." and ".." as we don't want to recurse on them.
+ 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..05f6cd3
--- /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-2019 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..a11b47e
--- /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-2019 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..bbb80a2
--- /dev/null
+++ b/Telegram/lib_base/base/platform/haiku/base_info_haiku.h
@@ -0,0 +1,57 @@
+/*
+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 "base/platform/base_platform_info.h"
+
+namespace Platform {
+
+inline constexpr bool IsLinux() {
+ return true;
+}
+
+inline constexpr bool IsLinux32Bit() {
+#ifdef Q_OS_LINUX32
+ return true;
+#else // Q_OS_LINUX32
+ return false;
+#endif // Q_OS_LINUX32
+}
+
+inline constexpr bool IsLinux64Bit() {
+#ifdef Q_OS_LINUX64
+ return true;
+#else // Q_OS_LINUX64
+ return false;
+#endif // Q_OS_LINUX64
+}
+
+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..550444b
--- /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-2019 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..d9ce6f6
--- /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-2019 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..7f9e74b
--- /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-2019 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..d9ce6f6
--- /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-2019 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..032d3c1
--- /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-2019 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..74b2a9d
--- /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-2019 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..85f1b4f
--- /dev/null
+++ b/Telegram/lib_base/base/platform/haiku/base_url_scheme_haiku.cpp
@@ -0,0 +1,192 @@
+/*
+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 "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;
+}
+
+bool RegisterDesktopFile(const UrlSchemeDescriptor &descriptor) {
+ const auto home = GetHomeDir();
+ if (home.isEmpty() || descriptor.executable.isEmpty() || descriptor.skipDesktopFileRegistration) {
+ return false;
+ }
+
+ if (!QDir(home + ".local/").exists()) {
+ return false;
+ }
+ const auto apps = home + ".local/share/applications/";
+ const auto icons = home + ".local/share/icons/";
+ if (!QDir(apps).exists()) {
+ QDir().mkpath(apps);
+ }
+ if (!QDir(icons).exists()) {
+ QDir().mkpath(icons);
+ }
+
+ const auto path = descriptor.desktopFileDir;
+ const auto file = path + descriptor.desktopFileName + ".desktop";
+ QDir().mkpath(path);
+ auto f = QFile(file);
+ if (!f.open(QIODevice::WriteOnly)) {
+ return false;
+ }
+ const auto icon = icons + descriptor.iconFileName + ".png";
+ if (descriptor.forceUpdateIcon) {
+ QFile(icon).remove();
+ }
+ if (descriptor.forceUpdateIcon || !QFile(icon).exists()) {
+ QFile(":/gui/art/logo.png").copy(icon);
+ }
+
+ auto s = QTextStream(&f);
+ s.setCodec("UTF-8");
+ s << "[Desktop Entry]\n";
+ s << "Version=1.0\n";
+ s << "Name=" << descriptor.displayAppName << "\n";
+ s << "Comment=" << descriptor.displayAppDescription << "\n";
+ s << "TryExec=" << EscapeShell(QFile::encodeName(descriptor.executable)) << "\n";
+ s << "Exec=" << EscapeShell(QFile::encodeName(descriptor.executable)) << " -- %u\n";
+ s << "Icon=" << descriptor.iconFileName << "\n";
+ s << "Terminal=false\n";
+ s << "StartupWMClass=" + QCoreApplication::instance()->applicationName() << "\n";
+ s << "Type=Application\n";
+ s << "MimeType=x-scheme-handler/" << descriptor.protocol << ";\n";
+ s << "X-GNOME-UsesNotifications=true\n";
+ f.close();
+
+ if (!RunShellCommand("desktop-file-install --dir=" + EscapeShell(QFile::encodeName(home + ".local/share/applications")) + " --delete-original " + EscapeShell(QFile::encodeName(file)))) {
+ return false;
+ }
+ RunShellCommand("update-desktop-database " + EscapeShell(QFile::encodeName(home + ".local/share/applications")));
+ RunShellCommand("xdg-mime default telegramdesktop.desktop x-scheme-handler/tg");
+ return true;
+}
+
+bool RegisterGnomeHandler(const UrlSchemeDescriptor &descriptor) {
+ const auto protocolUtf = descriptor.protocol.toUtf8();
+ if (!RunShellCommand("gconftool-2 -t string -s /desktop/gnome/url-handlers/" + protocolUtf + "/command " + EscapeShell(EscapeShell(QFile::encodeName(descriptor.executable)) + " -- %s"))) {
+ return false;
+ }
+ RunShellCommand("gconftool-2 -t bool -s /desktop/gnome/url-handlers/" + protocolUtf + "/needs_terminal false");
+ RunShellCommand("gconftool-2 -t bool -s /desktop/gnome/url-handlers/" + protocolUtf + "/enabled true");
+ return true;
+}
+
+bool RegisterKdeHandler(const UrlSchemeDescriptor &descriptor) {
+ const auto home = GetHomeDir();
+ if (home.isEmpty() || descriptor.executable.isEmpty()) {
+ return false;
+ }
+
+ const auto services = [&] {
+ if (QDir(home + ".kde4/").exists()) {
+ return home + ".kde4/share/kde4/services/";
+ } else if (QDir(home + ".kde/").exists()) {
+ return home + ".kde/share/kde4/services/";
+ }
+ return QString();
+ }();
+ if (services.isEmpty()) {
+ return false;
+ }
+ if (!QDir(services).exists()) {
+ QDir().mkpath(services);
+ }
+
+ const auto path = services;
+ const auto file = path + descriptor.protocol + ".protocol";
+ auto f = QFile(file);
+ if (!f.open(QIODevice::WriteOnly)) {
+ return false;
+ }
+ auto s = QTextStream(&f);
+ s.setCodec("UTF-8");
+ s << "[Protocol]\n";
+ s << "exec=" << QFile::decodeName(EscapeShell(QFile::encodeName(descriptor.executable))) << " -- %u\n";
+ s << "protocol=" << descriptor.protocol << "\n";
+ s << "input=none\n";
+ s << "output=none\n";
+ s << "helper=true\n";
+ s << "listing=false\n";
+ s << "reading=false\n";
+ s << "writing=false\n";
+ s << "makedir=false\n";
+ s << "deleting=false\n";
+ f.close();
+ return true;
+}
+
+} // namespace
+
+bool CheckUrlScheme(const UrlSchemeDescriptor &descriptor) {
+ return false;
+}
+
+void RegisterUrlScheme(const UrlSchemeDescriptor &descriptor) {
+ RegisterDesktopFile(descriptor);
+ RegisterGnomeHandler(descriptor);
+ RegisterKdeHandler(descriptor);
+}
+
+void UnregisterUrlScheme(const UrlSchemeDescriptor &descriptor) {
+ // TODO
+}
+
+} // 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..177a2a1
--- /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-2019 Gerasim Troeglazov, 3dEyes@gmail.com
+*/
+
+#pragma once
+
+#include "base/platform/base_platform_url_scheme.h"
diff --git a/Telegram/lib_spellcheck/CMakeLists.txt b/Telegram/lib_spellcheck/CMakeLists.txt
index 282e732..c85ee20 100644
--- a/Telegram/lib_spellcheck/CMakeLists.txt
+++ b/Telegram/lib_spellcheck/CMakeLists.txt
@@ -18,10 +18,6 @@ PRIVATE
spellcheck/platform/linux/linux_enchant.h
spellcheck/platform/linux/spellcheck_linux.cpp
spellcheck/platform/linux/spellcheck_linux.h
- spellcheck/platform/mac/spellcheck_mac.h
- spellcheck/platform/mac/spellcheck_mac.mm
- spellcheck/platform/win/spellcheck_win.cpp
- spellcheck/platform/win/spellcheck_win.h
spellcheck/spellcheck_utils.cpp
spellcheck/spellcheck_utils.h
spellcheck/spellcheck_types.h
@@ -39,7 +35,7 @@ PUBLIC
desktop-app::lib_ui
)
-if (LINUX)
+if (LINUX OR HAIKU)
find_package(PkgConfig REQUIRED)
pkg_search_module(ENCHANT REQUIRED enchant-2 enchant)
diff --git a/Telegram/lib_spellcheck/spellcheck/platform/linux/linux_enchant.cpp b/Telegram/lib_spellcheck/spellcheck/platform/linux/linux_enchant.cpp
index 3074802..88e3333 100644
--- a/Telegram/lib_spellcheck/spellcheck/platform/linux/linux_enchant.cpp
+++ b/Telegram/lib_spellcheck/spellcheck/platform/linux/linux_enchant.cpp
@@ -32,7 +32,11 @@
* rigid dependency on the Enchant library at runtime.
*/
+#ifdef __HAIKU__
+#include <enchant-2/enchant.h>
+#else
#include <enchant.h>
+#endif
#include <dlfcn.h>
#include "spellcheck/platform/linux/linux_enchant.h"
diff --git a/Telegram/lib_spellcheck/spellcheck/platform/platform_spellcheck.h b/Telegram/lib_spellcheck/spellcheck/platform/platform_spellcheck.h
index 6ad7201..89cf176 100644
--- a/Telegram/lib_spellcheck/spellcheck/platform/platform_spellcheck.h
+++ b/Telegram/lib_spellcheck/spellcheck/platform/platform_spellcheck.h
@@ -39,6 +39,6 @@ void CheckSpellingText(
#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_WINRT || defined Q_OS_LINUX || defined Q_OS_HAIKU // Q_OS_MAC || Q_OS_WIN
#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_storage/CMakeLists.txt b/Telegram/lib_storage/CMakeLists.txt
index b5a2576..3c74381 100644
--- a/Telegram/lib_storage/CMakeLists.txt
+++ b/Telegram/lib_storage/CMakeLists.txt
@@ -15,7 +15,6 @@ nice_target_sources(lib_storage ${src_loc}
PRIVATE
storage/storage_clear_legacy.cpp
storage/storage_clear_legacy_posix.cpp
- storage/storage_clear_legacy_win.cpp
storage/storage_clear_legacy.h
storage/storage_databases.cpp
storage/storage_databases.h
@@ -36,7 +35,6 @@ PRIVATE
storage/cache/storage_cache_types.cpp
storage/cache/storage_cache_types.h
storage/storage_clear_legacy_posix.cpp
- storage/storage_clear_legacy_win.cpp
)
target_include_directories(lib_storage
diff --git a/Telegram/lib_ui/CMakeLists.txt b/Telegram/lib_ui/CMakeLists.txt
index 687b25f..e18a853 100644
--- a/Telegram/lib_ui/CMakeLists.txt
+++ b/Telegram/lib_ui/CMakeLists.txt
@@ -21,9 +21,7 @@ set(style_files
)
set(qrc_files
fonts/fonts.qrc
- qt_conf/linux.qrc
- qt_conf/mac.qrc
- qt_conf/win.qrc
+ qt_conf/haiku.qrc
)
generate_palette(lib_ui ui/colors.palette)
@@ -70,24 +68,10 @@ PRIVATE
ui/layers/layer_manager.h
ui/layers/layer_widget.cpp
ui/layers/layer_widget.h
- ui/platform/linux/ui_window_linux.cpp
- ui/platform/linux/ui_window_linux.h
- ui/platform/linux/ui_utility_linux.cpp
- ui/platform/linux/ui_utility_linux.h
- ui/platform/mac/ui_window_mac.h
- ui/platform/mac/ui_window_mac.mm
- ui/platform/mac/ui_window_title_mac.h
- ui/platform/mac/ui_window_title_mac.mm
- ui/platform/mac/ui_utility_mac.h
- ui/platform/mac/ui_utility_mac.mm
- ui/platform/win/ui_window_shadow_win.cpp
- ui/platform/win/ui_window_shadow_win.h
- ui/platform/win/ui_window_title_win.cpp
- ui/platform/win/ui_window_title_win.h
- ui/platform/win/ui_window_win.cpp
- 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/qt_conf/haiku.qrc b/Telegram/lib_ui/qt_conf/haiku.qrc
new file mode 100644
index 0000000..b9f5692
--- /dev/null
+++ b/Telegram/lib_ui/qt_conf/haiku.qrc
@@ -0,0 +1,8 @@
+<RCC>
+ <qresource prefix="/qt/etc">
+ <file alias="qt.conf">qt_linux.conf</file>
+ </qresource>
+ <qresource prefix="/fc">
+ <file>fc-custom.conf</file>
+ </qresource>
+</RCC>
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..0bd8f94
--- /dev/null
+++ b/Telegram/lib_ui/ui/platform/haiku/ui_utility_haiku.cpp
@@ -0,0 +1,47 @@
+// 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 "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) {
+ if (const auto native = QGuiApplication::platformNativeInterface()) {
+ if (const auto desktop = QApplication::desktop()) {
+ const auto index = desktop->screenNumber(globalPosition);
+ const auto screens = QGuiApplication::screens();
+ if (const auto screen = (index >= 0 && index < screens.size()) ? screens[index] : QGuiApplication::primaryScreen()) {
+ if (native->nativeResourceForScreen(QByteArray("compositingEnabled"), screen)) {
+ return true;
+ }
+ static auto WarnedAbout = base::flat_set<int>();
+ if (!WarnedAbout.contains(index)) {
+ WarnedAbout.emplace(index);
+ UI_LOG(("WARNING: Compositing is disabled for screen index %1 (for position %2,%3)").arg(index).arg(globalPosition.x()).arg(globalPosition.y()));
+ }
+ } else {
+ UI_LOG(("WARNING: Could not get screen for index %1 (for position %2,%3)").arg(index).arg(globalPosition.x()).arg(globalPosition.y()));
+ }
+ }
+ }
+ return false;
+}
+
+} // 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..c2f49dc
--- /dev/null
+++ b/Telegram/lib_ui/ui/platform/haiku/ui_utility_haiku.h
@@ -0,0 +1,41 @@
+// 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
+
+class QPainter;
+class QPaintEvent;
+
+namespace Ui {
+namespace Platform {
+
+inline void StartTranslucentPaint(QPainter &p, QPaintEvent *e) {
+}
+
+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..8e2a83a
--- /dev/null
+++ b/Telegram/lib_ui/ui/platform/haiku/ui_window_haiku.cpp
@@ -0,0 +1,18 @@
+// 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 "ui/platform/linux/ui_window_linux.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..b4f4fe2
--- /dev/null
+++ b/Telegram/lib_ui/ui/platform/haiku/ui_window_haiku.h
@@ -0,0 +1,9 @@
+// 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 "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 d253c91..2034204 100644
--- a/Telegram/lib_ui/ui/platform/ui_platform_utility.h
+++ b/Telegram/lib_ui/ui/platform/ui_platform_utility.h
@@ -36,8 +36,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/Telegram/lib_ui/ui/style/style_core_font.cpp b/Telegram/lib_ui/ui/style/style_core_font.cpp
index cfe2111..fdb8f22 100644
--- a/Telegram/lib_ui/ui/style/style_core_font.cpp
+++ b/Telegram/lib_ui/ui/style/style_core_font.cpp
@@ -20,9 +20,11 @@ void style_InitFontsResource() {
Q_INIT_RESOURCE(win);
#elif defined Q_OS_MAC // Q_OS_WIN
Q_INIT_RESOURCE(mac);
-#else // Q_OS_WIN || Q_OS_MAC
+#elif defined Q_OS_HAIKU // Q_OS_WIN || Q_OS_MAC
+ Q_INIT_RESOURCE(haiku);
+#else // Q_OS_WIN || Q_OS_MAC || Q_OS_HAIKU
Q_INIT_RESOURCE(linux);
-#endif // Q_OS_WIN || Q_OS_MAC || Q_OS_LINUX
+#endif // Q_OS_WIN || Q_OS_MAC || Q_OS_LINUX || Q_OS_HAIKU
}
namespace style {
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 4187ad3..68e36e3 100644
--- a/cmake/external/CMakeLists.txt
+++ b/cmake/external/CMakeLists.txt
@@ -5,16 +5,9 @@
# https://github.com/desktop-app/legal/blob/master/LEGAL
add_subdirectory(auto_updates)
-add_subdirectory(crash_reports)
add_subdirectory(expected)
-add_subdirectory(ffmpeg)
add_subdirectory(gsl)
add_subdirectory(iconv)
-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)
@@ -23,4 +16,3 @@ if (APPLE)
endif()
add_subdirectory(variant)
add_subdirectory(xxhash)
-add_subdirectory(zlib)
diff --git a/cmake/init_target.cmake b/cmake/init_target.cmake
index c7a1244..fc691a6 100644
--- a/cmake/init_target.cmake
+++ b/cmake/init_target.cmake
@@ -27,7 +27,6 @@ function(init_target target_name) # init_target(my_target folder_name)
endif()
target_link_libraries(${target_name} PUBLIC desktop-app::common_options)
set_target_properties(${target_name} PROPERTIES
- LINK_SEARCH_START_STATIC 1
XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_WEAK YES
XCODE_ATTRIBUTE_GCC_INLINES_ARE_PRIVATE_EXTERN YES
XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN YES
diff --git a/cmake/options.cmake b/cmake/options.cmake
index 56dbe48..59d191a 100644
--- a/cmake/options.cmake
+++ b/cmake/options.cmake
@@ -23,6 +23,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..677cb36
--- /dev/null
+++ b/cmake/options_haiku.cmake
@@ -0,0 +1,31 @@
+# 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>,,-O3 -fno-strict-aliasing>
+ -pipe
+ -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>,,-O3>
+)
diff --git a/cmake/variables.cmake b/cmake/variables.cmake
index b3d7ff4..37fd1eb 100644
--- a/cmake/variables.cmake
+++ b/cmake/variables.cmake
@@ -37,6 +37,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")
@@ -57,6 +58,12 @@ elseif (APPLE)
report_bad_special_target()
endif()
set(DESKTOP_APP_USE_GLIBC_WRAPS OFF)
+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()
set(LINUX 1)
execute_process(COMMAND uname -m OUTPUT_VARIABLE machine_uname)
@@ -79,8 +86,10 @@ else()
set(CMAKE_NM /usr/bin/gcc-nm)
endif()
-if (NOT APPLE OR build_osx)
- get_filename_component(libs_loc "../Libraries" REALPATH)
+if (HAIKU)
+ get_filename_component(libs_loc "Telegram/ThirdParty" REALPATH)
+elseif (NOT APPLE OR build_osx)
+ get_filename_component(libs_loc "Telegram/ThirdParty" REALPATH)
else()
get_filename_component(libs_loc "../Libraries/macos" REALPATH)
endif()
--
2.24.1