#include #include #include #include #include #include #include "piapplx.h" #include "picontainerx.h" // $CHECK$ - Reza Aout 99 // Il y a un probleme sur la gestion de la taille de la fenetre principale // SetBinding(elastic) ne marche correctement pas sur la fenetre principale // et Des SetSize intempestive peuvent generer des comportements bizarres ! // Pour rediriger stdout #include #include #include // #define DEBUG_APPLX static Cursor a_curs[3]; static bool a_fgcur=false; // Voir fichier pimenux.cc , Pour resoudre certains conflits avec les WindowManagers void SetTopWdgForMenuX(SysDWdg mtw); static PIApplication* cur_piapp = NULL; PIApplication* PIApplicationGetApp() { return cur_piapp; } // Classe de container special pour top-container de Application X class PITopContAppX : public PIContainer { public : PITopContAppX(PIContainer *par, char *nom, PIWdg* topw, int sx=10, int sy=10, int px=0, int py=0); virtual ~PITopContAppX(); virtual void SetSize(int sx, int sy); virtual void SetPos(int px, int py); PIWdg* mTopWdg; }; /* --Methode-- */ PITopContAppX::PITopContAppX(PIContainer *par, char *nom, PIWdg* topw, int sx, int sy, int px, int py) : PIContainer(par, nom, (sx>10)?sx:10, (sy>10)?sy:10, px, py) { mTopWdg = topw; SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_fixed); } /* --Methode-- */ PITopContAppX::~PITopContAppX() { } /* --Methode-- */ void PITopContAppX::SetSize(int sx, int sy) { if ((sx <10) || (sy < 10) ) return; int px = XPos(); int py = YPos(); // Probleme sur Sun - Reza 10/99 , REGLE 08/2000 mTopWdg->SetSize(sx+px, sy+py); XtConfigureWidget(Parent()->XtWdg(), 0, 0, sx+px, sy+py, 0); XtConfigureWidget(XtWdg(), px, py, sx, sy, 0); // SetPos(px, py); // PIContainer::SetSize(sx, sy); } /* --Methode-- */ void PITopContAppX::SetPos(int px, int py) { } // --------------------------------------------- // Fonction pour gestion des close-window /* Nouvelle-Fonction */ static int fgactl = 0; static void CloseWindow (Widget w, XEvent*, String*,Cardinal*) { XtCallCallbacks(w, XtNpopdownCallback, NULL); } /* Nouvelle-Fonction */ static void popdwn_cb_app(Widget /*w*/, XtPointer *usd, XtPointer * ) { PIApplicationX * app = (PIApplicationX *) usd; app->SendSelf(0,PIMsg_Close, NULL) ; } /* --Methode-- */ PIApplicationX::PIApplicationX(int sx, int sy, int narg, char *arg[]) : PIApplicationGen() { int sxt, syt; #ifdef DEBUG_APPLX puts("PIApplicationX::PIApplicationX()_info : App creation"); #endif mStop = true; topwdg = new PIWdgX(narg, arg); int msx,msy; PrefCompSize(msx, msy); msy+=5; topwdg->SetSize(sx, sy+msy); //DBG printf("PIApplicationX-DBG:: Size=%d %d \n", topwdg->XSize(), topwdg->YSize()); intcont = new PIContainerX((PIMsgHandler *)this, topwdg, "MBCont", sx, sy+msy, 0, 0); // Pb avec les Popup MenuX et certains Window Manager , voir pimenux.cc SetTopWdgForMenuX(intcont->XtWdg()); menubar = new PIMenubar(this, "DefMenubar"); Menubar()->SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_free); sxt = ( sx > Menubar()->XSize() ) ? sx : Menubar()->XSize(); syt = ( sy > 10 ) ? sy : 10; // syt += Menubar()->YSize(); // syt += msy; // topwdg->SetSize(sxt, syt); // MBCont()->SetSize(sxt, syt); if (sx < sxt) sx = sxt; if (sy < 10) sy = 10; topcont = new PITopContAppX(MBCont(), "TopLevelCont", topwdg, sx, sy, 0, msy); MBCont()->Show(); //DBG printf("PIApplicationX-DBG2:: MBContSize=%d %d \n", MBCont()->XSize(), MBCont()->YSize()); topcont->Show(); if (!a_fgcur) { Display *mdsp; mdsp = XtDisplay (topwdg->XtWdg()); a_curs[0] = XCreateFontCursor(mdsp, XC_arrow); a_curs[1] = XCreateFontCursor(mdsp, XC_X_cursor); a_curs[2] = XCreateFontCursor(mdsp, XC_watch); } topwdg->Manage(); // ------------------------------------------------------ // Pour la gestion des close window des Window manager if (fgactl == 0) { XtActionsRec desact = {(char *)"CloseWindow" ,CloseWindow}; int szx, szy, szf; XtAppContext * appctx = PIXtAppCtx(szx, szy, szf); XtAppAddActions(*appctx, &desact, 1); Display *mdsp; mdsp = XtDisplay (topwdg->XtWdg()); Atom wmd; wmd = XInternAtom(mdsp, "WM_DELETE_WINDOW",False); XSetWMProtocols(mdsp, XtWindow(topwdg->XtWdg()), &wmd, 1); fgactl = 1; } XtTranslations trans; trans = XtParseTranslationTable("WM_PROTOCOLS:CloseWindow()"); XtOverrideTranslations(topwdg->XtWdg() , trans); Arg warg[2]; XtSetArg(warg[0], XmNdeleteResponse, XmDO_NOTHING); XtSetValues(topwdg->XtWdg(), warg, 1); XtAddCallback(topwdg->XtWdg(), XtNpopdownCallback, (XtCallbackProc)popdwn_cb_app, (XtPointer)this); // ------------------------------------------------------ cur_piapp = this; mState = -1; SetReady(); } /* --Methode-- */ PIApplicationX::~PIApplicationX() { #ifdef DEBUG_APPLX puts("PIApplicationX::~PIApplicationX()_info : App delete"); #endif Display *mdsp; mdsp = XtDisplay (topwdg->XtWdg()); topwdg->UnManage(); delete menubar; if (topcont != MBCont()) delete topcont; delete intcont; delete topwdg; XtCloseDisplay(mdsp); cur_piapp = NULL; return; } /* --Methode-- */ void PIApplicationX::Run() { XEvent evt; #ifdef DEBUG_APPLX puts("PIApplicationX::Run()_info : App Run "); #endif int szx, szy, szf; XtAppContext * appctx = PIXtAppCtx(szx, szy, szf); // Pour appeler FinishCreate() des objets dans la fenetre principale if (mStop) { // C'est la premiere fois topcont->SetSize(topcont->XSize(), topcont->YSize()); // topwdg->SetSize(MBCont()->XSize(), MBCont()->YSize()); MBCont()->FinishCreate(); } else mStop = true; // On rerentre apres un stop while (mStop) { XtAppNextEvent(*appctx, &evt); XtDispatchEvent(&evt); } return; } /* --Methode-- */ void PIApplicationX::SetReady() { Display * mdsp = XtDisplay (topwdg->XtWdg()); if (mState != kReadyState) { mState = kReadyState; Menubar()->SetSensitive(); XDefineCursor(mdsp, XtWindow(topwdg->XtWdg()), a_curs[0]); } XFlush(mdsp); } /* --Methode-- */ void PIApplicationX::SetBusy() { Display * mdsp = XtDisplay (topwdg->XtWdg()); if (mState != kBusyState) { mState = kBusyState; Menubar()->SetSensitive(); // if ( XtIsRealized(topwdg->XtWdg()) ) XDefineCursor(mdsp, XtWindow(topwdg->XtWdg()), a_curs[2]); } XFlush(mdsp); } /* --Methode-- */ void PIApplicationX::SetBlocked() { Display * mdsp = XtDisplay (topwdg->XtWdg()); if (mState != kBlockedState) { mState = kBlockedState; Menubar()->SetUnSensitive(); XDefineCursor(mdsp, XtWindow(topwdg->XtWdg()), a_curs[1]); } XFlush(mdsp); return; } /* --Methode-- */ void PIApplicationX::PrefCompSize(int& szx, int& szy) { int szf; PIXtAppCtx(szx, szy, szf); return; } /* --Methode-- */ void PIApplicationX::ScreenSize(int& szx, int& szy) { Display * dsp = PIXDisplay(); szx = DisplayWidth(dsp, DefaultScreen(dsp)); szy = DisplayHeight(dsp, DefaultScreen(dsp)); } /* --Methode-- */ void PIApplicationX::ScreenSizeMM(int& szx, int& szy) { Display * dsp = PIXDisplay(); szx = DisplayWidthMM(dsp, DefaultScreen(dsp)); szy = DisplayHeightMM(dsp, DefaultScreen(dsp)); } /* --Methode-- */ void PIApplicationX::ScreenResolution(int& resolx, int& resoly) { Display * dsp = PIXDisplay(); resolx = (int)((double)DisplayWidth(dsp, DefaultScreen(dsp))*10./ (double)DisplayWidthMM(dsp, DefaultScreen(dsp))); resoly = (int)((double)DisplayHeight(dsp, DefaultScreen(dsp))*10./ (double)DisplayHeightMM(dsp, DefaultScreen(dsp))); } /* Call-Back - Fonction privee de ce fichier */ static void redirectstream_callback(XtPointer, int *, XtInputId*); static PIConsole* consstream[2] = {NULL, NULL}; static unsigned char streamva[2] = { PIVA_Def, PIVA_Ital}; static int streamno[2] = {0,1}; static XtInputId inputid[2]; static int origfiledes[2]={-1, -1}; // descripteurs de fichiers de depart static void redirectstream_callback(XtPointer cld, int * fd, XtInputId* /*iid*/) { char buff[128]; int nr; int idx = *((int*)cld); if (idx != 1) idx = 0; if (!consstream[idx]) return; while ( (nr=read(*fd, buff, 127)) > 0 ) { buff[nr] = '\0'; consstream[idx]->AddStr(buff, streamva[idx], false); } consstream[idx]->Refresh(); } /* --Methode-- */ void PIApplicationX::RedirectOutStream(PIConsole* cons, unsigned char va) { if ( origfiledes[0]<0 ) origfiledes[0] = fcntl(1, F_DUPFD); if ( cons == consstream[0]) return; if ( (consstream[0]) && (cons) ) { consstream[0] = cons; streamva[0] = va; return; } else if (!cons) { consstream[0] = NULL; XtRemoveInput(inputid[0]); dup2(origfiledes[0], 1); return; } consstream[0] = cons; streamva[0] = va; int p[2]; pipe(p); // Redirection de stdout (fid=1) : close(1); dup(p[1]); close(p[1]); fcntl(p[0], F_SETFL, O_NONBLOCK); #if (!defined(__GNUG__) && !defined(HPUX)) setlinebuf(stdout); #endif ios::sync_with_stdio(); int szx, szy, szf; XtAppContext * appctx = PIXtAppCtx(szx, szy, szf); inputid[0] = XtAppAddInput(*appctx, p[0], (XtPointer) XtInputReadMask, redirectstream_callback, (XtPointer) streamno); } /* --Methode-- */ void PIApplicationX::RedirectErrStream(PIConsole* cons, unsigned char va) { if ( origfiledes[1]<0 ) origfiledes[1] = fcntl(2, F_DUPFD); if ( cons == consstream[1]) return; if ( (consstream[1]) && (cons) ) { consstream[1] = cons; streamva[1] = va; return; } else if (!cons) { consstream[1] = NULL; XtRemoveInput(inputid[1]); dup2(origfiledes[1], 2); return; } consstream[1] = cons; streamva[1] = va; int p[2]; pipe(p); // Redirection de stderr (fid=2) : close(2); dup(p[1]); close(p[1]); fcntl(p[0], F_SETFL, O_NONBLOCK); #if (!defined(__GNUG__) && !defined(HPUX)) setlinebuf(stderr); #endif ios::sync_with_stdio(); int szx, szy, szf; XtAppContext * appctx = PIXtAppCtx(szx, szy, szf); inputid[1] = XtAppAddInput(*appctx, p[0], (XtPointer) XtInputReadMask, redirectstream_callback, (XtPointer) (streamno+1)); }