mirror of
https://github.com/raysan5/raylib.git
synced 2026-04-12 01:59:09 -04:00
Redesigned to support disabling features on compilation with `-DSUPPORT_FEATURE=0` REMOVED: `SUPPORT_DEFAULT_FONT`, always supported REMOVED: `SUPPORT_IMAGE_MANIPULATION `, always supported REMOVED: `SUPPORT_TEXT_MANIPULATION`, always supported REDESIGNED: `SUPPORT_FONT_ATLAS_WHITE_REC` to `FONT_ATLAS_CORNER_REC_SIZE` REVIEWED: Config values (other than 0-1) are already defined on respective modules Other config tweaks here and there
This commit is contained in:
@ -713,7 +713,7 @@ const char *GetKeyName(int key)
|
||||
// Register all input events
|
||||
void PollInputEvents(void)
|
||||
{
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM)
|
||||
#if SUPPORT_GESTURES_SYSTEM
|
||||
// NOTE: Gestures update must be called every frame to reset gestures correctly
|
||||
// because ProcessGestureEvent() is just called on an event, not every frame
|
||||
UpdateGestures();
|
||||
@ -1065,11 +1065,11 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
||||
// Initialize hi-res timer
|
||||
InitTimer();
|
||||
|
||||
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
|
||||
#if SUPPORT_MODULE_RTEXT
|
||||
// Load default font
|
||||
// WARNING: External function: Module required: rtext
|
||||
LoadFontDefault();
|
||||
#if defined(SUPPORT_MODULE_RSHAPES)
|
||||
#if SUPPORT_MODULE_RSHAPES
|
||||
// Set font white rectangle for shapes drawing, so shapes and text can be batched together
|
||||
// WARNING: rshapes module is required, if not available, default internal white rectangle is used
|
||||
Rectangle rec = GetFontDefault().recs[95];
|
||||
@ -1085,7 +1085,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#if defined(SUPPORT_MODULE_RSHAPES)
|
||||
#if SUPPORT_MODULE_RSHAPES
|
||||
// Set default texture and rectangle to be used for shapes drawing
|
||||
// NOTE: rlgl default texture is a 1x1 pixel UNCOMPRESSED_R8G8B8A8
|
||||
Texture2D texture = { rlGetTextureIdDefault(), 1, 1, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
|
||||
@ -1347,7 +1347,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM)
|
||||
#if SUPPORT_GESTURES_SYSTEM
|
||||
GestureEvent gestureEvent = { 0 };
|
||||
|
||||
gestureEvent.pointCount = 0;
|
||||
|
||||
@ -65,7 +65,7 @@
|
||||
#define GLFW_NATIVE_INCLUDE_NONE // To avoid some symbols re-definition in windows.h
|
||||
#include "GLFW/glfw3native.h"
|
||||
|
||||
#if defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
|
||||
#if SUPPORT_WINMM_HIGHRES_TIMER && !SUPPORT_BUSY_WAIT_LOOP
|
||||
// NOTE: Those functions require linking with winmm library
|
||||
//#pragma warning(disable: 4273)
|
||||
__declspec(dllimport) unsigned int __stdcall timeEndPeriod(unsigned int uPeriod);
|
||||
@ -1048,7 +1048,7 @@ Image GetClipboardImage(void)
|
||||
{
|
||||
Image image = { 0 };
|
||||
|
||||
#if defined(SUPPORT_CLIPBOARD_IMAGE)
|
||||
#if SUPPORT_CLIPBOARD_IMAGE
|
||||
#if defined(_WIN32)
|
||||
unsigned long long int dataSize = 0;
|
||||
void *bmpData = NULL;
|
||||
@ -1062,7 +1062,7 @@ Image GetClipboardImage(void)
|
||||
#else
|
||||
TRACELOG(LOG_WARNING, "GetClipboardImage() not implemented on target platform");
|
||||
#endif
|
||||
#endif // SUPPORT_CLIPBOARD_IMAGE
|
||||
#endif
|
||||
|
||||
return image;
|
||||
}
|
||||
@ -1202,7 +1202,7 @@ const char *GetKeyName(int key)
|
||||
// Register all input events
|
||||
void PollInputEvents(void)
|
||||
{
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM)
|
||||
#if SUPPORT_GESTURES_SYSTEM
|
||||
// NOTE: Gestures update must be called every frame to reset gestures correctly
|
||||
// because ProcessGestureEvent() is just called on an event, not every frame
|
||||
UpdateGestures();
|
||||
@ -1514,7 +1514,7 @@ int InitPlatform(void)
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Choose OpenGL minor version (just hint)
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_FALSE);
|
||||
#if defined(RLGL_ENABLE_OPENGL_DEBUG_CONTEXT)
|
||||
#if RLGL_ENABLE_OPENGL_DEBUG_CONTEXT
|
||||
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); // Enable OpenGL Debug Context
|
||||
#endif
|
||||
}
|
||||
@ -1819,7 +1819,7 @@ void ClosePlatform(void)
|
||||
glfwDestroyWindow(platform.handle);
|
||||
glfwTerminate();
|
||||
|
||||
#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
|
||||
#if defined(_WIN32) && SUPPORT_WINMM_HIGHRES_TIMER && !SUPPORT_BUSY_WAIT_LOOP
|
||||
timeEndPeriod(1); // Restore time period
|
||||
#endif
|
||||
}
|
||||
@ -2049,7 +2049,7 @@ static void MouseButtonCallback(GLFWwindow *window, int button, int action, int
|
||||
CORE.Input.Mouse.currentButtonState[button] = action;
|
||||
CORE.Input.Touch.currentTouchState[button] = action;
|
||||
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM) && defined(SUPPORT_MOUSE_GESTURES)
|
||||
#if SUPPORT_GESTURES_SYSTEM && defined(SUPPORT_MOUSE_GESTURES)
|
||||
// Process mouse events as touches to be able to use mouse-gestures
|
||||
GestureEvent gestureEvent = { 0 };
|
||||
|
||||
@ -2084,7 +2084,7 @@ static void MouseCursorPosCallback(GLFWwindow *window, double x, double y)
|
||||
CORE.Input.Mouse.currentPosition.y = (float)y;
|
||||
CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition;
|
||||
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM) && defined(SUPPORT_MOUSE_GESTURES)
|
||||
#if SUPPORT_GESTURES_SYSTEM && defined(SUPPORT_MOUSE_GESTURES)
|
||||
// Process mouse events as touches to be able to use mouse-gestures
|
||||
GestureEvent gestureEvent = { 0 };
|
||||
|
||||
|
||||
@ -423,7 +423,6 @@ void *SDL_GetClipboardData(const char *mime_type, size_t *size)
|
||||
// We could possibly implement it ourselves in this case for some easier platforms
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif // USING_VERSION_SDL3
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -1163,7 +1162,7 @@ Image GetClipboardImage(void)
|
||||
{
|
||||
Image image = { 0 };
|
||||
|
||||
#if defined(SUPPORT_CLIPBOARD_IMAGE)
|
||||
#if SUPPORT_CLIPBOARD_IMAGE
|
||||
// Let's hope compiler put these arrays in static memory
|
||||
const char *imageFormats[] = {
|
||||
"image/bmp",
|
||||
@ -1350,7 +1349,7 @@ const char *GetKeyName(int key)
|
||||
// Register all input events
|
||||
void PollInputEvents(void)
|
||||
{
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM)
|
||||
#if SUPPORT_GESTURES_SYSTEM
|
||||
// NOTE: Gestures update must be called every frame to reset gestures correctly
|
||||
// because ProcessGestureEvent() is just called on an event, not every frame
|
||||
UpdateGestures();
|
||||
@ -1892,7 +1891,7 @@ void PollInputEvents(void)
|
||||
default: break;
|
||||
}
|
||||
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM)
|
||||
#if SUPPORT_GESTURES_SYSTEM
|
||||
if (touchAction > -1)
|
||||
{
|
||||
// Process mouse events as touches to be able to use mouse-gestures
|
||||
@ -1989,7 +1988,7 @@ int InitPlatform(void)
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
#if defined(RLGL_ENABLE_OPENGL_DEBUG_CONTEXT)
|
||||
#if RLGL_ENABLE_OPENGL_DEBUG_CONTEXT
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); // Enable OpenGL Debug Context
|
||||
#endif
|
||||
}
|
||||
@ -2113,7 +2112,7 @@ int InitPlatform(void)
|
||||
// NOTE: No need to call InitTimer(), let SDL manage it internally
|
||||
CORE.Time.previous = GetTime(); // Get time as double
|
||||
|
||||
#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
|
||||
#if defined(_WIN32) && SUPPORT_WINMM_HIGHRES_TIMER && !SUPPORT_BUSY_WAIT_LOOP
|
||||
SDL_SetHint(SDL_HINT_TIMER_RESOLUTION, "1"); // SDL equivalent of timeBeginPeriod() and timeEndPeriod()
|
||||
#endif
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@ -80,7 +80,7 @@
|
||||
#include <errno.h> // Required for: EBUSY, EAGAIN
|
||||
|
||||
#define MAX_DRM_CACHED_BUFFERS 3
|
||||
#endif // SUPPORT_DRM_CACHE
|
||||
#endif
|
||||
|
||||
#ifndef EGL_OPENGL_ES3_BIT
|
||||
#define EGL_OPENGL_ES3_BIT 0x40
|
||||
@ -160,7 +160,7 @@ static FramebufferCache fbCache[MAX_DRM_CACHED_BUFFERS] = { 0 };
|
||||
static volatile int fbCacheCount = 0;
|
||||
static volatile bool pendingFlip = false;
|
||||
static bool crtcSet = false;
|
||||
#endif // SUPPORT_DRM_CACHE
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
@ -253,7 +253,7 @@ static const short linuxToRaylibMap[KEYMAP_SIZE] = {
|
||||
int InitPlatform(void); // Initialize platform (graphics, inputs and more)
|
||||
void ClosePlatform(void); // Close platform
|
||||
|
||||
#if defined(SUPPORT_SSH_KEYBOARD_RPI)
|
||||
#if SUPPORT_SSH_KEYBOARD_RPI
|
||||
static void InitKeyboard(void); // Initialize raw keyboard system
|
||||
static void RestoreKeyboard(void); // Restore keyboard system
|
||||
static void ProcessKeyboard(void); // Process keyboard events
|
||||
@ -1065,7 +1065,7 @@ const char *GetKeyName(int key)
|
||||
// Register all input events
|
||||
void PollInputEvents(void)
|
||||
{
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM)
|
||||
#if SUPPORT_GESTURES_SYSTEM
|
||||
// NOTE: Gestures update must be called every frame to reset gestures correctly
|
||||
// because ProcessGestureEvent() is just called on an event, not every frame
|
||||
UpdateGestures();
|
||||
@ -1088,7 +1088,7 @@ void PollInputEvents(void)
|
||||
|
||||
PollKeyboardEvents();
|
||||
|
||||
#if defined(SUPPORT_SSH_KEYBOARD_RPI)
|
||||
#if SUPPORT_SSH_KEYBOARD_RPI
|
||||
// NOTE: Keyboard reading could be done using input_event(s) or just read from stdin, both methods are used here
|
||||
// stdin reading is still used for legacy purposes, it allows keyboard input trough SSH console
|
||||
if (!platform.eventKeyboardMode) ProcessKeyboard();
|
||||
@ -1621,7 +1621,7 @@ int InitPlatform(void)
|
||||
//----------------------------------------------------------------------------
|
||||
InitEvdevInput(); // Evdev inputs initialization
|
||||
|
||||
#if defined(SUPPORT_SSH_KEYBOARD_RPI)
|
||||
#if SUPPORT_SSH_KEYBOARD_RPI
|
||||
InitKeyboard(); // Keyboard init (stdin)
|
||||
#endif
|
||||
//----------------------------------------------------------------------------
|
||||
@ -1741,7 +1741,7 @@ void ClosePlatform(void)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(SUPPORT_SSH_KEYBOARD_RPI)
|
||||
#if SUPPORT_SSH_KEYBOARD_RPI
|
||||
// Initialize Keyboard system (using standard input)
|
||||
static void InitKeyboard(void)
|
||||
{
|
||||
@ -1900,7 +1900,7 @@ static void ProcessKeyboard(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // SUPPORT_SSH_KEYBOARD_RPI
|
||||
#endif // SUPPORT_SSH_KEYBOARD_RPI
|
||||
|
||||
// Initialize user input from evdev(/dev/input/event<N>)
|
||||
// this means mouse, keyboard or gamepad devices
|
||||
@ -2196,7 +2196,7 @@ static void PollKeyboardEvents(void)
|
||||
// Check if the event is a key event
|
||||
if (event.type != EV_KEY) continue;
|
||||
|
||||
#if defined(SUPPORT_SSH_KEYBOARD_RPI)
|
||||
#if SUPPORT_SSH_KEYBOARD_RPI
|
||||
// If the event was a key, we know a working keyboard is connected, so disable the SSH keyboard
|
||||
platform.eventKeyboardMode = true;
|
||||
#endif
|
||||
@ -2552,7 +2552,7 @@ static void PollMouseEvents(void)
|
||||
CORE.Input.Touch.pointId[i] = -1;
|
||||
}
|
||||
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM)
|
||||
#if SUPPORT_GESTURES_SYSTEM
|
||||
if (touchAction > -1)
|
||||
{
|
||||
GestureEvent gestureEvent = { 0 };
|
||||
|
||||
@ -435,7 +435,7 @@ const char *GetKeyName(int key)
|
||||
// Register all input events
|
||||
void PollInputEvents(void)
|
||||
{
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM)
|
||||
#if SUPPORT_GESTURES_SYSTEM
|
||||
// NOTE: Gestures update must be called every frame to reset gestures correctly
|
||||
// because ProcessGestureEvent() is just called on an event, not every frame
|
||||
UpdateGestures();
|
||||
|
||||
@ -1007,7 +1007,7 @@ const char *GetKeyName(int key)
|
||||
// Register all input events
|
||||
void PollInputEvents(void)
|
||||
{
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM)
|
||||
#if SUPPORT_GESTURES_SYSTEM
|
||||
// NOTE: Gestures update must be called every frame to reset gestures correctly
|
||||
// because ProcessGestureEvent() is just called on an event, not every frame
|
||||
UpdateGestures();
|
||||
@ -1210,7 +1210,7 @@ int InitPlatform(void)
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Choose OpenGL minor version (just hint)
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_FALSE);
|
||||
#if defined(RLGL_ENABLE_OPENGL_DEBUG_CONTEXT)
|
||||
#if RLGL_ENABLE_OPENGL_DEBUG_CONTEXT
|
||||
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); // Enable OpenGL Debug Context
|
||||
#endif
|
||||
}
|
||||
@ -1475,15 +1475,15 @@ static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float s
|
||||
// GLFW3: Called on windows minimized/restored
|
||||
static void WindowIconifyCallback(GLFWwindow *window, int iconified)
|
||||
{
|
||||
if (iconified) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // The window was iconified
|
||||
else FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // The window was restored
|
||||
if (iconified) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // The window was iconified
|
||||
else FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // The window was restored
|
||||
}
|
||||
|
||||
// GLFW3: Called on windows get/lose focus
|
||||
static void WindowFocusCallback(GLFWwindow *window, int focused)
|
||||
{
|
||||
if (focused) FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window was focused
|
||||
else FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window lost focus
|
||||
if (focused) FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window was focused
|
||||
else FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window lost focus
|
||||
}
|
||||
|
||||
// GLFW3: Called on file-drop over the window
|
||||
@ -1564,7 +1564,7 @@ static void MouseButtonCallback(GLFWwindow *window, int button, int action, int
|
||||
CORE.Input.Mouse.currentButtonState[button] = action;
|
||||
CORE.Input.Touch.currentTouchState[button] = action;
|
||||
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM) && defined(SUPPORT_MOUSE_GESTURES)
|
||||
#if SUPPORT_GESTURES_SYSTEM && defined(SUPPORT_MOUSE_GESTURES)
|
||||
// Process mouse events as touches to be able to use mouse-gestures
|
||||
GestureEvent gestureEvent = { 0 };
|
||||
|
||||
@ -1605,7 +1605,7 @@ static void MouseMoveCallback(GLFWwindow *window, double x, double y)
|
||||
CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition;
|
||||
}
|
||||
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM) && defined(SUPPORT_MOUSE_GESTURES)
|
||||
#if SUPPORT_GESTURES_SYSTEM && defined(SUPPORT_MOUSE_GESTURES)
|
||||
// Process mouse events as touches to be able to use mouse-gestures
|
||||
GestureEvent gestureEvent = { 0 };
|
||||
|
||||
@ -1748,7 +1748,7 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent
|
||||
CORE.Input.Mouse.currentPosition.y = CORE.Input.Touch.position[0].y;
|
||||
}
|
||||
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM)
|
||||
#if SUPPORT_GESTURES_SYSTEM
|
||||
GestureEvent gestureEvent = { 0 };
|
||||
gestureEvent.pointCount = CORE.Input.Touch.pointCount;
|
||||
|
||||
|
||||
@ -983,7 +983,7 @@ const char *GetKeyName(int key)
|
||||
// Register all input events
|
||||
void PollInputEvents(void)
|
||||
{
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM)
|
||||
#if SUPPORT_GESTURES_SYSTEM
|
||||
// NOTE: Gestures update must be called every frame to reset gestures correctly
|
||||
// because ProcessGestureEvent() is just called on an event, not every frame
|
||||
UpdateGestures();
|
||||
@ -1321,7 +1321,7 @@ static EM_BOOL EmscriptenFocusCallback(int eventType, const EmscriptenFocusEvent
|
||||
|
||||
switch (eventType)
|
||||
{
|
||||
case EMSCRIPTEN_EVENT_BLUR: FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); break; // The canvas lost focus
|
||||
case EMSCRIPTEN_EVENT_BLUR: FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); break;
|
||||
case EMSCRIPTEN_EVENT_FOCUS: FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); break;
|
||||
default: consumed = 0; break;
|
||||
}
|
||||
@ -1457,7 +1457,7 @@ static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent
|
||||
default: break;
|
||||
}
|
||||
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM) && defined(SUPPORT_MOUSE_GESTURES)
|
||||
#if SUPPORT_GESTURES_SYSTEM && defined(SUPPORT_MOUSE_GESTURES)
|
||||
// Process mouse events as touches to be able to use mouse-gestures
|
||||
GestureEvent gestureEvent = { 0 };
|
||||
|
||||
@ -1529,7 +1529,7 @@ static EM_BOOL EmscriptenMouseMoveCallback(int eventType, const EmscriptenMouseE
|
||||
CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition;
|
||||
}
|
||||
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM) && defined(SUPPORT_MOUSE_GESTURES)
|
||||
#if SUPPORT_GESTURES_SYSTEM && defined(SUPPORT_MOUSE_GESTURES)
|
||||
// Process mouse events as touches to be able to use mouse-gestures
|
||||
GestureEvent gestureEvent = { 0 };
|
||||
|
||||
@ -1639,7 +1639,7 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent
|
||||
CORE.Input.Mouse.currentPosition.y = CORE.Input.Touch.position[0].y;
|
||||
}
|
||||
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM)
|
||||
#if SUPPORT_GESTURES_SYSTEM
|
||||
GestureEvent gestureEvent = { 0 };
|
||||
gestureEvent.pointCount = CORE.Input.Touch.pointCount;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user