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

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

1/ Ajout include picons.h ds piapplx.cc suite suppression include ds piapplgen.h
2/ Remplacement PIBaseWdg par PIBaseWdgGen ds pidrwtools.h .cc

Reza , 15/02/2008

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