29 #include "gdk/win32/gdkwin32.h" 
   37 struct TGWin32GLManager::TGLContext {
 
   57    TGLContext  *fNextFreeContext;
 
   67       CDCGuard(
const CDCGuard &);
 
   68       CDCGuard &operator = (
const CDCGuard &);
 
   71       explicit CDCGuard(HDC hDC) : fHDC(hDC)
 
   90       WDCGuard(
const WDCGuard &);
 
   91       WDCGuard &operator = (
const WDCGuard &);
 
   94       WDCGuard(HDC hDC, Window_t winID) : fHDC(hDC), fWinID(winID)
 
   99             ReleaseDC((HWND)GDK_DRAWABLE_XID((GdkWindow *)fWinID), fHDC);
 
  112       BMPGuard(
const BMPGuard &);
 
  113       BMPGuard &operator = (
const BMPGuard &);
 
  116       explicit BMPGuard(HBITMAP bmp) : fBMP(bmp)
 
  134       WGLGuard(
const WGLGuard &);
 
  135       WGLGuard &operator = (
const WGLGuard &);
 
  138       explicit WGLGuard(HGLRC glrc) : fCtx(glrc)
 
  143             wglDeleteContext(fCtx);
 
  152 const PIXELFORMATDESCRIPTOR
 
  154    sizeof doubleBufferDesc,        
 
  172 const PIXELFORMATDESCRIPTOR
 
  174    sizeof singleScreenDesc,        
 
  191 class TGWin32GLManager::TGWin32GLImpl {
 
  193    TGWin32GLImpl() : fNextFreeContext(nullptr)
 
  196    std::deque<TGLContext> fGLContexts;
 
  197    TGLContext *fNextFreeContext;
 
  200 TGWin32GLManager::TGWin32GLImpl::~TGWin32GLImpl()
 
  203    std::deque<TGLContext>::size_type i = 0;
 
  205    for (; i < fGLContexts.size(); ++i) {
 
  206       TGLContext &ctx = fGLContexts[i];
 
  208       if (ctx.fGLContext) {
 
  210          ::Warning(
"TGWin32GLManager::~TGLWin32GLManager", 
"You forget to destroy gl-context %d\n", i);
 
  212          if (ctx.fPixmapIndex != -1) {
 
  213             gVirtualX->SelectWindow(ctx.fPixmapIndex);
 
  214             gVirtualX->ClosePixmap();
 
  217          wglDeleteContext(ctx.fGLContext);
 
  218          ReleaseDC((HWND)GDK_DRAWABLE_XID((GdkWindow *)gVirtualX->GetWindowID(ctx.fWindowIndex)),
 
  224 ClassImp(TGWin32GLManager);
 
  228 TGWin32GLManager::TGWin32GLManager() : fPimpl(new TGWin32GLImpl)
 
  230    gPtr2GLManager = &TGWin32GLManagerProxy::ProxyObject;
 
  231    gROOT->GetListOfSpecials()->AddLast(
this);
 
  237 TGWin32GLManager::~TGWin32GLManager()
 
  244 Int_t TGWin32GLManager::InitGLWindow(Window_t winID)
 
  246    return gVirtualX->InitWindow(winID);
 
  253 Int_t TGWin32GLManager::CreateGLContext(Int_t winInd)
 
  255    Window_t winID = gVirtualX->GetWindowID(winInd);
 
  256    HDC hDC = GetWindowDC((HWND)GDK_DRAWABLE_XID((GdkWindow *)winID));
 
  259       Error(
"CreateGLContext", 
"GetWindowDC failed\n");
 
  263    WDCGuard dcGuard(hDC, winID);
 
  265    if (Int_t pixFormat = ChoosePixelFormat(hDC, &doubleBufferDesc)) {
 
  266       if (SetPixelFormat(hDC, pixFormat, &doubleBufferDesc)) {
 
  267          HGLRC glCtx = wglCreateContext(hDC);
 
  270             Error(
"CreateGLContext", 
"wglCreateContext failed\n");
 
  274          TGLContext newDevice = {winInd, -1, hDC, 0, glCtx};
 
  275          PIXELFORMATDESCRIPTOR testFormat = {};
 
  276          DescribePixelFormat(hDC, pixFormat, 
sizeof testFormat, &testFormat);
 
  277          newDevice.fHighColor = testFormat.cColorBits < 24 ? kTRUE : kFALSE;
 
  279          if (TGLContext *ctx = fPimpl->fNextFreeContext) {
 
  280             Int_t ind = ctx->fWindowIndex;
 
  281             fPimpl->fNextFreeContext = fPimpl->fNextFreeContext->fNextFreeContext;
 
  286             WGLGuard wglGuard(glCtx);
 
  287             fPimpl->fGLContexts.push_back(newDevice);
 
  290             return fPimpl->fGLContexts.size() - 1;
 
  293          Error(
"CreateGLContext", 
"SetPixelFormat failed\n");
 
  295       Error(
"CreateGLContext", 
"ChoosePixelFormat failed\n");
 
  303 Bool_t TGWin32GLManager::CreateDIB(TGLContext &ctx)
const 
  305    HDC dibDC = CreateCompatibleDC(0);
 
  308       Error(
"CreateDIB", 
"CreateCompatibleDC failed\n");
 
  312    CDCGuard dcGuard(dibDC);
 
  314    BITMAPINFOHEADER bmpHeader = {
sizeof bmpHeader, (LONG) ctx.fW, (LONG) ctx.fH, 1, 32, BI_RGB};
 
  315    void *bmpCnt = 
nullptr;
 
  316    HBITMAP hDIB = CreateDIBSection(dibDC, (BITMAPINFO*)&bmpHeader, DIB_RGB_COLORS, &bmpCnt, 0, 0);
 
  319       Error(
"CreateDIB", 
"CreateDIBSection failed\n");
 
  323    BMPGuard bmpGuard(hDIB);
 
  325    ctx.fPixmapIndex = gVirtualX->AddPixmap((ULong_t)hDIB, ctx.fW, ctx.fH);
 
  327    ctx.fDIBData = 
static_cast<UChar_t *
>(bmpCnt);
 
  336 Bool_t TGWin32GLManager::AttachOffScreenDevice(Int_t ctxInd, Int_t x, Int_t y, UInt_t w, UInt_t h)
 
  338    TGLContext &ctx = fPimpl->fGLContexts[ctxInd];
 
  339    TGLContext newCtx = {ctx.fWindowIndex, -1, ctx.fDC, 0, ctx.fGLContext, w, h, x, y, ctx.fHighColor};
 
  341    if (CreateDIB(newCtx)) {
 
  352 Bool_t TGWin32GLManager::ResizeOffScreenDevice(Int_t ctxInd, Int_t x, Int_t y, UInt_t w, UInt_t h)
 
  354    TGLContext &ctx = fPimpl->fGLContexts[ctxInd];
 
  356    if (ctx.fPixmapIndex != -1)
 
  357       if (TMath::Abs(Int_t(w) - Int_t(ctx.fW)) > 1 || TMath::Abs(Int_t(h) - Int_t(ctx.fH)) > 1) {
 
  358          TGLContext newCtx = {ctx.fWindowIndex, -1, ctx.fDC, 0, ctx.fGLContext, w, h, x, y, ctx.fHighColor};
 
  359          if (CreateDIB(newCtx)) {
 
  361             gVirtualX->SelectWindow(ctx.fPixmapIndex);
 
  362             gVirtualX->ClosePixmap();
 
  365             Error(
"ResizeOffScreenDevice", 
"Error trying to create new DIB\n");
 
  378 void TGWin32GLManager::SelectOffScreenDevice(Int_t ctxInd)
 
  380    gVirtualX->SelectWindow(fPimpl->fGLContexts[ctxInd].fPixmapIndex);
 
  385 void TGWin32GLManager::MarkForDirectCopy(Int_t pixInd, Bool_t isDirect)
 
  387    if (fPimpl->fGLContexts[pixInd].fPixmapIndex != -1)
 
  388       fPimpl->fGLContexts[pixInd].fDirect = isDirect;
 
  393 void TGWin32GLManager::ReadGLBuffer(Int_t ctxInd)
 
  395    TGLContext &ctx = fPimpl->fGLContexts[ctxInd];
 
  397    if (ctx.fPixmapIndex != -1) {
 
  398       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
  399       glReadBuffer(GL_BACK);
 
  400       glReadPixels(0, 0, ctx.fW, ctx.fH, GL_BGRA_EXT, GL_UNSIGNED_BYTE, ctx.fDIBData);
 
  406 Int_t TGWin32GLManager::GetVirtualXInd(Int_t ctxInd)
 
  408    return fPimpl->fGLContexts[ctxInd].fPixmapIndex;
 
  413 Bool_t TGWin32GLManager::MakeCurrent(Int_t ctxInd)
 
  415    TGLContext &ctx = fPimpl->fGLContexts[ctxInd];
 
  416    return (Bool_t)wglMakeCurrent(ctx.fDC, ctx.fGLContext);
 
  421 void TGWin32GLManager::Flush(Int_t ctxInd)
 
  423    TGLContext &ctx = fPimpl->fGLContexts[ctxInd];
 
  425    if (ctx.fPixmapIndex == -1) {
 
  427       wglSwapLayerBuffers(ctx.fDC, WGL_SWAP_MAIN_PLANE);
 
  428    } 
else if (ctx.fDirect) {
 
  430       HDC hDC = CreateCompatibleDC(0);
 
  433          Error(
"Flush", 
"CreateCompatibleDC failed\n");
 
  437       HBITMAP oldDIB = (HBITMAP)SelectObject(hDC, ctx.fHBitmap);
 
  439       if (!BitBlt(ctx.fDC, ctx.fX, ctx.fY, ctx.fW, ctx.fH, hDC, 0, 0, SRCCOPY))
 
  440          ctx.fDirect = kFALSE;
 
  442       SelectObject(hDC, oldDIB);
 
  450 void TGWin32GLManager::DeleteGLContext(Int_t ctxInd)
 
  452    TGLContext &ctx = fPimpl->fGLContexts[ctxInd];
 
  454    if (ctx.fPixmapIndex != -1) {
 
  455       gVirtualX->SelectWindow(ctx.fPixmapIndex);
 
  456       gVirtualX->ClosePixmap();
 
  457       ctx.fPixmapIndex = -1;
 
  460    wglDeleteContext(ctx.fGLContext);
 
  462    ReleaseDC((HWND)GDK_DRAWABLE_XID((GdkWindow *)gVirtualX->GetWindowID(ctx.fWindowIndex)),
 
  465    ctx.fWindowIndex = ctxInd;
 
  466    ctx.fNextFreeContext = fPimpl->fNextFreeContext;
 
  467    fPimpl->fNextFreeContext = &ctx;
 
  472 void TGWin32GLManager::ExtractViewport(Int_t ctxInd, Int_t *viewport)
 
  474    TGLContext &ctx = fPimpl->fGLContexts[ctxInd];
 
  476    if (ctx.fPixmapIndex != -1) {
 
  479       viewport[2] = ctx.fW;
 
  480       viewport[3] = ctx.fH;
 
  486 void TGWin32GLManager::PaintSingleObject(TVirtualGLPainter *p)
 
  493 void TGWin32GLManager::PrintViewer(TVirtualViewer3D *vv)
 
  500 Bool_t TGWin32GLManager::SelectManip(TVirtualGLManip *manip, 
const TGLCamera * camera, 
const TGLRect * rect, 
const TGLBoundingBox * sceneBox)
 
  502    return manip->Select(*camera, *rect, *sceneBox);
 
  507 void TGWin32GLManager::PanObject(TVirtualGLPainter *o, Int_t x, Int_t y)
 
  514 Bool_t TGWin32GLManager::PlotSelected(TVirtualGLPainter *plot, Int_t px, Int_t py)
 
  516    return plot->PlotSelected(px, py);
 
  521 char *TGWin32GLManager::GetPlotInfo(TVirtualGLPainter *plot, Int_t px, Int_t py)
 
  523     return plot->GetPlotInfo(px, py);
 
  528 Bool_t TGWin32GLManager::HighColorFormat(Int_t ctxInd)
 
  533    return fPimpl->fGLContexts[ctxInd].fHighColor;