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

Last change on this file since 4086 was 4086, checked in by garnier, 12 years ago

before moving eventFilter

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