From c666391e6b36c0104de5e9d562c8ce11bf6f4905 Mon Sep 17 00:00:00 2001 From: Gerasim Troeglazov <3dEyes@gmail.com> Date: Mon, 6 Jan 2020 18:27:12 +1000 Subject: [PATCH] Telegram: bump version --- ...telegram_desktop-1.8.15-libtgvoip.patchset | 964 ---- .../telegram_desktop-1.8.15-sonnet.patchset | 105 - .../patches/telegram_desktop-1.8.15.patchset | 2928 ----------- .../patches/telegram_desktop-1.9.3.patchset | 4344 +++++++++++++++++ .../telegram_desktop-1.8.15.recipe | 201 - .../telegram_desktop-1.9.3.recipe | 161 + 6 files changed, 4505 insertions(+), 4198 deletions(-) delete mode 100644 net-im/telegram-desktop/patches/telegram_desktop-1.8.15-libtgvoip.patchset delete mode 100644 net-im/telegram-desktop/patches/telegram_desktop-1.8.15-sonnet.patchset delete mode 100644 net-im/telegram-desktop/patches/telegram_desktop-1.8.15.patchset create mode 100644 net-im/telegram-desktop/patches/telegram_desktop-1.9.3.patchset delete mode 100644 net-im/telegram-desktop/telegram_desktop-1.8.15.recipe create mode 100644 net-im/telegram-desktop/telegram_desktop-1.9.3.recipe diff --git a/net-im/telegram-desktop/patches/telegram_desktop-1.8.15-libtgvoip.patchset b/net-im/telegram-desktop/patches/telegram_desktop-1.8.15-libtgvoip.patchset deleted file mode 100644 index 34829d264..000000000 --- a/net-im/telegram-desktop/patches/telegram_desktop-1.8.15-libtgvoip.patchset +++ /dev/null @@ -1,964 +0,0 @@ -From ad449f133830076fad26121a34d780a0c385ce25 Mon Sep 17 00:00:00 2001 -From: Gerasim Troeglazov <3dEyes@gmail.com> -Date: Sat, 10 Aug 2019 12:20:44 +1000 -Subject: Add mediakit support - - -diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/OpusDecoder.cpp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/OpusDecoder.cpp -old mode 100755 -new mode 100644 -index 0ecd63e..61081f9 ---- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/OpusDecoder.cpp -+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/OpusDecoder.cpp -@@ -10,7 +10,7 @@ - #include - #include - #include --#ifdef HAVE_CONFIG_H -+#if defined(HAVE_CONFIG_H) || defined(__HAIKU__) - #include - #else - #include "opus.h" -diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/OpusEncoder.cpp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/OpusEncoder.cpp -old mode 100755 -new mode 100644 -index 8786bf5..ab5abc4 ---- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/OpusEncoder.cpp -+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/OpusEncoder.cpp -@@ -9,7 +9,7 @@ - #include - #include "logging.h" - #include "VoIPServerConfig.h" --#ifdef HAVE_CONFIG_H -+#if defined(HAVE_CONFIG_H) || defined(__HAIKU__) - #include - #else - #include "opus.h" -diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/OpusEncoder.h b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/OpusEncoder.h -old mode 100755 -new mode 100644 -diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/VoIPController.cpp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/VoIPController.cpp -old mode 100755 -new mode 100644 -index d9297ce..ca81e70 ---- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/VoIPController.cpp -+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/VoIPController.cpp -@@ -8,6 +8,9 @@ - #include - #include - #endif -+#ifdef __HAIKU__ -+#include -+#endif - #include - #include - #include -@@ -3052,6 +3055,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/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/audio/AudioIO.cpp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/audio/AudioIO.cpp -index 2c16ca7..e00c731 100644 ---- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/audio/AudioIO.cpp -+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/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(inputDevice, outputDevice); - #endif - return new ContextlessAudioIO(inputDevice, outputDevice); -+#elif defined(__HAIKU__) -+ return new ContextlessAudioIO(); - #elif defined(__linux__) - #ifndef WITHOUT_ALSA - #ifndef WITHOUT_PULSE -diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/audio/AudioInput.cpp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/audio/AudioInput.cpp -index dae647a..4bab98c 100644 ---- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/audio/AudioInput.cpp -+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/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/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/audio/AudioOutput.cpp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/audio/AudioOutput.cpp -index 458e8a5..1890350 100644 ---- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/audio/AudioOutput.cpp -+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/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/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/libtgvoip.gyp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/libtgvoip.gyp -index b5f3b81..1d5b508 100644 ---- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/libtgvoip.gyp -+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/libtgvoip.gyp -@@ -115,6 +115,14 @@ - '<(tgvoip_src_loc)/os/linux/AudioPulse.cpp', - '<(tgvoip_src_loc)/os/linux/AudioPulse.h', - -+ # Haiku -+ '<(tgvoip_src_loc)/os/haiku/AudioInputHaiku.cpp', -+ '<(tgvoip_src_loc)/os/haiku/AudioInputHaiku.h', -+ '<(tgvoip_src_loc)/os/haiku/AudioOutputHaiku.cpp', -+ '<(tgvoip_src_loc)/os/haiku/AudioOutputHaiku.h', -+ '<(tgvoip_src_loc)/os/haiku/RingBuffer.cpp', -+ '<(tgvoip_src_loc)/os/haiku/RingBuffer.h', -+ - # POSIX - '<(tgvoip_src_loc)/os/posix/NetworkSocketPosix.cpp', - '<(tgvoip_src_loc)/os/posix/NetworkSocketPosix.h', -@@ -737,6 +745,11 @@ - 'sources/': [['exclude', '<(tgvoip_src_loc)/os/posix/']], - }, - ], -+ [ -+ '"<(OS)" != "haiku"', { -+ 'sources/': [['exclude', '<(tgvoip_src_loc)/os/haiku/']], -+ }, -+ ], - [ - '"<(OS)" != "mac"', { - 'sources/': [['exclude', '<(tgvoip_src_loc)/os/darwin/']], -@@ -895,6 +908,22 @@ - }, - ], - [ -+ '"<(OS)" == "haiku"', { -+ 'defines': [ -+ 'WEBRTC_POSIX', -+ 'WEBRTC_HAIKU', -+ ], -+ 'cflags_cc': [ -+ '-msse2', -+ '-std=gnu++14', -+ ], -+ 'direct_dependent_settings': { -+ 'libraries': [ -+ -+ ], -+ }, -+ }, -+ ], [ - '"<(OS)" == "linux"', { - 'defines': [ - 'WEBRTC_POSIX', -diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/AudioInputHaiku.cpp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/AudioInputHaiku.cpp -new file mode 100644 -index 0000000..7cce3e3 ---- /dev/null -+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/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 -+#include -+#include -+#include -+#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(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(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(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(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/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/AudioInputHaiku.h b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/AudioInputHaiku.h -new file mode 100644 -index 0000000..1c63afe ---- /dev/null -+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/AudioOutputHaiku.cpp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/AudioOutputHaiku.cpp -new file mode 100644 -index 0000000..2fca8a1 ---- /dev/null -+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/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 -+#include -+#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/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/AudioOutputHaiku.h b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/AudioOutputHaiku.h -new file mode 100644 -index 0000000..91f2521 ---- /dev/null -+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/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 -+ -+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/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/RingBuffer.cpp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/RingBuffer.cpp -new file mode 100644 -index 0000000..43236d3 ---- /dev/null -+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/RingBuffer.cpp -@@ -0,0 +1,130 @@ -+#include -+#include -+#include -+#include -+ -+#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/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/RingBuffer.h b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/RingBuffer.h -new file mode 100644 -index 0000000..4715632 ---- /dev/null -+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/haiku/RingBuffer.h -@@ -0,0 +1,31 @@ -+#ifndef __RING_BUFFER_H__ -+#define __RING_BUFFER_H__ -+ -+#include -+ -+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/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/posix/NetworkSocketPosix.cpp b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/posix/NetworkSocketPosix.cpp -index 52eef76..c480dfb 100644 ---- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/os/posix/NetworkSocketPosix.cpp -+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/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/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/threading.h b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/threading.h -old mode 100755 -new mode 100644 -index 9dc2554..fc68fd4 ---- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/threading.h -+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/threading.h -@@ -9,7 +9,7 @@ - - #include - --#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 - #include -@@ -92,6 +92,7 @@ namespace tgvoip{ - static void* ActualEntryPoint(void* arg){ - Thread* self=reinterpret_cast(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/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/logging_webrtc.cc b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/logging_webrtc.cc -old mode 100755 -new mode 100644 -index a8d1522..991241b ---- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/logging_webrtc.cc -+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/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 -+#endif -+ - #include - #include - #include -@@ -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/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/platform_file.h b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/platform_file.h -old mode 100755 -new mode 100644 -diff --git a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/platform_thread_types.cc b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/platform_thread_types.cc -index 70cf237..e48948e 100644 ---- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/platform_thread_types.cc -+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/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/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/platform_thread_types.h b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/platform_thread_types.h -index 0bc42eb..c87cde9 100644 ---- a/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/webrtc_dsp/rtc_base/platform_thread_types.h -+++ b/libtgvoip-d4a0f719ffd8d29e88474f67abc9fc862661c3b9/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; --- -2.21.0 - diff --git a/net-im/telegram-desktop/patches/telegram_desktop-1.8.15-sonnet.patchset b/net-im/telegram-desktop/patches/telegram_desktop-1.8.15-sonnet.patchset deleted file mode 100644 index 3c2e9baef..000000000 --- a/net-im/telegram-desktop/patches/telegram_desktop-1.8.15-sonnet.patchset +++ /dev/null @@ -1,105 +0,0 @@ -From ef6a0eaa529bc699a78e18e7f2fd58d7d3d5df32 Mon Sep 17 00:00:00 2001 -From: Gerasim Troeglazov <3dEyes@gmail.com> -Date: Sun, 6 Oct 2019 20:25:58 +1000 -Subject: Add Sonnet spell checking - - -diff --git a/Telegram/SourceFiles/ui/widgets/input_fields.cpp b/Telegram/SourceFiles/ui/widgets/input_fields.cpp -index 1c0b13c..9e98c8d 100644 ---- a/Telegram/SourceFiles/ui/widgets/input_fields.cpp -+++ b/Telegram/SourceFiles/ui/widgets/input_fields.cpp -@@ -1336,6 +1336,8 @@ InputField::InputField( - setTextWithTags(_lastTextWithTags, HistoryAction::Clear); - } - -+ _SpellCheckDecorator = std::make_unique(_inner.get()); -+ - startBorderAnimation(); - startPlaceholderAnimation(); - finishAnimating(); -@@ -3305,6 +3307,12 @@ bool InputField::revertFormatReplace() { - void InputField::contextMenuEventInner(QContextMenuEvent *e) { - if (const auto menu = _inner->createStandardContextMenu()) { - addMarkdownActions(menu, e); -+ if (const auto h = _SpellCheckDecorator->highlighter()) { -+ menu->addSeparator(); -+ menu->addAction(h->isActive() ? qstr("Disable spell checking") : qstr("Enable spell checking"), [=] { -+ h->setActive(!h->isActive()); -+ }); -+ } - _contextMenu = base::make_unique_q(this, menu); - _contextMenu->popup(e->globalPos()); - } -diff --git a/Telegram/SourceFiles/ui/widgets/input_fields.h b/Telegram/SourceFiles/ui/widgets/input_fields.h -index ae480a0..fe65db1 100644 ---- a/Telegram/SourceFiles/ui/widgets/input_fields.h -+++ b/Telegram/SourceFiles/ui/widgets/input_fields.h -@@ -13,6 +13,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL - #include "ui/text/text_entity.h" - #include "styles/style_widgets.h" - -+#include -+#include -+ - #include - #include - #include -@@ -514,6 +517,8 @@ private: - InstantReplaces _mutableInstantReplaces; - bool _instantReplacesEnabled = true; - -+ std::unique_ptr _SpellCheckDecorator; -+ - }; - - class MaskedInputField : public RpWidgetWrap { -diff --git a/Telegram/gyp/common/haiku.gypi b/Telegram/gyp/common/haiku.gypi -index dbc6dce..78d0b6c 100644 ---- a/Telegram/gyp/common/haiku.gypi -+++ b/Telegram/gyp/common/haiku.gypi -@@ -34,7 +34,16 @@ - '-Wno-missing-field-initializers', - '-Wno-sign-compare', - ], -+ 'haiku_path_include%': '@HAIKU_HEADERS@', - }, -+ 'include_dirs': [ -+ '<(haiku_path_include)/KF5/SonnetCore', -+ '<(haiku_path_include)/KF5/SonnetCore/Sonnet', -+ '<(haiku_path_include)/KF5/SonnetCore/sonnet', -+ '<(haiku_path_include)/KF5/SonnetUi', -+ '<(haiku_path_include)/KF5/SonnetUi/Sonnet', -+ '<(haiku_path_include)/KF5/SonnetUi/sonnet', -+ ], - 'defines': [ - '_REENTRANT', - 'QT_PLUGIN', -diff --git a/Telegram/gyp/telegram/haiku.gypi b/Telegram/gyp/telegram/haiku.gypi -index 76a08fa..2062a63 100644 ---- a/Telegram/gyp/telegram/haiku.gypi -+++ b/Telegram/gyp/telegram/haiku.gypi -@@ -30,6 +30,12 @@ - '<(haiku_path_include)/AL', - '<(haiku_path_include)/breakpad', - '<(haiku_path_include)/opus', -+ '<(haiku_path_include)/KF5/SonnetCore', -+ '<(haiku_path_include)/KF5/SonnetCore/Sonnet', -+ '<(haiku_path_include)/KF5/SonnetCore/sonnet', -+ '<(haiku_path_include)/KF5/SonnetUi', -+ '<(haiku_path_include)/KF5/SonnetUi/Sonnet', -+ '<(haiku_path_include)/KF5/SonnetUi/sonnet', - '<(submodules_loc)/range/include', - '<(submodules_loc)/variant/test/include', - ], -@@ -46,6 +52,8 @@ - '-lnetwork', - '-ltranslation', - '-lbe', -+ '-lKF5SonnetCore', -+ '-lKF5SonnetUi', - '-llzma', - '-lz', - # ' /dev/null --libs <@(pkgconfig_libs))', --- -2.23.0 - diff --git a/net-im/telegram-desktop/patches/telegram_desktop-1.8.15.patchset b/net-im/telegram-desktop/patches/telegram_desktop-1.8.15.patchset deleted file mode 100644 index dd187712b..000000000 --- a/net-im/telegram-desktop/patches/telegram_desktop-1.8.15.patchset +++ /dev/null @@ -1,2928 +0,0 @@ -From 5a510ef350b1bd0f244c9c673701b4f581c86897 Mon Sep 17 00:00:00 2001 -From: Gerasim Troeglazov <3dEyes@gmail.com> -Date: Sun, 6 Oct 2019 20:25:00 +1000 -Subject: Add Haiku support - - -diff --git a/Telegram/Resources/etc/qt_haiku.conf b/Telegram/Resources/etc/qt_haiku.conf -new file mode 100644 -index 0000000..6d80862 ---- /dev/null -+++ b/Telegram/Resources/etc/qt_haiku.conf -@@ -0,0 +1,2 @@ -+[Paths] -+Libraries=:/gui/art -diff --git a/Telegram/Resources/qrc/haiku.qrc b/Telegram/Resources/qrc/haiku.qrc -new file mode 100644 -index 0000000..33115f9 ---- /dev/null -+++ b/Telegram/Resources/qrc/haiku.qrc -@@ -0,0 +1,5 @@ -+ -+ -+ ../etc/qt_haiku.conf -+ -+ -diff --git a/Telegram/SourceFiles/base/build_config.h b/Telegram/SourceFiles/base/build_config.h -index 3bcb595..b97d66a 100644 ---- a/Telegram/SourceFiles/base/build_config.h -+++ b/Telegram/SourceFiles/base/build_config.h -@@ -17,13 +17,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL - #define OS_LINUX 1 - #elif defined(_WIN32) // __APPLE__ || __linux__ - #define OS_WIN 1 -+#elif defined(__HAIKU__) -+#define OS_HAIKU 1 - #else // __APPLE__ || __linux__ || _WIN32 - #error Please add support for your platform in base/build_config.h - #endif // else for __APPLE__ || __linux__ || _WIN32 - - // 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 - -diff --git a/Telegram/SourceFiles/core/crash_reports.cpp b/Telegram/SourceFiles/core/crash_reports.cpp -index ce938a3..02066c7 100644 ---- a/Telegram/SourceFiles/core/crash_reports.cpp -+++ b/Telegram/SourceFiles/core/crash_reports.cpp -@@ -332,6 +332,8 @@ QString PlatformString() { - return qsl("MacOSold"); - } else if (Platform::IsMac()) { - return qsl("MacOS"); -+ } else if (Platform::IsHaiku()) { -+ return qsl("Haiku"); - } else if (Platform::IsLinux32Bit()) { - return qsl("Linux32Bit"); - } else if (Platform::IsLinux64Bit()) { -diff --git a/Telegram/SourceFiles/core/launcher.cpp b/Telegram/SourceFiles/core/launcher.cpp -index 3ba2830..faa982b 100644 ---- a/Telegram/SourceFiles/core/launcher.cpp -+++ b/Telegram/SourceFiles/core/launcher.cpp -@@ -17,6 +17,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL - #include "base/concurrent_timer.h" - #include "facades.h" - -+#ifdef __HAIKU__ -+#include -+#include -+#endif -+ - namespace Core { - namespace { - -@@ -272,6 +277,13 @@ int Launcher::exec() { - Logs::start(this); // must be started before Platform is started - Platform::start(); // must be started before Sandbox is created - -+#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)); -@@ -456,7 +468,16 @@ int Launcher::executeApplication() { - Sandbox sandbox(this, arguments.count(), arguments.values()); - Ui::MainQueueProcessor processor; - base::ConcurrentTimerEnvironment environment; -+#ifdef __HAIKU__ -+ int res = sandbox.start(); -+ CrashReports::Finish(); -+ Platform::finish(); -+ Logs::finish(); -+ kill(::getpid(), SIGKILL); -+ return res; -+#else - return sandbox.start(); -+#endif - } - - } // namespace Core -diff --git a/Telegram/SourceFiles/core/update_checker.cpp b/Telegram/SourceFiles/core/update_checker.cpp -index 338d1f1..b0199cb 100644 ---- a/Telegram/SourceFiles/core/update_checker.cpp -+++ b/Telegram/SourceFiles/core/update_checker.cpp -@@ -1511,6 +1511,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_LINUX -+ 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..c53a191 100644 ---- a/Telegram/SourceFiles/media/audio/media_audio.cpp -+++ b/Telegram/SourceFiles/media/audio/media_audio.cpp -@@ -102,6 +102,7 @@ void EnumeratePlaybackDevices() { - void EnumerateCaptureDevices() { - auto deviceNames = QStringList(); - auto devices = alcGetString(nullptr, ALC_CAPTURE_DEVICE_SPECIFIER); -+#ifndef __HAIKU__ - Assert(devices != nullptr); - while (*devices != 0) { - auto deviceName8Bit = QByteArray(devices); -@@ -110,7 +111,7 @@ void EnumerateCaptureDevices() { - devices += deviceName8Bit.size() + 1; - } - LOG(("Audio Capture Devices: %1").arg(deviceNames.join(';'))); -- -+#endif - if (auto device = alcGetString(nullptr, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER)) { - LOG(("Audio Capture 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..fc9b389 ---- /dev/null -+++ b/Telegram/SourceFiles/platform/haiku/file_utilities_haiku.cpp -@@ -0,0 +1,138 @@ -+/* -+This file is part of Telegram Desktop for Haiku, -+ -+You can redistribute it and/or modify it under the terms of the -+GNU General Public License as published by the Free Software Foundation, -+either version 3 of the License, or (at your option) any later version. -+ -+It is distributed in the hope that it will be useful, -+but WITHOUT ANY WARRANTY; without even the implied warranty of -+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+GNU General Public License for more details. -+ -+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE -+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 -+ -+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 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..a61342c ---- /dev/null -+++ b/Telegram/SourceFiles/platform/haiku/file_utilities_haiku.h -@@ -0,0 +1,67 @@ -+/* -+This file is part of Telegram Desktop for Haiku, -+ -+You can redistribute it and/or modify it under the terms of the -+GNU General Public License as published by the Free Software Foundation, -+either version 3 of the License, or (at your option) any later version. -+ -+It is distributed in the hope that it will be useful, -+but WITHOUT ANY WARRANTY; without even the implied warranty of -+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+GNU General Public License for more details. -+ -+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE -+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..5fe1b94 ---- /dev/null -+++ b/Telegram/SourceFiles/platform/haiku/haiku_desktop_environment.cpp -@@ -0,0 +1,67 @@ -+/* -+This file is part of Telegram Desktop for Haiku, -+ -+You can redistribute it and/or modify it under the terms of the -+GNU General Public License as published by the Free Software Foundation, -+either version 3 of the License, or (at your option) any later version. -+ -+It is distributed in the hope that it will be useful, -+but WITHOUT ANY WARRANTY; without even the implied warranty of -+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+GNU General Public License for more details. -+ -+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE -+Copyright (c) 2018 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(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..248d8a8 ---- /dev/null -+++ b/Telegram/SourceFiles/platform/haiku/haiku_desktop_environment.h -@@ -0,0 +1,33 @@ -+/* -+This file is part of Telegram Desktop for Haiku, -+ -+You can redistribute it and/or modify it under the terms of the -+GNU General Public License as published by the Free Software Foundation, -+either version 3 of the License, or (at your option) any later version. -+ -+It is distributed in the hope that it will be useful, -+but WITHOUT ANY WARRANTY; without even the implied warranty of -+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+GNU General Public License for more details. -+ -+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE -+Copyright (c) 2018 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..a9e79ac ---- /dev/null -+++ b/Telegram/SourceFiles/platform/haiku/info_haiku.cpp -@@ -0,0 +1,49 @@ -+/* -+This file is part of Telegram Desktop for Haiku, -+ -+You can redistribute it and/or modify it under the terms of the -+GNU General Public License as published by the Free Software Foundation, -+either version 3 of the License, or (at your option) any later version. -+ -+It is distributed in the hope that it will be useful, -+but WITHOUT ANY WARRANTY; without even the implied warranty of -+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+GNU General Public License for more details. -+ -+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE -+Copyright (c) 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..32f2da5 ---- /dev/null -+++ b/Telegram/SourceFiles/platform/haiku/info_haiku.h -@@ -0,0 +1,51 @@ -+/* -+This file is part of Telegram Desktop for Haiku, -+ -+You can redistribute it and/or modify it under the terms of the -+GNU General Public License as published by the Free Software Foundation, -+either version 3 of the License, or (at your option) any later version. -+ -+It is distributed in the hope that it will be useful, -+but WITHOUT ANY WARRANTY; without even the implied warranty of -+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+GNU General Public License for more details. -+ -+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE -+Copyright (c) 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..7cae4cc ---- /dev/null -+++ b/Telegram/SourceFiles/platform/haiku/launcher_haiku.cpp -@@ -0,0 +1,68 @@ -+/* -+This file is part of Telegram Desktop for Haiku, -+ -+You can redistribute it and/or modify it under the terms of the -+GNU General Public License as published by the Free Software Foundation, -+either version 3 of the License, or (at your option) any later version. -+ -+It is distributed in the hope that it will be useful, -+but WITHOUT ANY WARRANTY; without even the implied warranty of -+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+GNU General Public License for more details. -+ -+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE -+Copyright (c) 2018 Gerasim Troeglazov, 3dEyes@gmail.com -+*/ -+ -+#include "platform/haiku/launcher_haiku.h" -+ -+#include "core/crash_reports.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+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 _argumentValues; -+ std::vector _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..54073f5 ---- /dev/null -+++ b/Telegram/SourceFiles/platform/haiku/launcher_haiku.h -@@ -0,0 +1,32 @@ -+/* -+This file is part of Telegram Desktop for Haiku, -+ -+You can redistribute it and/or modify it under the terms of the -+GNU General Public License as published by the Free Software Foundation, -+either version 3 of the License, or (at your option) any later version. -+ -+It is distributed in the hope that it will be useful, -+but WITHOUT ANY WARRANTY; without even the implied warranty of -+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+GNU General Public License for more details. -+ -+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE -+Copyright (c) 2018 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..b0689e4 ---- /dev/null -+++ b/Telegram/SourceFiles/platform/haiku/main_window_haiku.cpp -@@ -0,0 +1,141 @@ -+/* -+This file is part of Telegram Desktop for Haiku, -+ -+You can redistribute it and/or modify it under the terms of the -+GNU General Public License as published by the Free Software Foundation, -+either version 3 of the License, or (at your option) any later version. -+ -+It is distributed in the hope that it will be useful, -+but WITHOUT ANY WARRANTY; without even the implied warranty of -+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+GNU General Public License for more details. -+ -+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE -+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 -+#include -+#include -+#include -+#include -+ -+namespace Platform { -+ -+MainWindow::MainWindow(not_null 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..234283f ---- /dev/null -+++ b/Telegram/SourceFiles/platform/haiku/main_window_haiku.h -@@ -0,0 +1,76 @@ -+/* -+This file is part of Telegram Desktop for Haiku, -+ -+You can redistribute it and/or modify it under the terms of the -+GNU General Public License as published by the Free Software Foundation, -+either version 3 of the License, or (at your option) any later version. -+ -+It is distributed in the hope that it will be useful, -+but WITHOUT ANY WARRANTY; without even the implied warranty of -+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+GNU General Public License for more details. -+ -+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE -+Copyright (c) 2018-2019 Gerasim Troeglazov, 3dEyes@gmail.com -+*/ -+ -+#pragma once -+ -+#include "platform/platform_main_window.h" -+#include "base/flags.h" -+ -+#include -+ -+namespace Platform { -+ -+class MainWindow : public Window::MainWindow { -+ Q_OBJECT -+ -+public: -+ explicit MainWindow(not_null 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..9709580 ---- /dev/null -+++ b/Telegram/SourceFiles/platform/haiku/notifications_haiku_gate.cpp -@@ -0,0 +1,70 @@ -+/* -+This file is part of Telegram Desktop for Haiku, -+ -+You can redistribute it and/or modify it under the terms of the -+GNU General Public License as published by the Free Software Foundation, -+either version 3 of the License, or (at your option) any later version. -+ -+It is distributed in the hope that it will be useful, -+but WITHOUT ANY WARRANTY; without even the implied warranty of -+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+GNU General Public License for more details. -+ -+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE -+Copyright (c) 2018 Gerasim Troeglazov, 3dEyes@gmail.com -+*/ -+ -+#include -+#include -+ -+#include -+#include -+ -+#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..2e59207 ---- /dev/null -+++ b/Telegram/SourceFiles/platform/haiku/notifications_manager_haiku.cpp -@@ -0,0 +1,229 @@ -+/* -+This file is part of Telegram Desktop for Haiku, -+ -+You can redistribute it and/or modify it under the terms of the -+GNU General Public License as published by the Free Software Foundation, -+either version 3 of the License, or (at your option) any later version. -+ -+It is distributed in the hope that it will be useful, -+but WITHOUT ANY WARRANTY; without even the implied warranty of -+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+GNU General Public License for more details. -+ -+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE -+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 -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 -+#include -+#include -+#include -+#include -+ -+namespace Platform { -+namespace Notifications { -+namespace { -+ -+} // namespace -+ -+bool Supported() { -+ return true; -+} -+ -+std::unique_ptr Create(Window::Notifications::System *system) { -+ if (Global::NativeNotifications() && Supported()) { -+ auto result = std::make_unique(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(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"); -+ qRegisterMetaType("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(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 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) { -+ _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..d905787 ---- /dev/null -+++ b/Telegram/SourceFiles/platform/haiku/notifications_manager_haiku.h -@@ -0,0 +1,134 @@ -+/* -+This file is part of Telegram Desktop for Haiku, -+ -+You can redistribute it and/or modify it under the terms of the -+GNU General Public License as published by the Free Software Foundation, -+either version 3 of the License, or (at your option) any later version. -+ -+It is distributed in the hope that it will be useful, -+but WITHOUT ANY WARRANTY; without even the implied warranty of -+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+GNU General Public License for more details. -+ -+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE -+Copyright (c) 2018 Gerasim Troeglazov, 3dEyes@gmail.com -+*/ -+ -+#pragma once -+ -+#include "platform/platform_notifications_manager.h" -+#include "window/notifications_utilities.h" -+ -+#include -+#include -+#include -+ -+#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 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) override; -+ -+ bool hasActionsSupport() const; -+ -+private: -+ class Private; -+ const std::unique_ptr _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 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 _guarded; -+ std::weak_ptr _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..a3ad1b8 ---- /dev/null -+++ b/Telegram/SourceFiles/platform/haiku/specific_haiku.cpp -@@ -0,0 +1,256 @@ -+/* -+This file is part of Telegram Desktop for Haiku, -+ -+You can redistribute it and/or modify it under the terms of the -+GNU General Public License as published by the Free Software Foundation, -+either version 3 of the License, or (at your option) any later version. -+ -+It is distributed in the hope that it will be useful, -+but WITHOUT ANY WARRANTY; without even the implied warranty of -+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+GNU General Public License for more details. -+ -+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE -+Copyright (c) 2018 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 -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+ -+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 resultCallback){ -+ resultCallback(PermissionStatus::Granted); -+} -+ -+void OpenSystemSettingsForPermission(PermissionType type){ -+} -+ -+bool OpenSystemSettings(SystemSettingsType type) { -+ if (type == SystemSettingsType::Audio) { -+ auto options = std::vector(); -+ 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..68d31bd ---- /dev/null -+++ b/Telegram/SourceFiles/platform/haiku/specific_haiku.h -@@ -0,0 +1,122 @@ -+/* -+This file is part of Telegram Desktop for Haiku, -+ -+You can redistribute it and/or modify it under the terms of the -+GNU General Public License as published by the Free Software Foundation, -+either version 3 of the License, or (at your option) any later version. -+ -+It is distributed in the hope that it will be useful, -+but WITHOUT ANY WARRANTY; without even the implied warranty of -+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+GNU General Public License for more details. -+ -+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE -+Copyright (c) 2018 Gerasim Troeglazov, 3dEyes@gmail.com -+*/ -+ -+#pragma once -+ -+#include -+ -+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 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/linux/notifications_manager_linux.h b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h -index f40204a..847471f 100644 ---- a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h -+++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h -@@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL - #pragma once - - #include "platform/platform_notifications_manager.h" -+#include "window/notifications_utilities.h" - - namespace Platform { - namespace Notifications { -diff --git a/Telegram/SourceFiles/platform/platform_audio.h b/Telegram/SourceFiles/platform/platform_audio.h -index 7705b2e..cfc1fc9 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..2839790 100644 ---- a/Telegram/SourceFiles/platform/platform_file_utilities.h -+++ b/Telegram/SourceFiles/platform/platform_file_utilities.h -@@ -47,6 +47,8 @@ bool Get( - #include "platform/mac/file_utilities_mac.h" - #elif defined Q_OS_LINUX // Q_OS_MAC - #include "platform/linux/file_utilities_linux.h" -+#elif defined Q_OS_HAIKU // Q_OS_LINUX -+#include "platform/haiku/file_utilities_haiku.h" - #elif defined Q_OS_WINRT || defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX - #include "platform/win/file_utilities_win.h" - #endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT || Q_OS_WIN -diff --git a/Telegram/SourceFiles/platform/platform_info.h b/Telegram/SourceFiles/platform/platform_info.h -index 3fe92ea..e06b16c 100644 ---- a/Telegram/SourceFiles/platform/platform_info.h -+++ b/Telegram/SourceFiles/platform/platform_info.h -@@ -39,6 +39,8 @@ namespace Platform { - [[nodiscard]] bool IsMac10_13OrGreater(); - [[nodiscard]] bool IsMac10_14OrGreater(); - -+[[nodiscard]] constexpr bool IsHaiku(); -+ - [[nodiscard]] constexpr bool IsLinux(); - [[nodiscard]] constexpr bool IsLinux32Bit(); - [[nodiscard]] constexpr bool IsLinux64Bit(); -@@ -49,6 +51,8 @@ namespace Platform { - #include "platform/mac/info_mac.h" - #elif defined Q_OS_LINUX // Q_OS_MAC - #include "platform/linux/info_linux.h" -+#elif defined Q_OS_HAIKU // Q_OS_HAIKU -+#include "platform/haiku/info_haiku.h" - #elif defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX - #include "platform/win/info_win.h" - #endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WIN -diff --git a/Telegram/SourceFiles/platform/platform_launcher.h b/Telegram/SourceFiles/platform/platform_launcher.h -index 27180d0..cdcd223 100644 ---- a/Telegram/SourceFiles/platform/platform_launcher.h -+++ b/Telegram/SourceFiles/platform/platform_launcher.h -@@ -25,6 +25,8 @@ namespace Platform { - #include "platform/mac/launcher_mac.h" - #elif defined Q_OS_LINUX // Q_OS_MAC - #include "platform/linux/launcher_linux.h" -+#elif defined Q_OS_HAIKU // Q_OS_LINUX -+#include "platform/haiku/launcher_haiku.h" - #elif defined Q_OS_WINRT || defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX - #include "platform/win/launcher_win.h" - #endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT || Q_OS_WIN -diff --git a/Telegram/SourceFiles/platform/platform_main_window.h b/Telegram/SourceFiles/platform/platform_main_window.h -index 33277c9..4e28b24 100644 ---- a/Telegram/SourceFiles/platform/platform_main_window.h -+++ b/Telegram/SourceFiles/platform/platform_main_window.h -@@ -21,6 +21,8 @@ class MainWindow; - #include "platform/mac/main_window_mac.h" - #elif defined Q_OS_LINUX // Q_OS_MAC - #include "platform/linux/main_window_linux.h" --#elif defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX -+#elif defined Q_OS_HAIKU // Q_OS_MAC || Q_OS_LINUX -+#include "platform/haiku/main_window_haiku.h" -+#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 -diff --git a/Telegram/SourceFiles/platform/platform_notifications_manager.h b/Telegram/SourceFiles/platform/platform_notifications_manager.h -index 692f4b4..a40f830 100644 ---- a/Telegram/SourceFiles/platform/platform_notifications_manager.h -+++ b/Telegram/SourceFiles/platform/platform_notifications_manager.h -@@ -28,6 +28,8 @@ void FlashBounce(); - #include "platform/mac/notifications_manager_mac.h" - #elif defined Q_OS_LINUX // Q_OS_MAC - #include "platform/linux/notifications_manager_linux.h" -+#elif defined Q_OS_HAIKU // Q_OS_LINUX -+#include "platform/haiku/notifications_manager_haiku.h" - #elif defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX - #include "platform/win/notifications_manager_win.h" - #endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WIN -diff --git a/Telegram/SourceFiles/platform/platform_specific.h b/Telegram/SourceFiles/platform/platform_specific.h -index f5650f9..5cd34e5 100644 ---- a/Telegram/SourceFiles/platform/platform_specific.h -+++ b/Telegram/SourceFiles/platform/platform_specific.h -@@ -53,6 +53,8 @@ void finish(); - #include "platform/mac/specific_mac.h" - #elif defined Q_OS_LINUX // Q_OS_MAC - #include "platform/linux/specific_linux.h" --#elif defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX -+#elif defined Q_OS_HAIKU // Q_OS_MAC || Q_OS_LINUX -+#include "platform/haiku/specific_haiku.h" -+#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 -diff --git a/Telegram/SourceFiles/platform/platform_window_title.h b/Telegram/SourceFiles/platform/platform_window_title.h -index 6aea663..8b67814 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 { - -diff --git a/Telegram/SourceFiles/qt_functions.cpp b/Telegram/SourceFiles/qt_functions.cpp -new file mode 100644 -index 0000000..e987503 ---- /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 -+ -+/* 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 a757d08..122ff0f 100644 ---- a/Telegram/SourceFiles/qt_static_plugins.cpp -+++ b/Telegram/SourceFiles/qt_static_plugins.cpp -@@ -15,14 +15,4 @@ Q_IMPORT_PLUGIN(QWebpPlugin) - Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin) - Q_IMPORT_PLUGIN(QGenericEnginePlugin) - #elif defined Q_OS_LINUX // Q_OS_WIN | Q_OS_MAC --Q_IMPORT_PLUGIN(QWebpPlugin) --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_notifications.cpp b/Telegram/SourceFiles/settings/settings_notifications.cpp -index ea7c4a8..e19ed0f 100644 ---- a/Telegram/SourceFiles/settings/settings_notifications.cpp -+++ b/Telegram/SourceFiles/settings/settings_notifications.cpp -@@ -623,7 +623,7 @@ void SetupNotificationsContent( - return QString(); - } else if (Platform::IsWindows()) { - return tr::lng_settings_use_windows(tr::now); -- } else if (Platform::IsLinux()) { -+ } else if (Platform::IsLinux() || Platform::IsHaiku()) { - return tr::lng_settings_use_native_notifications(tr::now); - } - return QString(); -diff --git a/Telegram/SourceFiles/storage/storage_encrypted_file_tests.cpp b/Telegram/SourceFiles/storage/storage_encrypted_file_tests.cpp -index 4d522a9..1ca7dd0 100644 ---- a/Telegram/SourceFiles/storage/storage_encrypted_file_tests.cpp -+++ b/Telegram/SourceFiles/storage/storage_encrypted_file_tests.cpp -@@ -188,6 +188,7 @@ TEST_CASE("two process encrypted file", "[storage_encrypted_file]") { - constexpr auto kMaxPath = 1024; - char result[kMaxPath] = { 0 }; - uint32_t size = kMaxPath; -+#ifndef Q_OS_HAIKU - #ifdef Q_OS_MAC - if (_NSGetExecutablePath(result, &size) == 0) { - return result; -@@ -198,6 +199,7 @@ TEST_CASE("two process encrypted file", "[storage_encrypted_file]") { - return result; - } - #endif // Q_OS_MAC -+#endif // Q_OS_HAIKU - return "tests_storage"; - #endif // Q_OS_WIN - }(); -diff --git a/Telegram/SourceFiles/ui/painter.h b/Telegram/SourceFiles/ui/painter.h -index 627c88e..2534f1d 100644 ---- a/Telegram/SourceFiles/ui/painter.h -+++ b/Telegram/SourceFiles/ui/painter.h -@@ -19,12 +19,12 @@ public: - - void drawTextLeft(int x, int y, int outerw, const QString &text, int textWidth = -1) { - QFontMetrics m(fontMetrics()); -- if (style::RightToLeft() && textWidth < 0) textWidth = m.width(text); -+ if (style::RightToLeft() && textWidth < 0) textWidth = m.horizontalAdvance(text); - drawText(style::RightToLeft() ? (outerw - x - textWidth) : x, y + m.ascent(), text); - } - void drawTextRight(int x, int y, int outerw, const QString &text, int textWidth = -1) { - QFontMetrics m(fontMetrics()); -- if (!style::RightToLeft() && textWidth < 0) textWidth = m.width(text); -+ if (!style::RightToLeft() && textWidth < 0) textWidth = m.horizontalAdvance(text); - drawText(style::RightToLeft() ? x : (outerw - x - textWidth), y + m.ascent(), text); - } - void drawPixmapLeft(int x, int y, int outerw, const QPixmap &pix, const QRect &from) { -diff --git a/Telegram/SourceFiles/ui/platform/haiku/ui_platform_utility_haiku.cpp b/Telegram/SourceFiles/ui/platform/haiku/ui_platform_utility_haiku.cpp -new file mode 100644 -index 0000000..40b75e9 ---- /dev/null -+++ b/Telegram/SourceFiles/ui/platform/haiku/ui_platform_utility_haiku.cpp -@@ -0,0 +1,39 @@ -+/* -+This file is part of Telegram Desktop for Haiku, -+ -+You can redistribute it and/or modify it under the terms of the -+GNU General Public License as published by the Free Software Foundation, -+either version 3 of the License, or (at your option) any later version. -+ -+It is distributed in the hope that it will be useful, -+but WITHOUT ANY WARRANTY; without even the implied warranty of -+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+GNU General Public License for more details. -+ -+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE -+Copyright (c) 2018 Gerasim Troeglazov, 3dEyes@gmail.com -+*/ -+ -+#include "ui/platform/haiku/ui_platform_utility_haiku.h" -+ -+#include "base/flat_set.h" -+#include "ui/ui_log.h" -+ -+#include -+#include -+#include -+#include -+ -+namespace Ui { -+namespace Platform { -+ -+bool IsApplicationActive() { -+ return static_cast(QApplication::instance())->activeWindow() != nullptr; -+} -+ -+bool TranslucentWindowsSupported(QPoint globalPosition) { -+ return false; -+} -+ -+} // namespace Platform -+} // namespace Ui -diff --git a/Telegram/SourceFiles/ui/platform/haiku/ui_platform_utility_haiku.h b/Telegram/SourceFiles/ui/platform/haiku/ui_platform_utility_haiku.h -new file mode 100644 -index 0000000..0b12104 ---- /dev/null -+++ b/Telegram/SourceFiles/ui/platform/haiku/ui_platform_utility_haiku.h -@@ -0,0 +1,51 @@ -+/* -+This file is part of Telegram Desktop for Haiku, -+ -+You can redistribute it and/or modify it under the terms of the -+GNU General Public License as published by the Free Software Foundation, -+either version 3 of the License, or (at your option) any later version. -+ -+It is distributed in the hope that it will be useful, -+but WITHOUT ANY WARRANTY; without even the implied warranty of -+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+GNU General Public License for more details. -+ -+Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE -+Copyright (c) 2019 Gerasim Troeglazov, 3dEyes@gmail.com -+*/ -+ -+#pragma once -+ -+class QPainter; -+class QPaintEvent; -+ -+namespace Ui { -+namespace Platform { -+ -+inline void StartTranslucentPaint(QPainter &p, QPaintEvent *e) { -+} -+ -+inline void InitOnTopPanel(not_null panel) { -+} -+ -+inline void DeInitOnTopPanel(not_null panel) { -+} -+ -+inline void ReInitOnTopPanel(not_null panel) { -+} -+ -+inline void UpdateOverlayed(not_null widget) { -+} -+ -+inline void ShowOverAll(not_null widget, bool canFocus) { -+} -+ -+inline void BringToBack(not_null widget) { -+} -+ -+inline constexpr bool UseMainQueueGeneric() { -+ return true; -+} -+ -+} // namespace Platform -+} // namespace Ui -diff --git a/Telegram/SourceFiles/ui/platform/ui_platform_utility.h b/Telegram/SourceFiles/ui/platform/ui_platform_utility.h -index 62c2fdf..0b4e851 100644 ---- a/Telegram/SourceFiles/ui/platform/ui_platform_utility.h -+++ b/Telegram/SourceFiles/ui/platform/ui_platform_utility.h -@@ -39,6 +39,8 @@ void DrainMainQueue(); // Needed only if UseMainQueueGeneric() is false. - #include "ui/platform/mac/ui_platform_utility_mac.h" - #elif defined Q_OS_LINUX // Q_OS_MAC - #include "ui/platform/linux/ui_platform_utility_linux.h" -+#elif defined Q_OS_HAIKU // Q_OS_LINUX -+#include "ui/platform/haiku/ui_platform_utility_haiku.h" - #elif defined Q_OS_WINRT || defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX - #include "ui/platform/win/ui_platform_utility_win.h" - #endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT || Q_OS_WIN -diff --git a/Telegram/SourceFiles/ui/style/style_core_font.cpp b/Telegram/SourceFiles/ui/style/style_core_font.cpp -index 653dbff..1e10a9c 100644 ---- a/Telegram/SourceFiles/ui/style/style_core_font.cpp -+++ b/Telegram/SourceFiles/ui/style/style_core_font.cpp -@@ -162,8 +162,8 @@ FontData::FontData(int size, uint32 flags, int family, Font *other) - f.setPixelSize(size); - if (_flags & FontBold) { - f.setBold(true); -- //} else if (fontFamilies[family] == "Open Sans Semibold") { -- // f.setWeight(QFont::DemiBold); -+ } else if (fontFamilies[family] == "Open Sans Semibold") { -+ f.setWeight(QFont::DemiBold); - } - f.setItalic(_flags & FontItalic); - f.setUnderline(_flags & FontUnderline); -diff --git a/Telegram/SourceFiles/ui/style/style_core_font.h b/Telegram/SourceFiles/ui/style/style_core_font.h -index a9cd5b1..f3ca2d9 100644 ---- a/Telegram/SourceFiles/ui/style/style_core_font.h -+++ b/Telegram/SourceFiles/ui/style/style_core_font.h -@@ -73,13 +73,13 @@ class FontData { - public: - - int32 width(const QString &str) const { -- return m.width(str); -+ return m.horizontalAdvance(str); - } - int32 width(const QString &str, int32 from, int32 to) const { - return width(str.mid(from, to)); - } - int32 width(QChar ch) const { -- return m.width(ch); -+ return m.horizontalAdvance(ch); - } - QString elided(const QString &str, int32 width, Qt::TextElideMode mode = Qt::ElideRight) const { - return m.elidedText(str, mode, width); -diff --git a/Telegram/SourceFiles/ui/text/text.cpp b/Telegram/SourceFiles/ui/text/text.cpp -index 7891995..eaeb52b 100644 ---- a/Telegram/SourceFiles/ui/text/text.cpp -+++ b/Telegram/SourceFiles/ui/text/text.cpp -@@ -1968,11 +1968,11 @@ private: - if (item == -1) - return; - --#ifdef OS_MAC_OLD -+#if defined(OS_MAC_OLD) || QT_VERSION < QT_VERSION_CHECK(5, 6, 0) - auto end = _e->findItem(line.from + line.length - 1); --#else // OS_MAC_OLD -+#else - auto end = _e->findItem(line.from + line.length - 1, item); --#endif // OS_MAC_OLD -+#endif - - auto blockIndex = _lineStartBlock; - auto currentBlock = _t->_blocks[blockIndex].get(); -diff --git a/Telegram/SourceFiles/ui/text/text_block.cpp b/Telegram/SourceFiles/ui/text/text_block.cpp -index 29173c5..b47a53d 100644 ---- a/Telegram/SourceFiles/ui/text/text_block.cpp -+++ b/Telegram/SourceFiles/ui/text/text_block.cpp -@@ -334,6 +334,9 @@ TextBlock::TextBlock(const style::font &font, const QString &str, QFixed minResi - - QStackTextEngine engine(part, blockFont->f); - BlockParser parser(&engine, this, minResizeWidth, _from, part); -+ QTextLayout layout(part, blockFont->f); -+ layout.beginLayout(); -+ layout.createLine(); - } - } - -diff --git a/Telegram/SourceFiles/ui/ui_utility.cpp b/Telegram/SourceFiles/ui/ui_utility.cpp -index 878d591..f7c4a47 100644 ---- a/Telegram/SourceFiles/ui/ui_utility.cpp -+++ b/Telegram/SourceFiles/ui/ui_utility.cpp -@@ -167,9 +167,9 @@ void SendSynteticMouseEvent(QWidget *widget, QEvent::Type type, Qt::MouseButton - , button - , QGuiApplication::mouseButtons() | button - , QGuiApplication::keyboardModifiers() --#ifndef OS_MAC_OLD -+#if !defined(OS_MAC_OLD) && QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) - , Qt::MouseEventSynthesizedByApplication --#endif // OS_MAC_OLD -+#endif - ); - ev.setTimestamp(crl::now()); - QGuiApplication::sendEvent(windowHandle, &ev); -diff --git a/Telegram/ThirdParty/minizip/ioapi.c b/Telegram/ThirdParty/minizip/ioapi.c -index 7f5c191..649255c 100644 ---- a/Telegram/ThirdParty/minizip/ioapi.c -+++ b/Telegram/ThirdParty/minizip/ioapi.c -@@ -14,7 +14,7 @@ - #define _CRT_SECURE_NO_WARNINGS - #endif - --#if defined(__APPLE__) || defined(IOAPI_NO_64) -+#if defined(__APPLE__) || defined(IOAPI_NO_64) || defined(__HAIKU__) - // In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions - #define FOPEN_FUNC(filename, mode) fopen(filename, mode) - #define FTELLO_FUNC(stream) ftello(stream) -diff --git a/Telegram/gyp/PrecompiledHeader.cmake b/Telegram/gyp/PrecompiledHeader.cmake -index dfe1193..0b13fc0 100644 ---- a/Telegram/gyp/PrecompiledHeader.cmake -+++ b/Telegram/gyp/PrecompiledHeader.cmake -@@ -114,7 +114,7 @@ function(add_precompiled_header _target _input) - set(_compiler_FLAGS "@${_pch_c_flags_file}") - add_custom_command( - OUTPUT "${_output_c}" -- COMMAND "${CMAKE_C_COMPILER}" ${_compiler_FLAGS} -x c-header -o "${_output_c}" -c "${_pchfile}" -+ COMMAND "${CMAKE_C_COMPILER}" ${_compiler_FLAGS} "$(C_DEFINES)" "$(C_INCLUDES)" "$(C_FLAGS)" -x c-header -o "${_output_c}" -c "${_pchfile}" - DEPENDS "${_pchfile}" "${_pch_c_flags_file}" - IMPLICIT_DEPENDS C "${_pch_header}" - COMMENT "Precompiling ${_name} for ${_target} (C)") -@@ -125,7 +125,7 @@ function(add_precompiled_header _target _input) - set(_compiler_FLAGS "@${_pch_cpp_flags_file}") - add_custom_command( - OUTPUT "${_output_cxx}" -- COMMAND "${CMAKE_CXX_COMPILER}" ${_compiler_FLAGS} -x c++-header -o "${_output_cxx}" -c "${_pchfile}" -+ COMMAND "${CMAKE_CXX_COMPILER}" ${_compiler_FLAGS} "$(CXX_DEFINES)" "$(CXX_INCLUDES)" "$(CXX_FLAGS)" -x c++-header -o "${_output_cxx}" -c "${_pchfile}" - DEPENDS "${_pchfile}" "${_pch_cpp_flags_file}" - IMPLICIT_DEPENDS CXX "${_pch_header}" - COMMENT "Precompiling header ${_name} for ${_target} (C++)") -diff --git a/Telegram/gyp/common/common.gypi b/Telegram/gyp/common/common.gypi -index 6531a7a..242f869 100644 ---- a/Telegram/gyp/common/common.gypi -+++ b/Telegram/gyp/common/common.gypi -@@ -9,6 +9,7 @@ - 'win.gypi', - 'mac.gypi', - 'linux.gypi', -+ 'haiku.gypi', - ], - 'variables': { - 'variables': { -@@ -29,6 +30,11 @@ - }, { - 'build_mac': 0, - }], -+ [ 'build_os == "haiku"', { -+ 'build_haiku': 1, -+ }, { -+ 'build_haiku': 0, -+ }], - [ 'build_os == "linux"', { - 'build_linux': 1, - }, { -@@ -40,11 +46,13 @@ - 'build_win%': '<(build_win)', - 'build_mac%': '<(build_mac)', - 'build_linux%': '<(build_linux)', -+ 'build_haiku%': '<(build_haiku)', - }, - 'build_os%': '<(build_os)', - 'build_win%': '<(build_win)', - 'build_mac%': '<(build_mac)', - 'build_linux%': '<(build_linux)', -+ 'build_haiku%': '<(build_haiku)', - - 'official_build_target%': '', - 'build_standard_win%': 'c++17', -@@ -54,6 +62,7 @@ - 'build_win%': '<(build_win)', - 'build_mac%': '<(build_mac)', - 'build_linux%': '<(build_linux)', -+ 'build_haiku%': '<(build_haiku)', - 'official_build_target%': '<(official_build_target)', - 'build_standard_win%': '<(build_standard_win)', - 'libs_loc%': '<(libs_loc)', -diff --git a/Telegram/gyp/common/haiku.gypi b/Telegram/gyp/common/haiku.gypi -new file mode 100644 -index 0000000..dbc6dce ---- /dev/null -+++ b/Telegram/gyp/common/haiku.gypi -@@ -0,0 +1,62 @@ -+# This file is part of Telegram Desktop, -+# the official desktop version of Telegram messaging app, see https://telegram.org -+# -+# Telegram Desktop is free software: you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation, either version 3 of the License, or -+# (at your option) any later version. -+# -+# It is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# In addition, as a special exception, the copyright holders give permission -+# to link the code of portions of this program with the OpenSSL library. -+# -+# Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE -+# Copyright (c) 2018-2019 Gerasim Troeglazov, 3dEyes@gmail.com -+ -+{ -+ 'conditions': [ -+ [ 'build_haiku', { -+ 'variables': { -+ 'haiku_common_flags': [ -+ '-Wall', -+ '-W', -+ '-fPIC', -+ '-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', -+ ], -+ }, -+ 'defines': [ -+ '_REENTRANT', -+ 'QT_PLUGIN', -+ 'Q_OS_HAIKU', -+ 'TDESKTOP_DISABLE_CRASH_REPORTS', -+ 'TDESKTOP_DISABLE_AUTOUPDATE', -+ 'TDESKTOP_DISABLE_UNITY_INTEGRATION', -+ 'TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION', -+ ], -+ 'cflags_c': [ -+ '<@(haiku_common_flags)', -+ '-std=gnu11', -+ ], -+ 'cflags_cc': [ -+ '<@(haiku_common_flags)', -+ '-std=c++1z', -+ '-Wno-register', -+ ], -+ 'configurations': { -+ 'Debug': { -+ }, -+ }, -+ }], -+ ], -+} -diff --git a/Telegram/gyp/generate.py b/Telegram/gyp/generate.py -index 4194e16..c2fd3c8 100644 ---- a/Telegram/gyp/generate.py -+++ b/Telegram/gyp/generate.py -@@ -98,6 +98,11 @@ elif sys.platform == 'darwin': - gypScript = '../../../Libraries/gyp/gyp' - gypArguments.append('-Gxcode_upgrade_check_project_version=1030') - gypFormats.append('xcode') -+elif sys.platform == 'haiku1': -+ gypScript = 'gyp' -+ gypFormats.append('cmake') -+ cmakeConfigurations.append('Debug') -+ cmakeConfigurations.append('Release') - else: - gypScript = '../../../Libraries/gyp/gyp' - gypFormats.append('cmake') -diff --git a/Telegram/gyp/lib_base.gyp b/Telegram/gyp/lib_base.gyp -index 98c0d88..d2aa3a6 100644 ---- a/Telegram/gyp/lib_base.gyp -+++ b/Telegram/gyp/lib_base.gyp -@@ -33,9 +33,10 @@ - 'include_dirs': [ - '<(src_loc)', - '<(SHARED_INTERMEDIATE_DIR)', -- '<(libs_loc)/range-v3/include', -+ '<(submodules_loc)/range/include', - '<(submodules_loc)/GSL/include', - '<(submodules_loc)/variant/include', -+ '<(submodules_loc)/variant/test/include', - '<(submodules_loc)/crl/src', - '<(submodules_loc)/xxHash', - ], -diff --git a/Telegram/gyp/lib_export.gyp b/Telegram/gyp/lib_export.gyp -index 140ea6b..51e0624 100644 ---- a/Telegram/gyp/lib_export.gyp -+++ b/Telegram/gyp/lib_export.gyp -@@ -44,9 +44,10 @@ - 'include_dirs': [ - '<(src_loc)', - '<(SHARED_INTERMEDIATE_DIR)', -- '<(libs_loc)/range-v3/include', -+ '<(submodules_loc)/range/include', - '<(submodules_loc)/GSL/include', - '<(submodules_loc)/variant/include', -+ '<(submodules_loc)/variant/test/include', - '<(submodules_loc)/crl/src', - ], - 'sources': [ -diff --git a/Telegram/gyp/lib_ffmpeg.gyp b/Telegram/gyp/lib_ffmpeg.gyp -index 22a2a96..241f21c 100644 ---- a/Telegram/gyp/lib_ffmpeg.gyp -+++ b/Telegram/gyp/lib_ffmpeg.gyp -@@ -34,9 +34,10 @@ - '<(src_loc)', - '<(SHARED_INTERMEDIATE_DIR)', - '<(libs_loc)/ffmpeg', -- '<(libs_loc)/range-v3/include', -+ '<(submodules_loc)/range/include', - '<(submodules_loc)/GSL/include', - '<(submodules_loc)/variant/include', -+ '<(submodules_loc)/variant/test/include', - '<(submodules_loc)/crl/src', - ], - 'sources': [ -diff --git a/Telegram/gyp/lib_lottie.gyp b/Telegram/gyp/lib_lottie.gyp -index ee2bb0f..d14c75b 100644 ---- a/Telegram/gyp/lib_lottie.gyp -+++ b/Telegram/gyp/lib_lottie.gyp -@@ -43,13 +43,14 @@ - 'include_dirs': [ - '<(src_loc)', - '<(SHARED_INTERMEDIATE_DIR)', -- '<(libs_loc)/range-v3/include', -+ '<(submodules_loc)/range/include', - '<(libs_loc)/zlib', - '<(libs_loc)/ffmpeg', - '<(rlottie_loc)', - '<(lz4_loc)', - '<(submodules_loc)/GSL/include', - '<(submodules_loc)/variant/include', -+ '<(submodules_loc)/variant/test/include', - '<(submodules_loc)/crl/src', - ], - 'sources': [ -diff --git a/Telegram/gyp/lib_mtproto.gyp b/Telegram/gyp/lib_mtproto.gyp -index 6adcd34..c9109b0 100644 ---- a/Telegram/gyp/lib_mtproto.gyp -+++ b/Telegram/gyp/lib_mtproto.gyp -@@ -44,9 +44,10 @@ - 'include_dirs': [ - '<(src_loc)', - '<(SHARED_INTERMEDIATE_DIR)', -- '<(libs_loc)/range-v3/include', -+ '<(submodules_loc)/range/include', - '<(submodules_loc)/GSL/include', - '<(submodules_loc)/variant/include', -+ '<(submodules_loc)/variant/test/include', - '<(submodules_loc)/crl/src', - ], - 'sources': [ -diff --git a/Telegram/gyp/lib_storage.gyp b/Telegram/gyp/lib_storage.gyp -index cd3b6d3..b16a472 100644 ---- a/Telegram/gyp/lib_storage.gyp -+++ b/Telegram/gyp/lib_storage.gyp -@@ -38,9 +38,10 @@ - 'include_dirs': [ - '<(src_loc)', - '<(SHARED_INTERMEDIATE_DIR)', -- '<(libs_loc)/range-v3/include', -+ '<(submodules_loc)/range/include', - '<(submodules_loc)/GSL/include', - '<(submodules_loc)/variant/include', -+ '<(submodules_loc)/variant/test/include', - '<(submodules_loc)/crl/src', - '<(submodules_loc)/xxHash', - ], -diff --git a/Telegram/gyp/lib_ui.gyp b/Telegram/gyp/lib_ui.gyp -index fa6bd4e..9876b75 100644 ---- a/Telegram/gyp/lib_ui.gyp -+++ b/Telegram/gyp/lib_ui.gyp -@@ -56,9 +56,10 @@ - 'include_dirs': [ - '<(src_loc)', - '<(SHARED_INTERMEDIATE_DIR)', -- '<(libs_loc)/range-v3/include', -+ '<(submodules_loc)/range/include', - '<(submodules_loc)/GSL/include', - '<(submodules_loc)/variant/include', -+ '<(submodules_loc)/variant/test/include', - '<(submodules_loc)/crl/src', - '<(emoji_suggestions_loc)', - ], -diff --git a/Telegram/gyp/lib_ui/sources.txt b/Telegram/gyp/lib_ui/sources.txt -index 2a64c1a..310aa51 100644 ---- a/Telegram/gyp/lib_ui/sources.txt -+++ b/Telegram/gyp/lib_ui/sources.txt -@@ -15,6 +15,8 @@ - <(src_loc)/ui/platform/ui_platform_utility.h - <(src_loc)/ui/platform/linux/ui_platform_utility_linux.cpp - <(src_loc)/ui/platform/linux/ui_platform_utility_linux.h -+<(src_loc)/ui/platform/haiku/ui_platform_utility_haiku.cpp -+<(src_loc)/ui/platform/haiku/ui_platform_utility_haiku.h - <(src_loc)/ui/platform/mac/ui_platform_utility_mac.h - <(src_loc)/ui/platform/mac/ui_platform_utility_mac.mm - <(src_loc)/ui/platform/win/ui_platform_utility_win.cpp -diff --git a/Telegram/gyp/list_sources.py b/Telegram/gyp/list_sources.py -index 9efee62..d978ed6 100644 ---- a/Telegram/gyp/list_sources.py -+++ b/Telegram/gyp/list_sources.py -@@ -113,6 +113,8 @@ if input_path != '': - platform_rules[file_path] = [ 'mac' ] - elif '/platform/linux/' in file_path: - platform_rules[file_path] = [ 'linux' ] -+ elif '/platform/haiku/' in file_path: -+ platform_rules[file_path] = [ 'haiku' ] - - for replace in replaces: - replace_parts = replace.split('=', 1) -diff --git a/Telegram/gyp/modules/qt.gypi b/Telegram/gyp/modules/qt.gypi -index 0b783ec..eac3792 100644 ---- a/Telegram/gyp/modules/qt.gypi -+++ b/Telegram/gyp/modules/qt.gypi -@@ -14,18 +14,14 @@ - [ 'build_macold', { - 'qt_version%': '5.3.2', - }, { -- 'qt_version%': '5.6.2', -+ 'qt_version%': ' /dev/null --libs <@(pkgconfig_libs))', -+ ], -+ 'cflags_cc': [ -+ '-Wno-strict-overflow', -+ '-Wno-maybe-uninitialized', -+ ], -+ 'configurations': { -+ 'Release': { -+ 'cflags': [ -+ '-Ofast', -+ '-fno-strict-aliasing', -+ ], -+ 'cflags_cc': [ -+ '-Ofast', -+ '-fno-strict-aliasing', -+ ], -+ 'ldflags': [ -+ '-Ofast', -+ ], -+ }, -+ }, -+ 'cmake_precompiled_header': '<(src_loc)/stdafx.h', -+ 'cmake_precompiled_header_script': 'PrecompiledHeader.cmake', -+ }]], -+} -diff --git a/Telegram/gyp/telegram/qrc.gypi b/Telegram/gyp/telegram/qrc.gypi -index 389ca8c..dbad7f4 100644 ---- a/Telegram/gyp/telegram/qrc.gypi -+++ b/Telegram/gyp/telegram/qrc.gypi -@@ -26,6 +26,13 @@ - ], - } - }], -+ [ 'build_haiku', { -+ 'variables': { -+ 'qrc_files': [ -+ '<(res_loc)/qrc/haiku.qrc', -+ ], -+ } -+ }], - [ 'build_mac', { - 'variables': { - 'qrc_files': [ -diff --git a/Telegram/gyp/telegram/sources.txt b/Telegram/gyp/telegram/sources.txt -index 38d9d0e..fd8fd85 100644 ---- a/Telegram/gyp/telegram/sources.txt -+++ b/Telegram/gyp/telegram/sources.txt -@@ -620,6 +620,20 @@ - <(src_loc)/platform/linux/notifications_manager_linux.h - <(src_loc)/platform/linux/specific_linux.cpp - <(src_loc)/platform/linux/specific_linux.h -+<(src_loc)/platform/haiku/file_utilities_haiku.cpp -+<(src_loc)/platform/haiku/file_utilities_haiku.h -+<(src_loc)/platform/haiku/haiku_desktop_environment.cpp -+<(src_loc)/platform/haiku/haiku_desktop_environment.h -+<(src_loc)/platform/haiku/launcher_haiku.cpp -+<(src_loc)/platform/haiku/launcher_haiku.h -+<(src_loc)/platform/haiku/notifications_manager_haiku.cpp -+<(src_loc)/platform/haiku/notifications_manager_haiku.h -+<(src_loc)/platform/haiku/main_window_haiku.cpp -+<(src_loc)/platform/haiku/main_window_haiku.h -+<(src_loc)/platform/haiku/specific_haiku.cpp -+<(src_loc)/platform/haiku/specific_haiku.h -+<(src_loc)/platform/haiku/info_haiku.cpp -+<(src_loc)/platform/haiku/info_haiku.h - <(src_loc)/platform/mac/file_utilities_mac.mm - <(src_loc)/platform/mac/file_utilities_mac.h - <(src_loc)/platform/mac/info_mac.mm -@@ -863,14 +877,7 @@ - <(src_loc)/settings.cpp - <(src_loc)/settings.h - --platforms: !win --<(minizip_loc)/crypt.h --<(minizip_loc)/ioapi.c --<(minizip_loc)/ioapi.h --<(minizip_loc)/zip.c --<(minizip_loc)/zip.h --<(minizip_loc)/unzip.c --<(minizip_loc)/unzip.h -+<(src_loc)/qt_functions.cpp - - platforms: win - <(res_loc)/winrc/Telegram.rc -diff --git a/Telegram/gyp/telegram/telegram.gypi b/Telegram/gyp/telegram/telegram.gypi -index c207db6..7123cbc 100644 ---- a/Telegram/gyp/telegram/telegram.gypi -+++ b/Telegram/gyp/telegram/telegram.gypi -@@ -57,6 +57,7 @@ - 'win.gypi', - 'mac.gypi', - 'linux.gypi', -+ 'haiku.gypi', - '../modules/openssl.gypi', - '../modules/qt.gypi', - '../modules/qt_moc.gypi', -@@ -72,7 +73,6 @@ - 'codegen.gyp:codegen_numbers', - 'codegen.gyp:codegen_style', - 'tests/tests.gyp:tests', -- 'utils.gyp:Updater', - '../ThirdParty/libtgvoip/libtgvoip.gyp:libtgvoip', - 'crl.gyp:crl', - 'lib_base.gyp:lib_base', -@@ -85,7 +85,6 @@ - ], - - 'defines': [ -- 'AL_LIBTYPE_STATIC', - 'AL_ALEXT_PROTOTYPES', - 'TGVOIP_USE_CXX11_LIB', - 'XXH_INLINE_ALL', -@@ -97,18 +96,11 @@ - 'include_dirs': [ - '<(src_loc)', - '<(SHARED_INTERMEDIATE_DIR)', -- '<(libs_loc)/breakpad/src', -- '<(libs_loc)/lzma/C', -- '<(libs_loc)/zlib', -- '<(libs_loc)/ffmpeg', -- '<(libs_loc)/openal-soft/include', -- '<(libs_loc)/opus/include', -- '<(libs_loc)/range-v3/include', -- '<(minizip_loc)', -- '<(sp_media_key_tap_loc)', - '<(emoji_suggestions_loc)', -+ '<(submodules_loc)/minizip', - '<(submodules_loc)/GSL/include', - '<(submodules_loc)/variant/include', -+ '<(submodules_loc)/variant/test/include', - '<(submodules_loc)/crl/src', - '<(submodules_loc)/xxHash', - ], -diff --git a/Telegram/gyp/tests/common_test.gypi b/Telegram/gyp/tests/common_test.gypi -index 70f9653..99cc76a 100644 ---- a/Telegram/gyp/tests/common_test.gypi -+++ b/Telegram/gyp/tests/common_test.gypi -@@ -13,9 +13,10 @@ - '<(src_loc)', - '<(submodules_loc)/GSL/include', - '<(submodules_loc)/variant/include', -+ '<(submodules_loc)/variant/test/include', - '<(submodules_loc)/Catch/include', - '<(submodules_loc)/crl/src', -- '<(libs_loc)/range-v3/include', -+ '<(submodules_loc)/range/include', - ], - 'sources': [ - '<(src_loc)/base/tests_main.cpp', -diff --git a/Telegram/gyp/utils.gyp b/Telegram/gyp/utils.gyp -index 63c0fa6..0ab02f5 100644 ---- a/Telegram/gyp/utils.gyp -+++ b/Telegram/gyp/utils.gyp -@@ -33,6 +33,13 @@ - '<(res_loc)/winrc/Updater.rc', - ], - }], -+ [ 'build_haiku', { -+ 'libraries': [ -+ 'ssl', -+ 'crypto', -+ 'lzma', -+ ], -+ }], - [ '"<(build_linux)" != "1"', { - 'sources!': [ - '<(src_loc)/_other/updater_linux.cpp', --- -2.23.0 - diff --git a/net-im/telegram-desktop/patches/telegram_desktop-1.9.3.patchset b/net-im/telegram-desktop/patches/telegram_desktop-1.9.3.patchset new file mode 100644 index 000000000..c6f3cbc2a --- /dev/null +++ b/net-im/telegram-desktop/patches/telegram_desktop-1.9.3.patchset @@ -0,0 +1,4344 @@ +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 + #include + +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 ++ ++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 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(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 ++#include ++#include ++#include ++#include ++#include ++ ++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 _argumentValues; ++ std::vector _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 ++#include ++#include ++#include ++#include ++ ++namespace Platform { ++ ++MainWindow::MainWindow(not_null 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 ++ ++namespace Platform { ++ ++class MainWindow : public Window::MainWindow { ++ Q_OBJECT ++ ++public: ++ explicit MainWindow(not_null 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 ++#include ++ ++#include ++#include ++ ++#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 ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++#include ++#include ++#include ++#include ++ ++namespace Platform { ++namespace Notifications { ++namespace { ++ ++} // namespace ++ ++bool Supported() { ++ return true; ++} ++ ++std::unique_ptr Create(Window::Notifications::System *system) { ++ if (Global::NativeNotifications() && Supported()) { ++ auto result = std::make_unique(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(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"); ++ qRegisterMetaType("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(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 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) { ++ _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 ++#include ++#include ++ ++#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 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) override; ++ ++ bool hasActionsSupport() const; ++ ++private: ++ class Private; ++ const std::unique_ptr _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 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 _guarded; ++ std::weak_ptr _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 ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++ ++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 resultCallback){ ++ resultCallback(PermissionStatus::Granted); ++} ++ ++void OpenSystemSettingsForPermission(PermissionType type){ ++} ++ ++bool OpenSystemSettings(SystemSettingsType type) { ++ if (type == SystemSettingsType::Audio) { ++ auto options = std::vector(); ++ 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 ++ ++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 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 ++ ++/* 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 + +-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 + + #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 + #include + #endif ++#ifdef __HAIKU__ ++#include ++#endif + #include + #include + #include +@@ -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(inputDevice, outputDevice); + #endif + return new ContextlessAudioIO(inputDevice, outputDevice); ++#elif defined(__HAIKU__) ++ return new ContextlessAudioIO(); + #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 ++#include ++#include ++#include ++#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(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(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(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(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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++#include ++#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 ++ ++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 ++#include ++#include ++#include ++ ++#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 ++ ++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 + +-#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 + #include +@@ -92,6 +92,7 @@ namespace tgvoip{ + static void* ActualEntryPoint(void* arg){ + Thread* self=reinterpret_cast(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 ++#endif ++ + #include + #include + #include +@@ -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 ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++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 ++ ++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 ++#include ++#include ++#include ++#include ++#include ++ ++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 ++ ++namespace base::Platform { ++ ++std::optional 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 ++#include ++#include ++#include ++#include ++#include ++ ++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 ++#else + #include ++#endif + #include + #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 @@ ++ ++ ++ qt_linux.conf ++ ++ ++ fc-custom.conf ++ ++ +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 ++#include ++#include ++#include ++ ++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(); ++ 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 panel) { ++} ++ ++inline void DeInitOnTopPanel(not_null panel) { ++} ++ ++inline void ReInitOnTopPanel(not_null panel) { ++} ++ ++inline void UpdateOverlayed(not_null widget) { ++} ++ ++inline void ShowOverAll(not_null widget, bool canFocus) { ++} ++ ++inline void BringToBack(not_null 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 CreateWindowHelper( ++ not_null 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 ++ $,,-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 ++ $,,-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 + diff --git a/net-im/telegram-desktop/telegram_desktop-1.8.15.recipe b/net-im/telegram-desktop/telegram_desktop-1.8.15.recipe deleted file mode 100644 index 1fdbb4199..000000000 --- a/net-im/telegram-desktop/telegram_desktop-1.8.15.recipe +++ /dev/null @@ -1,201 +0,0 @@ -SUMMARY="Telegram Desktop Messenger" -DESCRIPTION="Unofficial build of the original Telegram client for Haiku." -HOMEPAGE="https://www.telegram.org/" -COPYRIGHT="2013-2019 Telegram" -LICENSE="GNU GPL v3" -REVISION="2" -SOURCE_URI="https://github.com/telegramdesktop/tdesktop/archive/v$portVersion.tar.gz" -CHECKSUM_SHA256="68bb6c3d007fe21847286815f22c2532a7cf9c247dc2781d749ebeb40f02ed99" -SOURCE_FILENAME="tdesktop-$portVersion.tar.gz" -SOURCE_DIR="tdesktop-$portVersion" -srcGitRev_2="d4a0f719ffd8d29e88474f67abc9fc862661c3b9" -SOURCE_URI_2="https://github.com/telegramdesktop/libtgvoip/archive/$srcGitRev_2.tar.gz" -CHECKSUM_SHA256_2="bb75188b900907a5b00594ad3ddb78195c8d1fdc144e5a458b314dd666eba996" -SOURCE_FILENAME_2="libtgvoip-$srcGitRev_2.tar.gz" -srcGitRev_3="550ac2f159ca883d360c196149b466955c77a573" -SOURCE_URI_3="https://github.com/mapbox/variant/archive/$srcGitRev_3.tar.gz" -CHECKSUM_SHA256_3="aa794dfefe0a90501587e36d977b958d0df888503117a8d9aa43dc14f8526d9d" -SOURCE_FILENAME_3="variant-$srcGitRev_3.tar.gz" -srcGitRev_4="d846fe50a3f0bb7767c7e087a05f4be95f4da0ec" -SOURCE_URI_4="https://github.com/Microsoft/GSL/archive/$srcGitRev_4.tar.gz" -CHECKSUM_SHA256_4="be81db4ab1b57102a0fa1cd0c4a6469294eb9daf24294347592245b754f65ff6" -SOURCE_FILENAME_4="GSL-$srcGitRev_4.tar.gz" -srcGitRev_5="5ca44b68721833ae3731802ed99af67c6f38a53a" -SOURCE_URI_5="https://github.com/philsquared/Catch/archive/$srcGitRev_5.tar.gz" -CHECKSUM_SHA256_5="d24e6d9df2b8aa5739d3b9077c6b0ff0ef4d5ef8acc52c3a57e32893854d8d18" -SOURCE_FILENAME_5="Catch-$srcGitRev_5.tar.gz" -srcGitRev_6="52baf11aaeb7f5ea6955a438abaa1aee4c4308d8" -SOURCE_URI_6="https://github.com/telegramdesktop/crl/archive/$srcGitRev_6.tar.gz" -CHECKSUM_SHA256_6="9ab12f23916a66665dce9b3baf16594886322f426516d34e2166e7057d78e18e" -SOURCE_FILENAME_6="crl-$srcGitRev_6.tar.gz" -srcGitRev_7="8a732ee6736af8af024b5b2032580b85a9be8239" -SOURCE_URI_7="https://github.com/ericniebler/range-v3/archive/$srcGitRev_7.tar.gz" -CHECKSUM_SHA256_7="6cd6a412db92bf3c26a408f5807751f976b4a4cb2801c705cb63001e53b47a11" -SOURCE_FILENAME_7="range-$srcGitRev_7.tar.gz" -srcGitRev_8="7cc9639699f64b750c0b82333dced9ea77e8436e" -SOURCE_URI_8="https://github.com/Cyan4973/xxHash/archive/$srcGitRev_8.tar.gz" -CHECKSUM_SHA256_8="0d1e2b4ae15f98acc49084e23ba94853dba2b0f654865ecedb1072b3959421bf" -SOURCE_FILENAME_8="xxHash-$srcGitRev_8.tar.gz" -srcGitRev_9="589db026ec211bc4979e3bffe074f6e48ce7cedc" -SOURCE_URI_9="https://github.com/john-preston/rlottie/archive/$srcGitRev_9.zip" -CHECKSUM_SHA256_9="35047dc59500aa9c98459a8d656e07bfc6f0cf7189a902e83b8296f2f007f83a" -SOURCE_FILENAME_9="rlottie-$srcGitRev_9.zip" -srcGitRev_10="9a2a9f2d0f38a39c5ec9b329042ca5f060b058e0" -SOURCE_URI_10="https://github.com/lz4/lz4/archive/$srcGitRev_10.tar.gz" -CHECKSUM_SHA256_10="fb17b28934ea7f85bd381dd183d765973f7e90a7e2ebc2415af61fe6848741cc" -SOURCE_FILENAME_10="lz4-$srcGitRev_10.tar.gz" -srcGitRev_11="0663103551379b958b2e79c51d51d163ec484300" -SOURCE_URI_11="https://salsa.debian.org/debian/telegram-desktop/raw/$srcGitRev_11/debian/rules#noarchive" -CHECKSUM_SHA256_11="2b24fb808acee36b5a15824c4ff8bd8b8e83a326a9e4593d2b21922425c5ffb3" - -PATCHES=" - telegram_desktop-$portVersion.patchset - telegram_desktop-$portVersion-sonnet.patchset - " -PATCHES_2=" - telegram_desktop-$portVersion-libtgvoip.patchset - " -ADDITIONAL_FILES=" - telegram_desktop.rdef.in - logo_256_no_margin.png - " - -ARCHITECTURES="!x86_gcc2 x86_64" -SECONDARY_ARCHITECTURES="x86" - -PROVIDES=" - telegram_desktop$secondaryArchSuffix = $portVersion - app:Telegram$secondaryArchSuffix - cmd:tg_notify_gate - " -REQUIRES=" - haiku$secondaryArchSuffix - lib:libavcodec$secondaryArchSuffix - lib:libavformat$secondaryArchSuffix - lib:libavutil$secondaryArchSuffix - lib:libcrypto$secondaryArchSuffix - lib:libglib_2.0$secondaryArchSuffix - lib:libgthread_2.0$secondaryArchSuffix - lib:libKF5SonnetCore$secondaryArchSuffix - lib:libKF5SonnetUi$secondaryArchSuffix - lib:liblzma$secondaryArchSuffix - lib:libminizip$secondaryArchSuffix - lib:libopenal$secondaryArchSuffix - lib:libopus$secondaryArchSuffix - lib:libQt5Core$secondaryArchSuffix - lib:libQt5Gui$secondaryArchSuffix - lib:libQt5Network$secondaryArchSuffix - lib:libQt5Widgets$secondaryArchSuffix - lib:libswresample$secondaryArchSuffix - lib:libswscale$secondaryArchSuffix - lib:libz$secondaryArchSuffix - " - -BUILD_REQUIRES=" - haiku${secondaryArchSuffix}_devel - devel:libavcodec$secondaryArchSuffix - devel:libavformat$secondaryArchSuffix - devel:libavutil$secondaryArchSuffix - devel:libcrypto$secondaryArchSuffix - devel:libglib_2.0$secondaryArchSuffix - devel:libgthread_2.0$secondaryArchSuffix - devel:libKF5SonnetCore$secondaryArchSuffix - devel:libKF5SonnetUi$secondaryArchSuffix - devel:liblzma$secondaryArchSuffix - devel:libminizip$secondaryArchSuffix - devel:libopenal$secondaryArchSuffix - devel:libopus$secondaryArchSuffix - devel:libQt5Core$secondaryArchSuffix - devel:libQt5Gui$secondaryArchSuffix - devel:libQt5Network$secondaryArchSuffix - devel:libQt5Widgets$secondaryArchSuffix - devel:librapidjson$secondaryArchSuffix - devel:libswresample$secondaryArchSuffix - devel:libswscale$secondaryArchSuffix - devel:libz$secondaryArchSuffix - " -BUILD_PREREQUIRES=" - cmd:cmake - cmd:gcc$secondaryArchSuffix - cmd:gyp - cmd:lrelease$secondaryArchSuffix - cmd:make - cmd:pkg_config$secondaryArchSuffix - cmd:sed - " - -PATCH() -{ - sed -i "s|@HAIKU_HEADERS@|/system/$relativeIncludeDir|" Telegram/gyp/telegram/haiku.gypi - sed -i "s|@HAIKU_HEADERS@|/system/$relativeIncludeDir|" Telegram/gyp/common/haiku.gypi - sed -i "s|@HAIKU_HEADERS@|/system/$relativeIncludeDir|" Telegram/gyp/modules/qt.gypi - sed -i "s|@HAIKU_LIBS@|/system/$relativeLibDir|" Telegram/gyp/telegram/haiku.gypi - cp -f $sourceDir/../../../additional-files/logo_256_no_margin.png Telegram/Resources/art -} - -BUILD() -{ - # link submodules - rm -rf Telegram/ThirdParty/{libtgvoip,variant,GSL,Catch,crl,range,xxHash,rlottie,lz4} - ln -sfn $sourceDir2/libtgvoip-$srcGitRev_2 Telegram/ThirdParty/libtgvoip - ln -sfn $sourceDir3/variant-$srcGitRev_3 Telegram/ThirdParty/variant - ln -sfn $sourceDir4/GSL-$srcGitRev_4 Telegram/ThirdParty/GSL - ln -sfn $sourceDir5/Catch2-$srcGitRev_5 Telegram/ThirdParty/Catch - ln -sfn $sourceDir6/crl-$srcGitRev_6 Telegram/ThirdParty/crl - ln -sfn $sourceDir7/range-v3-$srcGitRev_7 Telegram/ThirdParty/range - ln -sfn $sourceDir8/xxHash-$srcGitRev_8 Telegram/ThirdParty/xxHash - ln -sfn $sourceDir9/rlottie-$srcGitRev_9 Telegram/ThirdParty/rlottie - ln -sfn $sourceDir10/lz4-$srcGitRev_10 Telegram/ThirdParty/lz4 - - # get API_ID and API_HASH from Debian - local TELEGRAM_API_ID=`sed -n 's/TELEGRAM_API_ID = \(.*\)/\1/p' < $sourceDir11/rules` - local TELEGRAM_API_HASH=`sed -n 's/TELEGRAM_API_HASH = \(.*\)/\1/p' < $sourceDir11/rules` - - if [ -z $TELEGRAM_API_ID ] || [ -z $TELEGRAM_API_HASH ]; then - TELEGRAM_API_ID="17349" - TELEGRAM_API_HASH="344583e45741c457fe1862106095a5eb" - echo -e "\e[91m***************************************************************************\e[39m" - echo -e "\e[91m Use demo API_ID = $TELEGRAM_API_ID and API_HASH = $TELEGRAM_API_HASH \e[39m" - echo -e "\e[91m***************************************************************************\e[39m" - else - echo -e "\e[32m***************************************************************************\e[39m" - echo -e "\e[32m Use custom API_ID = $TELEGRAM_API_ID and API_HASH = $TELEGRAM_API_HASH \e[39m" - echo -e "\e[32m***************************************************************************\e[39m" - fi - - Telegram/gyp/refresh.sh --api-id $TELEGRAM_API_ID --api-hash $TELEGRAM_API_HASH - cd out/Release - # multi-job takes too much memory - export DISABLE_ASLR=1 - make - - #build notify gate tool - gcc -o tg-notify-gate $sourceDir/Telegram/SourceFiles/platform/haiku/notifications_haiku_gate.cpp -lbe - rc -o tg-notify-gate.rsrc $sourceDir/Telegram/SourceFiles/platform/haiku/notifications_haiku_gate.rdef - xres -o tg-notify-gate tg-notify-gate.rsrc - mimeset --all tg-notify-gate -} - -INSTALL() -{ - mkdir -p $appsDir $prefix/bin - cp out/Release/tg-notify-gate $prefix/bin - cp out/Release/Telegram $appsDir - strip $appsDir/Telegram - - local APP_SIGNATURE="application/x-vnd.telegram" - local MAJOR="`echo "$portVersion" | cut -d. -f1`" - local MIDDLE="`echo "$portVersion" | cut -d. -f2`" - local MINOR="`echo "$portVersion" | cut -d. -f3`" - local LONG_INFO="$SUMMARY" - sed \ - -e "s|@APP_SIGNATURE@|$APP_SIGNATURE|" \ - -e "s|@MAJOR@|$MAJOR|" \ - -e "s|@MIDDLE@|$MIDDLE|" \ - -e "s|@MINOR@|$MINOR|" \ - -e "s|@LONG_INFO@|$LONG_INFO|" \ - $portDir/additional-files/telegram_desktop.rdef.in > telegram_desktop.rdef - - addResourcesToBinaries telegram_desktop.rdef $appsDir/Telegram - addAppDeskbarSymlink $appsDir/Telegram -} diff --git a/net-im/telegram-desktop/telegram_desktop-1.9.3.recipe b/net-im/telegram-desktop/telegram_desktop-1.9.3.recipe new file mode 100644 index 000000000..3ae48afa6 --- /dev/null +++ b/net-im/telegram-desktop/telegram_desktop-1.9.3.recipe @@ -0,0 +1,161 @@ +SUMMARY="Telegram Desktop Messenger" +DESCRIPTION="Unofficial build of the original Telegram client for Haiku." +HOMEPAGE="https://www.telegram.org/" +COPYRIGHT="2013-2019 Telegram" +LICENSE="GNU GPL v3" +REVISION="1" + +SOURCE_URI="https://github.com/telegramdesktop/tdesktop/releases/download/v$portVersion/tdesktop-$portVersion-full.tar.gz" +CHECKSUM_SHA256="ca9c67369140952d5ffe404ca082517193e3832b2c21ba1af791f078e4d9a7bb" +SOURCE_FILENAME="tdesktop-$portVersion-full.tar.gz" +SOURCE_DIR="tdesktop-$portVersion-full" +srcGitRev_2="8a732ee6736af8af024b5b2032580b85a9be8239" +SOURCE_URI_2="https://github.com/ericniebler/range-v3/archive/$srcGitRev_2.tar.gz" +CHECKSUM_SHA256_2="6cd6a412db92bf3c26a408f5807751f976b4a4cb2801c705cb63001e53b47a11" +SOURCE_FILENAME_2="range-$srcGitRev_2.tar.gz" +srcGitRev_3="0663103551379b958b2e79c51d51d163ec484300" +SOURCE_URI_3="https://salsa.debian.org/debian/telegram-desktop/raw/$srcGitRev_3/debian/rules#noarchive" +CHECKSUM_SHA256_3="2b24fb808acee36b5a15824c4ff8bd8b8e83a326a9e4593d2b21922425c5ffb3" + +PATCHES="telegram_desktop-$portVersion.patchset" +ADDITIONAL_FILES=" + telegram_desktop.rdef.in + logo_256_no_margin.png + " + +ARCHITECTURES="!x86_gcc2 x86_64" +SECONDARY_ARCHITECTURES="x86" + +PROVIDES=" + telegram_desktop$secondaryArchSuffix = $portVersion + app:Telegram$secondaryArchSuffix + cmd:tg_notify_gate + " +REQUIRES=" + haiku$secondaryArchSuffix + lib:libavcodec$secondaryArchSuffix + lib:libavformat$secondaryArchSuffix + lib:libavutil$secondaryArchSuffix + lib:libcrypto$secondaryArchSuffix + lib:libenchant_2$secondaryArchSuffix + lib:libglib_2.0$secondaryArchSuffix + lib:libgthread_2.0$secondaryArchSuffix + lib:liblz4$secondaryArchSuffix + lib:liblzma$secondaryArchSuffix + lib:libminizip$secondaryArchSuffix + lib:libopenal$secondaryArchSuffix + lib:libopus$secondaryArchSuffix + lib:libQt5Core$secondaryArchSuffix + lib:libQt5Gui$secondaryArchSuffix + lib:libQt5Network$secondaryArchSuffix + lib:libQt5Widgets$secondaryArchSuffix + lib:libswresample$secondaryArchSuffix + lib:libswscale$secondaryArchSuffix + lib:libz$secondaryArchSuffix + " + +BUILD_REQUIRES=" + haiku${secondaryArchSuffix}_devel + devel:libavcodec$secondaryArchSuffix + devel:libavformat$secondaryArchSuffix + devel:libavutil$secondaryArchSuffix + devel:libcrypto$secondaryArchSuffix + devel:libenchant_2$secondaryArchSuffix + devel:libglib_2.0$secondaryArchSuffix + devel:libgthread_2.0$secondaryArchSuffix + devel:liblz4$secondaryArchSuffix + devel:liblzma$secondaryArchSuffix + devel:libminizip$secondaryArchSuffix + devel:libopenal$secondaryArchSuffix + devel:libopus$secondaryArchSuffix + devel:libQt5Core$secondaryArchSuffix + devel:libQt5Gui$secondaryArchSuffix + devel:libQt5Network$secondaryArchSuffix + devel:libQt5Widgets$secondaryArchSuffix + devel:librapidjson$secondaryArchSuffix + devel:libswresample$secondaryArchSuffix + devel:libswscale$secondaryArchSuffix + devel:libz$secondaryArchSuffix + " +BUILD_PREREQUIRES=" + cmd:cmake + cmd:gcc$secondaryArchSuffix + cmd:lrelease$secondaryArchSuffix + cmd:make + cmd:pkg_config$secondaryArchSuffix + cmd:python + cmd:sed + " + +PATCH() +{ + cp -f $sourceDir/../../../additional-files/logo_256_no_margin.png Telegram/Resources/art +} + +BUILD() +{ + ln -sfn $sourceDir2/range-v3-$srcGitRev_2 Telegram/ThirdParty/range-v3 + + # get API_ID and API_HASH from Debian + local TELEGRAM_API_ID=`sed -n 's/TELEGRAM_API_ID = \(.*\)/\1/p' < $sourceDir3/rules` + local TELEGRAM_API_HASH=`sed -n 's/TELEGRAM_API_HASH = \(.*\)/\1/p' < $sourceDir3/rules` + + if [ -z $TELEGRAM_API_ID ] || [ -z $TELEGRAM_API_HASH ]; then + TELEGRAM_API_ID="17349" + TELEGRAM_API_HASH="344583e45741c457fe1862106095a5eb" + echo -e "\e[91m***************************************************************************\e[39m" + echo -e "\e[91m Use demo API_ID = $TELEGRAM_API_ID and API_HASH = $TELEGRAM_API_HASH \e[39m" + echo -e "\e[91m***************************************************************************\e[39m" + else + echo -e "\e[32m***************************************************************************\e[39m" + echo -e "\e[32m Use custom API_ID = $TELEGRAM_API_ID and API_HASH = $TELEGRAM_API_HASH \e[39m" + echo -e "\e[32m***************************************************************************\e[39m" + fi + + mkdir -p build + cd build + + cmake .. \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_DISABLE_PRECOMPILE_HEADERS=OFF \ + -DDESKTOP_APP_DISABLE_CRASH_REPORTS=ON \ + -DDESKTOP_APP_DISABLE_SPELLCHECK=OFF \ + -DTDESKTOP_API_TEST=OFF \ + -DTDESKTOP_DISABLE_DESKTOP_FILE_GENERATION=ON \ + -DTDESKTOP_DISABLE_GTK_INTEGRATION=ON \ + -DTDESKTOP_API_ID=$TELEGRAM_API_ID \ + -DTDESKTOP_API_HASH=$TELEGRAM_API_HASH + + export DISABLE_ASLR=1 + make $jobArgs + + #build notify gate tool + gcc -o tg-notify-gate $sourceDir/Telegram/SourceFiles/platform/haiku/notifications_haiku_gate.cpp -lbe + rc -o tg-notify-gate.rsrc $sourceDir/Telegram/SourceFiles/platform/haiku/notifications_haiku_gate.rdef + xres -o tg-notify-gate tg-notify-gate.rsrc + mimeset --all tg-notify-gate +} + +INSTALL() +{ + mkdir -p $appsDir $prefix/bin + cp build/tg-notify-gate $prefix/bin + cp build/bin/telegram-desktop $appsDir/Telegram + strip $appsDir/Telegram + + local APP_SIGNATURE="application/x-vnd.telegram" + local MAJOR="`echo "$portVersion" | cut -d. -f1`" + local MIDDLE="`echo "$portVersion" | cut -d. -f2`" + local MINOR="`echo "$portVersion" | cut -d. -f3`" + local LONG_INFO="$SUMMARY" + sed \ + -e "s|@APP_SIGNATURE@|$APP_SIGNATURE|" \ + -e "s|@MAJOR@|$MAJOR|" \ + -e "s|@MIDDLE@|$MIDDLE|" \ + -e "s|@MINOR@|$MINOR|" \ + -e "s|@LONG_INFO@|$LONG_INFO|" \ + $portDir/additional-files/telegram_desktop.rdef.in > build/telegram_desktop.rdef + + addResourcesToBinaries build/telegram_desktop.rdef $appsDir/Telegram + addAppDeskbarSymlink $appsDir/Telegram +}