*/}}
Browse Source

win32 thread progress fix

YimingWu 2 months ago
parent
commit
7d88fc90ca
4 changed files with 96 additions and 39 deletions
  1. 2 0
      CMakeLists.txt
  2. 1 0
      la_5.h
  3. 23 1
      la_interface.h
  4. 70 38
      la_kernel.c

+ 2 - 0
CMakeLists.txt

@@ -76,6 +76,8 @@ embed_resource("resources/soft_proof_table_sRGB.lagui.lut" "BuildResources/soft_
 embed_resource("resources/soft_proof_table_Clay.lagui.lut" "BuildResources/soft_proof_table_Clay.lagui.lut.c" "DATA_LUT_PROOF_CLAY")
 embed_resource("resources/soft_proof_table_D65P3.lagui.lut" "BuildResources/soft_proof_table_D65P3.lagui.lut.c" "DATA_LUT_PROOF_D65P3")
 
+add_compile_options("$<$<C_COMPILER_ID:MSVC>:/std:c11>")
+
 file(GLOB SOURCE_FILES 
 	./*.c ./*.cpp ./resources/*.c ./resources/*.cpp BuildResources/*.c)
 

+ 1 - 0
la_5.h

@@ -45,6 +45,7 @@
 //#include <io.h>
 #include <stddef.h> //offsetof
 #include <stdio.h>
+#include <threads.h>
 
 #ifdef __linux__
 #include <unistd.h>

+ 23 - 1
la_interface.h

@@ -49,6 +49,7 @@
 #include <GL/wglew.h>
 #endif
 
+#include <threads.h>
 #include "la_5.h"
 #include "la_data.h"
 //#include "llvm-c/Analysis.h"
@@ -326,6 +327,7 @@ STRUCTURE(laProgressDisplay){
     HBRUSH brush_fg;
     HPEN pen_fg;
     HDC hdc;
+    thrd_t th;
 #endif
     laTimeRecorder TimeCalled;
     real p1,p2;
@@ -2129,6 +2131,8 @@ void laValueMapperDestroy(laValueMapper* vm);
 laValueMapper* laValueMapperCopy(laValueMapper* new_optional, laValueMapper* vm);
 real laValueMapperEvaluate(laValueMapper* vm, real x, real* force_InMin, real* force_InMax, real* force_OutMin, real* force_OutMax, int ClampIn, int ClampOut);
 
+#define LA_PROGRESS_REPAINT_MESSAGE (WM_APP+1)
+
 void laShowProgress(real p1, real p2);
 void laHideProgress();
 
@@ -2728,11 +2732,29 @@ extern LA MAIN; // because of progress bar
         eglMakeCurrent(MAIN.egl_dpy,MAIN.egl_surf,MAIN.egl_surf,MAIN.glc)
 #define LA_LEAVE_GLES_CONTEXT \
         eglMakeCurrent(MAIN.egl_dpy,0,0,0)
-#else
+#endif
+
+#ifdef _WIN32
+#define LA_ACQUIRE_DC \
+    MAIN.Progress.hdc=GetDC(MAIN.Progress.w);
+#define LA_LEAVE_DC \
+    ReleaseDC(MAIN.Progress.w, MAIN.Progress.hdc);
+#endif
+
+#ifndef LA_ACQUIRE_DC
+#define LA_ACQUIRE_DC
+#endif
+#ifndef LA_LEAVE_DC
+#define LA_LEAVE_DC
+#endif
+#ifndef LA_ACQUIRE_GLES_CONTEXT
 #define LA_ACQUIRE_GLES_CONTEXT
+#endif
+#ifndef LA_LEAVE_GLES_CONTEXT
 #define LA_LEAVE_GLES_CONTEXT
 #endif
 
+
 extern laUiType *_LA_UI_FIXED_GROUP;
 extern laUiType *_LA_UI_TAB;
 extern laUiType _LA_UI_CONDITION;      //NO PTR

+ 70 - 38
la_kernel.c

@@ -443,7 +443,7 @@ void la_SetupGLEnviornment(laWindow* window, HWND hwnd, int Sync) {
 
     hglrc = wglCreateContextAttribsARB(hdc, MAIN.glc, Attrib);
 
-    if (!hglrc) SEND_PANIC_ERROR("Can't Create Opengl Context!\n", );
+    if (!hglrc) SEND_PANIC_ERROR("Can't Create Opengl Context!\n");
 
     tnsContextMakeCurrent(hglrc, hdc,0);
 
@@ -913,9 +913,7 @@ void laShowProgress(real p1, real p2){
             XMapWindow(MAIN.dpy,MAIN.Progress.w);
 #endif
 #ifdef _WIN32
-            int w=GetSystemMetrics(SM_CXFULLSCREEN), h=GetSystemMetrics(SM_CYFULLSCREEN);
-            SetWindowPos(MAIN.Progress.w, MAIN.CurrentWindow->win,w/2-ww/2,h/2-LA_RH*2/2,ww,LA_RH*2, SWP_ASYNCWINDOWPOS);
-            ShowWindowAsync(MAIN.Progress.w,SW_SHOW);
+            ShowWindow(MAIN.Progress.w, SW_NORMAL);
 #endif
             MAIN.Progress.Shown = 1;
         }
@@ -929,23 +927,7 @@ void laShowProgress(real p1, real p2){
     XSync(MAIN.dpy, 1); XFlush(MAIN.dpy);
 #endif
 #ifdef _WIN32
-    InvalidateRect(MAIN.Progress.w,0,1);
-    if(!MAIN.Progress.brush_bg){ MAIN.Progress.brush_bg=CreateSolidBrush(LA_COLOR3_TO_RGB(bg)); }
-    if(!MAIN.Progress.brush_fg){ MAIN.Progress.brush_fg=CreateSolidBrush(LA_COLOR3_TO_RGB(fg)); }
-    if(!MAIN.Progress.pen_fg){ MAIN.Progress.pen_fg=CreatePen(PS_SOLID, 2, LA_COLOR3_TO_RGB(fg)); }
-    RECT rect; GetClientRect(MAIN.Progress.w, &rect);
-    PAINTSTRUCT ps; BeginPaint(MAIN.Progress.w,&ps);
-    SelectObject(MAIN.Progress.hdc, MAIN.Progress.brush_bg);
-    Rectangle(MAIN.Progress.hdc, 0, 0, rect.right, rect.bottom);
-    SelectObject(MAIN.Progress.hdc, MAIN.Progress.brush_fg);
-    Rectangle(MAIN.Progress.hdc,LA_RH*2,0,LA_RH*2+PROGRESSW*MAIN.Progress.p1,LA_RH);
-    Rectangle(MAIN.Progress.hdc,LA_RH*2,LA_RH,LA_RH*2+PROGRESSW*MAIN.Progress.p2,LA_RH+LA_RH);
-    SelectObject(MAIN.Progress.hdc, MAIN.Progress.pen_fg);
-    tnsDrawLCD7_ProgressSystem(LA_RH*1.5,0,MAIN.Progress.p1);
-    tnsDrawLCD7_ProgressSystem(LA_RH*1.5,LA_RH,MAIN.Progress.p2);
-    EndPaint(MAIN.Progress.w,&ps);
-    MSG msg;
-    while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)){ TranslateMessage(&msg); DispatchMessage(&msg); };
+    PostMessage(MAIN.Progress.w, LA_PROGRESS_REPAINT_MESSAGE, 0, 0);
 #endif
 #ifdef LAGUI_ANDROID
     laWindow* window=MAIN.CurrentWindow; int pw=window->CW;
@@ -976,7 +958,7 @@ void laHideProgress(){
     XUnmapWindow(MAIN.dpy,MAIN.Progress.w); XSync(MAIN.dpy, 1); XFlush(MAIN.dpy);
 #endif
 #ifdef _WIN32
-    ShowWindowAsync(MAIN.Progress.w,SW_HIDE);
+    ShowWindow(MAIN.Progress.w,SW_HIDE);
     if(MAIN.CurrentWindow) UpdateWindow(MAIN.CurrentWindow->win);
 #endif
 #ifdef LAGUI_ANDROID
@@ -987,19 +969,10 @@ void laHideProgress(){
 
 //=======================
 
-void la_InitProgressWindow(){
-#ifdef LA_LINUX
-    MAIN.Progress.w=XCreateSimpleWindow(MAIN.dpy, RootWindow(MAIN.dpy, 0), 0, 0, PROGRESSW+LA_RH*2, LA_RH*2, 0, BlackPixel(MAIN.dpy, 0), WhitePixel(MAIN.dpy, 0));
-    if(!MAIN.Progress.w) return;
-    Atom window_type = XInternAtom(MAIN.dpy, "_NET_WM_WINDOW_TYPE", False); long value = XInternAtom(MAIN.dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
-    XChangeProperty(MAIN.dpy, MAIN.Progress.w, window_type,XA_ATOM, 32, PropModeReplace, (unsigned char *) &value,1 );
-    MAIN.Progress.gc=XCreateGC(MAIN.dpy,MAIN.Progress.w,0,&MAIN.Progress.gc_values);
-    if(MAIN.Progress.gc<0) return;
-    XSetFillStyle(MAIN.dpy, MAIN.Progress.gc, FillSolid);
-    XSetLineAttributes(MAIN.dpy, MAIN.Progress.gc, 2, LineSolid, CapButt, JoinBevel);
-    XSync(MAIN.dpy,0);
-#endif
 #ifdef _WIN32
+void la_Win32ProgressWindowThread(void* unused) {
+    laSpinLock(&MAIN.OpsLock);
+
     WNDCLASSW wc;
     wc.hInstance = MAIN.hinstance;
     wc.lpfnWndProc = LA_ProgressWindowProc;
@@ -1012,12 +985,34 @@ void la_InitProgressWindow(){
     wc.lpszMenuName = NULL;
     wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
 
-    if (!RegisterClassW(&wc)){ return; }
-    
-    MAIN.Progress.w=CreateWindowW(L"_LAGUIPROGRESS",L"Progress", WS_POPUP, 0,0,PROGRESSW+LA_RH*2,LA_RH*2,0,0,MAIN.hinstance,0);
+    if (!RegisterClassW(&wc)) { return; }
+
+    MAIN.Progress.w = CreateWindowW(L"_LAGUIPROGRESS", L"Progress", WS_POPUP, 0, 0, PROGRESSW + LA_RH * 2, LA_RH * 2, 0, 0, MAIN.hinstance, 0);
 
-    MAIN.Progress.hdc=GetDC(MAIN.Progress.w);
+    laSpinUnlock(&MAIN.OpsLock);
 
+    MSG msg;
+    while (GetMessage(&msg, MAIN.Progress.w, 0, 0)) {
+        TranslateMessage(&msg); DispatchMessage(&msg);
+    }
+}
+#endif
+void la_InitProgressWindow(){
+#ifdef LA_LINUX
+    MAIN.Progress.w=XCreateSimpleWindow(MAIN.dpy, RootWindow(MAIN.dpy, 0), 0, 0, PROGRESSW+LA_RH*2, LA_RH*2, 0, BlackPixel(MAIN.dpy, 0), WhitePixel(MAIN.dpy, 0));
+    if(!MAIN.Progress.w) return;
+    Atom window_type = XInternAtom(MAIN.dpy, "_NET_WM_WINDOW_TYPE", False); long value = XInternAtom(MAIN.dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
+    XChangeProperty(MAIN.dpy, MAIN.Progress.w, window_type,XA_ATOM, 32, PropModeReplace, (unsigned char *) &value,1 );
+    MAIN.Progress.gc=XCreateGC(MAIN.dpy,MAIN.Progress.w,0,&MAIN.Progress.gc_values);
+    if(MAIN.Progress.gc<0) return;
+    XSetFillStyle(MAIN.dpy, MAIN.Progress.gc, FillSolid);
+    XSetLineAttributes(MAIN.dpy, MAIN.Progress.gc, 2, LineSolid, CapButt, JoinBevel);
+    XSync(MAIN.dpy,0);
+#endif
+#ifdef _WIN32
+    thrd_create(&MAIN.Progress.th, la_Win32ProgressWindowThread, 0);
+
+    //MAIN.Progress.hdc=GetDC(MAIN.Progress.w);
 #endif
 }
 
@@ -1482,6 +1477,13 @@ void laShutoff(int SavePrefereces){
     //    }
     //}
 
+#ifdef _WIN32
+    laSpinLock(&MAIN.OpsLock);
+    PostMessage(MAIN.Progress.w, WM_QUIT, 0, 0);
+    laSpinUnlock(&MAIN.OpsLock);
+    thrd_join(MAIN.Progress.th, 0);
+#endif
+
     transDumpMissMatchRecord("TranslationDump.txt");
 
     if(MAIN.Cleanup) MAIN.Cleanup();
@@ -8024,6 +8026,36 @@ LRESULT CALLBACK LA_WindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lp
     return DefWindowProc(hwnd, message, wparam, lparam);
 }
 LRESULT CALLBACK LA_ProgressWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam){
+    switch (message) {
+    case WM_CLOSE:
+        return 0;
+    case WM_DESTROY:
+        return 0;
+    case LA_PROGRESS_REPAINT_MESSAGE:
+        InvalidateRect(MAIN.Progress.w, 0, 1);
+        int w = GetSystemMetrics(SM_CXFULLSCREEN), h = GetSystemMetrics(SM_CYFULLSCREEN);
+        int ww = PROGRESSW + LA_RH * 2;
+        SetWindowPos(MAIN.Progress.w, HWND_TOPMOST,w/2-ww/2,h/2-LA_RH*2/2,ww,LA_RH*2, 0);
+        return 0;
+    case WM_PAINT:
+        LA_ACQUIRE_DC
+        laBoxedTheme* bt = _LA_THEME_TAB; real* fg = laThemeColor(bt, LA_BT_TEXT); real* bg = laThemeColor(bt, LA_BT_NORMAL);
+        if (!MAIN.Progress.brush_bg) { MAIN.Progress.brush_bg = CreateSolidBrush(LA_COLOR3_TO_RGB(bg)); }
+        if (!MAIN.Progress.brush_fg) { MAIN.Progress.brush_fg = CreateSolidBrush(LA_COLOR3_TO_RGB(fg)); }
+        if (!MAIN.Progress.pen_fg) { MAIN.Progress.pen_fg = CreatePen(PS_SOLID, 2, LA_COLOR3_TO_RGB(fg)); }
+        RECT rect; GetClientRect(MAIN.Progress.w, &rect);
+        PAINTSTRUCT ps; BeginPaint(MAIN.Progress.w, &ps);
+        SelectObject(MAIN.Progress.hdc, MAIN.Progress.brush_bg);
+        Rectangle(MAIN.Progress.hdc, 0, 0, rect.right, rect.bottom);
+        SelectObject(MAIN.Progress.hdc, MAIN.Progress.brush_fg);
+        Rectangle(MAIN.Progress.hdc, LA_RH * 2, 0, LA_RH * 2 + PROGRESSW * MAIN.Progress.p1, LA_RH);
+        Rectangle(MAIN.Progress.hdc, LA_RH * 2, LA_RH, LA_RH * 2 + PROGRESSW * MAIN.Progress.p2, LA_RH + LA_RH);
+        SelectObject(MAIN.Progress.hdc, MAIN.Progress.pen_fg);
+        tnsDrawLCD7_ProgressSystem(LA_RH * 1.5, 0, MAIN.Progress.p1);
+        tnsDrawLCD7_ProgressSystem(LA_RH * 1.5, LA_RH, MAIN.Progress.p2);
+        EndPaint(MAIN.Progress.w, &ps);
+        LA_LEAVE_DC
+    }
     return DefWindowProc(hwnd, message, wparam, lparam);
 }
 #endif