source: Sophya/trunk/SophyaPI/PI/piapplx.cc@ 3372

Last change on this file since 3372 was 3372, checked in by ansari, 18 years ago

petite correction ds PIApplX::RedirectStdErr - Reza 31/10/2007

File size: 14.0 KB
RevLine 
[2]1#include <stdio.h>
[18]2#include <X11/cursorfont.h>
[1074]3#include <X11/IntrinsicP.h>
[1263]4#include <X11/Shell.h>
5#include <X11/StringDefs.h>
6#include <Xm/Xm.h>
[2615]7#include "sopnamsp.h"
[2]8#include "piapplx.h"
9#include "picontainerx.h"
10
[365]11// $CHECK$ - Reza Aout 99
12// Il y a un probleme sur la gestion de la taille de la fenetre principale
13// SetBinding(elastic) ne marche correctement pas sur la fenetre principale
14// et Des SetSize intempestive peuvent generer des comportements bizarres !
[2]15
[78]16// Pour rediriger stdout
17#include <unistd.h>
18#include <fcntl.h>
[3369]19#include <sys/types.h>
20#include <sys/stat.h>
[2]21
[2322]22#include <iostream>
[78]23
[135]24
[78]25// #define DEBUG_APPLX
26
[18]27static Cursor a_curs[3];
28static bool a_fgcur=false;
29
[60]30// Voir fichier pimenux.cc , Pour resoudre certains conflits avec les WindowManagers
31void SetTopWdgForMenuX(SysDWdg mtw);
32
[111]33static PIApplication* cur_piapp = NULL;
34PIApplication* PIApplicationGetApp() { return cur_piapp; }
35
[126]36
[132]37// Classe de container special pour top-container de Application X
[126]38
[132]39class PITopContAppX : public PIContainer {
40public :
[457]41 PITopContAppX(PIContainer *par, char *nom, PIWdg* topw,
[132]42 int sx=10, int sy=10, int px=0, int py=0);
43 virtual ~PITopContAppX();
44
45 virtual void SetSize(int sx, int sy);
46 virtual void SetPos(int px, int py);
[457]47
48PIWdg* mTopWdg;
[132]49};
50
[1074]51
[2]52/* --Methode-- */
[457]53PITopContAppX::PITopContAppX(PIContainer *par, char *nom, PIWdg* topw, int sx, int sy, int px, int py)
[365]54 : PIContainer(par, nom, (sx>10)?sx:10, (sy>10)?sy:10, px, py)
[132]55{
[457]56 mTopWdg = topw;
[365]57 SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_fixed);
[132]58}
59
60/* --Methode-- */
61PITopContAppX::~PITopContAppX()
62{
63}
64
65/* --Methode-- */
66void PITopContAppX::SetSize(int sx, int sy)
67{
[365]68if ((sx <10) || (sy < 10) ) return;
[1074]69
70int px = XPos();
71int py = YPos();
[1133]72// Probleme sur Sun - Reza 10/99 , REGLE 08/2000
73
[1074]74mTopWdg->SetSize(sx+px, sy+py);
75
76XtConfigureWidget(Parent()->XtWdg(), 0, 0, sx+px, sy+py, 0);
77XtConfigureWidget(XtWdg(), px, py, sx, sy, 0);
78// SetPos(px, py);
79// PIContainer::SetSize(sx, sy);
[132]80}
81
[365]82
[132]83/* --Methode-- */
84void PITopContAppX::SetPos(int px, int py)
85{
86}
87
[1263]88// ---------------------------------------------
89// Fonction pour gestion des close-window
90
91/* Nouvelle-Fonction */
92static int fgactl = 0;
93
94static void CloseWindow (Widget w, XEvent*, String*,Cardinal*)
95{
96XtCallCallbacks(w, XtNpopdownCallback, NULL);
97}
98
99/* Nouvelle-Fonction */
100static void popdwn_cb_app(Widget /*w*/, XtPointer *usd, XtPointer * )
101{
102PIApplicationX * app = (PIApplicationX *) usd;
103app->SendSelf(0,PIMsg_Close, NULL) ;
104}
105
106
[132]107/* --Methode-- */
[2]108PIApplicationX::PIApplicationX(int sx, int sy, int narg, char *arg[])
109: PIApplicationGen()
110{
111int sxt, syt;
112
113#ifdef DEBUG_APPLX
114puts("PIApplicationX::PIApplicationX()_info : App creation");
115#endif
116mStop = true;
[365]117
118
[2]119topwdg = new PIWdgX(narg, arg);
120
[365]121int msx,msy;
[1592]122PrefCompSize(msx, msy);
[365]123msy+=5;
124topwdg->SetSize(sx, sy+msy);
[3216]125//DBG printf("PIApplicationX-DBG:: Size=%d %d \n", topwdg->XSize(), topwdg->YSize());
[365]126
[2]127intcont = new PIContainerX((PIMsgHandler *)this, topwdg, "MBCont",
[365]128 sx, sy+msy, 0, 0);
[60]129// Pb avec les Popup MenuX et certains Window Manager , voir pimenux.cc
130SetTopWdgForMenuX(intcont->XtWdg());
131
[2]132menubar = new PIMenubar(this, "DefMenubar");
[23]133Menubar()->SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_free);
[2]134sxt = ( sx > Menubar()->XSize() ) ? sx : Menubar()->XSize();
[365]135syt = ( sy > 10 ) ? sy : 10;
136// syt += Menubar()->YSize();
137// syt += msy;
138// topwdg->SetSize(sxt, syt);
139// MBCont()->SetSize(sxt, syt);
[132]140if (sx < sxt) sx = sxt;
141if (sy < 10) sy = 10;
[457]142topcont = new PITopContAppX(MBCont(), "TopLevelCont", topwdg,
[132]143 sx, sy, 0, msy);
[163]144MBCont()->Show();
[3216]145//DBG printf("PIApplicationX-DBG2:: MBContSize=%d %d \n", MBCont()->XSize(), MBCont()->YSize());
[2]146
[1074]147
[365]148topcont->Show();
[18]149
[365]150
[18]151if (!a_fgcur)
152 {
153 Display *mdsp;
154 mdsp = XtDisplay (topwdg->XtWdg());
155 a_curs[0] = XCreateFontCursor(mdsp, XC_arrow);
156 a_curs[1] = XCreateFontCursor(mdsp, XC_X_cursor);
157 a_curs[2] = XCreateFontCursor(mdsp, XC_watch);
158 }
159
[365]160topwdg->Manage();
[1263]161
162// ------------------------------------------------------
163// Pour la gestion des close window des Window manager
164
165if (fgactl == 0) {
166 XtActionsRec desact = {(char *)"CloseWindow" ,CloseWindow};
167 int szx, szy, szf;
168 XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
169 XtAppAddActions(*appctx, &desact, 1);
170 Display *mdsp;
171 mdsp = XtDisplay (topwdg->XtWdg());
172 Atom wmd;
173 wmd = XInternAtom(mdsp, "WM_DELETE_WINDOW",False);
174 XSetWMProtocols(mdsp, XtWindow(topwdg->XtWdg()), &wmd, 1);
175 fgactl = 1;
176}
177
178XtTranslations trans;
179trans = XtParseTranslationTable("<Message>WM_PROTOCOLS:CloseWindow()");
180XtOverrideTranslations(topwdg->XtWdg() , trans);
181Arg warg[2];
182XtSetArg(warg[0], XmNdeleteResponse, XmDO_NOTHING);
183XtSetValues(topwdg->XtWdg(), warg, 1);
184
185XtAddCallback(topwdg->XtWdg(), XtNpopdownCallback,
186 (XtCallbackProc)popdwn_cb_app, (XtPointer)this);
187
188// ------------------------------------------------------
189
[111]190cur_piapp = this;
[18]191mState = -1;
192SetReady();
[2]193}
194
195/* --Methode-- */
196PIApplicationX::~PIApplicationX()
197{
198#ifdef DEBUG_APPLX
199puts("PIApplicationX::~PIApplicationX()_info : App delete");
200#endif
[18]201Display *mdsp;
202mdsp = XtDisplay (topwdg->XtWdg());
[52]203topwdg->UnManage();
[6]204delete menubar;
205if (topcont != MBCont()) delete topcont;
206delete intcont;
[2]207delete topwdg;
[18]208XtCloseDisplay(mdsp);
[111]209cur_piapp = NULL;
[18]210return;
[2]211}
212
213/* --Methode-- */
214void PIApplicationX::Run()
215{
216XEvent evt;
217#ifdef DEBUG_APPLX
218puts("PIApplicationX::Run()_info : App Run ");
219#endif
220
221
[114]222int szx, szy, szf;
223XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
[90]224
[110]225// Pour appeler FinishCreate() des objets dans la fenetre principale
[365]226if (mStop) { // C'est la premiere fois
[1074]227 topcont->SetSize(topcont->XSize(), topcont->YSize());
228 // topwdg->SetSize(MBCont()->XSize(), MBCont()->YSize());
[365]229 MBCont()->FinishCreate();
230 }
[141]231else mStop = true; // On rerentre apres un stop
[2]232while (mStop)
233 {
[90]234 XtAppNextEvent(*appctx, &evt);
[2]235 XtDispatchEvent(&evt);
236 }
237return;
238}
[18]239
240
241/* --Methode-- */
242void PIApplicationX::SetReady()
243{
[138]244Display * mdsp = XtDisplay (topwdg->XtWdg());
[18]245if (mState != kReadyState)
246 {
247 mState = kReadyState;
[106]248 Menubar()->SetSensitive();
[18]249 XDefineCursor(mdsp, XtWindow(topwdg->XtWdg()), a_curs[0]);
250 }
[138]251XFlush(mdsp);
[18]252}
253
254/* --Methode-- */
255void PIApplicationX::SetBusy()
256{
[138]257Display * mdsp = XtDisplay (topwdg->XtWdg());
[18]258if (mState != kBusyState)
259 {
260 mState = kBusyState;
[106]261 Menubar()->SetSensitive();
[18]262// if ( XtIsRealized(topwdg->XtWdg()) )
263 XDefineCursor(mdsp, XtWindow(topwdg->XtWdg()), a_curs[2]);
264 }
[138]265XFlush(mdsp);
[18]266}
267
268/* --Methode-- */
269void PIApplicationX::SetBlocked()
270{
[138]271Display * mdsp = XtDisplay (topwdg->XtWdg());
[18]272if (mState != kBlockedState)
273 {
274 mState = kBlockedState;
[106]275 Menubar()->SetUnSensitive();
[18]276 XDefineCursor(mdsp, XtWindow(topwdg->XtWdg()), a_curs[1]);
277 }
[138]278XFlush(mdsp);
279return;
[18]280}
[75]281
282
283/* --Methode-- */
[1592]284void PIApplicationX::PrefCompSize(int& szx, int& szy)
[75]285{
[114]286int szf;
287PIXtAppCtx(szx, szy, szf);
[90]288return;
[75]289}
290
[92]291/* --Methode-- */
[1592]292void PIApplicationX::ScreenSize(int& szx, int& szy)
[92]293{
294Display * dsp = PIXDisplay();
295szx = DisplayWidth(dsp, DefaultScreen(dsp));
296szy = DisplayHeight(dsp, DefaultScreen(dsp));
297}
[75]298
[1592]299/* --Methode-- */
300void PIApplicationX::ScreenSizeMM(int& szx, int& szy)
301{
302Display * dsp = PIXDisplay();
303szx = DisplayWidthMM(dsp, DefaultScreen(dsp));
304szy = DisplayHeightMM(dsp, DefaultScreen(dsp));
305}
[92]306
[1592]307/* --Methode-- */
308void PIApplicationX::ScreenResolution(int& resolx, int& resoly)
309{
310Display * dsp = PIXDisplay();
311resolx = (int)((double)DisplayWidth(dsp, DefaultScreen(dsp))*10./
312 (double)DisplayWidthMM(dsp, DefaultScreen(dsp)));
313resoly = (int)((double)DisplayHeight(dsp, DefaultScreen(dsp))*10./
314 (double)DisplayHeightMM(dsp, DefaultScreen(dsp)));
315}
[92]316
[1592]317
318
319
320
[78]321/* Call-Back - Fonction privee de ce fichier */
[81]322static void redirectstream_callback(XtPointer, int *, XtInputId*);
[78]323
[81]324static PIConsole* consstream[2] = {NULL, NULL};
325static unsigned char streamva[2] = { PIVA_Def, PIVA_Ital};
326static int streamno[2] = {0,1};
[135]327static XtInputId inputid[2];
328static int origfiledes[2]={-1, -1}; // descripteurs de fichiers de depart
[3369]329static bool fgcopieos[2]={false, false}; // Si true, recopie sur descripteurs de depart, en plus de redirection
330static int readfiledes[2]={-1, -1}; // descripteurs de fichiers ouvert en lecture , si redirection a travers fichier
331static XtIntervalId intervid[2];
332static unsigned long tm_interv = 40; // intervalle timer = 40 ms
[78]333
[3369]334//DBG static FILE * dbgfip = NULL;
335
336// call-back pour gestion de redirection stdout/stderr avec pipe
[81]337static void redirectstream_callback(XtPointer cld, int * fd, XtInputId* /*iid*/)
[78]338{
[2607]339char buff[512];
[3369]340int nr, tnr;
[81]341
342int idx = *((int*)cld);
343if (idx != 1) idx = 0;
[135]344if (!consstream[idx]) return;
[3369]345tnr = 0;
346while ( (nr=read(*fd, buff, 511)) > 0 ) {
[81]347 buff[nr] = '\0'; consstream[idx]->AddStr(buff, streamva[idx], false);
[3369]348 tnr += nr;
[78]349 }
[3369]350if (tnr > 0) consstream[idx]->Refresh();
[78]351}
352
[3369]353// call-back pour gestion de redirection stdout/stderr avec pipe
354static void redirectstream_timeout_callback(XtPointer cld, XtIntervalId * /*tid*/)
355{
356char buff[512];
357int nr, tnr;
358
359int idx = *((int*)cld);
360if (idx != 1) idx = 0;
361if (!consstream[idx]) return;
362tnr = 0;
363while ( (nr=read(readfiledes[idx], buff, 511)) > 0 ) {
364 buff[nr] = '\0'; consstream[idx]->AddStr(buff, streamva[idx], false);
365 tnr += nr;
366 if (fgcopieos[idx]) write(origfiledes[idx], buff, nr); // recopie sur filedesc original
367 }
368if (tnr > 0) consstream[idx]->Refresh();
369int szx, szy, szf;
370XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
371intervid[idx] = XtAppAddTimeOut(*appctx, tm_interv, redirectstream_timeout_callback, (XtPointer)(streamno+idx));
372}
373
[78]374/* --Methode-- */
[81]375void PIApplicationX::RedirectOutStream(PIConsole* cons, unsigned char va)
[78]376{
[3369]377if ( origfiledes[0]<0 ) origfiledes[0] = fcntl(1, F_DUPFD, 0);
378if ( cons == consstream[0]) {
379 streamva[0] = va;
380 return;
381}
[135]382if ( (consstream[0]) && (cons) ) { consstream[0] = cons; streamva[0] = va; return; }
383else if (!cons) {
384 consstream[0] = NULL;
385 XtRemoveInput(inputid[0]);
386 dup2(origfiledes[0], 1);
387 return;
388 }
[78]389
[81]390consstream[0] = cons; streamva[0] = va;
391
[78]392int p[2];
393pipe(p);
[90]394// Redirection de stdout (fid=1) :
[78]395close(1);
396dup(p[1]);
397close(p[1]);
398fcntl(p[0], F_SETFL, O_NONBLOCK);
[135]399
[365]400#if (!defined(__GNUG__) && !defined(HPUX))
[85]401setlinebuf(stdout);
[163]402#endif
[135]403ios::sync_with_stdio();
[78]404
[114]405int szx, szy, szf;
406XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
[135]407inputid[0] = XtAppAddInput(*appctx, p[0], (XtPointer) XtInputReadMask,
408 redirectstream_callback, (XtPointer) streamno);
[3369]409//DBG if (dbgfip == NULL) dbgfip = fopen("debug.log","w");
[78]410}
[81]411
412/* --Methode-- */
413void PIApplicationX::RedirectErrStream(PIConsole* cons, unsigned char va)
414{
[3369]415if ( origfiledes[1]<0 ) origfiledes[1] = fcntl(2, F_DUPFD, 0);
416if ( cons == consstream[1]) {
417 streamva[1] = va;
418 return;
419}
[135]420if ( (consstream[1]) && (cons) ) { consstream[1] = cons; streamva[1] = va; return; }
421else if (!cons) {
422 consstream[1] = NULL;
423 XtRemoveInput(inputid[1]);
424 dup2(origfiledes[1], 2);
425 return;
426 }
[81]427
428consstream[1] = cons; streamva[1] = va;
429
430int p[2];
431pipe(p);
[135]432// Redirection de stderr (fid=2) :
[81]433close(2);
434dup(p[1]);
435close(p[1]);
436fcntl(p[0], F_SETFL, O_NONBLOCK);
[135]437
[365]438#if (!defined(__GNUG__) && !defined(HPUX))
[85]439setlinebuf(stderr);
[163]440#endif
[135]441ios::sync_with_stdio();
[81]442
[114]443int szx, szy, szf;
444XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
[135]445inputid[1] = XtAppAddInput(*appctx, p[0], (XtPointer) XtInputReadMask,
446 redirectstream_callback, (XtPointer) (streamno+1));
[81]447}
448
[3369]449/* --Methode-- */
450void PIApplicationX::RedirectOutStream(PIConsole* cons, string const & flnm, bool fgcpos, unsigned char va)
451{
452if (origfiledes[0] < 0) {
453 origfiledes[0] = dup(1);
454 if (origfiledes[0] < 0) { perror("RedirectOutStream()/ERROR ofd[0]<0 "); return; }
455}
456if (readfiledes[0] > -1) { close(readfiledes[0]); readfiledes[0] = -1;}
457if (!cons) { // requete d'annulation de redirection
458 if (origfiledes[0] > -1) dup2(origfiledes[0], 1);
459 XtRemoveTimeOut(intervid[0]);
460 consstream[0] = NULL;
461 return;
462 }
463
464int fidso = open(flnm.c_str(), O_CREAT|O_WRONLY|O_NONBLOCK, S_IRUSR|S_IWUSR);
465if (fidso < 0) {
466 printf("PIApplicationX::RedirectOutStream()/ERROR creating file %s \n", flnm.c_str());
467 return;
468}
469int rdfid = open(flnm.c_str(), O_RDONLY|O_NONBLOCK, 0);
470if (rdfid < 0) {
471 printf("PIApplicationX::RedirectOutStream()/ERROR opening file %s for read \n", flnm.c_str());
472 return;
473}
474readfiledes[0] = rdfid;
475dup2(fidso, 1); // close(1=stdout), recopie fidso en fd=1
476close(fidso); // on ferme le fidso (on l'a recopie en fd=1)
477consstream[0] = cons; streamva[0] = va; fgcopieos[0] = fgcpos;
478
479#if (!defined(__GNUG__) && !defined(HPUX))
480setlinebuf(stdout);
481#endif
482ios::sync_with_stdio();
483
484int szx, szy, szf;
485XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
486intervid[0] = XtAppAddTimeOut(*appctx, tm_interv, redirectstream_timeout_callback,
487 (XtPointer)(streamno+0));
488
489//DBG if (dbgfip == NULL) dbgfip = fopen("debug.log","w");
490}
491
492/* --Methode-- */
493void PIApplicationX::RedirectErrStream(PIConsole* cons, string const & flnm, bool fgcpos, unsigned char va)
494{
495if (origfiledes[1] < 0) {
496 origfiledes[1] = dup(2);
497 if (origfiledes[1] < 0) { perror("RedirectOutStream()/ERROR ofd[1]<0 "); return; }
498}
499if (readfiledes[1] > -1) { close(readfiledes[1]); readfiledes[1] = -1;}
500if (!cons) { // requete d'annulation de redirection
[3372]501 if (origfiledes[1] > -1) dup2(origfiledes[1], 2);
[3369]502 XtRemoveTimeOut(intervid[1]);
503 consstream[1] = NULL;
504 return;
505 }
506
507int fidso = open(flnm.c_str(), O_CREAT|O_WRONLY|O_NONBLOCK, S_IRUSR|S_IWUSR);
508if (fidso < 0) {
509 printf("PIApplicationX::RedirectOutStream()/ERROR creating file %s \n", flnm.c_str());
510 return;
511}
512int rdfid = open(flnm.c_str(), O_RDONLY|O_NONBLOCK, 0);
513if (rdfid < 0) {
514 printf("PIApplicationX::RedirectOutStream()/ERROR opening file %s for read \n", flnm.c_str());
515 return;
516}
517readfiledes[1] = rdfid;
518dup2(fidso, 2); // close(2=stderr), recopie fidso en fd=2
519close(fidso); // on ferme le fidso (on l'a recopie en fd=2)
520consstream[1] = cons; streamva[1] = va; fgcopieos[1] = fgcpos;
521
522#if (!defined(__GNUG__) && !defined(HPUX))
523setlinebuf(stderr);
524#endif
525ios::sync_with_stdio();
526
527int szx, szy, szf;
528XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
529intervid[1] = XtAppAddTimeOut(*appctx, tm_interv, redirectstream_timeout_callback,
530 (XtPointer)(streamno+1));
531}
532
Note: See TracBrowser for help on using the repository browser.