From 233c6b18ed841ef4b3e4c625194ecebe38c68ceb Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 2 Jan 2024 14:24:17 +0300 Subject: [PATCH 01/29] Fixed local flag for silent out messages. --- Telegram/SourceFiles/api/api_sending.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Telegram/SourceFiles/api/api_sending.cpp b/Telegram/SourceFiles/api/api_sending.cpp index a0d6f4d95750d0..850f21656b11d3 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; From 34d9a21aae9bbbccb1fe32862b0906baa1def0c1 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 2 Jan 2024 14:30:34 +0300 Subject: [PATCH 02/29] Removed ability to reschedule message as silent as it's not supported. --- .../SourceFiles/history/view/history_view_context_menu.cpp | 2 +- .../SourceFiles/history/view/history_view_schedule_box.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp index 7d58593d015da0..018423367ef01e 100644 --- a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp +++ b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp @@ -552,7 +552,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) diff --git a/Telegram/SourceFiles/history/view/history_view_schedule_box.cpp b/Telegram/SourceFiles/history/view/history_view_schedule_box.cpp index 286edd18964635..c5e60091dd6e1d 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); From a3b91da66c586331abf4fc0d986be64a3296a3ca Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 2 Jan 2024 14:31:51 +0300 Subject: [PATCH 03/29] Added silent info to tooltip of scheduled messages. --- Telegram/SourceFiles/history/view/history_view_element.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index a573eace0ea365..d2c56ca8edf470 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); + } return dateText; } From 5933535c9b678b69165473b9f93c25b74f9bd398 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 2 Jan 2024 18:03:02 +0400 Subject: [PATCH 04/29] Fix loading more saved sublists. --- Telegram/SourceFiles/data/data_saved_messages.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Telegram/SourceFiles/data/data_saved_messages.cpp b/Telegram/SourceFiles/data/data_saved_messages.cpp index 695622bbe2996b..66bc87609b5f2b 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 { From cee29616321918993dc8c955b90a7b570bb60c9c Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 2 Jan 2024 17:49:41 +0300 Subject: [PATCH 05/29] Fixed width of name text in replies with block quote icon. --- Telegram/SourceFiles/history/view/history_view_reply.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Telegram/SourceFiles/history/view/history_view_reply.cpp b/Telegram/SourceFiles/history/view/history_view_reply.cpp index 527654d9ad83ae..5830bf0c50f832 100644 --- a/Telegram/SourceFiles/history/view/history_view_reply.cpp +++ b/Telegram/SourceFiles/history/view/history_view_reply.cpp @@ -732,7 +732,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 From e52fe9ddb0e4d12ca053f2b089e207afdcc084cb Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 3 Jan 2024 12:23:41 +0300 Subject: [PATCH 06/29] Removed ability to save files with ttl. --- Telegram/SourceFiles/history/history_inner_widget.cpp | 4 +++- .../history/view/history_view_context_menu.cpp | 11 ++++++++++- .../history/view/history_view_context_menu.h | 2 ++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index da1d308750965e..353bb687075d59 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -2309,7 +2309,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/view/history_view_context_menu.cpp b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp index 018423367ef01e..22fcc710b7e9c8 100644 --- a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp +++ b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp @@ -216,7 +216,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(); @@ -1224,6 +1224,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; @@ -1521,4 +1524,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 53a45e36c18abe..4979a678918d92 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 From 7a139ecda7a919559903b864856bfb7c2a6bfcba Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 3 Jan 2024 12:34:02 +0300 Subject: [PATCH 07/29] Added ability to fast jump to replied message with right click on panel. --- Telegram/SourceFiles/history/history_widget.cpp | 4 +++- .../history/view/controls/history_view_compose_controls.cpp | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 914af7961ad99b..1c4c5757224c24 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -6334,7 +6334,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 8b9ac3393a2902..b25be58f90f7aa 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()); From 5cf0b6b50ecfba06592be279f6884a016da8c49d Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 3 Jan 2024 12:55:57 +0300 Subject: [PATCH 08/29] Slightly improved code style in voice record bar class. --- .../history_view_voice_record_bar.cpp | 71 +++++++++---------- .../controls/history_view_voice_record_bar.h | 20 +++--- 2 files changed, 43 insertions(+), 48 deletions(-) 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 3f507ca61bc0b1..ea23c9a70c2dbe 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 @@ For license and copyright information please follow this link: #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" @@ -316,7 +317,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; @@ -359,7 +360,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); @@ -627,7 +628,7 @@ class RecordLock final : public Ui::RippleButton { private: void init(); - void drawProgress(Painter &p); + void drawProgress(QPainter &p); void setProgress(float64 progress); void startLockingAnimation(float64 to); @@ -648,12 +649,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, @@ -687,7 +684,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); } @@ -704,7 +701,7 @@ void RecordLock::init() { }, lifetime()); } -void RecordLock::drawProgress(Painter &p) { +void RecordLock::drawProgress(QPainter &p) { const auto progress = _progress.current(); const auto &originTop = _st.originTop; @@ -770,7 +767,7 @@ void RecordLock::drawProgress(Painter &p) { p.setOpacity(1.); } if (isLocked()) { - paintRipple(p, _rippleRect.x(), _rippleRect.y()); + Ui::RippleButton::paintRipple(p, _rippleRect.x(), _rippleRect.y()); } { const auto &arcOffset = st::historyRecordLockIconLineSkip; @@ -808,7 +805,7 @@ void RecordLock::drawProgress(Painter &p) { 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); @@ -821,8 +818,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()); @@ -980,19 +977,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()); } @@ -1054,9 +1051,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; @@ -1080,7 +1075,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.); @@ -1143,7 +1138,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()); } @@ -1506,7 +1501,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); @@ -1529,8 +1524,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); @@ -1542,18 +1537,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); } 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 09c4916789596f..2615cf8ba05064 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 @@ -112,29 +112,29 @@ class VoiceRecordBar final : public Ui::RpWidget { 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); From ca86dce7601e7f7092372d7c207eca548a06e804 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 3 Jan 2024 16:38:31 +0300 Subject: [PATCH 09/29] Added button to voice record bar for ttl voice messages. --- .../chat_helpers/chat_helpers.style | 1 + .../history_view_voice_record_bar.cpp | 270 ++++++++++++++---- .../controls/history_view_voice_record_bar.h | 9 + 3 files changed, 218 insertions(+), 62 deletions(-) diff --git a/Telegram/SourceFiles/chat_helpers/chat_helpers.style b/Telegram/SourceFiles/chat_helpers/chat_helpers.style index 7a323faeeb2841..c86e98b759851a 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/history/view/controls/history_view_voice_record_bar.cpp b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp index ea23c9a70c2dbe..778cd1763db3ba 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 @@ -199,6 +199,175 @@ 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 = 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 + - QMargins(innerRect.width() / 2, 0, -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(); +} + +QImage TTLButton::prepareRippleMask() const { + return Ui::RippleAnimation::EllipseMask(_rippleRect.size()); +} + +QPoint TTLButton::prepareRippleStartPosition() const { + return mapFromGlobal(QCursor::pos()) - _rippleRect.topLeft(); +} + } // namespace class ListenWrap final { @@ -704,68 +873,8 @@ void RecordLock::init() { 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 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 inner = DrawLockCircle(p, rect(), _st, progress); - 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()) { Ui::RippleButton::paintRipple(p, _rippleRect.x(), _rippleRect.y()); } @@ -800,7 +909,7 @@ void RecordLock::drawProgress(QPainter &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.) { @@ -1015,6 +1124,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(); }) @@ -1090,6 +1200,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); @@ -1213,6 +1350,7 @@ void VoiceRecordBar::init() { if (to == value) { _recordingLifetime.destroy(); } + updateTTLGeometry(TTLAnimationType::TopBottom, 1. - value); }; _showListenAnimation.start(std::move(callback), 0., to, duration); }, lifetime()); @@ -1222,6 +1360,9 @@ void VoiceRecordBar::init() { _lock->locks( ) | rpl::start_with_next([=] { + _ttlButton->show(); + updateTTLGeometry(TTLAnimationType::RightTopStatic, 0); + _level->setType(VoiceRecordButton::Type::Send); _level->clicks( @@ -1243,6 +1384,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()); @@ -1318,6 +1460,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(); @@ -1465,6 +1610,7 @@ void VoiceRecordBar::hideFast() { hide(); _lock->hide(); _level->hide(); + _ttlButton->clearState(); } void VoiceRecordBar::stopRecording(StopType type) { 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 2615cf8ba05064..8ec19191c6b5f1 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 @@ -103,12 +104,19 @@ class VoiceRecordBar final : public Ui::RpWidget { 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); @@ -143,6 +151,7 @@ class VoiceRecordBar final : public Ui::RpWidget { 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; From 69f8cb595123cdd35b785ef353b0edc0e118b091 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 3 Jan 2024 16:28:36 +0300 Subject: [PATCH 10/29] Added ability to send voice message with ttl. --- Telegram/SourceFiles/api/api_common.h | 1 + Telegram/SourceFiles/api/api_media.cpp | 18 +++++---- Telegram/SourceFiles/api/api_sending.cpp | 23 +++++++++++- .../SourceFiles/history/history_widget.cpp | 10 +++++ .../history_view_voice_record_bar.cpp | 37 ++++++++++++++++--- .../controls/history_view_voice_record_bar.h | 9 ++++- .../view/media/history_view_document.cpp | 7 ++-- 7 files changed, 84 insertions(+), 21 deletions(-) diff --git a/Telegram/SourceFiles/api/api_common.h b/Telegram/SourceFiles/api/api_common.h index c8284114255225..155666a5d4ee69 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 ec8c1e4b26d1f5..a9fdec5406345c 100644 --- a/Telegram/SourceFiles/api/api_media.cpp +++ b/Telegram/SourceFiles/api/api_media.cpp @@ -79,16 +79,17 @@ 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(); 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 +99,13 @@ 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(); 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 +115,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 850f21656b11d3..d971a03f44d24b 100644 --- a/Telegram/SourceFiles/api/api_sending.cpp +++ b/Telegram/SourceFiles/api/api_sending.cpp @@ -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/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 1c4c5757224c24..1fc698dcf6c5da 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -948,6 +948,16 @@ void HistoryWidget::initVoiceRecordBar() { } return false; }); + _voiceRecordBar->setTTLFilter([=] { + if (const auto peer = _history ? _history->peer : nullptr) { + if (const auto user = peer->asUser()) { + if (!user->isSelf() && !user->isBot()) { + return true; + } + } + } + return false; + }); const auto applyLocalDraft = [=] { if (_history && _history->localDraft({})) { 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 778cd1763db3ba..bc2cc83a5a8739 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 @@ -358,6 +358,7 @@ TTLButton::TTLButton( void TTLButton::clearState() { Ui::AbstractButton::setDisabled(true); update(); + Ui::RpWidget::hide(); } QImage TTLButton::prepareRippleMask() const { @@ -1360,7 +1361,9 @@ void VoiceRecordBar::init() { _lock->locks( ) | rpl::start_with_next([=] { - _ttlButton->show(); + if (_hasTTLFilter && _hasTTLFilter()) { + _ttlButton->show(); + } updateTTLGeometry(TTLAnimationType::RightTopStatic, 0); _level->setType(VoiceRecordButton::Type::Send); @@ -1472,10 +1475,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(), @@ -1610,7 +1617,7 @@ void VoiceRecordBar::hideFast() { hide(); _lock->hide(); _level->hide(); - _ttlButton->clearState(); + [[maybe_unused]] const auto s = takeTTLState(); } void VoiceRecordBar::stopRecording(StopType type) { @@ -1632,7 +1639,17 @@ void VoiceRecordBar::stopRecording(StopType type) { window()->activateWindow(); const auto duration = Duration(data.samples); if (type == StopType::Send) { - _sendVoiceRequests.fire({ data.bytes, data.waveform, duration }); + const auto options = Api::SendOptions{ + .ttlSeconds = takeTTLState() + ? std::numeric_limits::max() + : 0 + }; + _sendVoiceRequests.fire({ + data.bytes, + data.waveform, + duration, + options, + }); } else if (type == StopType::Listen) { _listen = std::make_unique( this, @@ -1702,11 +1719,15 @@ void VoiceRecordBar::drawMessage(QPainter &p, float64 recordActive) { void VoiceRecordBar::requestToSendWithOptions(Api::SendOptions options) { if (isListenState()) { const auto data = _listen->data(); + if (takeTTLState()) { + options.ttlSeconds = std::numeric_limits::max(); + } _sendVoiceRequests.fire({ data->bytes, data->waveform, Duration(data->samples), - options }); + options, + }); } } @@ -1825,6 +1846,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 8ec19191c6b5f1..31c0eb30e3735b 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 @@ -54,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, @@ -88,7 +89,8 @@ class VoiceRecordBar final : public Ui::RpWidget { 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; @@ -146,6 +148,8 @@ class VoiceRecordBar final : public Ui::RpWidget { void computeAndSetLockProgress(QPoint globalPos); + [[nodiscard]] bool takeTTLState() const; + const style::RecordBar &_st; const not_null _outerContainer; const std::shared_ptr _show; @@ -170,7 +174,8 @@ class VoiceRecordBar final : public Ui::RpWidget { Ui::Text::String _message; - Fn _startRecordingFilter; + FilterCallback _startRecordingFilter; + FilterCallback _hasTTLFilter; bool _warningShown = false; diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_document.cpp index e3e2808cdc2f3d..aeb2372082993d 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_document.cpp @@ -718,10 +718,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 +894,9 @@ void Document::draw( .highlight = highlightRequest ? &*highlightRequest : nullptr, }); } + if (_parent->data()->media()->ttlSeconds()) { + DrawCornerBadgeTTL(p, stm->msgFileBg, inner); + } } Ui::BubbleRounding Document::thumbRounding( From 098e797045c78be630bfa199a86c6f4517e2331f Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Thu, 4 Jan 2024 13:22:20 +0300 Subject: [PATCH 11/29] Fixed drawing of ttl circles with non-default scale. --- Telegram/SourceFiles/dialogs/dialogs_row.cpp | 2 +- .../history_view_voice_record_bar.cpp | 9 +++++-- .../view/media/history_view_document.cpp | 27 ++++++++++++------- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/Telegram/SourceFiles/dialogs/dialogs_row.cpp b/Telegram/SourceFiles/dialogs/dialogs_row.cpp index 54247193cdee68..29f84995615aa5 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_row.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_row.cpp @@ -86,7 +86,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/view/controls/history_view_voice_record_bar.cpp b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp index bc2cc83a5a8739..d878583eb56e8b 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 @@ -312,7 +312,8 @@ TTLButton::TTLButton( Ui::RippleButton::paintRipple(p, _rippleRect.x(), _rippleRect.y()); - const auto innerRect = inner - st::historyRecordLockMargin * 2; + const auto innerRect = QRectF(inner) + - st::historyRecordLockMargin * 2; auto hq = PainterHighQualityEnabler(p); p.setFont(st::semiboldFont); @@ -331,7 +332,11 @@ TTLButton::TTLButton( { 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); diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_document.cpp index aeb2372082993d..4071c5b359b6a0 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_document.cpp @@ -53,30 +53,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 +92,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); @@ -895,7 +901,10 @@ void Document::draw( }); } if (_parent->data()->media()->ttlSeconds()) { - DrawCornerBadgeTTL(p, stm->msgFileBg, inner); + const auto &fg = context.outbg + ? st::historyFileOutIconFg + : st::historyFileInIconFg; + DrawCornerBadgeTTL(p, stm->msgFileBg, fg, inner); } } From d8d9441731166bf027a58ebdda39bdb00ce5d0fa Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Thu, 4 Jan 2024 13:39:43 +0300 Subject: [PATCH 12/29] Slightly improved code style in HistoryView::Document. --- .../data/data_document_resolver.cpp | 5 +- .../view/media/history_view_document.cpp | 56 +++++++++---------- .../view/media/history_view_document.h | 18 +----- 3 files changed, 31 insertions(+), 48 deletions(-) diff --git a/Telegram/SourceFiles/data/data_document_resolver.cpp b/Telegram/SourceFiles/data/data_document_resolver.cpp index 05d23ecdf2d761..2c34719ff3140b 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/history/view/media/history_view_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_document.cpp index 4071c5b359b6a0..cd1501e9794c21 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 @@ For license and copyright information please follow this link: #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" @@ -145,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(); @@ -648,7 +665,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()) { @@ -970,29 +987,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); } @@ -1709,7 +1703,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 5e57308ed57297..5fa8dc1dace5ca 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 @@ class Document final 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 @@ class Document final 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 From 758219265a1c70eb0a347dedc5f070ea10bc1fcf Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Thu, 28 Dec 2023 12:24:37 +0300 Subject: [PATCH 13/29] Updated Qt to 6.2.7 on macOS. --- CMakeLists.txt | 2 +- Telegram/build/prepare/prepare.py | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c8225654e8e483..d2c04ab8f09d38 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,7 +62,7 @@ if (NOT DESKTOP_APP_USE_PACKAGED) if (WIN32) set(qt_version 5.15.11) 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/build/prepare/prepare.py b/Telegram/build/prepare/prepare.py index c29d931785d9ec..2256edba9f1383 100644 --- a/Telegram/build/prepare/prepare.py +++ b/Telegram/build/prepare/prepare.py @@ -418,7 +418,7 @@ def runStages(): stage('patches', """ git clone https://github.com/desktop-app/patches.git cd patches - git checkout 58c8cd0c0f + git checkout 182c4076ab """) stage('msys64', """ @@ -1386,14 +1386,14 @@ def runStages(): """) 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 +1401,7 @@ def runStages(): 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 \ From c7f11eb05a8f355192327761ca4ca813a10300e0 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Thu, 28 Dec 2023 13:57:27 +0300 Subject: [PATCH 14/29] Updated Qt to 5.15.12 on Windows. --- CMakeLists.txt | 2 +- Telegram/build/prepare/prepare.py | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d2c04ab8f09d38..abea2aaf4e766a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,7 +60,7 @@ 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.7) endif() diff --git a/Telegram/build/prepare/prepare.py b/Telegram/build/prepare/prepare.py index 2256edba9f1383..5964081ab4b23d 100644 --- a/Telegram/build/prepare/prepare.py +++ b/Telegram/build/prepare/prepare.py @@ -418,7 +418,7 @@ def runStages(): stage('patches', """ git clone https://github.com/desktop-app/patches.git cd patches - git checkout 182c4076ab + git checkout 26f2387219 """) stage('msys64', """ @@ -1299,23 +1299,23 @@ def runStages(): """) 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 +1323,7 @@ def runStages(): 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 +1358,14 @@ def runStages(): 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 \ From d2246337a205de93b6ca2002c0c57aa0416c3530 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 4 Jan 2024 09:33:13 +0400 Subject: [PATCH 15/29] Fix crash in ChannelsLimitBox. Fixes https://bugs.telegram.org/c/35214 Deleting `placeholder` in content->heightValue() resulted in `delete` sometimes being called deep inside the layer->show() which already had a reference to that `placeholder` saved and was accessed after -> crash. --- .../SourceFiles/boxes/premium_limits_box.cpp | 41 +++++++++++++------ 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/Telegram/SourceFiles/boxes/premium_limits_box.cpp b/Telegram/SourceFiles/boxes/premium_limits_box.cpp index 60eb5ecde36867..ad8d313df0e46e 100644 --- a/Telegram/SourceFiles/boxes/premium_limits_box.cpp +++ b/Telegram/SourceFiles/boxes/premium_limits_box.cpp @@ -68,6 +68,8 @@ class InactiveController final : public PeerListController { 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 @@ class InactiveController final : public PeerListController { TimeId date) const; const not_null _session; + rpl::variable _count; mtpRequestId _requestId = 0; }; @@ -91,12 +94,15 @@ class PublicsController final : public PeerListController { 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()); From 973f91b5e4a7dc87e56a5eef8cb79b44a62abcaf Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 3 Jan 2024 22:14:34 +0400 Subject: [PATCH 16/29] Add "Quit Telegram" taskbar menu item. Fixes #1161. --- Telegram/Resources/icons/win_quit.png | Bin 0 -> 406 bytes Telegram/Resources/icons/win_quit@2x.png | Bin 0 -> 686 bytes Telegram/Resources/icons/win_quit@3x.png | Bin 0 -> 952 bytes .../platform/win/integration_win.cpp | 92 ++++++++++++- .../platform/win/integration_win.h | 4 + .../SourceFiles/platform/win/specific_win.cpp | 3 +- .../SourceFiles/platform/win/tray_win.cpp | 123 ++++++++++++++++-- Telegram/SourceFiles/platform/win/tray_win.h | 3 + Telegram/SourceFiles/window/window.style | 4 + Telegram/lib_ui | 2 +- 10 files changed, 214 insertions(+), 17 deletions(-) create mode 100644 Telegram/Resources/icons/win_quit.png create mode 100644 Telegram/Resources/icons/win_quit@2x.png create mode 100644 Telegram/Resources/icons/win_quit@3x.png diff --git a/Telegram/Resources/icons/win_quit.png b/Telegram/Resources/icons/win_quit.png new file mode 100644 index 0000000000000000000000000000000000000000..a823f133e81b47e7d767c0bb3abbc9f0deedc772 GIT binary patch literal 406 zcmV;H0crk;P)+lEJEiKoo{g>4@1z$W>ruK0)C^B52Vg1U-S^L%8Sx ze1d!pF$iLyU9?KjmU9=0NVExExN`2o?!DeL=wJTxeKY64v;d&r?@uNZgb@5BP1ED? zm}ME%vs^CoJWrD3tCGj#5k--zstp1mWW8R$lswPx_j|{2>U>*K6xVfM+C0y9yPcva zr92o6{saJ^l-6%LpU;QG0RU#R+2wMX&*#qrO6hn!ZkV+a%d)a8dpe&8Rfny%wry*g z_RhK8ZrknlpMWurECvK@c#;zVAzt)P4tbyIon9OWO0iUaz-UEbjOF zTfs1l&1M4tx~_8^SJD8$7Dd6bY+dMdI%SVB#u)$h?Jx{Y(-cLKt7JGFu2!oc2pXQA zPNzwd&{|HXlO#!Xz6Agb!;D6wm+yVOUK@A&2H&KiL5SA>iU0rr07*qoM6N<$f+hR1 Ay#N3J literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/win_quit@2x.png b/Telegram/Resources/icons/win_quit@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..569097eda9395ba7da7e94a75bfc6030d794d739 GIT binary patch literal 686 zcmV;f0#W^mP)ne@qgZPP1qGM3LO};b1aVN8Qc%|} z>Q?s-9onh52rlic;#jKPD+ul)8VsT??WEwJ#i5Gie#854sjogIJxg-Q$@%5Jm%KcH zKbDFdj*gD5udiJ$m%(75S(nSDBuUk3wO+4p2l4y;pP!$|CRvuBpPzZ2XYIgZv52B5 z2!brj?RI-S9@DHG$6Z`p==FL4NT<{H_xDVMTrP)*v)Rn+^=>rp@9)39z9Qmsxip*2 zOn`2;i-?&_hRF?Ze0(g+G9pH!Q5L`2ZnpzKr_*5sj7B3ejO5160F_Dw0J1DI0#;_V zT1`ru&31cxOXg+`fIWAm>2wMJlgWgX*=+XZ<)v1u8I8s@Zu0Ua5(##I&*yu5eAH^S zq)aB0Bt#U&HH;kqKXrF^M`b7i_>G|yfXYx1u$IBmtf!}^H#awjhlkrTK0ZEz!Jxz8 zs8lL$x0~8QKA&e?{(jNb)fKgaQmN$ecn%H@w(Wr9IHS?Xaol`9mn2EyIXFK*9}EVF zxL7PAkqCgIle{KfLBRTSr2y3Q-2j)Dm#I`rqtTG^?Cgx1z8gRkMMR9p*VSS%KcMcP&Md_D(&)qt{SZ*LC(zQ4a& z%<5LF1pt9SfHB?abP9q10HP=|-SF`6K<4@B>B(xfYU$GJ^`TIx-|r*ha5!B3(Kd+Z z`DU}Z?JCB&XZbIkPFE-t$Zlt&zP`S~;V^r+YIPMX0!MA_j`MLYin!o@9*|_`ThQM zI;~sd_4PFv4BB7=A;uDo6^y8in5Iy*bNySvjgjp%-c z5k;}Bt*xr63bn|x?DP2^A0H`=BuT>m@A~>0LP!x(UtfQ4aDa1GS63-*004)FhbTo+ z6rayWol{+1{qXRBqTb%#IF6$XdU<(4DamA#+6J+>xQIJR6h*oaRuBYK-Q3(*6iTPl zxW=(X3*q^Oa1@(hOki1-QplnNAwxq$M@L7qv$F-~Tb_JIE{L&*R8_^b+wI=k+Tu8_ zudmPJ@k~xm>bm}83Lb__OG_4oJRXlM%et;-G8vc4h1(k&8&y>`P6}qdV51NK!0Yvn zjg7h8?!5L$Bx0P<&75+%oQ*;zOixb}IXNao>g1#lk(0whg`J!iD&SNSArmK_@cxE| zhL)BV8--G-)bjH3)YKHZlq5-2)o?gW)I(ieU7w$y`v0fDzn|z`77B$bD=Y2k8B+p* z0Fh84k+8lNAmQTTf@lmS5(&TG4xv$M0mzhAPaY;<%~(=0}^-cEf&favJxz%`C7nw6Cm{6Nmk%uw6(^z`7FCY4H2=P<3Ut>@?GxNp|i z*EcseZ*OmNxg24HD2l;gaBgm{qM`z|OiWB{Y-~_FfoL@P&H9#>HHk #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 dae97841196fad..0b29007d32856f 100644 --- a/Telegram/SourceFiles/platform/win/integration_win.h +++ b/Telegram/SourceFiles/platform/win/integration_win.h @@ -37,8 +37,12 @@ class WindowsIntegration final 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 77cc18de50d42e..ef5c88e3518f8c 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 b1337c6d9c7223..2a8e4615e028b7 100644 --- a/Telegram/SourceFiles/platform/win/tray_win.cpp +++ b/Telegram/SourceFiles/platform/win/tray_win.cpp @@ -26,6 +26,7 @@ For license and copyright information please follow this link: #include #include #include +#include namespace Platform { @@ -33,18 +34,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"; @@ -64,6 +57,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); @@ -339,8 +349,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 53631e55657a35..cb79c3beb5aeff 100644 --- a/Telegram/SourceFiles/platform/win/tray_win.h +++ b/Telegram/SourceFiles/platform/win/tray_win.h @@ -59,6 +59,7 @@ class Tray final { bool smallIcon, bool monochrome, bool supportMode); + [[nodiscard]] static QString QuitJumpListIconPath(); private: base::unique_qptr _icon; @@ -73,4 +74,6 @@ class Tray final { }; +void RefreshTaskbarThemeValue(); + } // namespace Platform diff --git a/Telegram/SourceFiles/window/window.style b/Telegram/SourceFiles/window/window.style index d15a67a4ed9d2c..38621c69bc6c4c 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/lib_ui b/Telegram/lib_ui index 99e36f9ac64048..7fef09421c2b71 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 99e36f9ac64048a6b7fcb0e6ee2e8eaca48935e1 +Subproject commit 7fef09421c2b71e5ab9cf481c0fcf2a0b6d2daf0 From ce78074df7c7fc00640eb8c0b25bff75f8608fb5 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 4 Jan 2024 10:22:46 +0400 Subject: [PATCH 17/29] Fix build on Windows. --- Telegram/SourceFiles/history/history_widget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 1fc698dcf6c5da..7cbe283fe3e8ce 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -949,7 +949,7 @@ void HistoryWidget::initVoiceRecordBar() { return false; }); _voiceRecordBar->setTTLFilter([=] { - if (const auto peer = _history ? _history->peer : nullptr) { + if (const auto peer = _history ? _history->peer.get() : nullptr) { if (const auto user = peer->asUser()) { if (!user->isSelf() && !user->isBot()) { return true; From 5a28e69f1aad950700d31c047c140cbea540b84e Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 4 Jan 2024 11:39:06 +0400 Subject: [PATCH 18/29] More cleaning in force-reconfiguration. --- cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake b/cmake index 4005d7befb3ffb..9620c467404f15 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 4005d7befb3ffbbbb7851ed767d5b58373958e6d +Subproject commit 9620c467404f15a01bb5271af02b2676c2aaf306 From 66afcbdae8f7642694bc04c9bc41b97aca5805b4 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 4 Jan 2024 15:07:36 +0400 Subject: [PATCH 19/29] Backport windows list in Dock Menu from Qt 6.3.*. --- Telegram/build/prepare/prepare.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/build/prepare/prepare.py b/Telegram/build/prepare/prepare.py index 5964081ab4b23d..f3d22173b8859d 100644 --- a/Telegram/build/prepare/prepare.py +++ b/Telegram/build/prepare/prepare.py @@ -418,7 +418,7 @@ def runStages(): stage('patches', """ git clone https://github.com/desktop-app/patches.git cd patches - git checkout 26f2387219 + git checkout d3107bf4a5 """) stage('msys64', """ From bb31357c5876c2c6159e5f52bc4863fe4ada2292 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 4 Jan 2024 17:20:45 +0400 Subject: [PATCH 20/29] More strict check for custom emoji dimensions. --- Telegram/SourceFiles/data/data_document.cpp | 3 +-- Telegram/SourceFiles/data/stickers/data_custom_emoji.cpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp index 32ff4be7575b82..807d1927ff3406 100644 --- a/Telegram/SourceFiles/data/data_document.cpp +++ b/Telegram/SourceFiles/data/data_document.cpp @@ -483,8 +483,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/stickers/data_custom_emoji.cpp b/Telegram/SourceFiles/data/stickers/data_custom_emoji.cpp index 1f80c53f636a26..5b271b5b629133 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.) From 3b50bc71b3afad43a10743b60d9f158f750e2c25 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Thu, 4 Jan 2024 17:45:59 +0300 Subject: [PATCH 21/29] Fixed possible rare crash from voice messages with ttl. --- .../SourceFiles/history/view/media/history_view_document.cpp | 5 +++-- Telegram/SourceFiles/mainwidget.cpp | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_document.cpp index cd1501e9794c21..7ca7bc747f0616 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_document.cpp @@ -346,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(); @@ -917,7 +918,7 @@ void Document::draw( .highlight = highlightRequest ? &*highlightRequest : nullptr, }); } - if (_parent->data()->media()->ttlSeconds()) { + if (_parent->data()->media() && _parent->data()->media()->ttlSeconds()) { const auto &fg = context.outbg ? st::historyFileOutIconFg : st::historyFileInIconFg; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index a62d538261819e..fe92a6de176d67 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) { From 16a2d4ec96cd8f323cd15157ce1595865856f8f4 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 4 Jan 2024 18:17:52 +0400 Subject: [PATCH 22/29] Fix wrong "Webview process crashed." message. --- .../SourceFiles/payments/ui/payments_panel.cpp | 15 +++++++++++++-- .../ui/chat/attach/attach_bot_webview.cpp | 14 ++++++++++++-- Telegram/lib_ui | 2 +- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/Telegram/SourceFiles/payments/ui/payments_panel.cpp b/Telegram/SourceFiles/payments/ui/payments_panel.cpp index 5e5c872de2afa7..bc2817d52b2809 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/ui/chat/attach/attach_bot_webview.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp index 209444ff10b007..c94f26294e7fb6 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/lib_ui b/Telegram/lib_ui index 7fef09421c2b71..30c5dfe6f65bab 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 7fef09421c2b71e5ab9cf481c0fcf2a0b6d2daf0 +Subproject commit 30c5dfe6f65babf234c889959061c97c4a2f391d From 52ef8e780a174650d4d91addf31e90b80681b319 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 4 Jan 2024 18:20:26 +0400 Subject: [PATCH 23/29] Update zlib/minizip. Fixes #27313. --- Telegram/ThirdParty/minizip/crypt.h | 12 +- Telegram/ThirdParty/minizip/ioapi.c | 61 +-- Telegram/ThirdParty/minizip/ioapi.h | 38 +- Telegram/ThirdParty/minizip/unzip.c | 515 +++++++------------- Telegram/ThirdParty/minizip/unzip.h | 136 +++--- Telegram/ThirdParty/minizip/zip.c | 332 ++++++------- Telegram/ThirdParty/minizip/zip.h | 303 ++++++------ Telegram/build/docker/centos_env/Dockerfile | 5 +- Telegram/build/prepare/prepare.py | 3 +- 9 files changed, 593 insertions(+), 812 deletions(-) diff --git a/Telegram/ThirdParty/minizip/crypt.h b/Telegram/ThirdParty/minizip/crypt.h index 1cc41f19d78ddf..f4b93b78dc31cc 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 0ca29db6af61c3..782d32469ae5d5 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 ae9ca7e8337d2f..a2d2e6e60d9250 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 3036b470b72b83..ed763f89f1f87d 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,24 @@ 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 @@ -227,127 +217,50 @@ 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, +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) - *pX = x; - 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; + 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; - return err; + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } } -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; +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; + 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.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.disk_num_start == MAXU32) - { - /* Disk Start Number */ - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != 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_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 == 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 6f95e94d7568f6..14105840f6d247 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 unzGetCurrentFileInfo OF((unzFile file, - unz_file_info *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(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 66d693f85a5809..e2e9da07c5f307 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 7e4509d77bee59..3e230d3405f603 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, - int append, - zipcharpc* globalcomment, - zlib_filefunc_def* pzlib_filefunc_def)); +extern zipFile ZEXPORT zipOpen2(const char *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc_def* pzlib_filefunc_def); -extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname, +extern zipFile ZEXPORT zipOpen2_64(const void *pathname, int append, zipcharpc* globalcomment, - zlib_filefunc64_def* pzlib_filefunc_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 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)); + 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 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 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_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(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(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_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(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(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_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(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(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 253b0207a991ce..823f5f2ff4999e 100644 --- a/Telegram/build/docker/centos_env/Dockerfile +++ b/Telegram/build/docker/centos_env/Dockerfile @@ -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 f3d22173b8859d..51cc2c2982de18 100644 --- a/Telegram/build/prepare/prepare.py +++ b/Telegram/build/prepare/prepare.py @@ -513,8 +513,9 @@ def runStages(): """) 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% ^ From 254ca57bf328784e1c612f5c3618a8f2fdad04b0 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 4 Jan 2024 18:36:32 +0400 Subject: [PATCH 24/29] Fix webm emoji/stickers with unknown dimensions. --- Telegram/SourceFiles/data/data_document.cpp | 46 +++++++++++++++++---- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp index 807d1927ff3406..e5b1f5be67ff5f 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() From 9287af17528de4d5f6bb6b6cc36ffbd39e9fdb38 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Thu, 4 Jan 2024 16:17:04 +0400 Subject: [PATCH 25/29] Update patches commit in Dockerfile --- Telegram/build/docker/centos_env/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/build/docker/centos_env/Dockerfile b/Telegram/build/docker/centos_env/Dockerfile index 823f5f2ff4999e..d4a4507265eff2 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 5f434041ae25d0ae0f7936bfe76c4535f6151ba9 \ && git reset --hard FETCH_HEAD \ && rm -rf .git From b38e72dcd98dd63406184c0cf7b8900f9738e08e Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 4 Jan 2024 18:55:27 +0400 Subject: [PATCH 26/29] Fix typo in Dockerfile. --- Telegram/build/docker/centos_env/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/build/docker/centos_env/Dockerfile b/Telegram/build/docker/centos_env/Dockerfile index d4a4507265eff2..95e11eed36f243 100644 --- a/Telegram/build/docker/centos_env/Dockerfile +++ b/Telegram/build/docker/centos_env/Dockerfile @@ -70,7 +70,7 @@ RUN git clone -b nasm-2.15.05 --depth=1 {{ GIT }}/netwide-assembler/nasm.git \ && rm -rf nasm FROM builder AS zlib -RUN git init zlib +RUN git init zlib \ && cd zlib \ && git remote add origin {{ GIT }}/madler/zlib.git \ && git fetch --depth=1 origin 643e17b7498d12ab8d15565662880579692f769d \ From 6e6f15e711b4ed51cba72f2948f8a9410572347b Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 4 Jan 2024 19:01:53 +0400 Subject: [PATCH 27/29] Version 4.14.3. - 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) --- Telegram/Resources/uwp/AppX/AppxManifest.xml | 2 +- Telegram/Resources/winrc/Telegram.rc | 8 ++++---- Telegram/Resources/winrc/Updater.rc | 8 ++++---- Telegram/SourceFiles/core/version.h | 4 ++-- Telegram/build/version | 8 ++++---- Telegram/lib_ui | 2 +- changelog.txt | 8 ++++++++ cmake | 2 +- 8 files changed, 25 insertions(+), 17 deletions(-) diff --git a/Telegram/Resources/uwp/AppX/AppxManifest.xml b/Telegram/Resources/uwp/AppX/AppxManifest.xml index 6dee69ef629934..bc517dc13f9c29 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 e162c8d1ec454e..ec675b7e329a6d 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", "Telegram FZ-LLC" VALUE "FileDescription", "Telegram Desktop" - VALUE "FileVersion", "4.14.2.0" + VALUE "FileVersion", "4.14.3.0" VALUE "LegalCopyright", "Copyright (C) 2014-2024" VALUE "ProductName", "Telegram 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 9e5612b20a2b3e..26208ac82461cd 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", "Telegram FZ-LLC" VALUE "FileDescription", "Telegram Desktop Updater" - VALUE "FileVersion", "4.14.2.0" + VALUE "FileVersion", "4.14.3.0" VALUE "LegalCopyright", "Copyright (C) 2014-2024" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "4.14.2.0" + VALUE "ProductVersion", "4.14.3.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h index 868f37caec222f..939e36683d055b 100644 --- a/Telegram/SourceFiles/core/version.h +++ b/Telegram/SourceFiles/core/version.h @@ -22,7 +22,7 @@ constexpr auto AppId = "{53F49750-6209-4FBF-9CA8-7A333C87D1ED}"_cs; constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs; constexpr auto AppName = "Telegram Desktop"_cs; constexpr auto AppFile = "Telegram"_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/build/version b/Telegram/build/version index b024a191106c55..beba60eed6c384 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/Telegram/lib_ui b/Telegram/lib_ui index 30c5dfe6f65bab..99e36f9ac64048 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 30c5dfe6f65babf234c889959061c97c4a2f391d +Subproject commit 99e36f9ac64048a6b7fcb0e6ee2e8eaca48935e1 diff --git a/changelog.txt b/changelog.txt index a69fb91442902e..a025ffcdf6fa19 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 9620c467404f15..4005d7befb3ffb 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 9620c467404f15a01bb5271af02b2676c2aaf306 +Subproject commit 4005d7befb3ffbbbb7851ed767d5b58373958e6d From f25638f492c3c1816d76173bc73f04c5d74ad635 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 4 Jan 2024 19:04:06 +0400 Subject: [PATCH 28/29] Version 4.14.3: Fix submodule revert. --- Telegram/lib_ui | 2 +- changelog.txt | 2 +- cmake | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 99e36f9ac64048..30c5dfe6f65bab 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 99e36f9ac64048a6b7fcb0e6ee2e8eaca48935e1 +Subproject commit 30c5dfe6f65babf234c889959061c97c4a2f391d diff --git a/changelog.txt b/changelog.txt index a025ffcdf6fa19..da9a23547ff8dd 100644 --- a/changelog.txt +++ b/changelog.txt @@ -4,7 +4,7 @@ - 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) +- Fix opened windows list in the Dock icon context menu. (macOS) 4.14.2 (02.01.24) diff --git a/cmake b/cmake index 4005d7befb3ffb..9620c467404f15 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 4005d7befb3ffbbbb7851ed767d5b58373958e6d +Subproject commit 9620c467404f15a01bb5271af02b2676c2aaf306 From 37d1940993ce1a7962de532a21929c8e41f10e70 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Thu, 4 Jan 2024 18:19:24 +0300 Subject: [PATCH 29/29] Version 4.14.3: Fixed ttl period for sending of voice messages with ttl. --- Telegram/SourceFiles/api/api_media.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Telegram/SourceFiles/api/api_media.cpp b/Telegram/SourceFiles/api/api_media.cpp index a9fdec5406345c..a76cb4b67586fa 100644 --- a/Telegram/SourceFiles/api/api_media.cpp +++ b/Telegram/SourceFiles/api/api_media.cpp @@ -80,7 +80,9 @@ MTPInputMedia PrepareUploadedPhoto( RemoteFileInfo info) { using Flag = MTPDinputMediaUploadedPhoto::Flag; const auto spoiler = item->media() && item->media()->hasSpoiler(); - const auto ttlSeconds = item->media() && item->media()->ttlSeconds(); + const auto ttlSeconds = item->media() + ? item->media()->ttlSeconds() + : 0; const auto flags = (spoiler ? Flag::f_spoiler : Flag()) | (info.attachedStickers.empty() ? Flag() : Flag::f_stickers) | (ttlSeconds ? Flag::f_ttl_seconds : Flag()); @@ -100,7 +102,9 @@ MTPInputMedia PrepareUploadedDocument( } using Flag = MTPDinputMediaUploadedDocument::Flag; const auto spoiler = item->media() && item->media()->hasSpoiler(); - const auto ttlSeconds = item->media() && item->media()->ttlSeconds(); + 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())