mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-22 17:12:25 -05:00
Fix launcher having black pixels left behind when windows are moved over it on linux
This commit is contained in:
parent
7f34c26ccd
commit
23065158a6
10 changed files with 95 additions and 24 deletions
|
@ -28,7 +28,7 @@ namespace InteropPatcher {
|
||||||
|
|
||||||
public static class Patcher {
|
public static class Patcher {
|
||||||
|
|
||||||
public static int Main( string[] args ) {
|
public static int Main(string[] args) {
|
||||||
try {
|
try {
|
||||||
if( args.Length == 0 ) {
|
if( args.Length == 0 ) {
|
||||||
Console.WriteLine( "Expecting single argument specifying the file to patch" );
|
Console.WriteLine( "Expecting single argument specifying the file to patch" );
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace Launcher {
|
||||||
public Screen Screen;
|
public Screen Screen;
|
||||||
|
|
||||||
/// <summary> Whether the client drawing area needs to be redrawn/presented to the screen. </summary>
|
/// <summary> Whether the client drawing area needs to be redrawn/presented to the screen. </summary>
|
||||||
public bool Dirty;
|
public bool Dirty, pendingRedraw;
|
||||||
/// <summary> The specific area/region of the window that needs to be redrawn. </summary>
|
/// <summary> The specific area/region of the window that needs to be redrawn. </summary>
|
||||||
public Rectangle DirtyArea;
|
public Rectangle DirtyArea;
|
||||||
|
|
||||||
|
@ -58,9 +58,9 @@ namespace Launcher {
|
||||||
PlatformDrawer platformDrawer;
|
PlatformDrawer platformDrawer;
|
||||||
public void Init() {
|
public void Init() {
|
||||||
Window.Resize += Resize;
|
Window.Resize += Resize;
|
||||||
Window.FocusedChanged += ForceRedraw;
|
Window.FocusedChanged += RedrawAll;
|
||||||
Window.WindowStateChanged += Resize;
|
Window.WindowStateChanged += Resize;
|
||||||
Window.Redraw += ForceRedraw;
|
Window.Redraw += RedrawPending;
|
||||||
Keyboard.KeyDown += KeyDown;
|
Keyboard.KeyDown += KeyDown;
|
||||||
|
|
||||||
ClassicalSharp.Program.CleanupMainDirectory();
|
ClassicalSharp.Program.CleanupMainDirectory();
|
||||||
|
@ -103,10 +103,16 @@ namespace Launcher {
|
||||||
void Resize(object sender, EventArgs e) {
|
void Resize(object sender, EventArgs e) {
|
||||||
UpdateClientSize();
|
UpdateClientSize();
|
||||||
platformDrawer.Resize();
|
platformDrawer.Resize();
|
||||||
ForceRedraw(sender, e);
|
RedrawAll(sender, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForceRedraw(object sender, EventArgs e) {
|
void RedrawPending(object sender, EventArgs e) {
|
||||||
|
// in case we get multiple of these events
|
||||||
|
pendingRedraw = true;
|
||||||
|
Dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RedrawAll(object sender, EventArgs e) {
|
||||||
if (Program.ShowingErrorDialog) return;
|
if (Program.ShowingErrorDialog) return;
|
||||||
RedrawBackground();
|
RedrawBackground();
|
||||||
if (Screen != null) Screen.Resize();
|
if (Screen != null) Screen.Resize();
|
||||||
|
@ -217,6 +223,11 @@ namespace Launcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Display() {
|
void Display() {
|
||||||
|
if (pendingRedraw) {
|
||||||
|
RedrawAll(null, null);
|
||||||
|
pendingRedraw = false;
|
||||||
|
}
|
||||||
|
|
||||||
Screen.OnDisplay();
|
Screen.OnDisplay();
|
||||||
Dirty = false;
|
Dirty = false;
|
||||||
|
|
||||||
|
@ -235,9 +246,9 @@ namespace Launcher {
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose() {
|
||||||
Window.Resize -= Resize;
|
Window.Resize -= Resize;
|
||||||
Window.FocusedChanged -= ForceRedraw;
|
Window.FocusedChanged -= RedrawAll;
|
||||||
Window.WindowStateChanged -= Resize;
|
Window.WindowStateChanged -= Resize;
|
||||||
Window.Redraw -= ForceRedraw;
|
Window.Redraw -= RedrawPending;
|
||||||
Keyboard.KeyDown -= KeyDown;
|
Keyboard.KeyDown -= KeyDown;
|
||||||
|
|
||||||
List<FastBitmap> bitmaps = FetchFlagsTask.Bitmaps;
|
List<FastBitmap> bitmaps = FetchFlagsTask.Bitmaps;
|
||||||
|
|
|
@ -107,6 +107,20 @@ namespace OpenTK.Platform.X11 {
|
||||||
public bool override_redirect;
|
public bool override_redirect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct XExposeEvent {
|
||||||
|
public XEventName type;
|
||||||
|
public IntPtr serial;
|
||||||
|
public bool send_event;
|
||||||
|
public IntPtr display;
|
||||||
|
public IntPtr window;
|
||||||
|
public int x;
|
||||||
|
public int y;
|
||||||
|
public int width;
|
||||||
|
public int height;
|
||||||
|
public int count;
|
||||||
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct XPropertyEvent {
|
public struct XPropertyEvent {
|
||||||
public XEventName type;
|
public XEventName type;
|
||||||
|
@ -215,6 +229,8 @@ namespace OpenTK.Platform.X11 {
|
||||||
[FieldOffset(0)]
|
[FieldOffset(0)]
|
||||||
public XConfigureEvent ConfigureEvent;
|
public XConfigureEvent ConfigureEvent;
|
||||||
[FieldOffset(0)]
|
[FieldOffset(0)]
|
||||||
|
public XExposeEvent ExposeEvent;
|
||||||
|
[FieldOffset(0)]
|
||||||
public XPropertyEvent PropertyEvent;
|
public XPropertyEvent PropertyEvent;
|
||||||
[FieldOffset(0)]
|
[FieldOffset(0)]
|
||||||
public XSelectionRequestEvent SelectionRequestEvent;
|
public XSelectionRequestEvent SelectionRequestEvent;
|
||||||
|
|
|
@ -272,6 +272,12 @@ namespace OpenTK.Platform.X11 {
|
||||||
RefreshWindowBounds(ref e);
|
RefreshWindowBounds(ref e);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case XEventName.Expose:
|
||||||
|
if (e.ExposeEvent.count == 0) {
|
||||||
|
RaiseRedraw();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case XEventName.KeyPress:
|
case XEventName.KeyPress:
|
||||||
ToggleKey(ref e.KeyEvent, true);
|
ToggleKey(ref e.KeyEvent, true);
|
||||||
int status = API.XLookupString(ref e.KeyEvent, ascii, ascii.Length, null, IntPtr.Zero);
|
int status = API.XLookupString(ref e.KeyEvent, ascii, ascii.Length, null, IntPtr.Zero);
|
||||||
|
|
|
@ -112,7 +112,7 @@ static void AsyncDownloader_Add(String* url, bool priority, String* id, UInt8 ty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Platform_MutexUnlock(async_pendingMutex);
|
Platform_MutexUnlock(async_pendingMutex);
|
||||||
Platform_EventSet(async_eventHandle);
|
Platform_EventSignal(async_eventHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncDownloader_GetSkin(STRING_PURE String* id, STRING_PURE String* skinName) {
|
void AsyncDownloader_GetSkin(STRING_PURE String* id, STRING_PURE String* skinName) {
|
||||||
|
@ -355,7 +355,7 @@ static void AsyncDownloader_Reset(void) {
|
||||||
AsyncRequestList_Free(&async_pending);
|
AsyncRequestList_Free(&async_pending);
|
||||||
}
|
}
|
||||||
Platform_MutexUnlock(async_pendingMutex);
|
Platform_MutexUnlock(async_pendingMutex);
|
||||||
Platform_EventSet(async_eventHandle);
|
Platform_EventSignal(async_eventHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AsyncDownloader_Free(void) {
|
static void AsyncDownloader_Free(void) {
|
||||||
|
|
|
@ -77,7 +77,7 @@ void Platform_MutexUnlock(void* handle);
|
||||||
|
|
||||||
void* Platform_EventCreate(void);
|
void* Platform_EventCreate(void);
|
||||||
void Platform_EventFree(void* handle);
|
void Platform_EventFree(void* handle);
|
||||||
void Platform_EventSet(void* handle);
|
void Platform_EventSignal(void* handle);
|
||||||
void Platform_EventWait(void* handle);
|
void Platform_EventWait(void* handle);
|
||||||
|
|
||||||
typedef Int64 Stopwatch;
|
typedef Int64 Stopwatch;
|
||||||
|
|
|
@ -341,7 +341,7 @@ void Platform_EventFree(void* handle) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Platform_EventSet(void* handle) {
|
void Platform_EventSignal(void* handle) {
|
||||||
SetEvent((HANDLE)handle);
|
SetEvent((HANDLE)handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "Entity.h"
|
#include "Entity.h"
|
||||||
#include "ExtMath.h"
|
#include "ExtMath.h"
|
||||||
#include "Physics.h"
|
#include "Physics.h"
|
||||||
|
#include "Game.h"
|
||||||
|
|
||||||
void World_Reset(void) {
|
void World_Reset(void) {
|
||||||
Platform_MemFree(&World_Blocks);
|
Platform_MemFree(&World_Blocks);
|
||||||
|
@ -19,7 +20,12 @@ void World_Reset(void) {
|
||||||
|
|
||||||
Random rnd;
|
Random rnd;
|
||||||
Random_InitFromCurrentTime(&rnd);
|
Random_InitFromCurrentTime(&rnd);
|
||||||
|
/* add a bit of randomness for uuid */
|
||||||
Int32 i;
|
Int32 i;
|
||||||
|
for (i = 0; i < Game_Username.length; i++) {
|
||||||
|
Random_Next(&rnd, Game_Username.buffer[i] + 3);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < 16; i++) {
|
for (i = 0; i < 16; i++) {
|
||||||
World_Uuid[i] = Random_Next(&rnd, 256);
|
World_Uuid[i] = Random_Next(&rnd, 256);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,14 @@ static void Platform_UnicodeExpand(UInt8* dst, STRING_PURE String* src) {
|
||||||
*dst = NULL;
|
*dst = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Platform_Init(void) { }
|
pthread_mutex_t event_mutex;
|
||||||
void Platform_Free(void) { }
|
void Platform_Init(void) {
|
||||||
|
pthread_mutex_init(&event_mutex, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Platform_Free(void) {
|
||||||
|
pthread_mutex_destroy(&event_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
void Platform_Exit(ReturnCode code) { exit(code); }
|
void Platform_Exit(ReturnCode code) { exit(code); }
|
||||||
STRING_PURE String Platform_GetCommandLineArgs(void);
|
STRING_PURE String Platform_GetCommandLineArgs(void);
|
||||||
|
@ -264,10 +270,30 @@ void Platform_MutexUnlock(void* handle) {
|
||||||
ErrorHandler_CheckOrFail(result, "Unlocking mutex");
|
ErrorHandler_CheckOrFail(result, "Unlocking mutex");
|
||||||
}
|
}
|
||||||
|
|
||||||
void* Platform_EventCreate(void);
|
pthread_cond_t condList[2]; Int32 condIndex;
|
||||||
void Platform_EventFree(void* handle);
|
void* Platform_EventCreate(void) {
|
||||||
void Platform_EventSet(void* handle);
|
if (condIndex == Array_Elems(condList)) ErrorHandler_Fail("Cannot allocate event");
|
||||||
void Platform_EventWait(void* handle);
|
pthread_cond_t* ptr = &condList[condIndex];
|
||||||
|
int result = pthread_cond_init(ptr, NULL);
|
||||||
|
|
||||||
|
ErrorHandler_CheckOrFail(result, "Creating event");
|
||||||
|
condIndex++; return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Platform_EventFree(void* handle) {
|
||||||
|
int result = pthread_cond_destroy((pthread_cond_t*)handle);
|
||||||
|
ErrorHandler_CheckOrFail(result, "Destroying event");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Platform_EventSignal(void* handle) {
|
||||||
|
int result = pthread_cond_signal((pthread_cond_t*)handle);
|
||||||
|
ErrorHandler_CheckOrFail(result, "Signalling event");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Platform_EventWait(void* handle) {
|
||||||
|
int result = pthread_cond_wait((pthread_cond_t*)handle, event_mutex);
|
||||||
|
ErrorHandler_CheckOrFail(result, "Waiting event");
|
||||||
|
}
|
||||||
|
|
||||||
void Stopwatch_Start(Stopwatch* timer);
|
void Stopwatch_Start(Stopwatch* timer);
|
||||||
Int32 Stopwatch_ElapsedMicroseconds(Stopwatch* timer);
|
Int32 Stopwatch_ElapsedMicroseconds(Stopwatch* timer);
|
||||||
|
|
|
@ -473,12 +473,18 @@ void Window_ProcessEvents(void) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ConfigureNotify:
|
case ConfigureNotify:
|
||||||
RefreshWindowBounds(&e);
|
Window_RefreshBounds(&e);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Expose:
|
||||||
|
if (e.xexpose.count == 0) {
|
||||||
|
Event_RaiseVoid(&WindowEvents_Redraw);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
{
|
{
|
||||||
ToggleKey(&e.xkey, true);
|
Window_ToggleKey(&e.xkey, true);
|
||||||
UInt8 data[16]; UInt8 convBuffer[16];
|
UInt8 data[16]; UInt8 convBuffer[16];
|
||||||
int status = XLookupString(&e.xkey, data, Array_Elems(data), NULL, NULL);
|
int status = XLookupString(&e.xkey, data, Array_Elems(data), NULL, NULL);
|
||||||
|
|
||||||
|
@ -493,7 +499,7 @@ void Window_ProcessEvents(void) {
|
||||||
case KeyRelease:
|
case KeyRelease:
|
||||||
/* TODO: raise KeyPress event. Use code from */
|
/* TODO: raise KeyPress event. Use code from */
|
||||||
/* http://anonsvn.mono-project.com/viewvc/trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Keyboard.cs?view=markup */
|
/* http://anonsvn.mono-project.com/viewvc/trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Keyboard.cs?view=markup */
|
||||||
ToggleKey(&e.xkey, false);
|
Window_ToggleKey(&e.xkey, false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ButtonPress:
|
case ButtonPress:
|
||||||
|
@ -538,7 +544,7 @@ void Window_ProcessEvents(void) {
|
||||||
|
|
||||||
case PropertyNotify:
|
case PropertyNotify:
|
||||||
if (e.xproperty.atom == net_wm_state) {
|
if (e.xproperty.atom == net_wm_state) {
|
||||||
RaiseWindowStateChanged();
|
Event_RaiseVoid(&WindowEvents_StateChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (e.xproperty.atom == net_frame_extents) {
|
//if (e.xproperty.atom == net_frame_extents) {
|
||||||
|
@ -763,7 +769,7 @@ static XVisualInfo GLContext_SelectVisual(struct GraphicsMode* mode) {
|
||||||
visual = glXChooseVisual(win_display, win_screen, attribs);
|
visual = glXChooseVisual(win_display, win_screen, attribs);
|
||||||
}
|
}
|
||||||
if (visual == NULL) {
|
if (visual == NULL) {
|
||||||
ErorrHandler_Fail("Requested GraphicsMode not available.");
|
ErrorHandler_Fail("Requested GraphicsMode not available.");
|
||||||
}
|
}
|
||||||
|
|
||||||
XVisualInfo info = *visual;
|
XVisualInfo info = *visual;
|
||||||
|
|
Loading…
Reference in a new issue