mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-19 12:35:52 -04:00
Cleanup utf8 decoding/encoding
This commit is contained in:
parent
45b4af80af
commit
375f1a70b1
@ -198,7 +198,7 @@ static void Window_UpdateWindowState(void) {
|
||||
break;
|
||||
}
|
||||
|
||||
Event_RaiseVoid(&WindowEvents_WindowStateChanged);
|
||||
Event_RaiseVoid(&WindowEvents_StateChanged);
|
||||
Window_UpdateSize();
|
||||
Event_RaiseVoid(&WindowEvents_Resized);
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ struct Event_Void WindowEvents_Closing; /* Window is about to close *
|
||||
struct Event_Void WindowEvents_Closed; /* Window has closed */
|
||||
struct Event_Void WindowEvents_VisibilityChanged; /* Visibility of the window changed */
|
||||
struct Event_Void WindowEvents_FocusChanged; /* Focus of the window changed */
|
||||
struct Event_Void WindowEvents_WindowStateChanged; /* WindowState of the window changed */
|
||||
struct Event_Void WindowEvents_StateChanged; /* WindowState of the window changed */
|
||||
|
||||
struct Event_Int KeyEvents_Press; /* Raised when a character is typed. Arg is a character */
|
||||
struct Event_Int KeyEvents_Down; /* Raised when a key is pressed. Arg is a member of Key enumeration */
|
||||
|
@ -822,12 +822,12 @@ ReturnCode Dat_Load(struct Stream* stream) {
|
||||
static int Cw_WriteEndString(uint8_t* data, const String* text) {
|
||||
Codepoint cp;
|
||||
uint8_t* cur = data + 2;
|
||||
int i, bytes, len = 0;
|
||||
int i, wrote, len = 0;
|
||||
|
||||
for (i = 0; i < text->length; i++) {
|
||||
cp = Convert_CP437ToUnicode(text->buffer[i]);
|
||||
bytes = Stream_WriteUtf8(cur, cp);
|
||||
len += bytes; cur += bytes;
|
||||
wrote = Convert_UnicodeToUtf8(cp, cur);
|
||||
len += wrote; cur += wrote;
|
||||
}
|
||||
|
||||
Stream_SetU16_BE(data, len);
|
||||
|
@ -561,7 +561,7 @@ void Window_ProcessEvents(void) {
|
||||
|
||||
case PropertyNotify:
|
||||
if (e.xproperty.atom == net_wm_state) {
|
||||
Event_RaiseVoid(&WindowEvents_WindowStateChanged);
|
||||
Event_RaiseVoid(&WindowEvents_StateChanged);
|
||||
}
|
||||
|
||||
/*if (e.xproperty.atom == net_frame_extents) {
|
||||
@ -608,9 +608,9 @@ void Window_ProcessEvents(void) {
|
||||
int i, len = 0;
|
||||
|
||||
for (i = 0; i < clipboard_copy_text.length; i++) {
|
||||
Codepoint cp = Convert_CP437ToUnicode(clipboard_copy_text.buffer[i]);
|
||||
uint8_t* cur = data + len;
|
||||
len += Stream_WriteUtf8(cur, cp);
|
||||
uint8_t* cur = data + len;
|
||||
Codepoint cp = Convert_CP437ToUnicode(clipboard_copy_text.buffer[i]);
|
||||
len += Convert_UnicodeToUtf8(cp, cur);
|
||||
}
|
||||
|
||||
XChangeProperty(win_display, reply.xselection.requestor, reply.xselection.property, xa_utf8_string, 8,
|
||||
|
@ -1804,15 +1804,18 @@ int Platform_GetCommandLineArgs(int argc, STRING_REF const char** argv, String*
|
||||
#ifdef CC_BUILD_POSIX
|
||||
int Platform_ConvertString(void* data, const String* src) {
|
||||
uint8_t* dst = data;
|
||||
uint8_t* cur;
|
||||
|
||||
Codepoint cp;
|
||||
int i, len;
|
||||
int i, len = 0;
|
||||
if (src->length > FILENAME_SIZE) ErrorHandler_Fail("String too long to expand");
|
||||
|
||||
for (i = 0; i < src->length; i++) {
|
||||
cp = Convert_CP437ToUnicode(src->buffer[i]);
|
||||
len = Stream_WriteUtf8(dst, cp); dst += len;
|
||||
cur = data + len;
|
||||
cp = Convert_CP437ToUnicode(src->buffer[i]);
|
||||
len += Convert_UnicodeToUtf8(cp, cur);
|
||||
}
|
||||
*dst = '\0';
|
||||
dst[len] = '\0';
|
||||
return len;
|
||||
}
|
||||
|
||||
|
@ -50,13 +50,13 @@ void GraphicsMode_MakeDefault(struct GraphicsMode* m);
|
||||
/* NOTE: Only useful for platform specific function calls - do NOT try to interpret the data.
|
||||
Returns the number of bytes written, excluding trailing NULL terminator. */
|
||||
NOINLINE_ int Platform_ConvertString(void* data, const String* src);
|
||||
/* Initalises the platform specific state */
|
||||
/* Initalises the platform specific state. */
|
||||
void Platform_Init(void);
|
||||
/* Frees the platform specific state */
|
||||
/* Frees the platform specific state. */
|
||||
void Platform_Free(void);
|
||||
/* Sets current directory to directory executable is in */
|
||||
/* Sets current directory to the directory the executable is in. */
|
||||
void Platform_SetWorkingDir(void);
|
||||
/* Exits the process with the given return code */
|
||||
/* Exits the process with the given return code .*/
|
||||
void Platform_Exit(ReturnCode code);
|
||||
/* Gets the command line arguments passed to the program. */
|
||||
int Platform_GetCommandLineArgs(int argc, STRING_REF const char** argv, String* args);
|
||||
|
66
src/Stream.c
66
src/Stream.c
@ -380,45 +380,25 @@ ReturnCode Stream_ReadU32_BE(struct Stream* s, uint32_t* value) {
|
||||
/*########################################################################################################################*
|
||||
*--------------------------------------------------Read/Write strings-----------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
ReturnCode Stream_ReadUtf8(struct Stream* s, Codepoint* cp) {
|
||||
uint8_t data;
|
||||
ReturnCode res = s->ReadU8(s, &data);
|
||||
if (res) return res;
|
||||
|
||||
/* Header byte is just the raw codepoint (common case) */
|
||||
if (data <= 0x7F) { *cp = data; return 0; }
|
||||
|
||||
/* Header byte encodes variable number of following bytes */
|
||||
/* The remaining bits of the header form first part of the character */
|
||||
int byteCount = 0, i;
|
||||
for (i = 7; i >= 0; i--) {
|
||||
if (data & (1 << i)) {
|
||||
byteCount++;
|
||||
data &= (uint8_t)~(1 << i);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*cp = data;
|
||||
for (i = 0; i < byteCount - 1; i++) {
|
||||
if ((res = s->ReadU8(s, &data))) return res;
|
||||
|
||||
*cp <<= 6;
|
||||
/* Top two bits of each are always 10 */
|
||||
*cp |= (Codepoint)(data & 0x3F);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ReturnCode Stream_ReadLine(struct Stream* s, String* text) {
|
||||
bool readAny = false;
|
||||
Codepoint cp;
|
||||
ReturnCode res;
|
||||
text->length = 0;
|
||||
|
||||
for (;;) {
|
||||
res = Stream_ReadUtf8(s, &cp);
|
||||
uint8_t tmp[8];
|
||||
uint32_t len;
|
||||
|
||||
text->length = 0;
|
||||
for (;;) {
|
||||
len = 0;
|
||||
|
||||
/* Read a UTF8 character from the stream */
|
||||
/* (in most cases it's just one byte) */
|
||||
do {
|
||||
if ((res = s->ReadU8(s, &tmp[len]))) break;
|
||||
len++;
|
||||
} while (!Convert_Utf8ToUnicode(&cp, tmp, len));
|
||||
|
||||
if (res == ERR_END_OF_STREAM) break;
|
||||
if (res) return res;
|
||||
|
||||
@ -431,22 +411,6 @@ ReturnCode Stream_ReadLine(struct Stream* s, String* text) {
|
||||
return readAny ? 0 : ERR_END_OF_STREAM;
|
||||
}
|
||||
|
||||
int Stream_WriteUtf8(uint8_t* buffer, Codepoint cp) {
|
||||
if (cp <= 0x7F) {
|
||||
buffer[0] = (uint8_t)cp;
|
||||
return 1;
|
||||
} else if (cp <= 0x7FF) {
|
||||
buffer[0] = 0xC0 | ((cp >> 6) & 0x1F);
|
||||
buffer[1] = 0x80 | ((cp) & 0x3F);
|
||||
return 2;
|
||||
} else {
|
||||
buffer[0] = 0xE0 | ((cp >> 12) & 0x0F);
|
||||
buffer[1] = 0x80 | ((cp >> 6) & 0x3F);
|
||||
buffer[2] = 0x80 | ((cp) & 0x3F);
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnCode Stream_WriteLine(struct Stream* s, String* text) {
|
||||
uint8_t buffer[2048 + 10]; /* some space for newline */
|
||||
uint8_t* cur;
|
||||
@ -463,7 +427,7 @@ ReturnCode Stream_WriteLine(struct Stream* s, String* text) {
|
||||
|
||||
cur = buffer + len;
|
||||
cp = Convert_CP437ToUnicode(text->buffer[i]);
|
||||
len += Stream_WriteUtf8(cur, cp);
|
||||
len += Convert_UnicodeToUtf8(cp, cur);
|
||||
}
|
||||
|
||||
cur = Platform_NewLine;
|
||||
|
@ -85,13 +85,9 @@ ReturnCode Stream_ReadU32_LE(struct Stream* s, uint32_t* value);
|
||||
/* Reads a big-endian 32 bit unsigned integer from the stream. */
|
||||
ReturnCode Stream_ReadU32_BE(struct Stream* s, uint32_t* value);
|
||||
|
||||
/* Reads a UTF8 encoded character from the stream. */
|
||||
ReturnCode Stream_ReadUtf8(struct Stream* s, Codepoint* cp);
|
||||
/* Reads a line of UTF8 encoded character from the stream. */
|
||||
/* NOTE: Reads one byte at a time. May want to use Stream_ReadonlyBuffered. */
|
||||
ReturnCode Stream_ReadLine(struct Stream* s, String* text);
|
||||
/* Writes a UTF8 encoded character to the stream. */
|
||||
int Stream_WriteUtf8(uint8_t* buffer, Codepoint cp);
|
||||
/* Writes a line of UTF8 encoded text to the stream. */
|
||||
ReturnCode Stream_WriteLine(struct Stream* s, String* text);
|
||||
#endif
|
||||
|
60
src/String.c
60
src/String.c
@ -481,7 +481,7 @@ void String_Format4(String* str, const char* format, const void* a1, const void*
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*-------------------------------------------------------Conversions-------------------------------------------------------*
|
||||
*------------------------------------------------Character set conversions------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
Codepoint Convert_ControlChars[32] = {
|
||||
0x0000, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022,
|
||||
@ -536,16 +536,64 @@ bool Convert_TryUnicodeToCP437(Codepoint cp, char* c) {
|
||||
|
||||
void String_DecodeUtf8(String* str, uint8_t* data, uint32_t len) {
|
||||
Codepoint cp;
|
||||
struct Stream mem;
|
||||
Stream_ReadonlyMemory(&mem, data, len);
|
||||
int read;
|
||||
|
||||
while (len) {
|
||||
read = Convert_Utf8ToUnicode(&cp, data, len);
|
||||
if (!read) break;
|
||||
|
||||
while (mem.Meta.Mem.Left) {
|
||||
ReturnCode res = Stream_ReadUtf8(&mem, &cp);
|
||||
if (res) break; /* Memory read only returns ERR_END_OF_STREAM */
|
||||
String_Append(str, Convert_UnicodeToCP437(cp));
|
||||
data += read; len -= read;
|
||||
}
|
||||
}
|
||||
|
||||
int Convert_Utf8ToUnicode(Codepoint* cp, const uint8_t* data, uint32_t len) {
|
||||
*cp = '\0';
|
||||
if (!len) return 0;
|
||||
|
||||
if (data[0] <= 0x7F) {
|
||||
*cp = data[0];
|
||||
return 1;
|
||||
} else if ((data[0] & 0xE0) == 0xC0) {
|
||||
if (len < 2) return 0;
|
||||
|
||||
*cp = ((data[0] & 0x1F) << 6) | ((data[1] & 0x3F));
|
||||
return 2;
|
||||
} else if ((data[0] & 0xF0) == 0xE0) {
|
||||
if (len < 3) return 0;
|
||||
|
||||
*cp = ((data[0] & 0x0F) << 12) | ((data[1] & 0x3F) << 6)
|
||||
| ((data[2] & 0x3F));
|
||||
return 3;
|
||||
} else {
|
||||
if (len < 4) return 0;
|
||||
|
||||
*cp = ((data[0] & 0x07) << 18) | ((data[1] & 0x3F) << 12)
|
||||
| ((data[2] & 0x3F) << 6) | (data[3] & 0x3F);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
int Convert_UnicodeToUtf8(Codepoint cp, uint8_t* data) {
|
||||
if (cp <= 0x7F) {
|
||||
data[0] = (uint8_t)cp;
|
||||
return 1;
|
||||
} else if (cp <= 0x7FF) {
|
||||
data[0] = 0xC0 | ((cp >> 6) & 0x1F);
|
||||
data[1] = 0x80 | ((cp) & 0x3F);
|
||||
return 2;
|
||||
} else {
|
||||
data[0] = 0xE0 | ((cp >> 12) & 0x0F);
|
||||
data[1] = 0x80 | ((cp >> 6) & 0x3F);
|
||||
data[2] = 0x80 | ((cp) & 0x3F);
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*--------------------------------------------------Numerical conversions--------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
bool Convert_TryParseUInt8(const String* str, uint8_t* value) {
|
||||
int tmp;
|
||||
*value = 0;
|
||||
|
@ -153,6 +153,11 @@ char Convert_UnicodeToCP437(Codepoint cp);
|
||||
bool Convert_TryUnicodeToCP437(Codepoint cp, char* c);
|
||||
/* Appends all characters from UTF8 encoded data to the given string. */
|
||||
void String_DecodeUtf8(String* str, uint8_t* data, uint32_t len);
|
||||
/* Decodes a unicode character from UTF8, returning number of bytes read. */
|
||||
/* Returns 0 if not enough input data to read the character. */
|
||||
int Convert_Utf8ToUnicode(Codepoint* cp, const uint8_t* data, uint32_t len);
|
||||
/* Encodes a unicode character in UTF8, returning number of bytes written. */
|
||||
int Convert_UnicodeToUtf8(Codepoint cp, uint8_t* data);
|
||||
|
||||
/* Attempts to convert the given string into an unsigned 8 bit integer. */
|
||||
NOINLINE_ bool Convert_TryParseUInt8(const String* str, uint8_t* value);
|
||||
|
@ -19,10 +19,10 @@
|
||||
#define Rect_Width(rect) (rect.right - rect.left)
|
||||
#define Rect_Height(rect) (rect.bottom - rect.top)
|
||||
|
||||
HINSTANCE win_Instance;
|
||||
HWND win_Handle;
|
||||
HINSTANCE win_instance;
|
||||
HWND win_handle;
|
||||
HDC win_DC;
|
||||
int win_State = WINDOW_STATE_NORMAL;
|
||||
int win_state;
|
||||
bool invisible_since_creation; /* Set by WindowsMessage.CREATE and consumed by Visible = true (calls BringWindowToFront) */
|
||||
int suppress_resize; /* Used in WindowBorder and WindowState in order to avoid rapid, consecutive resize events */
|
||||
Rect2D prev_bounds; /* Used to restore previous size when leaving fullscreen mode */
|
||||
@ -98,7 +98,7 @@ static Key Window_MapKey(WPARAM key) {
|
||||
|
||||
static void Window_Destroy(void) {
|
||||
if (!Window_Exists) return;
|
||||
DestroyWindow(win_Handle);
|
||||
DestroyWindow(win_handle);
|
||||
Window_Exists = false;
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ static void Window_DoSetHiddenBorder(bool value) {
|
||||
|
||||
/* To ensure maximized/minimized windows work correctly, reset state to normal,
|
||||
change the border, then go back to maximized/minimized. */
|
||||
int state = win_State;
|
||||
int state = win_state;
|
||||
Window_ResetWindowState();
|
||||
DWORD style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
||||
style |= (value ? WS_POPUP : WS_OVERLAPPEDWINDOW);
|
||||
@ -135,8 +135,8 @@ static void Window_DoSetHiddenBorder(bool value) {
|
||||
/* This avoids leaving garbage on the background window. */
|
||||
if (was_visible) Window_SetVisible(false);
|
||||
|
||||
SetWindowLongW(win_Handle, GWL_STYLE, style);
|
||||
SetWindowPos(win_Handle, NULL, 0, 0, Rect_Width(rect), Rect_Height(rect),
|
||||
SetWindowLongW(win_handle, GWL_STYLE, style);
|
||||
SetWindowPos(win_handle, NULL, 0, 0, Rect_Width(rect), Rect_Height(rect),
|
||||
SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
|
||||
|
||||
/* Force window to redraw update its borders, but only if it's
|
||||
@ -185,7 +185,7 @@ static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wPara
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
{
|
||||
WINDOWPOS* pos = (WINDOWPOS*)lParam;
|
||||
if (pos->hwnd != win_Handle) break;
|
||||
if (pos->hwnd != win_handle) break;
|
||||
|
||||
if (pos->x != Window_Bounds.X || pos->y != Window_Bounds.Y) {
|
||||
Window_Bounds.X = pos->x; Window_Bounds.Y = pos->y;
|
||||
@ -196,7 +196,7 @@ static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wPara
|
||||
Window_Bounds.Width = pos->cx; Window_Bounds.Height = pos->cy;
|
||||
Window_UpdateClientSize(handle);
|
||||
|
||||
SetWindowPos(win_Handle, NULL,
|
||||
SetWindowPos(win_handle, NULL,
|
||||
Window_Bounds.X, Window_Bounds.Y, Window_Bounds.Width, Window_Bounds.Height,
|
||||
SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
|
||||
|
||||
@ -219,16 +219,16 @@ static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wPara
|
||||
|
||||
case WM_SIZE:
|
||||
{
|
||||
int new_state = win_State;
|
||||
int new_state = win_state;
|
||||
switch (wParam) {
|
||||
case SIZE_RESTORED: new_state = WINDOW_STATE_NORMAL; break;
|
||||
case SIZE_MINIMIZED: new_state = WINDOW_STATE_MINIMISED; break;
|
||||
case SIZE_MAXIMIZED: new_state = win_hiddenBorder ? WINDOW_STATE_FULLSCREEN : WINDOW_STATE_MAXIMISED; break;
|
||||
}
|
||||
|
||||
if (new_state != win_State) {
|
||||
win_State = new_state;
|
||||
Event_RaiseVoid(&WindowEvents_WindowStateChanged);
|
||||
if (new_state != win_state) {
|
||||
win_state = new_state;
|
||||
Event_RaiseVoid(&WindowEvents_StateChanged);
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -375,8 +375,8 @@ static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wPara
|
||||
|
||||
case WM_DESTROY:
|
||||
Window_Exists = false;
|
||||
UnregisterClassW(win_ClassName, win_Instance);
|
||||
if (win_DC) ReleaseDC(win_Handle, win_DC);
|
||||
UnregisterClassW(win_ClassName, win_instance);
|
||||
if (win_DC) ReleaseDC(win_handle, win_DC);
|
||||
Event_RaiseVoid(&WindowEvents_Closed);
|
||||
break;
|
||||
}
|
||||
@ -388,7 +388,7 @@ static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wPara
|
||||
*--------------------------------------------------Public implementation--------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
void Window_Create(int x, int y, int width, int height, struct GraphicsMode* mode) {
|
||||
win_Instance = GetModuleHandleW(NULL);
|
||||
win_instance = GetModuleHandleW(NULL);
|
||||
/* TODO: UngroupFromTaskbar(); */
|
||||
|
||||
/* Find out the final window rectangle, after the WM has added its chrome (titlebar, sidebars etc). */
|
||||
@ -398,7 +398,7 @@ void Window_Create(int x, int y, int width, int height, struct GraphicsMode* mod
|
||||
WNDCLASSEXW wc = { 0 };
|
||||
wc.cbSize = sizeof(WNDCLASSEXW);
|
||||
wc.style = CS_OWNDC;
|
||||
wc.hInstance = win_Instance;
|
||||
wc.hInstance = win_instance;
|
||||
wc.lpfnWndProc = Window_Procedure;
|
||||
wc.lpszClassName = win_ClassName;
|
||||
/* TODO: Set window icons here */
|
||||
@ -407,12 +407,12 @@ void Window_Create(int x, int y, int width, int height, struct GraphicsMode* mod
|
||||
ATOM atom = RegisterClassExW(&wc);
|
||||
if (!atom) ErrorHandler_Fail2(GetLastError(), "Failed to register window class");
|
||||
|
||||
win_Handle = CreateWindowExW(0, atom, NULL, win_Style,
|
||||
win_handle = CreateWindowExW(0, atom, NULL, win_Style,
|
||||
rect.left, rect.top, Rect_Width(rect), Rect_Height(rect),
|
||||
NULL, NULL, win_Instance, NULL);
|
||||
if (!win_Handle) ErrorHandler_Fail2(GetLastError(), "Failed to create window");
|
||||
NULL, NULL, win_instance, NULL);
|
||||
if (!win_handle) ErrorHandler_Fail2(GetLastError(), "Failed to create window");
|
||||
|
||||
win_DC = GetDC(win_Handle);
|
||||
win_DC = GetDC(win_handle);
|
||||
if (!win_DC) ErrorHandler_Fail2(GetLastError(), "Failed to get device context");
|
||||
Window_Exists = true;
|
||||
}
|
||||
@ -420,7 +420,7 @@ void Window_Create(int x, int y, int width, int height, struct GraphicsMode* mod
|
||||
void Window_SetTitle(const String* title) {
|
||||
WCHAR str[300];
|
||||
Platform_ConvertString(str, title);
|
||||
SetWindowTextW(win_Handle, str);
|
||||
SetWindowTextW(win_handle, str);
|
||||
}
|
||||
|
||||
void Window_GetClipboardText(String* value) {
|
||||
@ -429,7 +429,7 @@ void Window_GetClipboardText(String* value) {
|
||||
value->length = 0;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (!OpenClipboard(win_Handle)) {
|
||||
if (!OpenClipboard(win_handle)) {
|
||||
Thread_Sleep(100);
|
||||
continue;
|
||||
}
|
||||
@ -466,7 +466,7 @@ void Window_SetClipboardText(const String* value) {
|
||||
/* retry up to 10 times */
|
||||
int i;
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (!OpenClipboard(win_Handle)) {
|
||||
if (!OpenClipboard(win_handle)) {
|
||||
Thread_Sleep(100);
|
||||
continue;
|
||||
}
|
||||
@ -491,48 +491,48 @@ void Window_SetClipboardText(const String* value) {
|
||||
|
||||
void Window_SetBounds(Rect2D rect) {
|
||||
/* Note: the bounds variable is updated when the resize/move message arrives.*/
|
||||
SetWindowPos(win_Handle, NULL, rect.X, rect.Y, rect.Width, rect.Height, 0);
|
||||
SetWindowPos(win_handle, NULL, rect.X, rect.Y, rect.Width, rect.Height, 0);
|
||||
}
|
||||
|
||||
void Window_SetLocation(int x, int y) {
|
||||
SetWindowPos(win_Handle, NULL, x, y, 0, 0, SWP_NOSIZE);
|
||||
SetWindowPos(win_handle, NULL, x, y, 0, 0, SWP_NOSIZE);
|
||||
}
|
||||
|
||||
void Window_SetSize(int width, int height) {
|
||||
SetWindowPos(win_Handle, NULL, 0, 0, width, height, SWP_NOMOVE);
|
||||
SetWindowPos(win_handle, NULL, 0, 0, width, height, SWP_NOMOVE);
|
||||
}
|
||||
|
||||
void Window_SetClientSize(int width, int height) {
|
||||
DWORD style = GetWindowLongW(win_Handle, GWL_STYLE);
|
||||
DWORD style = GetWindowLongW(win_handle, GWL_STYLE);
|
||||
RECT rect = { 0, 0, width, height };
|
||||
|
||||
AdjustWindowRect(&rect, style, false);
|
||||
Window_SetSize(Rect_Width(rect), Rect_Height(rect));
|
||||
}
|
||||
|
||||
void* Window_GetWindowHandle(void) { return win_Handle; }
|
||||
void* Window_GetWindowHandle(void) { return win_handle; }
|
||||
|
||||
bool Window_GetVisible(void) { return IsWindowVisible(win_Handle); }
|
||||
bool Window_GetVisible(void) { return IsWindowVisible(win_handle); }
|
||||
void Window_SetVisible(bool visible) {
|
||||
if (visible) {
|
||||
ShowWindow(win_Handle, SW_SHOW);
|
||||
ShowWindow(win_handle, SW_SHOW);
|
||||
if (invisible_since_creation) {
|
||||
BringWindowToTop(win_Handle);
|
||||
SetForegroundWindow(win_Handle);
|
||||
BringWindowToTop(win_handle);
|
||||
SetForegroundWindow(win_handle);
|
||||
}
|
||||
} else {
|
||||
ShowWindow(win_Handle, SW_HIDE);
|
||||
ShowWindow(win_handle, SW_HIDE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Window_Close(void) {
|
||||
PostMessageW(win_Handle, WM_CLOSE, 0, 0);
|
||||
PostMessageW(win_handle, WM_CLOSE, 0, 0);
|
||||
}
|
||||
|
||||
int Window_GetWindowState(void) { return win_State; }
|
||||
int Window_GetWindowState(void) { return win_state; }
|
||||
void Window_SetWindowState(int state) {
|
||||
if (win_State == state) return;
|
||||
if (win_state == state) return;
|
||||
|
||||
DWORD command = 0;
|
||||
bool exiting_fullscreen = false;
|
||||
@ -542,7 +542,7 @@ void Window_SetWindowState(int state) {
|
||||
command = SW_RESTORE;
|
||||
|
||||
/* If we are leaving fullscreen mode we need to restore the border. */
|
||||
if (win_State == WINDOW_STATE_FULLSCREEN)
|
||||
if (win_state == WINDOW_STATE_FULLSCREEN)
|
||||
exiting_fullscreen = true;
|
||||
break;
|
||||
|
||||
@ -567,11 +567,11 @@ void Window_SetWindowState(int state) {
|
||||
Window_SetHiddenBorder(true);
|
||||
|
||||
command = SW_MAXIMIZE;
|
||||
SetForegroundWindow(win_Handle);
|
||||
SetForegroundWindow(win_handle);
|
||||
break;
|
||||
}
|
||||
|
||||
if (command != 0) ShowWindow(win_Handle, command);
|
||||
if (command != 0) ShowWindow(win_handle, command);
|
||||
|
||||
/* Restore previous window border or apply pending border change when leaving fullscreen mode. */
|
||||
if (exiting_fullscreen) Window_SetHiddenBorder(false);
|
||||
@ -585,7 +585,7 @@ void Window_SetWindowState(int state) {
|
||||
|
||||
Point2D Window_PointToClient(int x, int y) {
|
||||
Point2D point = { x, y };
|
||||
if (!ScreenToClient(win_Handle, &point)) {
|
||||
if (!ScreenToClient(win_handle, &point)) {
|
||||
ErrorHandler_Fail2(GetLastError(), "Converting point from client to screen coordinates");
|
||||
}
|
||||
return point;
|
||||
@ -593,7 +593,7 @@ Point2D Window_PointToClient(int x, int y) {
|
||||
|
||||
Point2D Window_PointToScreen(int x, int y) {
|
||||
Point2D point = { x, y };
|
||||
if (!ClientToScreen(win_Handle, &point)) {
|
||||
if (!ClientToScreen(win_handle, &point)) {
|
||||
ErrorHandler_Fail2(GetLastError(), "Converting point from screen to client coordinates");
|
||||
}
|
||||
return point;
|
||||
@ -608,7 +608,7 @@ void Window_ProcessEvents(void) {
|
||||
|
||||
HWND foreground = GetForegroundWindow();
|
||||
if (foreground) {
|
||||
Window_Focused = foreground == win_Handle;
|
||||
Window_Focused = foreground == win_handle;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user