diff --git a/CMakeLists.txt b/CMakeLists.txt
index fbcd97777..8678bd78c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -60,9 +60,9 @@ include(cmake/options.cmake)
if (NOT DESKTOP_APP_USE_PACKAGED)
if (WIN32)
- set(qt_version 5.15.11)
+ set(qt_version 5.15.12)
elseif (APPLE)
- set(qt_version 6.2.6)
+ set(qt_version 6.2.7)
endif()
endif()
include(cmake/external/qt/package.cmake)
diff --git a/Telegram/Resources/icons/win_quit.png b/Telegram/Resources/icons/win_quit.png
new file mode 100644
index 000000000..a823f133e
Binary files /dev/null and b/Telegram/Resources/icons/win_quit.png differ
diff --git a/Telegram/Resources/icons/win_quit@2x.png b/Telegram/Resources/icons/win_quit@2x.png
new file mode 100644
index 000000000..569097eda
Binary files /dev/null and b/Telegram/Resources/icons/win_quit@2x.png differ
diff --git a/Telegram/Resources/icons/win_quit@3x.png b/Telegram/Resources/icons/win_quit@3x.png
new file mode 100644
index 000000000..c11e92bb2
Binary files /dev/null and b/Telegram/Resources/icons/win_quit@3x.png differ
diff --git a/Telegram/Resources/uwp/AppX/AppxManifest.xml b/Telegram/Resources/uwp/AppX/AppxManifest.xml
index 6dee69ef6..bc517dc13 100644
--- a/Telegram/Resources/uwp/AppX/AppxManifest.xml
+++ b/Telegram/Resources/uwp/AppX/AppxManifest.xml
@@ -10,7 +10,7 @@
+ Version="4.14.3.0" />
Telegram Desktop
Telegram Messenger LLP
diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc
index 8893763ae..f30626251 100644
--- a/Telegram/Resources/winrc/Telegram.rc
+++ b/Telegram/Resources/winrc/Telegram.rc
@@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 4,14,2,0
- PRODUCTVERSION 4,14,2,0
+ FILEVERSION 4,14,3,0
+ PRODUCTVERSION 4,14,3,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -62,10 +62,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Radolyn Labs"
VALUE "FileDescription", "AyuGram Desktop"
- VALUE "FileVersion", "4.14.2.0"
+ VALUE "FileVersion", "4.14.3.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2024"
VALUE "ProductName", "AyuGram Desktop"
- VALUE "ProductVersion", "4.14.2.0"
+ VALUE "ProductVersion", "4.14.3.0"
END
END
BLOCK "VarFileInfo"
diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc
index aa542f2cd..014686458 100644
--- a/Telegram/Resources/winrc/Updater.rc
+++ b/Telegram/Resources/winrc/Updater.rc
@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 4,14,2,0
- PRODUCTVERSION 4,14,2,0
+ FILEVERSION 4,14,3,0
+ PRODUCTVERSION 4,14,3,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -53,10 +53,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Radolyn Labs"
VALUE "FileDescription", "AyuGram Desktop Updater"
- VALUE "FileVersion", "4.14.2.0"
+ VALUE "FileVersion", "4.14.3.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2024"
VALUE "ProductName", "AyuGram Desktop"
- VALUE "ProductVersion", "4.14.2.0"
+ VALUE "ProductVersion", "4.14.3.0"
END
END
BLOCK "VarFileInfo"
diff --git a/Telegram/SourceFiles/api/api_common.h b/Telegram/SourceFiles/api/api_common.h
index c82841142..155666a5d 100644
--- a/Telegram/SourceFiles/api/api_common.h
+++ b/Telegram/SourceFiles/api/api_common.h
@@ -25,6 +25,7 @@ struct SendOptions {
bool silent = false;
bool handleSupportSwitch = false;
bool hideViaBot = false;
+ crl::time ttlSeconds = 0;
};
[[nodiscard]] SendOptions DefaultSendWhenOnlineOptions();
diff --git a/Telegram/SourceFiles/api/api_media.cpp b/Telegram/SourceFiles/api/api_media.cpp
index ec8c1e4b2..a76cb4b67 100644
--- a/Telegram/SourceFiles/api/api_media.cpp
+++ b/Telegram/SourceFiles/api/api_media.cpp
@@ -79,16 +79,19 @@ MTPInputMedia PrepareUploadedPhoto(
not_null item,
RemoteFileInfo info) {
using Flag = MTPDinputMediaUploadedPhoto::Flag;
- const auto spoiler = item->media()
- && item->media()->hasSpoiler();
+ const auto spoiler = item->media() && item->media()->hasSpoiler();
+ const auto ttlSeconds = item->media()
+ ? item->media()->ttlSeconds()
+ : 0;
const auto flags = (spoiler ? Flag::f_spoiler : Flag())
- | (info.attachedStickers.empty() ? Flag() : Flag::f_stickers);
+ | (info.attachedStickers.empty() ? Flag() : Flag::f_stickers)
+ | (ttlSeconds ? Flag::f_ttl_seconds : Flag());
return MTP_inputMediaUploadedPhoto(
MTP_flags(flags),
info.file,
MTP_vector(
ranges::to>(info.attachedStickers)),
- MTP_int(0));
+ MTP_int(ttlSeconds));
}
MTPInputMedia PrepareUploadedDocument(
@@ -98,12 +101,15 @@ MTPInputMedia PrepareUploadedDocument(
return MTP_inputMediaEmpty();
}
using Flag = MTPDinputMediaUploadedDocument::Flag;
- const auto spoiler = item->media()
- && item->media()->hasSpoiler();
+ const auto spoiler = item->media() && item->media()->hasSpoiler();
+ const auto ttlSeconds = item->media()
+ ? item->media()->ttlSeconds()
+ : 0;
const auto flags = (spoiler ? Flag::f_spoiler : Flag())
| (info.thumb ? Flag::f_thumb : Flag())
| (item->groupId() ? Flag::f_nosound_video : Flag())
- | (info.attachedStickers.empty() ? Flag::f_stickers : Flag());
+ | (info.attachedStickers.empty() ? Flag::f_stickers : Flag())
+ | (ttlSeconds ? Flag::f_ttl_seconds : Flag());
const auto document = item->media()->document();
return MTP_inputMediaUploadedDocument(
MTP_flags(flags),
@@ -113,7 +119,7 @@ MTPInputMedia PrepareUploadedDocument(
ComposeSendingDocumentAttributes(document),
MTP_vector(
ranges::to>(info.attachedStickers)),
- MTP_int(0));
+ MTP_int(ttlSeconds));
}
bool HasAttachedStickers(MTPInputMedia media) {
diff --git a/Telegram/SourceFiles/api/api_sending.cpp b/Telegram/SourceFiles/api/api_sending.cpp
index a0d6f4d95..d971a03f4 100644
--- a/Telegram/SourceFiles/api/api_sending.cpp
+++ b/Telegram/SourceFiles/api/api_sending.cpp
@@ -42,6 +42,9 @@ void InnerFillMessagePostFlags(
not_null peer,
MessageFlags &flags) {
const auto anonymousPost = peer->amAnonymous();
+ if (ShouldSendSilent(peer, options)) {
+ flags |= MessageFlag::Silent;
+ }
if (!anonymousPost || options.sendAs) {
flags |= MessageFlag::HasFromId;
return;
@@ -401,9 +404,6 @@ void SendConfirmedFile(
const auto anonymousPost = peer->amAnonymous();
const auto silentPost = ShouldSendSilent(peer, file->to.options);
FillMessagePostFlags(action, peer, flags);
- if (silentPost) {
- flags |= MessageFlag::Silent;
- }
if (file->to.options.scheduled) {
flags |= MessageFlag::IsOrWasScheduled;
@@ -443,11 +443,30 @@ void SendConfirmedFile(
MTPDocument(), // alt_document
MTPint());
} else if (file->type == SendMediaType::Audio) {
+ const auto ttlSeconds = file->to.options.ttlSeconds;
+ const auto isVoice = [&] {
+ return file->document.match([](const MTPDdocumentEmpty &d) {
+ return false;
+ }, [](const MTPDdocument &d) {
+ return ranges::any_of(d.vattributes().v, [&](
+ const MTPDocumentAttribute &attribute) {
+ using Att = MTPDdocumentAttributeAudio;
+ return attribute.match([](const Att &data) -> bool {
+ return data.vflags().v & Att::Flag::f_voice;
+ }, [](const auto &) {
+ return false;
+ });
+ });
+ });
+ }();
+ using Flag = MTPDmessageMediaDocument::Flag;
return MTP_messageMediaDocument(
- MTP_flags(MTPDmessageMediaDocument::Flag::f_document),
+ MTP_flags(Flag::f_document
+ | (isVoice ? Flag::f_voice : Flag())
+ | (ttlSeconds ? Flag::f_ttl_seconds : Flag())),
file->document,
MTPDocument(), // alt_document
- MTPint());
+ MTP_int(ttlSeconds));
} else {
Unexpected("Type in sendFilesConfirmed.");
}
diff --git a/Telegram/SourceFiles/boxes/premium_limits_box.cpp b/Telegram/SourceFiles/boxes/premium_limits_box.cpp
index 60eb5ecde..ad8d313df 100644
--- a/Telegram/SourceFiles/boxes/premium_limits_box.cpp
+++ b/Telegram/SourceFiles/boxes/premium_limits_box.cpp
@@ -68,6 +68,8 @@ public:
void prepare() override;
void rowClicked(not_null row) override;
+ [[nodiscard]] rpl::producer countValue() const;
+
private:
void appendRow(not_null peer, TimeId date);
[[nodiscard]] std::unique_ptr createRow(
@@ -75,6 +77,7 @@ private:
TimeId date) const;
const not_null _session;
+ rpl::variable _count;
mtpRequestId _requestId = 0;
};
@@ -91,12 +94,15 @@ public:
void rowClicked(not_null row) override;
void rowRightActionClicked(not_null row) override;
+ [[nodiscard]] rpl::producer countValue() const;
+
private:
void appendRow(not_null peer);
[[nodiscard]] std::unique_ptr createRow(
not_null peer) const;
const not_null _navigation;
+ rpl::variable _count;
Fn _closeBox;
mtpRequestId _requestId = 0;
@@ -210,17 +216,17 @@ void InactiveController::prepare() {
_requestId = _session->api().request(MTPchannels_GetInactiveChannels(
)).done([=](const MTPmessages_InactiveChats &result) {
_requestId = 0;
- result.match([&](const MTPDmessages_inactiveChats &data) {
- _session->data().processUsers(data.vusers());
- const auto &list = data.vchats().v;
- const auto &dates = data.vdates().v;
- for (auto i = 0, count = int(list.size()); i != count; ++i) {
- const auto peer = _session->data().processChat(list[i]);
- const auto date = (i < dates.size()) ? dates[i].v : TimeId();
- appendRow(peer, date);
- }
- delegate()->peerListRefreshRows();
- });
+ const auto &data = result.data();
+ _session->data().processUsers(data.vusers());
+ const auto &list = data.vchats().v;
+ const auto &dates = data.vdates().v;
+ for (auto i = 0, count = int(list.size()); i != count; ++i) {
+ const auto peer = _session->data().processChat(list[i]);
+ const auto date = (i < dates.size()) ? dates[i].v : TimeId();
+ appendRow(peer, date);
+ }
+ delegate()->peerListRefreshRows();
+ _count = delegate()->peerListFullRowsCount();
}).send();
}
@@ -228,6 +234,10 @@ void InactiveController::rowClicked(not_null row) {
delegate()->peerListSetRowChecked(row, !row->checked());
}
+rpl::producer InactiveController::countValue() const {
+ return _count.value();
+}
+
void InactiveController::appendRow(
not_null participant,
TimeId date) {
@@ -296,6 +306,10 @@ Main::Session &PublicsController::session() const {
return _navigation->session();
}
+rpl::producer PublicsController::countValue() const {
+ return _count.value();
+}
+
void PublicsController::prepare() {
_requestId = _navigation->session().api().request(
MTPchannels_GetAdminedPublicChannels(MTP_flags(0))
@@ -315,6 +329,7 @@ void PublicsController::prepare() {
}
delegate()->peerListRefreshRows();
}
+ _count = delegate()->peerListFullRowsCount();
}).send();
}
@@ -571,7 +586,7 @@ void ChannelsLimitBox(
{});
using namespace rpl::mappers;
- content->heightValue(
+ controller->countValue(
) | rpl::filter(_1 > 0) | rpl::start_with_next([=] {
delete placeholder;
}, placeholder->lifetime());
@@ -662,7 +677,7 @@ void PublicLinksLimitBox(
{});
using namespace rpl::mappers;
- content->heightValue(
+ controller->countValue(
) | rpl::filter(_1 > 0) | rpl::start_with_next([=] {
delete placeholder;
}, placeholder->lifetime());
diff --git a/Telegram/SourceFiles/chat_helpers/chat_helpers.style b/Telegram/SourceFiles/chat_helpers/chat_helpers.style
index 7a323faee..c86e98b75 100644
--- a/Telegram/SourceFiles/chat_helpers/chat_helpers.style
+++ b/Telegram/SourceFiles/chat_helpers/chat_helpers.style
@@ -1072,6 +1072,7 @@ historyRecordCancelActive: windowActiveTextFg;
historyRecordFont: font(13px);
historyRecordDurationSkip: 12px;
historyRecordDurationFg: historyComposeAreaFg;
+historyRecordTTLLineWidth: 2px;
historyRecordMainBlobMinRadius: 23px;
historyRecordMainBlobMaxRadius: 37px;
diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h
index 3da7c4e77..b2db36f80 100644
--- a/Telegram/SourceFiles/core/version.h
+++ b/Telegram/SourceFiles/core/version.h
@@ -22,7 +22,7 @@ constexpr auto AppId = "{53F49750-6209-4FBF-9CA8-7A333C87D666}"_cs;
constexpr auto AppNameOld = "AyuGram for Windows"_cs;
constexpr auto AppName = "AyuGram Desktop"_cs;
constexpr auto AppFile = "AyuGram"_cs;
-constexpr auto AppVersion = 4014002;
-constexpr auto AppVersionStr = "4.14.2";
+constexpr auto AppVersion = 4014003;
+constexpr auto AppVersionStr = "4.14.3";
constexpr auto AppBetaVersion = false;
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;
diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp
index 32ff4be75..e5b1f5be6 100644
--- a/Telegram/SourceFiles/data/data_document.cpp
+++ b/Telegram/SourceFiles/data/data_document.cpp
@@ -48,6 +48,8 @@ namespace {
constexpr auto kDefaultCoverThumbnailSize = 100;
constexpr auto kMaxAllowedPreloadPrefix = 6 * 1024 * 1024;
+constexpr auto kDefaultWebmEmojiSize = 100;
+constexpr auto kDefaultWebmStickerLargerSize = kStickerSideSize;
const auto kLottieStickerDimensions = QSize(
kStickerSideSize,
@@ -430,6 +432,42 @@ void DocumentData::setattributes(
_flags |= Flag::HasAttachedStickers;
});
}
+
+ // Any "video/webm" file is treated as a video-sticker.
+ if (hasMimeType(u"video/webm"_q)) {
+ if (type == FileDocument) {
+ type = StickerDocument;
+ _additional = std::make_unique();
+ }
+ if (type == StickerDocument) {
+ sticker()->type = StickerType::Webm;
+ }
+ }
+
+ // If "video/webm" sticker without dimensions we set them to default.
+ if (const auto info = sticker(); info
+ && info->set
+ && info->type == StickerType::Webm
+ && dimensions.isEmpty()) {
+ if (info->setType == Data::StickersType::Emoji) {
+ // Always fixed.
+ dimensions = { kDefaultWebmEmojiSize, kDefaultWebmEmojiSize };
+ } else if (info->setType == Data::StickersType::Stickers) {
+ // May have aspect != 1, so we count it from the thumbnail.
+ const auto thumbnail = QSize(
+ _thumbnail.location.width(),
+ _thumbnail.location.height()
+ ).scaled(
+ kDefaultWebmStickerLargerSize,
+ kDefaultWebmStickerLargerSize,
+ Qt::KeepAspectRatio);
+ if (!thumbnail.isEmpty()) {
+ dimensions = thumbnail;
+ }
+ }
+ }
+
+ // Check sticker size/dimensions properties (for sticker of any type).
if (type == StickerDocument
&& ((size > Storage::kMaxStickerBytesSize)
|| (!sticker()->isLottie()
@@ -438,14 +476,8 @@ void DocumentData::setattributes(
dimensions.height())))) {
type = FileDocument;
_additional = nullptr;
- } else if (type == FileDocument
- && hasMimeType(u"video/webm"_q)
- && (size < Storage::kMaxStickerBytesSize)
- && GoodStickerDimensions(dimensions.width(), dimensions.height())) {
- type = StickerDocument;
- _additional = std::make_unique();
- sticker()->type = StickerType::Webm;
}
+
if (isAudioFile()
|| isAnimation()
|| isVoiceMessage()
@@ -483,8 +515,7 @@ bool DocumentData::checkWallPaperProperties() {
}
if (type != FileDocument
|| !hasThumbnail()
- || !dimensions.width()
- || !dimensions.height()
+ || dimensions.isEmpty()
|| dimensions.width() > Storage::kMaxWallPaperDimension
|| dimensions.height() > Storage::kMaxWallPaperDimension
|| size > Storage::kMaxWallPaperInMemory) {
diff --git a/Telegram/SourceFiles/data/data_document_resolver.cpp b/Telegram/SourceFiles/data/data_document_resolver.cpp
index 05d23ecdf..2c34719ff 100644
--- a/Telegram/SourceFiles/data/data_document_resolver.cpp
+++ b/Telegram/SourceFiles/data/data_document_resolver.cpp
@@ -267,17 +267,18 @@ void ResolveDocument(
return false;
}
const auto &location = document->location(true);
+ const auto mime = u"image/"_q;
if (!location.isEmpty() && location.accessEnable()) {
const auto guard = gsl::finally([&] {
location.accessDisable();
});
const auto path = location.name();
- if (Core::MimeTypeForFile(QFileInfo(path)).name().startsWith("image/")
+ if (Core::MimeTypeForFile(QFileInfo(path)).name().startsWith(mime)
&& QImageReader(path).canRead()) {
showDocument();
return true;
}
- } else if (document->mimeString().startsWith("image/")
+ } else if (document->mimeString().startsWith(mime)
&& !media->bytes().isEmpty()) {
auto bytes = media->bytes();
auto buffer = QBuffer(&bytes);
diff --git a/Telegram/SourceFiles/data/data_saved_messages.cpp b/Telegram/SourceFiles/data/data_saved_messages.cpp
index 695622bbe..66bc87609 100644
--- a/Telegram/SourceFiles/data/data_saved_messages.cpp
+++ b/Telegram/SourceFiles/data/data_saved_messages.cpp
@@ -233,8 +233,10 @@ void SavedMessages::apply(
_chatsList.setLoaded();
} else if (result.type() == mtpc_messages_savedDialogs) {
_chatsList.setLoaded();
- } else if (offsetDate < _offsetDate
- || (offsetDate == _offsetDate && offsetId == _offsetId && offsetPeer == _offsetPeer)) {
+ } else if ((_offsetDate > 0 && offsetDate > _offsetDate)
+ || (offsetDate == _offsetDate
+ && offsetId == _offsetId
+ && offsetPeer == _offsetPeer)) {
LOG(("API Error: Bad order in messages.savedDialogs."));
_chatsList.setLoaded();
} else {
diff --git a/Telegram/SourceFiles/data/stickers/data_custom_emoji.cpp b/Telegram/SourceFiles/data/stickers/data_custom_emoji.cpp
index 1f80c53f6..5b271b5b6 100644
--- a/Telegram/SourceFiles/data/stickers/data_custom_emoji.cpp
+++ b/Telegram/SourceFiles/data/stickers/data_custom_emoji.cpp
@@ -414,7 +414,7 @@ Ui::CustomEmoji::Preview CustomEmojiLoader::preview() {
const auto make = [&](not_null document) -> Preview {
const auto dimensions = document->dimensions;
if (!document->inlineThumbnailIsPath()
- || !dimensions.width()) {
+ || dimensions.isEmpty()) {
return {};
}
const auto scale = (FrameSizeFromTag(_tag, _sizeOverride) * 1.)
diff --git a/Telegram/SourceFiles/dialogs/dialogs_row.cpp b/Telegram/SourceFiles/dialogs/dialogs_row.cpp
index cb35b3c51..eae45defe 100644
--- a/Telegram/SourceFiles/dialogs/dialogs_row.cpp
+++ b/Telegram/SourceFiles/dialogs/dialogs_row.cpp
@@ -90,7 +90,7 @@ constexpr auto kBlurRadius = 24;
q.drawArc(innerRect, arc::kQuarterLength, arc::kHalfLength);
q.setClipRect(innerRect
- - QMargins(innerRect.width() / 2, 0, -penWidth, -penWidth));
+ - QMargins(innerRect.width() / 2, -penWidth, -penWidth, -penWidth));
pen.setStyle(Qt::DotLine);
q.setPen(pen);
q.drawEllipse(innerRect);
diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp
index 7de4a765f..54241b6b7 100644
--- a/Telegram/SourceFiles/history/history_inner_widget.cpp
+++ b/Telegram/SourceFiles/history/history_inner_widget.cpp
@@ -2319,7 +2319,9 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
showContextInFolder(document);
}, &st::menuIconShowInFolder);
}
- if (item && !hasCopyMediaRestriction(item)) {
+ if (item
+ && !hasCopyMediaRestriction(item)
+ && !HistoryView::ItemHasTtl(item)) {
HistoryView::AddSaveSoundForNotifications(
_menu,
item,
diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp
index cc4028f84..2db71e78b 100644
--- a/Telegram/SourceFiles/history/history_widget.cpp
+++ b/Telegram/SourceFiles/history/history_widget.cpp
@@ -953,6 +953,16 @@ void HistoryWidget::initVoiceRecordBar() {
}
return false;
});
+ _voiceRecordBar->setTTLFilter([=] {
+ if (const auto peer = _history ? _history->peer.get() : nullptr) {
+ if (const auto user = peer->asUser()) {
+ if (!user->isSelf() && !user->isBot()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ });
const auto applyLocalDraft = [=] {
if (_history && _history->localDraft({})) {
@@ -6363,7 +6373,9 @@ void HistoryWidget::mousePressEvent(QMouseEvent *e) {
} else {
_forwardPanel->editOptions(controller()->uiShow());
}
- } else if (_replyTo && (e->modifiers() & Qt::ControlModifier)) {
+ } else if (_replyTo
+ && ((e->modifiers() & Qt::ControlModifier)
+ || (e->button() != Qt::LeftButton))) {
jumpToReply(_replyTo);
} else if (_replyTo) {
editDraftOptions();
diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp
index 8b9ac3393..b25be58f9 100644
--- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp
+++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp
@@ -386,6 +386,10 @@ void FieldHeader::init() {
} else if (reply) {
_editOptionsRequests.fire({});
}
+ } else if (!isLeftButton) {
+ if (const auto reply = replyingToMessage()) {
+ _jumpToItemRequests.fire_copy(reply);
+ }
}
}
}, lifetime());
diff --git a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp
index 028286ca8..85bee7a6c 100644
--- a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp
+++ b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp
@@ -32,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/ripple_animation.h"
#include "ui/text/format_values.h"
#include "ui/painter.h"
+#include "ui/rect.h"
#include "styles/style_chat.h"
#include "styles/style_chat_helpers.h"
#include "styles/style_layers.h"
@@ -204,6 +205,181 @@ void PaintWaveform(
}
}
+[[nodiscard]] QRect DrawLockCircle(
+ QPainter &p,
+ const QRect &widgetRect,
+ const style::RecordBarLock &st,
+ float64 progress) {
+ const auto &originTop = st.originTop;
+ const auto &originBottom = st.originBottom;
+ const auto &originBody = st.originBody;
+ const auto &shadowTop = st.shadowTop;
+ const auto &shadowBottom = st.shadowBottom;
+ const auto &shadowBody = st.shadowBody;
+ const auto &shadowMargins = st::historyRecordLockMargin;
+
+ const auto bottomMargin = anim::interpolate(
+ 0,
+ widgetRect.height() - shadowTop.height() - shadowBottom.height(),
+ progress);
+
+ const auto topMargin = anim::interpolate(
+ widgetRect.height() / 4,
+ 0,
+ progress);
+
+ const auto full = widgetRect - QMargins(0, topMargin, 0, bottomMargin);
+ const auto inner = full - shadowMargins;
+ const auto content = inner
+ - style::margins(0, originTop.height(), 0, originBottom.height());
+ const auto contentShadow = full
+ - style::margins(0, shadowTop.height(), 0, shadowBottom.height());
+
+ const auto w = full.width();
+ {
+ shadowTop.paint(p, full.topLeft(), w);
+ originTop.paint(p, inner.topLeft(), w);
+ }
+ {
+ const auto shadowPos = QPoint(
+ full.x(),
+ contentShadow.y() + contentShadow.height());
+ const auto originPos = QPoint(
+ inner.x(),
+ content.y() + content.height());
+ shadowBottom.paint(p, shadowPos, w);
+ originBottom.paint(p, originPos, w);
+ }
+ {
+ shadowBody.fill(p, contentShadow);
+ originBody.fill(p, content);
+ }
+ if (progress < 1.) {
+ const auto &arrow = st.arrow;
+ const auto arrowRect = QRect(
+ inner.x(),
+ content.y() + content.height() - arrow.height() / 2,
+ inner.width(),
+ arrow.height());
+ p.setOpacity(1. - progress);
+ arrow.paintInCenter(p, arrowRect);
+ p.setOpacity(1.);
+ }
+
+ return inner;
+}
+
+class TTLButton final : public Ui::RippleButton {
+public:
+ TTLButton(
+ not_null parent,
+ const style::RecordBar &st);
+
+ void clearState() override;
+
+protected:
+ QImage prepareRippleMask() const override;
+ QPoint prepareRippleStartPosition() const override;
+
+private:
+ const style::RecordBar &_st;
+ const QRect _rippleRect;
+ const QString _text;
+
+ Ui::Animations::Simple _activeAnimation;
+
+};
+
+TTLButton::TTLButton(
+ not_null parent,
+ const style::RecordBar &st)
+: RippleButton(parent, st.lock.ripple)
+, _st(st)
+, _rippleRect(Rect(Size(st::historyRecordLockTopShadow.width()))
+ - (st::historyRecordLockRippleMargin))
+, _text(u"1"_q) {
+ resize(Size(st::historyRecordLockTopShadow.width()));
+
+ setClickedCallback([=] {
+ Ui::AbstractButton::setDisabled(!Ui::AbstractButton::isDisabled());
+ const auto isActive = !Ui::AbstractButton::isDisabled();
+ _activeAnimation.start(
+ [=] { update(); },
+ isActive ? 0. : 1.,
+ isActive ? 1. : 0.,
+ st::historyRecordVoiceShowDuration);
+ });
+
+ paintRequest(
+ ) | rpl::start_with_next([=](const QRect &clip) {
+ auto p = QPainter(this);
+
+ const auto inner = DrawLockCircle(p, rect(), _st.lock, 1.);
+
+ Ui::RippleButton::paintRipple(p, _rippleRect.x(), _rippleRect.y());
+
+ const auto innerRect = QRectF(inner)
+ - st::historyRecordLockMargin * 2;
+ auto hq = PainterHighQualityEnabler(p);
+
+ p.setFont(st::semiboldFont);
+ p.setPen(_st.lock.fg);
+ p.drawText(inner, _text, style::al_center);
+
+ const auto penWidth = st::historyRecordTTLLineWidth;
+ auto pen = QPen(_st.lock.fg);
+ pen.setJoinStyle(Qt::RoundJoin);
+ pen.setCapStyle(Qt::RoundCap);
+ pen.setWidthF(penWidth);
+
+ p.setPen(pen);
+ p.setBrush(Qt::NoBrush);
+ p.drawArc(innerRect, arc::kQuarterLength, arc::kHalfLength);
+
+ {
+ p.setClipRect(innerRect
+ - QMarginsF(
+ innerRect.width() / 2,
+ -penWidth,
+ -penWidth,
+ -penWidth));
+ pen.setStyle(Qt::DotLine);
+ p.setPen(pen);
+ p.drawEllipse(innerRect);
+ p.setClipping(false);
+ }
+
+ const auto activeProgress = _activeAnimation.value(
+ !Ui::AbstractButton::isDisabled() ? 1 : 0);
+ if (activeProgress) {
+ p.setOpacity(activeProgress);
+ pen.setStyle(Qt::SolidLine);
+ pen.setBrush(st::windowBgActive);
+ p.setPen(pen);
+ p.setBrush(pen.brush());
+ p.drawEllipse(innerRect);
+
+ p.setPen(st::windowFgActive);
+ p.drawText(innerRect, _text, style::al_center);
+ }
+
+ }, lifetime());
+}
+
+void TTLButton::clearState() {
+ Ui::AbstractButton::setDisabled(true);
+ update();
+ Ui::RpWidget::hide();
+}
+
+QImage TTLButton::prepareRippleMask() const {
+ return Ui::RippleAnimation::EllipseMask(_rippleRect.size());
+}
+
+QPoint TTLButton::prepareRippleStartPosition() const {
+ return mapFromGlobal(QCursor::pos()) - _rippleRect.topLeft();
+}
+
} // namespace
class ListenWrap final {
@@ -322,7 +498,7 @@ void ListenWrap::init() {
_parent->paintRequest(
) | rpl::start_with_next([=](const QRect &clip) {
auto p = QPainter(_parent);
- PainterHighQualityEnabler hq(p);
+ auto hq = PainterHighQualityEnabler(p);
const auto progress = _showProgress.current();
p.setOpacity(progress);
const auto &remove = _st.remove;
@@ -365,7 +541,7 @@ void ListenWrap::init() {
}
p.setPen(Qt::NoPen);
p.setBrush(_st.cancelActive);
- QPainterPath path;
+ auto path = QPainterPath();
path.setFillRule(Qt::WindingFill);
path.addEllipse(bgLeftCircleRect);
path.addEllipse(bgRightCircleRect);
@@ -633,7 +809,7 @@ protected:
private:
void init();
- void drawProgress(Painter &p);
+ void drawProgress(QPainter &p);
void setProgress(float64 progress);
void startLockingAnimation(float64 to);
@@ -654,12 +830,8 @@ RecordLock::RecordLock(
const style::RecordBarLock &st)
: RippleButton(parent, st.ripple)
, _st(st)
-, _rippleRect(QRect(
- 0,
- 0,
- st::historyRecordLockTopShadow.width(),
- st::historyRecordLockTopShadow.width())
- .marginsRemoved(st::historyRecordLockRippleMargin))
+, _rippleRect(Rect(Size(st::historyRecordLockTopShadow.width()))
+ - (st::historyRecordLockRippleMargin))
, _arcPen(
QColor(Qt::white),
st::historyRecordLockIconLineWidth,
@@ -693,7 +865,7 @@ void RecordLock::init() {
if (!_visibleTopPart) {
return;
}
- Painter p(this);
+ auto p = QPainter(this);
if (_visibleTopPart > 0 && _visibleTopPart < height()) {
p.setClipRect(0, 0, width(), _visibleTopPart);
}
@@ -710,73 +882,13 @@ void RecordLock::init() {
}, lifetime());
}
-void RecordLock::drawProgress(Painter &p) {
+void RecordLock::drawProgress(QPainter &p) {
const auto progress = _progress.current();
- const auto &originTop = _st.originTop;
- const auto &originBottom = _st.originBottom;
- const auto &originBody = _st.originBody;
- const auto &shadowTop = _st.shadowTop;
- const auto &shadowBottom = _st.shadowBottom;
- const auto &shadowBody = _st.shadowBody;
- const auto &shadowMargins = st::historyRecordLockMargin;
+ const auto inner = DrawLockCircle(p, rect(), _st, progress);
- const auto bottomMargin = anim::interpolate(
- 0,
- rect().height() - shadowTop.height() - shadowBottom.height(),
- progress);
-
- const auto topMargin = anim::interpolate(
- rect().height() / 4,
- 0,
- progress);
-
- const auto full = rect().marginsRemoved(
- style::margins(0, topMargin, 0, bottomMargin));
- const auto inner = full.marginsRemoved(shadowMargins);
- const auto content = inner.marginsRemoved(style::margins(
- 0,
- originTop.height(),
- 0,
- originBottom.height()));
- const auto contentShadow = full.marginsRemoved(style::margins(
- 0,
- shadowTop.height(),
- 0,
- shadowBottom.height()));
-
- const auto w = full.width();
- {
- shadowTop.paint(p, full.topLeft(), w);
- originTop.paint(p, inner.topLeft(), w);
- }
- {
- const auto shadowPos = QPoint(
- full.x(),
- contentShadow.y() + contentShadow.height());
- const auto originPos = QPoint(
- inner.x(),
- content.y() + content.height());
- shadowBottom.paint(p, shadowPos, w);
- originBottom.paint(p, originPos, w);
- }
- {
- shadowBody.fill(p, contentShadow);
- originBody.fill(p, content);
- }
- {
- const auto &arrow = _st.arrow;
- const auto arrowRect = QRect(
- inner.x(),
- content.y() + content.height() - arrow.height() / 2,
- inner.width(),
- arrow.height());
- p.setOpacity(1. - progress);
- arrow.paintInCenter(p, arrowRect);
- p.setOpacity(1.);
- }
if (isLocked()) {
- paintRipple(p, _rippleRect.x(), _rippleRect.y());
+ Ui::RippleButton::paintRipple(p, _rippleRect.x(), _rippleRect.y());
}
{
const auto &arcOffset = st::historyRecordLockIconLineSkip;
@@ -809,12 +921,12 @@ void RecordLock::drawProgress(Painter &p) {
const auto lockTranslation = QPoint(
(inner.width() - size.width()) / 2,
- (originTop.height() * 2 - size.height()) / 2);
+ (_st.originTop.height() * 2 - size.height()) / 2);
const auto xRadius = anim::interpolate(2, 3, _lockToStopProgress);
if (_lockToStopProgress == 1.) {
// Paint the block.
- PainterHighQualityEnabler hq(p);
+ auto hq = PainterHighQualityEnabler(p);
p.translate(inner.topLeft() + lockTranslation);
p.setPen(Qt::NoPen);
p.setBrush(_st.fg);
@@ -827,8 +939,8 @@ void RecordLock::drawProgress(Painter &p) {
frame.setDevicePixelRatio(style::DevicePixelRatio());
frame.fill(Qt::transparent);
- Painter q(&frame);
- PainterHighQualityEnabler hq(q);
+ auto q = QPainter(&frame);
+ auto hq = PainterHighQualityEnabler(q);
q.setPen(Qt::NoPen);
q.setBrush(_arcPen.brush());
@@ -986,19 +1098,19 @@ void CancelButton::init() {
paintRequest(
) | rpl::start_with_next([=] {
- Painter p(this);
+ auto p = QPainter(this);
p.setOpacity(_showProgress.current());
- paintRipple(p, _rippleRect.x(), _rippleRect.y());
+ Ui::RippleButton::paintRipple(p, _rippleRect.x(), _rippleRect.y());
p.setPen(_st.cancelActive);
- _text.draw(
- p,
- 0,
- (height() - _text.minHeight()) / 2,
- width(),
- style::al_center);
+ _text.draw(p, {
+ .position = QPoint(0, (height() - _text.minHeight()) / 2),
+ .outerWidth = width(),
+ .availableWidth = width(),
+ .align = style::al_center,
+ });
}, lifetime());
}
@@ -1024,6 +1136,7 @@ VoiceRecordBar::VoiceRecordBar(
, _show(std::move(descriptor.show))
, _send(std::move(descriptor.send))
, _lock(std::make_unique(_outerContainer, _st.lock))
+, _ttlButton(std::make_unique(_outerContainer, _st))
, _level(std::make_unique(_outerContainer, _st))
, _cancel(std::make_unique(this, _st, descriptor.recorderHeight))
, _startTimer([=] { startRecording(); })
@@ -1060,9 +1173,7 @@ VoiceRecordBar::~VoiceRecordBar() {
}
void VoiceRecordBar::updateMessageGeometry() {
- const auto left = _durationRect.x()
- + _durationRect.width()
- + st::historyRecordTextLeft;
+ const auto left = rect::right(_durationRect) + st::historyRecordTextLeft;
const auto right = width()
- _send->width()
- st::historyRecordTextRight;
@@ -1086,7 +1197,7 @@ void VoiceRecordBar::updateLockGeometry() {
- st::historyRecordLockPosition.y()
- _lock->height();
const auto finalRight = _outerContainer->width()
- - (me.x() + me.width())
+ - rect::right(me)
+ st::historyRecordLockPosition.x();
const auto progress = _showLockAnimation.value(
_lockShowing.current() ? 1. : 0.);
@@ -1101,6 +1212,33 @@ void VoiceRecordBar::updateLockGeometry() {
}
}
+void VoiceRecordBar::updateTTLGeometry(
+ TTLAnimationType type,
+ float64 progress) {
+ const auto parent = parentWidget();
+ const auto me = Ui::MapFrom(_outerContainer, parent, geometry());
+ const auto anyTop = me.y() - st::historyRecordLockPosition.y();
+ if (type == TTLAnimationType::RightLeft) {
+ const auto finalRight = _outerContainer->width()
+ - rect::right(me)
+ + st::historyRecordLockPosition.x();
+
+ const auto from = -_ttlButton->width();
+ const auto right = anim::interpolate(from, finalRight, progress);
+ _ttlButton->moveToRight(right, _ttlButton->y());
+ } else if (type == TTLAnimationType::TopBottom) {
+ const auto ttlFrom = anyTop - _ttlButton->height() * 2;
+ const auto ttlTo = anyTop - _lock->height();
+ _ttlButton->moveToLeft(
+ _ttlButton->x(),
+ anim::interpolate(ttlFrom, ttlTo, 1. - progress));
+ } else if (type == TTLAnimationType::RightTopStatic) {
+ _ttlButton->moveToRight(
+ -_ttlButton->width(),
+ anyTop - _ttlButton->height() * 2);
+ }
+}
+
void VoiceRecordBar::init() {
if (_st.radius > 0) {
_backgroundRect.emplace(_st.radius, _st.bg);
@@ -1149,7 +1287,7 @@ void VoiceRecordBar::init() {
paintRequest(
) | rpl::start_with_next([=](const QRect &clip) {
- Painter p(this);
+ auto p = QPainter(this);
if (_showAnimation.animating()) {
p.setOpacity(showAnimationRatio());
}
@@ -1224,6 +1362,7 @@ void VoiceRecordBar::init() {
if (to == value) {
_recordingLifetime.destroy();
}
+ updateTTLGeometry(TTLAnimationType::TopBottom, 1. - value);
};
_showListenAnimation.start(std::move(callback), 0., to, duration);
}, lifetime());
@@ -1233,6 +1372,11 @@ void VoiceRecordBar::init() {
_lock->locks(
) | rpl::start_with_next([=] {
+ if (_hasTTLFilter && _hasTTLFilter()) {
+ _ttlButton->show();
+ }
+ updateTTLGeometry(TTLAnimationType::RightTopStatic, 0);
+
_level->setType(VoiceRecordButton::Type::Send);
_level->clicks(
@@ -1254,6 +1398,7 @@ void VoiceRecordBar::init() {
auto callback = [=](float64 value) {
_lock->requestPaintLockToStopProgress(value);
update();
+ updateTTLGeometry(TTLAnimationType::RightLeft, value);
};
_lockToStopAnimation.start(std::move(callback), from, to, duration);
}, lifetime());
@@ -1329,6 +1474,9 @@ void VoiceRecordBar::visibilityAnimate(bool show, Fn &&callback) {
_listen->requestPaintProgress(value);
}
update();
+ if (!show) {
+ updateTTLGeometry(TTLAnimationType::RightLeft, value);
+ }
if ((show && value == 1.) || (!show && value == 0.)) {
if (callback) {
callback();
@@ -1338,10 +1486,14 @@ void VoiceRecordBar::visibilityAnimate(bool show, Fn &&callback) {
_showAnimation.start(std::move(animationCallback), from, to, duration);
}
-void VoiceRecordBar::setStartRecordingFilter(Fn &&callback) {
+void VoiceRecordBar::setStartRecordingFilter(FilterCallback &&callback) {
_startRecordingFilter = std::move(callback);
}
+void VoiceRecordBar::setTTLFilter(FilterCallback &&callback) {
+ _hasTTLFilter = std::move(callback);
+}
+
void VoiceRecordBar::initLockGeometry() {
rpl::combine(
_lock->heightValue(),
@@ -1476,6 +1628,7 @@ void VoiceRecordBar::hideFast() {
hide();
_lock->hide();
_level->hide();
+ [[maybe_unused]] const auto s = takeTTLState();
}
void VoiceRecordBar::stopRecording(StopType type) {
@@ -1498,18 +1651,30 @@ void VoiceRecordBar::stopRecording(StopType type) {
const auto duration = Duration(data.samples);
if (type == StopType::Send) {
+ const auto options = Api::SendOptions{
+ .ttlSeconds = takeTTLState()
+ ? std::numeric_limits::max()
+ : 0
+ };
+
auto settings = &AyuSettings::getInstance();
auto sendVoiceCallback = crl::guard(this, [=, this]
{
- _sendVoiceRequests.fire({data.bytes, data.waveform, duration});
+ _sendVoiceRequests.fire({
+ data.bytes,
+ data.waveform,
+ duration,
+ options,
+ });
});
if (settings->voiceConfirmation) {
- Ui::show(AyuUi::MakeConfirmBox({
- .text = tr::ayu_ConfirmationVoice(),
- .confirmed = sendVoiceCallback,
- .confirmText = tr::lng_send_button()
- }));
+ Ui::show(AyuUi::MakeConfirmBox(
+ {
+ .text = tr::ayu_ConfirmationVoice(),
+ .confirmed = sendVoiceCallback,
+ .confirmText = tr::lng_send_button()
+ }));
}
else {
sendVoiceCallback();
@@ -1528,7 +1693,7 @@ void VoiceRecordBar::stopRecording(StopType type) {
}));
}
-void VoiceRecordBar::drawDuration(Painter &p) {
+void VoiceRecordBar::drawDuration(QPainter &p) {
const auto duration = FormatVoiceDuration(_recordingSamples);
p.setFont(_cancelFont);
p.setPen(_st.durationFg);
@@ -1551,8 +1716,8 @@ void VoiceRecordBar::startRedCircleAnimation() {
animation->start();
}
-void VoiceRecordBar::drawRedCircle(Painter &p) {
- PainterHighQualityEnabler hq(p);
+void VoiceRecordBar::drawRedCircle(QPainter &p) {
+ auto hq = PainterHighQualityEnabler(p);
p.setPen(Qt::NoPen);
p.setBrush(st::historyRecordVoiceFgInactive);
@@ -1564,18 +1729,18 @@ void VoiceRecordBar::drawRedCircle(Painter &p) {
p.setOpacity(opacity);
}
-void VoiceRecordBar::drawMessage(Painter &p, float64 recordActive) {
+void VoiceRecordBar::drawMessage(QPainter &p, float64 recordActive) {
p.setPen(anim::pen(_st.cancel, _st.cancelActive, 1. - recordActive));
const auto opacity = p.opacity();
p.setOpacity(opacity * (1. - _lock->lockToStopProgress()));
- _message.draw(
- p,
- _messageRect.x(),
- _messageRect.y(),
- _messageRect.width(),
- style::al_center);
+ _message.draw(p, {
+ .position = _messageRect.topLeft(),
+ .outerWidth = _messageRect.width(),
+ .availableWidth = _messageRect.width(),
+ .align = style::al_center,
+ });
p.setOpacity(opacity);
}
@@ -1583,23 +1748,28 @@ void VoiceRecordBar::drawMessage(Painter &p, float64 recordActive) {
void VoiceRecordBar::requestToSendWithOptions(Api::SendOptions options) {
if (isListenState()) {
const auto data = _listen->data();
+ if (takeTTLState()) {
+ options.ttlSeconds = std::numeric_limits::max();
+ }
+
auto settings = &AyuSettings::getInstance();
auto sendVoiceCallback = crl::guard(this, [=, this]
{
_sendVoiceRequests.fire({
- data->bytes,
- data->waveform,
- Duration(data->samples),
- options
- });
+ data->bytes,
+ data->waveform,
+ Duration(data->samples),
+ options,
+ });
});
if (settings->voiceConfirmation) {
- Ui::show(AyuUi::MakeConfirmBox({
- .text = tr::ayu_ConfirmationVoice(),
- .confirmed = sendVoiceCallback,
- .confirmText = tr::lng_send_button()
- }));
+ Ui::show(AyuUi::MakeConfirmBox(
+ {
+ .text = tr::ayu_ConfirmationVoice(),
+ .confirmed = sendVoiceCallback,
+ .confirmText = tr::lng_send_button()
+ }));
}
else {
sendVoiceCallback();
@@ -1722,6 +1892,12 @@ void VoiceRecordBar::computeAndSetLockProgress(QPoint globalPos) {
_lock->requestPaintProgress(Progress(localPos.y(), higher - lower));
}
+bool VoiceRecordBar::takeTTLState() const {
+ const auto hasTtl = !_ttlButton->isDisabled();
+ _ttlButton->clearState();
+ return hasTtl;
+}
+
void VoiceRecordBar::orderControls() {
stackUnder(_send.get());
_lock->raise();
diff --git a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.h b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.h
index 09c491678..31c0eb30e 100644
--- a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.h
+++ b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.h
@@ -21,6 +21,7 @@ struct RecordBar;
} // namespace style
namespace Ui {
+class AbstractButton;
class SendButton;
} // namespace Ui
@@ -53,6 +54,7 @@ class VoiceRecordBar final : public Ui::RpWidget {
public:
using SendActionUpdate = Controls::SendActionUpdate;
using VoiceToSend = Controls::VoiceToSend;
+ using FilterCallback = Fn;
VoiceRecordBar(
not_null parent,
@@ -87,7 +89,8 @@ public:
void requestToSendWithOptions(Api::SendOptions options);
- void setStartRecordingFilter(Fn &&callback);
+ void setStartRecordingFilter(FilterCallback &&callback);
+ void setTTLFilter(FilterCallback &&callback);
[[nodiscard]] bool isRecording() const;
[[nodiscard]] bool isRecordingLocked() const;
@@ -103,46 +106,56 @@ private:
Listen,
};
+ enum class TTLAnimationType {
+ RightLeft,
+ TopBottom,
+ RightTopStatic,
+ };
+
void init();
void initLockGeometry();
void initLevelGeometry();
void updateMessageGeometry();
void updateLockGeometry();
+ void updateTTLGeometry(TTLAnimationType type, float64 progress);
void recordUpdated(quint16 level, int samples);
- bool recordingAnimationCallback(crl::time now);
+ [[nodiscard]] bool recordingAnimationCallback(crl::time now);
void stop(bool send);
void stopRecording(StopType type);
void visibilityAnimate(bool show, Fn &&callback);
- bool showRecordButton() const;
- void drawDuration(Painter &p);
- void drawRedCircle(Painter &p);
- void drawMessage(Painter &p, float64 recordActive);
+ [[nodiscard]] bool showRecordButton() const;
+ void drawDuration(QPainter &p);
+ void drawRedCircle(QPainter &p);
+ void drawMessage(QPainter &p, float64 recordActive);
void startRedCircleAnimation();
void installListenStateFilter();
- bool isTypeRecord() const;
- bool hasDuration() const;
+ [[nodiscard]] bool isTypeRecord() const;
+ [[nodiscard]] bool hasDuration() const;
void finish();
void activeAnimate(bool active);
- float64 showAnimationRatio() const;
- float64 showListenAnimationRatio() const;
- float64 activeAnimationRatio() const;
+ [[nodiscard]] float64 showAnimationRatio() const;
+ [[nodiscard]] float64 showListenAnimationRatio() const;
+ [[nodiscard]] float64 activeAnimationRatio() const;
void computeAndSetLockProgress(QPoint globalPos);
+ [[nodiscard]] bool takeTTLState() const;
+
const style::RecordBar &_st;
const not_null _outerContainer;
const std::shared_ptr _show;
const std::shared_ptr _send;
const std::unique_ptr _lock;
+ const std::unique_ptr _ttlButton;
const std::unique_ptr _level;
const std::unique_ptr _cancel;
std::unique_ptr _listen;
@@ -161,7 +174,8 @@ private:
Ui::Text::String _message;
- Fn _startRecordingFilter;
+ FilterCallback _startRecordingFilter;
+ FilterCallback _hasTTLFilter;
bool _warningShown = false;
diff --git a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp
index 8d787b017..e6190c78c 100644
--- a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp
+++ b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp
@@ -225,7 +225,7 @@ void AddSaveDocumentAction(
HistoryItem *item,
not_null document,
not_null list) {
- if (list->hasCopyMediaRestriction(item)) {
+ if (list->hasCopyMediaRestriction(item) || ItemHasTtl(item)) {
return;
}
const auto origin = item ? item->fullId() : FullMsgId();
@@ -561,7 +561,7 @@ bool AddRescheduleAction(
? SendMenu::Type::Reminder
: HistoryView::CanScheduleUntilOnline(peer)
? SendMenu::Type::ScheduledToUser
- : SendMenu::Type::Scheduled;
+ : SendMenu::Type::Disabled;
const auto itemDate = firstItem->date();
const auto date = (itemDate == Api::kScheduledUntilOnlineTimestamp)
@@ -1244,6 +1244,9 @@ void AddSaveSoundForNotifications(
not_null item,
not_null document,
not_null controller) {
+ if (ItemHasTtl(item)) {
+ return;
+ }
const auto &ringtones = document->session().api().ringtones();
if (document->size > ringtones.maxSize()) {
return;
@@ -1546,4 +1549,10 @@ TextWithEntities TransribedText(not_null item) {
return {};
}
+bool ItemHasTtl(HistoryItem *item) {
+ return (item && item->media())
+ ? (item->media()->ttlSeconds() > 0)
+ : false;
+}
+
} // namespace HistoryView
diff --git a/Telegram/SourceFiles/history/view/history_view_context_menu.h b/Telegram/SourceFiles/history/view/history_view_context_menu.h
index 53a45e36c..4979a6789 100644
--- a/Telegram/SourceFiles/history/view/history_view_context_menu.h
+++ b/Telegram/SourceFiles/history/view/history_view_context_menu.h
@@ -110,4 +110,6 @@ void AddEmojiPacksAction(
[[nodiscard]] TextWithEntities TransribedText(not_null item);
+[[nodiscard]] bool ItemHasTtl(HistoryItem *item);
+
} // namespace HistoryView
diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp
index b95dd5f0f..96c3173bb 100644
--- a/Telegram/SourceFiles/history/view/history_view_element.cpp
+++ b/Telegram/SourceFiles/history/view/history_view_element.cpp
@@ -276,6 +276,9 @@ QString DateTooltipText(not_null view) {
msgsigned->postAuthor);
}
}
+ if (item->isScheduled() && item->isSilent()) {
+ dateText += '\n' + QChar(0xD83D) + QChar(0xDD15);
+ }
if (!item->isLocal()) { // local messages have strange ID
dateText += '\n';
dateText += "ID: ";
diff --git a/Telegram/SourceFiles/history/view/history_view_reply.cpp b/Telegram/SourceFiles/history/view/history_view_reply.cpp
index 619e9ac6d..e568b5ac2 100644
--- a/Telegram/SourceFiles/history/view/history_view_reply.cpp
+++ b/Telegram/SourceFiles/history/view/history_view_reply.cpp
@@ -738,7 +738,11 @@ void Reply::paint(
const auto textw = w
- st::historyReplyPadding.left()
- st::historyReplyPadding.right();
- const auto namew = textw - previewSkip;
+ const auto namew = textw
+ - previewSkip
+ - (_hasQuoteIcon
+ ? st::messageTextStyle.blockquote.icon.width()
+ : 0);
auto firstLineSkip = _nameTwoLines ? 0 : previewSkip;
if (namew > 0) {
p.setPen(!inBubble
diff --git a/Telegram/SourceFiles/history/view/history_view_schedule_box.cpp b/Telegram/SourceFiles/history/view/history_view_schedule_box.cpp
index 286edd189..c5e60091d 100644
--- a/Telegram/SourceFiles/history/view/history_view_schedule_box.cpp
+++ b/Telegram/SourceFiles/history/view/history_view_schedule_box.cpp
@@ -93,9 +93,10 @@ void ScheduleBox(
.style = style.chooseDateTimeArgs,
});
+ using T = SendMenu::Type;
SendMenu::SetupMenuAndShortcuts(
descriptor.submit.data(),
- [=] { return SendMenu::Type::SilentOnly; },
+ [t = type == T::Disabled ? T::Disabled : T::SilentOnly] { return t; },
[=] { save(true, descriptor.collect()); },
nullptr,
nullptr);
diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_document.cpp
index e3e2808cd..7ca7bc747 100644
--- a/Telegram/SourceFiles/history/view/media/history_view_document.cpp
+++ b/Telegram/SourceFiles/history/view/media/history_view_document.cpp
@@ -23,24 +23,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_cursor_state.h"
#include "history/view/history_view_transcribe_button.h"
#include "history/view/media/history_view_media_common.h"
-#include "ui/image/image.h"
#include "ui/text/format_values.h"
#include "ui/text/format_song_document_name.h"
#include "ui/text/text_utilities.h"
-#include "ui/chat/message_bubble.h"
#include "ui/chat/chat_style.h"
-#include "ui/cached_round_corners.h"
#include "ui/painter.h"
#include "ui/power_saving.h"
#include "ui/rect.h"
-#include "ui/ui_utility.h"
#include "data/data_session.h"
#include "data/data_document.h"
#include "data/data_document_media.h"
#include "data/data_document_resolver.h"
-#include "data/data_media_types.h"
#include "data/data_file_click_handler.h"
-#include "data/data_file_origin.h"
#include "api/api_transcribes.h"
#include "apiwrap.h"
#include "styles/style_chat.h"
@@ -53,30 +47,36 @@ constexpr auto kAudioVoiceMsgUpdateView = crl::time(100);
void DrawCornerBadgeTTL(
QPainter &p,
- const style::color &color,
+ const style::color &bg,
+ const style::color &fg,
const QRect &circleRect) {
p.save();
- const auto partRect = QRect(
- circleRect.left() + circleRect.width() - st::dialogsTTLBadgeSize * 0.85,
- circleRect.top() + circleRect.height() - st::dialogsTTLBadgeSize * 0.85,
+ const auto partRect = QRectF(
+ rect::right(circleRect)
+ - st::dialogsTTLBadgeSize
+ + rect::m::sum::h(st::dialogsTTLBadgeInnerMargins),
+ rect::bottom(circleRect)
+ - st::dialogsTTLBadgeSize
+ + rect::m::sum::v(st::dialogsTTLBadgeInnerMargins),
st::dialogsTTLBadgeSize,
st::dialogsTTLBadgeSize);
auto hq = PainterHighQualityEnabler(p);
- p.setBrush(color);
+ p.setPen(Qt::NoPen);
+ p.setBrush(bg);
p.drawEllipse(partRect);
const auto innerRect = partRect - st::dialogsTTLBadgeInnerMargins;
const auto ttlText = u"1"_q;
p.setFont(st::dialogsScamFont);
- p.setPen(st::premiumButtonFg);
+ p.setPen(fg);
p.drawText(innerRect, ttlText, style::al_center);
constexpr auto kPenWidth = 1.5;
const auto penWidth = style::ConvertScaleExact(kPenWidth);
- auto pen = QPen(st::premiumButtonFg);
+ auto pen = QPen(fg);
pen.setJoinStyle(Qt::RoundJoin);
pen.setCapStyle(Qt::RoundCap);
pen.setWidthF(penWidth);
@@ -86,7 +86,7 @@ void DrawCornerBadgeTTL(
p.drawArc(innerRect, arc::kQuarterLength, arc::kHalfLength);
p.setClipRect(innerRect
- - QMargins(innerRect.width() / 2, 0, -penWidth, -penWidth));
+ - QMarginsF(innerRect.width() / 2, -penWidth, -penWidth, -penWidth));
pen.setStyle(Qt::DotLine);
p.setPen(pen);
p.drawEllipse(innerRect);
@@ -139,6 +139,29 @@ void DrawCornerBadgeTTL(
};
}
+void FillThumbnailOverlay(
+ QPainter &p,
+ QRect rect,
+ Ui::BubbleRounding rounding,
+ const PaintContext &context) {
+ using Corner = Ui::BubbleCornerRounding;
+ using Radius = Ui::CachedCornerRadius;
+ auto corners = Ui::CornersPixmaps();
+ const auto &st = context.st;
+ const auto lookup = [&](Corner corner) {
+ switch (corner) {
+ case Corner::None: return Radius::Small;
+ case Corner::Small: return Radius::ThumbSmall;
+ case Corner::Large: return Radius::ThumbLarge;
+ }
+ Unexpected("Corner value in FillThumbnailOverlay.");
+ };
+ for (auto i = 0; i != 4; ++i) {
+ corners.p[i] = st->msgSelectOverlayCorners(lookup(rounding[i])).p[i];
+ }
+ Ui::FillComplexOverlayRect(p, rect, st->msgSelectOverlay(), corners);
+}
+
[[nodiscard]] QString CleanTagSymbols(const QString &value) {
auto result = QString();
const auto begin = value.begin(), end = value.end();
@@ -323,7 +346,8 @@ Document::Document(
::Media::Player::instance()->tracksFinished(
) | rpl::filter([=](AudioMsgId::Type type) {
return (type == AudioMsgId::Type::Voice);
- }) | rpl::to_empty
+ }) | rpl::to_empty,
+ ::Media::Player::instance()->stops(AudioMsgId::Type::Voice)
) | rpl::start_with_next([=]() mutable {
_drawTtl = nullptr;
const auto item = _parent->data();
@@ -642,7 +666,7 @@ void Document::draw(
validateThumbnail(thumbed, st.thumbSize, rounding);
p.drawImage(rthumb, thumbed->thumbnail);
if (context.selected()) {
- fillThumbnailOverlay(p, rthumb, rounding, context);
+ FillThumbnailOverlay(p, rthumb, rounding, context);
}
if (radial || (!loaded && !_data->loading()) || _data->waitingForAlbum()) {
@@ -718,10 +742,6 @@ void Document::draw(
PainterHighQualityEnabler hq(p);
p.setBrush(stm->msgFileBg);
p.drawEllipse(inner);
-
- if (_parent->data()->media()->ttlSeconds()) {
- DrawCornerBadgeTTL(p, stm->msgFileBg, inner);
- }
}
}
@@ -898,6 +918,12 @@ void Document::draw(
.highlight = highlightRequest ? &*highlightRequest : nullptr,
});
}
+ if (_parent->data()->media() && _parent->data()->media()->ttlSeconds()) {
+ const auto &fg = context.outbg
+ ? st::historyFileOutIconFg
+ : st::historyFileInIconFg;
+ DrawCornerBadgeTTL(p, stm->msgFileBg, fg, inner);
+ }
}
Ui::BubbleRounding Document::thumbRounding(
@@ -962,29 +988,6 @@ void Document::validateThumbnail(
thumbed->rounding = rounding;
}
-void Document::fillThumbnailOverlay(
- QPainter &p,
- QRect rect,
- Ui::BubbleRounding rounding,
- const PaintContext &context) const {
- using Corner = Ui::BubbleCornerRounding;
- using Radius = Ui::CachedCornerRadius;
- auto corners = Ui::CornersPixmaps();
- const auto &st = context.st;
- const auto lookup = [&](Corner corner) {
- switch (corner) {
- case Corner::None: return Radius::Small;
- case Corner::Small: return Radius::ThumbSmall;
- case Corner::Large: return Radius::ThumbLarge;
- }
- Unexpected("Corner value in Document::fillThumbnailOverlay.");
- };
- for (auto i = 0; i != 4; ++i) {
- corners.p[i] = st->msgSelectOverlayCorners(lookup(rounding[i])).p[i];
- }
- Ui::FillComplexOverlayRect(p, rect, st->msgSelectOverlay(), corners);
-}
-
bool Document::hasHeavyPart() const {
return (_dataMedia != nullptr);
}
@@ -1701,7 +1704,7 @@ bool DrawThumbnailAsSongCover(
const style::color &colored,
const std::shared_ptr &dataMedia,
const QRect &rect,
- const bool selected) {
+ bool selected) {
if (!dataMedia) {
return false;
}
diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.h b/Telegram/SourceFiles/history/view/media/history_view_document.h
index 5e57308ed..5fa8dc1da 100644
--- a/Telegram/SourceFiles/history/view/media/history_view_document.h
+++ b/Telegram/SourceFiles/history/view/media/history_view_document.h
@@ -17,11 +17,9 @@ namespace Data {
class DocumentMedia;
} // namespace Data
-namespace Ui {
-namespace Text {
+namespace Ui::Text {
class String;
-} // namespace Text
-} // namespace Ui
+} // namespace Ui::Text
namespace HistoryView {
@@ -101,11 +99,6 @@ protected:
bool dataLoaded() const override;
private:
- struct StateFromPlayback {
- int64 statusSize = 0;
- bool showPause = false;
- TimeId realDuration = 0;
- };
enum class LayoutMode {
Full,
Grouped,
@@ -139,11 +132,6 @@ private:
not_null thumbed,
int size,
Ui::BubbleRounding rounding) const;
- void fillThumbnailOverlay(
- QPainter &p,
- QRect rect,
- Ui::BubbleRounding rounding,
- const PaintContext &context) const;
void setStatusSize(int64 newSize, TimeId realDuration = 0) const;
bool updateStatusText() const; // returns showPause
@@ -191,6 +179,6 @@ bool DrawThumbnailAsSongCover(
const style::color &colored,
const std::shared_ptr &dataMedia,
const QRect &rect,
- const bool selected = false);
+ bool selected = false);
} // namespace HistoryView
diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp
index 4855c4368..3f1c1864d 100644
--- a/Telegram/SourceFiles/mainwidget.cpp
+++ b/Telegram/SourceFiles/mainwidget.cpp
@@ -755,7 +755,6 @@ void MainWidget::handleAudioUpdate(const Media::Player::TrackState &state) {
const auto item = session().data().message(state.id.contextId());
if (!Media::Player::IsStoppedOrStopping(state.state)) {
const auto ttlSeconds = item
- && !item->out()
&& item->media()
&& item->media()->ttlSeconds();
if (!ttlSeconds) {
diff --git a/Telegram/SourceFiles/payments/ui/payments_panel.cpp b/Telegram/SourceFiles/payments/ui/payments_panel.cpp
index 5e5c872de..bc2817d52 100644
--- a/Telegram/SourceFiles/payments/ui/payments_panel.cpp
+++ b/Telegram/SourceFiles/payments/ui/payments_panel.cpp
@@ -96,7 +96,7 @@ Panel::Panel(not_null delegate)
}
Panel::~Panel() {
- _webview = nullptr;
+ base::take(_webview);
_progress = nullptr;
_widget = nullptr;
}
@@ -528,6 +528,7 @@ bool Panel::createWebview(const Webview::ThemeParams ¶ms) {
auto outer = base::make_unique_q(_widget.get());
const auto container = outer.get();
_widget->showInner(std::move(outer));
+ const auto webviewParent = QPointer(container);
_webviewBottom = std::make_unique(_widget.get());
const auto bottom = _webviewBottom.get();
@@ -552,7 +553,7 @@ bool Panel::createWebview(const Webview::ThemeParams ¶ms) {
const auto raw = &_webview->window;
QObject::connect(container, &QObject::destroyed, [=] {
if (_webview && &_webview->window == raw) {
- _webview = nullptr;
+ base::take(_webview);
if (_webviewProgress) {
hideWebviewProgress();
if (_progress && !_progress->shown) {
@@ -568,6 +569,16 @@ bool Panel::createWebview(const Webview::ThemeParams ¶ms) {
return false;
}
QObject::connect(raw->widget(), &QObject::destroyed, [=] {
+ const auto parent = webviewParent.data();
+ if (!_webview
+ || &_webview->window != raw
+ || !parent
+ || _widget->inner() != parent) {
+ // If we destroyed _webview ourselves,
+ // or if we changed _widget->inner ourselves,
+ // we don't show any message, nothing crashed.
+ return;
+ }
crl::on_main(this, [=] {
showCriticalError({ "Error: WebView has crashed." });
});
diff --git a/Telegram/SourceFiles/platform/win/integration_win.cpp b/Telegram/SourceFiles/platform/win/integration_win.cpp
index b8d53a506..3d8b592e7 100644
--- a/Telegram/SourceFiles/platform/win/integration_win.cpp
+++ b/Telegram/SourceFiles/platform/win/integration_win.cpp
@@ -7,17 +7,24 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "platform/win/integration_win.h"
-#include "platform/platform_integration.h"
-#include "platform/platform_specific.h"
+#include "base/platform/win/base_windows_winrt.h"
#include "core/application.h"
#include "core/core_settings.h"
#include "core/sandbox.h"
+#include "lang/lang_keys.h"
+#include "platform/win/windows_app_user_model_id.h"
+#include "platform/win/tray_win.h"
+#include "platform/platform_integration.h"
+#include "platform/platform_specific.h"
#include "tray.h"
-#include "base/platform/win/base_windows_winrt.h"
+#include "styles/style_window.h"
#include
#include
+#include
+#include
+
namespace Platform {
void WindowsIntegration::init() {
@@ -48,6 +55,78 @@ bool WindowsIntegration::nativeEventFilter(
});
}
+void WindowsIntegration::createCustomJumpList() {
+ _jumpList = base::WinRT::TryCreateInstance(
+ CLSID_DestinationList);
+ if (_jumpList) {
+ refreshCustomJumpList();
+ }
+}
+
+void WindowsIntegration::refreshCustomJumpList() {
+ auto added = false;
+ auto maxSlots = UINT();
+ auto removed = (IObjectArray*)nullptr;
+ auto hr = _jumpList->BeginList(&maxSlots, IID_PPV_ARGS(&removed));
+ if (!SUCCEEDED(hr)) {
+ return;
+ }
+ const auto guard = gsl::finally([&] {
+ if (added) {
+ _jumpList->CommitList();
+ } else {
+ _jumpList->AbortList();
+ }
+ });
+
+ auto shellLink = base::WinRT::TryCreateInstance(
+ CLSID_ShellLink);
+ if (!shellLink) {
+ return;
+ }
+
+ // Set the path to your application and the command-line argument for quitting
+ const auto exe = QDir::toNativeSeparators(cExeDir() + cExeName());
+ const auto dir = QDir::toNativeSeparators(QDir(cWorkingDir()).absolutePath());
+ const auto icon = Tray::QuitJumpListIconPath();
+ shellLink->SetArguments(L"-quit");
+ shellLink->SetPath(exe.toStdWString().c_str());
+ shellLink->SetWorkingDirectory(dir.toStdWString().c_str());
+ shellLink->SetIconLocation(icon.toStdWString().c_str(), 0);
+
+ if (const auto propertyStore = shellLink.try_as()) {
+ auto appIdPropVar = PROPVARIANT();
+ hr = InitPropVariantFromString(
+ AppUserModelId::Id().c_str(),
+ &appIdPropVar);
+ if (SUCCEEDED(hr)) {
+ hr = propertyStore->SetValue(
+ AppUserModelId::Key(),
+ appIdPropVar);
+ PropVariantClear(&appIdPropVar);
+ }
+ auto titlePropVar = PROPVARIANT();
+ hr = InitPropVariantFromString(
+ tr::lng_quit_from_tray(tr::now).toStdWString().c_str(),
+ &titlePropVar);
+ if (SUCCEEDED(hr)) {
+ hr = propertyStore->SetValue(PKEY_Title, titlePropVar);
+ PropVariantClear(&titlePropVar);
+ }
+ propertyStore->Commit();
+ }
+
+ auto collection = base::WinRT::TryCreateInstance(
+ CLSID_EnumerableObjectCollection);
+ if (!collection) {
+ return;
+ }
+ collection->AddObject(shellLink.get());
+
+ _jumpList->AddUserTasks(collection.get());
+ added = true;
+}
+
bool WindowsIntegration::processEvent(
HWND hWnd,
UINT msg,
@@ -58,6 +137,9 @@ bool WindowsIntegration::processEvent(
_taskbarList = base::WinRT::TryCreateInstance(
CLSID_TaskbarList,
CLSCTX_ALL);
+ if (_taskbarList) {
+ createCustomJumpList();
+ }
}
switch (msg) {
@@ -80,10 +162,14 @@ bool WindowsIntegration::processEvent(
break;
case WM_SETTINGCHANGE:
+ RefreshTaskbarThemeValue();
#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0)
Core::App().settings().setSystemDarkMode(Platform::IsDarkMode());
#endif // Qt < 6.5.0
Core::App().tray().updateIconCounters();
+ if (_jumpList) {
+ refreshCustomJumpList();
+ }
break;
}
return false;
diff --git a/Telegram/SourceFiles/platform/win/integration_win.h b/Telegram/SourceFiles/platform/win/integration_win.h
index dae978411..0b29007d3 100644
--- a/Telegram/SourceFiles/platform/win/integration_win.h
+++ b/Telegram/SourceFiles/platform/win/integration_win.h
@@ -37,8 +37,12 @@ private:
LPARAM lParam,
LRESULT *result);
+ void createCustomJumpList();
+ void refreshCustomJumpList();
+
uint32 _taskbarCreatedMsgId = 0;
winrt::com_ptr _taskbarList;
+ winrt::com_ptr _jumpList;
};
diff --git a/Telegram/SourceFiles/platform/win/specific_win.cpp b/Telegram/SourceFiles/platform/win/specific_win.cpp
index 71a47067d..bbb17458d 100644
--- a/Telegram/SourceFiles/platform/win/specific_win.cpp
+++ b/Telegram/SourceFiles/platform/win/specific_win.cpp
@@ -195,8 +195,7 @@ bool ManageAppLink(
return true;
}
const auto shellLink = base::WinRT::TryCreateInstance(
- CLSID_ShellLink,
- CLSCTX_INPROC_SERVER);
+ CLSID_ShellLink);
if (!shellLink) {
if (!silent) LOG(("App Error: could not create instance of IID_IShellLink %1").arg(hr));
return false;
diff --git a/Telegram/SourceFiles/platform/win/tray_win.cpp b/Telegram/SourceFiles/platform/win/tray_win.cpp
index 1ad1f4f23..5ef4ea452 100644
--- a/Telegram/SourceFiles/platform/win/tray_win.cpp
+++ b/Telegram/SourceFiles/platform/win/tray_win.cpp
@@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include
#include
#include
+#include
// AyuGram includes
#include "ayu/ui/ayu_assets.h"
@@ -38,18 +39,10 @@ namespace {
constexpr auto kTooltipDelay = crl::time(10000);
-[[nodiscard]] std::optional IsDarkTaskbar() {
- static const auto kSystemVersion = QOperatingSystemVersion::current();
- static const auto kDarkModeAddedVersion = QOperatingSystemVersion(
- QOperatingSystemVersion::Windows,
- 10,
- 0,
- 18282);
- static const auto kSupported = (kSystemVersion >= kDarkModeAddedVersion);
- if (!kSupported) {
- return std::nullopt;
- }
+std::optional DarkTaskbar;
+bool DarkTasbarValueValid/* = false*/;
+[[nodiscard]] std::optional ReadDarkTaskbarValue() {
const auto keyName = L""
"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
const auto valueName = L"SystemUsesLightTheme";
@@ -69,6 +62,23 @@ constexpr auto kTooltipDelay = crl::time(10000);
return (value == 0);
}
+[[nodiscard]] std::optional IsDarkTaskbar() {
+ static const auto kSystemVersion = QOperatingSystemVersion::current();
+ static const auto kDarkModeAddedVersion = QOperatingSystemVersion(
+ QOperatingSystemVersion::Windows,
+ 10,
+ 0,
+ 18282);
+ static const auto kSupported = (kSystemVersion >= kDarkModeAddedVersion);
+ if (!kSupported) {
+ return std::nullopt;
+ } else if (!DarkTasbarValueValid) {
+ DarkTasbarValueValid = true;
+ DarkTaskbar = ReadDarkTaskbarValue();
+ }
+ return DarkTaskbar;
+}
+
[[nodiscard]] QImage MonochromeIconFor(int size, bool darkMode) {
Expects(size > 0);
@@ -353,8 +363,99 @@ QPixmap Tray::IconWithCounter(
monochrome));
}
+void WriteIco(const QString &path, std::vector images) {
+ Expects(!images.empty());
+
+ auto buffer = QByteArray();
+ const auto write = [&](auto value) {
+ buffer.append(reinterpret_cast(&value), sizeof(value));
+ };
+
+ const auto count = int(images.size());
+
+ auto full = 0;
+ auto pngs = std::vector();
+ pngs.reserve(count);
+ for (const auto &image : images) {
+ pngs.emplace_back();
+ {
+ auto buffer = QBuffer(&pngs.back());
+ image.save(&buffer, "PNG");
+ }
+ full += pngs.back().size();
+ }
+
+ // Images directory
+ constexpr auto entry = sizeof(int8)
+ + sizeof(int8)
+ + sizeof(int8)
+ + sizeof(int8)
+ + sizeof(int16)
+ + sizeof(int16)
+ + sizeof(uint32)
+ + sizeof(uint32);
+ static_assert(entry == 16);
+
+ auto offset = 3 * sizeof(int16) + count * entry;
+ full += offset;
+
+ buffer.reserve(full);
+
+ // Thanks https://stackoverflow.com/a/54289564/6509833
+ write(int16(0));
+ write(int16(1));
+ write(int16(count));
+
+ for (auto i = 0; i != count; ++i) {
+ const auto &image = images[i];
+ Assert(image.width() <= 256 && image.height() <= 256);
+
+ write(int8(image.width() == 256 ? 0 : image.width()));
+ write(int8(image.height() == 256 ? 0 : image.height()));
+ write(int8(0)); // palette size
+ write(int8(0)); // reserved
+ write(int16(1)); // color planes
+ write(int16(image.depth())); // bits-per-pixel
+ write(uint32(pngs[i].size())); // size of image in bytes
+ write(uint32(offset)); // offset
+ offset += pngs[i].size();
+ }
+ for (auto i = 0; i != count; ++i) {
+ buffer.append(pngs[i]);
+ }
+
+ auto f = QFile(path);
+ if (f.open(QIODevice::WriteOnly)) {
+ f.write(buffer);
+ }
+}
+
+QString Tray::QuitJumpListIconPath() {
+ const auto dark = IsDarkTaskbar();
+ const auto key = !dark ? 0 : *dark ? 1 : 2;
+ const auto path = cWorkingDir() + u"tdata/temp/quit_%1.ico"_q.arg(key);
+ if (QFile::exists(path)) {
+ return path;
+ }
+ const auto color = !dark
+ ? st::trayCounterBg->c
+ : *dark
+ ? QColor(255, 255, 255)
+ : QColor(0, 0, 0, 228);
+ WriteIco(path, {
+ st::winQuitIcon.instance(color, 100, true),
+ st::winQuitIcon.instance(color, 200, true),
+ st::winQuitIcon.instance(color, 300, true),
+ });
+ return path;
+}
+
bool HasMonochromeSetting() {
return IsDarkTaskbar().has_value();
}
+void RefreshTaskbarThemeValue() {
+ DarkTasbarValueValid = false;
+}
+
} // namespace Platform
diff --git a/Telegram/SourceFiles/platform/win/tray_win.h b/Telegram/SourceFiles/platform/win/tray_win.h
index 53631e556..cb79c3beb 100644
--- a/Telegram/SourceFiles/platform/win/tray_win.h
+++ b/Telegram/SourceFiles/platform/win/tray_win.h
@@ -59,6 +59,7 @@ public:
bool smallIcon,
bool monochrome,
bool supportMode);
+ [[nodiscard]] static QString QuitJumpListIconPath();
private:
base::unique_qptr _icon;
@@ -73,4 +74,6 @@ private:
};
+void RefreshTaskbarThemeValue();
+
} // namespace Platform
diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp
index 209444ff1..c94f26294 100644
--- a/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp
+++ b/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp
@@ -364,7 +364,7 @@ Panel::Panel(
}
Panel::~Panel() {
- _webview = nullptr;
+ base::take(_webview);
_progress = nullptr;
_widget = nullptr;
}
@@ -587,7 +587,7 @@ bool Panel::createWebview(const Webview::ThemeParams ¶ms) {
QObject::connect(container, &QObject::destroyed, [=] {
if (_webview && &_webview->window == raw) {
- _webview = nullptr;
+ base::take(_webview);
if (_webviewProgress) {
hideWebviewProgress();
if (_progress && !_progress->shown) {
@@ -604,6 +604,16 @@ bool Panel::createWebview(const Webview::ThemeParams ¶ms) {
return false;
}
QObject::connect(raw->widget(), &QObject::destroyed, [=] {
+ const auto parent = _webviewParent.data();
+ if (!_webview
+ || &_webview->window != raw
+ || !parent
+ || _widget->inner() != parent) {
+ // If we destroyed _webview ourselves,
+ // or if we changed _widget->inner ourselves,
+ // we don't show any message, nothing crashed.
+ return;
+ }
crl::on_main(this, [=] {
showCriticalError({ "Error: WebView has crashed." });
});
diff --git a/Telegram/SourceFiles/window/window.style b/Telegram/SourceFiles/window/window.style
index d15a67a4e..38621c69b 100644
--- a/Telegram/SourceFiles/window/window.style
+++ b/Telegram/SourceFiles/window/window.style
@@ -317,6 +317,10 @@ windowArchiveToast: Toast(defaultToast) {
maxWidth: boxWideWidth;
}
+// Windows specific
+
+winQuitIcon: icon {{ "win_quit", windowFg }};
+
// Mac specific
macAccessoryWidth: 450.;
diff --git a/Telegram/ThirdParty/minizip/crypt.h b/Telegram/ThirdParty/minizip/crypt.h
index 1cc41f19d..f4b93b78d 100644
--- a/Telegram/ThirdParty/minizip/crypt.h
+++ b/Telegram/ThirdParty/minizip/crypt.h
@@ -32,8 +32,7 @@
/***********************************************************************
* Return the next byte in the pseudo-random sequence
*/
-static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab)
-{
+static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab) {
unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
* unpredictable manner on 16-bit systems; not a problem
* with any known compiler so far, though */
@@ -46,8 +45,7 @@ static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab)
/***********************************************************************
* Update the encryption keys with the next byte of plain text
*/
-static int update_keys(unsigned long* pkeys,const z_crc_t* pcrc_32_tab,int c)
-{
+static int update_keys(unsigned long* pkeys, const z_crc_t* pcrc_32_tab, int c) {
(*(pkeys+0)) = CRC32((*(pkeys+0)), c);
(*(pkeys+1)) += (*(pkeys+0)) & 0xff;
(*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
@@ -63,8 +61,7 @@ static int update_keys(unsigned long* pkeys,const z_crc_t* pcrc_32_tab,int c)
* Initialize the encryption keys and the random header according to
* the given password.
*/
-static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t* pcrc_32_tab)
-{
+static void init_keys(const char* passwd, unsigned long* pkeys, const z_crc_t* pcrc_32_tab) {
*(pkeys+0) = 305419896L;
*(pkeys+1) = 591751049L;
*(pkeys+2) = 878082192L;
@@ -93,8 +90,7 @@ static unsigned crypthead(const char* passwd, /* password string */
int bufSize,
unsigned long* pkeys,
const z_crc_t* pcrc_32_tab,
- unsigned long crcForCrypting)
-{
+ unsigned long crcForCrypting) {
unsigned n; /* index in random header */
int t; /* temporary */
int c; /* random byte */
diff --git a/Telegram/ThirdParty/minizip/ioapi.c b/Telegram/ThirdParty/minizip/ioapi.c
index 0ca29db6a..782d32469 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__) || defined(MINIZIP_FOPEN_NO_64)
// 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)
@@ -28,8 +28,7 @@
#include "ioapi.h"
-voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)
-{
+voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc, const void*filename, int mode) {
if (pfilefunc->zfile_func64.zopen64_file != NULL)
return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode);
else
@@ -38,8 +37,7 @@ voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename
}
}
-long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)
-{
+long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) {
if (pfilefunc->zfile_func64.zseek64_file != NULL)
return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
else
@@ -52,8 +50,7 @@ long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZP
}
}
-ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)
-{
+ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc, voidpf filestream) {
if (pfilefunc->zfile_func64.zseek64_file != NULL)
return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);
else
@@ -66,11 +63,9 @@ ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream
}
}
-void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)
-{
+void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32, const zlib_filefunc_def* p_filefunc32) {
p_filefunc64_32->zfile_func64.zopen64_file = NULL;
p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
- p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
p_filefunc64_32->zfile_func64.ztell64_file = NULL;
@@ -84,16 +79,7 @@ void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filef
-static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode));
-static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));
-static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size));
-static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream));
-static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
-static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream));
-static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream));
-
-static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode)
-{
+static voidpf ZCALLBACK fopen_file_func(voidpf opaque, const char* filename, int mode) {
FILE* file = NULL;
const char* mode_fopen = NULL;
(void)opaque;
@@ -111,8 +97,7 @@ static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, in
return file;
}
-static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode)
-{
+static voidpf ZCALLBACK fopen64_file_func(voidpf opaque, const void* filename, int mode) {
FILE* file = NULL;
const char* mode_fopen = NULL;
(void)opaque;
@@ -131,24 +116,21 @@ static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename,
}
-static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size)
-{
+static uLong ZCALLBACK fread_file_func(voidpf opaque, voidpf stream, void* buf, uLong size) {
uLong ret;
(void)opaque;
ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
return ret;
}
-static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size)
-{
+static uLong ZCALLBACK fwrite_file_func(voidpf opaque, voidpf stream, const void* buf, uLong size) {
uLong ret;
(void)opaque;
ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
return ret;
}
-static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
-{
+static long ZCALLBACK ftell_file_func(voidpf opaque, voidpf stream) {
long ret;
(void)opaque;
ret = ftell((FILE *)stream);
@@ -156,16 +138,14 @@ static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
}
-static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)
-{
+static ZPOS64_T ZCALLBACK ftell64_file_func(voidpf opaque, voidpf stream) {
ZPOS64_T ret;
(void)opaque;
ret = (ZPOS64_T)FTELLO_FUNC((FILE *)stream);
return ret;
}
-static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin)
-{
+static long ZCALLBACK fseek_file_func(voidpf opaque, voidpf stream, uLong offset, int origin) {
int fseek_origin=0;
long ret;
(void)opaque;
@@ -188,8 +168,7 @@ static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offs
return ret;
}
-static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)
-{
+static long ZCALLBACK fseek64_file_func(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) {
int fseek_origin=0;
long ret;
(void)opaque;
@@ -208,31 +187,28 @@ static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T
}
ret = 0;
- if(FSEEKO_FUNC((FILE *)stream, (z_off_t)offset, fseek_origin) != 0)
+ if(FSEEKO_FUNC((FILE *)stream, (z_off64_t)offset, fseek_origin) != 0)
ret = -1;
return ret;
}
-static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)
-{
+static int ZCALLBACK fclose_file_func(voidpf opaque, voidpf stream) {
int ret;
(void)opaque;
ret = fclose((FILE *)stream);
return ret;
}
-static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)
-{
+static int ZCALLBACK ferror_file_func(voidpf opaque, voidpf stream) {
int ret;
(void)opaque;
ret = ferror((FILE *)stream);
return ret;
}
-void fill_fopen_filefunc (zlib_filefunc_def* pzlib_filefunc_def)
-{
+void fill_fopen_filefunc(zlib_filefunc_def* pzlib_filefunc_def) {
pzlib_filefunc_def->zopen_file = fopen_file_func;
pzlib_filefunc_def->zread_file = fread_file_func;
pzlib_filefunc_def->zwrite_file = fwrite_file_func;
@@ -243,8 +219,7 @@ void fill_fopen_filefunc (zlib_filefunc_def* pzlib_filefunc_def)
pzlib_filefunc_def->opaque = NULL;
}
-void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def)
-{
+void fill_fopen64_filefunc(zlib_filefunc64_def* pzlib_filefunc_def) {
pzlib_filefunc_def->zopen64_file = fopen64_file_func;
pzlib_filefunc_def->zread_file = fread_file_func;
pzlib_filefunc_def->zwrite_file = fwrite_file_func;
diff --git a/Telegram/ThirdParty/minizip/ioapi.h b/Telegram/ThirdParty/minizip/ioapi.h
index ae9ca7e83..a2d2e6e60 100644
--- a/Telegram/ThirdParty/minizip/ioapi.h
+++ b/Telegram/ThirdParty/minizip/ioapi.h
@@ -50,7 +50,7 @@
#define ftello64 ftell
#define fseeko64 fseek
#else
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__) || defined(MINIZIP_FOPEN_NO_64)
#define fopen64 fopen
#define ftello64 ftello
#define fseeko64 fseeko
@@ -82,7 +82,7 @@
#include "mz64conf.h"
#endif
-/* a type choosen by DEFINE */
+/* a type chosen by DEFINE */
#ifdef HAVE_64BIT_INT_CUSTOM
typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T;
#else
@@ -134,17 +134,17 @@ extern "C" {
-typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
-typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
-typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
-typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
-typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
+typedef voidpf (ZCALLBACK *open_file_func) (voidpf opaque, const char* filename, int mode);
+typedef uLong (ZCALLBACK *read_file_func) (voidpf opaque, voidpf stream, void* buf, uLong size);
+typedef uLong (ZCALLBACK *write_file_func) (voidpf opaque, voidpf stream, const void* buf, uLong size);
+typedef int (ZCALLBACK *close_file_func) (voidpf opaque, voidpf stream);
+typedef int (ZCALLBACK *testerror_file_func) (voidpf opaque, voidpf stream);
-typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
-typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
+typedef long (ZCALLBACK *tell_file_func) (voidpf opaque, voidpf stream);
+typedef long (ZCALLBACK *seek_file_func) (voidpf opaque, voidpf stream, uLong offset, int origin);
-/* here is the "old" 32 bits structure structure */
+/* here is the "old" 32 bits structure */
typedef struct zlib_filefunc_def_s
{
open_file_func zopen_file;
@@ -157,9 +157,9 @@ typedef struct zlib_filefunc_def_s
voidpf opaque;
} zlib_filefunc_def;
-typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream));
-typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
-typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode));
+typedef ZPOS64_T (ZCALLBACK *tell64_file_func) (voidpf opaque, voidpf stream);
+typedef long (ZCALLBACK *seek64_file_func) (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin);
+typedef voidpf (ZCALLBACK *open64_file_func) (voidpf opaque, const void* filename, int mode);
typedef struct zlib_filefunc64_def_s
{
@@ -173,8 +173,8 @@ typedef struct zlib_filefunc64_def_s
voidpf opaque;
} zlib_filefunc64_def;
-void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
-void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
+void fill_fopen64_filefunc(zlib_filefunc64_def* pzlib_filefunc_def);
+void fill_fopen_filefunc(zlib_filefunc_def* pzlib_filefunc_def);
/* now internal definition, only for zip.c and unzip.h */
typedef struct zlib_filefunc64_32_def_s
@@ -193,11 +193,11 @@ typedef struct zlib_filefunc64_32_def_s
#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream))
#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream))
-voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode));
-long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));
-ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));
+voidpf call_zopen64(const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode);
+long call_zseek64(const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin);
+ZPOS64_T call_ztell64(const zlib_filefunc64_32_def* pfilefunc,voidpf filestream);
-void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
+void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode)))
#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream)))
diff --git a/Telegram/ThirdParty/minizip/unzip.c b/Telegram/ThirdParty/minizip/unzip.c
index 3036b470b..ed763f89f 100644
--- a/Telegram/ThirdParty/minizip/unzip.c
+++ b/Telegram/ThirdParty/minizip/unzip.c
@@ -49,12 +49,12 @@
Copyright (C) 2007-2008 Even Rouault
- Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).
+ Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).
Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G
should only read the compressed/uncompressed size from the Zip64 format if
the size from normal header was 0xFFFFFFFF
- Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant
- Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)
+ Oct-2009 - Mathias Svensson - Applied some bug fixes from patches received from Gilles Vollant
+ Oct-2009 - Mathias Svensson - Applied support to unzip files with compression method BZIP2 (bzip2 lib is required)
Patch created by Daniel Borca
Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
@@ -77,8 +77,6 @@
#ifdef STDC
# include
-# include
-# include
#endif
#ifdef NO_ERRNO_H
extern int errno;
@@ -111,9 +109,6 @@
#ifndef ALLOC
# define ALLOC(size) (malloc(size))
#endif
-#ifndef TRYFREE
-# define TRYFREE(p) { free(p);}
-#endif
#define SIZECENTRALDIRITEM (0x2e)
#define SIZEZIPLOCALHEADER (0x1e)
@@ -153,7 +148,7 @@ typedef struct
ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/
zlib_filefunc64_32_def z_filefunc;
- voidpf filestream; /* io structore of the zipfile */
+ voidpf filestream; /* io structure of the zipfile */
uLong compression_method; /* compression method (0==store) */
ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
int raw;
@@ -166,7 +161,7 @@ typedef struct
{
zlib_filefunc64_32_def z_filefunc;
int is64bitOpenFunction;
- voidpf filestream; /* io structore of the zipfile */
+ voidpf filestream; /* io structure of the zipfile */
unz_global_info64 gi; /* public global information */
ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
ZPOS64_T num_file; /* number of the current file in the zipfile*/
@@ -197,29 +192,44 @@ typedef struct
#include "crypt.h"
#endif
+
/* ===========================================================================
- Read a byte from a gz_stream; update next_in and avail_in. Return EOF
- for end of file.
- IN assertion: the stream s has been successfully opened for reading.
+ Reads a long in LSB order from the given gz_stream. Sets
*/
-
-local int unz64local_getByte OF((
- const zlib_filefunc64_32_def* pzlib_filefunc_def,
- voidpf filestream,
- int *pi));
-
-local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)
-{
- unsigned char c;
- int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
- if (err==1)
+local int unz64local_getShort(const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ uLong *pX) {
+ unsigned char c[2];
+ int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,c,2);
+ if (err==2)
{
- *pi = (int)c;
+ *pX = c[0] | ((uLong)c[1] << 8);
return UNZ_OK;
}
else
{
+ *pX = 0;
+ if (ZERROR64(*pzlib_filefunc_def,filestream))
+ return UNZ_ERRNO;
+ else
+ return UNZ_EOF;
+ }
+}
+
+local int unz64local_getLong(const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ uLong *pX) {
+ unsigned char c[4];
+ int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,c,4);
+ if (err==4)
+ {
+ *pX = c[0] | ((uLong)c[1] << 8) | ((uLong)c[2] << 16) | ((uLong)c[3] << 24);
+ return UNZ_OK;
+ }
+ else
+ {
+ *pX = 0;
if (ZERROR64(*pzlib_filefunc_def,filestream))
return UNZ_ERRNO;
else
@@ -228,126 +238,29 @@ local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, v
}
-/* ===========================================================================
- Reads a long in LSB order from the given gz_stream. Sets
-*/
-local int unz64local_getShort OF((
- const zlib_filefunc64_32_def* pzlib_filefunc_def,
- voidpf filestream,
- uLong *pX));
-
-local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
- voidpf filestream,
- uLong *pX)
-{
- uLong x ;
- int i = 0;
- int err;
-
- err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
- x = (uLong)i;
-
- if (err==UNZ_OK)
- err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
- x |= ((uLong)i)<<8;
-
- if (err==UNZ_OK)
- *pX = x;
+local int unz64local_getLong64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ ZPOS64_T *pX) {
+ unsigned char c[8];
+ int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,c,8);
+ if (err==8)
+ {
+ *pX = c[0] | ((ZPOS64_T)c[1] << 8) | ((ZPOS64_T)c[2] << 16) | ((ZPOS64_T)c[3] << 24)
+ | ((ZPOS64_T)c[4] << 32) | ((ZPOS64_T)c[5] << 40) | ((ZPOS64_T)c[6] << 48) | ((ZPOS64_T)c[7] << 56);
+ return UNZ_OK;
+ }
else
+ {
*pX = 0;
- return err;
-}
-
-local int unz64local_getLong OF((
- const zlib_filefunc64_32_def* pzlib_filefunc_def,
- voidpf filestream,
- uLong *pX));
-
-local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
- voidpf filestream,
- uLong *pX)
-{
- uLong x ;
- int i = 0;
- int err;
-
- err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
- x = (uLong)i;
-
- if (err==UNZ_OK)
- err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
- x |= ((uLong)i)<<8;
-
- if (err==UNZ_OK)
- err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
- x |= ((uLong)i)<<16;
-
- if (err==UNZ_OK)
- err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<24;
-
- if (err==UNZ_OK)
- *pX = x;
- else
- *pX = 0;
- return err;
-}
-
-local int unz64local_getLong64 OF((
- const zlib_filefunc64_32_def* pzlib_filefunc_def,
- voidpf filestream,
- ZPOS64_T *pX));
-
-
-local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
- voidpf filestream,
- ZPOS64_T *pX)
-{
- ZPOS64_T x ;
- int i = 0;
- int err;
-
- err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
- x = (ZPOS64_T)i;
-
- if (err==UNZ_OK)
- err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
- x |= ((ZPOS64_T)i)<<8;
-
- if (err==UNZ_OK)
- err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
- x |= ((ZPOS64_T)i)<<16;
-
- if (err==UNZ_OK)
- err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
- x |= ((ZPOS64_T)i)<<24;
-
- if (err==UNZ_OK)
- err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
- x |= ((ZPOS64_T)i)<<32;
-
- if (err==UNZ_OK)
- err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
- x |= ((ZPOS64_T)i)<<40;
-
- if (err==UNZ_OK)
- err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
- x |= ((ZPOS64_T)i)<<48;
-
- if (err==UNZ_OK)
- err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
- x |= ((ZPOS64_T)i)<<56;
-
- if (err==UNZ_OK)
- *pX = x;
- else
- *pX = 0;
- return err;
+ if (ZERROR64(*pzlib_filefunc_def,filestream))
+ return UNZ_ERRNO;
+ else
+ return UNZ_EOF;
+ }
}
/* My own strcmpi / strcasecmp */
-local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
-{
+local int strcmpcasenosensitive_internal(const char* fileName1, const char* fileName2) {
for (;;)
{
char c1=*(fileName1++);
@@ -379,19 +292,17 @@ local int strcmpcasenosensitive_internal (const char* fileName1, const char* fil
#endif
/*
- Compare two filename (fileName1,fileName2).
- If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
- If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+ Compare two filenames (fileName1,fileName2).
+ If iCaseSensitivity = 1, comparison is case sensitive (like strcmp)
+ If iCaseSensitivity = 2, comparison is not case sensitive (like strcmpi
or strcasecmp)
- If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+ If iCaseSensitivity = 0, case sensitivity is default of your operating system
(like 1 on Unix, 2 on Windows)
*/
extern int ZEXPORT unzStringFileNameCompare (const char* fileName1,
- const char* fileName2,
- int iCaseSensitivity)
-
-{
+ const char* fileName2,
+ int iCaseSensitivity) {
if (iCaseSensitivity==0)
iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
@@ -405,21 +316,23 @@ extern int ZEXPORT unzStringFileNameCompare (const char* fileName1,
#define BUFREADCOMMENT (0x400)
#endif
+#ifndef CENTRALDIRINVALID
+#define CENTRALDIRINVALID ((ZPOS64_T)(-1))
+#endif
+
/*
Locate the Central directory of a zipfile (at the end, just before
the global comment)
*/
-local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
-local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
-{
+local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) {
unsigned char* buf;
ZPOS64_T uSizeFile;
ZPOS64_T uBackRead;
ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
- ZPOS64_T uPosFound=0;
+ ZPOS64_T uPosFound=CENTRALDIRINVALID;
if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
- return 0;
+ return CENTRALDIRINVALID;
uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
@@ -429,7 +342,7 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f
buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
if (buf==NULL)
- return 0;
+ return CENTRALDIRINVALID;
uBackRead = 4;
while (uBackReadz_filefunc, s->filestream);
- TRYFREE(s);
+ free(s);
return UNZ_OK;
}
@@ -825,8 +727,7 @@ extern int ZEXPORT unzClose (unzFile file)
Write info about the ZipFile in the *pglobal_info structure.
No preparation of the structure is needed
return UNZ_OK if there is no problem. */
-extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
-{
+extern int ZEXPORT unzGetGlobalInfo64(unzFile file, unz_global_info64* pglobal_info) {
unz64_s* s;
if (file==NULL)
return UNZ_PARAMERROR;
@@ -835,8 +736,7 @@ extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_
return UNZ_OK;
}
-extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
-{
+extern int ZEXPORT unzGetGlobalInfo(unzFile file, unz_global_info* pglobal_info32) {
unz64_s* s;
if (file==NULL)
return UNZ_PARAMERROR;
@@ -847,10 +747,9 @@ extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info
return UNZ_OK;
}
/*
- Translate date/time from Dos format to tm_unz (readable more easilty)
+ Translate date/time from Dos format to tm_unz (readable more easily)
*/
-local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
-{
+local void unz64local_DosDateToTmuDate(ZPOS64_T ulDosDate, tm_unz* ptm) {
ZPOS64_T uDate;
uDate = (ZPOS64_T)(ulDosDate>>16);
ptm->tm_mday = (int)(uDate&0x1f) ;
@@ -865,28 +764,16 @@ local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
/*
Get Info about the current file in the zipfile, with internal only info
*/
-local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
- unz_file_info64 *pfile_info,
- unz_file_info64_internal
- *pfile_info_internal,
- char *szFileName,
- uLong fileNameBufferSize,
- void *extraField,
- uLong extraFieldBufferSize,
- char *szComment,
- uLong commentBufferSize));
-
-local int unz64local_GetCurrentFileInfoInternal (unzFile file,
- unz_file_info64 *pfile_info,
- unz_file_info64_internal
- *pfile_info_internal,
- char *szFileName,
- uLong fileNameBufferSize,
- void *extraField,
- uLong extraFieldBufferSize,
- char *szComment,
- uLong commentBufferSize)
-{
+local int unz64local_GetCurrentFileInfoInternal(unzFile file,
+ unz_file_info64 *pfile_info,
+ unz_file_info64_internal
+ *pfile_info_internal,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize) {
unz64_s* s;
unz_file_info64 file_info;
unz_file_info64_internal file_info_internal;
@@ -1038,33 +925,31 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file,
/* ZIP64 extra fields */
if (headerId == 0x0001)
{
- uLong uL;
+ if(file_info.uncompressed_size == MAXU32)
+ {
+ if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
+ err=UNZ_ERRNO;
+ }
- if(file_info.uncompressed_size == MAXU32)
- {
- if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
- err=UNZ_ERRNO;
- }
+ if(file_info.compressed_size == MAXU32)
+ {
+ if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
+ err=UNZ_ERRNO;
+ }
- if(file_info.compressed_size == MAXU32)
- {
- if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
- err=UNZ_ERRNO;
- }
+ if(file_info_internal.offset_curfile == MAXU32)
+ {
+ /* Relative Header offset */
+ if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
+ err=UNZ_ERRNO;
+ }
- if(file_info_internal.offset_curfile == MAXU32)
- {
- /* Relative Header offset */
- if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
- err=UNZ_ERRNO;
- }
-
- if(file_info.disk_num_start == MAXU32)
- {
- /* Disk Start Number */
- if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
- err=UNZ_ERRNO;
- }
+ if(file_info.disk_num_start == 0xffff)
+ {
+ /* Disk Start Number */
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
+ err=UNZ_ERRNO;
+ }
}
else
@@ -1121,24 +1006,22 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file,
No preparation of the structure is needed
return UNZ_OK if there is no problem.
*/
-extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,
- unz_file_info64 * pfile_info,
- char * szFileName, uLong fileNameBufferSize,
- void *extraField, uLong extraFieldBufferSize,
- char* szComment, uLong commentBufferSize)
-{
+extern int ZEXPORT unzGetCurrentFileInfo64(unzFile file,
+ unz_file_info64 * pfile_info,
+ char * szFileName, uLong fileNameBufferSize,
+ void *extraField, uLong extraFieldBufferSize,
+ char* szComment, uLong commentBufferSize) {
return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
- szFileName,fileNameBufferSize,
- extraField,extraFieldBufferSize,
- szComment,commentBufferSize);
+ szFileName,fileNameBufferSize,
+ extraField,extraFieldBufferSize,
+ szComment,commentBufferSize);
}
-extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
- unz_file_info * pfile_info,
- char * szFileName, uLong fileNameBufferSize,
- void *extraField, uLong extraFieldBufferSize,
- char* szComment, uLong commentBufferSize)
-{
+extern int ZEXPORT unzGetCurrentFileInfo(unzFile file,
+ unz_file_info * pfile_info,
+ char * szFileName, uLong fileNameBufferSize,
+ void *extraField, uLong extraFieldBufferSize,
+ char* szComment, uLong commentBufferSize) {
int err;
unz_file_info64 file_info64;
err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
@@ -1162,7 +1045,7 @@ extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
pfile_info->internal_fa = file_info64.internal_fa;
pfile_info->external_fa = file_info64.external_fa;
- pfile_info->tmu_date = file_info64.tmu_date,
+ pfile_info->tmu_date = file_info64.tmu_date;
pfile_info->compressed_size = (uLong)file_info64.compressed_size;
@@ -1175,8 +1058,7 @@ extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
Set the current file of the zipfile to the first file.
return UNZ_OK if there is no problem
*/
-extern int ZEXPORT unzGoToFirstFile (unzFile file)
-{
+extern int ZEXPORT unzGoToFirstFile(unzFile file) {
int err=UNZ_OK;
unz64_s* s;
if (file==NULL)
@@ -1196,8 +1078,7 @@ extern int ZEXPORT unzGoToFirstFile (unzFile file)
return UNZ_OK if there is no problem
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
*/
-extern int ZEXPORT unzGoToNextFile (unzFile file)
-{
+extern int ZEXPORT unzGoToNextFile(unzFile file) {
unz64_s* s;
int err;
@@ -1229,8 +1110,7 @@ extern int ZEXPORT unzGoToNextFile (unzFile file)
UNZ_OK if the file is found. It becomes the current file.
UNZ_END_OF_LIST_OF_FILE if the file is not found
*/
-extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
-{
+extern int ZEXPORT unzLocateFile(unzFile file, const char *szFileName, int iCaseSensitivity) {
unz64_s* s;
int err;
@@ -1305,8 +1185,7 @@ typedef struct unz_file_pos_s
} unz_file_pos;
*/
-extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos)
-{
+extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) {
unz64_s* s;
if (file==NULL || file_pos==NULL)
@@ -1321,10 +1200,7 @@ extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos)
return UNZ_OK;
}
-extern int ZEXPORT unzGetFilePos(
- unzFile file,
- unz_file_pos* file_pos)
-{
+extern int ZEXPORT unzGetFilePos(unzFile file, unz_file_pos* file_pos) {
unz64_file_pos file_pos64;
int err = unzGetFilePos64(file,&file_pos64);
if (err==UNZ_OK)
@@ -1335,8 +1211,7 @@ extern int ZEXPORT unzGetFilePos(
return err;
}
-extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
-{
+extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) {
unz64_s* s;
int err;
@@ -1357,10 +1232,7 @@ extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos
return err;
}
-extern int ZEXPORT unzGoToFilePos(
- unzFile file,
- unz_file_pos* file_pos)
-{
+extern int ZEXPORT unzGoToFilePos(unzFile file, unz_file_pos* file_pos) {
unz64_file_pos file_pos64;
if (file_pos == NULL)
return UNZ_PARAMERROR;
@@ -1382,10 +1254,9 @@ extern int ZEXPORT unzGoToFilePos(
store in *piSizeVar the size of extra info in local header
(filename and size of extra field data)
*/
-local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
- ZPOS64_T * poffset_local_extrafield,
- uInt * psize_local_extrafield)
-{
+local int unz64local_CheckCurrentFileCoherencyHeader(unz64_s* s, uInt* piSizeVar,
+ ZPOS64_T * poffset_local_extrafield,
+ uInt * psize_local_extrafield) {
uLong uMagic,uData,uFlags;
uLong size_filename;
uLong size_extra_field;
@@ -1469,9 +1340,8 @@ local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVa
Open for reading data the current file in the zipfile.
If there is no error and the file is opened, the return value is UNZ_OK.
*/
-extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
- int* level, int raw, const char* password)
-{
+extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int* method,
+ int* level, int raw, const char* password) {
int err=UNZ_OK;
uInt iSizeVar;
unz64_s* s;
@@ -1509,7 +1379,7 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
if (pfile_in_zip_read_info->read_buffer==NULL)
{
- TRYFREE(pfile_in_zip_read_info);
+ free(pfile_in_zip_read_info);
return UNZ_INTERNALERROR;
}
@@ -1566,8 +1436,8 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
else
{
- TRYFREE(pfile_in_zip_read_info->read_buffer);
- TRYFREE(pfile_in_zip_read_info);
+ free(pfile_in_zip_read_info->read_buffer);
+ free(pfile_in_zip_read_info);
return err;
}
#else
@@ -1587,8 +1457,8 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
else
{
- TRYFREE(pfile_in_zip_read_info->read_buffer);
- TRYFREE(pfile_in_zip_read_info);
+ free(pfile_in_zip_read_info->read_buffer);
+ free(pfile_in_zip_read_info);
return err;
}
/* windowBits is passed < 0 to tell that there is no zlib header.
@@ -1640,25 +1510,21 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
return UNZ_OK;
}
-extern int ZEXPORT unzOpenCurrentFile (unzFile file)
-{
+extern int ZEXPORT unzOpenCurrentFile(unzFile file) {
return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
}
-extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password)
-{
+extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file, const char* password) {
return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
}
-extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
-{
+extern int ZEXPORT unzOpenCurrentFile2(unzFile file, int* method, int* level, int raw) {
return unzOpenCurrentFile3(file, method, level, raw, NULL);
}
/** Addition for GDAL : START */
-extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
-{
+extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64(unzFile file) {
unz64_s* s;
file_in_zip64_read_info_s* pfile_in_zip_read_info;
s=(unz64_s*)file;
@@ -1678,13 +1544,12 @@ extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
buf contain buffer where data must be copied
len the size of buf.
- return the number of byte copied if somes bytes are copied
+ return the number of byte copied if some bytes are copied
return 0 if the end of file was reached
return <0 with error code if there is an error
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
*/
-extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
-{
+extern int ZEXPORT unzReadCurrentFile(unzFile file, voidp buf, unsigned len) {
int err=UNZ_OK;
uInt iRead = 0;
unz64_s* s;
@@ -1891,8 +1756,7 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
/*
Give the current position in uncompressed data
*/
-extern z_off_t ZEXPORT unztell (unzFile file)
-{
+extern z_off_t ZEXPORT unztell(unzFile file) {
unz64_s* s;
file_in_zip64_read_info_s* pfile_in_zip_read_info;
if (file==NULL)
@@ -1906,8 +1770,7 @@ extern z_off_t ZEXPORT unztell (unzFile file)
return (z_off_t)pfile_in_zip_read_info->stream.total_out;
}
-extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
-{
+extern ZPOS64_T ZEXPORT unztell64(unzFile file) {
unz64_s* s;
file_in_zip64_read_info_s* pfile_in_zip_read_info;
@@ -1926,8 +1789,7 @@ extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
/*
return 1 if the end of file was reached, 0 elsewhere
*/
-extern int ZEXPORT unzeof (unzFile file)
-{
+extern int ZEXPORT unzeof(unzFile file) {
unz64_s* s;
file_in_zip64_read_info_s* pfile_in_zip_read_info;
if (file==NULL)
@@ -1958,8 +1820,7 @@ more info in the local-header version than in the central-header)
the return value is the number of bytes copied in buf, or (if <0)
the error code
*/
-extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
-{
+extern int ZEXPORT unzGetLocalExtrafield(unzFile file, voidp buf, unsigned len) {
unz64_s* s;
file_in_zip64_read_info_s* pfile_in_zip_read_info;
uInt read_now;
@@ -2006,8 +1867,7 @@ extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
Close the file in zip opened with unzOpenCurrentFile
Return UNZ_CRCERROR if all the file was read but the CRC is not good
*/
-extern int ZEXPORT unzCloseCurrentFile (unzFile file)
-{
+extern int ZEXPORT unzCloseCurrentFile(unzFile file) {
int err=UNZ_OK;
unz64_s* s;
@@ -2029,7 +1889,7 @@ extern int ZEXPORT unzCloseCurrentFile (unzFile file)
}
- TRYFREE(pfile_in_zip_read_info->read_buffer);
+ free(pfile_in_zip_read_info->read_buffer);
pfile_in_zip_read_info->read_buffer = NULL;
if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
inflateEnd(&pfile_in_zip_read_info->stream);
@@ -2040,7 +1900,7 @@ extern int ZEXPORT unzCloseCurrentFile (unzFile file)
pfile_in_zip_read_info->stream_initialised = 0;
- TRYFREE(pfile_in_zip_read_info);
+ free(pfile_in_zip_read_info);
s->pfile_in_zip_read=NULL;
@@ -2053,8 +1913,7 @@ extern int ZEXPORT unzCloseCurrentFile (unzFile file)
uSizeBuf is the size of the szComment buffer.
return the number of byte copied or an error code <0
*/
-extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
-{
+extern int ZEXPORT unzGetGlobalComment(unzFile file, char * szComment, uLong uSizeBuf) {
unz64_s* s;
uLong uReadThis ;
if (file==NULL)
@@ -2081,8 +1940,7 @@ extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uS
}
/* Additions by RX '2004 */
-extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
-{
+extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) {
unz64_s* s;
if (file==NULL)
@@ -2096,8 +1954,7 @@ extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
return s->pos_in_central_dir;
}
-extern uLong ZEXPORT unzGetOffset (unzFile file)
-{
+extern uLong ZEXPORT unzGetOffset(unzFile file) {
ZPOS64_T offset64;
if (file==NULL)
@@ -2106,8 +1963,7 @@ extern uLong ZEXPORT unzGetOffset (unzFile file)
return (uLong)offset64;
}
-extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
-{
+extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) {
unz64_s* s;
int err;
@@ -2124,7 +1980,6 @@ extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
return err;
}
-extern int ZEXPORT unzSetOffset (unzFile file, uLong pos)
-{
+extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) {
return unzSetOffset64(file,pos);
}
diff --git a/Telegram/ThirdParty/minizip/unzip.h b/Telegram/ThirdParty/minizip/unzip.h
index 6f95e94d7..14105840f 100644
--- a/Telegram/ThirdParty/minizip/unzip.h
+++ b/Telegram/ThirdParty/minizip/unzip.h
@@ -150,21 +150,21 @@ typedef struct unz_file_info_s
tm_unz tmu_date;
} unz_file_info;
-extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
- const char* fileName2,
- int iCaseSensitivity));
+extern int ZEXPORT unzStringFileNameCompare(const char* fileName1,
+ const char* fileName2,
+ int iCaseSensitivity);
/*
- Compare two filename (fileName1,fileName2).
- If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
- If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+ Compare two filenames (fileName1,fileName2).
+ If iCaseSensitivity = 1, comparison is case sensitive (like strcmp)
+ If iCaseSensitivity = 2, comparison is not case sensitive (like strcmpi
or strcasecmp)
- If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+ If iCaseSensitivity = 0, case sensitivity is default of your operating system
(like 1 on Unix, 2 on Windows)
*/
-extern unzFile ZEXPORT unzOpen OF((const char *path));
-extern unzFile ZEXPORT unzOpen64 OF((const void *path));
+extern unzFile ZEXPORT unzOpen(const char *path);
+extern unzFile ZEXPORT unzOpen64(const void *path);
/*
Open a Zip file. path contain the full pathname (by example,
on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
@@ -181,41 +181,41 @@ extern unzFile ZEXPORT unzOpen64 OF((const void *path));
*/
-extern unzFile ZEXPORT unzOpen2 OF((const char *path,
- zlib_filefunc_def* pzlib_filefunc_def));
+extern unzFile ZEXPORT unzOpen2(const char *path,
+ zlib_filefunc_def* pzlib_filefunc_def);
/*
Open a Zip file, like unzOpen, but provide a set of file low level API
for read/write the zip file (see ioapi.h)
*/
-extern unzFile ZEXPORT unzOpen2_64 OF((const void *path,
- zlib_filefunc64_def* pzlib_filefunc_def));
+extern unzFile ZEXPORT unzOpen2_64(const void *path,
+ zlib_filefunc64_def* pzlib_filefunc_def);
/*
Open a Zip file, like unz64Open, but provide a set of file low level API
for read/write the zip file (see ioapi.h)
*/
-extern int ZEXPORT unzClose OF((unzFile file));
+extern int ZEXPORT unzClose(unzFile file);
/*
Close a ZipFile opened with unzOpen.
If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
these files MUST be closed with unzCloseCurrentFile before call unzClose.
return UNZ_OK if there is no problem. */
-extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
- unz_global_info *pglobal_info));
+extern int ZEXPORT unzGetGlobalInfo(unzFile file,
+ unz_global_info *pglobal_info);
-extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file,
- unz_global_info64 *pglobal_info));
+extern int ZEXPORT unzGetGlobalInfo64(unzFile file,
+ unz_global_info64 *pglobal_info);
/*
Write info about the ZipFile in the *pglobal_info structure.
No preparation of the structure is needed
return UNZ_OK if there is no problem. */
-extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
- char *szComment,
- uLong uSizeBuf));
+extern int ZEXPORT unzGetGlobalComment(unzFile file,
+ char *szComment,
+ uLong uSizeBuf);
/*
Get the global comment string of the ZipFile, in the szComment buffer.
uSizeBuf is the size of the szComment buffer.
@@ -226,22 +226,22 @@ extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
/***************************************************************************/
/* Unzip package allow you browse the directory of the zipfile */
-extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
+extern int ZEXPORT unzGoToFirstFile(unzFile file);
/*
Set the current file of the zipfile to the first file.
return UNZ_OK if there is no problem
*/
-extern int ZEXPORT unzGoToNextFile OF((unzFile file));
+extern int ZEXPORT unzGoToNextFile(unzFile file);
/*
Set the current file of the zipfile to the next file.
return UNZ_OK if there is no problem
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
*/
-extern int ZEXPORT unzLocateFile OF((unzFile file,
- const char *szFileName,
- int iCaseSensitivity));
+extern int ZEXPORT unzLocateFile(unzFile file,
+ const char *szFileName,
+ int iCaseSensitivity);
/*
Try locate the file szFileName in the zipfile.
For the iCaseSensitivity signification, see unzStringFileNameCompare
@@ -285,26 +285,26 @@ extern int ZEXPORT unzGoToFilePos64(
/* ****************************************** */
-extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file,
- unz_file_info64 *pfile_info,
- char *szFileName,
- uLong fileNameBufferSize,
- void *extraField,
- uLong extraFieldBufferSize,
- char *szComment,
- uLong commentBufferSize));
+extern int ZEXPORT unzGetCurrentFileInfo64(unzFile file,
+ unz_file_info64 *pfile_info,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize);
-extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
- unz_file_info *pfile_info,
- char *szFileName,
- uLong fileNameBufferSize,
- void *extraField,
- uLong extraFieldBufferSize,
- char *szComment,
- uLong commentBufferSize));
+extern int ZEXPORT unzGetCurrentFileInfo(unzFile file,
+ unz_file_info *pfile_info,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize);
/*
Get Info about the current file
- if pfile_info!=NULL, the *pfile_info structure will contain somes info about
+ if pfile_info!=NULL, the *pfile_info structure will contain some info about
the current file
if szFileName!=NULL, the filemane string will be copied in szFileName
(fileNameBufferSize is the size of the buffer)
@@ -318,7 +318,7 @@ extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
/** Addition for GDAL : START */
-extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file));
+extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64(unzFile file);
/** Addition for GDAL : END */
@@ -328,24 +328,24 @@ extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file));
from it, and close it (you can close it before reading all the file)
*/
-extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
+extern int ZEXPORT unzOpenCurrentFile(unzFile file);
/*
Open for reading data the current file in the zipfile.
If there is no error, the return value is UNZ_OK.
*/
-extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
- const char* password));
+extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file,
+ const char* password);
/*
Open for reading data the current file in the zipfile.
password is a crypting password
If there is no error, the return value is UNZ_OK.
*/
-extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
- int* method,
- int* level,
- int raw));
+extern int ZEXPORT unzOpenCurrentFile2(unzFile file,
+ int* method,
+ int* level,
+ int raw);
/*
Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
if raw==1
@@ -355,11 +355,11 @@ extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
but you CANNOT set method parameter as NULL
*/
-extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
- int* method,
- int* level,
- int raw,
- const char* password));
+extern int ZEXPORT unzOpenCurrentFile3(unzFile file,
+ int* method,
+ int* level,
+ int raw,
+ const char* password);
/*
Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
if raw==1
@@ -370,41 +370,41 @@ extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
*/
-extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
+extern int ZEXPORT unzCloseCurrentFile(unzFile file);
/*
Close the file in zip opened with unzOpenCurrentFile
Return UNZ_CRCERROR if all the file was read but the CRC is not good
*/
-extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
- voidp buf,
- unsigned len));
+extern int ZEXPORT unzReadCurrentFile(unzFile file,
+ voidp buf,
+ unsigned len);
/*
Read bytes from the current file (opened by unzOpenCurrentFile)
buf contain buffer where data must be copied
len the size of buf.
- return the number of byte copied if somes bytes are copied
+ return the number of byte copied if some bytes are copied
return 0 if the end of file was reached
return <0 with error code if there is an error
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
*/
-extern z_off_t ZEXPORT unztell OF((unzFile file));
+extern z_off_t ZEXPORT unztell(unzFile file);
-extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file));
+extern ZPOS64_T ZEXPORT unztell64(unzFile file);
/*
Give the current position in uncompressed data
*/
-extern int ZEXPORT unzeof OF((unzFile file));
+extern int ZEXPORT unzeof(unzFile file);
/*
return 1 if the end of file was reached, 0 elsewhere
*/
-extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
- voidp buf,
- unsigned len));
+extern int ZEXPORT unzGetLocalExtrafield(unzFile file,
+ voidp buf,
+ unsigned len);
/*
Read extra field from the current file (opened by unzOpenCurrentFile)
This is the local-header version of the extra field (sometimes, there is
diff --git a/Telegram/ThirdParty/minizip/zip.c b/Telegram/ThirdParty/minizip/zip.c
index 66d693f85..e2e9da07c 100644
--- a/Telegram/ThirdParty/minizip/zip.c
+++ b/Telegram/ThirdParty/minizip/zip.c
@@ -14,7 +14,7 @@
Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives
Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.
Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data
- It is used when recreting zip archive with RAW when deleting items from a zip.
+ It is used when recreating zip archive with RAW when deleting items from a zip.
ZIP64 data is automatically added to items that needs it, and existing ZIP64 data need to be removed.
Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
@@ -25,14 +25,13 @@
#include
#include
#include
+#include
#include
#include "zlib.h"
#include "zip.h"
#ifdef STDC
# include
-# include
-# include
#endif
#ifdef NO_ERRNO_H
extern int errno;
@@ -47,7 +46,7 @@
/* compile with -Dlocal if your debugger can't find static symbols */
#ifndef VERSIONMADEBY
-# define VERSIONMADEBY (0x0) /* platform depedent */
+# define VERSIONMADEBY (0x0) /* platform dependent */
#endif
#ifndef Z_BUFSIZE
@@ -61,9 +60,6 @@
#ifndef ALLOC
# define ALLOC(size) (malloc(size))
#endif
-#ifndef TRYFREE
-# define TRYFREE(p) {if (p) free(p);}
-#endif
/*
#define SIZECENTRALDIRITEM (0x2e)
@@ -138,20 +134,20 @@ typedef struct
uInt pos_in_buffered_data; /* last written byte in buffered_data */
ZPOS64_T pos_local_header; /* offset of the local header of the file
- currenty writing */
+ currently writing */
char* central_header; /* central header data for the current file */
uLong size_centralExtra;
uLong size_centralheader; /* size of the central header for cur file */
uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */
uLong flag; /* flag of the file currently writing */
- int method; /* compression method of file currenty wr.*/
+ int method; /* compression method of file currently wr.*/
int raw; /* 1 for directly writing raw data */
Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
uLong dosDate;
uLong crc32;
int encrypt;
- int zip64; /* Add ZIP64 extened information in the extra field */
+ int zip64; /* Add ZIP64 extended information in the extra field */
ZPOS64_T pos_zip64extrainfo;
ZPOS64_T totalCompressedData;
ZPOS64_T totalUncompressedData;
@@ -165,10 +161,10 @@ typedef struct
typedef struct
{
zlib_filefunc64_32_def z_filefunc;
- voidpf filestream; /* io structore of the zipfile */
+ voidpf filestream; /* io structure of the zipfile */
linkedlist_data central_dir;/* datablock with central dir in construction*/
int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
- curfile64_info ci; /* info on the file curretly writing */
+ curfile64_info ci; /* info on the file currently writing */
ZPOS64_T begin_pos; /* position of the beginning of the zipfile */
ZPOS64_T add_position_when_writing_offset;
@@ -186,8 +182,7 @@ typedef struct
#include "crypt.h"
#endif
-local linkedlist_datablock_internal* allocate_new_datablock()
-{
+local linkedlist_datablock_internal* allocate_new_datablock(void) {
linkedlist_datablock_internal* ldi;
ldi = (linkedlist_datablock_internal*)
ALLOC(sizeof(linkedlist_datablock_internal));
@@ -200,30 +195,26 @@ local linkedlist_datablock_internal* allocate_new_datablock()
return ldi;
}
-local void free_datablock(linkedlist_datablock_internal* ldi)
-{
+local void free_datablock(linkedlist_datablock_internal* ldi) {
while (ldi!=NULL)
{
linkedlist_datablock_internal* ldinext = ldi->next_datablock;
- TRYFREE(ldi);
+ free(ldi);
ldi = ldinext;
}
}
-local void init_linkedlist(linkedlist_data* ll)
-{
+local void init_linkedlist(linkedlist_data* ll) {
ll->first_block = ll->last_block = NULL;
}
-local void free_linkedlist(linkedlist_data* ll)
-{
+local void free_linkedlist(linkedlist_data* ll) {
free_datablock(ll->first_block);
ll->first_block = ll->last_block = NULL;
}
-local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
-{
+local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) {
linkedlist_datablock_internal* ldi;
const unsigned char* from_copy;
@@ -238,7 +229,7 @@ local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
}
ldi = ll->last_block;
- from_copy = (unsigned char*)buf;
+ from_copy = (const unsigned char*)buf;
while (len>0)
{
@@ -283,9 +274,7 @@ local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
*/
-local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte));
-local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)
-{
+local int zip64local_putValue(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) {
unsigned char buf[8];
int n;
for (n = 0; n < nbByte; n++)
@@ -307,9 +296,7 @@ local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def,
return ZIP_OK;
}
-local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte));
-local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)
-{
+local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) {
unsigned char* buf=(unsigned char*)dest;
int n;
for (n = 0; n < nbByte; n++) {
@@ -329,8 +316,7 @@ local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)
/****************************************************************************/
-local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)
-{
+local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) {
uLong year = (uLong)ptm->tm_year;
if (year>=1980)
year-=1980;
@@ -344,10 +330,7 @@ local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)
/****************************************************************************/
-local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi));
-
-local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi)
-{
+local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int* pi) {
unsigned char c;
int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
if (err==1)
@@ -368,10 +351,7 @@ local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,vo
/* ===========================================================================
Reads a long in LSB order from the given gz_stream. Sets
*/
-local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
-
-local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
-{
+local int zip64local_getShort(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) {
uLong x ;
int i = 0;
int err;
@@ -390,10 +370,7 @@ local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
return err;
}
-local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
-
-local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
-{
+local int zip64local_getLong(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) {
uLong x ;
int i = 0;
int err;
@@ -420,11 +397,8 @@ local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
return err;
}
-local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX));
-
-local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)
-{
+local int zip64local_getLong64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) {
ZPOS64_T x;
int i = 0;
int err;
@@ -475,10 +449,7 @@ local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def
Locate the Central directory of a zipfile (at the end, just before
the global comment)
*/
-local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
-
-local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
-{
+local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) {
unsigned char* buf;
ZPOS64_T uSizeFile;
ZPOS64_T uBackRead;
@@ -529,7 +500,7 @@ local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f
if (uPosFound!=0)
break;
}
- TRYFREE(buf);
+ free(buf);
return uPosFound;
}
@@ -537,10 +508,7 @@ local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f
Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before
the global comment)
*/
-local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
-
-local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
-{
+local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) {
unsigned char* buf;
ZPOS64_T uSizeFile;
ZPOS64_T uBackRead;
@@ -595,7 +563,7 @@ local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib
break;
}
- TRYFREE(buf);
+ free(buf);
if (uPosFound == 0)
return 0;
@@ -637,8 +605,7 @@ local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib
return relativeOffset;
}
-local int LoadCentralDirectoryRecord(zip64_internal* pziinit)
-{
+local int LoadCentralDirectoryRecord(zip64_internal* pziinit) {
int err=ZIP_OK;
ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
@@ -647,10 +614,10 @@ local int LoadCentralDirectoryRecord(zip64_internal* pziinit)
ZPOS64_T central_pos;
uLong uL;
- uLong number_disk; /* number of the current dist, used for
- spaning ZIP, unsupported, always 0*/
- uLong number_disk_with_CD; /* number the the disk with central dir, used
- for spaning ZIP, unsupported, always 0*/
+ uLong number_disk; /* number of the current disk, used for
+ spanning ZIP, unsupported, always 0*/
+ uLong number_disk_with_CD; /* number of the disk with central dir, used
+ for spanning ZIP, unsupported, always 0*/
ZPOS64_T number_entry;
ZPOS64_T number_entry_CD; /* total number of entries in
the central dir
@@ -830,7 +797,7 @@ local int LoadCentralDirectoryRecord(zip64_internal* pziinit)
size_central_dir_to_read-=read_this;
}
- TRYFREE(buf_read);
+ free(buf_read);
}
pziinit->begin_pos = byte_before_the_zipfile;
pziinit->number_entry = number_entry_CD;
@@ -846,8 +813,7 @@ local int LoadCentralDirectoryRecord(zip64_internal* pziinit)
/************************************************************/
-extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)
-{
+extern zipFile ZEXPORT zipOpen3(const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) {
zip64_internal ziinit;
zip64_internal* zi;
int err=ZIP_OK;
@@ -905,9 +871,9 @@ extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* gl
if (err != ZIP_OK)
{
# ifndef NO_ADDFILEINEXISTINGZIP
- TRYFREE(ziinit.globalcomment);
+ free(ziinit.globalcomment);
# endif /* !NO_ADDFILEINEXISTINGZIP*/
- TRYFREE(zi);
+ free(zi);
return NULL;
}
else
@@ -917,8 +883,7 @@ extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* gl
}
}
-extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def)
-{
+extern zipFile ZEXPORT zipOpen2(const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) {
if (pzlib_filefunc32_def != NULL)
{
zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
@@ -929,8 +894,7 @@ extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* gl
return zipOpen3(pathname, append, globalcomment, NULL);
}
-extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)
-{
+extern zipFile ZEXPORT zipOpen2_64(const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) {
if (pzlib_filefunc_def != NULL)
{
zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
@@ -945,18 +909,15 @@ extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc*
-extern zipFile ZEXPORT zipOpen (const char* pathname, int append)
-{
+extern zipFile ZEXPORT zipOpen(const char* pathname, int append) {
return zipOpen3((const void*)pathname,append,NULL,NULL);
}
-extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append)
-{
+extern zipFile ZEXPORT zipOpen64(const void* pathname, int append) {
return zipOpen3(pathname,append,NULL,NULL);
}
-local int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)
-{
+local int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) {
/* write the local header */
int err;
uInt size_filename = (uInt)strlen(filename);
@@ -1052,14 +1013,13 @@ local int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt s
It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize
unnecessary allocations.
*/
-extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
- const void* extrafield_local, uInt size_extrafield_local,
- const void* extrafield_global, uInt size_extrafield_global,
- const char* comment, int method, int level, int raw,
- int windowBits,int memLevel, int strategy,
- const char* password, uLong crcForCrypting,
- uLong versionMadeBy, uLong flagBase, int zip64)
-{
+extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw,
+ int windowBits,int memLevel, int strategy,
+ const char* password, uLong crcForCrypting,
+ uLong versionMadeBy, uLong flagBase, int zip64) {
zip64_internal* zi;
uInt size_filename;
uInt size_comment;
@@ -1083,6 +1043,17 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename,
return ZIP_PARAMERROR;
#endif
+ // The filename and comment length must fit in 16 bits.
+ if ((filename!=NULL) && (strlen(filename)>0xffff))
+ return ZIP_PARAMERROR;
+ if ((comment!=NULL) && (strlen(comment)>0xffff))
+ return ZIP_PARAMERROR;
+ // The extra field length must fit in 16 bits. If the member also requires
+ // a Zip64 extra block, that will also need to fit within that 16-bit
+ // length, but that will be checked for later.
+ if ((size_extrafield_local>0xffff) || (size_extrafield_global>0xffff))
+ return ZIP_PARAMERROR;
+
zi = (zip64_internal*)file;
if (zi->in_opened_file_inzip == 1)
@@ -1262,35 +1233,33 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename,
return err;
}
-extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
- const void* extrafield_local, uInt size_extrafield_local,
- const void* extrafield_global, uInt size_extrafield_global,
- const char* comment, int method, int level, int raw,
- int windowBits,int memLevel, int strategy,
- const char* password, uLong crcForCrypting,
- uLong versionMadeBy, uLong flagBase)
-{
- return zipOpenNewFileInZip4_64 (file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level, raw,
- windowBits, memLevel, strategy,
- password, crcForCrypting, versionMadeBy, flagBase, 0);
+extern int ZEXPORT zipOpenNewFileInZip4(zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw,
+ int windowBits,int memLevel, int strategy,
+ const char* password, uLong crcForCrypting,
+ uLong versionMadeBy, uLong flagBase) {
+ return zipOpenNewFileInZip4_64(file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, raw,
+ windowBits, memLevel, strategy,
+ password, crcForCrypting, versionMadeBy, flagBase, 0);
}
-extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
- const void* extrafield_local, uInt size_extrafield_local,
- const void* extrafield_global, uInt size_extrafield_global,
- const char* comment, int method, int level, int raw,
- int windowBits,int memLevel, int strategy,
- const char* password, uLong crcForCrypting)
-{
- return zipOpenNewFileInZip4_64 (file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level, raw,
- windowBits, memLevel, strategy,
- password, crcForCrypting, VERSIONMADEBY, 0, 0);
+extern int ZEXPORT zipOpenNewFileInZip3(zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw,
+ int windowBits,int memLevel, int strategy,
+ const char* password, uLong crcForCrypting) {
+ return zipOpenNewFileInZip4_64(file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, raw,
+ windowBits, memLevel, strategy,
+ password, crcForCrypting, VERSIONMADEBY, 0, 0);
}
extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
@@ -1298,70 +1267,64 @@ extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, c
const void* extrafield_global, uInt size_extrafield_global,
const char* comment, int method, int level, int raw,
int windowBits,int memLevel, int strategy,
- const char* password, uLong crcForCrypting, int zip64)
-{
- return zipOpenNewFileInZip4_64 (file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level, raw,
- windowBits, memLevel, strategy,
- password, crcForCrypting, VERSIONMADEBY, 0, zip64);
+ const char* password, uLong crcForCrypting, int zip64) {
+ return zipOpenNewFileInZip4_64(file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, raw,
+ windowBits, memLevel, strategy,
+ password, crcForCrypting, VERSIONMADEBY, 0, zip64);
}
extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,
const void* extrafield_local, uInt size_extrafield_local,
const void* extrafield_global, uInt size_extrafield_global,
- const char* comment, int method, int level, int raw)
-{
- return zipOpenNewFileInZip4_64 (file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level, raw,
- -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
- NULL, 0, VERSIONMADEBY, 0, 0);
+ const char* comment, int method, int level, int raw) {
+ return zipOpenNewFileInZip4_64(file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, raw,
+ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+ NULL, 0, VERSIONMADEBY, 0, 0);
}
extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
- const void* extrafield_local, uInt size_extrafield_local,
- const void* extrafield_global, uInt size_extrafield_global,
- const char* comment, int method, int level, int raw, int zip64)
-{
- return zipOpenNewFileInZip4_64 (file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level, raw,
- -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
- NULL, 0, VERSIONMADEBY, 0, zip64);
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw, int zip64) {
+ return zipOpenNewFileInZip4_64(file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, raw,
+ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+ NULL, 0, VERSIONMADEBY, 0, zip64);
}
-extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
- const void* extrafield_local, uInt size_extrafield_local,
- const void*extrafield_global, uInt size_extrafield_global,
- const char* comment, int method, int level, int zip64)
-{
- return zipOpenNewFileInZip4_64 (file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level, 0,
- -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
- NULL, 0, VERSIONMADEBY, 0, zip64);
+extern int ZEXPORT zipOpenNewFileInZip64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void*extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int zip64) {
+ return zipOpenNewFileInZip4_64(file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, 0,
+ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+ NULL, 0, VERSIONMADEBY, 0, zip64);
}
-extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,
- const void* extrafield_local, uInt size_extrafield_local,
- const void*extrafield_global, uInt size_extrafield_global,
- const char* comment, int method, int level)
-{
- return zipOpenNewFileInZip4_64 (file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level, 0,
- -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
- NULL, 0, VERSIONMADEBY, 0, 0);
+extern int ZEXPORT zipOpenNewFileInZip(zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void*extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level) {
+ return zipOpenNewFileInZip4_64(file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, 0,
+ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+ NULL, 0, VERSIONMADEBY, 0, 0);
}
-local int zip64FlushWriteBuffer(zip64_internal* zi)
-{
+local int zip64FlushWriteBuffer(zip64_internal* zi) {
int err=ZIP_OK;
if (zi->ci.encrypt != 0)
@@ -1399,8 +1362,7 @@ local int zip64FlushWriteBuffer(zip64_internal* zi)
return err;
}
-extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)
-{
+extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void* buf, unsigned int len) {
zip64_internal* zi;
int err=ZIP_OK;
@@ -1450,7 +1412,7 @@ extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned in
else
#endif
{
- zi->ci.stream.next_in = (Bytef*)buf;
+ zi->ci.stream.next_in = (Bytef*)(uintptr_t)buf;
zi->ci.stream.avail_in = len;
while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
@@ -1501,13 +1463,11 @@ extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned in
return err;
}
-extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)
-{
+extern int ZEXPORT zipCloseFileInZipRaw(zipFile file, uLong uncompressed_size, uLong crc32) {
return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);
}
-extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
-{
+extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_size, uLong crc32) {
zip64_internal* zi;
ZPOS64_T compressed_size;
uLong invalidValue = 0xffffffff;
@@ -1742,13 +1702,11 @@ extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_s
return err;
}
-extern int ZEXPORT zipCloseFileInZip (zipFile file)
-{
+extern int ZEXPORT zipCloseFileInZip(zipFile file) {
return zipCloseFileInZipRaw (file,0,0);
}
-local int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
-{
+local int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) {
int err = ZIP_OK;
ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writing_offset;
@@ -1769,8 +1727,7 @@ local int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T z
return err;
}
-local int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
-{
+local int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) {
int err = ZIP_OK;
uLong Zip64DataSize = 44;
@@ -1808,8 +1765,8 @@ local int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_
}
return err;
}
-local int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
-{
+
+local int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) {
int err = ZIP_OK;
/*signature*/
@@ -1856,8 +1813,7 @@ local int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centr
return err;
}
-local int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
-{
+local int Write_GlobalComment(zip64_internal* zi, const char* global_comment) {
int err = ZIP_OK;
uInt size_global_comment = 0;
@@ -1874,8 +1830,7 @@ local int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
return err;
}
-extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
-{
+extern int ZEXPORT zipClose(zipFile file, const char* global_comment) {
zip64_internal* zi;
int err = 0;
uLong size_centraldir = 0;
@@ -1917,7 +1872,7 @@ extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
free_linkedlist(&(zi->central_dir));
pos = centraldir_pos_inzip - zi->add_position_when_writing_offset;
- if(pos >= 0xffffffff || zi->number_entry > 0xFFFF)
+ if(pos >= 0xffffffff || zi->number_entry >= 0xFFFF)
{
ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
@@ -1936,15 +1891,14 @@ extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
err = ZIP_ERRNO;
#ifndef NO_ADDFILEINEXISTINGZIP
- TRYFREE(zi->globalcomment);
+ free(zi->globalcomment);
#endif
- TRYFREE(zi);
+ free(zi);
return err;
}
-extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader)
-{
+extern int ZEXPORT zipRemoveExtraInfoBlock(char* pData, int* dataLen, short sHeader) {
char* p = pData;
int size = 0;
char* pNewHeader;
@@ -1996,7 +1950,7 @@ extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHe
else
retVal = ZIP_ERRNO;
- TRYFREE(pNewHeader);
+ free(pNewHeader);
return retVal;
}
diff --git a/Telegram/ThirdParty/minizip/zip.h b/Telegram/ThirdParty/minizip/zip.h
index 7e4509d77..3e230d340 100644
--- a/Telegram/ThirdParty/minizip/zip.h
+++ b/Telegram/ThirdParty/minizip/zip.h
@@ -113,8 +113,8 @@ typedef const char* zipcharpc;
#define APPEND_STATUS_CREATEAFTER (1)
#define APPEND_STATUS_ADDINZIP (2)
-extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));
-extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append));
+extern zipFile ZEXPORT zipOpen(const char *pathname, int append);
+extern zipFile ZEXPORT zipOpen64(const void *pathname, int append);
/*
Create a zipfile.
pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on
@@ -131,55 +131,55 @@ extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append));
/* Note : there is no delete function into a zipfile.
If you want delete file into a zipfile, you must open a zipfile, and create another
- Of couse, you can use RAW reading and writing to copy the file you did not want delte
+ Of course, you can use RAW reading and writing to copy the file you did not want delete
*/
-extern zipFile ZEXPORT zipOpen2 OF((const char *pathname,
+extern zipFile ZEXPORT zipOpen2(const char *pathname,
+ int append,
+ zipcharpc* globalcomment,
+ zlib_filefunc_def* pzlib_filefunc_def);
+
+extern zipFile ZEXPORT zipOpen2_64(const void *pathname,
int append,
zipcharpc* globalcomment,
- zlib_filefunc_def* pzlib_filefunc_def));
+ zlib_filefunc64_def* pzlib_filefunc_def);
-extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname,
- int append,
- zipcharpc* globalcomment,
- zlib_filefunc64_def* pzlib_filefunc_def));
+extern zipFile ZEXPORT zipOpen3(const void *pathname,
+ int append,
+ zipcharpc* globalcomment,
+ zlib_filefunc64_32_def* pzlib_filefunc64_32_def);
-extern zipFile ZEXPORT zipOpen3 OF((const void *pathname,
- int append,
- zipcharpc* globalcomment,
- zlib_filefunc64_32_def* pzlib_filefunc64_32_def));
+extern int ZEXPORT zipOpenNewFileInZip(zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level);
-extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
- const char* filename,
- const zip_fileinfo* zipfi,
- const void* extrafield_local,
- uInt size_extrafield_local,
- const void* extrafield_global,
- uInt size_extrafield_global,
- const char* comment,
- int method,
- int level));
-
-extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file,
- const char* filename,
- const zip_fileinfo* zipfi,
- const void* extrafield_local,
- uInt size_extrafield_local,
- const void* extrafield_global,
- uInt size_extrafield_global,
- const char* comment,
- int method,
- int level,
- int zip64));
+extern int ZEXPORT zipOpenNewFileInZip64(zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int zip64);
/*
Open a file in the ZIP for writing.
filename : the filename in zip (if NULL, '-' without quote will be used
*zipfi contain supplemental information
if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
- contains the extrafield data the the local header
+ contains the extrafield data for the local header
if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
- contains the extrafield data the the local header
+ contains the extrafield data for the global header
if comment != NULL, comment contain the comment string
method contain the compression method (0 for store, Z_DEFLATED for deflate)
level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
@@ -189,70 +189,69 @@ extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file,
*/
-extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
- const char* filename,
- const zip_fileinfo* zipfi,
- const void* extrafield_local,
- uInt size_extrafield_local,
- const void* extrafield_global,
- uInt size_extrafield_global,
- const char* comment,
- int method,
- int level,
- int raw));
+extern int ZEXPORT zipOpenNewFileInZip2(zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw);
-extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file,
- const char* filename,
- const zip_fileinfo* zipfi,
- const void* extrafield_local,
- uInt size_extrafield_local,
- const void* extrafield_global,
- uInt size_extrafield_global,
- const char* comment,
- int method,
- int level,
- int raw,
- int zip64));
+extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw,
+ int zip64);
/*
Same than zipOpenNewFileInZip, except if raw=1, we write raw file
*/
-extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
- const char* filename,
- const zip_fileinfo* zipfi,
- const void* extrafield_local,
- uInt size_extrafield_local,
- const void* extrafield_global,
- uInt size_extrafield_global,
- const char* comment,
- int method,
- int level,
- int raw,
- int windowBits,
- int memLevel,
- int strategy,
- const char* password,
- uLong crcForCrypting));
+extern int ZEXPORT zipOpenNewFileInZip3(zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw,
+ int windowBits,
+ int memLevel,
+ int strategy,
+ const char* password,
+ uLong crcForCrypting);
-extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file,
- const char* filename,
- const zip_fileinfo* zipfi,
- const void* extrafield_local,
- uInt size_extrafield_local,
- const void* extrafield_global,
- uInt size_extrafield_global,
- const char* comment,
- int method,
- int level,
- int raw,
- int windowBits,
- int memLevel,
- int strategy,
- const char* password,
- uLong crcForCrypting,
- int zip64
- ));
+extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw,
+ int windowBits,
+ int memLevel,
+ int strategy,
+ const char* password,
+ uLong crcForCrypting,
+ int zip64);
/*
Same than zipOpenNewFileInZip2, except
@@ -261,47 +260,45 @@ extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file,
crcForCrypting : crc of file to compress (needed for crypting)
*/
-extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file,
- const char* filename,
- const zip_fileinfo* zipfi,
- const void* extrafield_local,
- uInt size_extrafield_local,
- const void* extrafield_global,
- uInt size_extrafield_global,
- const char* comment,
- int method,
- int level,
- int raw,
- int windowBits,
- int memLevel,
- int strategy,
- const char* password,
- uLong crcForCrypting,
- uLong versionMadeBy,
- uLong flagBase
- ));
+extern int ZEXPORT zipOpenNewFileInZip4(zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw,
+ int windowBits,
+ int memLevel,
+ int strategy,
+ const char* password,
+ uLong crcForCrypting,
+ uLong versionMadeBy,
+ uLong flagBase);
-extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file,
- const char* filename,
- const zip_fileinfo* zipfi,
- const void* extrafield_local,
- uInt size_extrafield_local,
- const void* extrafield_global,
- uInt size_extrafield_global,
- const char* comment,
- int method,
- int level,
- int raw,
- int windowBits,
- int memLevel,
- int strategy,
- const char* password,
- uLong crcForCrypting,
- uLong versionMadeBy,
- uLong flagBase,
- int zip64
- ));
+extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw,
+ int windowBits,
+ int memLevel,
+ int strategy,
+ const char* password,
+ uLong crcForCrypting,
+ uLong versionMadeBy,
+ uLong flagBase,
+ int zip64);
/*
Same than zipOpenNewFileInZip4, except
versionMadeBy : value for Version made by field
@@ -309,25 +306,25 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file,
*/
-extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
- const void* buf,
- unsigned len));
+extern int ZEXPORT zipWriteInFileInZip(zipFile file,
+ const void* buf,
+ unsigned len);
/*
Write data in the zipfile
*/
-extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
+extern int ZEXPORT zipCloseFileInZip(zipFile file);
/*
Close the current file in the zipfile
*/
-extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
- uLong uncompressed_size,
- uLong crc32));
+extern int ZEXPORT zipCloseFileInZipRaw(zipFile file,
+ uLong uncompressed_size,
+ uLong crc32);
-extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file,
- ZPOS64_T uncompressed_size,
- uLong crc32));
+extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file,
+ ZPOS64_T uncompressed_size,
+ uLong crc32);
/*
Close the current file in the zipfile, for file opened with
@@ -335,14 +332,14 @@ extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file,
uncompressed_size and crc32 are value for the uncompressed size
*/
-extern int ZEXPORT zipClose OF((zipFile file,
- const char* global_comment));
+extern int ZEXPORT zipClose(zipFile file,
+ const char* global_comment);
/*
Close the zipfile
*/
-extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader));
+extern int ZEXPORT zipRemoveExtraInfoBlock(char* pData, int* dataLen, short sHeader);
/*
zipRemoveExtraInfoBlock - Added by Mathias Svensson
diff --git a/Telegram/build/docker/centos_env/Dockerfile b/Telegram/build/docker/centos_env/Dockerfile
index 253b0207a..d2c6320a0 100644
--- a/Telegram/build/docker/centos_env/Dockerfile
+++ b/Telegram/build/docker/centos_env/Dockerfile
@@ -54,7 +54,7 @@ FROM builder AS patches
RUN git init patches \
&& cd patches \
&& git remote add origin {{ GIT }}/desktop-app/patches.git \
- && git fetch --depth=1 origin 78fe199b743df0358c04502d6947cd42bb5d16ed \
+ && git fetch --depth=1 origin 1e6c830a66649a60a2a277015143260f5716517b \
&& git reset --hard FETCH_HEAD \
&& rm -rf .git
@@ -70,8 +70,11 @@ RUN git clone -b nasm-2.15.05 --depth=1 {{ GIT }}/netwide-assembler/nasm.git \
&& rm -rf nasm
FROM builder AS zlib
-RUN git clone -b v1.2.13 --depth=1 {{ GIT }}/madler/zlib.git \
+RUN git init zlib \
&& cd zlib \
+ && git remote add origin {{ GIT }}/madler/zlib.git \
+ && git fetch --depth=1 origin 643e17b7498d12ab8d15565662880579692f769d \
+ && git reset --hard FETCH_HEAD \
&& ./configure \
&& make -j$(nproc) \
&& make DESTDIR="{{ LibrariesPath }}/zlib-cache" install \
diff --git a/Telegram/build/prepare/prepare.py b/Telegram/build/prepare/prepare.py
index c29d93178..51cc2c298 100644
--- a/Telegram/build/prepare/prepare.py
+++ b/Telegram/build/prepare/prepare.py
@@ -418,7 +418,7 @@ if customRunCommand:
stage('patches', """
git clone https://github.com/desktop-app/patches.git
cd patches
- git checkout 58c8cd0c0f
+ git checkout d3107bf4a5
""")
stage('msys64', """
@@ -513,8 +513,9 @@ stage('xz', """
""")
stage('zlib', """
- git clone -b v1.3 https://github.com/madler/zlib.git
+ git clone https://github.com/madler/zlib.git
cd zlib
+ git checkout 643e17b749
win:
cmake . ^
-A %WIN32X64% ^
@@ -1299,23 +1300,23 @@ release:
""")
if buildQt5:
- stage('qt_5_15_11', """
- git clone https://github.com/qt/qt5.git qt_5_15_11
- cd qt_5_15_11
+ stage('qt_5_15_12', """
+ git clone https://github.com/qt/qt5.git qt_5_15_12
+ cd qt_5_15_12
perl init-repository --module-subset=qtbase,qtimageformats,qtsvg
- git checkout v5.15.11-lts-lgpl
+ git checkout v5.15.12-lts-lgpl
git submodule update qtbase qtimageformats qtsvg
-depends:patches/qtbase_5.15.11/*.patch
+depends:patches/qtbase_5.15.12/*.patch
cd qtbase
win:
- for /r %%i in (..\\..\\patches\\qtbase_5.15.11\\*) do git apply %%i -v
+ for /r %%i in (..\\..\\patches\\qtbase_5.15.12\\*) do git apply %%i -v
cd ..
SET CONFIGURATIONS=-debug
release:
SET CONFIGURATIONS=-debug-and-release
win:
- """ + removeDir("\"%LIBS_DIR%\\Qt-5.15.11\"") + """
+ """ + removeDir("\"%LIBS_DIR%\\Qt-5.15.12\"") + """
SET ANGLE_DIR=%LIBS_DIR%\\tg_angle
SET ANGLE_LIBS_DIR=%ANGLE_DIR%\\out
SET MOZJPEG_DIR=%LIBS_DIR%\\mozjpeg
@@ -1323,7 +1324,7 @@ win:
SET OPENSSL_LIBS_DIR=%OPENSSL_DIR%\\out
SET ZLIB_LIBS_DIR=%LIBS_DIR%\\zlib
SET WEBP_DIR=%LIBS_DIR%\\libwebp
- configure -prefix "%LIBS_DIR%\\Qt-5.15.11" ^
+ configure -prefix "%LIBS_DIR%\\Qt-5.15.12" ^
%CONFIGURATIONS% ^
-force-debug-info ^
-opensource ^
@@ -1358,14 +1359,14 @@ win:
jom -j16
jom -j16 install
mac:
- find ../../patches/qtbase_5.15.11 -type f -print0 | sort -z | xargs -0 git apply
+ find ../../patches/qtbase_5.15.12 -type f -print0 | sort -z | xargs -0 git apply
cd ..
CONFIGURATIONS=-debug
release:
CONFIGURATIONS=-debug-and-release
mac:
- ./configure -prefix "$USED_PREFIX/Qt-5.15.11" \
+ ./configure -prefix "$USED_PREFIX/Qt-5.15.12" \
$CONFIGURATIONS \
-force-debug-info \
-opensource \
@@ -1386,14 +1387,14 @@ mac:
""")
if buildQt6:
- stage('qt_6_2_6', """
+ stage('qt_6_2_7', """
mac:
- git clone -b v6.2.6-lts-lgpl https://github.com/qt/qt5.git qt_6_2_6
- cd qt_6_2_6
+ git clone -b v6.2.7-lts-lgpl https://github.com/qt/qt5.git qt_6_2_7
+ cd qt_6_2_7
perl init-repository --module-subset=qtbase,qtimageformats,qtsvg
-depends:patches/qtbase_6.2.6/*.patch
+depends:patches/qtbase_6.2.7/*.patch
cd qtbase
- find ../../patches/qtbase_6.2.6 -type f -print0 | sort -z | xargs -0 git apply -v
+ find ../../patches/qtbase_6.2.7 -type f -print0 | sort -z | xargs -0 git apply -v
cd ..
sed -i.bak 's/tqtc-//' {qtimageformats,qtsvg}/dependencies.yaml
@@ -1401,7 +1402,7 @@ depends:patches/qtbase_6.2.6/*.patch
release:
CONFIGURATIONS=-debug-and-release
mac:
- ./configure -prefix "$USED_PREFIX/Qt-6.2.6" \
+ ./configure -prefix "$USED_PREFIX/Qt-6.2.7" \
$CONFIGURATIONS \
-force-debug-info \
-opensource \
diff --git a/Telegram/build/version b/Telegram/build/version
index b024a1911..beba60eed 100644
--- a/Telegram/build/version
+++ b/Telegram/build/version
@@ -1,7 +1,7 @@
-AppVersion 4014002
+AppVersion 4014003
AppVersionStrMajor 4.14
-AppVersionStrSmall 4.14.2
-AppVersionStr 4.14.2
+AppVersionStrSmall 4.14.3
+AppVersionStr 4.14.3
BetaChannel 0
AlphaVersion 0
-AppVersionOriginal 4.14.2
+AppVersionOriginal 4.14.3
diff --git a/changelog.txt b/changelog.txt
index a69fb9144..da9a23547 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,3 +1,11 @@
+4.14.3 (04.01.24)
+
+- Allow sending single-time voice messages.
+- Fix payments card validation.
+- Fix crash when trying to join channels above the limit.
+- Add "Quit Telegram" to the Taskbar context menu. (Windows)
+- Fix opened windows list in the Dock icon context menu. (macOS)
+
4.14.2 (02.01.24)
- Show original senders name in reply to forward information.
diff --git a/cmake b/cmake
index 4005d7bef..9620c4674 160000
--- a/cmake
+++ b/cmake
@@ -1 +1 @@
-Subproject commit 4005d7befb3ffbbbb7851ed767d5b58373958e6d
+Subproject commit 9620c467404f15a01bb5271af02b2676c2aaf306