Exemplo n.º 1
0
gboolean DrawFunc(gpointer user) {
    ENGD *engd = user;
    GdkGLDrawable *pGLD = 0;
    GdkRectangle rect = {};
    GdkModifierType gmod;
    gint xptr, yptr;
    GdkRegion *creg;
    GdkWindow *hwnd;
    intptr_t *data;
    uint32_t attr;

    cEngineCallback(engd, ECB_GUSR, (intptr_t)&data);
    if (!(hwnd = gtk_widget_get_window(GTK_WIDGET(data[0]))))
        return TRUE;

    gdk_window_get_pointer(hwnd, &xptr, &yptr, &gmod);
    attr = ((gmod & GDK_BUTTON1_MASK)? UFR_LBTN : 0)
         | ((gmod & GDK_BUTTON2_MASK)? UFR_MBTN : 0)
         | ((gmod & GDK_BUTTON3_MASK)? UFR_RBTN : 0)
         | ((gtk_window_is_active(GTK_WINDOW(data[0])))? UFR_MOUS : 0);
    attr = cPrepareFrame(engd, xptr, yptr, attr);
    if (attr & PFR_SKIP)
        usleep(1000);
    if (attr & PFR_HALT)
        return TRUE;
    if (attr & PFR_PICK) {
        rect.width  = (int16_t)(data[2]);
        rect.height = (int16_t)(data[2] >> 16);
    }
Exemplo n.º 2
0
void lRunMainLoop(ENGD *engd, long xpos, long ypos, long xdim, long ydim,
                  BGRA **bptr, intptr_t *data, uint32_t flgs) {
    enum {EXT_ATTR = WS_EX_TOPMOST | WS_EX_TOOLWINDOW | WS_EX_LAYERED};
    BLENDFUNCTION bstr = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
    WNDCLASSEX wndc = {sizeof(wndc), CS_HREDRAW | CS_VREDRAW, WindowProc,
                       0, 0, 0, 0, LoadCursor(0, IDC_HAND), 0, 0, " ", 0};
    PIXELFORMATDESCRIPTOR ppfd = {sizeof(ppfd), 1, PFD_SUPPORT_OPENGL |
                                  PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER,
                                  PFD_TYPE_RGBA, 32};
    BITMAPINFO bmpi = {{sizeof(bmpi.bmiHeader), 0, 0,
                        1, 8 * sizeof(BGRA), BI_RGB}};
    struct { /// DWM_BLURBEHIND from DWM API (Vista and later)
        DWORD dwFlags;
        BOOL  fEnable;     /// dwFlags | 0x01 (DWM_BB_ENABLE)
        HRGN  hRgnBlur;    /// dwFlags | 0x02 (DWM_BB_BLURREGION)
        BOOL  fTransition; /// dwFlags | 0x04 (DWM_BB_TRANSITIONONMAXIMIZED)
    } blur = {0x03, TRUE, CreateRectRgn(0, 0, 1, 1), TRUE};
    SIZE dims = {xdim - xpos, ydim - ypos};
    POINT cpos, mpos, zpos = {};
    MSG pmsg = {};

    BLENDFUNCTION *bfun;
    BOOL APIENTRY (*ULW)(HWND, HDC, POINT*, SIZE*, HDC, POINT*,
                         COLORREF, BLENDFUNCTION*, DWORD) = 0;
    BOOL APIENTRY (*SLW)(HWND, COLORREF, BYTE, DWORD) = 0;
    HRESULT APIENTRY (*EBW)(HWND, typeof(blur)*) = 0;
    HRESULT APIENTRY (*ICE)(BOOL*) = 0;
    HINSTANCE husr, hdwm;
    UINT opts, attr;
    HDC devc, mwdc;
    HBITMAP hdib;
    HGLRC mwrc;
    HWND hwnd;
    BOOL comp;

    mwrc = 0;
    devc = CreateCompatibleDC(0);
    bmpi.bmiHeader.biWidth = dims.cx;
    bmpi.bmiHeader.biHeight = (~flgs & COM_RGPU)? -dims.cy : dims.cy;
    hdib = CreateDIBSection(devc, &bmpi, DIB_RGB_COLORS, (void*)bptr, 0, 0);
    SelectObject(devc, hdib);

    if ((hdwm = LoadLibrary("dwmapi")))
        EBW = (typeof(EBW))GetProcAddress(hdwm, "DwmEnableBlurBehindWindow");

    bfun = &bstr;
    opts = ULW_ALPHA;
    attr = EXT_ATTR;
    mpos = (POINT){xpos, ypos};

    husr = LoadLibrary("user32");
    if ((flgs & COM_OPAQ) || (flgs & WIN_IRGN)
    || !(ULW = (typeof(ULW))GetProcAddress(husr, "UpdateLayeredWindow"))) {
        bfun = (typeof(bfun))*bptr;
        zpos.y = bmpi.bmiHeader.biHeight;
        ULW = (typeof(ULW))ULWstub;
        attr &= ~WS_EX_LAYERED;
        if (flgs & COM_OPAQ)
            opts = ULW_OPAQUE;
    }
    RegisterClassEx(&wndc);
    hwnd = CreateWindowEx(attr, wndc.lpszClassName, 0, WS_POPUP | WS_VISIBLE,
                          0, 0, 0, 0, 0, 0, wndc.hInstance, engd);
    data[0] = (intptr_t)hwnd;
    mwdc = GetDC(hwnd);

    if (EBW) {
        comp = FALSE;
        ICE = (typeof(ICE))GetProcAddress(hdwm, "DwmIsCompositionEnabled");
        /// if there`s DWM, there absolutely have to be layered windows
        SLW = (typeof(SLW))GetProcAddress(husr, "SetLayeredWindowAttributes");
        ICE(&comp);
        attr = GetVersion();
        /// major 6 minor 1 is Win7; in newer versions ICE() is lying to us
        if (!comp && (MAKEWORD(HIBYTE(attr), LOBYTE(attr)) <= 0x0601))
            EBW = 0;
        else {
            /// does nothing visible to the window,
            /// but enables input transparency!
            SLW(hwnd, 0x000000, 0xFF, 2 /** 2 == LWA_ALPHA **/);
            EBW(hwnd, &blur);
        }
    }
    if (flgs & COM_RGPU) {
        ppfd.iLayerType = PFD_MAIN_PLANE;
        SetPixelFormat(mwdc, ChoosePixelFormat(mwdc, &ppfd), &ppfd);
        wglMakeCurrent(mwdc, mwrc = wglCreateContext(mwdc));
    }
    /// "+1" is a dirty hack to not let Windows consider us fullscreen if OGL
    /// is active: all sorts of weird things happen to fullscreen OGL windows
    /// when they are DWM + layered, at least on Intel HD 3000 + Vista / Win7
    SetWindowPos(hwnd, 0, mpos.x, mpos.y, dims.cx, dims.cy + ((EBW)? 1 : 0),
                 SWP_NOZORDER | SWP_NOACTIVATE);
    lShowMainWindow(engd, flgs & COM_SHOW);
    while (data[0]) {
        if (PeekMessage(&pmsg, 0, 0, 0, PM_REMOVE)) {
            TranslateMessage(&pmsg);
            DispatchMessage(&pmsg);
            continue;
        }
        GetCursorPos(&cpos);
        ScreenToClient(hwnd, &cpos);
        attr = ((GetActiveWindow() == hwnd)?    UFR_MOUS : 0)
             | ((GetAsyncKeyState(VK_LBUTTON))? UFR_LBTN : 0)
             | ((GetAsyncKeyState(VK_MBUTTON))? UFR_MBTN : 0)
             | ((GetAsyncKeyState(VK_RBUTTON))? UFR_RBTN : 0)
             | ((GetAsyncKeyState(VK_UP     ))? UFR_PL1W : 0)
             | ((GetAsyncKeyState(VK_DOWN   ))? UFR_PL1S : 0)
             | ((GetAsyncKeyState(VK_LEFT   ))? UFR_PL1A : 0)
             | ((GetAsyncKeyState(VK_RIGHT  ))? UFR_PL1D : 0)
             | ((GetAsyncKeyState('W'       ))? UFR_PL2W : 0)
             | ((GetAsyncKeyState('S'       ))? UFR_PL2S : 0)
             | ((GetAsyncKeyState('A'       ))? UFR_PL2A : 0)
             | ((GetAsyncKeyState('D'       ))? UFR_PL2D : 0);
        attr = cPrepareFrame(engd, cpos.x, cpos.y, attr);
        if (attr & PFR_SKIP)
            Sleep(1);
        if (!IsWindow(hwnd))
            break;
        if (attr & PFR_HALT)
            continue;
        if (~flgs & COM_RGPU)
            BitBlt(devc, 0, 0, dims.cx, dims.cy, mwdc, 0, 0, BLACKNESS);
        cOutputFrame(engd, !EBW);
        if (!EBW)
            ULW(hwnd, mwdc, &mpos, &dims, devc, &zpos, 0, bfun, opts);
        else {
            if (flgs & COM_RGPU)
                SwapBuffers(mwdc);
            else
                BitBlt(mwdc, 0, 0, dims.cx, dims.cy, devc, 0, 0, SRCCOPY);
            SetWindowLongPtr(hwnd, GWL_EXSTYLE, (attr & PFR_PICK)? EXT_ATTR :
                                               WS_EX_TRANSPARENT | EXT_ATTR);
        }
    }
    cDeallocFrame(engd, !EBW);
    if (flgs & COM_RGPU) {
        wglMakeCurrent(0, 0);
        wglDeleteContext(mwrc);
    }
    KillTimer(hwnd, 1);
    ReleaseDC(hwnd, mwdc);
    DestroyWindow(hwnd);
    DeleteDC(mwdc);
    DeleteDC(devc);
    DeleteObject(hdib);
    DeleteObject(blur.hRgnBlur);
    /// mandatory: we are a library, not an application
    UnregisterClass(wndc.lpszClassName, wndc.hInstance);
    /// finally, we need to purge the message queue, as it may be reused,
    /// and nobody wants garbage messages for windows that are long gone
    while (PeekMessage(&pmsg, 0, 0, 0, PM_REMOVE));
    FreeLibrary(husr);
    FreeLibrary(hdwm);
}