This commit is contained in:
Berkus Decker 2017-12-01 06:22:21 +00:00 committed by GitHub
commit 5374f4799a
766 changed files with 91255 additions and 9837 deletions

4
.gitignore vendored
View File

@ -55,3 +55,7 @@ xcuserdata
/Linux/
/Telegram/Makefile
*.*~
_build_
_conan_build_

12
.gitmodules vendored
View File

@ -1,12 +0,0 @@
[submodule "Telegram/ThirdParty/libtgvoip"]
path = Telegram/ThirdParty/libtgvoip
url = https://github.com/telegramdesktop/libtgvoip
[submodule "Telegram/ThirdParty/variant"]
path = Telegram/ThirdParty/variant
url = https://github.com/mapbox/variant
[submodule "Telegram/ThirdParty/GSL"]
path = Telegram/ThirdParty/GSL
url = https://github.com/Microsoft/GSL.git
[submodule "Telegram/ThirdParty/Catch"]
path = Telegram/ThirdParty/Catch
url = https://github.com/philsquared/Catch

42
CMakeLists.txt Normal file
View File

@ -0,0 +1,42 @@
cmake_minimum_required(VERSION 3.10)
project(telegram-desktop)
if(EXISTS ${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
else()
find_package(OpenSSL REQUIRED)
endif()
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cotire/CMake;${PROJECT_SOURCE_DIR}/modules/")
include(cotire)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Ignore automoc-ing generated files (@tbd?)
cmake_policy(SET CMP0071 OLD)
# Needs OpenAL-SOFT
# Install via `brew install openal-soft` and configure with `env OPENALDIR=/usr/local/opt/openal-soft`
find_package(OpenAL REQUIRED)
find_package(FFmpeg REQUIRED)
find_package(Zlib REQUIRED)
#@todo Turn into find_package(Opus REQUIRED)
find_library(OPUS_LIB opus)
find_path(OPUS_INCLUDE_DIR opus/opus.h)
if (NOT SWSCALE_FOUND)
message(FATAL_ERROR "FFmpeg swscale is required")
endif()
if (NOT SWRESAMPLE_FOUND)
message(FATAL_ERROR "FFmpeg swresample is required")
endif()
if (NOT OPUS_LIB)
message(FATAL_ERROR "opus codec is required")
endif()
add_subdirectory(Telegram)

View File

@ -1,6 +1,14 @@
# [Telegram Desktop][telegram_desktop] Official Messenger
# [Telegram Desktop][telegram_desktop] - pro.cxx fork
This is the complete source code and the build instructions for the alpha version of the official desktop client for the [Telegram][telegram] messenger, based on the [Telegram API][telegram_api] and the [MTProto][telegram_proto] secure protocol.
This is the complete source code and the build instructions for the alpha version of the pro.cxx fork of desktop client for the [Telegram][telegram] messenger, based on the [Telegram API][telegram_api] and the [MTProto][telegram_proto] secure protocol.
## Build instructions
mkdir _build_
cd _build_
conan install .. --build missing
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=/usr/local/opt/qt5/ ..
ninja
[![Version](https://badge.fury.io/gh/telegramdesktop%2Ftdesktop.svg)](https://github.com/telegramdesktop/tdesktop/releases)
[![Build Status](https://travis-ci.org/telegramdesktop/tdesktop.svg?branch=dev)](https://travis-ci.org/telegramdesktop/tdesktop)
@ -28,7 +36,6 @@ The source code is published under GPLv3 with OpenSSL exception, the license is
* liblzma ([public domain](http://tukaani.org/xz/))
* Google Breakpad ([License](https://chromium.googlesource.com/breakpad/breakpad/+/master/LICENSE))
* Google Crashpad ([Apache License 2.0](https://chromium.googlesource.com/crashpad/crashpad/+/master/LICENSE))
* GYP ([BSD License](https://github.com/bnoordhuis/gyp/blob/master/LICENSE))
* Ninja ([Apache License 2.0](https://github.com/ninja-build/ninja/blob/master/COPYING))
* OpenAL Soft ([LGPL](http://kcat.strangesoft.net/openal.html))
* Opus codec ([BSD License](http://www.opus-codec.org/license/))
@ -39,10 +46,6 @@ The source code is published under GPLv3 with OpenSSL exception, the license is
* Emoji alpha codes ([MIT License](https://github.com/emojione/emojione/blob/master/extras/alpha-codes/LICENSE.md))
* Catch test framework ([Boost License](https://github.com/philsquared/Catch/blob/master/LICENSE.txt))
## Build instructions
* [Visual Studio 2017][msvc]
* [Xcode 8][xcode]
* [GYP/CMake on GNU/Linux][cmake]
[//]: # (LINKS)

671
Telegram/CMakeLists.txt Normal file
View File

@ -0,0 +1,671 @@
find_package(Qt5 COMPONENTS Core Gui Widgets Network REQUIRED)
# defines
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
add_definitions(-DQ_OS_LINUX64)
else()
add_definitions(-DQ_OS_LINUX32)
endif()
endif()
find_program(CCACHE ccache)
if (CCACHE)
message(STATUS "Enabling ccache")
set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE})
set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE})
endif()
##======================
## Codegen Tools
##======================
include_directories(SourceFiles)
add_subdirectory(SourceFiles/codegen)
#-w<(PRODUCT_DIR)/../.. -- wtf is that
add_custom_command(
COMMENT "Generating palette"
OUTPUT
styles/palette.h
styles/palette.cpp
COMMAND
codegen_style -I${CMAKE_CURRENT_SOURCE_DIR}/Resources -I${CMAKE_CURRENT_SOURCE_DIR}
-o${CMAKE_CURRENT_BINARY_DIR}/styles -w${CMAKE_SOURCE_DIR}
colors.palette
WORKING_DIRECTORY styles
DEPENDS
codegen_style
${CMAKE_CURRENT_SOURCE_DIR}/Resources/colors.palette
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/Resources/colors.palette
)
add_custom_target(palette_output
DEPENDS styles/palette.h styles/palette.cpp)
add_custom_command(
COMMENT "Generating numbers"
OUTPUT
numbers.h
numbers.cpp
COMMAND
codegen_numbers -o${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/Resources/numbers.txt
WORKING_DIRECTORY .
DEPENDS
codegen_numbers
${CMAKE_CURRENT_SOURCE_DIR}/Resources/numbers.txt
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/Resources/numbers.txt
)
add_custom_target(numbers_output
DEPENDS numbers.h numbers.cpp)
add_custom_command(
COMMENT "Generating langs"
OUTPUT
lang_auto.h
lang_auto.cpp
COMMAND
codegen_lang -o${CMAKE_CURRENT_BINARY_DIR} -w${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/Resources/langs/lang.strings
WORKING_DIRECTORY .
DEPENDS
codegen_lang
${CMAKE_CURRENT_SOURCE_DIR}/Resources/langs/lang.strings
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/Resources/langs/lang.strings
)
add_custom_target(lang_output
DEPENDS lang_auto.h lang_auto.cpp)
add_custom_command(
COMMENT "Generating emoji"
OUTPUT
emoji.cpp
emoji.h
emoji_suggestions_data.cpp
emoji_suggestions_data.h
COMMAND
codegen_emoji ${CMAKE_CURRENT_SOURCE_DIR}/Resources/emoji_autocomplete.json -o ${CMAKE_CURRENT_BINARY_DIR}
WORKING_DIRECTORY .
DEPENDS
codegen_emoji
${CMAKE_CURRENT_SOURCE_DIR}/Resources/emoji_autocomplete.json
VERBATIM
)
add_custom_target(emoji_output
DEPENDS
emoji.h
emoji.cpp
emoji_suggestions_data.cpp
emoji_suggestions_data.h
)
add_custom_command(
COMMENT "Generating scheme"
OUTPUT
scheme.cpp
scheme.h
COMMAND
python ${CMAKE_CURRENT_SOURCE_DIR}/SourceFiles/codegen/scheme/codegen_scheme.py -o${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/Resources/scheme.tl
WORKING_DIRECTORY .
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/SourceFiles/codegen/scheme/codegen_scheme.py
${CMAKE_CURRENT_SOURCE_DIR}/Resources/scheme.tl
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/Resources/scheme.tl
VERBATIM
)
add_custom_target(scheme_output
DEPENDS scheme.h scheme.cpp)
##========
list(APPEND style_files
Resources/basic
SourceFiles/boxes/boxes
SourceFiles/calls/calls
SourceFiles/chat_helpers/chat_helpers
SourceFiles/dialogs/dialogs
SourceFiles/history/history
SourceFiles/intro/intro
SourceFiles/media/player/media_player
SourceFiles/media/view/mediaview
SourceFiles/overview/overview
SourceFiles/profile/profile
SourceFiles/settings/settings
SourceFiles/ui/widgets/widgets
SourceFiles/window/window
)
foreach (src ${style_files})
# '-w<(PRODUCT_DIR)/../..',
get_filename_component(src_file ${src} NAME)
add_custom_command(
COMMENT "Generating ${src_file}"
OUTPUT
${CMAKE_CURRENT_BINARY_DIR}/styles/style_${src_file}.h
${CMAKE_CURRENT_BINARY_DIR}/styles/style_${src_file}.cpp
COMMAND
codegen_style -I${CMAKE_CURRENT_SOURCE_DIR}/Resources -I${CMAKE_CURRENT_SOURCE_DIR}
-I${CMAKE_CURRENT_SOURCE_DIR}/SourceFiles
-o${CMAKE_CURRENT_BINARY_DIR}/styles -w${CMAKE_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/${src}.style
DEPENDS
codegen_style
${CMAKE_CURRENT_SOURCE_DIR}/${src}.style
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/${src}.style
)
add_custom_target(${src_file}_styles_output
DEPENDS
${CMAKE_CURRENT_BINARY_DIR}/styles/style_${src_file}.h
${CMAKE_CURRENT_BINARY_DIR}/styles/style_${src_file}.cpp
)
list(APPEND style_sources
${CMAKE_CURRENT_BINARY_DIR}/styles/style_${src_file}.cpp)
endforeach()
##======================
## Main app
##======================
#add_subdirectory(SourceFiles/boxes) - see comment in that dir
set(APP_SRC
${CMAKE_CURRENT_BINARY_DIR}/styles/palette.cpp
${CMAKE_CURRENT_BINARY_DIR}/numbers.cpp
${CMAKE_CURRENT_BINARY_DIR}/lang_auto.cpp
${CMAKE_CURRENT_BINARY_DIR}/scheme.cpp
${CMAKE_CURRENT_BINARY_DIR}/emoji.cpp
${CMAKE_CURRENT_BINARY_DIR}/emoji_suggestions_data.cpp
${style_sources}
SourceFiles/base/observer.cpp
SourceFiles/base/parse_helper.cpp
SourceFiles/base/qthelp_url.cpp
SourceFiles/base/runtime_composer.cpp
SourceFiles/base/task_queue.cpp
SourceFiles/base/timer.cpp
SourceFiles/boxes/about_box.cpp
SourceFiles/boxes/abstract_box.cpp
SourceFiles/boxes/add_contact_box.cpp
SourceFiles/boxes/autolock_box.cpp
SourceFiles/boxes/background_box.cpp
SourceFiles/boxes/calendar_box.cpp
SourceFiles/boxes/change_phone_box.cpp
SourceFiles/boxes/confirm_box.cpp
SourceFiles/boxes/confirm_phone_box.cpp
SourceFiles/boxes/connection_box.cpp
SourceFiles/boxes/download_path_box.cpp
SourceFiles/boxes/edit_color_box.cpp
SourceFiles/boxes/edit_participant_box.cpp
SourceFiles/boxes/edit_privacy_box.cpp
SourceFiles/boxes/language_box.cpp
SourceFiles/boxes/local_storage_box.cpp
SourceFiles/boxes/mute_settings_box.cpp
SourceFiles/boxes/notifications_box.cpp
SourceFiles/boxes/passcode_box.cpp
SourceFiles/boxes/peer_list_box.cpp
SourceFiles/boxes/peer_list_controllers.cpp
SourceFiles/boxes/photo_crop_box.cpp
SourceFiles/boxes/rate_call_box.cpp
SourceFiles/boxes/report_box.cpp
SourceFiles/boxes/self_destruction_box.cpp
SourceFiles/boxes/send_files_box.cpp
SourceFiles/boxes/sessions_box.cpp
SourceFiles/boxes/share_box.cpp
SourceFiles/boxes/sticker_set_box.cpp
SourceFiles/boxes/stickers_box.cpp
SourceFiles/boxes/username_box.cpp
SourceFiles/calls/calls_box_controller.cpp
SourceFiles/calls/calls_call.cpp
SourceFiles/calls/calls_emoji_fingerprint.cpp
SourceFiles/calls/calls_instance.cpp
SourceFiles/calls/calls_panel.cpp
SourceFiles/calls/calls_top_bar.cpp
SourceFiles/chat_helpers/bot_keyboard.cpp
SourceFiles/chat_helpers/emoji_list_widget.cpp
SourceFiles/chat_helpers/emoji_suggestions_widget.cpp
SourceFiles/chat_helpers/field_autocomplete.cpp
SourceFiles/chat_helpers/gifs_list_widget.cpp
SourceFiles/chat_helpers/message_field.cpp
SourceFiles/chat_helpers/stickers.cpp
SourceFiles/chat_helpers/stickers_list_widget.cpp
SourceFiles/chat_helpers/tabbed_panel.cpp
SourceFiles/chat_helpers/tabbed_section.cpp
SourceFiles/chat_helpers/tabbed_selector.cpp
SourceFiles/core/click_handler.cpp
SourceFiles/core/click_handler_types.cpp
SourceFiles/core/file_utilities.cpp
SourceFiles/core/single_timer.cpp
SourceFiles/core/utils.cpp
SourceFiles/data/data_abstract_structure.cpp
SourceFiles/data/data_drafts.cpp
SourceFiles/dialogs/dialogs_indexed_list.cpp
SourceFiles/dialogs/dialogs_inner_widget.cpp
SourceFiles/dialogs/dialogs_layout.cpp
SourceFiles/dialogs/dialogs_list.cpp
SourceFiles/dialogs/dialogs_row.cpp
SourceFiles/dialogs/dialogs_search_from_controllers.cpp
SourceFiles/dialogs/dialogs_widget.cpp
SourceFiles/history/history.cpp
SourceFiles/history/history_admin_log_filter.cpp
SourceFiles/history/history_admin_log_inner.cpp
SourceFiles/history/history_admin_log_item.cpp
SourceFiles/history/history_admin_log_section.cpp
SourceFiles/history/history_drag_area.cpp
SourceFiles/history/history_inner_widget.cpp
SourceFiles/history/history_item.cpp
SourceFiles/history/history_location_manager.cpp
SourceFiles/history/history_media_types.cpp
SourceFiles/history/history_message.cpp
SourceFiles/history/history_service.cpp
SourceFiles/history/history_service_layout.cpp
SourceFiles/history/history_widget.cpp
SourceFiles/inline_bots/inline_bot_layout_internal.cpp
SourceFiles/inline_bots/inline_bot_layout_item.cpp
SourceFiles/inline_bots/inline_bot_result.cpp
SourceFiles/inline_bots/inline_bot_send_data.cpp
SourceFiles/inline_bots/inline_results_widget.cpp
SourceFiles/intro/introcode.cpp
SourceFiles/intro/introphone.cpp
SourceFiles/intro/intropwdcheck.cpp
SourceFiles/intro/introsignup.cpp
SourceFiles/intro/introstart.cpp
SourceFiles/intro/introwidget.cpp
SourceFiles/lang/lang_cloud_manager.cpp
SourceFiles/lang/lang_file_parser.cpp
SourceFiles/lang/lang_instance.cpp
SourceFiles/lang/lang_keys.cpp
SourceFiles/lang/lang_tag.cpp
SourceFiles/lang/lang_translator.cpp
SourceFiles/media/player/media_player_button.cpp
SourceFiles/media/player/media_player_cover.cpp
SourceFiles/media/player/media_player_float.cpp
SourceFiles/media/player/media_player_instance.cpp
SourceFiles/media/player/media_player_list.cpp
SourceFiles/media/player/media_player_panel.cpp
SourceFiles/media/player/media_player_volume_controller.cpp
SourceFiles/media/player/media_player_widget.cpp
SourceFiles/media/view/media_clip_controller.cpp
SourceFiles/media/view/media_clip_playback.cpp
SourceFiles/media/view/media_clip_volume_controller.cpp
SourceFiles/media/media_audio.cpp
SourceFiles/media/media_audio_capture.cpp
SourceFiles/media/media_audio_ffmpeg_loader.cpp
SourceFiles/media/media_audio_loader.cpp
SourceFiles/media/media_audio_loaders.cpp
SourceFiles/media/media_audio_track.cpp
SourceFiles/media/media_child_ffmpeg_loader.cpp
SourceFiles/media/media_clip_ffmpeg.cpp
SourceFiles/media/media_clip_implementation.cpp
SourceFiles/media/media_clip_qtgif.cpp
SourceFiles/media/media_clip_reader.cpp
SourceFiles/mtproto/auth_key.cpp
SourceFiles/mtproto/config_loader.cpp
SourceFiles/mtproto/connection.cpp
SourceFiles/mtproto/connection_abstract.cpp
SourceFiles/mtproto/connection_auto.cpp
SourceFiles/mtproto/connection_http.cpp
SourceFiles/mtproto/connection_tcp.cpp
SourceFiles/mtproto/core_types.cpp
SourceFiles/mtproto/dc_options.cpp
SourceFiles/mtproto/dcenter.cpp
SourceFiles/mtproto/facade.cpp
SourceFiles/mtproto/mtp_instance.cpp
SourceFiles/mtproto/rpc_sender.cpp
SourceFiles/mtproto/rsa_public_key.cpp
SourceFiles/mtproto/session.cpp
SourceFiles/mtproto/special_config_request.cpp
SourceFiles/mtproto/type_utils.cpp
SourceFiles/overview/overview_layout.cpp
SourceFiles/profile/profile_back_button.cpp
SourceFiles/profile/profile_block_actions.cpp
SourceFiles/profile/profile_block_channel_members.cpp
SourceFiles/profile/profile_block_group_members.cpp
SourceFiles/profile/profile_block_info.cpp
SourceFiles/profile/profile_block_invite_link.cpp
SourceFiles/profile/profile_block_peer_list.cpp
SourceFiles/profile/profile_block_settings.cpp
SourceFiles/profile/profile_block_shared_media.cpp
SourceFiles/profile/profile_block_widget.cpp
SourceFiles/profile/profile_channel_controllers.cpp
SourceFiles/profile/profile_common_groups_section.cpp
SourceFiles/profile/profile_cover.cpp
SourceFiles/profile/profile_cover_drop_area.cpp
SourceFiles/profile/profile_fixed_bar.cpp
SourceFiles/profile/profile_inner_widget.cpp
SourceFiles/profile/profile_section_memento.cpp
SourceFiles/profile/profile_userpic_button.cpp
SourceFiles/profile/profile_widget.cpp
SourceFiles/settings/settings_advanced_widget.cpp
SourceFiles/settings/settings_background_widget.cpp
SourceFiles/settings/settings_block_widget.cpp
SourceFiles/settings/settings_chat_settings_widget.cpp
SourceFiles/settings/settings_cover.cpp
SourceFiles/settings/settings_fixed_bar.cpp
SourceFiles/settings/settings_general_widget.cpp
SourceFiles/settings/settings_info_widget.cpp
SourceFiles/settings/settings_inner_widget.cpp
SourceFiles/settings/settings_layer.cpp
SourceFiles/settings/settings_notifications_widget.cpp
SourceFiles/settings/settings_privacy_controllers.cpp
SourceFiles/settings/settings_privacy_widget.cpp
SourceFiles/settings/settings_scale_widget.cpp
SourceFiles/settings/settings_widget.cpp
SourceFiles/storage/file_download.cpp
SourceFiles/storage/file_upload.cpp
SourceFiles/storage/localimageloader.cpp
SourceFiles/storage/localstorage.cpp
SourceFiles/storage/serialize_common.cpp
SourceFiles/storage/serialize_document.cpp
SourceFiles/ui/effects/cross_animation.cpp
SourceFiles/ui/effects/panel_animation.cpp
SourceFiles/ui/effects/radial_animation.cpp
SourceFiles/ui/effects/ripple_animation.cpp
SourceFiles/ui/effects/round_checkbox.cpp
SourceFiles/ui/effects/send_action_animations.cpp
SourceFiles/ui/effects/slide_animation.cpp
SourceFiles/ui/effects/widget_fade_wrap.cpp
SourceFiles/ui/effects/widget_slide_wrap.cpp
SourceFiles/ui/style/style_core.cpp
SourceFiles/ui/style/style_core_color.cpp
SourceFiles/ui/style/style_core_font.cpp
SourceFiles/ui/style/style_core_icon.cpp
SourceFiles/ui/style/style_core_types.cpp
SourceFiles/ui/text/text.cpp
SourceFiles/ui/text/text_block.cpp
SourceFiles/ui/text/text_entity.cpp
SourceFiles/ui/toast/toast.cpp
SourceFiles/ui/toast/toast_manager.cpp
SourceFiles/ui/toast/toast_widget.cpp
SourceFiles/ui/widgets/buttons.cpp
SourceFiles/ui/widgets/checkbox.cpp
SourceFiles/ui/widgets/continuous_sliders.cpp
SourceFiles/ui/widgets/discrete_sliders.cpp
SourceFiles/ui/widgets/dropdown_menu.cpp
SourceFiles/ui/widgets/inner_dropdown.cpp
SourceFiles/ui/widgets/input_fields.cpp
SourceFiles/ui/widgets/labels.cpp
SourceFiles/ui/widgets/menu.cpp
SourceFiles/ui/widgets/multi_select.cpp
SourceFiles/ui/widgets/popup_menu.cpp
SourceFiles/ui/widgets/scroll_area.cpp
SourceFiles/ui/widgets/shadow.cpp
SourceFiles/ui/widgets/tooltip.cpp
SourceFiles/ui/abstract_button.cpp
SourceFiles/ui/animation.cpp
SourceFiles/ui/countryinput.cpp
SourceFiles/ui/emoji_config.cpp
SourceFiles/ui/images.cpp
SourceFiles/ui/special_buttons.cpp
SourceFiles/ui/twidget.cpp
SourceFiles/window/themes/window_theme.cpp
SourceFiles/window/themes/window_theme_editor.cpp
SourceFiles/window/themes/window_theme_editor_block.cpp
SourceFiles/window/themes/window_theme_preview.cpp
SourceFiles/window/themes/window_theme_warning.cpp
SourceFiles/window/main_window.cpp
SourceFiles/window/notifications_manager.cpp
SourceFiles/window/notifications_manager_default.cpp
SourceFiles/window/notifications_utilities.cpp
SourceFiles/window/player_wrap_widget.cpp
SourceFiles/window/section_widget.cpp
SourceFiles/window/top_bar_widget.cpp
SourceFiles/window/window_controller.cpp
SourceFiles/window/window_main_menu.cpp
SourceFiles/window/window_slide_animation.cpp
SourceFiles/apiwrap.cpp
SourceFiles/app.cpp
SourceFiles/application.cpp
SourceFiles/auth_session.cpp
SourceFiles/facades.cpp
SourceFiles/layerwidget.cpp
SourceFiles/layout.cpp
SourceFiles/logs.cpp
SourceFiles/main.cpp
SourceFiles/mainwidget.cpp
SourceFiles/mainwindow.cpp
SourceFiles/mediaview.cpp
SourceFiles/messenger.cpp
SourceFiles/observer_peer.cpp
SourceFiles/overviewwidget.cpp
SourceFiles/passcodewidget.cpp
SourceFiles/qt_functions.cpp
SourceFiles/settings.cpp
SourceFiles/shortcuts.cpp
SourceFiles/structs.cpp
)
set(PLAT_SRC)
if (APPLE)
set(PLAT_SRC ${PLAT_SRC}
SourceFiles/platform/mac/file_utilities_mac.mm
SourceFiles/platform/mac/mac_utilities.mm
SourceFiles/platform/mac/main_window_mac.mm
SourceFiles/platform/mac/notifications_manager_mac.mm
SourceFiles/platform/mac/specific_mac.mm
SourceFiles/platform/mac/specific_mac_p.mm
SourceFiles/platform/mac/window_title_mac.mm
)
set(tg_RESOURCES Resources/qrc/telegram_mac.qrc)
endif()
if (WIN32)
set(PLAT_SRC ${PLAT_SRC}
SourceFiles/platform/win/audio_win.cpp
SourceFiles/platform/win/file_utilities_win.cpp
SourceFiles/platform/win/main_window_win.cpp
SourceFiles/platform/win/notifications_manager_win.cpp
SourceFiles/platform/win/specific_win.cpp
SourceFiles/platform/win/window_title_win.cpp
SourceFiles/platform/win/windows_app_user_model_id.cpp
SourceFiles/platform/win/windows_dlls.cpp
SourceFiles/platform/win/windows_event_filter.cpp
)
set(tg_RESOURCES Resources/qrc/telegram_wnd.qrc)
endif()
if (WINRT)
set(PLAT_SRC ${PLAT_SRC}
SourceFiles/platform/winrt/main_window_winrt.cpp
)
endif()
if (LINUX)
set(PLAT_SRC ${PLAT_SRC}
SourceFiles/platform/linux/file_utilities_linux.cpp
SourceFiles/platform/linux/linux_desktop_environment.cpp
SourceFiles/platform/linux/linux_gdk_helper.cpp
SourceFiles/platform/linux/linux_libnotify.cpp
SourceFiles/platform/linux/linux_libs.cpp
SourceFiles/platform/linux/main_window_linux.cpp
SourceFiles/platform/linux/notifications_manager_linux.cpp
SourceFiles/platform/linux/specific_linux.cpp
)
set(tg_RESOURCES Resources/qrc/telegram_linux.qrc)
endif()
list(APPEND tg_RESOURCES
Resources/qrc/telegram.qrc
Resources/qrc/telegram_sounds.qrc
Resources/qrc/telegram_emoji.qrc
Resources/qrc/telegram_emoji_large.qrc
)
qt5_add_resources(tg_RESOURCES_RCC ${tg_RESOURCES})
set(THIRD_PARTY_SRC)
if (APPLE)
list(APPEND THIRD_PARTY_SRC
ThirdParty/SPMediaKeyTap/SPMediaKeyTap.m
ThirdParty/SPMediaKeyTap/SPInvocationGrabbing/NSObject+SPInvocationGrabbing.m
)
include_directories(ThirdParty/SPMediaKeyTap)
endif()
list(APPEND THIRD_PARTY_SRC
ThirdParty/minizip/ioapi.c
ThirdParty/minizip/zip.c
ThirdParty/minizip/unzip.c
ThirdParty/emoji_suggestions/emoji_suggestions.cpp
)
include_directories(ThirdParty) # For minizip/ but we use fully-qualified include path to avoid ambiguity
include_directories(ThirdParty/GSL/include ThirdParty/variant/include
ThirdParty/emoji_suggestions ThirdParty/libtgvoip)
##======================
## Telegram
##======================
include_directories(SourceFiles SourceFiles/core)
include_directories(${OPENAL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIRS}
${LIBZIP_INCLUDE_DIR_ZIP} ${LIBZIP_INCLUDE_DIR_ZIPCONF}
${OPENSSL_INCLUDE_DIR} ${LIBLZMA_INCLUDE_DIRS}
${ICONV_INCLUDE_DIR} ${OPUS_INCLUDE_DIR}
${FFMPEG_INCLUDE_DIRS})
add_subdirectory(ThirdParty/libtgvoip)
# Shut up for testbuilding, remove me
include_directories(/usr/local/opt/openal-soft/include)
# End remove me
if(NOT WIN32)
add_definitions(-Wno-switch)
endif()
if (WIN32)
add_definitions(-D_CRT_SECURE_NO_WARNINGS -DWIN32 -D_WINDOWS -DUNICODE -DWIN64 -DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP)
list(APPEND APP_SRC Resources/winrc/Telegram.rc)
endif()
add_definitions(-DTDESKTOP_DISABLE_CRASH_REPORTS)
if (APPLE)
set(MACOSX_BUNDLE_ICON_FILE Icon.icns)
add_custom_command(
COMMENT "Generating icon file"
OUTPUT
${CMAKE_CURRENT_BINARY_DIR}/${MACOSX_BUNDLE_ICON_FILE}
COMMAND
iconutil -c icns -o ${CMAKE_CURRENT_BINARY_DIR}/${MACOSX_BUNDLE_ICON_FILE} ${CMAKE_CURRENT_SOURCE_DIR}/Telegram/Images.xcassets/Icon.iconset/
WORKING_DIRECTORY .
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/Telegram/Images.xcassets/Icon.iconset
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/Telegram/Images.xcassets/Icon.iconset
)
add_custom_target(iconset_output
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${MACOSX_BUNDLE_ICON_FILE})
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${MACOSX_BUNDLE_ICON_FILE}
PROPERTIES
MACOSX_PACKAGE_LOCATION Resources)
set(APPLE_BUNDLE_SRC ${CMAKE_CURRENT_BINARY_DIR}/${MACOSX_BUNDLE_ICON_FILE})
endif()
add_executable(Telegram WIN32 MACOSX_BUNDLE
${APP_SRC}
${PLAT_SRC}
${THIRD_PARTY_SRC}
${tg_RESOURCES}
${tg_RESOURCES_RCC}
${APPLE_BUNDLE_SRC}
)
# Disable a single annoying warning about c++17
if(NOT WIN32)
target_compile_options(Telegram PRIVATE -Wno-c++1z-extensions)
endif()
# Enable C++14 support for msvc (@todo this should be done in cmake)
if(WIN32)
target_compile_options(Telegram PRIVATE /std:c++14)
endif()
target_compile_definitions(Telegram PRIVATE ${FFMPEG_DEFINITIONS})
target_link_libraries(Telegram
Qt5::Core
Qt5::Widgets
Qt5::Network
Qt5::GuiPrivate
tgvoip
${OPENAL_LIBRARY}
${FFMPEG_LIBRARIES}
${ZLIB_LIBRARIES}
${SWRESAMPLE_LIBRARIES}
${SWSCALE_LIBRARIES}
${OPENSSL_LIBRARIES}
${OPUS_LIB}
${CONAN_LIBS}
) # crashpad::crashpad_client)
add_dependencies(Telegram boxes_styles_output)
if (APPLE)
add_dependencies(Telegram iconset_output)
set_target_properties(Telegram
PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Telegram.plist
)
find_library(COREFOUNDATION_LIB CoreFoundation)
find_library(COREAUDIO_LIB CoreAudio)
find_library(AUDIOUNIT_LIB AudioUnit)
find_library(AUDIOTOOLBOX_LIB AudioToolbox)
find_library(COCOA_LIB Cocoa)
find_library(CARBON_LIB Carbon)
find_library(IOKIT_LIB IOKit)
target_link_libraries(Telegram
${COREFOUNDATION_LIB}
${COCOA_LIB}
${CARBON_LIB}
${COREAUDIO_LIB}
${AUDIOUNIT_LIB}
${AUDIOTOOLBOX_LIB}
${IOKIT_LIB}
)
endif()
if(WIN32)
target_link_libraries(Telegram winmm imm32 ws2_32 kernel32 user32 gdi32 winspool comdlg32 advapi32 shell32 ole32 oleaut32 uuid odbc32 odbccp32 Shlwapi Iphlpapi Gdiplus Strmiids)
endif()
set_target_properties(Telegram
PROPERTIES
COTIRE_CXX_PREFIX_HEADER_INIT SourceFiles/stdafx.h
COTIRE_ADD_UNITY_BUILD FALSE
)
cotire(Telegram)
# See https://github.com/sakra/cotire/blob/master/MANUAL.md#objective-c
# ObjC and ObjC++ files cannot be cotired, so they have to include appropriate Qt and Tg
# headers themselves, this applies to macOS platform sources.

View File

@ -1,52 +0,0 @@
diff --git a/base/mac/scoped_nsobject.h b/base/mac/scoped_nsobject.h
index 2e157a4..5a306a1 100644
--- a/base/mac/scoped_nsobject.h
+++ b/base/mac/scoped_nsobject.h
@@ -11,6 +11,7 @@
#include "base/compiler_specific.h"
#include "base/mac/scoped_typeref.h"
+#include "base/template_util.h"
namespace base {
@@ -55,7 +56,7 @@ class scoped_nsobject : public scoped_nsprotocol<NST*> {
public:
using scoped_nsprotocol<NST*>::scoped_nsprotocol;
- static_assert(std::is_same<NST, NSAutoreleasePool>::value == false,
+ static_assert(is_same<NST, NSAutoreleasePool>::value == false,
"Use ScopedNSAutoreleasePool instead");
};
diff --git a/base/macros.h b/base/macros.h
index 5d96783..096704c 100644
--- a/base/macros.h
+++ b/base/macros.h
@@ -42,8 +42,9 @@ char (&ArraySizeHelper(const T (&array)[N]))[N];
template <typename Dest, typename Source>
inline Dest bit_cast(const Source& source) {
+#if __cplusplus >= 201103L
static_assert(sizeof(Dest) == sizeof(Source), "sizes must be equal");
-
+#endif
Dest dest;
memcpy(&dest, &source, sizeof(dest));
return dest;
diff --git a/build/common.gypi b/build/common.gypi
index 1affc70..6e8f292 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -66,6 +66,11 @@
'conditions': [
['clang!=0', {
'CLANG_CXX_LANGUAGE_STANDARD': 'c++11', # -std=c++11
+ 'conditions': [
+ ['mac_deployment_target=="10.8"', {
+ 'CLANG_CXX_LIBRARY': 'libc++', # force -stdlib=libc++ for 10.8
+ }]
+ ],
# Don't link in libarclite_macosx.a, see http://crbug.com/156530.
'CLANG_LINK_OBJC_RUNTIME': 'NO', # -fno-objc-link-runtime

View File

@ -1,22 +0,0 @@
diff --git a/Alc/backends/winmm.c b/Alc/backends/winmm.c
index 9d8f8e9..8c8e44a 100644
--- a/Alc/backends/winmm.c
+++ b/Alc/backends/winmm.c
@@ -219,7 +219,7 @@ FORCE_ALIGN static int ALCwinmmPlayback_mixerProc(void *arg)
SetRTPriority();
althrd_setname(althrd_current(), MIXER_THREAD_NAME);
- while(GetMessage(&msg, NULL, 0, 0))
+ if (!self->killNow) while(GetMessage(&msg, NULL, 0, 0))
{
if(msg.message != WOM_DONE)
continue;
@@ -504,7 +504,7 @@ static int ALCwinmmCapture_captureProc(void *arg)
althrd_setname(althrd_current(), RECORD_THREAD_NAME);
- while(GetMessage(&msg, NULL, 0, 0))
+ if (!self->killNow) while(GetMessage(&msg, NULL, 0, 0))
{
if(msg.message != WIM_DATA)
continue;

View File

@ -1,539 +0,0 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#include "packer.h"
#include <QtCore/QtPlugin>
#ifdef Q_OS_MAC
//Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin)
#endif
bool AlphaChannel = false;
quint64 BetaVersion = 0;
const char *PublicKey = "\
-----BEGIN RSA PUBLIC KEY-----\n\
MIGJAoGBAMA4ViQrjkPZ9xj0lrer3r23JvxOnrtE8nI69XLGSr+sRERz9YnUptnU\n\
BZpkIfKaRcl6XzNJiN28cVwO1Ui5JSa814UAiDHzWUqCaXUiUEQ6NmNTneiGx2sQ\n\
+9PKKlb8mmr3BB9A45ZNwLT6G9AK3+qkZLHojeSA+m84/a6GP4svAgMBAAE=\n\
-----END RSA PUBLIC KEY-----\
";
const char *PublicAlphaKey = "\
-----BEGIN RSA PUBLIC KEY-----\n\
MIGJAoGBALWu9GGs0HED7KG7BM73CFZ6o0xufKBRQsdnq3lwA8nFQEvmdu+g/I1j\n\
0LQ+0IQO7GW4jAgzF/4+soPDb6uHQeNFrlVx1JS9DZGhhjZ5rf65yg11nTCIHZCG\n\
w/CVnbwQOw0g5GBwwFV3r0uTTvy44xx8XXxk+Qknu4eBCsmrAFNnAgMBAAE=\n\
-----END RSA PUBLIC KEY-----\
";
extern const char *PrivateKey;
extern const char *PrivateAlphaKey;
#include "../../../../TelegramPrivate/packer_private.h" // RSA PRIVATE KEYS for update signing
#include "../../../../TelegramPrivate/beta_private.h" // private key for beta version file generation
QString countBetaVersionSignature(quint64 version);
// sha1 hash
typedef unsigned char uchar;
typedef unsigned int uint32;
typedef signed int int32;
namespace{
inline uint32 sha1Shift(uint32 v, uint32 shift) {
return ((v << shift) | (v >> (32 - shift)));
}
void sha1PartHash(uint32 *sha, uint32 *temp) {
uint32 a = sha[0], b = sha[1], c = sha[2], d = sha[3], e = sha[4], round = 0;
#define _shiftswap(f, v) { \
uint32 t = sha1Shift(a, 5) + (f) + e + v + temp[round]; \
e = d; \
d = c; \
c = sha1Shift(b, 30); \
b = a; \
a = t; \
++round; \
}
#define _shiftshiftswap(f, v) { \
temp[round] = sha1Shift((temp[round - 3] ^ temp[round - 8] ^ temp[round - 14] ^ temp[round - 16]), 1); \
_shiftswap(f, v) \
}
while (round < 16) _shiftswap((b & c) | (~b & d), 0x5a827999)
while (round < 20) _shiftshiftswap((b & c) | (~b & d), 0x5a827999)
while (round < 40) _shiftshiftswap(b ^ c ^ d, 0x6ed9eba1)
while (round < 60) _shiftshiftswap((b & c) | (b & d) | (c & d), 0x8f1bbcdc)
while (round < 80) _shiftshiftswap(b ^ c ^ d, 0xca62c1d6)
#undef _shiftshiftswap
#undef _shiftswap
sha[0] += a;
sha[1] += b;
sha[2] += c;
sha[3] += d;
sha[4] += e;
}
} // namespace
int32 *hashSha1(const void *data, uint32 len, void *dest) {
const uchar *buf = (const uchar *)data;
uint32 temp[80], block = 0, end;
uint32 sha[5] = {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0};
for (end = block + 64; block + 64 <= len; end = block + 64) {
for (uint32 i = 0; block < end; block += 4) {
temp[i++] = (uint32) buf[block + 3]
| (((uint32) buf[block + 2]) << 8)
| (((uint32) buf[block + 1]) << 16)
| (((uint32) buf[block]) << 24);
}
sha1PartHash(sha, temp);
}
end = len - block;
memset(temp, 0, sizeof(uint32) * 16);
uint32 last = 0;
for (; last < end; ++last) {
temp[last >> 2] |= (uint32)buf[last + block] << ((3 - (last & 0x03)) << 3);
}
temp[last >> 2] |= 0x80 << ((3 - (last & 3)) << 3);
if (end >= 56) {
sha1PartHash(sha, temp);
memset(temp, 0, sizeof(uint32) * 16);
}
temp[15] = len << 3;
sha1PartHash(sha, temp);
uchar *sha1To = (uchar*)dest;
for (int32 i = 19; i >= 0; --i) {
sha1To[i] = (sha[i >> 2] >> (((3 - i) & 0x03) << 3)) & 0xFF;
}
return (int32*)sha1To;
}
QString BetaSignature;
int main(int argc, char *argv[])
{
QString workDir;
QString remove;
int version = 0;
bool target32 = false;
QFileInfoList files;
for (int i = 0; i < argc; ++i) {
if (string("-path") == argv[i] && i + 1 < argc) {
QString path = workDir + QString(argv[i + 1]);
QFileInfo info(path);
files.push_back(info);
if (remove.isEmpty()) remove = info.canonicalPath() + "/";
} else if (string("-target") == argv[i] && i + 1 < argc) {
target32 = (string("mac32") == argv[i + 1]);
} else if (string("-version") == argv[i] && i + 1 < argc) {
version = QString(argv[i + 1]).toInt();
} else if (string("-alpha") == argv[i]) {
AlphaChannel = true;
} else if (string("-beta") == argv[i] && i + 1 < argc) {
BetaVersion = QString(argv[i + 1]).toULongLong();
if (BetaVersion > version * 1000ULL && BetaVersion < (version + 1) * 1000ULL) {
AlphaChannel = false;
BetaSignature = countBetaVersionSignature(BetaVersion);
if (BetaSignature.isEmpty()) {
return -1;
}
} else {
cout << "Bad -beta param value passed, should be for the same version: " << version << ", beta: " << BetaVersion << "\n";
return -1;
}
}
}
if (files.isEmpty() || remove.isEmpty() || version <= 1016 || version > 999999999) {
#ifdef Q_OS_WIN
cout << "Usage: Packer.exe -path {file} -version {version} OR Packer.exe -path {dir} -version {version}\n";
#elif defined Q_OS_MAC
cout << "Usage: Packer.app -path {file} -version {version} OR Packer.app -path {dir} -version {version}\n";
#else
cout << "Usage: Packer -path {file} -version {version} OR Packer -path {dir} -version {version}\n";
#endif
return -1;
}
bool hasDirs = true;
while (hasDirs) {
hasDirs = false;
for (QFileInfoList::iterator i = files.begin(); i != files.end(); ++i) {
QFileInfo info(*i);
QString fullPath = info.canonicalFilePath();
if (info.isDir()) {
hasDirs = true;
files.erase(i);
QDir d = QDir(info.absoluteFilePath());
QString fullDir = d.canonicalPath();
QStringList entries = d.entryList(QDir::Files | QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot);
files.append(d.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot));
break;
} else if (!info.isReadable()) {
cout << "Can't read: " << info.absoluteFilePath().toUtf8().constData() << "\n";
return -1;
} else if (info.isHidden()) {
hasDirs = true;
files.erase(i);
break;
}
}
}
for (QFileInfoList::iterator i = files.begin(); i != files.end(); ++i) {
QFileInfo info(*i);
if (!info.canonicalFilePath().startsWith(remove)) {
cout << "Can't find '" << remove.toUtf8().constData() << "' in file '" << info.canonicalFilePath().toUtf8().constData() << "' :(\n";
return -1;
}
}
QByteArray result;
{
QBuffer buffer(&result);
buffer.open(QIODevice::WriteOnly);
QDataStream stream(&buffer);
stream.setVersion(QDataStream::Qt_5_1);
if (BetaVersion) {
stream << quint32(0x7FFFFFFF);
stream << quint64(BetaVersion);
} else {
stream << quint32(version);
}
stream << quint32(files.size());
cout << "Found " << files.size() << " file" << (files.size() == 1 ? "" : "s") << "..\n";
for (QFileInfoList::iterator i = files.begin(); i != files.end(); ++i) {
QFileInfo info(*i);
QString fullName = info.canonicalFilePath();
QString name = fullName.mid(remove.length());
cout << name.toUtf8().constData() << " (" << info.size() << ")\n";
QFile f(fullName);
if (!f.open(QIODevice::ReadOnly)) {
cout << "Can't open '" << fullName.toUtf8().constData() << "' for read..\n";
return -1;
}
QByteArray inner = f.readAll();
stream << name << quint32(inner.size()) << inner;
#if defined Q_OS_MAC || defined Q_OS_LINUX
stream << (QFileInfo(fullName).isExecutable() ? true : false);
#endif
}
if (stream.status() != QDataStream::Ok) {
cout << "Stream status is bad: " << stream.status() << "\n";
return -1;
}
}
int32 resultSize = result.size();
cout << "Compression start, size: " << resultSize << "\n";
QByteArray compressed, resultCheck;
#ifdef Q_OS_WIN // use Lzma SDK for win
const int32 hSigLen = 128, hShaLen = 20, hPropsLen = LZMA_PROPS_SIZE, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hPropsLen + hOriginalSizeLen; // header
compressed.resize(hSize + resultSize + 1024 * 1024); // rsa signature + sha1 + lzma props + max compressed size
size_t compressedLen = compressed.size() - hSize;
size_t outPropsSize = LZMA_PROPS_SIZE;
uchar *_dest = (uchar*)(compressed.data() + hSize);
size_t *_destLen = &compressedLen;
const uchar *_src = (const uchar*)(result.constData());
size_t _srcLen = result.size();
uchar *_outProps = (uchar*)(compressed.data() + hSigLen + hShaLen);
int res = LzmaCompress(_dest, _destLen, _src, _srcLen, _outProps, &outPropsSize, 9, 64 * 1024 * 1024, 4, 0, 2, 273, 2);
if (res != SZ_OK) {
cout << "Error in compression: " << res << "\n";
return -1;
}
compressed.resize(int(hSize + compressedLen));
memcpy(compressed.data() + hSigLen + hShaLen + hPropsLen, &resultSize, hOriginalSizeLen);
cout << "Compressed to size: " << compressedLen << "\n";
cout << "Checking uncompressed..\n";
int32 resultCheckLen;
memcpy(&resultCheckLen, compressed.constData() + hSigLen + hShaLen + hPropsLen, hOriginalSizeLen);
if (resultCheckLen <= 0 || resultCheckLen > 1024 * 1024 * 1024) {
cout << "Bad result len: " << resultCheckLen << "\n";
return -1;
}
resultCheck.resize(resultCheckLen);
size_t resultLen = resultCheck.size();
SizeT srcLen = compressedLen;
int uncompressRes = LzmaUncompress((uchar*)resultCheck.data(), &resultLen, (const uchar*)(compressed.constData() + hSize), &srcLen, (const uchar*)(compressed.constData() + hSigLen + hShaLen), LZMA_PROPS_SIZE);
if (uncompressRes != SZ_OK) {
cout << "Uncompress failed: " << uncompressRes << "\n";
return -1;
}
if (resultLen != size_t(result.size())) {
cout << "Uncompress bad size: " << resultLen << ", was: " << result.size() << "\n";
return -1;
}
#else // use liblzma for others
const int32 hSigLen = 128, hShaLen = 20, hPropsLen = 0, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hOriginalSizeLen; // header
compressed.resize(hSize + resultSize + 1024 * 1024); // rsa signature + sha1 + lzma props + max compressed size
size_t compressedLen = compressed.size() - hSize;
lzma_stream stream = LZMA_STREAM_INIT;
int preset = 9 | LZMA_PRESET_EXTREME;
lzma_ret ret = lzma_easy_encoder(&stream, preset, LZMA_CHECK_CRC64);
if (ret != LZMA_OK) {
const char *msg;
switch (ret) {
case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
case LZMA_OPTIONS_ERROR: msg = "Specified preset is not supported"; break;
case LZMA_UNSUPPORTED_CHECK: msg = "Specified integrity check is not supported"; break;
default: msg = "Unknown error, possibly a bug"; break;
}
cout << "Error initializing the encoder: " << msg << " (error code " << ret << ")\n";
return -1;
}
stream.avail_in = resultSize;
stream.next_in = (uint8_t*)result.constData();
stream.avail_out = compressedLen;
stream.next_out = (uint8_t*)(compressed.data() + hSize);
lzma_ret res = lzma_code(&stream, LZMA_FINISH);
compressedLen -= stream.avail_out;
lzma_end(&stream);
if (res != LZMA_OK && res != LZMA_STREAM_END) {
const char *msg;
switch (res) {
case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
case LZMA_DATA_ERROR: msg = "File size limits exceeded"; break;
default: msg = "Unknown error, possibly a bug"; break;
}
cout << "Error in compression: " << msg << " (error code " << res << ")\n";
return -1;
}
compressed.resize(int(hSize + compressedLen));
memcpy(compressed.data() + hSigLen + hShaLen, &resultSize, hOriginalSizeLen);
cout << "Compressed to size: " << compressedLen << "\n";
cout << "Checking uncompressed..\n";
int32 resultCheckLen;
memcpy(&resultCheckLen, compressed.constData() + hSigLen + hShaLen, hOriginalSizeLen);
if (resultCheckLen <= 0 || resultCheckLen > 1024 * 1024 * 1024) {
cout << "Bad result len: " << resultCheckLen << "\n";
return -1;
}
resultCheck.resize(resultCheckLen);
size_t resultLen = resultCheck.size();
stream = LZMA_STREAM_INIT;
ret = lzma_stream_decoder(&stream, UINT64_MAX, LZMA_CONCATENATED);
if (ret != LZMA_OK) {
const char *msg;
switch (ret) {
case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
case LZMA_OPTIONS_ERROR: msg = "Specified preset is not supported"; break;
case LZMA_UNSUPPORTED_CHECK: msg = "Specified integrity check is not supported"; break;
default: msg = "Unknown error, possibly a bug"; break;
}
cout << "Error initializing the decoder: " << msg << " (error code " << ret << ")\n";
return -1;
}
stream.avail_in = compressedLen;
stream.next_in = (uint8_t*)(compressed.constData() + hSize);
stream.avail_out = resultLen;
stream.next_out = (uint8_t*)resultCheck.data();
res = lzma_code(&stream, LZMA_FINISH);
if (stream.avail_in) {
cout << "Error in decompression, " << stream.avail_in << " bytes left in _in of " << compressedLen << " whole.\n";
return -1;
} else if (stream.avail_out) {
cout << "Error in decompression, " << stream.avail_out << " bytes free left in _out of " << resultLen << " whole.\n";
return -1;
}
lzma_end(&stream);
if (res != LZMA_OK && res != LZMA_STREAM_END) {
const char *msg;
switch (res) {
case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
case LZMA_FORMAT_ERROR: msg = "The input data is not in the .xz format"; break;
case LZMA_OPTIONS_ERROR: msg = "Unsupported compression options"; break;
case LZMA_DATA_ERROR: msg = "Compressed file is corrupt"; break;
case LZMA_BUF_ERROR: msg = "Compressed data is truncated or otherwise corrupt"; break;
default: msg = "Unknown error, possibly a bug"; break;
}
cout << "Error in decompression: " << msg << " (error code " << res << ")\n";
return -1;
}
#endif
if (memcmp(result.constData(), resultCheck.constData(), resultLen)) {
cout << "Data differ :(\n";
return -1;
}
/**/
result = resultCheck = QByteArray();
cout << "Counting SHA1 hash..\n";
uchar sha1Buffer[20];
memcpy(compressed.data() + hSigLen, hashSha1(compressed.constData() + hSigLen + hShaLen, uint32(compressedLen + hPropsLen + hOriginalSizeLen), sha1Buffer), hShaLen); // count sha1
uint32 siglen = 0;
cout << "Signing..\n";
RSA *prKey = PEM_read_bio_RSAPrivateKey(BIO_new_mem_buf(const_cast<char*>((AlphaChannel || BetaVersion) ? PrivateAlphaKey : PrivateKey), -1), 0, 0, 0);
if (!prKey) {
cout << "Could not read RSA private key!\n";
return -1;
}
if (RSA_size(prKey) != hSigLen) {
cout << "Bad private key, size: " << RSA_size(prKey) << "\n";
RSA_free(prKey);
return -1;
}
if (RSA_sign(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (uchar*)(compressed.data()), &siglen, prKey) != 1) { // count signature
cout << "Signing failed!\n";
RSA_free(prKey);
return -1;
}
RSA_free(prKey);
if (siglen != hSigLen) {
cout << "Bad signature length: " << siglen << "\n";
return -1;
}
cout << "Checking signature..\n";
RSA *pbKey = PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast<char*>((AlphaChannel || BetaVersion) ? PublicAlphaKey : PublicKey), -1), 0, 0, 0);
if (!pbKey) {
cout << "Could not read RSA public key!\n";
return -1;
}
if (RSA_verify(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (const uchar*)(compressed.constData()), siglen, pbKey) != 1) { // verify signature
RSA_free(pbKey);
cout << "Signature verification failed!\n";
return -1;
}
cout << "Signature verified!\n";
RSA_free(pbKey);
#ifdef Q_OS_WIN
QString outName(QString("tupdate%1").arg(BetaVersion ? BetaVersion : version));
#elif defined Q_OS_MAC
QString outName((target32 ? QString("tmac32upd%1") : QString("tmacupd%1")).arg(BetaVersion ? BetaVersion : version));
#elif defined Q_OS_LINUX32
QString outName(QString("tlinux32upd%1").arg(BetaVersion ? BetaVersion : version));
#elif defined Q_OS_LINUX64
QString outName(QString("tlinuxupd%1").arg(BetaVersion ? BetaVersion : version));
#else
#error Unknown platform!
#endif
if (BetaVersion) {
outName += "_" + BetaSignature;
}
QFile out(outName);
if (!out.open(QIODevice::WriteOnly)) {
cout << "Can't open '" << outName.toUtf8().constData() << "' for write..\n";
return -1;
}
out.write(compressed);
out.close();
if (BetaVersion) {
QString keyName(QString("tbeta_%1_key").arg(BetaVersion));
QFile key(keyName);
if (!key.open(QIODevice::WriteOnly)) {
cout << "Can't open '" << keyName.toUtf8().constData() << "' for write..\n";
return -1;
}
key.write(BetaSignature.toUtf8());
key.close();
}
cout << "Update file '" << outName.toUtf8().constData() << "' written successfully!\n";
return 0;
}
QString countBetaVersionSignature(quint64 version) { // duplicated in autoupdate.cpp
QByteArray cBetaPrivateKey(BetaPrivateKey);
if (cBetaPrivateKey.isEmpty()) {
cout << "Error: Trying to count beta version signature without beta private key!\n";
return QString();
}
QByteArray signedData = (QLatin1String("TelegramBeta_") + QString::number(version, 16).toLower()).toUtf8();
static const int32 shaSize = 20, keySize = 128;
uchar sha1Buffer[shaSize];
hashSha1(signedData.constData(), signedData.size(), sha1Buffer); // count sha1
uint32 siglen = 0;
RSA *prKey = PEM_read_bio_RSAPrivateKey(BIO_new_mem_buf(const_cast<char*>(cBetaPrivateKey.constData()), -1), 0, 0, 0);
if (!prKey) {
cout << "Error: Could not read beta private key!\n";
return QString();
}
if (RSA_size(prKey) != keySize) {
cout << "Error: Bad beta private key size: " << RSA_size(prKey) << "\n";
RSA_free(prKey);
return QString();
}
QByteArray signature;
signature.resize(keySize);
if (RSA_sign(NID_sha1, (const uchar*)(sha1Buffer), shaSize, (uchar*)(signature.data()), &siglen, prKey) != 1) { // count signature
cout << "Error: Counting beta version signature failed!\n";
RSA_free(prKey);
return QString();
}
RSA_free(prKey);
if (siglen != keySize) {
cout << "Error: Bad beta version signature length: " << siglen << "\n";
return QString();
}
signature = signature.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
signature = signature.replace('-', '8').replace('_', 'B');
return QString::fromUtf8(signature.mid(19, 32));
}

View File

@ -1,52 +0,0 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
#include <QtCore/QCoreApplication>
#include <QtCore/QFileInfo>
#include <QtCore/QFile>
#include <QtCore/QDir>
#include <QtCore/QStringList>
#include <QtCore/QBuffer>
#include <QtCore/QDataStream>
#include <zlib.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#ifdef Q_OS_WIN // use Lzma SDK for win
#include <LzmaLib.h>
#else
#include <lzma.h>
#endif
#include <string>
#include <iostream>
#include <exception>
using std::string;
using std::wstring;
using std::cout;

View File

@ -1,590 +0,0 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#include "updater.h"
bool _debug = false;
wstring updaterName, updaterDir, updateTo, exeName;
bool equal(const wstring &a, const wstring &b) {
return !_wcsicmp(a.c_str(), b.c_str());
}
void updateError(const WCHAR *msg, DWORD errorCode) {
WCHAR errMsg[2048];
LPWSTR errorText = NULL, errorTextDefault = L"(Unknown error)";
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&errorText, 0, 0);
if (!errorText) {
errorText = errorTextDefault;
}
wsprintf(errMsg, L"%s, error code: %d\nError message: %s", msg, errorCode, errorText);
MessageBox(0, errMsg, L"Update error!", MB_ICONERROR);
if (errorText != errorTextDefault) {
LocalFree(errorText);
}
}
HANDLE _logFile = 0;
void openLog() {
if (!_debug || _logFile) return;
wstring logPath = L"DebugLogs";
if (!CreateDirectory(logPath.c_str(), NULL)) {
DWORD errorCode = GetLastError();
if (errorCode && errorCode != ERROR_ALREADY_EXISTS) {
updateError(L"Failed to create log directory", errorCode);
return;
}
}
SYSTEMTIME stLocalTime;
GetLocalTime(&stLocalTime);
static const int maxFileLen = MAX_PATH * 10;
WCHAR logName[maxFileLen];
wsprintf(logName, L"DebugLogs\\%04d%02d%02d_%02d%02d%02d_upd.txt",
stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond);
_logFile = CreateFile(logName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (_logFile == INVALID_HANDLE_VALUE) { // :(
updateError(L"Failed to create log file", GetLastError());
_logFile = 0;
return;
}
}
void closeLog() {
if (!_logFile) return;
CloseHandle(_logFile);
_logFile = 0;
}
void writeLog(const wstring &msg) {
if (!_logFile) return;
wstring full = msg + L'\n';
DWORD written = 0;
BOOL result = WriteFile(_logFile, full.c_str(), full.size() * sizeof(wchar_t), &written, 0);
if (!result) {
updateError((L"Failed to write log entry '" + msg + L"'").c_str(), GetLastError());
closeLog();
return;
}
BOOL flushr = FlushFileBuffers(_logFile);
if (!flushr) {
updateError((L"Failed to flush log on entry '" + msg + L"'").c_str(), GetLastError());
closeLog();
return;
}
}
void fullClearPath(const wstring &dir) {
WCHAR path[4096];
memcpy(path, dir.c_str(), (dir.size() + 1) * sizeof(WCHAR));
path[dir.size() + 1] = 0;
writeLog(L"Fully clearing path '" + dir + L"'..");
SHFILEOPSTRUCT file_op = {
NULL,
FO_DELETE,
path,
L"",
FOF_NOCONFIRMATION |
FOF_NOERRORUI |
FOF_SILENT,
false,
0,
L""
};
int res = SHFileOperation(&file_op);
if (res) writeLog(L"Error: failed to clear path! :(");
}
void delFolder() {
wstring delPathOld = L"tupdates\\ready", delPath = L"tupdates\\temp", delFolder = L"tupdates";
fullClearPath(delPathOld);
fullClearPath(delPath);
RemoveDirectory(delFolder.c_str());
}
DWORD versionNum = 0, versionLen = 0, readLen = 0;
WCHAR versionStr[32] = { 0 };
bool update() {
writeLog(L"Update started..");
wstring updDir = L"tupdates\\temp", readyFilePath = L"tupdates\\temp\\ready", tdataDir = L"tupdates\\temp\\tdata";
{
HANDLE readyFile = CreateFile(readyFilePath.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (readyFile != INVALID_HANDLE_VALUE) {
CloseHandle(readyFile);
} else {
updDir = L"tupdates\\ready"; // old
tdataDir = L"tupdates\\ready\\tdata";
}
}
HANDLE versionFile = CreateFile((tdataDir + L"\\version").c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (versionFile != INVALID_HANDLE_VALUE) {
if (!ReadFile(versionFile, &versionNum, sizeof(DWORD), &readLen, NULL) || readLen != sizeof(DWORD)) {
versionNum = 0;
} else {
if (versionNum == 0x7FFFFFFF) { // beta version
} else if (!ReadFile(versionFile, &versionLen, sizeof(DWORD), &readLen, NULL) || readLen != sizeof(DWORD) || versionLen > 63) {
versionNum = 0;
} else if (!ReadFile(versionFile, versionStr, versionLen, &readLen, NULL) || readLen != versionLen) {
versionNum = 0;
}
}
CloseHandle(versionFile);
writeLog(L"Version file read.");
} else {
writeLog(L"Could not open version file to update registry :(");
}
deque<wstring> dirs;
dirs.push_back(updDir);
deque<wstring> from, to, forcedirs;
do {
wstring dir = dirs.front();
dirs.pop_front();
wstring toDir = updateTo;
if (dir.size() > updDir.size() + 1) {
toDir += (dir.substr(updDir.size() + 1) + L"\\");
forcedirs.push_back(toDir);
writeLog(L"Parsing dir '" + toDir + L"' in update tree..");
}
WIN32_FIND_DATA findData;
HANDLE findHandle = FindFirstFileEx((dir + L"\\*").c_str(), FindExInfoStandard, &findData, FindExSearchNameMatch, 0, 0);
if (findHandle == INVALID_HANDLE_VALUE) {
DWORD errorCode = GetLastError();
if (errorCode == ERROR_PATH_NOT_FOUND) { // no update is ready
return true;
}
writeLog(L"Error: failed to find update files :(");
updateError(L"Failed to find update files", errorCode);
delFolder();
return false;
}
do {
wstring fname = dir + L"\\" + findData.cFileName;
if (fname.substr(0, tdataDir.size()) == tdataDir && (fname.size() <= tdataDir.size() || fname.at(tdataDir.size()) == '/')) {
writeLog(L"Skipped 'tdata' path '" + fname + L"'");
} else if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (findData.cFileName != wstring(L".") && findData.cFileName != wstring(L"..")) {
dirs.push_back(fname);
writeLog(L"Added dir '" + fname + L"' in update tree..");
}
} else {
wstring tofname = updateTo + fname.substr(updDir.size() + 1);
if (equal(tofname, updaterName)) { // bad update - has Updater.exe - delete all dir
writeLog(L"Error: bad update, has Updater.exe! '" + tofname + L"' equal '" + updaterName + L"'");
delFolder();
return false;
} else if (equal(tofname, updateTo + L"Telegram.exe") && exeName != L"Telegram.exe") {
wstring fullBinaryPath = updateTo + exeName;
writeLog(L"Target binary found: '" + tofname + L"', changing to '" + fullBinaryPath + L"'");
tofname = fullBinaryPath;
}
if (equal(fname, readyFilePath)) {
writeLog(L"Skipped ready file '" + fname + L"'");
} else {
from.push_back(fname);
to.push_back(tofname);
writeLog(L"Added file '" + fname + L"' to be copied to '" + tofname + L"'");
}
}
} while (FindNextFile(findHandle, &findData));
DWORD errorCode = GetLastError();
if (errorCode && errorCode != ERROR_NO_MORE_FILES) { // everything is found
writeLog(L"Error: failed to find next update file :(");
updateError(L"Failed to find next update file", errorCode);
delFolder();
return false;
}
FindClose(findHandle);
} while (!dirs.empty());
for (size_t i = 0; i < forcedirs.size(); ++i) {
wstring forcedir = forcedirs[i];
writeLog(L"Forcing dir '" + forcedir + L"'..");
if (!forcedir.empty() && !CreateDirectory(forcedir.c_str(), NULL)) {
DWORD errorCode = GetLastError();
if (errorCode && errorCode != ERROR_ALREADY_EXISTS) {
writeLog(L"Error: failed to create dir '" + forcedir + L"'..");
updateError(L"Failed to create directory", errorCode);
delFolder();
return false;
}
writeLog(L"Already exists!");
}
}
for (size_t i = 0; i < from.size(); ++i) {
wstring fname = from[i], tofname = to[i];
BOOL copyResult;
do {
writeLog(L"Copying file '" + fname + L"' to '" + tofname + L"'..");
int copyTries = 0;
do {
copyResult = CopyFile(fname.c_str(), tofname.c_str(), FALSE);
if (!copyResult) {
++copyTries;
Sleep(100);
} else {
break;
}
} while (copyTries < 100);
if (!copyResult) {
writeLog(L"Error: failed to copy, asking to retry..");
WCHAR errMsg[2048];
wsprintf(errMsg, L"Failed to update Telegram :(\n%s is not accessible.", tofname.c_str());
if (MessageBox(0, errMsg, L"Update error!", MB_ICONERROR | MB_RETRYCANCEL) != IDRETRY) {
delFolder();
return false;
}
}
} while (!copyResult);
}
writeLog(L"Update succeed! Clearing folder..");
delFolder();
return true;
}
void updateRegistry() {
if (versionNum && versionNum != 0x7FFFFFFF) {
writeLog(L"Updating registry..");
versionStr[versionLen / 2] = 0;
HKEY rkey;
LSTATUS status = RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{53F49750-6209-4FBF-9CA8-7A333C87D1ED}_is1", 0, KEY_QUERY_VALUE | KEY_SET_VALUE, &rkey);
if (status == ERROR_SUCCESS) {
writeLog(L"Checking registry install location..");
static const int bufSize = 4096;
DWORD locationType, locationSize = bufSize * 2;
WCHAR locationStr[bufSize], exp[bufSize];
if (RegQueryValueEx(rkey, L"InstallLocation", 0, &locationType, (BYTE*)locationStr, &locationSize) == ERROR_SUCCESS) {
locationSize /= 2;
if (locationStr[locationSize - 1]) {
locationStr[locationSize++] = 0;
}
if (locationType == REG_EXPAND_SZ) {
DWORD copy = ExpandEnvironmentStrings(locationStr, exp, bufSize);
if (copy <= bufSize) {
memcpy(locationStr, exp, copy * sizeof(WCHAR));
}
}
if (locationType == REG_EXPAND_SZ || locationType == REG_SZ) {
if (PathCanonicalize(exp, locationStr)) {
memcpy(locationStr, exp, bufSize * sizeof(WCHAR));
if (GetFullPathName(L".", bufSize, exp, 0) < bufSize) {
wstring installpath = locationStr, mypath = exp;
if (installpath == mypath + L"\\" || true) { // always update reg info, if we found it
WCHAR nameStr[bufSize], dateStr[bufSize], publisherStr[bufSize], icongroupStr[bufSize];
SYSTEMTIME stLocalTime;
GetLocalTime(&stLocalTime);
RegSetValueEx(rkey, L"DisplayVersion", 0, REG_SZ, (BYTE*)versionStr, ((versionLen / 2) + 1) * sizeof(WCHAR));
wsprintf(nameStr, L"Telegram Desktop version %s", versionStr);
RegSetValueEx(rkey, L"DisplayName", 0, REG_SZ, (BYTE*)nameStr, (wcslen(nameStr) + 1) * sizeof(WCHAR));
wsprintf(publisherStr, L"Telegram Messenger LLP");
RegSetValueEx(rkey, L"Publisher", 0, REG_SZ, (BYTE*)publisherStr, (wcslen(publisherStr) + 1) * sizeof(WCHAR));
wsprintf(icongroupStr, L"Telegram Desktop");
RegSetValueEx(rkey, L"Inno Setup: Icon Group", 0, REG_SZ, (BYTE*)icongroupStr, (wcslen(icongroupStr) + 1) * sizeof(WCHAR));
wsprintf(dateStr, L"%04d%02d%02d", stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay);
RegSetValueEx(rkey, L"InstallDate", 0, REG_SZ, (BYTE*)dateStr, (wcslen(dateStr) + 1) * sizeof(WCHAR));
WCHAR *appURL = L"https://desktop.telegram.org";
RegSetValueEx(rkey, L"HelpLink", 0, REG_SZ, (BYTE*)appURL, (wcslen(appURL) + 1) * sizeof(WCHAR));
RegSetValueEx(rkey, L"URLInfoAbout", 0, REG_SZ, (BYTE*)appURL, (wcslen(appURL) + 1) * sizeof(WCHAR));
RegSetValueEx(rkey, L"URLUpdateInfo", 0, REG_SZ, (BYTE*)appURL, (wcslen(appURL) + 1) * sizeof(WCHAR));
}
}
}
}
}
RegCloseKey(rkey);
}
}
}
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prevInstance, LPWSTR cmdParamarg, int cmdShow) {
openLog();
_oldWndExceptionFilter = SetUnhandledExceptionFilter(_exceptionFilter);
// CAPIHook apiHook("kernel32.dll", "SetUnhandledExceptionFilter", (PROC)RedirectedSetUnhandledExceptionFilter);
writeLog(L"Updaters started..");
LPWSTR *args;
int argsCount;
bool needupdate = false, autostart = false, debug = false, writeprotected = false, startintray = false, testmode = false;
args = CommandLineToArgvW(GetCommandLine(), &argsCount);
if (args) {
for (int i = 1; i < argsCount; ++i) {
if (equal(args[i], L"-update")) {
needupdate = true;
} else if (equal(args[i], L"-autostart")) {
autostart = true;
} else if (equal(args[i], L"-debug")) {
debug = _debug = true;
openLog();
} else if (equal(args[i], L"-startintray")) {
startintray = true;
} else if (equal(args[i], L"-testmode")) {
testmode = true;
} else if (equal(args[i], L"-writeprotected") && ++i < argsCount) {
writeprotected = true;
updateTo = args[i];
for (int i = 0, l = updateTo.size(); i < l; ++i) {
if (updateTo[i] == L'/') {
updateTo[i] = L'\\';
}
}
} else if (equal(args[i], L"-exename") && ++i < argsCount) {
exeName = args[i];
for (int i = 0, l = exeName.size(); i < l; ++i) {
if (exeName[i] == L'/' || exeName[i] == L'\\') {
exeName = L"Telegram.exe";
break;
}
}
}
}
if (exeName.empty()) {
exeName = L"Telegram.exe";
}
if (needupdate) writeLog(L"Need to update!");
if (autostart) writeLog(L"From autostart!");
if (writeprotected) writeLog(L"Write Protected folder!");
updaterName = args[0];
writeLog(L"Updater name is: " + updaterName);
if (updaterName.size() > 11) {
if (equal(updaterName.substr(updaterName.size() - 11), L"Updater.exe")) {
updaterDir = updaterName.substr(0, updaterName.size() - 11);
writeLog(L"Updater dir is: " + updaterDir);
if (!writeprotected) {
updateTo = updaterDir;
}
writeLog(L"Update to: " + updateTo);
if (needupdate && update()) {
updateRegistry();
}
if (writeprotected) { // if we can't clear all tupdates\ready (Updater.exe is there) - clear only version
if (DeleteFile(L"tupdates\\temp\\tdata\\version") || DeleteFile(L"tupdates\\ready\\tdata\\version")) {
writeLog(L"Version file deleted!");
} else {
writeLog(L"Error: could not delete version file");
}
}
} else {
writeLog(L"Error: bad exe name!");
}
} else {
writeLog(L"Error: short exe name!");
}
LocalFree(args);
} else {
writeLog(L"Error: No command line arguments!");
}
wstring targs;
if (autostart) targs += L" -autostart";
if (debug) targs += L" -debug";
if (startintray) targs += L" -startintray";
if (testmode) targs += L" -testmode";
bool executed = false;
if (writeprotected) { // run un-elevated
writeLog(L"Trying to run un-elevated by temp.lnk");
HRESULT hres = CoInitialize(0);
if (SUCCEEDED(hres)) {
IShellLink* psl;
HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl);
if (SUCCEEDED(hres)) {
IPersistFile* ppf;
wstring exe = updateTo + exeName, dir = updateTo;
psl->SetArguments((targs.size() ? targs.substr(1) : targs).c_str());
psl->SetPath(exe.c_str());
psl->SetWorkingDirectory(dir.c_str());
psl->SetDescription(L"");
hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);
if (SUCCEEDED(hres)) {
wstring lnk = L"tupdates\\temp\\temp.lnk";
hres = ppf->Save(lnk.c_str(), TRUE);
if (!SUCCEEDED(hres)) {
lnk = L"tupdates\\ready\\temp.lnk"; // old
hres = ppf->Save(lnk.c_str(), TRUE);
}
ppf->Release();
if (SUCCEEDED(hres)) {
writeLog(L"Executing un-elevated through link..");
ShellExecute(0, 0, L"explorer.exe", lnk.c_str(), 0, SW_SHOWNORMAL);
executed = true;
} else {
writeLog(L"Error: ppf->Save failed");
}
} else {
writeLog(L"Error: Could not create interface IID_IPersistFile");
}
psl->Release();
} else {
writeLog(L"Error: could not create instance of IID_IShellLink");
}
CoUninitialize();
} else {
writeLog(L"Error: Could not initialize COM");
}
}
if (!executed) {
ShellExecute(0, 0, (updateTo + exeName).c_str(), (L"-noupdate" + targs).c_str(), 0, SW_SHOWNORMAL);
}
writeLog(L"Executed '" + exeName + L"', closing log and quitting..");
closeLog();
return 0;
}
static const WCHAR *_programName = L"Telegram Desktop"; // folder in APPDATA, if current path is unavailable for writing
static const WCHAR *_exeName = L"Updater.exe";
LPTOP_LEVEL_EXCEPTION_FILTER _oldWndExceptionFilter = 0;
typedef BOOL (FAR STDAPICALLTYPE *t_miniDumpWriteDump)(
_In_ HANDLE hProcess,
_In_ DWORD ProcessId,
_In_ HANDLE hFile,
_In_ MINIDUMP_TYPE DumpType,
_In_opt_ PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
_In_opt_ PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
_In_opt_ PMINIDUMP_CALLBACK_INFORMATION CallbackParam
);
t_miniDumpWriteDump miniDumpWriteDump = 0;
HANDLE _generateDumpFileAtPath(const WCHAR *path) {
static const int maxFileLen = MAX_PATH * 10;
WCHAR szPath[maxFileLen];
wsprintf(szPath, L"%stdata\\", path);
if (!CreateDirectory(szPath, NULL)) {
if (GetLastError() != ERROR_ALREADY_EXISTS) {
return 0;
}
}
wsprintf(szPath, L"%sdumps\\", path);
if (!CreateDirectory(szPath, NULL)) {
if (GetLastError() != ERROR_ALREADY_EXISTS) {
return 0;
}
}
WCHAR szFileName[maxFileLen];
WCHAR szExeName[maxFileLen];
wcscpy_s(szExeName, _exeName);
WCHAR *dotFrom = wcschr(szExeName, WCHAR(L'.'));
if (dotFrom) {
wsprintf(dotFrom, L"");
}
SYSTEMTIME stLocalTime;
GetLocalTime(&stLocalTime);
wsprintf(szFileName, L"%s%s-%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp",
szPath, szExeName, updaterVersionStr,
stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond,
GetCurrentProcessId(), GetCurrentThreadId());
return CreateFile(szFileName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
}
void _generateDump(EXCEPTION_POINTERS* pExceptionPointers) {
static const int maxFileLen = MAX_PATH * 10;
closeLog();
HMODULE hDll = LoadLibrary(L"DBGHELP.DLL");
if (!hDll) return;
miniDumpWriteDump = (t_miniDumpWriteDump)GetProcAddress(hDll, "MiniDumpWriteDump");
if (!miniDumpWriteDump) return;
HANDLE hDumpFile = 0;
WCHAR szPath[maxFileLen];
DWORD len = GetModuleFileName(GetModuleHandle(0), szPath, maxFileLen);
if (!len) return;
WCHAR *pathEnd = szPath + len;
if (!_wcsicmp(pathEnd - wcslen(_exeName), _exeName)) {
wsprintf(pathEnd - wcslen(_exeName), L"");
hDumpFile = _generateDumpFileAtPath(szPath);
}
if (!hDumpFile || hDumpFile == INVALID_HANDLE_VALUE) {
WCHAR wstrPath[maxFileLen];
DWORD wstrPathLen;
if (wstrPathLen = GetEnvironmentVariable(L"APPDATA", wstrPath, maxFileLen)) {
wsprintf(wstrPath + wstrPathLen, L"\\%s\\", _programName);
hDumpFile = _generateDumpFileAtPath(wstrPath);
}
}
if (!hDumpFile || hDumpFile == INVALID_HANDLE_VALUE) {
return;
}
MINIDUMP_EXCEPTION_INFORMATION ExpParam = {0};
ExpParam.ThreadId = GetCurrentThreadId();
ExpParam.ExceptionPointers = pExceptionPointers;
ExpParam.ClientPointers = TRUE;
miniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpWithDataSegs, &ExpParam, NULL, NULL);
}
LONG CALLBACK _exceptionFilter(EXCEPTION_POINTERS* pExceptionPointers) {
_generateDump(pExceptionPointers);
return _oldWndExceptionFilter ? (*_oldWndExceptionFilter)(pExceptionPointers) : EXCEPTION_CONTINUE_SEARCH;
}
// see http://www.codeproject.com/Articles/154686/SetUnhandledExceptionFilter-and-the-C-C-Runtime-Li
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI RedirectedSetUnhandledExceptionFilter(_In_opt_ LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter) {
// When the CRT calls SetUnhandledExceptionFilter with NULL parameter
// our handler will not get removed.
_oldWndExceptionFilter = lpTopLevelExceptionFilter;
return 0;
}

View File

@ -1,46 +0,0 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
#include <windows.h>
#include <string>
#pragma warning(push)
#pragma warning(disable:4091)
#include <DbgHelp.h>
#include <ShlObj.h>
#pragma warning(pop)
#include <Shellapi.h>
#include <Shlwapi.h>
#include <deque>
#include <string>
using std::deque;
using std::wstring;
extern LPTOP_LEVEL_EXCEPTION_FILTER _oldWndExceptionFilter;
LONG CALLBACK _exceptionFilter(EXCEPTION_POINTERS* pExceptionPointers);
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI RedirectedSetUnhandledExceptionFilter(_In_opt_ LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter);
static int updaterVersion = 1000;
static const WCHAR *updaterVersionStr = L"0.1.0";

View File

@ -1,476 +0,0 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#include <cstdio>
#include <sys/stat.h>
#include <sys/types.h>
#include <cstdlib>
#include <unistd.h>
#include <dirent.h>
#include <pwd.h>
#include <string>
#include <deque>
#include <cstring>
#include <cerrno>
#include <algorithm>
#include <cstdarg>
#include <ctime>
#include <iostream>
using std::string;
using std::deque;
using std::cout;
bool do_mkdir(const char *path) { // from http://stackoverflow.com/questions/675039/how-can-i-create-directory-tree-in-c-linux
struct stat statbuf;
if (stat(path, &statbuf) != 0) {
/* Directory does not exist. EEXIST for race condition */
if (mkdir(path, S_IRWXU) != 0 && errno != EEXIST) return false;
} else if (!S_ISDIR(statbuf.st_mode)) {
errno = ENOTDIR;
return false;
}
return true;
}
bool _debug = false;
string updaterDir;
string updaterName;
string workDir;
string exeName;
string exePath;
FILE *_logFile = 0;
void openLog() {
if (!_debug || _logFile) return;
if (!do_mkdir((workDir + "DebugLogs").c_str())) {
return;
}
time_t timer;
time(&timer);
struct tm *t = localtime(&timer);
static const int maxFileLen = 65536;
char logName[maxFileLen];
sprintf(logName, "%sDebugLogs/%04d%02d%02d_%02d%02d%02d_upd.txt", workDir.c_str(),
t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
_logFile = fopen(logName, "w");
}
void closeLog() {
if (!_logFile) return;
fclose(_logFile);
_logFile = 0;
}
void writeLog(const char *format, ...) {
if (!_logFile) {
return;
}
va_list args;
va_start(args, format);
vfprintf(_logFile, format, args);
fprintf(_logFile, "\n");
fflush(_logFile);
va_end(args);
}
bool copyFile(const char *from, const char *to) {
FILE *ffrom = fopen(from, "rb"), *fto = fopen(to, "wb");
if (!ffrom) {
if (fto) fclose(fto);
return false;
}
if (!fto) {
fclose(ffrom);
return false;
}
static const int BufSize = 65536;
char buf[BufSize];
while (size_t size = fread(buf, 1, BufSize, ffrom)) {
fwrite(buf, 1, size, fto);
}
struct stat fst; // from http://stackoverflow.com/questions/5486774/keeping-fileowner-and-permissions-after-copying-file-in-c
//let's say this wont fail since you already worked OK on that fp
if (fstat(fileno(ffrom), &fst) != 0) {
fclose(ffrom);
fclose(fto);
return false;
}
//update to the same uid/gid
if (fchown(fileno(fto), fst.st_uid, fst.st_gid) != 0) {
fclose(ffrom);
fclose(fto);
return false;
}
//update the permissions
if (fchmod(fileno(fto), fst.st_mode) != 0) {
fclose(ffrom);
fclose(fto);
return false;
}
fclose(ffrom);
fclose(fto);
return true;
}
bool remove_directory(const string &path) { // from http://stackoverflow.com/questions/2256945/removing-a-non-empty-directory-programmatically-in-c-or-c
DIR *d = opendir(path.c_str());
writeLog("Removing dir '%s'", path.c_str());
if (!d) {
writeLog("Could not open dir '%s'", path.c_str());
return (errno == ENOENT);
}
while (struct dirent *p = readdir(d)) {
/* Skip the names "." and ".." as we don't want to recurse on them. */
if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, "..")) continue;
string fname = path + '/' + p->d_name;
struct stat statbuf;
writeLog("Trying to get stat() for '%s'", fname.c_str());
if (!stat(fname.c_str(), &statbuf)) {
if (S_ISDIR(statbuf.st_mode)) {
if (!remove_directory(fname.c_str())) {
closedir(d);
return false;
}
} else {
writeLog("Unlinking file '%s'", fname.c_str());
if (unlink(fname.c_str())) {
writeLog("Failed to unlink '%s'", fname.c_str());
closedir(d);
return false;
}
}
} else {
writeLog("Failed to call stat() on '%s'", fname.c_str());
}
}
closedir(d);
writeLog("Finally removing dir '%s'", path.c_str());
return !rmdir(path.c_str());
}
bool mkpath(const char *path) {
int status = 0, pathsize = strlen(path) + 1;
char *copypath = new char[pathsize];
memcpy(copypath, path, pathsize);
char *pp = copypath, *sp;
while (status == 0 && (sp = strchr(pp, '/')) != 0) {
if (sp != pp) {
/* Neither root nor double slash in path */
*sp = '\0';
if (!do_mkdir(copypath)) {
delete[] copypath;
return false;
}
*sp = '/';
}
pp = sp + 1;
}
delete[] copypath;
return do_mkdir(path);
}
bool equal(string a, string b) {
std::transform(a.begin(), a.end(), a.begin(), ::tolower);
std::transform(b.begin(), b.end(), b.begin(), ::tolower);
return a == b;
}
void delFolder() {
string delPathOld = workDir + "tupdates/ready", delPath = workDir + "tupdates/temp", delFolder = workDir + "tupdates";
writeLog("Fully clearing old path '%s'..", delPathOld.c_str());
if (!remove_directory(delPathOld)) {
writeLog("Failed to clear old path! :( New path was used?..");
}
writeLog("Fully clearing path '%s'..", delPath.c_str());
if (!remove_directory(delPath)) {
writeLog("Error: failed to clear path! :(");
}
rmdir(delFolder.c_str());
}
bool update() {
writeLog("Update started..");
string updDir = workDir + "tupdates/temp", readyFilePath = workDir + "tupdates/temp/ready", tdataDir = workDir + "tupdates/temp/tdata";
{
FILE *readyFile = fopen(readyFilePath.c_str(), "rb");
if (readyFile) {
fclose(readyFile);
writeLog("Ready file found! Using new path '%s'..", updDir.c_str());
} else {
updDir = workDir + "tupdates/ready"; // old
tdataDir = workDir + "tupdates/ready/tdata";
writeLog("Ready file not found! Using old path '%s'..", updDir.c_str());
}
}
deque<string> dirs;
dirs.push_back(updDir);
deque<string> from, to, forcedirs;
do {
string dir = dirs.front();
dirs.pop_front();
string toDir = exePath;
if (dir.size() > updDir.size() + 1) {
toDir += (dir.substr(updDir.size() + 1) + '/');
forcedirs.push_back(toDir);
writeLog("Parsing dir '%s' in update tree..", toDir.c_str());
}
DIR *d = opendir(dir.c_str());
if (!d) {
writeLog("Failed to open dir %s", dir.c_str());
return false;
}
while (struct dirent *p = readdir(d)) {
/* Skip the names "." and ".." as we don't want to recurse on them. */
if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, "..")) continue;
string fname = dir + '/' + p->d_name;
struct stat statbuf;
if (fname.substr(0, tdataDir.size()) == tdataDir && (fname.size() <= tdataDir.size() || fname.at(tdataDir.size()) == '/')) {
writeLog("Skipping 'tdata' path '%s'", fname.c_str());
} else if (!stat(fname.c_str(), &statbuf)) {
if (S_ISDIR(statbuf.st_mode)) {
dirs.push_back(fname);
writeLog("Added dir '%s' in update tree..", fname.c_str());
} else {
string tofname = exePath + fname.substr(updDir.size() + 1);
if (equal(tofname, updaterName)) { // bad update - has Updater - delete all dir
writeLog("Error: bad update, has Updater! '%s' equal '%s'", tofname.c_str(), updaterName.c_str());
delFolder();
return false;
} else if (equal(tofname, exePath + "Telegram") && exeName != "Telegram") {
string fullBinaryPath = exePath + exeName;
writeLog("Target binary found: '%s', changing to '%s'", tofname.c_str(), fullBinaryPath.c_str());
tofname = fullBinaryPath;
}
if (fname == readyFilePath) {
writeLog("Skipped ready file '%s'", fname.c_str());
} else {
from.push_back(fname);
to.push_back(tofname);
writeLog("Added file '%s' to be copied to '%s'", fname.c_str(), tofname.c_str());
}
}
} else {
writeLog("Could not get stat() for file %s", fname.c_str());
}
}
closedir(d);
} while (!dirs.empty());
for (size_t i = 0; i < forcedirs.size(); ++i) {
string forcedir = forcedirs[i];
writeLog("Forcing dir '%s'..", forcedir.c_str());
if (!forcedir.empty() && !mkpath(forcedir.c_str())) {
writeLog("Error: failed to create dir '%s'..", forcedir.c_str());
delFolder();
return false;
}
}
for (size_t i = 0; i < from.size(); ++i) {
string fname = from[i], tofname = to[i];
writeLog("Copying file '%s' to '%s'..", fname.c_str(), tofname.c_str());
int copyTries = 0, triesLimit = 30;
do {
if (!copyFile(fname.c_str(), tofname.c_str())) {
++copyTries;
usleep(100000);
} else {
break;
}
} while (copyTries < triesLimit);
if (copyTries == triesLimit) {
writeLog("Error: failed to copy, asking to retry..");
delFolder();
return false;
}
}
writeLog("Update succeed! Clearing folder..");
delFolder();
return true;
}
string CurrentExecutablePath(int argc, char *argv[]) {
constexpr auto kMaxPath = 1024;
char result[kMaxPath] = { 0 };
auto count = readlink("/proc/self/exe", result, kMaxPath);
if (count > 0) {
return string(result);
}
// Fallback to the first command line argument.
return argc ? string(argv[0]) : string();
}
int main(int argc, char *argv[]) {
bool needupdate = true, autostart = false, debug = false, tosettings = false, startintray = false, testmode = false;
char *key = 0, *crashreport = 0;
for (int i = 1; i < argc; ++i) {
if (equal(argv[i], "-noupdate")) {
needupdate = false;
} else if (equal(argv[i], "-autostart")) {
autostart = true;
} else if (equal(argv[i], "-debug")) {
debug = _debug = true;
} else if (equal(argv[i], "-startintray")) {
startintray = true;
} else if (equal(argv[i], "-testmode")) {
testmode = true;
} else if (equal(argv[i], "-tosettings")) {
tosettings = true;
} else if (equal(argv[i], "-key") && ++i < argc) {
key = argv[i];
} else if (equal(argv[i], "-workpath") && ++i < argc) {
workDir = argv[i];
} else if (equal(argv[i], "-crashreport") && ++i < argc) {
crashreport = argv[i];
} else if (equal(argv[i], "-exename") && ++i < argc) {
exeName = argv[i];
} else if (equal(argv[i], "-exepath") && ++i < argc) {
exePath = argv[i];
}
}
if (exeName.empty() || exeName.find('/') != string::npos) {
exeName = "Telegram";
}
openLog();
writeLog("Updater started..");
for (int i = 0; i < argc; ++i) {
writeLog("Argument: '%s'", argv[i]);
}
if (needupdate) writeLog("Need to update!");
if (autostart) writeLog("From autostart!");
updaterName = CurrentExecutablePath(argc, argv);
writeLog("Updater binary full path is: %s", updaterName.c_str());
if (exePath.empty()) {
writeLog("Executable path is not specified :(");
} else {
writeLog("Executable path: %s", exePath.c_str());
}
if (updaterName.size() >= 7) {
if (equal(updaterName.substr(updaterName.size() - 7), "Updater")) {
updaterDir = updaterName.substr(0, updaterName.size() - 7);
writeLog("Updater binary dir is: %s", updaterDir.c_str());
if (exePath.empty()) {
exePath = updaterDir;
writeLog("Using updater binary dir.", exePath.c_str());
}
if (needupdate) {
if (workDir.empty()) { // old app launched, update prepared in tupdates/ready (not in tupdates/temp)
writeLog("No workdir, trying to figure it out");
struct passwd *pw = getpwuid(getuid());
if (pw && pw->pw_dir && strlen(pw->pw_dir)) {
string tryDir = pw->pw_dir + string("/.TelegramDesktop/");
struct stat statbuf;
writeLog("Trying to use '%s' as workDir, getting stat() for tupdates/ready", tryDir.c_str());
if (!stat((tryDir + "tupdates/ready").c_str(), &statbuf)) {
writeLog("Stat got");
if (S_ISDIR(statbuf.st_mode)) {
writeLog("It is directory, using home work dir");
workDir = tryDir;
}
}
}
if (workDir.empty()) {
workDir = exePath;
struct stat statbuf;
writeLog("Trying to use current as workDir, getting stat() for tupdates/ready");
if (!stat("tupdates/ready", &statbuf)) {
writeLog("Stat got");
if (S_ISDIR(statbuf.st_mode)) {
writeLog("It is directory, using current dir");
workDir = string();
}
}
}
} else {
writeLog("Passed workpath is '%s'", workDir.c_str());
}
update();
}
} else {
writeLog("Error: bad exe name!");
}
} else {
writeLog("Error: short exe name!");
}
static const int MaxLen = 65536, MaxArgsCount = 128;
char path[MaxLen] = {0};
string fullBinaryPath = exePath + exeName;
strcpy(path, fullBinaryPath.c_str());
char *args[MaxArgsCount] = {0}, p_noupdate[] = "-noupdate", p_autostart[] = "-autostart", p_debug[] = "-debug", p_tosettings[] = "-tosettings", p_key[] = "-key", p_startintray[] = "-startintray", p_testmode[] = "-testmode";
int argIndex = 0;
args[argIndex++] = path;
if (crashreport) {
args[argIndex++] = crashreport;
} else {
args[argIndex++] = p_noupdate;
if (autostart) args[argIndex++] = p_autostart;
if (debug) args[argIndex++] = p_debug;
if (startintray) args[argIndex++] = p_startintray;
if (testmode) args[argIndex++] = p_testmode;
if (tosettings) args[argIndex++] = p_tosettings;
if (key) {
args[argIndex++] = p_key;
args[argIndex++] = key;
}
}
pid_t pid = fork();
switch (pid) {
case -1: writeLog("fork() failed!"); return 1;
case 0: execv(path, args); return 1;
}
writeLog("Executed Telegram, closing log and quitting..");
closeLog();
return 0;
}

View File

@ -1,272 +0,0 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#import <Cocoa/Cocoa.h>
NSString *appName = @"Telegram.app";
NSString *appDir = nil;
NSString *workDir = nil;
NSString *crashReportArg = nil;
#ifdef _DEBUG
BOOL _debug = YES;
#else
BOOL _debug = NO;
#endif
NSFileHandle *_logFile = nil;
void openLog() {
if (!_debug || _logFile) return;
NSString *logDir = [workDir stringByAppendingString:@"DebugLogs"];
if (![[NSFileManager defaultManager] createDirectoryAtPath:logDir withIntermediateDirectories:YES attributes:nil error:nil]) {
return;
}
NSDateFormatter *fmt = [[NSDateFormatter alloc] initWithDateFormat:@"DebugLogs/%Y%m%d_%H%M%S_upd.txt" allowNaturalLanguage:NO];
NSString *logPath = [workDir stringByAppendingString:[fmt stringFromDate:[NSDate date]]];
[[NSFileManager defaultManager] createFileAtPath:logPath contents:nil attributes:nil];
_logFile = [NSFileHandle fileHandleForWritingAtPath:logPath];
}
void closeLog() {
if (!_logFile) return;
[_logFile closeFile];
}
void writeLog(NSString *msg) {
if (!_logFile) return;
[_logFile writeData:[[msg stringByAppendingString:@"\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[_logFile synchronizeFile];
}
void delFolder() {
writeLog([@"Fully clearing old path: " stringByAppendingString:[workDir stringByAppendingString:@"tupdates/ready"]]);
if (![[NSFileManager defaultManager] removeItemAtPath:[workDir stringByAppendingString:@"tupdates/ready"] error:nil]) {
writeLog(@"Failed to clear old path! :( New path was used?..");
}
writeLog([@"Fully clearing new path: " stringByAppendingString:[workDir stringByAppendingString:@"tupdates/temp"]]);
if (![[NSFileManager defaultManager] removeItemAtPath:[workDir stringByAppendingString:@"tupdates/temp"] error:nil]) {
writeLog(@"Error: failed to clear new path! :(");
}
rmdir([[workDir stringByAppendingString:@"tupdates"] fileSystemRepresentation]);
}
int main(int argc, const char * argv[]) {
NSString *path = [[NSBundle mainBundle] bundlePath];
if (!path) {
return -1;
}
NSRange range = [path rangeOfString:@".app/" options:NSBackwardsSearch];
if (range.location == NSNotFound) {
return -1;
}
path = [path substringToIndex:range.location > 0 ? range.location : 0];
range = [path rangeOfString:@"/" options:NSBackwardsSearch];
NSString *appRealName = (range.location == NSNotFound) ? path : [path substringFromIndex:range.location + 1];
appRealName = [[NSArray arrayWithObjects:appRealName, @".app", nil] componentsJoinedByString:@""];
appDir = (range.location == NSNotFound) ? @"" : [path substringToIndex:range.location + 1];
NSString *appDirFull = [appDir stringByAppendingString:appRealName];
openLog();
pid_t procId = 0;
BOOL update = YES, toSettings = NO, autoStart = NO, startInTray = NO, testMode = NO;
NSString *key = nil;
for (int i = 0; i < argc; ++i) {
if ([@"-workpath" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
if (++i < argc) {
workDir = [NSString stringWithUTF8String:argv[i]];
}
} else if ([@"-procid" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
if (++i < argc) {
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
procId = [[formatter numberFromString:[NSString stringWithUTF8String:argv[i]]] intValue];
}
} else if ([@"-crashreport" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
if (++i < argc) {
crashReportArg = [NSString stringWithUTF8String:argv[i]];
}
} else if ([@"-noupdate" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
update = NO;
} else if ([@"-tosettings" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
toSettings = YES;
} else if ([@"-autostart" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
autoStart = YES;
} else if ([@"-debug" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
_debug = YES;
} else if ([@"-startintray" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
startInTray = YES;
} else if ([@"-testmode" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
testMode = YES;
} else if ([@"-key" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
if (++i < argc) key = [NSString stringWithUTF8String:argv[i]];
}
}
if (!workDir) workDir = appDir;
openLog();
NSMutableArray *argsArr = [[NSMutableArray alloc] initWithCapacity:argc];
for (int i = 0; i < argc; ++i) {
[argsArr addObject:[NSString stringWithUTF8String:argv[i]]];
}
writeLog([[NSArray arrayWithObjects:@"Arguments: '", [argsArr componentsJoinedByString:@"' '"], @"'..", nil] componentsJoinedByString:@""]);
if (key) writeLog([@"Key: " stringByAppendingString:key]);
if (toSettings) writeLog(@"To Settings!");
if (procId) {
NSRunningApplication *app = [NSRunningApplication runningApplicationWithProcessIdentifier:procId];
for (int i = 0; i < 5 && app != nil && ![app isTerminated]; ++i) {
usleep(200000);
app = [NSRunningApplication runningApplicationWithProcessIdentifier:procId];
}
if (app) [app forceTerminate];
app = [NSRunningApplication runningApplicationWithProcessIdentifier:procId];
for (int i = 0; i < 5 && app != nil && ![app isTerminated]; ++i) {
usleep(200000);
app = [NSRunningApplication runningApplicationWithProcessIdentifier:procId];
}
}
if (update) {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *readyFilePath = [workDir stringByAppendingString:@"tupdates/temp/ready"];
NSString *srcDir = [workDir stringByAppendingString:@"tupdates/temp/"], *srcEnum = [workDir stringByAppendingString:@"tupdates/temp"];
if ([fileManager fileExistsAtPath:readyFilePath]) {
writeLog([@"Ready file found! Using new path: " stringByAppendingString: srcEnum]);
} else {
srcDir = [workDir stringByAppendingString:@"tupdates/ready/"]; // old
srcEnum = [workDir stringByAppendingString:@"tupdates/ready"];
writeLog([@"Ready file not found! Using old path: " stringByAppendingString: srcEnum]);
}
writeLog([@"Starting update files iteration, path: " stringByAppendingString: srcEnum]);
// Take the Updater (this currently running binary) from the place where it was placed by Telegram
// and copy it to the folder with the new version of the app (ready),
// so it won't be deleted when we will clear the "Telegram.app/Contents" folder.
NSString *oldVersionUpdaterPath = [appDirFull stringByAppendingString: @"/Contents/Frameworks/Updater" ];
NSString *newVersionUpdaterPath = [srcEnum stringByAppendingString:[[NSArray arrayWithObjects:@"/", appName, @"/Contents/Frameworks/Updater", nil] componentsJoinedByString:@""]];
writeLog([[NSArray arrayWithObjects: @"Copying Updater from old path ", oldVersionUpdaterPath, @" to new path ", newVersionUpdaterPath, nil] componentsJoinedByString:@""]);
if (![fileManager fileExistsAtPath:newVersionUpdaterPath]) {
if (![fileManager copyItemAtPath:oldVersionUpdaterPath toPath:newVersionUpdaterPath error:nil]) {
writeLog([[NSArray arrayWithObjects: @"Failed to copy file from ", oldVersionUpdaterPath, @" to ", newVersionUpdaterPath, nil] componentsJoinedByString:@""]);
delFolder();
return -1;
}
}
NSString *contentsPath = [appDirFull stringByAppendingString: @"/Contents"];
writeLog([[NSArray arrayWithObjects: @"Clearing dir ", contentsPath, nil] componentsJoinedByString:@""]);
if (![fileManager removeItemAtPath:contentsPath error:nil]) {
writeLog([@"Failed to clear path for directory " stringByAppendingString:contentsPath]);
delFolder();
return -1;
}
NSArray *keys = [NSArray arrayWithObject:NSURLIsDirectoryKey];
NSDirectoryEnumerator *enumerator = [fileManager
enumeratorAtURL:[NSURL fileURLWithPath:srcEnum]
includingPropertiesForKeys:keys
options:0
errorHandler:^(NSURL *url, NSError *error) {
writeLog([[[@"Error in enumerating " stringByAppendingString:[url absoluteString]] stringByAppendingString: @" error is: "] stringByAppendingString: [error description]]);
return NO;
}];
for (NSURL *url in enumerator) {
NSString *srcPath = [url path];
writeLog([@"Handling file " stringByAppendingString:srcPath]);
NSRange r = [srcPath rangeOfString:srcDir];
if (r.location != 0) {
writeLog([@"Bad file found, no base path " stringByAppendingString:srcPath]);
delFolder();
break;
}
NSString *pathPart = [srcPath substringFromIndex:r.length];
r = [pathPart rangeOfString:appName];
if (r.location != 0) {
writeLog([@"Skipping not app file " stringByAppendingString:srcPath]);
continue;
}
NSString *dstPath = [appDirFull stringByAppendingString:[pathPart substringFromIndex:r.length]];
NSError *error;
NSNumber *isDirectory = nil;
if (![url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:&error]) {
writeLog([@"Failed to get IsDirectory for file " stringByAppendingString:[url path]]);
delFolder();
break;
}
if ([isDirectory boolValue]) {
writeLog([[NSArray arrayWithObjects: @"Copying dir ", srcPath, @" to ", dstPath, nil] componentsJoinedByString:@""]);
if (![fileManager createDirectoryAtPath:dstPath withIntermediateDirectories:YES attributes:nil error:nil]) {
writeLog([@"Failed to force path for directory " stringByAppendingString:dstPath]);
delFolder();
break;
}
} else if ([srcPath isEqualToString:readyFilePath]) {
writeLog([[NSArray arrayWithObjects: @"Skipping ready file ", srcPath, nil] componentsJoinedByString:@""]);
} else if ([fileManager fileExistsAtPath:dstPath]) {
if (![[NSData dataWithContentsOfFile:srcPath] writeToFile:dstPath atomically:YES]) {
writeLog([@"Failed to edit file " stringByAppendingString:dstPath]);
delFolder();
break;
}
} else {
if (![fileManager copyItemAtPath:srcPath toPath:dstPath error:nil]) {
writeLog([@"Failed to copy file to " stringByAppendingString:dstPath]);
delFolder();
break;
}
}
}
delFolder();
}
NSString *appPath = [[NSArray arrayWithObjects:appDir, appRealName, nil] componentsJoinedByString:@""];
NSMutableArray *args = [[NSMutableArray alloc] initWithObjects: crashReportArg ? crashReportArg : @"-noupdate", nil];
if (!crashReportArg) {
if (toSettings) [args addObject:@"-tosettings"];
if (_debug) [args addObject:@"-debug"];
if (startInTray) [args addObject:@"-startintray"];
if (testMode) [args addObject:@"-testmode"];
if (autoStart) [args addObject:@"-autostart"];
if (key) {
[args addObject:@"-key"];
[args addObject:key];
}
}
writeLog([[NSArray arrayWithObjects:@"Running application '", appPath, @"' with args '", [args componentsJoinedByString:@"' '"], @"'..", nil] componentsJoinedByString:@""]);
NSError *error = nil;
NSRunningApplication *result = [[NSWorkspace sharedWorkspace]
launchApplicationAtURL:[NSURL fileURLWithPath:appPath]
options:NSWorkspaceLaunchDefault
configuration:[NSDictionary
dictionaryWithObject:args
forKey:NSWorkspaceLaunchConfigurationArguments]
error:&error];
if (!result) {
writeLog([@"Could not run application, error: " stringByAppendingString:error ? [error localizedDescription] : @"(nil)"]);
}
closeLog();
return result ? 0 : -1;
}

View File

@ -121,7 +121,7 @@ void ApiWrap::addLocalChangelogs(int oldAppVersion) {
}
}
void ApiWrap::applyUpdates(const MTPUpdates &updates, uint64 sentMessageRandomId) {
void ApiWrap::applyUpdates(const MTPUpdates &updates, uint64_t sentMessageRandomId) {
App::main()->feedUpdates(updates, sentMessageRandomId);
}
@ -796,7 +796,7 @@ void ApiWrap::unblockParticipant(PeerData *peer, UserData *user) {
}
}
void ApiWrap::scheduleStickerSetRequest(uint64 setId, uint64 access) {
void ApiWrap::scheduleStickerSetRequest(uint64_t setId, uint64_t access) {
if (!_stickerSetRequests.contains(setId)) {
_stickerSetRequests.insert(setId, qMakePair(access, 0));
}
@ -1274,7 +1274,7 @@ PeerData *ApiWrap::notifySettingReceived(MTPInputNotifyPeer notifyPeer, const MT
return requestedPeer;
}
void ApiWrap::gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result) {
void ApiWrap::gotStickerSet(uint64_t setId, const MTPmessages_StickerSet &result) {
_stickerSetRequests.remove(setId);
Stickers::FeedSetFull(result);
}
@ -1302,13 +1302,13 @@ void ApiWrap::clearWebPageRequests() {
void ApiWrap::resolveWebPages() {
auto ids = QVector<MTPint>(); // temp_req_id = -1
using IndexAndMessageIds = QPair<int32, QVector<MTPint>>;
using IndexAndMessageIds = QPair<int32_t, QVector<MTPint>>;
using MessageIdsByChannel = QMap<ChannelData*, IndexAndMessageIds>;
MessageIdsByChannel idsByChannel; // temp_req_id = -index - 2
auto &items = App::webPageItems();
ids.reserve(_webPagesPending.size());
int32 t = unixtime(), m = INT_MAX;
int32_t t = unixtime(), m = INT_MAX;
for (auto i = _webPagesPending.begin(); i != _webPagesPending.cend(); ++i) {
if (i.value() > 0) continue;
if (i.key()->pendingTill <= t) {
@ -1405,13 +1405,13 @@ void ApiWrap::gotWebPages(ChannelData *channel, const MTPmessages_Messages &msgs
}
if (!v) return;
QMap<uint64, int32> msgsIds; // copied from feedMsgs
for (int32 i = 0, l = v->size(); i < l; ++i) {
QMap<uint64_t, int32_t> msgsIds; // copied from feedMsgs
for (int32_t i = 0, l = v->size(); i < l; ++i) {
const auto &msg(v->at(i));
switch (msg.type()) {
case mtpc_message: msgsIds.insert((uint64(uint32(msg.c_message().vid.v)) << 32) | uint64(i), i); break;
case mtpc_messageEmpty: msgsIds.insert((uint64(uint32(msg.c_messageEmpty().vid.v)) << 32) | uint64(i), i); break;
case mtpc_messageService: msgsIds.insert((uint64(uint32(msg.c_messageService().vid.v)) << 32) | uint64(i), i); break;
case mtpc_message: msgsIds.insert((uint64_t(uint32_t(msg.c_message().vid.v)) << 32) | uint64_t(i), i); break;
case mtpc_messageEmpty: msgsIds.insert((uint64_t(uint32_t(msg.c_messageEmpty().vid.v)) << 32) | uint64_t(i), i); break;
case mtpc_messageService: msgsIds.insert((uint64_t(uint32_t(msg.c_messageService().vid.v)) << 32) | uint64_t(i), i); break;
}
}

View File

@ -21,6 +21,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#pragma once
#include "base/timer.h"
#include <QtCore/QObject>
#include "mtproto/rpc_sender.h"
#include "mtproto/core_types.h"
#include "core/single_timer.h"
#include "mtproto/sender.h"
#include "base/flat_map.h"
@ -45,7 +48,7 @@ public:
ApiWrap(not_null<AuthSession*> session);
void start();
void applyUpdates(const MTPUpdates &updates, uint64 sentMessageRandomId = 0);
void applyUpdates(const MTPUpdates &updates, uint64_t sentMessageRandomId = 0);
using RequestMessageDataCallback = base::lambda<void(ChannelData*, MsgId)>;
void requestMessageData(ChannelData *channel, MsgId msgId, RequestMessageDataCallback callback);
@ -68,7 +71,7 @@ public:
void clearWebPageRequest(WebPageData *page);
void clearWebPageRequests();
void scheduleStickerSetRequest(uint64 setId, uint64 access);
void scheduleStickerSetRequest(uint64_t setId, uint64_t access);
void requestStickerSets();
void saveStickerSets(const Stickers::Order &localOrder, const Stickers::Order &localRemoved);
void updateStickers();
@ -136,7 +139,7 @@ private:
void lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelParticipants &result, mtpRequestId req);
void resolveWebPages();
void gotWebPages(ChannelData *channel, const MTPmessages_Messages &result, mtpRequestId req);
void gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result);
void gotStickerSet(uint64_t setId, const MTPmessages_StickerSet &result);
PeerData *notifySettingReceived(MTPInputNotifyPeer peer, const MTPPeerNotifySettings &settings);
@ -177,7 +180,7 @@ private:
QMap<WebPageData*, mtpRequestId> _webPagesPending;
base::Timer _webPagesTimer;
QMap<uint64, QPair<uint64, mtpRequestId> > _stickerSetRequests;
QMap<uint64_t, QPair<uint64_t, mtpRequestId> > _stickerSetRequests;
QMap<ChannelData*, mtpRequestId> _channelAmInRequests;
QMap<UserData*, mtpRequestId> _blockRequests;

View File

@ -91,10 +91,10 @@ namespace {
using ChannelMsgsData = QMap<ChannelId, MsgsData>;
ChannelMsgsData channelMsgsData;
using RandomData = QMap<uint64, FullMsgId>;
using RandomData = QMap<uint64_t, FullMsgId>;
RandomData randomData;
using SentData = QMap<uint64, QPair<PeerId, QString>>;
using SentData = QMap<uint64_t, QPair<PeerId, QString>>;
SentData sentData;
HistoryItem *hoveredItem = nullptr,
@ -111,7 +111,7 @@ namespace {
QPixmap p[4];
};
QVector<CornersPixmaps> corners;
using CornersMap = QMap<uint32, CornersPixmaps>;
using CornersMap = QMap<uint32_t, CornersPixmaps>;
CornersMap cornersMap;
QImage cornersMaskLarge[4], cornersMaskSmall[4];
@ -119,7 +119,7 @@ namespace {
EmojiImagesMap MainEmojiMap;
QMap<int, EmojiImagesMap> OtherEmojiMap;
int32 serviceImageCacheSize = 0;
int32_t serviceImageCacheSize = 0;
using LastPhotosList = QLinkedList<PhotoData*>;
LastPhotosList lastPhotos;
@ -145,8 +145,8 @@ namespace App {
QString result;
result.reserve(number.size() + groups.size() + 1);
result.append('+');
int32 sum = 0;
for (int32 i = 0, l = groups.size(); i < l; ++i) {
int32_t sum = 0;
for (int32_t i = 0, l = groups.size(); i < l; ++i) {
result.append(number.midRef(sum, groups.at(i)));
sum += groups.at(i);
if (sum < number.size()) result.append(' ');
@ -227,17 +227,17 @@ namespace {
case -2: {
QDate yesterday(date(now).date());
return int32(QDateTime(yesterday.addDays(-3)).toTime_t()) + (unixtime() - myunixtime());
return int32_t(QDateTime(yesterday.addDays(-3)).toTime_t()) + (unixtime() - myunixtime());
} break;
case -3: {
QDate weekago(date(now).date());
return int32(QDateTime(weekago.addDays(-7)).toTime_t()) + (unixtime() - myunixtime());
return int32_t(QDateTime(weekago.addDays(-7)).toTime_t()) + (unixtime() - myunixtime());
} break;
case -4: {
QDate monthago(date(now).date());
return int32(QDateTime(monthago.addDays(-30)).toTime_t()) + (unixtime() - myunixtime());
return int32_t(QDateTime(monthago.addDays(-30)).toTime_t()) + (unixtime() - myunixtime());
} break;
}
return -online;
@ -245,14 +245,14 @@ namespace {
return online;
}
int32 onlineWillChangeIn(UserData *user, TimeId now) {
int32_t onlineWillChangeIn(UserData *user, TimeId now) {
if (isServiceUser(user->id) || user->botInfo) {
return 86400;
}
return onlineWillChangeIn(user->onlineTill, now);
}
int32 onlineWillChangeIn(TimeId online, TimeId now) {
int32_t onlineWillChangeIn(TimeId online, TimeId now) {
if (online <= 0) {
if (-online > now) return -online - now;
return 86400;
@ -260,11 +260,11 @@ namespace {
if (online > now) {
return online - now;
}
int32 minutes = (now - online) / 60;
int32_t minutes = (now - online) / 60;
if (minutes < 60) {
return (minutes + 1) * 60 - (now - online);
}
int32 hours = (now - online) / 3600;
int32_t hours = (now - online) / 3600;
if (hours < 12) {
return (hours + 1) * 3600 - (now - online);
}
@ -307,13 +307,13 @@ namespace {
}
return lng_status_lastseen_date_time(lt_date, dOnline.date().toString(qsl("dd.MM.yy")), lt_time, dOnline.time().toString(cTimeFormat()));
}
int32 minutes = (now - online) / 60;
int32_t minutes = (now - online) / 60;
if (!minutes) {
return lang(lng_status_lastseen_now);
} else if (minutes < 60) {
return lng_status_lastseen_minutes(lt_count, minutes);
}
int32 hours = (now - online) / 3600;
int32_t hours = (now - online) / 3600;
if (hours < 12) {
return lng_status_lastseen_hours(lt_count, hours);
}
@ -790,12 +790,12 @@ namespace {
chat->version = d.vversion.v;
auto &v = d.vparticipants.v;
chat->count = v.size();
int32 pversion = chat->participants.isEmpty() ? 1 : (chat->participants.begin().value() + 1);
int32_t pversion = chat->participants.isEmpty() ? 1 : (chat->participants.begin().value() + 1);
chat->invitedByMe.clear();
chat->admins.clear();
chat->flags &= ~MTPDchat::Flag::f_admin;
for (auto i = v.cbegin(), e = v.cend(); i != e; ++i) {
int32 uid = 0, inviter = 0;
int32_t uid = 0, inviter = 0;
switch (i->type()) {
case mtpc_chatParticipantCreator: {
const auto &p(i->c_chatParticipantCreator());
@ -835,7 +835,7 @@ namespace {
if (!chat->participants.isEmpty()) {
History *h = App::historyLoaded(chat->id);
bool found = !h || !h->lastKeyboardFrom;
int32 botStatus = -1;
int32_t botStatus = -1;
for (auto i = chat->participants.begin(), e = chat->participants.end(); i != e;) {
if (i.value() < pversion) {
i = chat->participants.erase(i);
@ -934,7 +934,7 @@ namespace {
}
}
if (chat->botStatus > 0 && user->botInfo) {
int32 botStatus = -1;
int32_t botStatus = -1;
for (auto j = chat->participants.cbegin(), e = chat->participants.cend(); j != e; ++j) {
if (j.key()->botInfo) {
if (true || botStatus > 0/* || !j.key()->botInfo->readsAllHistory*/) {
@ -1060,7 +1060,7 @@ namespace {
void addSavedGif(DocumentData *doc) {
SavedGifs &saved(cRefSavedGifs());
int32 index = saved.indexOf(doc);
int32_t index = saved.indexOf(doc);
if (index) {
if (index > 0) saved.remove(index);
saved.push_front(doc);
@ -1086,8 +1086,8 @@ namespace {
}
void feedMsgs(const QVector<MTPMessage> &msgs, NewMessageType type) {
QMap<uint64, int32> msgsIds;
for (int32 i = 0, l = msgs.size(); i < l; ++i) {
QMap<uint64_t, int32_t> msgsIds;
for (int32_t i = 0, l = msgs.size(); i < l; ++i) {
const auto &msg(msgs.at(i));
switch (msg.type()) {
case mtpc_message: {
@ -1100,14 +1100,14 @@ namespace {
}
}
if (needToAdd) {
msgsIds.insert((uint64(uint32(d.vid.v)) << 32) | uint64(i), i);
msgsIds.insert((uint64_t(uint32_t(d.vid.v)) << 32) | uint64_t(i), i);
}
} break;
case mtpc_messageEmpty: msgsIds.insert((uint64(uint32(msg.c_messageEmpty().vid.v)) << 32) | uint64(i), i); break;
case mtpc_messageService: msgsIds.insert((uint64(uint32(msg.c_messageService().vid.v)) << 32) | uint64(i), i); break;
case mtpc_messageEmpty: msgsIds.insert((uint64_t(uint32_t(msg.c_messageEmpty().vid.v)) << 32) | uint64_t(i), i); break;
case mtpc_messageService: msgsIds.insert((uint64_t(uint32_t(msg.c_messageService().vid.v)) << 32) | uint64_t(i), i); break;
}
}
for (QMap<uint64, int32>::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) {
for (QMap<uint64_t, int32_t>::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) {
histories().addNewMessage(msgs.at(i.value()), type);
}
}
@ -1140,7 +1140,7 @@ namespace {
return ImagePtr();
}
StorageImageLocation imageLocation(int32 w, int32 h, const MTPFileLocation &loc) {
StorageImageLocation imageLocation(int32_t w, int32_t h, const MTPFileLocation &loc) {
if (loc.type() == mtpc_fileLocation) {
const auto &l(loc.c_fileLocation());
return StorageImageLocation(w, h, l.vdc_id.v, l.vvolume_id.v, l.vlocal_id.v, l.vsecret.v);
@ -1279,9 +1279,9 @@ namespace {
PhotoData *feedPhoto(const MTPPhoto &photo, const PreparedPhotoThumbs &thumbs) {
const QPixmap *thumb = 0, *medium = 0, *full = 0;
int32 thumbLevel = -1, mediumLevel = -1, fullLevel = -1;
int32_t thumbLevel = -1, mediumLevel = -1, fullLevel = -1;
for (PreparedPhotoThumbs::const_iterator i = thumbs.cbegin(), e = thumbs.cend(); i != e; ++i) {
int32 newThumbLevel = -1, newMediumLevel = -1, newFullLevel = -1;
int32_t newThumbLevel = -1, newMediumLevel = -1, newFullLevel = -1;
switch (i.key()) {
case 's': newThumbLevel = 0; newMediumLevel = 5; newFullLevel = 4; break; // box 100x100
case 'm': newThumbLevel = 2; newMediumLevel = 0; newFullLevel = 3; break; // box 320x320
@ -1325,7 +1325,7 @@ namespace {
PhotoData *feedPhoto(const MTPDphoto &photo, PhotoData *convert) {
auto &sizes = photo.vsizes.v;
const MTPPhotoSize *thumb = 0, *medium = 0, *full = 0;
int32 thumbLevel = -1, mediumLevel = -1, fullLevel = -1;
int32_t thumbLevel = -1, mediumLevel = -1, fullLevel = -1;
for (QVector<MTPPhotoSize>::const_iterator i = sizes.cbegin(), e = sizes.cend(); i != e; ++i) {
char size = 0;
switch (i->type()) {
@ -1341,7 +1341,7 @@ namespace {
}
if (!size) continue;
int32 newThumbLevel = -1, newMediumLevel = -1, newFullLevel = -1;
int32_t newThumbLevel = -1, newMediumLevel = -1, newFullLevel = -1;
switch (size) {
case 's': newThumbLevel = 0; newMediumLevel = 5; newFullLevel = 4; break; // box 100x100
case 'm': newThumbLevel = 2; newMediumLevel = 0; newFullLevel = 3; break; // box 320x320
@ -1468,6 +1468,7 @@ namespace {
return nullptr;
}
} break;
case PeerData::NotLoaded: break;
}
return i.value();
}
@ -1514,7 +1515,7 @@ namespace {
return i.value();
}
PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const uint64 &access, int32 date, const ImagePtr &thumb, const ImagePtr &medium, const ImagePtr &full) {
PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const uint64_t &access, int32_t date, const ImagePtr &thumb, const ImagePtr &medium, const ImagePtr &full) {
if (convert) {
if (convert->id != photo) {
PhotosData::iterator i = ::photosData.find(convert->id);
@ -1575,7 +1576,7 @@ namespace {
return i.value();
}
DocumentData *documentSet(const DocumentId &document, DocumentData *convert, const uint64 &access, int32 version, int32 date, const QVector<MTPDocumentAttribute> &attributes, const QString &mime, const ImagePtr &thumb, int32 dc, int32 size, const StorageImageLocation &thumbLocation) {
DocumentData *documentSet(const DocumentId &document, DocumentData *convert, const uint64_t &access, int32_t version, int32_t date, const QVector<MTPDocumentAttribute> &attributes, const QString &mime, const ImagePtr &thumb, int32_t dc, int32_t size, const StorageImageLocation &thumbLocation) {
bool versionChanged = false;
bool sentSticker = false;
if (convert) {
@ -1697,7 +1698,7 @@ namespace {
return i.value();
}
WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const TextWithEntities &description, PhotoData *photo, DocumentData *document, int32 duration, const QString &author, int32 pendingTill) {
WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const TextWithEntities &description, PhotoData *photo, DocumentData *document, int32_t duration, const QString &author, int32_t pendingTill) {
if (convert) {
if (convert->id != webPage) {
auto i = webPagesData.find(convert->id);
@ -1769,7 +1770,7 @@ namespace {
return i.value();
}
GameData *gameSet(const GameId &game, GameData *convert, const uint64 &accessHash, const QString &shortName, const QString &title, const QString &description, PhotoData *photo, DocumentData *document) {
GameData *gameSet(const GameId &game, GameData *convert, const uint64_t &accessHash, const QString &shortName, const QString &title, const QString &description, PhotoData *photo, DocumentData *document) {
if (convert) {
if (convert->id != game) {
auto i = gamesData.find(convert->id);
@ -1862,7 +1863,7 @@ namespace {
return ::histories.findOrInsert(peer);
}
History *historyFromDialog(const PeerId &peer, int32 unreadCnt, int32 maxInboxRead, int32 maxOutboxRead) {
History *historyFromDialog(const PeerId &peer, int32_t unreadCnt, int32_t maxInboxRead, int32_t maxOutboxRead) {
return ::histories.findOrInsert(peer, unreadCnt, maxInboxRead, maxOutboxRead);
}
@ -2056,15 +2057,15 @@ namespace {
}
}
void historyRegRandom(uint64 randomId, const FullMsgId &itemId) {
void historyRegRandom(uint64_t randomId, const FullMsgId &itemId) {
randomData.insert(randomId, itemId);
}
void historyUnregRandom(uint64 randomId) {
void historyUnregRandom(uint64_t randomId) {
randomData.remove(randomId);
}
FullMsgId histItemByRandom(uint64 randomId) {
FullMsgId histItemByRandom(uint64_t randomId) {
RandomData::const_iterator i = randomData.constFind(randomId);
if (i != randomData.cend()) {
return i.value();
@ -2072,23 +2073,23 @@ namespace {
return FullMsgId();
}
void historyRegSentData(uint64 randomId, const PeerId &peerId, const QString &text) {
void historyRegSentData(uint64_t randomId, const PeerId &peerId, const QString &text) {
sentData.insert(randomId, qMakePair(peerId, text));
}
void historyUnregSentData(uint64 randomId) {
void historyUnregSentData(uint64_t randomId) {
sentData.remove(randomId);
}
void histSentDataByItem(uint64 randomId, PeerId &peerId, QString &text) {
void histSentDataByItem(uint64_t randomId, PeerId &peerId, QString &text) {
QPair<PeerId, QString> d = sentData.value(randomId);
peerId = d.first;
text = d.second;
}
void prepareCorners(RoundCorners index, int32 radius, const QBrush &brush, const style::color *shadow = nullptr, QImage *cors = nullptr) {
void prepareCorners(RoundCorners index, int32_t radius, const QBrush &brush, const style::color *shadow = nullptr, QImage *cors = nullptr) {
Expects(::corners.size() > index);
int32 r = radius * cIntRetinaFactor(), s = st::msgShadow * cIntRetinaFactor();
int32_t r = radius * cIntRetinaFactor(), s = st::msgShadow * cIntRetinaFactor();
QImage rect(r * 3, r * 3 + (shadow ? s : 0), QImage::Format_ARGB32_Premultiplied), localCors[4];
{
Painter p(&rect);
@ -2335,7 +2336,7 @@ namespace {
return *::emojiLarge;
}
const QPixmap &emojiSingle(EmojiPtr emoji, int32 fontHeight) {
const QPixmap &emojiSingle(EmojiPtr emoji, int32_t fontHeight) {
auto &map = (fontHeight == st::msgFont->height) ? MainEmojiMap : OtherEmojiMap[fontHeight];
auto i = map.constFind(emoji->index());
if (i == map.cend()) {
@ -2352,7 +2353,7 @@ namespace {
}
void checkImageCacheSize() {
int64 nowImageCacheSize = imageCacheSize();
int64_t nowImageCacheSize = imageCacheSize();
if (nowImageCacheSize > serviceImageCacheSize + MemoryForImageCache) {
App::forgetMedia();
serviceImageCacheSize = imageCacheSize();
@ -2392,17 +2393,8 @@ namespace {
}
void restart() {
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
bool updateReady = (Sandbox::updatingState() == Application::UpdatingReady);
#else // !TDESKTOP_DISABLE_AUTOUPDATE
bool updateReady = false;
#endif // else for !TDESKTOP_DISABLE_AUTOUPDATE
if (updateReady) {
cSetRestartingUpdate(true);
} else {
cSetRestarting(true);
cSetRestartingToSettings(true);
}
cSetRestarting(true);
cSetRestartingToSettings(true);
App::quit();
}
@ -2532,7 +2524,7 @@ namespace {
return ::gameItems;
}
void regSharedContactItem(int32 userId, HistoryItem *item) {
void regSharedContactItem(int32_t userId, HistoryItem *item) {
auto user = App::userLoaded(userId);
auto canShareThisContact = user ? user->canShareThisContact() : false;
::sharedContactItems[userId].insert(item);
@ -2541,7 +2533,7 @@ namespace {
}
}
void unregSharedContactItem(int32 userId, HistoryItem *item) {
void unregSharedContactItem(int32_t userId, HistoryItem *item) {
auto user = App::userLoaded(userId);
auto canShareThisContact = user ? user->canShareThisContact() : false;
::sharedContactItems[userId].remove(item);
@ -2575,7 +2567,7 @@ namespace {
}
}
QString phoneFromSharedContact(int32 userId) {
QString phoneFromSharedContact(int32_t userId) {
auto i = ::sharedContactItems.constFind(userId);
if (i != ::sharedContactItems.cend() && !i->isEmpty()) {
if (auto media = (*i->cbegin())->getMedia()) {
@ -2587,7 +2579,7 @@ namespace {
return QString();
}
void regMuted(PeerData *peer, int32 changeIn) {
void regMuted(PeerData *peer, int32_t changeIn) {
::mutedPeers.insert(peer, true);
if (App::main()) App::main()->updateMutedIn(changeIn);
}
@ -2597,9 +2589,9 @@ namespace {
}
void updateMuted() {
int32 changeInMin = 0;
int32_t changeInMin = 0;
for (MutedPeers::iterator i = ::mutedPeers.begin(); i != ::mutedPeers.end();) {
int32 changeIn = 0;
int32_t changeIn = 0;
History *h = App::history(i.key()->id);
if (isNotifyMuted(i.key()->notify, &changeIn)) {
h->setMute(true);
@ -2694,7 +2686,7 @@ namespace {
return ::cornersMaskSmall;
}
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, const CornersPixmaps &corner, const style::color *shadow, RectParts parts) {
void roundRect(Painter &p, int32_t x, int32_t y, int32_t w, int32_t h, style::color bg, const CornersPixmaps &corner, const style::color *shadow, RectParts parts) {
auto cornerWidth = corner.p[0].width() / cIntRetinaFactor();
auto cornerHeight = corner.p[0].height() / cIntRetinaFactor();
if (w < 2 * cornerWidth || h < 2 * cornerHeight) return;
@ -2738,11 +2730,11 @@ namespace {
}
}
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, RoundCorners index, const style::color *shadow, RectParts parts) {
void roundRect(Painter &p, int32_t x, int32_t y, int32_t w, int32_t h, style::color bg, RoundCorners index, const style::color *shadow, RectParts parts) {
roundRect(p, x, y, w, h, bg, ::corners[index], shadow, parts);
}
void roundShadow(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color shadow, RoundCorners index, RectParts parts) {
void roundShadow(Painter &p, int32_t x, int32_t y, int32_t w, int32_t h, style::color shadow, RoundCorners index, RectParts parts) {
auto &corner = ::corners[index];
auto cornerWidth = corner.p[0].width() / cIntRetinaFactor();
auto cornerHeight = corner.p[0].height() / cIntRetinaFactor();
@ -2759,8 +2751,8 @@ namespace {
}
}
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, ImageRoundRadius radius, RectParts parts) {
auto colorKey = ((uint32(bg->c.alpha()) & 0xFF) << 24) | ((uint32(bg->c.red()) & 0xFF) << 16) | ((uint32(bg->c.green()) & 0xFF) << 8) | ((uint32(bg->c.blue()) & 0xFF) << 24);
void roundRect(Painter &p, int32_t x, int32_t y, int32_t w, int32_t h, style::color bg, ImageRoundRadius radius, RectParts parts) {
auto colorKey = ((uint32_t(bg->c.alpha()) & 0xFF) << 24) | ((uint32_t(bg->c.red()) & 0xFF) << 16) | ((uint32_t(bg->c.green()) & 0xFF) << 8) | ((uint32_t(bg->c.blue()) & 0xFF) << 24);
auto i = cornersMap.find(colorKey);
if (i == cornersMap.cend()) {
QImage images[4];

View File

@ -34,7 +34,7 @@ using PhotoItems = QHash<PhotoData*, HistoryItemsMap>;
using DocumentItems = QHash<DocumentData*, HistoryItemsMap>;
using WebPageItems = QHash<WebPageData*, HistoryItemsMap>;
using GameItems = QHash<GameData*, HistoryItemsMap>;
using SharedContactItems = QHash<int32, HistoryItemsMap>;
using SharedContactItems = QHash<int32_t, HistoryItemsMap>;
using GifItems = QHash<Media::Clip::Reader*, HistoryItem*>;
using PhotosData = QHash<PhotoId, PhotoData*>;
@ -53,8 +53,8 @@ namespace App {
QString formatPhone(QString phone);
TimeId onlineForSort(UserData *user, TimeId now);
int32 onlineWillChangeIn(UserData *user, TimeId now);
int32 onlineWillChangeIn(TimeId online, TimeId now);
int32_t onlineWillChangeIn(UserData *user, TimeId now);
int32_t onlineWillChangeIn(TimeId online, TimeId now);
QString onlineText(UserData *user, TimeId now, bool precise = false);
QString onlineText(TimeId online, TimeId now, bool precise = false);
bool onlineColorUse(UserData *user, TimeId now);
@ -82,7 +82,7 @@ namespace App {
void feedUserLink(MTPint userId, const MTPContactLink &myLink, const MTPContactLink &foreignLink);
ImagePtr image(const MTPPhotoSize &size);
StorageImageLocation imageLocation(int32 w, int32 h, const MTPFileLocation &loc);
StorageImageLocation imageLocation(int32_t w, int32_t h, const MTPFileLocation &loc);
StorageImageLocation imageLocation(const MTPPhotoSize &size);
PhotoData *feedPhoto(const MTPPhoto &photo, const PreparedPhotoThumbs &thumbs);
@ -143,13 +143,13 @@ namespace App {
PeerData *peerByName(const QString &username);
QString peerName(const PeerData *peer, bool forDialogs = false);
PhotoData *photo(const PhotoId &photo);
PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const uint64 &access, int32 date, const ImagePtr &thumb, const ImagePtr &medium, const ImagePtr &full);
PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const uint64_t &access, int32_t date, const ImagePtr &thumb, const ImagePtr &medium, const ImagePtr &full);
DocumentData *document(const DocumentId &document);
DocumentData *documentSet(const DocumentId &document, DocumentData *convert, const uint64 &access, int32 version, int32 date, const QVector<MTPDocumentAttribute> &attributes, const QString &mime, const ImagePtr &thumb, int32 dc, int32 size, const StorageImageLocation &thumbLocation);
DocumentData *documentSet(const DocumentId &document, DocumentData *convert, const uint64_t &access, int32_t version, int32_t date, const QVector<MTPDocumentAttribute> &attributes, const QString &mime, const ImagePtr &thumb, int32_t dc, int32_t size, const StorageImageLocation &thumbLocation);
WebPageData *webPage(const WebPageId &webPage);
WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const TextWithEntities &description, PhotoData *photo, DocumentData *doc, int32 duration, const QString &author, int32 pendingTill);
WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const TextWithEntities &description, PhotoData *photo, DocumentData *doc, int32_t duration, const QString &author, int32_t pendingTill);
GameData *game(const GameId &game);
GameData *gameSet(const GameId &game, GameData *convert, const uint64 &accessHash, const QString &shortName, const QString &title, const QString &description, PhotoData *photo, DocumentData *doc);
GameData *gameSet(const GameId &game, GameData *convert, const uint64_t &accessHash, const QString &shortName, const QString &title, const QString &description, PhotoData *photo, DocumentData *doc);
LocationData *location(const LocationCoords &coords);
void forgetMedia();
@ -157,7 +157,7 @@ namespace App {
Histories &histories();
not_null<History*> history(const PeerId &peer);
History *historyFromDialog(const PeerId &peer, int32 unreadCnt, int32 maxInboxRead, int32 maxOutboxRead);
History *historyFromDialog(const PeerId &peer, int32_t unreadCnt, int32_t maxInboxRead, int32_t maxOutboxRead);
History *historyLoaded(const PeerId &peer);
HistoryItem *histItemById(ChannelId channelId, MsgId itemId);
inline not_null<History*> history(const PeerData *peer) {
@ -182,12 +182,12 @@ namespace App {
void historyRegDependency(HistoryItem *dependent, HistoryItem *dependency);
void historyUnregDependency(HistoryItem *dependent, HistoryItem *dependency);
void historyRegRandom(uint64 randomId, const FullMsgId &itemId);
void historyUnregRandom(uint64 randomId);
FullMsgId histItemByRandom(uint64 randomId);
void historyRegSentData(uint64 randomId, const PeerId &peerId, const QString &text);
void historyUnregSentData(uint64 randomId);
void histSentDataByItem(uint64 randomId, PeerId &peerId, QString &text);
void historyRegRandom(uint64_t randomId, const FullMsgId &itemId);
void historyUnregRandom(uint64_t randomId);
FullMsgId histItemByRandom(uint64_t randomId);
void historyRegSentData(uint64_t randomId, const PeerId &peerId, const QString &text);
void historyUnregSentData(uint64_t randomId);
void histSentDataByItem(uint64_t randomId, PeerId &peerId, QString &text);
void hoveredItem(HistoryItem *item);
HistoryItem *hoveredItem();
@ -206,7 +206,7 @@ namespace App {
const style::font &monofont();
const QPixmap &emoji();
const QPixmap &emojiLarge();
const QPixmap &emojiSingle(EmojiPtr emoji, int32 fontHeight);
const QPixmap &emojiSingle(EmojiPtr emoji, int32_t fontHeight);
void clearHistories();
@ -252,17 +252,17 @@ namespace App {
void unregGameItem(GameData *data, HistoryItem *item);
const GameItems &gameItems();
void regSharedContactItem(int32 userId, HistoryItem *item);
void unregSharedContactItem(int32 userId, HistoryItem *item);
void regSharedContactItem(int32_t userId, HistoryItem *item);
void unregSharedContactItem(int32_t userId, HistoryItem *item);
const SharedContactItems &sharedContactItems();
QString phoneFromSharedContact(int32 userId);
QString phoneFromSharedContact(int32_t userId);
void regGifItem(Media::Clip::Reader *reader, HistoryItem *item);
void unregGifItem(Media::Clip::Reader *reader);
void stopRoundVideoPlayback();
void stopGifItems();
void regMuted(PeerData *peer, int32 changeIn);
void regMuted(PeerData *peer, int32_t changeIn);
void unregMuted(PeerData *peer);
void updateMuted();
@ -276,23 +276,23 @@ namespace App {
void complexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, ImageRoundCorners corners);
QImage *cornersMask(ImageRoundRadius radius);
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, RoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full);
void roundRect(Painter &p, int32_t x, int32_t y, int32_t w, int32_t h, style::color bg, RoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full);
inline void roundRect(Painter &p, const QRect &rect, style::color bg, RoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full) {
return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, index, shadow, parts);
}
void roundShadow(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color shadow, RoundCorners index, RectParts parts = RectPart::Full);
void roundShadow(Painter &p, int32_t x, int32_t y, int32_t w, int32_t h, style::color shadow, RoundCorners index, RectParts parts = RectPart::Full);
inline void roundShadow(Painter &p, const QRect &rect, style::color shadow, RoundCorners index, RectParts parts = RectPart::Full) {
return roundShadow(p, rect.x(), rect.y(), rect.width(), rect.height(), shadow, index, parts);
}
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, ImageRoundRadius radius, RectParts parts = RectPart::Full);
void roundRect(Painter &p, int32_t x, int32_t y, int32_t w, int32_t h, style::color bg, ImageRoundRadius radius, RectParts parts = RectPart::Full);
inline void roundRect(Painter &p, const QRect &rect, style::color bg, ImageRoundRadius radius, RectParts parts = RectPart::Full) {
return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, radius, parts);
}
struct WallPaper {
WallPaper(int32 id, ImagePtr thumb, ImagePtr full) : id(id), thumb(thumb), full(full) {
WallPaper(int32_t id, ImagePtr thumb, ImagePtr full) : id(id), thumb(thumb), full(full) {
}
int32 id;
int32_t id;
ImagePtr thumb;
ImagePtr full;
};

View File

@ -24,13 +24,13 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "mainwidget.h"
#include "mainwindow.h"
#include "storage/localstorage.h"
#include "autoupdater.h"
#include "window/notifications_manager.h"
#include "messenger.h"
#include "base/timer.h"
namespace {
// @todo are there no other ways to get/set hex?
QChar _toHex(ushort v) {
v = v & 0x000F;
return QChar::fromLatin1((v >= 10) ? ('a' + (v - 10)) : ('0' + v));
@ -39,6 +39,7 @@ ushort _fromHex(QChar c) {
return ((c.unicode() >= uchar('a')) ? (c.unicode() - uchar('a') + 10) : (c.unicode() - uchar('0'))) & 0x000F;
}
// @todo urlencode/decode functions might help here??
QString _escapeTo7bit(const QString &str) {
QString result;
result.reserve(str.size() * 2);
@ -85,20 +86,13 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) {
connect(&_localSocket, SIGNAL(connected()), this, SLOT(socketConnected()));
connect(&_localSocket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
connect(&_localSocket, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(socketError(QLocalSocket::LocalSocketError)));
connect(&_localSocket, SIGNAL(bytesWritten(qint64)), this, SLOT(socketWritten(qint64)));
connect(&_localSocket, SIGNAL(bytesWritten(int64_t)), this, SLOT(socketWritten(int64_t)));
connect(&_localSocket, SIGNAL(readyRead()), this, SLOT(socketReading()));
connect(&_localServer, SIGNAL(newConnection()), this, SLOT(newInstanceConnected()));
QTimer::singleShot(0, this, SLOT(startApplication()));
connect(this, SIGNAL(aboutToQuit()), this, SLOT(closeApplication()));
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
_updateCheckTimer.create(this);
connect(_updateCheckTimer, SIGNAL(timeout()), this, SLOT(updateCheck()));
connect(this, SIGNAL(updateFailed()), this, SLOT(onUpdateFailed()));
connect(this, SIGNAL(updateReady()), this, SLOT(onUpdateReady()));
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
if (cManyInstance()) {
LOG(("Many instance allowed, starting..."));
singleInstanceChecked();
@ -135,7 +129,7 @@ void Application::socketConnected() {
_localSocket.write(commands.toLatin1());
}
void Application::socketWritten(qint64/* bytes*/) {
void Application::socketWritten(int64_t/* bytes*/) {
if (_localSocket.state() != QLocalSocket::ConnectedState) {
LOG(("Socket is not connected %1").arg(_localSocket.state()));
return;
@ -153,7 +147,7 @@ void Application::socketReading() {
}
_localSocketReadData.append(_localSocket.readAll());
if (QRegularExpression("RES:(\\d+);").match(_localSocketReadData).hasMatch()) {
uint64 pid = _localSocketReadData.mid(4, _localSocketReadData.length() - 5).toULongLong();
uint64_t pid = _localSocketReadData.mid(4, _localSocketReadData.length() - 5).toULongLong();
psActivateProcess(pid);
LOG(("Show command response received, pid = %1, activating and quitting...").arg(pid));
return App::quit();
@ -185,14 +179,6 @@ void Application::socketError(QLocalSocket::LocalSocketError e) {
}
#endif // !Q_OS_WINRT
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
if (!cNoStartUpdate() && checkReadyUpdate()) {
cSetRestartingUpdate(true);
DEBUG_LOG(("Application Info: installing update instead of starting app..."));
return App::quit();
}
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
singleInstanceChecked();
}
@ -249,8 +235,8 @@ void Application::readClients() {
i->second.append(i->first->readAll());
if (i->second.size()) {
QString cmds(QString::fromLatin1(i->second));
int32 from = 0, l = cmds.length();
for (int32 to = cmds.indexOf(QChar(';'), from); to >= from; to = (from < l) ? cmds.indexOf(QChar(';'), from) : -1) {
int32_t from = 0, l = cmds.length();
for (int32_t to = cmds.indexOf(QChar(';'), from); to >= from; to = (from < l) ? cmds.indexOf(QChar(';'), from) : -1) {
QStringRef cmd(&cmds, from, to - from);
if (cmd.startsWith(qsl("CMD:"))) {
Sandbox::execExternal(cmds.mid(from + 4, to - from - 4));
@ -332,171 +318,8 @@ void Application::closeApplication() {
_localClients.clear();
_localSocket.close();
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
delete _updateReply;
_updateReply = 0;
if (_updateChecker) _updateChecker->deleteLater();
_updateChecker = 0;
if (_updateThread) {
_updateThread->quit();
}
_updateThread = 0;
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
}
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
void Application::updateCheck() {
startUpdateCheck(false);
}
void Application::updateGotCurrent() {
if (!_updateReply || _updateThread) return;
cSetLastUpdateCheck(unixtime());
QRegularExpressionMatch m = QRegularExpression(qsl("^\\s*(\\d+)\\s*:\\s*([\\x21-\\x7f]+)\\s*$")).match(QString::fromLatin1(_updateReply->readAll()));
if (m.hasMatch()) {
uint64 currentVersion = m.captured(1).toULongLong();
QString url = m.captured(2);
bool betaVersion = false;
if (url.startsWith(qstr("beta_"))) {
betaVersion = true;
url = url.mid(5) + '_' + countBetaVersionSignature(currentVersion);
}
if ((!betaVersion || cBetaVersion()) && currentVersion > (betaVersion ? cBetaVersion() : uint64(AppVersion))) {
_updateThread = new QThread();
connect(_updateThread, SIGNAL(finished()), _updateThread, SLOT(deleteLater()));
_updateChecker = new UpdateChecker(_updateThread, url);
_updateThread->start();
}
}
if (_updateReply) _updateReply->deleteLater();
_updateReply = 0;
if (!_updateThread) {
QDir updates(cWorkingDir() + "tupdates");
if (updates.exists()) {
QFileInfoList list = updates.entryInfoList(QDir::Files);
for (QFileInfoList::iterator i = list.begin(), e = list.end(); i != e; ++i) {
if (QRegularExpression("^(tupdate|tmacupd|tmac32upd|tlinuxupd|tlinux32upd)\\d+(_[a-z\\d]+)?$", QRegularExpression::CaseInsensitiveOption).match(i->fileName()).hasMatch()) {
QFile(i->absoluteFilePath()).remove();
}
}
}
emit updateLatest();
}
startUpdateCheck(true);
Local::writeSettings();
}
void Application::updateFailedCurrent(QNetworkReply::NetworkError e) {
LOG(("App Error: could not get current version (update check): %1").arg(e));
if (_updateReply) _updateReply->deleteLater();
_updateReply = 0;
emit updateFailed();
startUpdateCheck(true);
}
void Application::onUpdateReady() {
if (_updateChecker) {
_updateChecker->deleteLater();
_updateChecker = nullptr;
}
_updateCheckTimer->stop();
cSetLastUpdateCheck(unixtime());
Local::writeSettings();
}
void Application::onUpdateFailed() {
if (_updateChecker) {
_updateChecker->deleteLater();
_updateChecker = 0;
if (_updateThread) _updateThread->quit();
_updateThread = 0;
}
cSetLastUpdateCheck(unixtime());
Local::writeSettings();
}
Application::UpdatingState Application::updatingState() {
if (!_updateThread) return Application::UpdatingNone;
if (!_updateChecker) return Application::UpdatingReady;
return Application::UpdatingDownload;
}
int32 Application::updatingSize() {
if (!_updateChecker) return 0;
return _updateChecker->size();
}
int32 Application::updatingReady() {
if (!_updateChecker) return 0;
return _updateChecker->ready();
}
void Application::stopUpdate() {
if (_updateReply) {
_updateReply->abort();
_updateReply->deleteLater();
_updateReply = 0;
}
if (_updateChecker) {
_updateChecker->deleteLater();
_updateChecker = 0;
if (_updateThread) _updateThread->quit();
_updateThread = 0;
}
}
void Application::startUpdateCheck(bool forceWait) {
if (!Sandbox::started()) return;
_updateCheckTimer->stop();
if (_updateThread || _updateReply || !cAutoUpdate() || cExeName().isEmpty()) return;
int32 constDelay = cBetaVersion() ? 600 : UpdateDelayConstPart, randDelay = cBetaVersion() ? 300 : UpdateDelayRandPart;
int32 updateInSecs = cLastUpdateCheck() + constDelay + int32(rand() % randDelay) - unixtime();
bool sendRequest = (updateInSecs <= 0 || updateInSecs > (constDelay + randDelay));
if (!sendRequest && !forceWait) {
QDir updates(cWorkingDir() + "tupdates");
if (updates.exists()) {
QFileInfoList list = updates.entryInfoList(QDir::Files);
for (QFileInfoList::iterator i = list.begin(), e = list.end(); i != e; ++i) {
if (QRegularExpression("^(tupdate|tmacupd|tmac32upd|tlinuxupd|tlinux32upd)\\d+(_[a-z\\d]+)?$", QRegularExpression::CaseInsensitiveOption).match(i->fileName()).hasMatch()) {
sendRequest = true;
}
}
}
}
if (cManyInstance() && !cDebug()) return; // only main instance is updating
if (sendRequest) {
QUrl url(cUpdateURL());
if (cBetaVersion()) {
url.setQuery(qsl("version=%1&beta=%2").arg(AppVersion).arg(cBetaVersion()));
} else if (cAlphaVersion()) {
url.setQuery(qsl("version=%1&alpha=1").arg(AppVersion));
} else {
url.setQuery(qsl("version=%1").arg(AppVersion));
}
QString u = url.toString();
QNetworkRequest checkVersion(url);
if (_updateReply) _updateReply->deleteLater();
App::setProxySettings(_updateManager);
_updateReply = _updateManager.get(checkVersion);
connect(_updateReply, SIGNAL(finished()), this, SLOT(updateGotCurrent()));
connect(_updateReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(updateFailedCurrent(QNetworkReply::NetworkError)));
emit updateChecking();
} else {
_updateCheckTimer->start((updateInSecs + 5) * 1000);
}
}
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
inline Application *application() {
return qobject_cast<Application*>(QApplication::instance());
}
@ -548,73 +371,6 @@ void adjustSingleTimers() {
base::Timer::Adjust();
}
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
void startUpdateCheck() {
if (auto a = application()) {
return a->startUpdateCheck(false);
}
}
void stopUpdate() {
if (auto a = application()) {
return a->stopUpdate();
}
}
Application::UpdatingState updatingState() {
if (auto a = application()) {
return a->updatingState();
}
return Application::UpdatingNone;
}
int32 updatingSize() {
if (auto a = application()) {
return a->updatingSize();
}
return 0;
}
int32 updatingReady() {
if (auto a = application()) {
return a->updatingReady();
}
return 0;
}
void updateChecking() {
if (auto a = application()) {
emit a->updateChecking();
}
}
void updateLatest() {
if (auto a = application()) {
emit a->updateLatest();
}
}
void updateProgress(qint64 ready, qint64 total) {
if (auto a = application()) {
emit a->updateProgress(ready, total);
}
}
void updateFailed() {
if (auto a = application()) {
emit a->updateFailed();
}
}
void updateReady() {
if (auto a = application()) {
emit a->updateReady();
}
}
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
void connect(const char *signal, QObject *object, const char *method) {
if (auto a = application()) {
a->connect(a, signal, object, method);
@ -624,7 +380,7 @@ void connect(const char *signal, QObject *object, const char *method) {
void launch() {
Assert(application() != 0);
float64 dpi = Application::primaryScreen()->logicalDotsPerInch();
double dpi = Application::primaryScreen()->logicalDotsPerInch();
if (dpi <= 108) { // 0-96-108
cSetScreenScale(dbisOne);
} else if (dpi <= 132) { // 108-120-132
@ -646,7 +402,7 @@ void launch() {
}
cSetRetina(true);
cSetRetinaFactor(devicePixelRatio);
cSetIntRetinaFactor(int32(cRetinaFactor()));
cSetIntRetinaFactor(int32_t(cRetinaFactor()));
cSetConfigScale(dbisOne);
cSetRealScale(dbisOne);
}

View File

@ -20,7 +20,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
class UpdateChecker;
#include "stdafx.h"
#include <QApplication>
class Application : public QApplication {
Q_OBJECT
@ -41,7 +43,7 @@ public slots:
void socketConnected();
void socketError(QLocalSocket::LocalSocketError e);
void socketDisconnected();
void socketWritten(qint64 bytes);
void socketWritten(int64_t bytes);
void socketReading();
void newInstanceConnected();
@ -64,47 +66,6 @@ private:
bool _secondInstance = false;
void singleInstanceChecked();
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
// Autoupdating
public:
void startUpdateCheck(bool forceWait);
void stopUpdate();
enum UpdatingState {
UpdatingNone,
UpdatingDownload,
UpdatingReady,
};
UpdatingState updatingState();
int32 updatingSize();
int32 updatingReady();
signals:
void updateChecking();
void updateLatest();
void updateProgress(qint64 ready, qint64 total);
void updateReady();
void updateFailed();
public slots:
void updateCheck();
void updateGotCurrent();
void updateFailedCurrent(QNetworkReply::NetworkError e);
void onUpdateReady();
void onUpdateFailed();
private:
object_ptr<SingleTimer> _updateCheckTimer = { nullptr };
QNetworkReply *_updateReply = nullptr;
QNetworkAccessManager _updateManager;
QThread *_updateThread = nullptr;
UpdateChecker *_updateChecker = nullptr;
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
};
namespace Sandbox {
@ -118,23 +79,6 @@ void execExternal(const QString &cmd);
void adjustSingleTimers();
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
void startUpdateCheck();
void stopUpdate();
Application::UpdatingState updatingState();
int32 updatingSize();
int32 updatingReady();
void updateChecking();
void updateLatest();
void updateProgress(qint64 ready, qint64 total);
void updateFailed();
void updateReady();
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
void connect(const char *signal, QObject *object, const char *method);
void launch();

View File

@ -45,30 +45,30 @@ AuthSessionData::Variables::Variables()
}
QByteArray AuthSessionData::serialize() const {
auto size = sizeof(qint32) * 8;
auto size = sizeof(int32_t) * 8;
for (auto i = _variables.soundOverrides.cbegin(), e = _variables.soundOverrides.cend(); i != e; ++i) {
size += Serialize::stringSize(i.key()) + Serialize::stringSize(i.value());
}
size += _variables.groupStickersSectionHidden.size() * sizeof(quint64);
size += _variables.groupStickersSectionHidden.size() * sizeof(uint64_t);
auto result = QByteArray();
result.reserve(size);
{
QDataStream stream(&result, QIODevice::WriteOnly);
stream.setVersion(QDataStream::Qt_5_1);
stream << static_cast<qint32>(_variables.selectorTab);
stream << qint32(_variables.lastSeenWarningSeen ? 1 : 0);
stream << qint32(_variables.tabbedSelectorSectionEnabled ? 1 : 0);
stream << qint32(_variables.soundOverrides.size());
stream << static_cast<int32_t>(_variables.selectorTab);
stream << int32_t(_variables.lastSeenWarningSeen ? 1 : 0);
stream << int32_t(_variables.tabbedSelectorSectionEnabled ? 1 : 0);
stream << int32_t(_variables.soundOverrides.size());
for (auto i = _variables.soundOverrides.cbegin(), e = _variables.soundOverrides.cend(); i != e; ++i) {
stream << i.key() << i.value();
}
stream << qint32(_variables.tabbedSelectorSectionTooltipShown);
stream << qint32(_variables.floatPlayerColumn);
stream << qint32(_variables.floatPlayerCorner);
stream << qint32(_variables.groupStickersSectionHidden.size());
stream << int32_t(_variables.tabbedSelectorSectionTooltipShown);
stream << int32_t(_variables.floatPlayerColumn);
stream << int32_t(_variables.floatPlayerCorner);
stream << int32_t(_variables.groupStickersSectionHidden.size());
for (auto peerId : _variables.groupStickersSectionHidden) {
stream << quint64(peerId);
stream << uint64_t(peerId);
}
}
return result;
@ -81,12 +81,12 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
QDataStream stream(serialized);
stream.setVersion(QDataStream::Qt_5_1);
qint32 selectorTab = static_cast<qint32>(ChatHelpers::SelectorTab::Emoji);
qint32 lastSeenWarningSeen = 0;
qint32 tabbedSelectorSectionEnabled = 1;
qint32 tabbedSelectorSectionTooltipShown = 0;
qint32 floatPlayerColumn = static_cast<qint32>(Window::Column::Second);
qint32 floatPlayerCorner = static_cast<qint32>(RectPart::TopRight);
int32_t selectorTab = static_cast<int32_t>(ChatHelpers::SelectorTab::Emoji);
int32_t lastSeenWarningSeen = 0;
int32_t tabbedSelectorSectionEnabled = 1;
int32_t tabbedSelectorSectionTooltipShown = 0;
int32_t floatPlayerColumn = static_cast<int32_t>(Window::Column::Second);
int32_t floatPlayerCorner = static_cast<int32_t>(RectPart::TopRight);
QMap<QString, QString> soundOverrides;
OrderedSet<PeerId> groupStickersSectionHidden;
stream >> selectorTab;
@ -95,7 +95,7 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
stream >> tabbedSelectorSectionEnabled;
}
if (!stream.atEnd()) {
auto count = qint32(0);
auto count = int32_t(0);
stream >> count;
if (stream.status() == QDataStream::Ok) {
for (auto i = 0; i != count; ++i) {
@ -112,11 +112,11 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
stream >> floatPlayerColumn >> floatPlayerCorner;
}
if (!stream.atEnd()) {
auto count = qint32(0);
auto count = int32_t(0);
stream >> count;
if (stream.status() == QDataStream::Ok) {
for (auto i = 0; i != count; ++i) {
quint64 peerId;
uint64_t peerId;
stream >> peerId;
groupStickersSectionHidden.insert(peerId);
}

View File

@ -1,627 +0,0 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#include "autoupdater.h"
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#ifdef Q_OS_WIN // use Lzma SDK for win
#include <LzmaLib.h>
#else // Q_OS_WIN
#include <lzma.h>
#endif // else of Q_OS_WIN
#include "application.h"
#include "platform/platform_specific.h"
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
#ifdef Q_OS_WIN
typedef DWORD VerInt;
typedef WCHAR VerChar;
#else // Q_OS_WIN
typedef int VerInt;
typedef wchar_t VerChar;
#endif // Q_OS_WIN
UpdateChecker::UpdateChecker(QThread *thread, const QString &url) : reply(0), already(0), full(0) {
updateUrl = url;
moveToThread(thread);
manager.moveToThread(thread);
App::setProxySettings(manager);
connect(thread, SIGNAL(started()), this, SLOT(start()));
initOutput();
}
void UpdateChecker::initOutput() {
QString fileName;
QRegularExpressionMatch m = QRegularExpression(qsl("/([^/\\?]+)(\\?|$)")).match(updateUrl);
if (m.hasMatch()) {
fileName = m.captured(1).replace(QRegularExpression(qsl("[^a-zA-Z0-9_\\-]")), QString());
}
if (fileName.isEmpty()) {
fileName = qsl("tupdate-%1").arg(rand_value<uint32>() % 1000000);
}
QString dirStr = cWorkingDir() + qsl("tupdates/");
fileName = dirStr + fileName;
QFileInfo file(fileName);
QDir dir(dirStr);
if (dir.exists()) {
QFileInfoList all = dir.entryInfoList(QDir::Files);
for (QFileInfoList::iterator i = all.begin(), e = all.end(); i != e; ++i) {
if (i->absoluteFilePath() != file.absoluteFilePath()) {
QFile::remove(i->absoluteFilePath());
}
}
} else {
dir.mkdir(dir.absolutePath());
}
outputFile.setFileName(fileName);
if (file.exists()) {
uint64 fullSize = file.size();
if (fullSize < INT_MAX) {
int32 goodSize = (int32)fullSize;
if (goodSize % UpdateChunk) {
goodSize = goodSize - (goodSize % UpdateChunk);
if (goodSize) {
if (outputFile.open(QIODevice::ReadOnly)) {
QByteArray goodData = outputFile.readAll().mid(0, goodSize);
outputFile.close();
if (outputFile.open(QIODevice::WriteOnly)) {
outputFile.write(goodData);
outputFile.close();
QMutexLocker lock(&mutex);
already = goodSize;
}
}
}
} else {
QMutexLocker lock(&mutex);
already = goodSize;
}
}
if (!already) {
QFile::remove(fileName);
}
}
}
void UpdateChecker::start() {
sendRequest();
}
void UpdateChecker::sendRequest() {
QNetworkRequest req(updateUrl);
QByteArray rangeHeaderValue = "bytes=" + QByteArray::number(already) + "-";
req.setRawHeader("Range", rangeHeaderValue);
req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
if (reply) reply->deleteLater();
reply = manager.get(req);
connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(partFinished(qint64,qint64)));
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(partFailed(QNetworkReply::NetworkError)));
connect(reply, SIGNAL(metaDataChanged()), this, SLOT(partMetaGot()));
}
void UpdateChecker::partMetaGot() {
typedef QList<QNetworkReply::RawHeaderPair> Pairs;
Pairs pairs = reply->rawHeaderPairs();
for (Pairs::iterator i = pairs.begin(), e = pairs.end(); i != e; ++i) {
if (QString::fromUtf8(i->first).toLower() == "content-range") {
QRegularExpressionMatch m = QRegularExpression(qsl("/(\\d+)([^\\d]|$)")).match(QString::fromUtf8(i->second));
if (m.hasMatch()) {
{
QMutexLocker lock(&mutex);
full = m.captured(1).toInt();
}
Sandbox::updateProgress(already, full);
}
}
}
}
int32 UpdateChecker::ready() {
QMutexLocker lock(&mutex);
return already;
}
int32 UpdateChecker::size() {
QMutexLocker lock(&mutex);
return full;
}
void UpdateChecker::partFinished(qint64 got, qint64 total) {
if (!reply) return;
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
if (statusCode.isValid()) {
int status = statusCode.toInt();
if (status != 200 && status != 206 && status != 416) {
LOG(("Update Error: Bad HTTP status received in partFinished(): %1").arg(status));
return fatalFail();
}
}
if (!already && !full) {
QMutexLocker lock(&mutex);
full = total;
}
DEBUG_LOG(("Update Info: part %1 of %2").arg(got).arg(total));
if (!outputFile.isOpen()) {
if (!outputFile.open(QIODevice::Append)) {
LOG(("Update Error: Could not open output file '%1' for appending").arg(outputFile.fileName()));
return fatalFail();
}
}
QByteArray r = reply->readAll();
if (!r.isEmpty()) {
outputFile.write(r);
QMutexLocker lock(&mutex);
already += r.size();
}
if (got >= total) {
reply->deleteLater();
reply = 0;
outputFile.close();
unpackUpdate();
} else {
Sandbox::updateProgress(already, full);
}
}
void UpdateChecker::partFailed(QNetworkReply::NetworkError e) {
if (!reply) return;
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
reply->deleteLater();
reply = 0;
if (statusCode.isValid()) {
int status = statusCode.toInt();
if (status == 416) { // Requested range not satisfiable
outputFile.close();
unpackUpdate();
return;
}
}
LOG(("Update Error: failed to download part starting from %1, error %2").arg(already).arg(e));
Sandbox::updateFailed();
}
void UpdateChecker::fatalFail() {
clearAll();
Sandbox::updateFailed();
}
void UpdateChecker::clearAll() {
psDeleteDir(cWorkingDir() + qsl("tupdates"));
}
//QString winapiErrorWrap() {
// WCHAR errMsg[2048];
// DWORD errorCode = GetLastError();
// LPTSTR errorText = NULL, errorTextDefault = L"(Unknown error)";
// FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errorText, 0, 0);
// if (!errorText) {
// errorText = errorTextDefault;
// }
// StringCbPrintf(errMsg, sizeof(errMsg), L"Error code: %d, error message: %s", errorCode, errorText);
// if (errorText != errorTextDefault) {
// LocalFree(errorText);
// }
// return QString::fromWCharArray(errMsg);
//}
void UpdateChecker::unpackUpdate() {
QByteArray packed;
if (!outputFile.open(QIODevice::ReadOnly)) {
LOG(("Update Error: cant read updates file!"));
return fatalFail();
}
#ifdef Q_OS_WIN // use Lzma SDK for win
const int32 hSigLen = 128, hShaLen = 20, hPropsLen = LZMA_PROPS_SIZE, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hPropsLen + hOriginalSizeLen; // header
#else // Q_OS_WIN
const int32 hSigLen = 128, hShaLen = 20, hPropsLen = 0, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hOriginalSizeLen; // header
#endif // Q_OS_WIN
QByteArray compressed = outputFile.readAll();
int32 compressedLen = compressed.size() - hSize;
if (compressedLen <= 0) {
LOG(("Update Error: bad compressed size: %1").arg(compressed.size()));
return fatalFail();
}
outputFile.close();
QString tempDirPath = cWorkingDir() + qsl("tupdates/temp"), readyFilePath = cWorkingDir() + qsl("tupdates/temp/ready");
psDeleteDir(tempDirPath);
QDir tempDir(tempDirPath);
if (tempDir.exists() || QFile(readyFilePath).exists()) {
LOG(("Update Error: cant clear tupdates/temp dir!"));
return fatalFail();
}
uchar sha1Buffer[20];
bool goodSha1 = !memcmp(compressed.constData() + hSigLen, hashSha1(compressed.constData() + hSigLen + hShaLen, compressedLen + hPropsLen + hOriginalSizeLen, sha1Buffer), hShaLen);
if (!goodSha1) {
LOG(("Update Error: bad SHA1 hash of update file!"));
return fatalFail();
}
RSA *pbKey = PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast<char*>(AppAlphaVersion ? UpdatesPublicAlphaKey : UpdatesPublicKey), -1), 0, 0, 0);
if (!pbKey) {
LOG(("Update Error: cant read public rsa key!"));
return fatalFail();
}
if (RSA_verify(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (const uchar*)(compressed.constData()), hSigLen, pbKey) != 1) { // verify signature
RSA_free(pbKey);
if (cAlphaVersion() || cBetaVersion()) { // try other public key, if we are in alpha or beta version
pbKey = PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast<char*>(AppAlphaVersion ? UpdatesPublicKey : UpdatesPublicAlphaKey), -1), 0, 0, 0);
if (!pbKey) {
LOG(("Update Error: cant read public rsa key!"));
return fatalFail();
}
if (RSA_verify(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (const uchar*)(compressed.constData()), hSigLen, pbKey) != 1) { // verify signature
RSA_free(pbKey);
LOG(("Update Error: bad RSA signature of update file!"));
return fatalFail();
}
} else {
LOG(("Update Error: bad RSA signature of update file!"));
return fatalFail();
}
}
RSA_free(pbKey);
QByteArray uncompressed;
int32 uncompressedLen;
memcpy(&uncompressedLen, compressed.constData() + hSigLen + hShaLen + hPropsLen, hOriginalSizeLen);
uncompressed.resize(uncompressedLen);
size_t resultLen = uncompressed.size();
#ifdef Q_OS_WIN // use Lzma SDK for win
SizeT srcLen = compressedLen;
int uncompressRes = LzmaUncompress((uchar*)uncompressed.data(), &resultLen, (const uchar*)(compressed.constData() + hSize), &srcLen, (const uchar*)(compressed.constData() + hSigLen + hShaLen), LZMA_PROPS_SIZE);
if (uncompressRes != SZ_OK) {
LOG(("Update Error: could not uncompress lzma, code: %1").arg(uncompressRes));
return fatalFail();
}
#else // Q_OS_WIN
lzma_stream stream = LZMA_STREAM_INIT;
lzma_ret ret = lzma_stream_decoder(&stream, UINT64_MAX, LZMA_CONCATENATED);
if (ret != LZMA_OK) {
const char *msg;
switch (ret) {
case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
case LZMA_OPTIONS_ERROR: msg = "Specified preset is not supported"; break;
case LZMA_UNSUPPORTED_CHECK: msg = "Specified integrity check is not supported"; break;
default: msg = "Unknown error, possibly a bug"; break;
}
LOG(("Error initializing the decoder: %1 (error code %2)").arg(msg).arg(ret));
return fatalFail();
}
stream.avail_in = compressedLen;
stream.next_in = (uint8_t*)(compressed.constData() + hSize);
stream.avail_out = resultLen;
stream.next_out = (uint8_t*)uncompressed.data();
lzma_ret res = lzma_code(&stream, LZMA_FINISH);
if (stream.avail_in) {
LOG(("Error in decompression, %1 bytes left in _in of %2 whole.").arg(stream.avail_in).arg(compressedLen));
return fatalFail();
} else if (stream.avail_out) {
LOG(("Error in decompression, %1 bytes free left in _out of %2 whole.").arg(stream.avail_out).arg(resultLen));
return fatalFail();
}
lzma_end(&stream);
if (res != LZMA_OK && res != LZMA_STREAM_END) {
const char *msg;
switch (res) {
case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
case LZMA_FORMAT_ERROR: msg = "The input data is not in the .xz format"; break;
case LZMA_OPTIONS_ERROR: msg = "Unsupported compression options"; break;
case LZMA_DATA_ERROR: msg = "Compressed file is corrupt"; break;
case LZMA_BUF_ERROR: msg = "Compressed data is truncated or otherwise corrupt"; break;
default: msg = "Unknown error, possibly a bug"; break;
}
LOG(("Error in decompression: %1 (error code %2)").arg(msg).arg(res));
return fatalFail();
}
#endif // Q_OS_WIN
tempDir.mkdir(tempDir.absolutePath());
quint32 version;
{
QDataStream stream(uncompressed);
stream.setVersion(QDataStream::Qt_5_1);
stream >> version;
if (stream.status() != QDataStream::Ok) {
LOG(("Update Error: cant read version from downloaded stream, status: %1").arg(stream.status()));
return fatalFail();
}
quint64 betaVersion = 0;
if (version == 0x7FFFFFFF) { // beta version
stream >> betaVersion;
if (stream.status() != QDataStream::Ok) {
LOG(("Update Error: cant read beta version from downloaded stream, status: %1").arg(stream.status()));
return fatalFail();
}
if (!cBetaVersion() || betaVersion <= cBetaVersion()) {
LOG(("Update Error: downloaded beta version %1 is not greater, than mine %2").arg(betaVersion).arg(cBetaVersion()));
return fatalFail();
}
} else if (int32(version) <= AppVersion) {
LOG(("Update Error: downloaded version %1 is not greater, than mine %2").arg(version).arg(AppVersion));
return fatalFail();
}
quint32 filesCount;
stream >> filesCount;
if (stream.status() != QDataStream::Ok) {
LOG(("Update Error: cant read files count from downloaded stream, status: %1").arg(stream.status()));
return fatalFail();
}
if (!filesCount) {
LOG(("Update Error: update is empty!"));
return fatalFail();
}
for (uint32 i = 0; i < filesCount; ++i) {
QString relativeName;
quint32 fileSize;
QByteArray fileInnerData;
bool executable = false;
stream >> relativeName >> fileSize >> fileInnerData;
#if defined Q_OS_MAC || defined Q_OS_LINUX
stream >> executable;
#endif // Q_OS_MAC || Q_OS_LINUX
if (stream.status() != QDataStream::Ok) {
LOG(("Update Error: cant read file from downloaded stream, status: %1").arg(stream.status()));
return fatalFail();
}
if (fileSize != quint32(fileInnerData.size())) {
LOG(("Update Error: bad file size %1 not matching data size %2").arg(fileSize).arg(fileInnerData.size()));
return fatalFail();
}
QFile f(tempDirPath + '/' + relativeName);
if (!QDir().mkpath(QFileInfo(f).absolutePath())) {
LOG(("Update Error: cant mkpath for file '%1'").arg(tempDirPath + '/' + relativeName));
return fatalFail();
}
if (!f.open(QIODevice::WriteOnly)) {
LOG(("Update Error: cant open file '%1' for writing").arg(tempDirPath + '/' + relativeName));
return fatalFail();
}
auto writtenBytes = f.write(fileInnerData);
if (writtenBytes != fileSize) {
f.close();
LOG(("Update Error: cant write file '%1', desiredSize: %2, write result: %3").arg(tempDirPath + '/' + relativeName).arg(fileSize).arg(writtenBytes));
return fatalFail();
}
f.close();
if (executable) {
QFileDevice::Permissions p = f.permissions();
p |= QFileDevice::ExeOwner | QFileDevice::ExeUser | QFileDevice::ExeGroup | QFileDevice::ExeOther;
f.setPermissions(p);
}
}
// create tdata/version file
tempDir.mkdir(QDir(tempDirPath + qsl("/tdata")).absolutePath());
std::wstring versionString = ((version % 1000) ? QString("%1.%2.%3").arg(int(version / 1000000)).arg(int((version % 1000000) / 1000)).arg(int(version % 1000)) : QString("%1.%2").arg(int(version / 1000000)).arg(int((version % 1000000) / 1000))).toStdWString();
VerInt versionNum = VerInt(version), versionLen = VerInt(versionString.size() * sizeof(VerChar));
VerChar versionStr[32];
memcpy(versionStr, versionString.c_str(), versionLen);
QFile fVersion(tempDirPath + qsl("/tdata/version"));
if (!fVersion.open(QIODevice::WriteOnly)) {
LOG(("Update Error: cant write version file '%1'").arg(tempDirPath + qsl("/version")));
return fatalFail();
}
fVersion.write((const char*)&versionNum, sizeof(VerInt));
if (versionNum == 0x7FFFFFFF) { // beta version
fVersion.write((const char*)&betaVersion, sizeof(quint64));
} else {
fVersion.write((const char*)&versionLen, sizeof(VerInt));
fVersion.write((const char*)&versionStr[0], versionLen);
}
fVersion.close();
}
QFile readyFile(readyFilePath);
if (readyFile.open(QIODevice::WriteOnly)) {
if (readyFile.write("1", 1)) {
readyFile.close();
} else {
LOG(("Update Error: cant write ready file '%1'").arg(readyFilePath));
return fatalFail();
}
} else {
LOG(("Update Error: cant create ready file '%1'").arg(readyFilePath));
return fatalFail();
}
outputFile.remove();
Sandbox::updateReady();
}
UpdateChecker::~UpdateChecker() {
delete reply;
reply = 0;
}
bool checkReadyUpdate() {
QString readyFilePath = cWorkingDir() + qsl("tupdates/temp/ready"), readyPath = cWorkingDir() + qsl("tupdates/temp");
if (!QFile(readyFilePath).exists() || cExeName().isEmpty()) {
if (QDir(cWorkingDir() + qsl("tupdates/ready")).exists() || QDir(cWorkingDir() + qsl("tupdates/temp")).exists()) {
UpdateChecker::clearAll();
}
return false;
}
// check ready version
QString versionPath = readyPath + qsl("/tdata/version");
{
QFile fVersion(versionPath);
if (!fVersion.open(QIODevice::ReadOnly)) {
LOG(("Update Error: cant read version file '%1'").arg(versionPath));
UpdateChecker::clearAll();
return false;
}
VerInt versionNum;
if (fVersion.read((char*)&versionNum, sizeof(VerInt)) != sizeof(VerInt)) {
LOG(("Update Error: cant read version from file '%1'").arg(versionPath));
UpdateChecker::clearAll();
return false;
}
if (versionNum == 0x7FFFFFFF) { // beta version
quint64 betaVersion = 0;
if (fVersion.read((char*)&betaVersion, sizeof(quint64)) != sizeof(quint64)) {
LOG(("Update Error: cant read beta version from file '%1'").arg(versionPath));
UpdateChecker::clearAll();
return false;
}
if (!cBetaVersion() || betaVersion <= cBetaVersion()) {
LOG(("Update Error: cant install beta version %1 having beta version %2").arg(betaVersion).arg(cBetaVersion()));
UpdateChecker::clearAll();
return false;
}
} else if (versionNum <= AppVersion) {
LOG(("Update Error: cant install version %1 having version %2").arg(versionNum).arg(AppVersion));
UpdateChecker::clearAll();
return false;
}
fVersion.close();
}
#ifdef Q_OS_WIN
QString curUpdater = (cExeDir() + qsl("Updater.exe"));
QFileInfo updater(cWorkingDir() + qsl("tupdates/temp/Updater.exe"));
#elif defined Q_OS_MAC // Q_OS_WIN
QString curUpdater = (cExeDir() + cExeName() + qsl("/Contents/Frameworks/Updater"));
QFileInfo updater(cWorkingDir() + qsl("tupdates/temp/Telegram.app/Contents/Frameworks/Updater"));
#elif defined Q_OS_LINUX // Q_OS_MAC
QString curUpdater = (cExeDir() + qsl("Updater"));
QFileInfo updater(cWorkingDir() + qsl("tupdates/temp/Updater"));
#endif // Q_OS_LINUX
if (!updater.exists()) {
QFileInfo current(curUpdater);
if (!current.exists()) {
UpdateChecker::clearAll();
return false;
}
if (!QFile(current.absoluteFilePath()).copy(updater.absoluteFilePath())) {
UpdateChecker::clearAll();
return false;
}
}
#ifdef Q_OS_WIN
if (CopyFile(updater.absoluteFilePath().toStdWString().c_str(), curUpdater.toStdWString().c_str(), FALSE) == FALSE) {
DWORD errorCode = GetLastError();
if (errorCode == ERROR_ACCESS_DENIED) { // we are in write-protected dir, like Program Files
cSetWriteProtected(true);
return true;
} else {
UpdateChecker::clearAll();
return false;
}
}
if (DeleteFile(updater.absoluteFilePath().toStdWString().c_str()) == FALSE) {
UpdateChecker::clearAll();
return false;
}
#elif defined Q_OS_MAC // Q_OS_WIN
QDir().mkpath(QFileInfo(curUpdater).absolutePath());
DEBUG_LOG(("Update Info: moving %1 to %2...").arg(updater.absoluteFilePath()).arg(curUpdater));
if (!objc_moveFile(updater.absoluteFilePath(), curUpdater)) {
UpdateChecker::clearAll();
return false;
}
#elif defined Q_OS_LINUX // Q_OS_MAC
if (!linuxMoveFile(QFile::encodeName(updater.absoluteFilePath()).constData(), QFile::encodeName(curUpdater).constData())) {
UpdateChecker::clearAll();
return false;
}
#endif // Q_OS_LINUX
return true;
}
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
QString countBetaVersionSignature(uint64 version) { // duplicated in packer.cpp
if (cBetaPrivateKey().isEmpty()) {
LOG(("Error: Trying to count beta version signature without beta private key!"));
return QString();
}
QByteArray signedData = (qstr("TelegramBeta_") + QString::number(version, 16).toLower()).toUtf8();
static const int32 shaSize = 20, keySize = 128;
uchar sha1Buffer[shaSize];
hashSha1(signedData.constData(), signedData.size(), sha1Buffer); // count sha1
uint32 siglen = 0;
RSA *prKey = PEM_read_bio_RSAPrivateKey(BIO_new_mem_buf(const_cast<char*>(cBetaPrivateKey().constData()), -1), 0, 0, 0);
if (!prKey) {
LOG(("Error: Could not read beta private key!"));
return QString();
}
if (RSA_size(prKey) != keySize) {
LOG(("Error: Bad beta private key size: %1").arg(RSA_size(prKey)));
RSA_free(prKey);
return QString();
}
QByteArray signature;
signature.resize(keySize);
if (RSA_sign(NID_sha1, (const uchar*)(sha1Buffer), shaSize, (uchar*)(signature.data()), &siglen, prKey) != 1) { // count signature
LOG(("Error: Counting beta version signature failed!"));
RSA_free(prKey);
return QString();
}
RSA_free(prKey);
if (siglen != keySize) {
LOG(("Error: Bad beta version signature length: %1").arg(siglen));
return QString();
}
signature = signature.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
signature = signature.replace('-', '8').replace('_', 'B');
return QString::fromUtf8(signature.mid(19, 32));
}

View File

@ -1,76 +0,0 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
#include <QtNetwork/QLocalSocket>
#include <QtNetwork/QLocalServer>
#include <QtNetwork/QNetworkReply>
class UpdateChecker : public QObject {
Q_OBJECT
public:
UpdateChecker(QThread *thread, const QString &url);
void unpackUpdate();
int32 ready();
int32 size();
static void clearAll();
~UpdateChecker();
public slots:
void start();
void partMetaGot();
void partFinished(qint64 got, qint64 total);
void partFailed(QNetworkReply::NetworkError e);
void sendRequest();
private:
void initOutput();
void fatalFail();
QString updateUrl;
QNetworkAccessManager manager;
QNetworkReply *reply;
int32 already, full;
QFile outputFile;
QMutex mutex;
};
bool checkReadyUpdate();
#else // TDESKTOP_DISABLE_AUTOUPDATE
class UpdateChecker : public QObject {
Q_OBJECT
};
#endif // TDESKTOP_DISABLE_AUTOUPDATE
QString countBetaVersionSignature(uint64 version);

View File

@ -22,6 +22,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
namespace base {
// @todo use ranges-v3 here
template <typename Range, typename Method>
decltype(auto) for_each(Range &&range, Method &&method) {
return std::for_each(

View File

@ -22,6 +22,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include <vector>
#include <deque>
#include <QSharedPointer>
#include "base/type_traits.h"
namespace base {

View File

@ -21,7 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "base/runtime_composer.h"
struct RuntimeComposerMetadatasMap {
QMap<uint64, RuntimeComposerMetadata*> data;
QMap<uint64_t, RuntimeComposerMetadata*> data;
~RuntimeComposerMetadatasMap() {
for_const (const RuntimeComposerMetadata *p, data) {
delete p;
@ -29,7 +29,7 @@ struct RuntimeComposerMetadatasMap {
}
};
const RuntimeComposerMetadata *GetRuntimeComposerMetadata(uint64 mask) {
const RuntimeComposerMetadata *GetRuntimeComposerMetadata(uint64_t mask) {
static RuntimeComposerMetadatasMap RuntimeComposerMetadatas;
static QMutex RuntimeComposerMetadatasMutex;

View File

@ -84,7 +84,7 @@ struct RuntimeComponent {
}
return MyIndex.loadAcquire() - 1;
}
static uint64 Bit() {
static uint64_t Bit() {
return (1ULL << Index());
}
@ -103,7 +103,7 @@ protected:
class RuntimeComposerMetadata {
public:
RuntimeComposerMetadata(uint64 mask) : _mask(mask) {
RuntimeComposerMetadata(uint64_t mask) : _mask(mask) {
for (int i = 0; i != 64; ++i) {
auto componentBit = (1ULL << i);
if (_mask & componentBit) {
@ -130,26 +130,26 @@ public:
std::size_t offsets[64] = { 0 };
int last = 64;
bool equals(uint64 mask) const {
bool equals(uint64_t mask) const {
return _mask == mask;
}
uint64 maskadd(uint64 mask) const {
uint64_t maskadd(uint64_t mask) const {
return _mask | mask;
}
uint64 maskremove(uint64 mask) const {
uint64_t maskremove(uint64_t mask) const {
return _mask & (~mask);
}
private:
uint64 _mask;
uint64_t _mask;
};
const RuntimeComposerMetadata *GetRuntimeComposerMetadata(uint64 mask);
const RuntimeComposerMetadata *GetRuntimeComposerMetadata(uint64_t mask);
class RuntimeComposer {
public:
RuntimeComposer(uint64 mask = 0) : _data(zerodata()) {
RuntimeComposer(uint64_t mask = 0) : _data(zerodata()) {
if (mask) {
auto meta = GetRuntimeComposerMetadata(mask);
@ -212,7 +212,7 @@ public:
}
protected:
void UpdateComponents(uint64 mask = 0) {
void UpdateComponents(uint64_t mask = 0) {
if (!_meta()->equals(mask)) {
RuntimeComposer tmp(mask);
tmp.swap(*this);
@ -228,10 +228,10 @@ protected:
}
}
}
void AddComponents(uint64 mask = 0) {
void AddComponents(uint64_t mask = 0) {
UpdateComponents(_meta()->maskadd(mask));
}
void RemoveComponents(uint64 mask = 0) {
void RemoveComponents(uint64_t mask = 0) {
UpdateComponents(_meta()->maskremove(mask));
}

View File

@ -1,717 +0,0 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
namespace base {
template <typename Object, typename ParentObject = void>
class virtual_object;
template <typename ConcreteMethod, typename ReturnType, typename ...Args>
class virtual_method;
template <typename ConcreteMethod, typename BaseMethod>
class virtual_override;
namespace virtual_methods {
struct child_entry;
using is_parent_check = bool(*)(const child_entry &possible_parent);
struct child_entry {
is_parent_check check_is_parent;
int *table_index;
};
using child_entries = std::vector<child_entry>;
// Recursive method to find if some class is a child of some other class.
template <typename ConcreteObject>
struct is_parent {
static inline bool check(const child_entry &possible_parent) {
// Generate a good error message if ConcreteObject is not a child of virtual_object<>.
using all_objects_must_derive_virtual_object = typename ConcreteObject::virtual_object_parent;
using ConcreteObjectParent = all_objects_must_derive_virtual_object;
return (possible_parent.check_is_parent == &is_parent<ConcreteObject>::check)
|| is_parent<ConcreteObjectParent>::check(possible_parent);
}
};
template <>
struct is_parent<void> {
static inline bool check(const child_entry &possible_parent) {
return (possible_parent.check_is_parent == &is_parent<void>::check);
}
};
// Just force the compiler not to optimize away the object that "enforce" points at.
inline void dont_optimize_away(void *enforce) {
static volatile void *result = nullptr;
if (result) {
result = enforce;
}
}
template <typename Type, Type Value>
struct dont_optimize_away_struct {
};
inline bool first_dispatch_fired(bool did_fire = false) {
static bool fired = false;
if (did_fire) {
fired = true;
}
return fired;
}
template <typename Object, void (*Creator)(const child_entry &)>
class object_registrator {
public:
inline object_registrator() {
Assert(!first_dispatch_fired());
Creator(child_entry {
&is_parent<Object>::check,
&_index,
});
}
static inline int &Index() {
return _index;
}
private:
static int _index;
};
template <typename Object, void (*Creator)(const child_entry &)>
int object_registrator<Object, Creator>::_index = -1;
class object_base {
protected:
virtual ~object_base() = default;
};
template <typename ...ConcreteArgs>
struct multi_index_collector;
template <int M, typename ...ConcreteArgs>
struct override_key_collector_helper;
template <typename Call, typename ...Args>
struct table_fill_entry_helper;
template <typename ...Args>
struct table_count_size;
} // namespace virtual_methods
// This should be a base class for every child object in your hierarchy.
// It registers this child in the root virtual_objects classes list.
// Also it holds its own index in the classes list that is used for fast
// invoking of methods from the virtual tables in different virtual_methods.
template <typename Object, typename ParentObject>
class virtual_object : public ParentObject {
protected:
virtual ~virtual_object() {
virtual_methods::dont_optimize_away(&_virtual_object_registrator);
}
private:
using virtual_object_parent = ParentObject;
friend struct virtual_methods::is_parent<Object>;
template <typename ...Args>
friend struct virtual_methods::multi_index_collector;
template <int M, typename ...ConcreteArgs>
friend struct virtual_methods::override_key_collector_helper;
template <typename OtherObject, typename OtherParentObject>
friend class virtual_object;
template <typename BaseMethod, typename ReturnType, typename ...Args>
friend class virtual_method;
static inline void virtual_object_register_child(const virtual_methods::child_entry &entry) {
return ParentObject::virtual_object_register_child(entry);
}
using virtual_object_registrator = virtual_methods::object_registrator<Object, &virtual_object::virtual_object_register_child>;
static virtual_object_registrator _virtual_object_registrator;
using virtual_object_dont_optimize_away_registrator = virtual_methods::dont_optimize_away_struct<virtual_object_registrator*, &_virtual_object_registrator>;
static inline int &virtual_object_child_index_static() {
return virtual_object_registrator::Index();
}
int &virtual_object_child_index() override {
return virtual_object_child_index_static();
}
};
template <typename Object, typename ParentObject>
typename virtual_object<Object, ParentObject>::virtual_object_registrator virtual_object<Object, ParentObject>::_virtual_object_registrator = {};
// This should be a base class for the root of the whole hierarchy.
// It holds the table of all child classes in a list.
// This list is used by virtual_methods to generate virtual table.
template <typename Object>
class virtual_object<Object, void> : public virtual_methods::object_base {
protected:
virtual ~virtual_object() {
virtual_methods::dont_optimize_away(&_virtual_object_registrator);
}
private:
using virtual_object_parent = void;
friend struct virtual_methods::is_parent<Object>;
template <typename ...Args>
friend struct virtual_methods::table_count_size;
template <typename ...Args>
friend struct virtual_methods::multi_index_collector;
template <int M, typename ...ConcreteArgs>
friend struct virtual_methods::override_key_collector_helper;
template <typename Call, typename ...Args>
friend struct virtual_methods::table_fill_entry_helper;
template <typename OtherObject, typename OtherParentObject>
friend class virtual_object;
template <typename BaseMethod, typename ReturnType, typename ...Args>
friend class virtual_method;
static inline virtual_methods::child_entries &virtual_object_get_child_entries() {
static virtual_methods::child_entries entries;
return entries;
}
// Registers a new child class.
// After that on the next call to virtual_method::virtual_method_prepare_table() will
// generate a new virtual table for that virtual method.
static inline void virtual_object_register_child(const virtual_methods::child_entry &entry) {
auto &entries = virtual_object_get_child_entries();
for (auto i = entries.begin(), e = entries.end(); i != e; ++i) {
if (entry.check_is_parent(*i)) {
*entry.table_index = (i - entries.begin());
i = entries.insert(i, entry);
for (++i, e = entries.end(); i != e; ++i) {
++*(i->table_index);
}
return;
}
}
*entry.table_index = entries.size();
entries.push_back(entry);
}
using virtual_object_registrator = virtual_methods::object_registrator<Object, &virtual_object::virtual_object_register_child>;
static virtual_object_registrator _virtual_object_registrator;
using virtual_object_dont_optimize_away_registrator = virtual_methods::dont_optimize_away_struct<virtual_object_registrator*, &_virtual_object_registrator>;
static inline int &virtual_object_child_index_static() {
return virtual_object_registrator::Index();
}
virtual int &virtual_object_child_index() {
return virtual_object_child_index_static();
}
};
template <typename Object>
typename virtual_object<Object, void>::virtual_object_registrator virtual_object<Object, void>::_virtual_object_registrator = {};
namespace virtual_methods {
template <typename Arg>
struct is_virtual_argument : public std::integral_constant<bool,
base::type_traits<Arg>::is_pointer::value
? std::is_base_of<object_base, typename base::type_traits<Arg>::pointed_type>::value
: false> {
};
template <int N, int Instance>
class multi_int_wrap {
public:
inline multi_int_wrap(int *indices) : _indices(indices) {
}
inline multi_int_wrap<N - 1, Instance> subindex() const {
static_assert(N > 0, "Wrong multi_int_wrap created!");
return multi_int_wrap<N - 1, Instance>(_indices + 1);
}
inline int &current() const {
return *_indices;
}
private:
int *_indices;
};
template <int Instance>
class multi_int_wrap<0, Instance> {
public:
inline multi_int_wrap(int *indices) {
}
inline int current() const {
return 1;
}
};
template <int N>
using multi_index_wrap = multi_int_wrap<N, 0>;
template <int N>
using multi_size_wrap = multi_int_wrap<N, 1>;
template <typename ConcreteArg, typename ...ConcreteArgs>
struct multi_index_collector<ConcreteArg, ConcreteArgs...> {
static constexpr int N = sizeof...(ConcreteArgs) + 1;
static inline void call(multi_index_wrap<N> indices, ConcreteArg arg, ConcreteArgs... args) {
indices.current() = computeIndex(is_virtual_argument<ConcreteArg>(), arg);
multi_index_collector<ConcreteArgs...>::call(indices.subindex(), args...);
}
static inline int computeIndex(std::integral_constant<bool, false>, ConcreteArg arg) {
return 0;
}
static inline int computeIndex(std::integral_constant<bool, true>, ConcreteArg arg) {
return arg->virtual_object_child_index();
}
};
template <>
struct multi_index_collector<> {
static inline void call(multi_index_wrap<0> indices) {
}
};
template <int N>
class override_key;
template <int N, int Instance>
class multi_int {
public:
inline multi_int_wrap<N, Instance> data_wrap() {
return multi_int_wrap<N, Instance>(_indices);
}
template <typename ...ConcreteArgs>
static inline multi_int<N, Instance> collect(ConcreteArgs... args) {
multi_int<N, Instance> result;
multi_index_collector<ConcreteArgs...>::call(result.data_wrap(), args...);
return result;
}
inline void reset() {
memset(_indices, 0, sizeof(_indices));
}
inline int value(int index) const {
return _indices[index];
}
inline void copy(multi_int_wrap<N, Instance> other) {
memcpy(_indices, &other.current(), sizeof(_indices));
}
private:
int _indices[N] = { 0 };
friend class override_key<N>;
};
template <int N>
using multi_index = multi_int<N, 0>;
template <int N>
using multi_size = multi_int<N, 1>;
template <typename Call, int N>
class table_data_wrap {
public:
inline table_data_wrap(Call *data, multi_size_wrap<N> size) : _data(data), _size(size) {
}
inline table_data_wrap<Call, N - 1> operator[](int index) const {
return table_data_wrap<Call, N - 1>(_data + index * _size.subindex().current(), _size.subindex());
}
inline Call &operator[](multi_index_wrap<N> index) const {
return (*this)[index.current()][index.subindex()];
}
inline int size() const {
return count_size(std::integral_constant<int,N>());
}
private:
template <int M>
inline int count_size(std::integral_constant<int,M>) const {
return _size.current() / _size.subindex().current();
}
inline int count_size(std::integral_constant<int,1>) const {
return _size.current();
}
Call *_data;
multi_size_wrap<N> _size;
};
template <typename Call>
class table_data_wrap<Call, 0> {
public:
inline table_data_wrap(Call *data, multi_size_wrap<0> size) : _data(data) {
}
inline Call &operator[](multi_index_wrap<0> index) const {
return *_data;
}
private:
Call *_data;
};
template <typename Call, int N>
class table_data_wrap;
template <typename Arg, typename ...Args>
struct table_count_size<Arg, Args...> {
static constexpr int N = sizeof...(Args) + 1;
static inline void call(multi_size_wrap<N> index) {
auto subindex = index.subindex();
table_count_size<Args...>::call(subindex);
index.current() = count(is_virtual_argument<Arg>()) * subindex.current();
}
static inline int count(std::integral_constant<bool, false>) {
return 1;
}
static inline int count(std::integral_constant<bool, true>) {
return base::type_traits<Arg>::pointed_type::virtual_object_get_child_entries().size();
}
};
template <>
struct table_count_size<> {
static inline void call(multi_size_wrap<0> index) {
}
};
template <typename Call, int N>
class table_data {
public:
inline table_data_wrap<Call, N> data_wrap() {
return table_data_wrap<Call, N>(_data.data(), _size.data_wrap());
}
inline Call &operator[](multi_index<N> index) {
int flat_index = 0;
for (int i = 0; i != N - 1; ++i) {
flat_index += _size.value(i + 1) * index.value(i);
}
flat_index += index.value(N - 1);
return _data[flat_index];
}
template <typename ...Args>
inline bool changed() {
if (!_data.empty()) {
return false;
}
multi_size<N> size;
table_count_size<Args...>::call(size.data_wrap());
_size = size;
_data.resize(_size.value(0), nullptr);
return true;
}
private:
std::vector<Call> _data;
multi_size<N> _size;
};
template <typename Call>
class table_data<Call, 0> {
public:
inline table_data_wrap<Call, 0> data_wrap() {
return table_data_wrap<Call, 0>(&_call, multi_size_wrap<0>(nullptr));
}
inline Call &operator[](multi_index<0> index) {
return _call;
}
inline bool changed() const {
return false;
}
private:
Call _call = nullptr;
};
template <typename Call, typename ...Args>
struct table_fill_entry_helper;
template <typename Call, typename Arg, typename ...Args>
struct table_fill_entry_helper<Call, Arg, Args...> {
static constexpr int N = sizeof...(Args) + 1;
static inline bool call(table_data_wrap<Call, N> table, multi_index_wrap<N> index, Call &fill) {
auto start = index.current();
for (auto i = start, count = table.size(); i != count; ++i) {
auto foundGoodType = good(is_virtual_argument<Arg>(), start, index.current());
if (foundGoodType) {
index.current() = i;
if (table_fill_entry_helper<Call, Args...>::call(table[i], index.subindex(), fill)) {
return true;
}
}
}
index.current() = start;
return false;
}
static inline bool good(std::integral_constant<bool,false>, int start, int current) {
return (start == current);
}
static inline bool good(std::integral_constant<bool,true>, int start, int current) {
using BaseObject = typename base::type_traits<Arg>::pointed_type;
auto &entries = BaseObject::virtual_object_get_child_entries();
return (start == current) || entries[start].check_is_parent(entries[current]);
}
};
template <typename Call>
struct table_fill_entry_helper<Call> {
static inline bool call(table_data_wrap<Call, 0> table, multi_index_wrap<0> index, Call &fill) {
if (auto overrideMethod = table[index]) {
fill = overrideMethod;
return true;
}
return false;
}
};
template <typename Call, int N>
struct table_fill_entry;
template <typename ReturnType, int N, typename BaseMethod, typename ...Args>
struct table_fill_entry<ReturnType(*)(BaseMethod*, Args...), N> {
using Call = ReturnType(*)(BaseMethod*, Args...);
static inline void call(table_data_wrap<Call, N> table, multi_index_wrap<N> index, Call &fill) {
table_fill_entry_helper<Call, Args...>::call(table, index, fill);
}
};
template <typename Call, int N>
inline void fill_entry(table_data_wrap<Call, N> table, multi_index_wrap<N> index, Call &fill) {
return virtual_methods::table_fill_entry<Call, N>::call(table, index, fill);
}
template <int M, typename ...ConcreteArgs>
struct override_key_collector_helper;
template <int M, typename ConcreteArg, typename ...ConcreteArgs>
struct override_key_collector_helper<M, ConcreteArg, ConcreteArgs...> {
static inline void call(int **indices) {
setValue(is_virtual_argument<ConcreteArg>(), indices);
override_key_collector_helper<M + 1, ConcreteArgs...>::call(indices);
}
static inline void setValue(std::integral_constant<bool,false>, int **indices) {
indices[M] = nullptr;
}
static inline void setValue(std::integral_constant<bool,true>, int **indices) {
using ConcreteObject = typename base::type_traits<ConcreteArg>::pointed_type;
using IsParentCheckStruct = is_parent<ConcreteObject>;
using IsParentCheckPointer = decltype(&IsParentCheckStruct::check);
using override_key_collector_dont_optimize_away = dont_optimize_away_struct<IsParentCheckPointer, &IsParentCheckStruct::check>;
override_key_collector_dont_optimize_away dont_optimize_away_object;
(void)dont_optimize_away_object;
// Check that is_parent<> can be instantiated.
// So every ConcreteObject is a valid child of virtual_object<>.
dont_optimize_away(reinterpret_cast<void*>(&IsParentCheckStruct::check));
indices[M] = &ConcreteObject::virtual_object_child_index_static();
}
};
template <int M>
struct override_key_collector_helper<M> {
static inline void call(int **indices) {
}
};
template <typename CallSignature>
struct override_key_collector;
template <typename ReturnType, typename BaseMethod, typename ...ConcreteArgs>
struct override_key_collector<ReturnType(*)(BaseMethod, ConcreteArgs...)> {
static inline void call(int **indices) {
override_key_collector_helper<0, ConcreteArgs...>::call(indices);
}
};
template <int N>
class override_key {
public:
inline multi_index<N> value() const {
multi_index<N> result;
for (int i = 0; i != N; ++i) {
auto pointer = _indices[i];
result._indices[i] = (pointer ? *pointer : 0);
}
return result;
}
friend inline bool operator<(const override_key &k1, const override_key &k2) {
for (int i = 0; i != N; ++i) {
auto pointer1 = k1._indices[i], pointer2 = k2._indices[i];
if (pointer1 < pointer2) {
return true;
} else if (pointer1 > pointer2) {
return false;
}
}
return false;
}
template <typename CallSignature>
inline void collect() {
override_key_collector<CallSignature>::call(_indices);
}
private:
int *_indices[N];
};
template <typename BaseMethod, typename ConcreteMethod, typename CallSignature, typename ...Args>
struct static_cast_helper;
template <typename BaseMethod, typename ConcreteMethod, typename ReturnType, typename ...ConcreteArgs, typename ...Args>
struct static_cast_helper<BaseMethod, ConcreteMethod, ReturnType(*)(BaseMethod *, ConcreteArgs...), Args...> {
static inline ReturnType call(BaseMethod *context, Args ...args) {
return ConcreteMethod::call(context, static_cast<ConcreteArgs>(args)...);
}
};
} // namespace virtual_methods
// This is a base class for all your virtual methods.
// It dispatches a call to one of the registered virtual_overrides
// or calls the fallback method of the BaseMethod class.
template <typename BaseMethod, typename ReturnType, typename ...Args>
class virtual_method {
static constexpr int N = sizeof...(Args);
using virtual_method_call = ReturnType(*)(BaseMethod *context, Args... args);
public:
inline ReturnType call(Args... args) {
auto context = static_cast<BaseMethod*>(this);
auto index = virtual_methods::multi_index<N>::collect(args...);
auto &table = virtual_method_prepare_table();
auto &entry = table[index];
if (!entry) {
virtual_methods::fill_entry(table.data_wrap(), index.data_wrap(), entry);
if (!entry) {
entry = &virtual_method::virtual_method_base_instance;
}
}
return (*entry)(context, args...);
}
private:
// This map of methods contains only the original registered overrides.
using virtual_method_override_key = virtual_methods::override_key<N>;
using virtual_method_override_map = std::map<virtual_method_override_key, virtual_method_call>;
static inline virtual_method_override_map &virtual_method_get_override_map() {
static virtual_method_override_map override_map;
return override_map;
}
// This method generates and returns a virtual table which holds a method
// for any child in the hierarchy or nullptr if none of the virtual_overrides fit.
using virtual_method_table_data = virtual_methods::table_data<virtual_method_call, N>;
static inline virtual_method_table_data &virtual_method_get_table_data() {
static virtual_method_table_data virtual_table;
return virtual_table;
}
static inline virtual_method_table_data &virtual_method_prepare_table() {
auto &virtual_table = virtual_method_get_table_data();
if (virtual_table.template changed<Args...>()) {
virtual_methods::first_dispatch_fired(true);
// The class hierarchy has changed - we need to generate the virtual table once again.
// All other handlers will be placed if they're called.
for (auto &i : virtual_method_get_override_map()) {
virtual_table[i.first.value()] = i.second;
}
}
return virtual_table;
}
static ReturnType virtual_method_base_instance(BaseMethod *context, Args... args) {
return BaseMethod::default_call(context, args...);
}
template <typename ConcreteMethod>
static ReturnType virtual_method_override_instance(BaseMethod *context, Args... args) {
return virtual_methods::static_cast_helper<BaseMethod, ConcreteMethod, decltype(&ConcreteMethod::call), Args...>::call(context, args...);
}
template <typename ConcreteMethod>
static inline void virtual_method_register_override() {
auto call = &virtual_method_override_instance<ConcreteMethod>;
virtual_methods::override_key<N> key;
key.template collect<decltype(&ConcreteMethod::call)>();
virtual_method_get_override_map()[key] = call;
}
template <typename ConcreteMethod, typename OtherBaseMethod>
friend class virtual_override;
};
template <typename ConcreteMethod, typename BaseMethod>
class virtual_override {
protected:
virtual ~virtual_override() {
virtual_methods::dont_optimize_away(&_virtual_override_registrator);
}
private:
class virtual_override_registrator {
public:
inline virtual_override_registrator() {
Assert(!virtual_methods::first_dispatch_fired());
BaseMethod::template virtual_method_register_override<ConcreteMethod>();
}
};
static virtual_override_registrator _virtual_override_registrator;
using virtual_override_dont_optimize_away_registrator = virtual_methods::dont_optimize_away_struct<virtual_override_registrator*, &_virtual_override_registrator>;
};
template <typename ConcreteMethod, typename BaseMethod>
typename virtual_override<ConcreteMethod, BaseMethod>::virtual_override_registrator virtual_override<ConcreteMethod, BaseMethod>::_virtual_override_registrator = {};
} // namespace base

View File

@ -20,6 +20,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
// @todo replace this with std::experimental::observer_ptr
namespace base {
class enable_weak_from_this;

View File

@ -23,8 +23,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
#include "zip.h"
#include "unzip.h"
#include "minizip/zip.h"
#include "minizip/unzip.h"
namespace zlib {
namespace internal {
@ -243,7 +243,7 @@ public:
}
auto size = fileInfo.uncompressed_size;
if (size > static_cast<uint32>(fileSizeLimit)) {
if (size > static_cast<uint32_t>(fileSizeLimit)) {
if (_error == UNZ_OK) _error = -1;
LOG(("Error: current file is too large (should be less than %1, got %2) in a zip file.").arg(fileSizeLimit).arg(size));
return QByteArray();

View File

@ -0,0 +1,36 @@
# Unused: cotire PCH needs more rigid structure.
# To do: get rid of the PCH requirement for more flexible build structure.
add_library(tg_boxes STATIC
about_box.cpp
abstract_box.cpp
add_contact_box.cpp
autolock_box.cpp
background_box.cpp
calendar_box.cpp
change_phone_box.cpp
confirm_box.cpp
confirm_phone_box.cpp
connection_box.cpp
download_path_box.cpp
edit_color_box.cpp
edit_participant_box.cpp
edit_privacy_box.cpp
language_box.cpp
local_storage_box.cpp
mute_settings_box.cpp
notifications_box.cpp
passcode_box.cpp
peer_list_box.cpp
peer_list_controllers.cpp
photo_crop_box.cpp
rate_call_box.cpp
report_box.cpp
self_destruction_box.cpp
send_files_box.cpp
sessions_box.cpp
share_box.cpp
sticker_set_box.cpp
stickers_box.cpp
username_box.cpp
)
add_dependencies(tg_boxes boxes_styles_output)

View File

@ -23,7 +23,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "lang/lang_keys.h"
#include "mainwidget.h"
#include "mainwindow.h"
#include "autoupdater.h"
#include "boxes/confirm_box.h"
#include "application.h"
#include "ui/widgets/buttons.h"
@ -61,23 +60,7 @@ void AboutBox::resizeEvent(QResizeEvent *e) {
}
void AboutBox::showVersionHistory() {
if (cRealBetaVersion()) {
auto url = qsl("https://tdesktop.com/");
switch (cPlatform()) {
case dbipWindows: url += qsl("win/%1.zip"); break;
case dbipMac: url += qsl("mac/%1.zip"); break;
case dbipMacOld: url += qsl("mac32/%1.zip"); break;
case dbipLinux32: url += qsl("linux32/%1.tar.xz"); break;
case dbipLinux64: url += qsl("linux/%1.tar.xz"); break;
}
url = url.arg(qsl("tbeta%1_%2").arg(cRealBetaVersion()).arg(countBetaVersionSignature(cRealBetaVersion())));
Application::clipboard()->setText(url);
Ui::show(Box<InformBox>("The link to the current private beta version of Telegram Desktop was copied to the clipboard."));
} else {
QDesktopServices::openUrl(qsl("https://desktop.telegram.org/changelog"));
}
QDesktopServices::openUrl(qsl("https://desktop.telegram.org/changelog"));
}
void AboutBox::keyPressEvent(QKeyEvent *e) {

View File

@ -104,7 +104,7 @@ void BoxContent::onDraggingScrollDelta(int delta) {
}
void BoxContent::onDraggingScrollTimer() {
auto delta = (_draggingScrollDelta > 0) ? qMin(_draggingScrollDelta * 3 / 20 + 1, int32(MaxScrollSpeed)) : qMax(_draggingScrollDelta * 3 / 20 - 1, -int32(MaxScrollSpeed));
auto delta = (_draggingScrollDelta > 0) ? qMin(_draggingScrollDelta * 3 / 20 + 1, int32_t(MaxScrollSpeed)) : qMax(_draggingScrollDelta * 3 / 20 - 1, -int32_t(MaxScrollSpeed));
_scroll->scrollToY(_scroll->scrollTop() + delta);
}

View File

@ -221,11 +221,11 @@ void AddContactBox::onSave() {
}
_sentName = firstName;
if (_user) {
_contactId = rand_value<uint64>();
_contactId = rand_value<uint64_t>();
QVector<MTPInputContact> v(1, MTP_inputPhoneContact(MTP_long(_contactId), MTP_string(_user->phone()), MTP_string(firstName), MTP_string(lastName)));
_addRequest = MTP::send(MTPcontacts_ImportContacts(MTP_vector<MTPInputContact>(v)), rpcDone(&AddContactBox::onSaveUserDone), rpcFail(&AddContactBox::onSaveUserFail));
} else {
_contactId = rand_value<uint64>();
_contactId = rand_value<uint64_t>();
QVector<MTPInputContact> v(1, MTP_inputPhoneContact(MTP_long(_contactId), MTP_string(phone), MTP_string(firstName), MTP_string(lastName)));
_addRequest = MTP::send(MTPcontacts_ImportContacts(MTP_vector<MTPInputContact>(v)), rpcDone(&AddContactBox::onImportDone));
}
@ -745,8 +745,8 @@ void SetupChannelBox::onChange() {
}
_checkTimer.stop();
} else {
int32 len = name.size();
for (int32 i = 0; i < len; ++i) {
int32_t len = name.size();
for (int32_t i = 0; i < len; ++i) {
QChar ch = name.at(i);
if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z') && (ch < '0' || ch > '9') && ch != '_') {
if (_errorText != lang(lng_create_channel_link_bad_symbols)) {
@ -1498,8 +1498,8 @@ void RevokePublicLinkBox::Inner::paintChat(Painter &p, const ChatRow &row, bool
p.setPen(st::contactsNameFg);
int32 namex = st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left();
int32 namew = width() - namex - st::contactsPadding.right() - (_revokeWidth + st::contactsCheckPosition.x() * 2);
int32_t namex = st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left();
int32_t namew = width() - namex - st::contactsPadding.right() - (_revokeWidth + st::contactsCheckPosition.x() * 2);
if (peer->isVerified()) {
auto icon = &st::dialogsVerifiedIcon;
namew -= icon->width();

View File

@ -84,7 +84,7 @@ private:
bool _retrying = false;
bool _invertOrder = false;
uint64 _contactId = 0;
uint64_t _contactId = 0;
mtpRequestId _addRequest = 0;
QString _sentName;
@ -185,7 +185,7 @@ private:
std::shared_ptr<Ui::RadioenumGroup<Privacy>> _privacyGroup;
object_ptr<Ui::Radioenum<Privacy>> _public;
object_ptr<Ui::Radioenum<Privacy>> _private;
int32 _aboutPublicWidth, _aboutPublicHeight;
int32_t _aboutPublicWidth, _aboutPublicHeight;
Text _aboutPublic, _aboutPrivate;
object_ptr<Ui::UsernameInput> _link;

View File

@ -115,10 +115,10 @@ void BackgroundBox::Inner::gotWallpapers(const MTPVector<MTPWallPaper> &result)
auto &d = w.c_wallPaper();
auto &sizes = d.vsizes.v;
const MTPPhotoSize *thumb = 0, *full = 0;
int32 thumbLevel = -1, fullLevel = -1;
int32_t thumbLevel = -1, fullLevel = -1;
for (QVector<MTPPhotoSize>::const_iterator j = sizes.cbegin(), e = sizes.cend(); j != e; ++j) {
char size = 0;
int32 w = 0, h = 0;
int32_t w = 0, h = 0;
switch (j->type()) {
case mtpc_photoSize: {
auto &s = j->c_photoSize().vtype.v;
@ -136,7 +136,7 @@ void BackgroundBox::Inner::gotWallpapers(const MTPVector<MTPWallPaper> &result)
}
if (!size || !w || !h) continue;
int32 newThumbLevel = qAbs((st::backgroundSize.width() * cIntRetinaFactor()) - w), newFullLevel = qAbs(2560 - w);
int32_t newThumbLevel = qAbs((st::backgroundSize.width() * cIntRetinaFactor()) - w), newFullLevel = qAbs(2560 - w);
if (thumbLevel < 0 || newThumbLevel < thumbLevel) {
thumbLevel = newThumbLevel;
thumb = &(*j);

View File

@ -115,7 +115,7 @@ private:
not_null<ChannelData*> _channel;
Text _text;
int32 _textWidth, _textHeight;
int32_t _textWidth, _textHeight;
QRect _invitationLink;
bool _linkOver = false;
@ -141,7 +141,7 @@ private:
ChatData *_chat;
Text _text, _note;
int32 _textWidth, _textHeight;
int32_t _textWidth, _textHeight;
};

View File

@ -303,7 +303,7 @@ void AutoDownloadBox::resizeEvent(QResizeEvent *e) {
void AutoDownloadBox::onSave() {
bool changed = false;
int32 autoDownloadPhoto = (_photoPrivate->checked() ? 0 : dbiadNoPrivate) | (_photoGroups->checked() ? 0 : dbiadNoGroups);
int32_t autoDownloadPhoto = (_photoPrivate->checked() ? 0 : dbiadNoPrivate) | (_photoGroups->checked() ? 0 : dbiadNoGroups);
if (cAutoDownloadPhoto() != autoDownloadPhoto) {
bool enabledPrivate = ((cAutoDownloadPhoto() & dbiadNoPrivate) && !(autoDownloadPhoto & dbiadNoPrivate));
bool enabledGroups = ((cAutoDownloadPhoto() & dbiadNoGroups) && !(autoDownloadPhoto & dbiadNoGroups));
@ -316,7 +316,7 @@ void AutoDownloadBox::onSave() {
}
changed = true;
}
int32 autoDownloadAudio = (_audioPrivate->checked() ? 0 : dbiadNoPrivate) | (_audioGroups->checked() ? 0 : dbiadNoGroups);
int32_t autoDownloadAudio = (_audioPrivate->checked() ? 0 : dbiadNoPrivate) | (_audioGroups->checked() ? 0 : dbiadNoGroups);
if (cAutoDownloadAudio() != autoDownloadAudio) {
bool enabledPrivate = ((cAutoDownloadAudio() & dbiadNoPrivate) && !(autoDownloadAudio & dbiadNoPrivate));
bool enabledGroups = ((cAutoDownloadAudio() & dbiadNoGroups) && !(autoDownloadAudio & dbiadNoGroups));
@ -330,7 +330,7 @@ void AutoDownloadBox::onSave() {
}
changed = true;
}
int32 autoDownloadGif = (_gifPrivate->checked() ? 0 : dbiadNoPrivate) | (_gifGroups->checked() ? 0 : dbiadNoGroups);
int32_t autoDownloadGif = (_gifPrivate->checked() ? 0 : dbiadNoPrivate) | (_gifGroups->checked() ? 0 : dbiadNoGroups);
if (cAutoDownloadGif() != autoDownloadGif) {
bool enabledPrivate = ((cAutoDownloadGif() & dbiadNoPrivate) && !(autoDownloadGif & dbiadNoPrivate));
bool enabledGroups = ((cAutoDownloadGif() & dbiadNoGroups) && !(autoDownloadGif & dbiadNoGroups));

View File

@ -30,10 +30,10 @@ class EditColorBox::Picker : public TWidget {
public:
Picker(QWidget *parent, QColor color);
float64 valueX() const {
double valueX() const {
return _x;
}
float64 valueY() const {
double valueY() const {
return _y;
}
@ -64,8 +64,8 @@ private:
QImage _palette;
bool _paletteInvalidated = false;
float64 _x = 0.;
float64 _y = 0.;
double _x = 0.;
double _y = 0.;
bool _choosing = false;
base::Observable<void> _changed;
@ -150,8 +150,8 @@ void EditColorBox::Picker::preparePalette() {
_paletteInvalidated = false;
auto size = _palette.width();
auto ints = reinterpret_cast<uint32*>(_palette.bits());
auto intsAddPerLine = (_palette.bytesPerLine() - size * sizeof(uint32)) / sizeof(uint32);
auto ints = reinterpret_cast<uint32_t*>(_palette.bits());
auto intsAddPerLine = (_palette.bytesPerLine() - size * sizeof(uint32_t)) / sizeof(uint32_t);
constexpr auto Large = 1024 * 1024;
constexpr auto LargeBit = 20; // n / Large == (n >> LargeBit)
@ -190,8 +190,8 @@ void EditColorBox::Picker::preparePalette() {
}
void EditColorBox::Picker::updateCurrentPoint(QPoint localPosition) {
auto x = snap(localPosition.x(), 0, width()) / float64(width());
auto y = snap(localPosition.y(), 0, height()) / float64(height());
auto x = snap(localPosition.x(), 0, width()) / double(width());
auto y = snap(localPosition.y(), 0, height()) / double(height());
if (_x != x || _y != y) {
_x = x;
_y = y;
@ -236,10 +236,10 @@ public:
base::Observable<void> &changed() {
return _changed;
}
float64 value() const {
double value() const {
return _value;
}
void setValue(float64 value) {
void setValue(double value) {
_value = snap(value, 0., 1.);
update();
}
@ -256,8 +256,8 @@ protected:
void mouseReleaseEvent(QMouseEvent *e) override;
private:
float64 valueFromColor(QColor color) const;
float64 valueFromHue(int hue) const;
double valueFromColor(QColor color) const;
double valueFromHue(int hue) const;
bool isHorizontal() const {
return (_direction == Direction::Horizontal);
}
@ -271,7 +271,7 @@ private:
Type _type = Type::Hue;
QColor _color;
float64 _value = 0;
double _value = 0;
QImage _mask;
QPixmap _pixmap;
@ -339,8 +339,8 @@ void EditColorBox::Slider::generatePixmap() {
auto size = (isHorizontal() ? width() : height()) * cIntRetinaFactor();
auto image = QImage(size, cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
image.setDevicePixelRatio(cRetinaFactor());
auto ints = reinterpret_cast<uint32*>(image.bits());
auto intsPerLine = image.bytesPerLine() / sizeof(uint32);
auto ints = reinterpret_cast<uint32_t*>(image.bits());
auto intsPerLine = image.bytesPerLine() / sizeof(uint32_t);
auto intsPerLineAdded = intsPerLine - size;
constexpr auto Large = 1024 * 1024;
@ -408,11 +408,11 @@ void EditColorBox::Slider::colorUpdated() {
update();
}
float64 EditColorBox::Slider::valueFromColor(QColor color) const {
double EditColorBox::Slider::valueFromColor(QColor color) const {
return (_type == Type::Hue) ? valueFromHue(color.hsvHue()) : color.alphaF();
}
float64 EditColorBox::Slider::valueFromHue(int hue) const {
double EditColorBox::Slider::valueFromHue(int hue) const {
return (1. - snap(hue, 0, 360) / 360.);
}
@ -430,7 +430,7 @@ void EditColorBox::Slider::updatePixmapFromMask() {
void EditColorBox::Slider::updateCurrentPoint(QPoint localPosition) {
auto coord = (isHorizontal() ? localPosition.x() : localPosition.y()) - st::colorSliderSkip;
auto maximum = (isHorizontal() ? width() : height()) - 2 * st::colorSliderSkip;
auto value = snap(coord, 0, maximum) / float64(maximum);
auto value = snap(coord, 0, maximum) / double(maximum);
if (_value != value) {
_value = value;
update();
@ -909,4 +909,4 @@ void EditColorBox::setRGB(int red, int green, int blue, int alpha) {
updateControlsFromColor();
updateHSVFields();
update();
}
}

View File

@ -141,8 +141,8 @@ void PasscodeBox::paintEvent(QPaintEvent *e) {
Painter p(this);
int32 w = st::boxWidth - st::boxPadding.left() * 1.5;
int32 abouty = (_passwordHint->isHidden() ? ((_reenterPasscode->isHidden() ? (_oldPasscode->y() + (_hasRecovery && !_hintText.isEmpty() ? st::passcodeTextLine : 0)) : _reenterPasscode->y()) + st::passcodeSkip) : _passwordHint->y()) + _oldPasscode->height() + st::passcodeLittleSkip + st::passcodeAboutSkip;
int32_t w = st::boxWidth - st::boxPadding.left() * 1.5;
int32_t abouty = (_passwordHint->isHidden() ? ((_reenterPasscode->isHidden() ? (_oldPasscode->y() + (_hasRecovery && !_hintText.isEmpty() ? st::passcodeTextLine : 0)) : _reenterPasscode->y()) + st::passcodeSkip) : _passwordHint->y()) + _oldPasscode->height() + st::passcodeLittleSkip + st::passcodeAboutSkip;
p.setPen(st::boxTextFg);
_about.drawLeft(p, st::boxPadding.left(), abouty, w, width());
@ -170,7 +170,7 @@ void PasscodeBox::resizeEvent(QResizeEvent *e) {
BoxContent::resizeEvent(e);
bool has = _cloudPwd ? (!_curSalt.isEmpty()) : Global::LocalPasscode();
int32 w = st::boxWidth - st::boxPadding.left() - st::boxPadding.right();
int32_t w = st::boxWidth - st::boxPadding.left() - st::boxPadding.right();
_oldPasscode->resize(w, _oldPasscode->height());
_oldPasscode->moveToLeft(st::boxPadding.left(), st::passcodePadding.top());
_newPasscode->resize(w, _newPasscode->height());
@ -443,7 +443,7 @@ void RecoverBox::paintEvent(QPaintEvent *e) {
p.setFont(st::normalFont);
p.setPen(st::boxTextFg);
int32 w = st::boxWidth - st::boxPadding.left() * 1.5;
int32_t w = st::boxWidth - st::boxPadding.left() * 1.5;
p.drawText(QRect(st::boxPadding.left(), _recoverCode->y() - st::passcodeTextLine - st::passcodePadding.top(), w, st::passcodePadding.top() + st::passcodeTextLine), _pattern, style::al_left);
if (!_error.isEmpty()) {

View File

@ -34,9 +34,12 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "storage/file_download.h"
#include "window/themes/window_theme.h"
PeerListBox::PeerListBox(QWidget*, std::unique_ptr<PeerListController> controller, base::lambda<void(not_null<PeerListBox*>)> init)
: _controller(std::move(controller))
, _init(std::move(init)) {
PeerListBox::PeerListBox(QWidget*
, std::unique_ptr<PeerListController> controller
, base::lambda<void(not_null<PeerListBox*>)> init)
: _controller(std::move(controller))
, _init(std::move(init))
{
Expects(_controller != nullptr);
}
@ -49,7 +52,7 @@ void PeerListBox::createMultiSelect() {
_select.create(this, std::move(entity), margins, std::move(callback));
_select->entity()->setSubmittedCallback([this](bool chtrlShiftEnter) { _inner->submitted(); });
_select->entity()->setQueryChangedCallback([this](const QString &query) { searchQueryChanged(query); });
_select->entity()->setItemRemovedCallback([this](uint64 itemId) {
_select->entity()->setItemRemovedCallback([this](uint64_t itemId) {
if (auto peer = App::peerLoaded(itemId)) {
if (auto row = peerListFindRow(peer->id)) {
_inner->changeCheckState(row, false, PeerListRow::SetStyle::Animated);
@ -341,7 +344,7 @@ int PeerListBox::peerListSelectedRowsCount() {
std::vector<not_null<PeerData*>> PeerListBox::peerListCollectSelectedRows() {
auto result = std::vector<not_null<PeerData*>> {};
auto items = _select ? _select->entity()->getItems() : QVector<uint64> {};
auto items = _select ? _select->entity()->getItems() : QVector<uint64_t> {};
if (!items.empty()) {
result.reserve(items.size());
for_const (auto itemId, items) {
@ -496,7 +499,7 @@ void PeerListRow::setStatusText(const QString &text) {
_status.setText(st::defaultTextStyle, text, _textNameOptions);
}
float64 PeerListRow::checkedRatio() {
double PeerListRow::checkedRatio() {
return _checkbox ? _checkbox->checkedAnimationRatio() : 0.;
}

View File

@ -43,7 +43,7 @@ inline auto PaintUserpicCallback(PeerData *peer) {
};
}
using PeerListRowId = uint64;
using PeerListRowId = uint64_t;
class PeerListRow {
public:
PeerListRow(not_null<PeerData*> peer);
@ -139,7 +139,7 @@ public:
void stopLastRipple();
void paintRipple(Painter &p, TimeMs ms, int x, int y, int outerWidth);
void paintUserpic(Painter &p, TimeMs ms, int x, int y, int outerWidth);
float64 checkedRatio();
double checkedRatio();
void setNameFirstChars(const OrderedSet<QChar> &nameFirstChars) {
_nameFirstChars = nameFirstChars;

View File

@ -717,7 +717,7 @@ void AddBotToGroupBoxController::shareBotGame(not_null<PeerData*> chat) {
}
auto history = App::historyLoaded(chat);
auto afterRequestId = history ? history->sendRequestId : 0;
auto randomId = rand_value<uint64>();
auto randomId = rand_value<uint64_t>();
auto gameShortName = bot->botInfo->shareGameShortName;
auto inputGame = MTP_inputGameShortName(
bot->inputUser,
@ -764,7 +764,7 @@ void AddBotToGroupBoxController::addBotToGroup(not_null<PeerData*> chat) {
auto request = MTPmessages_StartBot(
bot->inputUser,
chat->input,
MTP_long(rand_value<uint64>()),
MTP_long(rand_value<uint64_t>()),
MTP_string(info->startGroupToken));
auto done = App::main()->rpcDone(
&MainWidget::sentUpdatesReceived);

View File

@ -56,7 +56,7 @@ void PhotoCropBox::prepare() {
connect(this, SIGNAL(ready(const QImage&)), this, SLOT(onReady(const QImage&)));
}
int32 s = st::boxWideWidth - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
int32_t s = st::boxWideWidth - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
_thumb = App::pixmapFromImageInPlace(_img.scaled(s * cIntRetinaFactor(), s * cIntRetinaFactor(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
_thumb.setDevicePixelRatio(cRetinaFactor());
_mask = QImage(_thumb.size(), QImage::Format_ARGB32_Premultiplied);
@ -94,7 +94,7 @@ void PhotoCropBox::mousePressEvent(QMouseEvent *e) {
int PhotoCropBox::mouseState(QPoint p) {
p -= QPoint(_thumbx, _thumby);
int32 delta = st::cropPointSize, mdelta(-delta / 2);
int32_t delta = st::cropPointSize, mdelta(-delta / 2);
if (QRect(_cropx + mdelta, _cropy + mdelta, delta, delta).contains(p)) {
return 1;
} else if (QRect(_cropx + _cropw + mdelta, _cropy + mdelta, delta, delta).contains(p)) {
@ -122,7 +122,7 @@ void PhotoCropBox::mouseMoveEvent(QMouseEvent *e) {
}
if (_downState) {
if (_downState == 1) {
int32 dx = e->pos().x() - _fromposx, dy = e->pos().y() - _fromposy, d = (dx < dy) ? dx : dy;
int32_t dx = e->pos().x() - _fromposx, dy = e->pos().y() - _fromposy, d = (dx < dy) ? dx : dy;
if (_fromcropx + d < 0) {
d = -_fromcropx;
}
@ -139,7 +139,7 @@ void PhotoCropBox::mouseMoveEvent(QMouseEvent *e) {
update();
}
} else if (_downState == 2) {
int32 dx = _fromposx - e->pos().x(), dy = e->pos().y() - _fromposy, d = (dx < dy) ? dx : dy;
int32_t dx = _fromposx - e->pos().x(), dy = e->pos().y() - _fromposy, d = (dx < dy) ? dx : dy;
if (_fromcropx + _fromcropw - d > _thumbw) {
d = _fromcropx + _fromcropw - _thumbw;
}
@ -155,7 +155,7 @@ void PhotoCropBox::mouseMoveEvent(QMouseEvent *e) {
update();
}
} else if (_downState == 3) {
int32 dx = _fromposx - e->pos().x(), dy = _fromposy - e->pos().y(), d = (dx < dy) ? dx : dy;
int32_t dx = _fromposx - e->pos().x(), dy = _fromposy - e->pos().y(), d = (dx < dy) ? dx : dy;
if (_fromcropx + _fromcropw - d > _thumbw) {
d = _fromcropx + _fromcropw - _thumbw;
}
@ -170,7 +170,7 @@ void PhotoCropBox::mouseMoveEvent(QMouseEvent *e) {
update();
}
} else if (_downState == 4) {
int32 dx = e->pos().x() - _fromposx, dy = _fromposy - e->pos().y(), d = (dx < dy) ? dx : dy;
int32_t dx = e->pos().x() - _fromposx, dy = _fromposy - e->pos().y(), d = (dx < dy) ? dx : dy;
if (_fromcropx + d < 0) {
d = -_fromcropx;
}
@ -186,7 +186,7 @@ void PhotoCropBox::mouseMoveEvent(QMouseEvent *e) {
update();
}
} else if (_downState == 5) {
int32 dx = e->pos().x() - _fromposx, dy = e->pos().y() - _fromposy;
int32_t dx = e->pos().x() - _fromposx, dy = e->pos().y() - _fromposy;
if (_fromcropx + dx < 0) {
dx = -_fromcropx;
} else if (_fromcropx + _fromcropw + dx > _thumbw) {
@ -204,7 +204,7 @@ void PhotoCropBox::mouseMoveEvent(QMouseEvent *e) {
}
}
}
int32 cursorState = _downState ? _downState : mouseState(e->pos());
int32_t cursorState = _downState ? _downState : mouseState(e->pos());
QCursor cur(style::cur_default);
if (cursorState == 1 || cursorState == 3) {
cur = style::cur_sizefdiag;
@ -260,8 +260,8 @@ void PhotoCropBox::sendPhoto() {
if (_img.width() < _thumb.width()) {
from = _thumb.toImage();
}
float64 x = float64(_cropx) / _thumbw, y = float64(_cropy) / _thumbh, w = float64(_cropw) / _thumbw;
int32 ix = int32(x * from.width()), iy = int32(y * from.height()), iw = int32(w * from.width());
double x = double(_cropx) / _thumbw, y = double(_cropy) / _thumbh, w = double(_cropw) / _thumbw;
int32_t ix = int32_t(x * from.width()), iy = int32_t(y * from.height()), iw = int32_t(w * from.width());
if (ix < 0) {
ix = 0;
}
@ -274,7 +274,7 @@ void PhotoCropBox::sendPhoto() {
if (iy + iw > from.height()) {
iw = from.height() - iy;
}
int32 offset = ix * from.depth() / 8 + iy * from.bytesPerLine();
int32_t offset = ix * from.depth() / 8 + iy * from.bytesPerLine();
QImage cropped(from.constBits() + offset, iw, iw, from.bytesPerLine(), from.format()), tosend;
if (from.format() == QImage::Format_Indexed8) {
cropped.setColorCount(from.colorCount());

View File

@ -29,7 +29,7 @@ public:
PhotoCropBox(QWidget*, const QImage &img, const PeerId &peer);
PhotoCropBox(QWidget*, const QImage &img, PeerData *peer);
int32 mouseState(QPoint p);
int32_t mouseState(QPoint p);
signals:
void ready(const QImage &tosend);
@ -51,10 +51,10 @@ private:
void sendPhoto();
QString _title;
int32 _downState = 0;
int32 _thumbx, _thumby, _thumbw, _thumbh;
int32 _cropx, _cropy, _cropw;
int32 _fromposx, _fromposy, _fromcropx, _fromcropy, _fromcropw;
int32_t _downState = 0;
int32_t _thumbx, _thumby, _thumbw, _thumbh;
int32_t _cropx, _cropy, _cropw;
int32_t _fromposx, _fromposy, _fromcropx, _fromcropy, _fromcropw;
QImage _img;
QPixmap _thumb;
QImage _mask, _fade;

View File

@ -36,7 +36,7 @@ constexpr auto kMaxRating = 5;
} // namespace
RateCallBox::RateCallBox(QWidget*, uint64 callId, uint64 callAccessHash)
RateCallBox::RateCallBox(QWidget*, uint64_t callId, uint64_t callAccessHash)
: _callId(callId)
, _callAccessHash(callAccessHash) {
}

View File

@ -33,7 +33,7 @@ class RateCallBox : public BoxContent, private MTP::Sender {
Q_OBJECT
public:
RateCallBox(QWidget*, uint64 callId, uint64 callAccessHash);
RateCallBox(QWidget*, uint64_t callId, uint64_t callAccessHash);
private slots:
void onSend();
@ -52,8 +52,8 @@ private:
void updateMaxHeight();
void ratingChanged(int value);
uint64 _callId = 0;
uint64 _callAccessHash = 0;
uint64_t _callId = 0;
uint64_t _callAccessHash = 0;
int _rating = 0;
std::vector<object_ptr<Ui::IconButton>> _stars;

View File

@ -112,9 +112,9 @@ void SendFilesBox::prepareSingleFileLayout() {
_previewWidth = qMax(image.width(), kMinPreviewWidth);
}
auto maxthumbh = qMin(qRound(1.5 * _previewWidth), st::confirmMaxHeight);
_previewHeight = qRound(originalHeight * float64(_previewWidth) / originalWidth);
_previewHeight = qRound(originalHeight * double(_previewWidth) / originalWidth);
if (_previewHeight > maxthumbh) {
_previewWidth = qRound(_previewWidth * float64(maxthumbh) / _previewHeight);
_previewWidth = qRound(_previewWidth * double(maxthumbh) / _previewHeight);
accumulate_max(_previewWidth, kMinPreviewWidth);
_previewHeight = maxthumbh;
}
@ -374,7 +374,7 @@ void SendFilesBox::paintEvent(QPaintEvent *e) {
linktop = st::msgFileThumbLinkTop;
}
auto namewidth = w - nameleft - (_fileThumb.isNull() ? st::msgFilePadding.left() : st::msgFileThumbPadding.left());
int32 x = (width() - w) / 2, y = st::boxPhotoPadding.top();
int32_t x = (width() - w) / 2, y = st::boxPhotoPadding.top();
App::roundRect(p, x, y, w, h, st::msgOutBg, MessageOutCorners, &st::msgOutShadow);
@ -493,7 +493,7 @@ EditCaptionBox::EditCaptionBox(QWidget*, HistoryMedia *media, FullMsgId msgId) :
if (image->isNull()) {
_thumbw = 0;
} else {
int32 tw = image->width(), th = image->height();
int32_t tw = image->width(), th = image->height();
if (tw > th) {
_thumbw = (tw * st::msgFileThumbSize) / th;
} else {
@ -515,10 +515,10 @@ EditCaptionBox::EditCaptionBox(QWidget*, HistoryMedia *media, FullMsgId msgId) :
_isAudio = (doc->voice() || doc->song());
}
} else {
int32 maxW = 0, maxH = 0;
int32_t maxW = 0, maxH = 0;
if (_animated) {
int32 limitW = st::boxWideWidth - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
int32 limitH = st::confirmMaxHeight;
int32_t limitW = st::boxWideWidth - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
int32_t limitH = st::confirmMaxHeight;
maxW = qMax(dimensions.width(), 1);
maxH = qMax(dimensions.height(), 1);
if (maxW * limitH > maxH * limitW) {
@ -539,7 +539,7 @@ EditCaptionBox::EditCaptionBox(QWidget*, HistoryMedia *media, FullMsgId msgId) :
maxH = dimensions.height();
_thumb = image->pixNoCache(maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), Images::Option::Smooth, maxW, maxH);
}
int32 tw = _thumb.width(), th = _thumb.height();
int32_t tw = _thumb.width(), th = _thumb.height();
if (!tw || !th) {
tw = th = 1;
}
@ -547,10 +547,10 @@ EditCaptionBox::EditCaptionBox(QWidget*, HistoryMedia *media, FullMsgId msgId) :
if (_thumb.width() < _thumbw) {
_thumbw = (_thumb.width() > 20) ? _thumb.width() : 20;
}
int32 maxthumbh = qMin(qRound(1.5 * _thumbw), int(st::confirmMaxHeight));
_thumbh = qRound(th * float64(_thumbw) / tw);
int32_t maxthumbh = qMin(qRound(1.5 * _thumbw), int(st::confirmMaxHeight));
_thumbh = qRound(th * double(_thumbw) / tw);
if (_thumbh > maxthumbh) {
_thumbw = qRound(_thumbw * float64(maxthumbh) / _thumbh);
_thumbw = qRound(_thumbw * double(maxthumbh) / _thumbh);
_thumbh = maxthumbh;
if (_thumbw < 10) {
_thumbw = 10;
@ -677,9 +677,9 @@ void EditCaptionBox::paintEvent(QPaintEvent *e) {
icon->paintInCenter(p, inner);
}
} else if (_doc) {
int32 w = width() - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
int32 h = _thumbw ? (0 + st::msgFileThumbSize + 0) : (0 + st::msgFileSize + 0);
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0;
int32_t w = width() - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
int32_t h = _thumbw ? (0 + st::msgFileThumbSize + 0) : (0 + st::msgFileSize + 0);
int32_t nameleft = 0, nametop = 0, nameright = 0, statustop = 0;
if (_thumbw) {
nameleft = 0 + st::msgFileThumbSize + st::msgFileThumbPadding.right();
nametop = st::msgFileThumbNameTop - st::msgFileThumbPadding.top();
@ -691,12 +691,12 @@ void EditCaptionBox::paintEvent(QPaintEvent *e) {
nameright = 0;
statustop = st::msgFileStatusTop - st::msgFilePadding.top();
}
int32 namewidth = w - nameleft - 0;
int32_t namewidth = w - nameleft - 0;
if (namewidth > _statusw) {
//w -= (namewidth - _statusw);
//namewidth = _statusw;
}
int32 x = (width() - w) / 2, y = st::boxPhotoPadding.top();
int32_t x = (width() - w) / 2, y = st::boxPhotoPadding.top();
// App::roundRect(p, x, y, w, h, st::msgInBg, MessageInCorners, &st::msgInShadow);

View File

@ -115,7 +115,7 @@ void SessionsBox::gotAuthorizations(const MTPaccount_Authorizations &result) {
// deviceModel = qsl("Linux");
// }
if (appVer == QString::number(appVer.toInt())) {
int32 ver = appVer.toInt();
int32_t ver = appVer.toInt();
appVer = QString("%1.%2").arg(ver / 1000000).arg((ver % 1000000) / 1000) + ((ver % 1000) ? ('.' + QString::number(ver % 1000)) : QString());
//} else {
// appVer = QString();
@ -140,7 +140,7 @@ void SessionsBox::gotAuthorizations(const MTPaccount_Authorizations &result) {
if (!data.hash || (d.vflags.v & 1)) {
data.active = lang(lng_sessions_header);
data.activeWidth = st::sessionWhenFont->width(lang(lng_sessions_header));
int32 availForName = availCurrent - st::sessionPadding.right() - data.activeWidth;
int32_t availForName = availCurrent - st::sessionPadding.right() - data.activeWidth;
if (data.nameWidth > availForName) {
data.name = st::sessionNameFont->elided(data.name, availForName);
data.nameWidth = st::sessionNameFont->width(data.name);
@ -168,7 +168,7 @@ void SessionsBox::gotAuthorizations(const MTPaccount_Authorizations &result) {
data.active = lastDate.toString(qsl("d.MM.yy"));
}
data.activeWidth = st::sessionWhenFont->width(data.active);
int32 availForName = availOther - st::sessionPadding.right() - data.activeWidth;
int32_t availForName = availOther - st::sessionPadding.right() - data.activeWidth;
if (data.nameWidth > availForName) {
data.name = st::sessionNameFont->elided(data.name, availForName);
data.nameWidth = st::sessionNameFont->width(data.name);
@ -185,7 +185,7 @@ void SessionsBox::gotAuthorizations(const MTPaccount_Authorizations &result) {
}
_list.push_back(data);
for (int32 i = _list.size(); i > 1;) {
for (int32_t i = _list.size(); i > 1;) {
--i;
if (_list.at(i).activeTime > _list.at(i - 1).activeTime) {
qSwap(_list[i], _list[i - 1]);
@ -242,8 +242,8 @@ void SessionsBox::Inner::paintEvent(QPaintEvent *e) {
Painter p(this);
p.fillRect(r, st::boxBg);
int32 x = st::sessionPadding.left(), xact = st::sessionTerminateSkip + st::sessionTerminate.iconPosition.x();// st::sessionTerminateSkip + st::sessionTerminate.width + st::sessionTerminateSkip;
int32 w = width();
int32_t x = st::sessionPadding.left(), xact = st::sessionTerminateSkip + st::sessionTerminate.iconPosition.x();// st::sessionTerminateSkip + st::sessionTerminate.width + st::sessionTerminateSkip;
int32_t w = width();
if (_current->active.isEmpty() && _list->isEmpty()) {
p.setFont(st::noContactsFont->f);
@ -277,11 +277,11 @@ void SessionsBox::Inner::paintEvent(QPaintEvent *e) {
}
p.setFont(st::linkFont->f);
int32 count = _list->size();
int32 from = floorclamp(r.y() - st::sessionCurrentHeight, st::sessionHeight, 0, count);
int32 to = ceilclamp(r.y() + r.height() - st::sessionCurrentHeight, st::sessionHeight, 0, count);
int32_t count = _list->size();
int32_t from = floorclamp(r.y() - st::sessionCurrentHeight, st::sessionHeight, 0, count);
int32_t to = ceilclamp(r.y() + r.height() - st::sessionCurrentHeight, st::sessionHeight, 0, count);
p.translate(0, from * st::sessionHeight);
for (int32 i = from; i < to; ++i) {
for (int32_t i = from; i < to; ++i) {
const SessionsBox::Data &auth(_list->at(i));
p.setFont(st::sessionNameFont);
@ -334,8 +334,8 @@ void SessionsBox::Inner::onTerminateAll() {
})), KeepOtherLayers);
}
void SessionsBox::Inner::terminateDone(uint64 hash, const MTPBool &result) {
for (int32 i = 0, l = _list->size(); i < l; ++i) {
void SessionsBox::Inner::terminateDone(uint64_t hash, const MTPBool &result) {
for (int32_t i = 0, l = _list->size(); i < l; ++i) {
if (_list->at(i).hash == hash) {
_list->removeAt(i);
break;
@ -345,7 +345,7 @@ void SessionsBox::Inner::terminateDone(uint64 hash, const MTPBool &result) {
emit oneTerminated();
}
bool SessionsBox::Inner::terminateFail(uint64 hash, const RPCError &error) {
bool SessionsBox::Inner::terminateFail(uint64_t hash, const RPCError &error) {
if (MTP::isDefaultHandledError(error)) return false;
TerminateButtons::iterator i = _terminateButtons.find(hash);
@ -379,7 +379,7 @@ void SessionsBox::Inner::listUpdated() {
for (TerminateButtons::iterator i = _terminateButtons.begin(), e = _terminateButtons.end(); i != e; ++i) {
i.value()->move(0, -1);
}
for (int32 i = 0, l = _list->size(); i < l; ++i) {
for (int32_t i = 0, l = _list->size(); i < l; ++i) {
TerminateButtons::iterator j = _terminateButtons.find(_list->at(i).hash);
if (j == _terminateButtons.cend()) {
j = _terminateButtons.insert(_list->at(i).hash, new Ui::IconButton(this, st::sessionTerminate));

View File

@ -52,10 +52,10 @@ private slots:
private:
void setLoading(bool loading);
struct Data {
uint64 hash;
uint64_t hash;
int32 activeTime;
int32 nameWidth, activeWidth, infoWidth, ipWidth;
int32_t activeTime;
int32_t nameWidth, activeWidth, infoWidth, ipWidth;
QString name, active, info, ip;
};
using List = QList<Data>;
@ -98,8 +98,8 @@ public slots:
void onTerminateAll();
private:
void terminateDone(uint64 hash, const MTPBool &result);
bool terminateFail(uint64 hash, const RPCError &error);
void terminateDone(uint64_t hash, const MTPBool &result);
bool terminateFail(uint64_t hash, const RPCError &error);
void terminateAllDone(const MTPBool &res);
bool terminateAllFail(const RPCError &error);
@ -107,7 +107,7 @@ private:
SessionsBox::List *_list;
SessionsBox::Data *_current;
typedef QMap<uint64, Ui::IconButton*> TerminateButtons;
typedef QMap<uint64_t, Ui::IconButton*> TerminateButtons;
TerminateButtons _terminateButtons;
object_ptr<Ui::LinkButton> _terminateAll;

View File

@ -64,7 +64,7 @@ void ShareBox::prepare() {
setDimensions(st::boxWideWidth, st::boxMaxListHeight);
_select->setQueryChangedCallback([this](const QString &query) { onFilterUpdate(query); });
_select->setItemRemovedCallback([this](uint64 itemId) {
_select->setItemRemovedCallback([this](uint64_t itemId) {
if (auto peer = App::peerLoaded(itemId)) {
_inner->peerUnselected(peer);
onSelectedChanged();
@ -481,7 +481,7 @@ ShareBox::Inner::Chat *ShareBox::Inner::getChat(Dialogs::Row *row) {
void ShareBox::Inner::setActive(int active) {
if (active != _active) {
auto changeNameFg = [this](int index, float64 from, float64 to) {
auto changeNameFg = [this](int index, double from, double to) {
if (auto chat = getChatAtIndex(index)) {
chat->nameActive.start([this, peer = chat->peer] {
repaintChat(peer);
@ -620,7 +620,7 @@ void ShareBox::Inner::onSelectActive() {
}
void ShareBox::Inner::resizeEvent(QResizeEvent *e) {
_columnSkip = (width() - _columnCount * st::sharePhotoCheckbox.imageRadius * 2) / float64(_columnCount + 1);
_columnSkip = (width() - _columnCount * st::sharePhotoCheckbox.imageRadius * 2) / double(_columnCount + 1);
_rowWidthReal = st::sharePhotoCheckbox.imageRadius * 2 + _columnSkip;
_rowsLeft = qFloor(_columnSkip / 2);
_rowWidth = qFloor(_rowWidthReal);
@ -743,7 +743,7 @@ void ShareBox::Inner::updateFilter(QString filter) {
void ShareBox::Inner::peopleReceived(const QString &query, const QVector<MTPPeer> &people) {
_lastQuery = query.toLower().trimmed();
if (_lastQuery.at(0) == '@') _lastQuery = _lastQuery.mid(1);
int32 already = _byUsernameFiltered.size();
int32_t already = _byUsernameFiltered.size();
_byUsernameFiltered.reserve(already + people.size());
d_byUsernameFiltered.reserve(already + people.size());
for_const (auto &mtpPeer, people) {
@ -800,10 +800,10 @@ QVector<PeerData*> ShareBox::Inner::selected() const {
QString AppendShareGameScoreUrl(const QString &url, const FullMsgId &fullId) {
auto shareHashData = QByteArray(0x10, Qt::Uninitialized);
auto shareHashDataInts = reinterpret_cast<int32*>(shareHashData.data());
auto shareHashDataInts = reinterpret_cast<int32_t*>(shareHashData.data());
auto channel = fullId.channel ? App::channelLoaded(fullId.channel) : static_cast<ChannelData*>(nullptr);
auto channelAccessHash = channel ? channel->access : 0ULL;
auto channelAccessHashInts = reinterpret_cast<int32*>(&channelAccessHash);
auto channelAccessHashInts = reinterpret_cast<int32_t*>(&channelAccessHash);
shareHashDataInts[0] = Auth().userId();
shareHashDataInts[1] = fullId.channel;
shareHashDataInts[2] = fullId.msg;
@ -815,7 +815,7 @@ QString AppendShareGameScoreUrl(const QString &url, const FullMsgId &fullId) {
hashSha1(shareHashData.constData(), shareHashData.size(), shareHashEncrypted.data());
// Mix in channel access hash to the first 64 bits of SHA1 of data.
*reinterpret_cast<uint64*>(shareHashEncrypted.data()) ^= *reinterpret_cast<uint64*>(channelAccessHashInts);
*reinterpret_cast<uint64_t*>(shareHashEncrypted.data()) ^= *reinterpret_cast<uint64_t*>(channelAccessHashInts);
// Encrypt data.
if (!Local::encrypt(shareHashData.constData(), shareHashEncrypted.data() + key128Size, shareHashData.size(), shareHashEncrypted.constData())) {
@ -861,7 +861,7 @@ void ShareGameScoreByHash(const QString &hash) {
hashSha1(hashData.constData(), hashData.size(), dataSha1);
// Mix out channel access hash from the first 64 bits of SHA1 of data.
auto channelAccessHash = *reinterpret_cast<uint64*>(hashEncrypted.data()) ^ *reinterpret_cast<uint64*>(dataSha1);
auto channelAccessHash = *reinterpret_cast<uint64_t*>(hashEncrypted.data()) ^ *reinterpret_cast<uint64_t*>(dataSha1);
// Check next 64 bits of SHA1() of data.
auto skipSha1Part = sizeof(channelAccessHash);
@ -870,14 +870,14 @@ void ShareGameScoreByHash(const QString &hash) {
return;
}
auto hashDataInts = reinterpret_cast<int32*>(hashData.data());
auto hashDataInts = reinterpret_cast<int32_t*>(hashData.data());
if (!AuthSession::Exists() || hashDataInts[0] != Auth().userId()) {
Ui::show(Box<InformBox>(lang(lng_share_wrong_user)));
return;
}
// Check first 32 bits of channel access hash.
auto channelAccessHashInts = reinterpret_cast<int32*>(&channelAccessHash);
auto channelAccessHashInts = reinterpret_cast<int32_t*>(&channelAccessHash);
if (channelAccessHashInts[0] != hashDataInts[3]) {
Ui::show(Box<InformBox>(lang(lng_share_wrong_user)));
return;

View File

@ -182,8 +182,8 @@ private:
void refresh();
float64 _columnSkip = 0.;
float64 _rowWidthReal = 0.;
double _columnSkip = 0.;
double _rowWidthReal = 0.;
int _rowsLeft = 0;
int _rowsTop = 0;
int _rowWidth = 0;

View File

@ -56,10 +56,10 @@ void StickerSetBox::prepare() {
onUpdateButtons();
connect(_inner, SIGNAL(updateButtons()), this, SLOT(onUpdateButtons()));
connect(_inner, SIGNAL(installed(uint64)), this, SLOT(onInstalled(uint64)));
connect(_inner, SIGNAL(installed(uint64_t)), this, SLOT(onInstalled(uint64_t)));
}
void StickerSetBox::onInstalled(uint64 setId) {
void StickerSetBox::onInstalled(uint64_t setId) {
emit installed(setId);
closeBox();
}
@ -180,7 +180,7 @@ void StickerSetBox::Inner::gotSet(const MTPmessages_StickerSet &set) {
if (_pack.isEmpty()) {
Ui::show(Box<InformBox>(lang(lng_stickers_not_found)));
} else {
int32 rows = _pack.size() / kStickersPanelPerRow + ((_pack.size() % kStickersPanelPerRow) ? 1 : 0);
int32_t rows = _pack.size() / kStickersPanelPerRow + ((_pack.size() % kStickersPanelPerRow) ? 1 : 0);
resize(st::stickersPadding.left() + kStickersPanelPerRow * st::stickersSize.width(), st::stickersPadding.top() + rows * st::stickersSize.height() + st::stickersPadding.bottom());
}
_loaded = true;
@ -315,7 +315,7 @@ void StickerSetBox::Inner::setSelected(int selected) {
}
}
void StickerSetBox::Inner::startOverAnimation(int index, float64 from, float64 to) {
void StickerSetBox::Inner::startOverAnimation(int index, double from, double to) {
if (index >= 0 && index < _packOvers.size()) {
_packOvers[index].start([this, index] {
int row = index / kStickersPanelPerRow;
@ -335,13 +335,13 @@ void StickerSetBox::Inner::onPreview() {
}
}
int32 StickerSetBox::Inner::stickerFromGlobalPos(const QPoint &p) const {
int32_t StickerSetBox::Inner::stickerFromGlobalPos(const QPoint &p) const {
QPoint l(mapFromGlobal(p));
if (rtl()) l.setX(width() - l.x());
int32 row = (l.y() >= st::stickersPadding.top()) ? qFloor((l.y() - st::stickersPadding.top()) / st::stickersSize.height()) : -1;
int32 col = (l.x() >= st::stickersPadding.left()) ? qFloor((l.x() - st::stickersPadding.left()) / st::stickersSize.width()) : -1;
int32_t row = (l.y() >= st::stickersPadding.top()) ? qFloor((l.y() - st::stickersPadding.top()) / st::stickersSize.height()) : -1;
int32_t col = (l.x() >= st::stickersPadding.left()) ? qFloor((l.x() - st::stickersPadding.left()) / st::stickersSize.width()) : -1;
if (row >= 0 && col >= 0 && col < kStickersPanelPerRow) {
int32 result = row * kStickersPanelPerRow + col;
int32_t result = row * kStickersPanelPerRow + col;
return (result < _pack.size()) ? result : -1;
}
return -1;
@ -354,12 +354,12 @@ void StickerSetBox::Inner::paintEvent(QPaintEvent *e) {
if (_pack.isEmpty()) return;
auto ms = getms();
int32 rows = _pack.size() / kStickersPanelPerRow + ((_pack.size() % kStickersPanelPerRow) ? 1 : 0);
int32 from = qFloor(e->rect().top() / st::stickersSize.height()), to = qFloor(e->rect().bottom() / st::stickersSize.height()) + 1;
int32_t rows = _pack.size() / kStickersPanelPerRow + ((_pack.size() % kStickersPanelPerRow) ? 1 : 0);
int32_t from = qFloor(e->rect().top() / st::stickersSize.height()), to = qFloor(e->rect().bottom() / st::stickersSize.height()) + 1;
for (int32 i = from; i < to; ++i) {
for (int32 j = 0; j < kStickersPanelPerRow; ++j) {
int32 index = i * kStickersPanelPerRow + j;
for (int32_t i = from; i < to; ++i) {
for (int32_t j = 0; j < kStickersPanelPerRow; ++j) {
int32_t index = i * kStickersPanelPerRow + j;
if (index >= _pack.size()) break;
Assert(index < _packOvers.size());
@ -386,9 +386,9 @@ void StickerSetBox::Inner::paintEvent(QPaintEvent *e) {
}
}
float64 coef = qMin((st::stickersSize.width() - st::buttonRadius * 2) / float64(doc->dimensions.width()), (st::stickersSize.height() - st::buttonRadius * 2) / float64(doc->dimensions.height()));
double coef = qMin((st::stickersSize.width() - st::buttonRadius * 2) / double(doc->dimensions.width()), (st::stickersSize.height() - st::buttonRadius * 2) / double(doc->dimensions.height()));
if (coef > 1) coef = 1;
int32 w = qRound(coef * doc->dimensions.width()), h = qRound(coef * doc->dimensions.height());
int32_t w = qRound(coef * doc->dimensions.width()), h = qRound(coef * doc->dimensions.height());
if (w < 1) w = 1;
if (h < 1) h = 1;
QPoint ppos = pos + QPoint((st::stickersSize.width() - w) / 2, (st::stickersSize.height() - h) / 2);
@ -410,7 +410,7 @@ bool StickerSetBox::Inner::loaded() const {
return _loaded && !_pack.isEmpty();
}
int32 StickerSetBox::Inner::notInstalled() const {
int32_t StickerSetBox::Inner::notInstalled() const {
if (!_loaded) return 0;
auto it = Global::StickerSets().constFind(_setId);
if (it == Global::StickerSets().cend() || !(it->flags & MTPDstickerSet::Flag::f_installed) || (it->flags & MTPDstickerSet::Flag::f_archived)) return _pack.size();

View File

@ -36,7 +36,7 @@ public:
StickerSetBox(QWidget*, const MTPInputStickerSet &set);
signals:
void installed(uint64 id);
void installed(uint64_t id);
protected:
void prepare() override;
@ -48,7 +48,7 @@ private slots:
void onShareStickers();
void onUpdateButtons();
void onInstalled(uint64 id);
void onInstalled(uint64_t id);
private:
void updateButtons();
@ -68,7 +68,7 @@ public:
Inner(QWidget *parent, const MTPInputStickerSet &set);
bool loaded() const;
int32 notInstalled() const;
int32_t notInstalled() const;
bool official() const;
base::lambda<TextWithEntities()> title() const;
QString shortName() const;
@ -90,12 +90,12 @@ private slots:
signals:
void updateButtons();
void installed(uint64 id);
void installed(uint64_t id);
private:
void updateSelected();
void setSelected(int selected);
void startOverAnimation(int index, float64 from, float64 to);
void startOverAnimation(int index, double from, double to);
int stickerFromGlobalPos(const QPoint &p) const;
void gotSet(const MTPmessages_StickerSet &set);
@ -112,11 +112,11 @@ private:
StickerPack _pack;
StickersByEmojiMap _emoji;
bool _loaded = false;
uint64 _setId = 0;
uint64 _setAccess = 0;
uint64_t _setId = 0;
uint64_t _setAccess = 0;
QString _setTitle, _setShortName;
int32 _setCount = 0;
int32 _setHash = 0;
int32_t _setCount = 0;
int32_t _setHash = 0;
MTPDstickerSet::Flags _setFlags = 0;
int _visibleTop = 0;

View File

@ -156,7 +156,7 @@ StickersBox::StickersBox(QWidget*, not_null<ChannelData*> megagroup)
subscribe(_installed.widget()->scrollToY, [this](int y) { onScrollToY(y); });
}
void StickersBox::getArchivedDone(uint64 offsetId, const MTPmessages_ArchivedStickers &result) {
void StickersBox::getArchivedDone(uint64_t offsetId, const MTPmessages_ArchivedStickers &result) {
_archivedRequestId = 0;
_archivedLoaded = true;
if (result.type() != mtpc_messages_archivedStickers) {
@ -253,10 +253,10 @@ void StickersBox::prepare() {
if (_archived.widget() && _section != Section::Archived) _archived.widget()->hide();
if (_featured.widget()) {
_featured.widget()->setInstallSetCallback([this](uint64 setId) { installSet(setId); });
_featured.widget()->setInstallSetCallback([this](uint64_t setId) { installSet(setId); });
}
if (_archived.widget()) {
_archived.widget()->setInstallSetCallback([this](uint64 setId) { installSet(setId); });
_archived.widget()->setInstallSetCallback([this](uint64_t setId) { installSet(setId); });
_archived.widget()->setLoadMoreCallback([this] { loadMoreArchived(); });
}
@ -326,7 +326,7 @@ void StickersBox::loadMoreArchived() {
return;
}
uint64 lastId = 0;
uint64_t lastId = 0;
for (auto setIt = Global::ArchivedStickerSetsOrder().cend(), e = Global::ArchivedStickerSetsOrder().cbegin(); setIt != e;) {
--setIt;
auto it = Global::StickerSets().constFind(*setIt);
@ -441,7 +441,7 @@ QPixmap StickersBox::grabContentCache() {
return result;
}
void StickersBox::installSet(uint64 setId) {
void StickersBox::installSet(uint64_t setId) {
auto &sets = Global::RefStickerSets();
auto it = sets.find(setId);
if (it == sets.cend()) {
@ -468,7 +468,7 @@ void StickersBox::installDone(const MTPmessages_StickerSetInstallResult &result)
}
}
bool StickersBox::installFail(uint64 setId, const RPCError &error) {
bool StickersBox::installFail(uint64_t setId, const RPCError &error) {
if (MTP::isDefaultHandledError(error)) return false;
auto &sets = Global::RefStickerSets();
@ -568,7 +568,7 @@ void StickersBox::setInnerFocus() {
StickersBox::~StickersBox() = default;
StickersBox::Inner::Row::Row(uint64 id, DocumentData *sticker, int32 count, const QString &title, int titleWidth, bool installed, bool official, bool unread, bool archived, bool removed, int32 pixw, int32 pixh) : id(id)
StickersBox::Inner::Row::Row(uint64_t id, DocumentData *sticker, int32_t count, const QString &title, int titleWidth, bool installed, bool official, bool unread, bool archived, bool removed, int32_t pixw, int32_t pixh) : id(id)
, sticker(sticker)
, count(count)
, title(title)
@ -654,11 +654,11 @@ void StickersBox::Inner::paintEvent(QPaintEvent *e) {
} else {
p.translate(0, _itemsTop);
int32 yFrom = clip.y() - _itemsTop, yTo = clip.y() + clip.height() - _itemsTop;
int32 from = floorclamp(yFrom - _rowHeight, _rowHeight, 0, _rows.size());
int32 to = ceilclamp(yTo + _rowHeight, _rowHeight, 0, _rows.size());
int32_t yFrom = clip.y() - _itemsTop, yTo = clip.y() + clip.height() - _itemsTop;
int32_t from = floorclamp(yFrom - _rowHeight, _rowHeight, 0, _rows.size());
int32_t to = ceilclamp(yTo + _rowHeight, _rowHeight, 0, _rows.size());
p.translate(0, from * _rowHeight);
for (int32 i = from; i < to; ++i) {
for (int32_t i = from; i < to; ++i) {
if (i != _above) {
paintRow(p, _rows[i].get(), i, ms);
}
@ -957,14 +957,14 @@ void StickersBox::Inner::onUpdateSelected() {
}
if (_dragStart.y() > local.y() && _dragging > 0) {
shift = -floorclamp(_dragStart.y() - local.y() + (_rowHeight / 2), _rowHeight, 0, _dragging - firstSetIndex);
for (int32 from = _dragging, to = _dragging + shift; from > to; --from) {
for (int32_t from = _dragging, to = _dragging + shift; from > to; --from) {
qSwap(_rows[from], _rows[from - 1]);
_rows[from]->yadd = anim::value(_rows[from]->yadd.current() - _rowHeight, 0);
_animStartTimes[from] = ms;
}
} else if (_dragStart.y() < local.y() && _dragging + 1 < _rows.size()) {
shift = floorclamp(local.y() - _dragStart.y() + (_rowHeight / 2), _rowHeight, 0, _rows.size() - _dragging - 1);
for (int32 from = _dragging, to = _dragging + shift; from < to; ++from) {
for (int32_t from = _dragging, to = _dragging + shift; from < to; ++from) {
qSwap(_rows[from], _rows[from + 1]);
_rows[from]->yadd = anim::value(_rows[from]->yadd.current() + _rowHeight, 0);
_animStartTimes[from] = ms;
@ -1033,7 +1033,7 @@ void StickersBox::Inner::onUpdateSelected() {
}
}
float64 StickersBox::Inner::aboveShadowOpacity() const {
double StickersBox::Inner::aboveShadowOpacity() const {
if (_above < 0) return 0;
auto dx = 0;
@ -1126,7 +1126,7 @@ void StickersBox::Inner::step_shifting(TimeMs ms, bool timer) {
if (updateMin < 0) updateMin = i;
updateMax = i;
if (start + st::stickersRowDuration > ms && ms >= start) {
_rows[i]->yadd.update(float64(ms - start) / st::stickersRowDuration, anim::sineInOut);
_rows[i]->yadd.update(double(ms - start) / st::stickersRowDuration, anim::sineInOut);
animating = true;
} else {
_rows[i]->yadd.finish();
@ -1138,7 +1138,7 @@ void StickersBox::Inner::step_shifting(TimeMs ms, bool timer) {
if (updateMin < 0 || updateMin > _above) updateMin = _above;
if (updateMax < _above) updateMin = _above;
if (_aboveShadowFadeStart + st::stickersRowDuration > ms && ms > _aboveShadowFadeStart) {
_aboveShadowFadeOpacity.update(float64(ms - _aboveShadowFadeStart) / st::stickersRowDuration, anim::sineInOut);
_aboveShadowFadeOpacity.update(double(ms - _aboveShadowFadeStart) / st::stickersRowDuration, anim::sineInOut);
animating = true;
} else {
_aboveShadowFadeOpacity.finish();
@ -1179,7 +1179,7 @@ void StickersBox::Inner::clear() {
update();
}
void StickersBox::Inner::setActionSel(int32 actionSel) {
void StickersBox::Inner::setActionSel(int32_t actionSel) {
if (actionSel != _actionSel) {
if (_actionSel >= 0) update(0, _itemsTop + _actionSel * _rowHeight, width(), _rowHeight);
_actionSel = actionSel;
@ -1502,7 +1502,7 @@ Stickers::Order StickersBox::Inner::getRemovedSets() const {
});
}
int StickersBox::Inner::getRowIndex(uint64 setId) const {
int StickersBox::Inner::getRowIndex(uint64_t setId) const {
for (auto i = 0, count = int(_rows.size()); i != count; ++i) {
auto &row = _rows[i];
if (row->id == setId) {

View File

@ -96,19 +96,19 @@ private:
void rebuildList(Tab *tab = nullptr);
void updateTabsGeometry();
void switchTab();
void installSet(uint64 setId);
void installSet(uint64_t setId);
int getTopSkip() const;
void saveChanges();
QPixmap grabContentCache();
void installDone(const MTPmessages_StickerSetInstallResult &result);
bool installFail(uint64 setId, const RPCError &error);
bool installFail(uint64_t setId, const RPCError &error);
void preloadArchivedSets();
void requestArchivedSets();
void loadMoreArchived();
void getArchivedDone(uint64 offsetId, const MTPmessages_ArchivedStickers &result);
void getArchivedDone(uint64_t offsetId, const MTPmessages_ArchivedStickers &result);
object_ptr<Ui::SettingsSlider> _tabs = { nullptr };
QList<Section> _tabIndices;
@ -166,7 +166,7 @@ public:
void setFullOrder(const Stickers::Order &order);
void setRemovedSets(const Stickers::Order &removed);
void setInstallSetCallback(base::lambda<void(uint64 setId)> callback) {
void setInstallSetCallback(base::lambda<void(uint64_t setId)> callback) {
_installSetCallback = std::move(callback);
}
void setLoadMoreCallback(base::lambda<void()> callback) {
@ -199,15 +199,15 @@ public slots:
private:
struct Row {
Row(uint64 id, DocumentData *sticker, int32 count, const QString &title, int titleWidth, bool installed, bool official, bool unread, bool archived, bool removed, int32 pixw, int32 pixh);
Row(uint64_t id, DocumentData *sticker, int32_t count, const QString &title, int titleWidth, bool installed, bool official, bool unread, bool archived, bool removed, int32_t pixw, int32_t pixh);
bool isRecentSet() const {
return (id == Stickers::CloudRecentSetId);
}
~Row();
uint64 id = 0;
uint64_t id = 0;
DocumentData *sticker = nullptr;
int32 count = 0;
int32_t count = 0;
QString title;
int titleWidth = 0;
bool installed = false;
@ -215,8 +215,8 @@ private:
bool unread = false;
bool archived = false;
bool removed = false;
int32 pixw = 0;
int32 pixh = 0;
int32_t pixw = 0;
int32_t pixh = 0;
anim::value yadd;
std::unique_ptr<Ui::RippleAnimation> ripple;
};
@ -226,7 +226,7 @@ private:
void checkLoadMore();
void updateScrollbarWidth();
int getRowIndex(uint64 setId) const;
int getRowIndex(uint64_t setId) const;
void setRowRemoved(int index, bool removed);
void setSelected(int selected);
@ -240,8 +240,8 @@ private:
void paintRow(Painter &p, Row *set, int index, TimeMs ms);
void paintFakeButton(Painter &p, Row *set, int index, TimeMs ms);
void clear();
void setActionSel(int32 actionSel);
float64 aboveShadowOpacity() const;
void setActionSel(int32_t actionSel);
double aboveShadowOpacity() const;
void readVisibleSets();
@ -259,7 +259,7 @@ private:
Section _section;
int32 _rowHeight;
int32_t _rowHeight;
std::vector<std::unique_ptr<Row>> _rows;
QList<TimeMs> _animStartTimes;
@ -267,7 +267,7 @@ private:
anim::value _aboveShadowFadeOpacity;
BasicAnimation _a_shifting;
base::lambda<void(uint64 setId)> _installSetCallback;
base::lambda<void(uint64_t setId)> _installSetCallback;
base::lambda<void()> _loadMoreCallback;
int _visibleTop = 0;

View File

@ -79,10 +79,10 @@ void UsernameBox::paintEvent(QPaintEvent *e) {
p.drawTextLeft(st::usernamePadding.left(), _username->y() + _username->height() + ((st::usernameSkip - st::boxTextFont->height) / 2), width(), lang(lng_username_choose));
}
p.setPen(st::boxTextFg);
int32 availw = st::boxWidth - st::usernamePadding.left(), h = _about.countHeight(availw);
int32_t availw = st::boxWidth - st::usernamePadding.left(), h = _about.countHeight(availw);
_about.drawLeft(p, st::usernamePadding.left(), _username->y() + _username->height() + st::usernameSkip, availw, width());
int32 linky = _username->y() + _username->height() + st::usernameSkip + h + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2);
int32_t linky = _username->y() + _username->height() + st::usernameSkip + h + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2);
if (_link->isHidden()) {
p.drawTextLeft(st::usernamePadding.left(), linky, width(), lang(lng_username_link_willbe));
p.setPen(st::usernameDefaultFg);
@ -98,8 +98,8 @@ void UsernameBox::resizeEvent(QResizeEvent *e) {
_username->resize(width() - st::usernamePadding.left() - st::usernamePadding.right(), _username->height());
_username->moveToLeft(st::usernamePadding.left(), st::usernamePadding.top());
int32 availw = st::boxWidth - st::usernamePadding.left(), h = _about.countHeight(availw);
int32 linky = _username->y() + _username->height() + st::usernameSkip + h + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2);
int32_t availw = st::boxWidth - st::usernamePadding.left(), h = _about.countHeight(availw);
int32_t linky = _username->y() + _username->height() + st::usernameSkip + h + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2);
_link->moveToLeft(st::usernamePadding.left(), linky + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2));
}
@ -131,8 +131,8 @@ void UsernameBox::onChanged() {
}
_checkTimer->stop();
} else {
int32 len = name.size();
for (int32 i = 0; i < len; ++i) {
int32_t len = name.size();
for (int32_t i = 0; i < len; ++i) {
QChar ch = name.at(i);
if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z') && (ch < '0' || ch > '9') && ch != '_' && (ch != '@' || i > 0)) {
if (_errorText != lang(lng_username_bad_symbols)) {
@ -243,4 +243,4 @@ void UsernameBox::updateLinkText() {
update();
}
}
}
}

View File

@ -63,16 +63,16 @@ void ConvertEndpoint(std::vector<tgvoip::Endpoint> &ep, const MTPDphoneConnectio
}
constexpr auto kFingerprintDataSize = 256;
uint64 ComputeFingerprint(const std::array<gsl::byte, kFingerprintDataSize> &authKey) {
uint64_t ComputeFingerprint(const std::array<gsl::byte, kFingerprintDataSize> &authKey) {
auto hash = openssl::Sha1(authKey);
return (gsl::to_integer<uint64>(hash[19]) << 56)
| (gsl::to_integer<uint64>(hash[18]) << 48)
| (gsl::to_integer<uint64>(hash[17]) << 40)
| (gsl::to_integer<uint64>(hash[16]) << 32)
| (gsl::to_integer<uint64>(hash[15]) << 24)
| (gsl::to_integer<uint64>(hash[14]) << 16)
| (gsl::to_integer<uint64>(hash[13]) << 8)
| (gsl::to_integer<uint64>(hash[12]));
return (gsl::to_integer<uint64_t>(hash[19]) << 56)
| (gsl::to_integer<uint64_t>(hash[18]) << 48)
| (gsl::to_integer<uint64_t>(hash[17]) << 40)
| (gsl::to_integer<uint64_t>(hash[16]) << 32)
| (gsl::to_integer<uint64_t>(hash[15]) << 24)
| (gsl::to_integer<uint64_t>(hash[14]) << 16)
| (gsl::to_integer<uint64_t>(hash[13]) << 8)
| (gsl::to_integer<uint64_t>(hash[12]));
}
} // namespace
@ -137,7 +137,7 @@ void Call::startOutgoing() {
Expects(_type == Type::Outgoing);
Expects(_state == State::Requesting);
request(MTPphone_RequestCall(_user->inputUser, MTP_int(rand_value<int32>()), MTP_bytes(_gaHash), MTP_phoneCallProtocol(MTP_flags(MTPDphoneCallProtocol::Flag::f_udp_p2p | MTPDphoneCallProtocol::Flag::f_udp_reflector), MTP_int(kMinLayer), MTP_int(kMaxLayer)))).done([this](const MTPphone_PhoneCall &result) {
request(MTPphone_RequestCall(_user->inputUser, MTP_int(rand_value<int32_t>()), MTP_bytes(_gaHash), MTP_phoneCallProtocol(MTP_flags(MTPDphoneCallProtocol::Flag::f_udp_p2p | MTPDphoneCallProtocol::Flag::f_udp_reflector), MTP_int(kMinLayer), MTP_int(kMaxLayer)))).done([this](const MTPphone_PhoneCall &result) {
Expects(result.type() == mtpc_phone_phoneCall);
setState(State::Waiting);
@ -267,7 +267,7 @@ void Call::startWaitingTrack() {
_waitingTrack->playInLoop();
}
float64 Call::getWaitingSoundPeakValue() const {
double Call::getWaitingSoundPeakValue() const {
if (_waitingTrack) {
auto when = getms() + kSoundSampleMs / 4;
return _waitingTrack->getPeakValue(when);

View File

@ -38,8 +38,8 @@ class VoIPController;
namespace Calls {
struct DhConfig {
int32 version = 0;
int32 g = 0;
int32_t version = 0;
int32_t g = 0;
std::vector<gsl::byte> p;
};
@ -115,7 +115,7 @@ public:
}
TimeMs getDurationMs() const;
float64 getWaitingSoundPeakValue() const;
double getWaitingSoundPeakValue() const;
void answer();
void hangup();
@ -179,9 +179,9 @@ private:
MTP::AuthKey::Data _authKey;
MTPPhoneCallProtocol _protocol;
uint64 _id = 0;
uint64 _accessHash = 0;
uint64 _keyFingerprint = 0;
uint64_t _id = 0;
uint64_t _accessHash = 0;
uint64_t _keyFingerprint = 0;
std::unique_ptr<tgvoip::VoIPController> _controller;

View File

@ -112,16 +112,16 @@ ushort Offsets[] = {
620, 622, 624, 626, 628, 630, 632, 634, 636, 638, 640, 641,
642, 643, 644, 646, 648, 650, 652, 654, 656, 658 };
uint64 ComputeEmojiIndex(base::const_byte_span bytes) {
uint64_t ComputeEmojiIndex(base::const_byte_span bytes) {
Expects(bytes.size() == 8);
return ((gsl::to_integer<uint64>(bytes[0]) & 0x7F) << 56)
| (gsl::to_integer<uint64>(bytes[1]) << 48)
| (gsl::to_integer<uint64>(bytes[2]) << 40)
| (gsl::to_integer<uint64>(bytes[3]) << 32)
| (gsl::to_integer<uint64>(bytes[4]) << 24)
| (gsl::to_integer<uint64>(bytes[5]) << 16)
| (gsl::to_integer<uint64>(bytes[6]) << 8)
| (gsl::to_integer<uint64>(bytes[7]));
return ((gsl::to_integer<uint64_t>(bytes[0]) & 0x7F) << 56)
| (gsl::to_integer<uint64_t>(bytes[1]) << 48)
| (gsl::to_integer<uint64_t>(bytes[2]) << 40)
| (gsl::to_integer<uint64_t>(bytes[3]) << 32)
| (gsl::to_integer<uint64_t>(bytes[4]) << 24)
| (gsl::to_integer<uint64_t>(bytes[5]) << 16)
| (gsl::to_integer<uint64_t>(bytes[6]) << 8)
| (gsl::to_integer<uint64_t>(bytes[7]));
}
} // namespace

View File

@ -49,8 +49,8 @@ class Panel::Button : public Ui::RippleButton {
public:
Button(QWidget *parent, const style::CallButton &stFrom, const style::CallButton *stTo = nullptr);
void setProgress(float64 progress);
void setOuterValue(float64 value);
void setProgress(double progress);
void setOuterValue(double value);
protected:
void paintEvent(QPaintEvent *e) override;
@ -66,13 +66,13 @@ private:
not_null<const style::CallButton*> _stFrom;
const style::CallButton *_stTo = nullptr;
float64 _progress = 0.;
double _progress = 0.;
QImage _bgMask, _bg;
QPixmap _bgFrom, _bgTo;
QImage _iconMixedMask, _iconFrom, _iconTo, _iconMixed;
float64 _outerValue = 0.;
double _outerValue = 0.;
Animation _outerAnimation;
};
@ -114,7 +114,7 @@ Panel::Button::Button(QWidget *parent, const style::CallButton &stFrom, const st
}
}
void Panel::Button::setOuterValue(float64 value) {
void Panel::Button::setOuterValue(double value) {
if (_outerValue != value) {
_outerAnimation.start([this] {
if (_progress == 0. || _progress == 1.) {
@ -125,7 +125,7 @@ void Panel::Button::setOuterValue(float64 value) {
}
}
void Panel::Button::setProgress(float64 progress) {
void Panel::Button::setProgress(double progress) {
_progress = progress;
update();
}
@ -208,7 +208,7 @@ void Panel::Button::mixIconMasks() {
Painter p(&_iconMixedMask);
PainterHighQualityEnabler hq(p);
auto paintIconMask = [this, &p](const QImage &mask, float64 angle) {
auto paintIconMask = [this, &p](const QImage &mask, double angle) {
auto skipFrom = _stFrom->button.rippleAreaSize / 2;
p.translate(skipFrom, skipFrom);
p.rotate(angle);

View File

@ -60,7 +60,7 @@ int BotKeyboard::Style::buttonRadius() const {
return st::buttonRadius;
}
void BotKeyboard::Style::paintButtonBg(Painter &p, const QRect &rect, float64 howMuchOver) const {
void BotKeyboard::Style::paintButtonBg(Painter &p, const QRect &rect, double howMuchOver) const {
App::roundRect(p, rect, st::botKbBg, BotKeyboardCorners);
}

View File

@ -95,7 +95,7 @@ private:
void repaint(not_null<const HistoryItem*> item) const override;
protected:
void paintButtonBg(Painter &p, const QRect &rect, float64 howMuchOver) const override;
void paintButtonBg(Painter &p, const QRect &rect, double howMuchOver) const override;
void paintButtonIcon(Painter &p, const QRect &rect, int outerWidth, HistoryMessageReplyMarkup::Button::Type type) const override;
void paintButtonLoading(Painter &p, const QRect &rect) const override;
int minButtonWidth(HistoryMessageReplyMarkup::Button::Type type) const override;

View File

@ -186,7 +186,7 @@ void EmojiColorPicker::mouseReleaseEvent(QMouseEvent *e) {
void EmojiColorPicker::handleMouseRelease(QPoint globalPos) {
_lastMousePos = globalPos;
int32 pressed = _pressedSel;
int32_t pressed = _pressedSel;
_pressedSel = -1;
updateSelected();
@ -492,7 +492,7 @@ void EmojiListWidget::mousePressEvent(QMouseEvent *e) {
}
void EmojiListWidget::mouseReleaseEvent(QMouseEvent *e) {
int32 pressed = _pressedSel;
int32_t pressed = _pressedSel;
_pressedSel = -1;
_lastMousePos = e->globalPos();
@ -553,7 +553,7 @@ void EmojiListWidget::onShowPicker() {
y += _picker->height() - st::buttonRadius + st::emojiPanSize.height() - st::buttonRadius;
}
auto xmax = width() - _picker->width();
auto coef = float64(sel % kEmojiPanelPerRow) / float64(kEmojiPanelPerRow - 1);
auto coef = double(sel % kEmojiPanelPerRow) / double(kEmojiPanelPerRow - 1);
if (rtl()) coef = 1. - coef;
_picker->move(qRound(xmax * coef), y);

View File

@ -155,7 +155,7 @@ private:
int _counts[kEmojiSectionCount];
QVector<EmojiPtr> _emoji[kEmojiSectionCount];
int32 _esize;
int32_t _esize;
int _selected = -1;
int _pressedSel = -1;

View File

@ -142,7 +142,7 @@ inline int indexOfInFirstN(const T &v, const U &elem, int last) {
}
void FieldAutocomplete::updateFiltered(bool resetScroll) {
int32 now = unixtime(), recentInlineBots = 0;
int32_t now = unixtime(), recentInlineBots = 0;
internal::MentionRows mrows;
internal::HashtagRows hrows;
internal::BotCommandRows brows;
@ -190,7 +190,7 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) {
}
}
if (_chat) {
QMultiMap<int32, UserData*> ordered;
QMultiMap<int32_t, UserData*> ordered;
mrows.reserve(mrows.size() + (_chat->participants.isEmpty() ? _chat->lastAuthors.size() : _chat->participants.size()));
if (_chat->noParticipantInfo()) {
Auth().api().requestFullPeer(_chat);
@ -219,7 +219,7 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) {
}
}
} else if (_channel && _channel->isMegagroup()) {
QMultiMap<int32, UserData*> ordered;
QMultiMap<int32_t, UserData*> ordered;
if (_channel->mgInfo->lastParticipants.isEmpty() || _channel->lastParticipantsCountOutdated()) {
Auth().api().requestLastParticipants(_channel);
} else {
@ -246,7 +246,7 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) {
bool listAllSuggestions = _filter.isEmpty();
bool hasUsername = _filter.indexOf('@') > 0;
QMap<UserData*, bool> bots;
int32 cnt = 0;
int32_t cnt = 0;
if (_chat) {
if (_chat->noParticipantInfo()) {
Auth().api().requestFullPeer(_chat);
@ -287,7 +287,7 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) {
}
if (cnt) {
brows.reserve(cnt);
int32 botStatus = _chat ? _chat->botStatus : ((_channel && _channel->isMegagroup()) ? _channel->mgInfo->botStatus : -1);
int32_t botStatus = _chat ? _chat->botStatus : ((_channel && _channel->isMegagroup()) ? _channel->mgInfo->botStatus : -1);
if (_chat) {
for (auto i = _chat->lastAuthors.cbegin(), e = _chat->lastAuthors.cend(); i != e; ++i) {
auto user = *i;
@ -314,7 +314,7 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) {
if (!bots.isEmpty()) {
for (QMap<UserData*, bool>::const_iterator i = bots.cbegin(), e = bots.cend(); i != e; ++i) {
UserData *user = i.key();
for (int32 j = 0, l = user->botInfo->commands.size(); j < l; ++j) {
for (int32_t j = 0, l = user->botInfo->commands.size(); j < l; ++j) {
if (!listAllSuggestions) {
QString toFilter = (hasUsername || botStatus == 0 || botStatus == 2) ? user->botInfo->commands.at(j).command + '@' + user->username : user->botInfo->commands.at(j).command;
if (!toFilter.startsWith(_filter, Qt::CaseInsensitive)/* || toFilter.size() == _filter.size()*/) continue;
@ -364,10 +364,10 @@ void FieldAutocomplete::setBoundings(QRect boundings) {
}
void FieldAutocomplete::recount(bool resetScroll) {
int32 h = 0, oldst = _scroll->scrollTop(), st = oldst, maxh = 4.5 * st::mentionHeight;
int32_t h = 0, oldst = _scroll->scrollTop(), st = oldst, maxh = 4.5 * st::mentionHeight;
if (!_srows.isEmpty()) {
int32 stickersPerRow = qMax(1, int32(_boundings.width() - 2 * st::stickerPanPadding) / int32(st::stickerPanSize.width()));
int32 rows = rowscount(_srows.size(), stickersPerRow);
int32_t stickersPerRow = qMax(1, int32_t(_boundings.width() - 2 * st::stickerPanPadding) / int32_t(st::stickerPanSize.width()));
int32_t rows = rowscount(_srows.size(), stickersPerRow);
h = st::stickerPanPadding + rows * st::stickerPanSize.height();
} else if (!_mrows.isEmpty()) {
h = _mrows.size() * st::mentionHeight;
@ -465,11 +465,11 @@ UserData *FieldAutocomplete::user() const {
return _user;
}
int32 FieldAutocomplete::innerTop() {
int32_t FieldAutocomplete::innerTop() {
return _scroll->scrollTop();
}
int32 FieldAutocomplete::innerBottom() {
int32_t FieldAutocomplete::innerBottom() {
return _scroll->scrollTop() + _scroll->height();
}
@ -531,20 +531,20 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
QRect r(e->rect());
if (r != rect()) p.setClipRect(r);
int32 atwidth = st::mentionFont->width('@'), hashwidth = st::mentionFont->width('#');
int32 mentionleft = 2 * st::mentionPadding.left() + st::mentionPhotoSize;
int32 mentionwidth = width() - mentionleft - 2 * st::mentionPadding.right();
int32 htagleft = st::historyAttach.width + st::historyComposeField.textMrg.left() - st::lineWidth, htagwidth = width() - st::mentionPadding.right() - htagleft - st::mentionScroll.width;
int32_t atwidth = st::mentionFont->width('@'), hashwidth = st::mentionFont->width('#');
int32_t mentionleft = 2 * st::mentionPadding.left() + st::mentionPhotoSize;
int32_t mentionwidth = width() - mentionleft - 2 * st::mentionPadding.right();
int32_t htagleft = st::historyAttach.width + st::historyComposeField.textMrg.left() - st::lineWidth, htagwidth = width() - st::mentionPadding.right() - htagleft - st::mentionScroll.width;
if (!_srows->isEmpty()) {
int32 rows = rowscount(_srows->size(), _stickersPerRow);
int32 fromrow = floorclamp(r.y() - st::stickerPanPadding, st::stickerPanSize.height(), 0, rows);
int32 torow = ceilclamp(r.y() + r.height() - st::stickerPanPadding, st::stickerPanSize.height(), 0, rows);
int32 fromcol = floorclamp(r.x() - st::stickerPanPadding, st::stickerPanSize.width(), 0, _stickersPerRow);
int32 tocol = ceilclamp(r.x() + r.width() - st::stickerPanPadding, st::stickerPanSize.width(), 0, _stickersPerRow);
for (int32 row = fromrow; row < torow; ++row) {
for (int32 col = fromcol; col < tocol; ++col) {
int32 index = row * _stickersPerRow + col;
int32_t rows = rowscount(_srows->size(), _stickersPerRow);
int32_t fromrow = floorclamp(r.y() - st::stickerPanPadding, st::stickerPanSize.height(), 0, rows);
int32_t torow = ceilclamp(r.y() + r.height() - st::stickerPanPadding, st::stickerPanSize.height(), 0, rows);
int32_t fromcol = floorclamp(r.x() - st::stickerPanPadding, st::stickerPanSize.width(), 0, _stickersPerRow);
int32_t tocol = ceilclamp(r.x() + r.width() - st::stickerPanPadding, st::stickerPanSize.width(), 0, _stickersPerRow);
for (int32_t row = fromrow; row < torow; ++row) {
for (int32_t col = fromcol; col < tocol; ++col) {
int32_t index = row * _stickersPerRow + col;
if (index >= _srows->size()) break;
DocumentData *sticker = _srows->at(index);
@ -564,9 +564,9 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
sticker->checkSticker();
}
float64 coef = qMin((st::stickerPanSize.width() - st::buttonRadius * 2) / float64(sticker->dimensions.width()), (st::stickerPanSize.height() - st::buttonRadius * 2) / float64(sticker->dimensions.height()));
double coef = qMin((st::stickerPanSize.width() - st::buttonRadius * 2) / double(sticker->dimensions.width()), (st::stickerPanSize.height() - st::buttonRadius * 2) / double(sticker->dimensions.height()));
if (coef > 1) coef = 1;
int32 w = qRound(coef * sticker->dimensions.width()), h = qRound(coef * sticker->dimensions.height());
int32_t w = qRound(coef * sticker->dimensions.width()), h = qRound(coef * sticker->dimensions.height());
if (w < 1) w = 1;
if (h < 1) h = 1;
QPoint ppos = pos + QPoint((st::stickerPanSize.width() - w) / 2, (st::stickerPanSize.height() - h) / 2);
@ -578,13 +578,13 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
}
}
} else {
int32 from = qFloor(e->rect().top() / st::mentionHeight), to = qFloor(e->rect().bottom() / st::mentionHeight) + 1;
int32 last = _mrows->isEmpty() ? (_hrows->isEmpty() ? _brows->size() : _hrows->size()) : _mrows->size();
int32_t from = qFloor(e->rect().top() / st::mentionHeight), to = qFloor(e->rect().bottom() / st::mentionHeight) + 1;
int32_t last = _mrows->isEmpty() ? (_hrows->isEmpty() ? _brows->size() : _hrows->size()) : _mrows->size();
auto filter = _parent->filter();
bool hasUsername = filter.indexOf('@') > 0;
int filterSize = filter.size();
bool filterIsEmpty = filter.isEmpty();
for (int32 i = from; i < to; ++i) {
for (int32_t i = from; i < to; ++i) {
if (i >= last) break;
bool selected = (i == _sel);
@ -599,7 +599,7 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
UserData *user = _mrows->at(i);
QString first = (!filterIsEmpty && user->username.startsWith(filter, Qt::CaseInsensitive)) ? ('@' + user->username.mid(0, filterSize)) : QString();
QString second = first.isEmpty() ? (user->username.isEmpty() ? QString() : ('@' + user->username)) : user->username.mid(filterSize);
int32 firstwidth = st::mentionFont->width(first), secondwidth = st::mentionFont->width(second), unamewidth = firstwidth + secondwidth, namewidth = user->nameText.maxWidth();
int32_t firstwidth = st::mentionFont->width(first), secondwidth = st::mentionFont->width(second), unamewidth = firstwidth + secondwidth, namewidth = user->nameText.maxWidth();
if (mentionwidth < unamewidth + namewidth) {
namewidth = (mentionwidth * namewidth) / (namewidth + unamewidth);
unamewidth = mentionwidth - namewidth;
@ -631,7 +631,7 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
QString hrow = _hrows->at(i);
QString first = filterIsEmpty ? QString() : ('#' + hrow.mid(0, filterSize));
QString second = filterIsEmpty ? ('#' + hrow) : hrow.mid(filterSize);
int32 firstwidth = st::mentionFont->width(first), secondwidth = st::mentionFont->width(second);
int32_t firstwidth = st::mentionFont->width(first), secondwidth = st::mentionFont->width(second);
if (htagwidth < firstwidth + secondwidth) {
if (htagwidth < firstwidth + st::mentionFont->elidew) {
first = st::mentionFont->elided(first + second, htagwidth);
@ -655,7 +655,7 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
const BotCommand *command = _brows->at(i).second;
QString toHighlight = command->command;
int32 botStatus = _parent->chat() ? _parent->chat()->botStatus : ((_parent->channel() && _parent->channel()->isMegagroup()) ? _parent->channel()->mgInfo->botStatus : -1);
int32_t botStatus = _parent->chat() ? _parent->chat()->botStatus : ((_parent->channel() && _parent->channel()->isMegagroup()) ? _parent->channel()->mgInfo->botStatus : -1);
if (hasUsername || botStatus == 0 || botStatus == 2) {
toHighlight += '@' + user->username;
}
@ -684,7 +684,7 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
}
void FieldAutocompleteInner::resizeEvent(QResizeEvent *e) {
_stickersPerRow = qMax(1, int32(width() - 2 * st::stickerPanPadding) / int32(st::stickerPanSize.width()));
_stickersPerRow = qMax(1, int32_t(width() - 2 * st::stickerPanPadding) / int32_t(st::stickerPanSize.width()));
}
void FieldAutocompleteInner::mouseMoveEvent(QMouseEvent *e) {
@ -704,8 +704,8 @@ void FieldAutocompleteInner::clearSel(bool hidden) {
bool FieldAutocompleteInner::moveSel(int key) {
_mouseSel = false;
int32 maxSel = (_mrows->isEmpty() ? (_hrows->isEmpty() ? (_brows->isEmpty() ? _srows->size() : _brows->size()) : _hrows->size()) : _mrows->size());
int32 direction = (key == Qt::Key_Up) ? -1 : (key == Qt::Key_Down ? 1 : 0);
int32_t maxSel = (_mrows->isEmpty() ? (_hrows->isEmpty() ? (_brows->isEmpty() ? _srows->size() : _brows->size()) : _hrows->size()) : _mrows->size());
int32_t direction = (key == Qt::Key_Up) ? -1 : (key == Qt::Key_Down ? 1 : 0);
if (!_srows->isEmpty()) {
if (key == Qt::Key_Left) {
direction = -1;
@ -749,7 +749,7 @@ bool FieldAutocompleteInner::chooseSelected(FieldAutocomplete::ChooseMethod meth
if (_sel >= 0 && _sel < _brows->size()) {
UserData *user = _brows->at(_sel).first;
const BotCommand *command(_brows->at(_sel).second);
int32 botStatus = _parent->chat() ? _parent->chat()->botStatus : ((_parent->channel() && _parent->channel()->isMegagroup()) ? _parent->channel()->mgInfo->botStatus : -1);
int32_t botStatus = _parent->chat() ? _parent->chat()->botStatus : ((_parent->channel() && _parent->channel()->isMegagroup()) ? _parent->channel()->mgInfo->botStatus : -1);
if (botStatus == 0 || botStatus == 2 || _parent->filter().indexOf('@') > 0) {
emit botCommandChosen('/' + command->command + '@' + user->username, method);
} else {
@ -761,7 +761,7 @@ bool FieldAutocompleteInner::chooseSelected(FieldAutocomplete::ChooseMethod meth
return false;
}
void FieldAutocompleteInner::setRecentInlineBotsInRows(int32 bots) {
void FieldAutocompleteInner::setRecentInlineBotsInRows(int32_t bots) {
_recentInlineBotsInRows = bots;
}
@ -787,7 +787,7 @@ void FieldAutocompleteInner::mousePressEvent(QMouseEvent *e) {
} else {
UserData *toRemove = _mrows->at(_sel);
RecentInlineBots &recent(cRefRecentInlineBots());
int32 index = recent.indexOf(toRemove);
int32_t index = recent.indexOf(toRemove);
if (index >= 0) {
recent.remove(index);
removed = true;
@ -812,7 +812,7 @@ void FieldAutocompleteInner::mousePressEvent(QMouseEvent *e) {
void FieldAutocompleteInner::mouseReleaseEvent(QMouseEvent *e) {
_previewTimer.stop();
int32 pressed = _down;
int32_t pressed = _down;
_down = -1;
_mousePos = mapToGlobal(e->pos());
@ -847,7 +847,7 @@ void FieldAutocompleteInner::updateSelectedRow() {
if (_srows->isEmpty()) {
update(0, _sel * st::mentionHeight, width(), st::mentionHeight);
} else {
int32 row = _sel / _stickersPerRow, col = _sel % _stickersPerRow;
int32_t row = _sel / _stickersPerRow, col = _sel % _stickersPerRow;
update(st::stickerPanPadding + col * st::stickerPanSize.width(), st::stickerPanPadding + row * st::stickerPanSize.height(), st::stickerPanSize.width(), st::stickerPanSize.height());
}
}
@ -862,7 +862,7 @@ void FieldAutocompleteInner::setSel(int sel, bool scroll) {
if (_srows->isEmpty()) {
emit mustScrollTo(_sel * st::mentionHeight, (_sel + 1) * st::mentionHeight);
} else {
int32 row = _sel / _stickersPerRow;
int32_t row = _sel / _stickersPerRow;
emit mustScrollTo(st::stickerPanPadding + row * st::stickerPanSize.height(), st::stickerPanPadding + (row + 1) * st::stickerPanSize.height());
}
}
@ -874,18 +874,18 @@ void FieldAutocompleteInner::onUpdateSelected(bool force) {
if (_down >= 0 && !_previewShown) return;
int32 sel = -1, maxSel = 0;
int32_t sel = -1, maxSel = 0;
if (!_srows->isEmpty()) {
int32 rows = rowscount(_srows->size(), _stickersPerRow);
int32 row = (mouse.y() >= st::stickerPanPadding) ? ((mouse.y() - st::stickerPanPadding) / st::stickerPanSize.height()) : -1;
int32 col = (mouse.x() >= st::stickerPanPadding) ? ((mouse.x() - st::stickerPanPadding) / st::stickerPanSize.width()) : -1;
int32_t rows = rowscount(_srows->size(), _stickersPerRow);
int32_t row = (mouse.y() >= st::stickerPanPadding) ? ((mouse.y() - st::stickerPanPadding) / st::stickerPanSize.height()) : -1;
int32_t col = (mouse.x() >= st::stickerPanPadding) ? ((mouse.x() - st::stickerPanPadding) / st::stickerPanSize.width()) : -1;
if (row >= 0 && col >= 0) {
sel = row * _stickersPerRow + col;
}
maxSel = _srows->size();
_overDelete = false;
} else {
sel = mouse.y() / int32(st::mentionHeight);
sel = mouse.y() / int32_t(st::mentionHeight);
maxSel = _mrows->isEmpty() ? (_hrows->isEmpty() ? _brows->size() : _hrows->size()) : _mrows->size();
_overDelete = (!_hrows->isEmpty() || (!_mrows->isEmpty() && sel < _recentInlineBotsInRows)) ? (mouse.x() >= width() - st::mentionHeight) : false;
}

View File

@ -52,8 +52,8 @@ public:
ChannelData *channel() const;
UserData *user() const;
int32 innerTop();
int32 innerBottom();
int32_t innerTop();
int32_t innerBottom();
bool eventFilter(QObject *obj, QEvent *e) override;
@ -126,7 +126,7 @@ private:
QRect _boundings;
bool _addInlineBots;
int32 _width, _height;
int32_t _width, _height;
bool _hiding = false;
Animation _a_opacity;
@ -147,7 +147,7 @@ public:
bool moveSel(int key);
bool chooseSelected(FieldAutocomplete::ChooseMethod method) const;
void setRecentInlineBotsInRows(int32 bots);
void setRecentInlineBotsInRows(int32_t bots);
signals:
void mentionChosen(UserData *user, FieldAutocomplete::ChooseMethod method) const;
@ -180,8 +180,8 @@ private:
HashtagRows *_hrows;
BotCommandRows *_brows;
StickerPack *_srows;
int32 _stickersPerRow, _recentInlineBotsInRows;
int32 _sel, _down;
int32_t _stickersPerRow, _recentInlineBotsInRows;
int32_t _sel, _down;
bool _mouseSel;
QPoint _mousePos;

View File

@ -418,7 +418,7 @@ void GifsListWidget::processPanelHideFinished() {
}
}
bool GifsListWidget::inlineRowsAddItem(DocumentData *savedGif, InlineResult *result, Row &row, int32 &sumWidth) {
bool GifsListWidget::inlineRowsAddItem(DocumentData *savedGif, InlineResult *result, Row &row, int32_t &sumWidth) {
LayoutItem *layout = nullptr;
if (savedGif) {
layout = layoutPrepareSavedGif(savedGif, (_rows.size() * MatrixRowShift) + row.items.size());
@ -441,7 +441,7 @@ bool GifsListWidget::inlineRowsAddItem(DocumentData *savedGif, InlineResult *res
return true;
}
bool GifsListWidget::inlineRowFinalize(Row &row, int32 &sumWidth, bool force) {
bool GifsListWidget::inlineRowFinalize(Row &row, int32_t &sumWidth, bool force) {
if (row.items.isEmpty()) return false;
auto full = (row.items.size() >= kInlineItemsMaxPerRow);
@ -502,7 +502,7 @@ void GifsListWidget::clearInlineRows(bool resultsDeleted) {
_rows.clear();
}
GifsListWidget::LayoutItem *GifsListWidget::layoutPrepareSavedGif(DocumentData *doc, int32 position) {
GifsListWidget::LayoutItem *GifsListWidget::layoutPrepareSavedGif(DocumentData *doc, int32_t position) {
auto it = _gifLayouts.find(doc);
if (it == _gifLayouts.cend()) {
if (auto layout = LayoutItem::createLayoutGif(this, doc)) {
@ -518,7 +518,7 @@ GifsListWidget::LayoutItem *GifsListWidget::layoutPrepareSavedGif(DocumentData *
return it->second.get();
}
GifsListWidget::LayoutItem *GifsListWidget::layoutPrepareInlineResult(InlineResult *result, int32 position) {
GifsListWidget::LayoutItem *GifsListWidget::layoutPrepareInlineResult(InlineResult *result, int32_t position) {
auto it = _inlineLayouts.find(result);
if (it == _inlineLayouts.cend()) {
if (auto layout = LayoutItem::createLayout(this, result, _inlineWithThumb)) {
@ -562,7 +562,7 @@ void GifsListWidget::deleteUnusedInlineLayouts() {
}
}
GifsListWidget::Row &GifsListWidget::layoutInlineRow(Row &row, int32 sumWidth) {
GifsListWidget::Row &GifsListWidget::layoutInlineRow(Row &row, int32_t sumWidth) {
auto count = int(row.items.size());
Assert(count <= kInlineItemsMaxPerRow);
@ -640,7 +640,7 @@ int GifsListWidget::refreshInlineRows(const InlineCacheEntry *entry, bool result
inlineRowFinalize(row, sumWidth, true);
}
int32 h = countHeight();
int32_t h = countHeight();
if (h != height()) resize(width(), h);
update();
@ -763,7 +763,7 @@ void GifsListWidget::beforeHiding() {
}
}
bool GifsListWidget::refreshInlineRows(int32 *added) {
bool GifsListWidget::refreshInlineRows(int32_t *added) {
auto it = _inlineCache.find(_inlineQuery);
const InlineCacheEntry *entry = nullptr;
if (it != _inlineCache.cend()) {
@ -775,7 +775,7 @@ bool GifsListWidget::refreshInlineRows(int32 *added) {
return (entry != nullptr);
}
int32 GifsListWidget::showInlineRows(bool newResults) {
int32_t GifsListWidget::showInlineRows(bool newResults) {
auto added = 0;
auto clear = !refreshInlineRows(&added);
if (newResults) {

View File

@ -117,8 +117,8 @@ private:
int refreshInlineRows(const InlineCacheEntry *results, bool resultsDeleted);
void checkLoadMore();
int32 showInlineRows(bool newResults);
bool refreshInlineRows(int32 *added = 0);
int32_t showInlineRows(bool newResults);
bool refreshInlineRows(int32_t *added = 0);
void inlineResultsDone(const MTPmessages_BotResults &result);
void updateSelected();
@ -137,15 +137,15 @@ private:
void clearInlineRows(bool resultsDeleted);
std::map<DocumentData*, std::unique_ptr<LayoutItem>> _gifLayouts;
LayoutItem *layoutPrepareSavedGif(DocumentData *doc, int32 position);
LayoutItem *layoutPrepareSavedGif(DocumentData *doc, int32_t position);
std::map<InlineResult*, std::unique_ptr<LayoutItem>> _inlineLayouts;
LayoutItem *layoutPrepareInlineResult(InlineResult *result, int32 position);
LayoutItem *layoutPrepareInlineResult(InlineResult *result, int32_t position);
bool inlineRowsAddItem(DocumentData *savedGif, InlineResult *result, Row &row, int32 &sumWidth);
bool inlineRowFinalize(Row &row, int32 &sumWidth, bool force = false);
bool inlineRowsAddItem(DocumentData *savedGif, InlineResult *result, Row &row, int32_t &sumWidth);
bool inlineRowFinalize(Row &row, int32_t &sumWidth, bool force = false);
Row &layoutInlineRow(Row &row, int32 sumWidth = 0);
Row &layoutInlineRow(Row &row, int32_t sumWidth = 0);
void deleteUnusedGifLayouts();
void deleteUnusedInlineLayouts();

View File

@ -144,8 +144,8 @@ void MessageField::dropEvent(QDropEvent *e) {
bool MessageField::canInsertFromMimeData(const QMimeData *source) const {
if (source->hasUrls()) {
int32 files = 0;
for (int32 i = 0; i < source->urls().size(); ++i) {
int32_t files = 0;
for (int32_t i = 0; i < source->urls().size(); ++i) {
if (source->urls().at(i).isLocalFile()) {
++files;
}

View File

@ -43,7 +43,7 @@ void ApplyArchivedResult(const MTPDmessages_stickerSetInstallResultArchive &d) {
auto &order = Global::RefStickerSetsOrder();
Order archived;
archived.reserve(v.size());
QMap<uint64, uint64> setsToRequest;
QMap<uint64_t, uint64_t> setsToRequest;
for_const (auto &stickerSet, v) {
const MTPDstickerSet *setData = nullptr;
switch (stickerSet.type()) {
@ -96,7 +96,7 @@ bool ApplyArchivedResultFake() {
auto sets = QVector<MTPStickerSetCovered>();
for (auto &set : Global::RefStickerSets()) {
if ((set.flags & MTPDstickerSet::Flag::f_installed) && !(set.flags & MTPDstickerSet_ClientFlag::f_special)) {
if (rand_value<uint32>() % 128 < 64) {
if (rand_value<uint32_t>() % 128 < 64) {
auto data = MTP_stickerSet(MTP_flags(set.flags | MTPDstickerSet::Flag::f_archived), MTP_long(set.id), MTP_long(set.access), MTP_string(set.title), MTP_string(set.shortName), MTP_int(set.count), MTP_int(set.hash));
sets.push_back(MTP_stickerSetCovered(data, MTP_documentEmpty(MTP_long(0))));
}
@ -108,7 +108,7 @@ bool ApplyArchivedResultFake() {
return true;
}
void InstallLocally(uint64 setId) {
void InstallLocally(uint64_t setId) {
auto &sets = Global::RefStickerSets();
auto it = sets.find(setId);
if (it == sets.end()) {
@ -151,7 +151,7 @@ void InstallLocally(uint64 setId) {
Auth().data().stickersUpdated().notify(true);
}
void UndoInstallLocally(uint64 setId) {
void UndoInstallLocally(uint64_t setId) {
auto &sets = Global::RefStickerSets();
auto it = sets.find(setId);
if (it == sets.end()) {
@ -172,7 +172,7 @@ void UndoInstallLocally(uint64 setId) {
Ui::show(Box<InformBox>(lang(lng_stickers_not_found)), KeepOtherLayers);
}
void MarkFeaturedAsRead(uint64 setId) {
void MarkFeaturedAsRead(uint64_t setId) {
if (!FeaturedReaderInstance) {
if (auto main = App::main()) {
FeaturedReaderInstance = object_ptr<internal::FeaturedReader>(main);
@ -338,12 +338,12 @@ void SetFaved(not_null<DocumentData*> document, bool faved) {
}
}
void SetsReceived(const QVector<MTPStickerSet> &data, int32 hash) {
void SetsReceived(const QVector<MTPStickerSet> &data, int32_t hash) {
auto &setsOrder = Global::RefStickerSetsOrder();
setsOrder.clear();
auto &sets = Global::RefStickerSets();
QMap<uint64, uint64> setsToRequest;
QMap<uint64_t, uint64_t> setsToRequest;
for (auto &set : sets) {
if (!(set.flags & MTPDstickerSet::Flag::f_archived)) {
set.flags &= ~MTPDstickerSet::Flag::f_installed; // mark for removing
@ -425,7 +425,7 @@ void SetPackAndEmoji(Set &set, StickerPack &&pack, const QVector<MTPStickerPack>
}
}
void SpecialSetReceived(uint64 setId, const QString &setTitle, const QVector<MTPDocument> &items, int32 hash, const QVector<MTPStickerPack> &packs) {
void SpecialSetReceived(uint64_t setId, const QString &setTitle, const QVector<MTPDocument> &items, int32_t hash, const QVector<MTPStickerPack> &packs) {
auto &sets = Global::RefStickerSets();
auto it = sets.find(setId);
@ -503,8 +503,8 @@ void SpecialSetReceived(uint64 setId, const QString &setTitle, const QVector<MTP
Auth().data().stickersUpdated().notify(true);
}
void FeaturedSetsReceived(const QVector<MTPStickerSetCovered> &data, const QVector<MTPlong> &unread, int32 hash) {
OrderedSet<uint64> unreadMap;
void FeaturedSetsReceived(const QVector<MTPStickerSetCovered> &data, const QVector<MTPlong> &unread, int32_t hash) {
OrderedSet<uint64_t> unreadMap;
for_const (auto &unreadSetId, unread) {
unreadMap.insert(unreadSetId.v);
}
@ -513,7 +513,7 @@ void FeaturedSetsReceived(const QVector<MTPStickerSetCovered> &data, const QVect
setsOrder.clear();
auto &sets = Global::RefStickerSets();
QMap<uint64, uint64> setsToRequest;
QMap<uint64_t, uint64_t> setsToRequest;
for (auto &set : sets) {
set.flags &= ~MTPDstickerSet_ClientFlag::f_featured; // mark for removing
}
@ -606,7 +606,7 @@ void FeaturedSetsReceived(const QVector<MTPStickerSetCovered> &data, const QVect
Auth().data().stickersUpdated().notify(true);
}
void GifsReceived(const QVector<MTPDocument> &items, int32 hash) {
void GifsReceived(const QVector<MTPDocument> &items, int32_t hash) {
auto &saved = cRefSavedGifs();
saved.clear();
@ -632,7 +632,7 @@ void GifsReceived(const QVector<MTPDocument> &items, int32 hash) {
StickerPack GetListByEmoji(not_null<EmojiPtr> emoji) {
auto original = emoji->original();
auto result = StickerPack();
auto setsToRequest = QMap<uint64, uint64>();
auto setsToRequest = QMap<uint64_t, uint64_t>();
auto &sets = Global::RefStickerSets();
auto faved = StickerPack();
@ -840,7 +840,7 @@ FeaturedReader::FeaturedReader(QObject *parent) : QObject(parent)
_timer->setTimeoutHandler([this] { readSets(); });
}
void FeaturedReader::scheduleRead(uint64 setId) {
void FeaturedReader::scheduleRead(uint64_t setId) {
if (!_setIds.contains(setId)) {
_setIds.insert(setId);
_timer->start(kReadFeaturedSetsTimeoutMs);

View File

@ -28,16 +28,16 @@ constexpr auto kPanelPerRow = 5;
void ApplyArchivedResult(const MTPDmessages_stickerSetInstallResultArchive &d);
bool ApplyArchivedResultFake(); // For testing.
void InstallLocally(uint64 setId);
void UndoInstallLocally(uint64 setId);
void MarkFeaturedAsRead(uint64 setId);
void InstallLocally(uint64_t setId);
void UndoInstallLocally(uint64_t setId);
void MarkFeaturedAsRead(uint64_t setId);
bool IsFaved(not_null<DocumentData*> document);
void SetFaved(not_null<DocumentData*> document, bool faved);
void SetsReceived(const QVector<MTPStickerSet> &data, int32 hash);
void SpecialSetReceived(uint64 setId, const QString &setTitle, const QVector<MTPDocument> &items, int32 hash, const QVector<MTPStickerPack> &packs = QVector<MTPStickerPack>());
void FeaturedSetsReceived(const QVector<MTPStickerSetCovered> &data, const QVector<MTPlong> &unread, int32 hash);
void GifsReceived(const QVector<MTPDocument> &items, int32 hash);
void SetsReceived(const QVector<MTPStickerSet> &data, int32_t hash);
void SpecialSetReceived(uint64_t setId, const QString &setTitle, const QVector<MTPDocument> &items, int32_t hash, const QVector<MTPStickerPack> &packs = QVector<MTPStickerPack>());
void FeaturedSetsReceived(const QVector<MTPStickerSetCovered> &data, const QVector<MTPlong> &unread, int32_t hash);
void GifsReceived(const QVector<MTPDocument> &items, int32_t hash);
StickerPack GetListByEmoji(not_null<EmojiPtr> emoji);
base::optional<std::vector<not_null<EmojiPtr>>> GetEmojiListFromSet(
@ -53,13 +53,13 @@ namespace internal {
class FeaturedReader : public QObject, private MTP::Sender {
public:
FeaturedReader(QObject *parent);
void scheduleRead(uint64 setId);
void scheduleRead(uint64_t setId);
private:
void readSets();
object_ptr<SingleTimer> _timer;
OrderedSet<uint64> _setIds;
OrderedSet<uint64_t> _setIds;
};

View File

@ -46,11 +46,11 @@ constexpr auto kInlineItemsMaxPerRow = 5;
} // namespace
struct StickerIcon {
StickerIcon(uint64 setId) : setId(setId) {
StickerIcon(uint64_t setId) : setId(setId) {
}
StickerIcon(uint64 setId, DocumentData *sticker, int32 pixw, int32 pixh) : setId(setId), sticker(sticker), pixw(pixw), pixh(pixh) {
StickerIcon(uint64_t setId, DocumentData *sticker, int32_t pixw, int32_t pixh) : setId(setId), sticker(sticker), pixw(pixw), pixh(pixh) {
}
uint64 setId = 0;
uint64_t setId = 0;
DocumentData *sticker = nullptr;
ChannelData *megagroup = nullptr;
int pixw = 0;
@ -63,7 +63,7 @@ public:
Footer(not_null<StickersListWidget*> parent);
void preloadImages();
void validateSelectedIcon(uint64 setId, ValidateIconAnimations animations);
void validateSelectedIcon(uint64_t setId, ValidateIconAnimations animations);
void refreshIcons(ValidateIconAnimations animations);
bool hasOnlyFeaturedSets() const;
@ -143,7 +143,7 @@ void StickersListWidget::Footer::preloadImages() {
});
}
void StickersListWidget::Footer::validateSelectedIcon(uint64 setId, ValidateIconAnimations animations) {
void StickersListWidget::Footer::validateSelectedIcon(uint64_t setId, ValidateIconAnimations animations) {
auto newSel = 0;
for (auto i = 0, l = _icons.size(); i != l; ++i) {
if (_icons[i].setId == setId) {
@ -214,7 +214,7 @@ void StickersListWidget::Footer::paintEvent(QPaintEvent *e) {
} else if (icon.megagroup) {
icon.megagroup->paintUserpicLeft(p, x + (st::emojiCategory.width - st::stickerGroupCategorySize) / 2, _iconsTop + (st::emojiCategory.height - st::stickerGroupCategorySize) / 2, width(), st::stickerGroupCategorySize);
} else {
auto getSpecialSetIcon = [](uint64 setId) {
auto getSpecialSetIcon = [](uint64_t setId) {
if (setId == Stickers::FeaturedSetId) {
return &st::stickersTrending;
} else if (setId == Stickers::FavedSetId) {
@ -344,7 +344,7 @@ void StickersListWidget::Footer::updateSelected() {
}
auto p = mapFromGlobal(_iconsMousePos);
int32 x = p.x(), y = p.y(), newOver = -1;
int32_t x = p.x(), y = p.y(), newOver = -1;
if (rtl()) x = width() - x;
x -= _iconsLeft;
if (x >= st::emojiCategory.width * (kVisibleIconsCount - 1) && x < st::emojiCategory.width * kVisibleIconsCount && y >= _iconsTop && y < _iconsTop + st::emojiCategory.height) {
@ -416,7 +416,7 @@ void StickersListWidget::validateSelectedIcon(ValidateIconAnimations animations)
void StickersListWidget::Footer::step_icons(TimeMs ms, bool timer) {
if (_iconsStartAnim) {
auto dt = (ms - _iconsStartAnim) / float64(st::stickerIconMove);
auto dt = (ms - _iconsStartAnim) / double(st::stickerIconMove);
if (dt >= 1) {
_iconsStartAnim = 0;
_iconsX.finish();
@ -575,11 +575,11 @@ int StickersListWidget::countHeight() {
return qMax(minimalLastHeight, countResult()) + st::stickerPanPadding;
}
void StickersListWidget::installedLocally(uint64 setId) {
void StickersListWidget::installedLocally(uint64_t setId) {
_installedLocallySets.insert(setId);
}
void StickersListWidget::notInstalledLocally(uint64 setId) {
void StickersListWidget::notInstalledLocally(uint64_t setId) {
_installedLocallySets.remove(setId);
}
@ -827,7 +827,7 @@ void StickersListWidget::paintSticker(Painter &p, Set &set, int y, int index, bo
sticker->checkSticker();
}
auto coef = qMin((st::stickerPanSize.width() - st::buttonRadius * 2) / float64(sticker->dimensions.width()), (st::stickerPanSize.height() - st::buttonRadius * 2) / float64(sticker->dimensions.height()));
auto coef = qMin((st::stickerPanSize.width() - st::buttonRadius * 2) / double(sticker->dimensions.width()), (st::stickerPanSize.height() - st::buttonRadius * 2) / double(sticker->dimensions.height()));
if (coef > 1) coef = 1;
auto w = qMax(qRound(coef * sticker->dimensions.width()), 1);
auto h = qMax(qRound(coef * sticker->dimensions.height()), 1);
@ -1041,7 +1041,7 @@ void StickersListWidget::removeRecentSticker(int section, int index) {
bool refresh = false;
auto sticker = _mySets[section].pack[index];
auto &recent = cGetRecentStickers();
for (int32 i = 0, l = recent.size(); i < l; ++i) {
for (int32_t i = 0, l = recent.size(); i < l; ++i) {
if (recent.at(i).first == sticker) {
recent.removeAt(i);
Local::writeUserSettings();
@ -1198,14 +1198,14 @@ void StickersListWidget::preloadImages() {
}
}
uint64 StickersListWidget::currentSet(int yOffset) const {
uint64_t StickersListWidget::currentSet(int yOffset) const {
if (_section == Section::Featured) {
return Stickers::FeaturedSetId;
}
return _mySets.isEmpty() ? Stickers::RecentSetId : _mySets[sectionInfoByOffset(yOffset).section].id;
}
void StickersListWidget::appendSet(Sets &to, uint64 setId, AppendSkip skip) {
void StickersListWidget::appendSet(Sets &to, uint64_t setId, AppendSkip skip) {
auto &sets = Global::StickerSets();
auto it = sets.constFind(setId);
if (it == sets.cend() || it->stickers.isEmpty()) return;
@ -1281,7 +1281,7 @@ void StickersListWidget::refreshRecentStickers(bool performResize) {
}
if (performResize && (_section == Section::Stickers || _section == Section::Featured)) {
int32 h = countHeight();
int32_t h = countHeight();
if (h != height()) {
resize(width(), h);
update();
@ -1545,7 +1545,7 @@ void StickersListWidget::onPreview() {
}
}
void StickersListWidget::showStickerSet(uint64 setId) {
void StickersListWidget::showStickerSet(uint64_t setId) {
clearSelection();
if (setId == Stickers::FeaturedSetId) {
@ -1615,7 +1615,7 @@ void StickersListWidget::showMegagroupSet(ChannelData *megagroup) {
}
}
void StickersListWidget::displaySet(uint64 setId) {
void StickersListWidget::displaySet(uint64_t setId) {
if (setId == Stickers::MegagroupSetId) {
if (_megagroupSet->canEditStickers()) {
_displayingSetId = setId;
@ -1643,7 +1643,7 @@ void StickersListWidget::displaySet(uint64 setId) {
}
}
void StickersListWidget::installSet(uint64 setId) {
void StickersListWidget::installSet(uint64_t setId) {
auto &sets = Global::StickerSets();
auto it = sets.constFind(setId);
if (it != sets.cend()) {
@ -1683,7 +1683,7 @@ void StickersListWidget::removeMegagroupSet(bool locally) {
})));
}
void StickersListWidget::removeSet(uint64 setId) {
void StickersListWidget::removeSet(uint64_t setId) {
auto &sets = Global::StickerSets();
auto it = sets.constFind(setId);
if (it != sets.cend()) {

View File

@ -46,7 +46,7 @@ public:
void clearSelection() override;
object_ptr<TabbedSelector::InnerFooter> createFooter() override;
void showStickerSet(uint64 setId);
void showStickerSet(uint64_t setId);
void showMegagroupSet(ChannelData *megagroup);
void refreshStickers();
@ -56,10 +56,10 @@ public:
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
uint64 currentSet(int yOffset) const;
uint64_t currentSet(int yOffset) const;
void installedLocally(uint64 setId);
void notInstalledLocally(uint64 setId);
void installedLocally(uint64_t setId);
void notInstalledLocally(uint64_t setId);
void clearInstalledLocally();
~StickersListWidget();
@ -133,9 +133,9 @@ private:
};
struct Set {
Set(uint64 id, MTPDstickerSet::Flags flags, const QString &title, int32 hoversSize, const StickerPack &pack = StickerPack()) : id(id), flags(flags), title(title), pack(pack) {
Set(uint64_t id, MTPDstickerSet::Flags flags, const QString &title, int32_t hoversSize, const StickerPack &pack = StickerPack()) : id(id), flags(flags), title(title), pack(pack) {
}
uint64 id;
uint64_t id;
MTPDstickerSet::Flags flags;
QString title;
StickerPack pack;
@ -148,10 +148,10 @@ private:
SectionInfo sectionInfo(int section) const;
SectionInfo sectionInfoByOffset(int yOffset) const;
void displaySet(uint64 setId);
void installSet(uint64 setId);
void displaySet(uint64_t setId);
void installSet(uint64_t setId);
void removeMegagroupSet(bool locally);
void removeSet(uint64 setId);
void removeSet(uint64_t setId);
bool setHasTitle(const Set &set) const;
bool stickerHasDeleteButton(const Set &set, int index) const;
@ -204,7 +204,7 @@ private:
Archived,
Installed,
};
void appendSet(Sets &to, uint64 setId, AppendSkip skip = AppendSkip::None);
void appendSet(Sets &to, uint64_t setId, AppendSkip skip = AppendSkip::None);
void selectEmoji(EmojiPtr emoji);
int stickersLeft() const;
@ -216,14 +216,14 @@ private:
ChannelData *_megagroupSet = nullptr;
Sets _mySets;
Sets _featuredSets;
OrderedSet<uint64> _installedLocallySets;
OrderedSet<uint64_t> _installedLocallySets;
QList<bool> _custom;
base::flat_set<not_null<DocumentData*>> _favedStickersMap;
Section _section = Section::Stickers;
uint64 _displayingSetId = 0;
uint64 _removingSetId = 0;
uint64_t _displayingSetId = 0;
uint64_t _removingSetId = 0;
Footer *_footer = nullptr;

View File

@ -376,7 +376,7 @@ bool TabbedPanel::eventFilter(QObject *obj, QEvent *e) {
return false;
}
void TabbedPanel::stickersInstalled(uint64 setId) {
void TabbedPanel::stickersInstalled(uint64_t setId) {
if (isDestroying()) {
return;
}

View File

@ -51,7 +51,7 @@ public:
return _hiding || _hideTimer.isActive();
}
void stickersInstalled(uint64 setId);
void stickersInstalled(uint64_t setId);
bool overlaps(const QRect &globalRect) const;

View File

@ -69,7 +69,7 @@ QPointer<TabbedSelector> TabbedSection::getSelector() const {
return _selector.data();
}
void TabbedSection::stickersInstalled(uint64 setId) {
void TabbedSection::stickersInstalled(uint64_t setId) {
_selector->stickersInstalled(setId);
}

View File

@ -40,7 +40,7 @@ public:
object_ptr<TabbedSelector> takeSelector();
QPointer<TabbedSelector> getSelector() const;
void stickersInstalled(uint64 setId);
void stickersInstalled(uint64_t setId);
// Float player interface.
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override;

View File

@ -52,7 +52,7 @@ public:
void setFinalImages(Direction direction, QImage &&left, QImage &&right, QRect inner, bool wasSectionIcons);
void start();
void paintFrame(QPainter &p, float64 dt, float64 opacity);
void paintFrame(QPainter &p, double dt, double opacity);
private:
Direction _direction = Direction::LeftToRight;
@ -133,7 +133,7 @@ void TabbedSelector::SlideAnimation::start() {
_frameIntsPerLineAdd = (_width - _innerWidth) + _frameIntsPerLineAdded;
}
void TabbedSelector::SlideAnimation::paintFrame(QPainter &p, float64 dt, float64 opacity) {
void TabbedSelector::SlideAnimation::paintFrame(QPainter &p, double dt, double opacity) {
Expects(started());
Expects(dt >= 0.);
@ -219,15 +219,15 @@ void TabbedSelector::SlideAnimation::paintFrame(QPainter &p, float64 dt, float64
if (opacity == 1.) {
// Fill above the frame top with transparent.
auto fillTopInts = (_frameInts + outerTop * _frameIntsPerLine + outerLeft);
auto fillWidth = (outerRight - outerLeft) * sizeof(uint32);
auto fillWidth = (outerRight - outerLeft) * sizeof(uint32_t);
for (auto fillTop = _innerTop - outerTop; fillTop != 0; --fillTop) {
memset(fillTopInts, 0, fillWidth);
fillTopInts += _frameIntsPerLine;
}
// Fill to the left and to the right of the frame with transparent.
auto fillLeft = (_innerLeft - outerLeft) * sizeof(uint32);
auto fillRight = (outerRight - _innerRight) * sizeof(uint32);
auto fillLeft = (_innerLeft - outerLeft) * sizeof(uint32_t);
auto fillRight = (outerRight - _innerRight) * sizeof(uint32_t);
if (fillLeft || fillRight) {
auto fillInts = _frameInts + _innerTop * _frameIntsPerLine;
for (auto y = _innerTop; y != _innerBottom; ++y) {
@ -250,7 +250,7 @@ void TabbedSelector::SlideAnimation::paintFrame(QPainter &p, float64 dt, float64
// Debug
//frameInts = _frameInts;
//auto pattern = anim::shifted((static_cast<uint32>(0xFF) << 24) | (static_cast<uint32>(0xFF) << 16) | (static_cast<uint32>(0xFF) << 8) | static_cast<uint32>(0xFF));
//auto pattern = anim::shifted((static_cast<uint32_t>(0xFF) << 24) | (static_cast<uint32_t>(0xFF) << 16) | (static_cast<uint32_t>(0xFF) << 8) | static_cast<uint32_t>(0xFF));
//for (auto y = 0; y != _finalHeight; ++y) {
// for (auto x = 0; x != _finalWidth; ++x) {
// auto source = *frameInts;
@ -514,7 +514,7 @@ void TabbedSelector::afterShown() {
}
}
void TabbedSelector::stickersInstalled(uint64 setId) {
void TabbedSelector::stickersInstalled(uint64_t setId) {
_tabsSlider->setActiveSection(static_cast<int>(SelectorTab::Stickers));
stickers()->showStickerSet(setId);
}

View File

@ -60,7 +60,7 @@ public:
void setRoundRadius(int radius);
void refreshStickers();
void stickersInstalled(uint64 setId);
void stickersInstalled(uint64_t setId);
void showMegagroupSet(ChannelData *megagroup);
void setCurrentPeer(PeerData *peer);

View File

@ -0,0 +1,5 @@
add_subdirectory(common)
add_subdirectory(emoji)
add_subdirectory(lang)
add_subdirectory(numbers)
add_subdirectory(style)

View File

@ -0,0 +1,8 @@
add_library(codegen_common STATIC
basic_tokenized_file.cpp
checked_utf8_string.cpp
clean_file.cpp
cpp_file.cpp
logging.cpp
)
qt5_use_modules(codegen_common Core)

View File

@ -290,6 +290,8 @@ LogStream operator<<(LogStream &&stream, BasicTokenizedFile::Token::Type type) {
case Type::Plus: value = "'+'"; break;
case Type::Minus: value = "'-'"; break;
case Type::Equals: value = "'='"; break;
case Type::And: value = "'and'"; break;
case Type::Or: value = "'or'"; break;
case Type::Name: value = "'identifier'"; break;
}
return std::forward<LogStream>(stream) << value;

View File

@ -0,0 +1,9 @@
add_executable(codegen_emoji
data.cpp
generator.cpp
main.cpp
options.cpp
replaces.cpp
)
target_link_libraries(codegen_emoji codegen_common Qt5::Core Qt5::Gui)
qt5_use_modules(codegen_emoji Core)

View File

@ -19,15 +19,12 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#include "codegen/emoji/data.h"
#include <cstdint>
namespace codegen {
namespace emoji {
namespace {
using uint16 = quint16;
using uint32 = quint32;
using uint64 = quint64;
using std::vector;
using std::map;
using std::find;
@ -36,7 +33,7 @@ using std::move;
using std::begin;
using std::end;
using InputId = vector<uint32>;
using InputId = vector<uint32_t>;
using InputCategory = vector<InputId>;
// copied from emoji_box.cpp
@ -83,7 +80,7 @@ Replace Replaces[] = {
{ { 0xD83DDE08U }, "}:)" },
};
using ColorId = uint32;
using ColorId = uint32_t;
ColorId Colors[] = {
0xD83CDFFBU,
0xD83CDFFCU,
@ -1703,11 +1700,11 @@ InputCategory Category7 = {
constexpr auto kErrorBadData = 401;
void append(Id &id, uint32 code) {
if (auto first = static_cast<uint16>((code >> 16) & 0xFFFFU)) {
void append(Id &id, uint32_t code) {
if (auto first = static_cast<uint16_t>((code >> 16) & 0xFFFFU)) {
id.append(QChar(first));
}
id.append(QChar(static_cast<uint16>(code & 0xFFFFU)));
id.append(QChar(static_cast<uint16_t>(code & 0xFFFFU)));
}
using VariatedIds = map<Id, bool>;

View File

@ -123,11 +123,11 @@ QRect computeSourceRect(const QImage &image) {
return result;
}
uint32 Crc32Table[256];
uint32_t Crc32Table[256];
class Crc32Initializer {
public:
Crc32Initializer() {
uint32 poly = 0x04C11DB7U;
uint32_t poly = 0x04C11DB7U;
for (auto i = 0; i != 256; ++i) {
Crc32Table[i] = reflect(i, 8) << 24;
for (auto j = 0; j != 8; ++j) {
@ -138,8 +138,8 @@ public:
}
private:
uint32 reflect(uint32 val, char ch) {
uint32 result = 0;
uint32_t reflect(uint32_t val, char ch) {
uint32_t result = 0;
for (int i = 1; i < (ch + 1); ++i) {
if (val & 1) {
result |= 1 << (ch - i);
@ -151,11 +151,11 @@ private:
};
uint32 countCrc32(const void *data, std::size_t size) {
uint32_t countCrc32(const void *data, std::size_t size) {
static Crc32Initializer InitTable;
auto buffer = static_cast<const unsigned char*>(data);
auto result = uint32(0xFFFFFFFFU);
auto result = uint32_t(0xFFFFFFFFU);
for (auto i = std::size_t(0); i != size; ++i) {
result = (result >> 8) ^ Crc32Table[(result & 0xFFU) ^ buffer[i]];
}
@ -363,7 +363,7 @@ void Init() {\n\
\n\
Items.reserve(base::array_size(Data));\n\
for (auto &data : Data) {\n\
Items.emplace_back(takeString(data.idSize), uint16(data.column), uint16(data.row), bool(data.postfixed), bool(data.variated), data.original ? &Items[data.original - 1] : nullptr, One::CreationTag());\n\
Items.emplace_back(takeString(data.idSize), uint16_t(data.column), uint16_t(data.row), bool(data.postfixed), bool(data.variated), data.original ? &Items[data.original - 1] : nullptr, One::CreationTag());\n\
}\n\
InitReplacements();\n\
}\n\
@ -806,9 +806,9 @@ bool Generator::writeReplacements() {
QMap<QChar, QVector<int>> byCharIndices;
suggestionsSource_->stream() << "\
struct ReplacementStruct {\n\
small emojiSize;\n\
small replacementSize;\n\
small wordsCount;\n\
smallchar emojiSize;\n\
smallchar replacementSize;\n\
smallchar wordsCount;\n\
};\n\
\n\
const utf16char ReplacementData[] = {";
@ -833,7 +833,7 @@ const utf16char ReplacementData[] = {";
}
suggestionsSource_->stream() << " };\n\
\n\
const small ReplacementWordLengths[] = {";
const smallchar ReplacementWordLengths[] = {";
startBinary();
for (auto &replace : replaces_.list) {
auto wordLengths = QStringList();
@ -846,7 +846,7 @@ const small ReplacementWordLengths[] = {";
const ReplacementStruct ReplacementInitData[] = {\n";
for (auto &replace : replaces_.list) {
suggestionsSource_->stream() << "\
{ small(" << replace.id.size() << "), small(" << replace.replacement.size() << "), small(" << replace.words.size() << ") },\n";
{ smallchar(" << replace.id.size() << "), smallchar(" << replace.replacement.size() << "), smallchar(" << replace.words.size() << ") },\n";
}
suggestionsSource_->stream() << "};\n\
\n\
@ -984,7 +984,7 @@ void Generator::writeIntBinary(common::CppFile *source, int data) {
++_binaryFullLength;
}
void Generator::writeUintBinary(common::CppFile *source, uint32 data) {
void Generator::writeUintBinary(common::CppFile *source, uint32_t data) {
if (_binaryFullLength > 0) source->stream() << ",";
if (!_binaryCount++) {
source->stream() << "\n";

View File

@ -20,6 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once
#include <cstdint>
#include <memory>
#include <QtCore/QString>
#include <QtCore/QSet>
@ -31,8 +32,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
namespace codegen {
namespace emoji {
using uint32 = unsigned int;
class Generator {
public:
Generator(const Options &options);
@ -66,7 +65,7 @@ private:
void startBinary();
bool writeStringBinary(common::CppFile *source, const QString &string);
void writeIntBinary(common::CppFile *source, int data);
void writeUintBinary(common::CppFile *source, uint32 data);
void writeUintBinary(common::CppFile *source, uint32_t data);
const common::ProjectInfo &project_;
int colorsCount_ = 0;

View File

@ -0,0 +1,9 @@
add_executable(codegen_lang
generator.cpp
main.cpp
options.cpp
parsed_file.cpp
processor.cpp
)
target_link_libraries(codegen_lang codegen_common Qt5::Core Qt5::Gui)
qt5_use_modules(codegen_lang Core Gui)

View File

@ -150,8 +150,8 @@ QString lang(LangKey key);\n\
for (auto &tagData : entry.tags) {
auto &tag = tagData.tag;
auto isPluralTag = isPlural && (tag == kPluralTag);
genericParams.push_back("lngtag_" + tag + ", " + (isPluralTag ? "float64 " : "const ResultString &") + tag + "__val");
params.push_back("lngtag_" + tag + ", " + (isPluralTag ? "float64 " : "const QString &") + tag + "__val");
genericParams.push_back("lngtag_" + tag + ", " + (isPluralTag ? "double " : "const ResultString &") + tag + "__val");
params.push_back("lngtag_" + tag + ", " + (isPluralTag ? "double " : "const QString &") + tag + "__val");
if (isPluralTag) {
plural = "\tauto plural = Lang::Plural(" + key + ", " + kPluralTag + "__val);\n";
applyTags.push_back("\tresult = Lang::ReplaceTag<ResultString>::Call(std::move(result), lt_" + tag + ", Lang::StartReplacements<ResultString>::Call(std::move(plural.replacement)));\n");

View File

@ -0,0 +1,9 @@
add_executable(codegen_numbers
generator.cpp
main.cpp
options.cpp
parsed_file.cpp
processor.cpp
)
target_link_libraries(codegen_numbers codegen_common Qt5::Core)
qt5_use_modules(codegen_numbers Core)

View File

@ -51,7 +51,7 @@ bool Generator::writeSource() {
QVector<int> phoneNumberParse(const QString &number) {\n\
QVector<int> result;\n\
\n\
int32 len = number.size();\n\
int32_t len = number.size();\n\
if (len > 0) switch (number.at(0).unicode()) {\n";
QString already;

View File

@ -311,7 +311,7 @@ with open(input_file) as f:
prmsInit = [];
prmsNames = [];
if (hasFlags != ''):
funcsText += '\tenum class Flag : int32 {\n';
funcsText += '\tenum class Flag : int32_t {\n';
maxbit = 0;
parentFlagsCheck['MTP' + name] = {};
for paramName in conditionsList:
@ -356,12 +356,12 @@ with open(input_file) as f:
funcsText += '\tMTP' + name + '(' + ', '.join(prmsStr) + ') : ' + ', '.join(prmsInit) + ' {\n\t}\n';
funcsText += '\n';
funcsText += '\tuint32 innerLength() const;\n'; # count size
funcsText += '\tuint32_t innerLength() const;\n'; # count size
if (isTemplate != ''):
methodBodies += 'template <typename TQueryType>\n'
methodBodies += 'uint32 MTP' + name + '<TQueryType>::innerLength() const {\n';
methodBodies += 'uint32_t MTP' + name + '<TQueryType>::innerLength() const {\n';
else:
methodBodies += 'uint32 MTP' + name + '::innerLength() const {\n';
methodBodies += 'uint32_t MTP' + name + '::innerLength() const {\n';
size = [];
for k in prmsList:
v = prms[k];
@ -453,7 +453,7 @@ def addTextSerialize(lst, dct, dataLetter):
conditions = data[6];
trivialConditions = data[7];
result += 'void Serialize_' + name + '(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {\n';
result += 'void Serialize_' + name + '(MTPStringLogger &to, int32_t stage, int32_t lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32_t iflag) {\n';
if (len(conditions)):
result += '\tMTP' + dataLetter + name + '::Flags flag(iflag);\n\n';
if (len(prms)):
@ -592,7 +592,7 @@ for restype in typesList:
writeText = '';
if (hasFlags != ''):
dataText += '\tenum class Flag : int32 {\n';
dataText += '\tenum class Flag : int32_t {\n';
maxbit = 0;
parentFlagsCheck['MTPD' + name] = {};
for paramName in conditionsList:
@ -752,8 +752,8 @@ for restype in typesList:
if (withData):
typesText += getters;
typesText += '\n\tuint32 innerLength() const;\n'; # size method
methods += '\nuint32 MTP' + restype + '::innerLength() const {\n';
typesText += '\n\tuint32_t innerLength() const;\n'; # size method
methods += '\nuint32_t MTP' + restype + '::innerLength() const {\n';
if (withType and sizeCases):
methods += '\tswitch (_type) {\n';
methods += sizeCases;
@ -853,7 +853,7 @@ for childName in parentFlagsList:
# manual types added here
textSerializeMethods += '\
void _serialize_rpc_result(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {\n\
void _serialize_rpc_result(MTPStringLogger &to, int32_t stage, int32_t lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32_t iflag) {\n\
if (stage) {\n\
to.add(",\\n").addSpaces(lev);\n\
} else {\n\
@ -867,7 +867,7 @@ void _serialize_rpc_result(MTPStringLogger &to, int32 stage, int32 lev, Types &t
}\n\
}\n\
\n\
void _serialize_msg_container(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {\n\
void _serialize_msg_container(MTPStringLogger &to, int32_t stage, int32_t lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32_t iflag) {\n\
if (stage) {\n\
to.add(",\\n").addSpaces(lev);\n\
} else {\n\
@ -880,7 +880,7 @@ void _serialize_msg_container(MTPStringLogger &to, int32 stage, int32 lev, Types
}\n\
}\n\
\n\
void _serialize_core_message(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag) {\n\
void _serialize_core_message(MTPStringLogger &to, int32_t stage, int32_t lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32_t iflag) {\n\
if (stage) {\n\
to.add(",\\n").addSpaces(lev);\n\
} else {\n\
@ -966,7 +966,7 @@ enum {\n\
// Factory methods declaration\n\
' + factories + '\n\
// Human-readable text serialization\n\
void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpPrime cons, uint32 level, mtpPrime vcons);\n'
void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpPrime cons, uint32_t level, mtpPrime vcons);\n'
source = '\
/*\n\
@ -1007,12 +1007,12 @@ public:\n\
' + methods + '\n\
\n\
using Types = QVector<mtpTypeId>;\n\
using StagesFlags = QVector<int32>;\n\
using StagesFlags = QVector<int32_t>;\n\
\n\
' + textSerializeMethods + '\n\
namespace {\n\
\n\
using TextSerializer = void (*)(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 iflag);\n\
using TextSerializer = void (*)(MTPStringLogger &to, int32_t stage, int32_t lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32_t iflag);\n\
using TextSerializers = QMap<mtpTypeId, TextSerializer>;\n\
\n\
QMap<mtpTypeId, TextSerializer> createTextSerializers() {\n\
@ -1025,17 +1025,17 @@ QMap<mtpTypeId, TextSerializer> createTextSerializers() {\n\
\n\
} // namespace\n\
\n\
void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpPrime cons, uint32 level, mtpPrime vcons) {\n\
void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpPrime cons, uint32_t level, mtpPrime vcons) {\n\
static auto serializers = createTextSerializers();\n\
\n\
QVector<mtpTypeId> types, vtypes;\n\
QVector<int32> stages, flags;\n\
QVector<int32_t> stages, flags;\n\
types.reserve(20); vtypes.reserve(20); stages.reserve(20); flags.reserve(20);\n\
types.push_back(mtpTypeId(cons)); vtypes.push_back(mtpTypeId(vcons)); stages.push_back(0); flags.push_back(0);\n\
\n\
const mtpPrime *start = from;\n\
mtpTypeId type = cons, vtype = vcons;\n\
int32 stage = 0, flag = 0;\n\
int32_t stage = 0, flag = 0;\n\
\n\
while (!types.isEmpty()) {\n\
type = types.back();\n\
@ -1052,7 +1052,7 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
start = ++from;\n\
}\n\
\n\
int32 lev = level + types.size() - 1;\n\
int32_t lev = level + types.size() - 1;\n\
auto it = serializers.constFind(type);\n\
if (it != serializers.cend()) {\n\
(*it.value())(to, stage, lev, types, vtypes, stages, flags, start, end, flag);\n\

View File

@ -0,0 +1,11 @@
add_executable(codegen_style
generator.cpp
main.cpp
module.cpp
options.cpp
parsed_file.cpp
processor.cpp
structure_types.cpp
)
target_link_libraries(codegen_style codegen_common Qt5::Core Qt5::Gui)
qt5_use_modules(codegen_style Core Gui)

View File

@ -46,7 +46,7 @@ constexpr int kErrorBadIconFormat = 862;
class Crc32Table {
public:
Crc32Table() {
quint32 poly = 0x04c11db7;
uint32_t poly = 0x04c11db7;
for (auto i = 0; i != 256; ++i) {
_data[i] = reflect(i, 8) << 24;
for (auto j = 0; j != 8; ++j) {
@ -56,13 +56,13 @@ public:
}
}
inline quint32 operator[](int index) const {
inline uint32_t operator[](int index) const {
return _data[index];
}
private:
quint32 reflect(quint32 val, char ch) {
quint32 result = 0;
uint32_t reflect(uint32_t val, char ch) {
uint32_t result = 0;
for (int i = 1; i < (ch + 1); ++i) {
if (val & 1) {
result |= 1 << (ch - i);
@ -72,21 +72,21 @@ private:
return result;
}
quint32 _data[256];
uint32_t _data[256];
};
qint32 hashCrc32(const void *data, int len) {
int32_t hashCrc32(const void *data, int len) {
static Crc32Table table;
const uchar *buffer = static_cast<const uchar *>(data);
quint32 crc = 0xffffffff;
uint32_t crc = 0xffffffff;
for (int i = 0; i != len; ++i) {
crc = (crc >> 8) ^ table[(crc & 0xFF) ^ buffer[i]];
}
return static_cast<qint32>(crc ^ 0xffffffff);
return static_cast<int32_t>(crc ^ 0xffffffff);
}
char hexChar(uchar ch) {
@ -504,7 +504,7 @@ public:\n\
return *this;\n\
}\n\
\n\
static int32 Checksum();\n\
static int32_t Checksum();\n\
\n\
~palette() {\n\
clear();\n\
@ -809,7 +809,7 @@ void palette::finalize() {\n\
source_->stream() << "\
}\n\
\n\
int32 palette::Checksum() {\n\
int32_t palette::Checksum() {\n\
return " << checksum << ";\n\
}\n";
@ -1178,7 +1178,7 @@ QByteArray iconMaskValueSize(int width, int height) {
{
QDataStream stream(&result, QIODevice::Append);
stream.setVersion(QDataStream::Qt_5_1);
stream << qint32(width) << qint32(height);
stream << int32_t(width) << int32_t(height);
}
return result;
}

View File

@ -23,7 +23,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include <memory>
#include <string>
#include <functional>
#include <QImage>
#include <QtGui/QImage>
#include "codegen/common/basic_tokenized_file.h"
#include "codegen/style/options.h"
#include "codegen/style/module.h"

Some files were not shown because too many files have changed in this diff Show More