// // This File contains the definition of the MGImage-class // // Author: Thomas Bretz // Version: V1.0 (1-8-2000) // // x11/src/GX11Gui.cxx // ////////////////////////////////////////////////////////////////////////////// // // MGImage // // If sync-mode is enabled the Redraw function is secured by a mutex (ignore // error messages about it comming from root) This has the advantage that // if you use a timer for screen update reading and writing the image is // synchronized. In this way you don't get flickering half images. // ////////////////////////////////////////////////////////////////////////////// #include "MGImage.h" #include #include #include "MLog.h" #include "MLogManip.h" ClassImp(MGImage); using namespace std; MGImage::MGImage(const TGWindow* p, UInt_t w, UInt_t h, UInt_t options, ULong_t back) : TGFrame(p, w, h, options, back), fWidth(w), fHeight(h) { // p = pointer to MainFrame (not owner) // w = width of frame // h = width of frame // // Creat drawing semaphore // fMuxPixmap = new TMutex; Resize(GetWidth(), GetHeight()); // // create empty pixmap // fDefGC = gVirtualX->CreateGC(fId, 0); fImage = (XImage*)gVirtualX->CreateImage(fWidth, fHeight); gLog << all << "Detected Color Depth: " << gVirtualX->GetDepth() << endl; } MGImage::~MGImage() { if (fMuxPixmap->Lock()==13) cout << "MGImage::~MGImage - mutex is already locked by this thread" << endl; gLog << inf2 << "Deleting MGImage..." << endl; gVirtualX->DeleteGC(fDefGC); gVirtualX->DeleteImage((Drawable_t)fImage); //cout << fMuxPixmap->UnLock() << endl; delete fMuxPixmap; gLog << inf2 << "MGImage destroyed." << endl; } void MGImage::DoRedraw() { if (TestBit(kSyncMode)) while (fMuxPixmap->Lock()==13) usleep(1); // gVirtualX->DrawLine(fId, fDefGC, 0, 0, fWidth+2, 0); // gVirtualX->DrawLine(fId, fDefGC, 0, 0, 0, fHeight+2); // gVirtualX->DrawLine(fId, fDefGC, fWidth+2, 0, fWidth+2, fHeight+2); // gVirtualX->DrawLine(fId, fDefGC, 0, fHeight+2, fWidth+2, fHeight+2); // if (TestBit(kNeedRedraw)) { gVirtualX->PutImage(fId, fDefGC, (Drawable_t)fImage, 0, 0, 0, 0, fWidth, fHeight); ResetBit(kNeedRedraw); } if (TestBit(kSyncMode)) if (fMuxPixmap->UnLock()==13) gLog << warn << "MGImage::DoRedraw - tried to unlock mutex locked by other thread." << endl; } void MGImage::DrawImg16(unsigned short *d, char *s, char *e) { // d=destination, s=source, e=end // rrrrrggg gggbbbbb // while (s>3); s++; } } void MGImage::DrawImg24(char *d, char *s, char *e) { // d=destination, s=source, e=end // rrrrrrrr gggggggg bbbbbbbb aaaaaaaa // while (sLock()==13) usleep(1); else { const Int_t rc = fMuxPixmap->Lock(); if (rc==13) cout << "MGImage::DrawImg - mutex is already locked by this thread" << endl; if (rc) return; } switch (gVirtualX->GetDepth()) { case 8: memcpy(fImage->data, buffer, fWidth*fHeight); break; case 16: DrawImg16((unsigned short*)fImage->data, (char*)buffer, (char*)(buffer+fWidth*fHeight)); break; case 24: DrawImg24(fImage->data, (char*)buffer, (char*)(buffer+fWidth*fHeight)); break; default: cout << "Sorry, " << gVirtualX->GetDepth() << "bit color depth not yet implemented." << endl; } SetBit(kNeedRedraw); if (fMuxPixmap->UnLock()==13) cout << "MGImage::DrawImage - tried to unlock mutex locked by other thread." << endl; } void MGImage::DrawColImg16(unsigned short *d, char *s1, char *s2, char *e) { // d=destination, s1=source1, s2=source2, e=end // d: rrrrrggg gggbbbbb // s2: 00rrggbb // while (s1>4)&0x3)*85; *d++ = ((*s2>>2)&0x3)*85; *d++ = ((*s2++ )&0x3)*85; d++; s1++; } else { *d++ = *s1; *d++ = *s1; *d++ = *s1++; d++; s2++; } } } void MGImage::DrawColImg(const byte *gbuf, const byte *cbuf) { if (TestBit(kSyncMode)) while (fMuxPixmap->Lock()==13) usleep(1); else { const Int_t rc = fMuxPixmap->Lock(); if (rc==13) cout << "MGImage::DrawColImg - mutex is already locked by this thread" << endl; if (rc) return; } // FROM libAfterImage: // ------------------- //#define ALPHA_TRANSPARENT 0x00 //#define ALPHA_SEMI_TRANSPARENT 0x7F //#define ALPHA_SOLID 0xFF // * Lowermost 8 bits - Blue channel // * bits 8 to 15 - Green channel // * bits 16 to 23 - Red channel // * bits 24 to 31 - Alpha channel //#define ARGB32_White 0xFFFFFFFF //#define ARGB32_Black 0xFF000000 // FIXME: This loop depends on the screen color depth switch (gVirtualX->GetDepth()) { case 16: DrawColImg16((unsigned short*)fImage->data, (char*)gbuf, (char*)cbuf, (char*)(gbuf+fWidth*fHeight)); break; case 24: DrawColImg24(fImage->data, (char*)gbuf, (char*)cbuf, (char*)(gbuf+fWidth*fHeight)); break; default: cout << "Sorry, " << gVirtualX->GetDepth() << "bit color depth not yet implemented." << endl; } SetBit(kNeedRedraw); if (fMuxPixmap->UnLock()==13) cout << "MGImage::DrawColImage - tried to unlock mutex locked by other thread." << endl; }