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

Last change on this file since 4077 was 4077, checked in by garnier, 13 years ago

Last version of PI comming from Reza

File size: 14.1 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, 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, 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);
129//DBG printf("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,
147 sx, sy, 0, msy);
148MBCont()->Show();
149//DBG printf("PIApplicationX-DBG2:: MBContSize=%d %d \n", MBCont()->XSize(), MBCont()->YSize());
150
151
152topcont->Show();
153
154
155if (!a_fgcur)
156 {
157 Display *mdsp;
158 mdsp = XtDisplay (topwdg->XtWdg());
159 a_curs[0] = XCreateFontCursor(mdsp, XC_arrow);
160 a_curs[1] = XCreateFontCursor(mdsp, XC_X_cursor);
161 a_curs[2] = XCreateFontCursor(mdsp, XC_watch);
162 }
163
164topwdg->Manage();
165
166// ------------------------------------------------------
167// Pour la gestion des close window des Window manager
168
169if (fgactl == 0) {
170 XtActionsRec desact = {(char *)"CloseWindow" ,CloseWindow};
171 int szx, szy, szf;
172 XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
173 XtAppAddActions(*appctx, &desact, 1);
174 Display *mdsp;
175 mdsp = XtDisplay (topwdg->XtWdg());
176 Atom wmd;
177 wmd = XInternAtom(mdsp, "WM_DELETE_WINDOW",False);
178 XSetWMProtocols(mdsp, XtWindow(topwdg->XtWdg()), &wmd, 1);
179 fgactl = 1;
180}
181
182XtTranslations trans;
183trans = XtParseTranslationTable("<Message>WM_PROTOCOLS:CloseWindow()");
184XtOverrideTranslations(topwdg->XtWdg() , trans);
185Arg warg[2];
186XtSetArg(warg[0], XmNdeleteResponse, XmDO_NOTHING);
187XtSetValues(topwdg->XtWdg(), warg, 1);
188
189XtAddCallback(topwdg->XtWdg(), XtNpopdownCallback,
190 (XtCallbackProc)popdwn_cb_app, (XtPointer)this);
191
192// ------------------------------------------------------
193
194cur_piapp = this;
195mState = -1;
196SetReady();
197}
198
199/* --Methode-- */
200PIApplicationX::~PIApplicationX()
201{
202#ifdef DEBUG_APPLX
203puts("PIApplicationX::~PIApplicationX()_info : App delete");
204#endif
205Display *mdsp;
206mdsp = XtDisplay (topwdg->XtWdg());
207topwdg->UnManage();
208delete menubar;
209if (topcont != MBCont()) delete topcont;
210delete intcont;
211delete topwdg;
212XtCloseDisplay(mdsp);
213cur_piapp = NULL;
214return;
215}
216
217/* --Methode-- */
218void PIApplicationX::Run()
219{
220XEvent evt;
221#ifdef DEBUG_APPLX
222puts("PIApplicationX::Run()_info : App Run ");
223#endif
224
225
226int szx, szy, szf;
227XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
228
229// Pour appeler FinishCreate() des objets dans la fenetre principale
230if (mStop) { // C'est la premiere fois
231 topcont->SetSize(topcont->XSize(), topcont->YSize());
232 // topwdg->SetSize(MBCont()->XSize(), MBCont()->YSize());
233 MBCont()->FinishCreate();
234 }
235else mStop = true; // On rerentre apres un stop
236while (mStop)
237 {
238 XtAppNextEvent(*appctx, &evt);
239 XtDispatchEvent(&evt);
240 }
241return;
242}
243
244
245/* --Methode-- */
246void PIApplicationX::SetReady()
247{
248Display * mdsp = XtDisplay (topwdg->XtWdg());
249if (mState != kReadyState)
250 {
251 mState = kReadyState;
252 Menubar()->SetSensitive();
253 XDefineCursor(mdsp, XtWindow(topwdg->XtWdg()), a_curs[0]);
254 }
255XFlush(mdsp);
256}
257
258/* --Methode-- */
259void PIApplicationX::SetBusy()
260{
261Display * mdsp = XtDisplay (topwdg->XtWdg());
262if (mState != kBusyState)
263 {
264 mState = kBusyState;
265 Menubar()->SetSensitive();
266// if ( XtIsRealized(topwdg->XtWdg()) )
267 XDefineCursor(mdsp, XtWindow(topwdg->XtWdg()), a_curs[2]);
268 }
269XFlush(mdsp);
270}
271
272/* --Methode-- */
273void PIApplicationX::SetBlocked()
274{
275Display * mdsp = XtDisplay (topwdg->XtWdg());
276if (mState != kBlockedState)
277 {
278 mState = kBlockedState;
279 Menubar()->SetUnSensitive();
280 XDefineCursor(mdsp, XtWindow(topwdg->XtWdg()), a_curs[1]);
281 }
282XFlush(mdsp);
283return;
284}
285
286
287/* --Methode-- */
288void PIApplicationX::PrefCompSize(int& szx, int& szy)
289{
290int szf;
291PIXtAppCtx(szx, szy, szf);
292return;
293}
294
295/* --Methode-- */
296void PIApplicationX::ScreenSize(int& szx, int& szy)
297{
298Display * dsp = PIXDisplay();
299szx = DisplayWidth(dsp, DefaultScreen(dsp));
300szy = DisplayHeight(dsp, DefaultScreen(dsp));
301}
302
303/* --Methode-- */
304void PIApplicationX::ScreenSizeMM(int& szx, int& szy)
305{
306Display * dsp = PIXDisplay();
307szx = DisplayWidthMM(dsp, DefaultScreen(dsp));
308szy = DisplayHeightMM(dsp, DefaultScreen(dsp));
309}
310
311/* --Methode-- */
312void PIApplicationX::ScreenResolution(int& resolx, int& resoly)
313{
314Display * dsp = PIXDisplay();
315resolx = (int)((double)DisplayWidth(dsp, DefaultScreen(dsp))*10./
316 (double)DisplayWidthMM(dsp, DefaultScreen(dsp)));
317resoly = (int)((double)DisplayHeight(dsp, DefaultScreen(dsp))*10./
318 (double)DisplayHeightMM(dsp, DefaultScreen(dsp)));
319}
320
321
322
323
324
325/* Call-Back - Fonction privee de ce fichier */
326static void redirectstream_callback(XtPointer, int *, XtInputId*);
327
328static PIConsole* consstream[2] = {NULL, NULL};
329static unsigned char streamva[2] = { PIVA_Def, PIVA_Ital};
330static int streamno[2] = {0,1};
331static XtInputId inputid[2];
332static int origfiledes[2]={-1, -1}; // descripteurs de fichiers de depart
333static bool fgcopieos[2]={false, false}; // Si true, recopie sur descripteurs de depart, en plus de redirection
334static int readfiledes[2]={-1, -1}; // descripteurs de fichiers ouvert en lecture , si redirection a travers fichier
335static XtIntervalId intervid[2];
336static unsigned long tm_interv = 40; // intervalle timer = 40 ms
337
338//DBG static FILE * dbgfip = NULL;
339
340// call-back pour gestion de redirection stdout/stderr avec pipe
341static void redirectstream_callback(XtPointer cld, int * fd, XtInputId* /*iid*/)
342{
343char buff[512];
344int nr, tnr;
345
346int idx = *((int*)cld);
347if (idx != 1) idx = 0;
348if (!consstream[idx]) return;
349tnr = 0;
350while ( (nr=read(*fd, buff, 511)) > 0 ) {
351 buff[nr] = '\0'; consstream[idx]->AddStr(buff, streamva[idx], false);
352 tnr += nr;
353 }
354if (tnr > 0) consstream[idx]->Refresh();
355}
356
357// call-back pour gestion de redirection stdout/stderr avec pipe
358static void redirectstream_timeout_callback(XtPointer cld, XtIntervalId * /*tid*/)
359{
360char buff[512];
361int nr, tnr;
362
363int idx = *((int*)cld);
364if (idx != 1) idx = 0;
365if (!consstream[idx]) return;
366tnr = 0;
367while ( (nr=read(readfiledes[idx], buff, 511)) > 0 ) {
368 buff[nr] = '\0'; consstream[idx]->AddStr(buff, streamva[idx], false);
369 tnr += nr;
370 if (fgcopieos[idx]) write(origfiledes[idx], buff, nr); // recopie sur filedesc original
371 }
372if (tnr > 0) consstream[idx]->Refresh();
373int szx, szy, szf;
374XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
375intervid[idx] = XtAppAddTimeOut(*appctx, tm_interv, redirectstream_timeout_callback, (XtPointer)(streamno+idx));
376}
377
378/* --Methode-- */
379void PIApplicationX::RedirectOutStream(PIConsole* cons, unsigned char va)
380{
381if ( origfiledes[0]<0 ) origfiledes[0] = fcntl(1, F_DUPFD, 0);
382if ( cons == consstream[0]) {
383 streamva[0] = va;
384 return;
385}
386if ( (consstream[0]) && (cons) ) { consstream[0] = cons; streamva[0] = va; return; }
387else if (!cons) {
388 consstream[0] = NULL;
389 XtRemoveInput(inputid[0]);
390 dup2(origfiledes[0], 1);
391 return;
392 }
393
394consstream[0] = cons; streamva[0] = va;
395
396int p[2];
397pipe(p);
398// Redirection de stdout (fid=1) :
399close(1);
400dup(p[1]);
401close(p[1]);
402fcntl(p[0], F_SETFL, O_NONBLOCK);
403
404#if (!defined(__GNUG__) && !defined(HPUX))
405setlinebuf(stdout);
406#endif
407ios::sync_with_stdio();
408
409int szx, szy, szf;
410XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
411inputid[0] = XtAppAddInput(*appctx, p[0], (XtPointer) XtInputReadMask,
412 redirectstream_callback, (XtPointer) streamno);
413//DBG if (dbgfip == NULL) dbgfip = fopen("debug.log","w");
414}
415
416/* --Methode-- */
417void PIApplicationX::RedirectErrStream(PIConsole* cons, unsigned char va)
418{
419if ( origfiledes[1]<0 ) origfiledes[1] = fcntl(2, F_DUPFD, 0);
420if ( cons == consstream[1]) {
421 streamva[1] = va;
422 return;
423}
424if ( (consstream[1]) && (cons) ) { consstream[1] = cons; streamva[1] = va; return; }
425else if (!cons) {
426 consstream[1] = NULL;
427 XtRemoveInput(inputid[1]);
428 dup2(origfiledes[1], 2);
429 return;
430 }
431
432consstream[1] = cons; streamva[1] = va;
433
434int p[2];
435pipe(p);
436// Redirection de stderr (fid=2) :
437close(2);
438dup(p[1]);
439close(p[1]);
440fcntl(p[0], F_SETFL, O_NONBLOCK);
441
442#if (!defined(__GNUG__) && !defined(HPUX))
443setlinebuf(stderr);
444#endif
445ios::sync_with_stdio();
446
447int szx, szy, szf;
448XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
449inputid[1] = XtAppAddInput(*appctx, p[0], (XtPointer) XtInputReadMask,
450 redirectstream_callback, (XtPointer) (streamno+1));
451}
452
453/* --Methode-- */
454void PIApplicationX::RedirectOutStream(PIConsole* cons, string const & flnm, bool fgcpos, unsigned char va)
455{
456if (origfiledes[0] < 0) {
457 origfiledes[0] = dup(1);
458 if (origfiledes[0] < 0) { perror("RedirectOutStream()/ERROR ofd[0]<0 "); return; }
459}
460if (readfiledes[0] > -1) { close(readfiledes[0]); readfiledes[0] = -1;}
461if (!cons) { // requete d'annulation de redirection
462 if (origfiledes[0] > -1) dup2(origfiledes[0], 1);
463 XtRemoveTimeOut(intervid[0]);
464 consstream[0] = NULL;
465 return;
466 }
467
468int fidso = open(flnm.c_str(), O_CREAT|O_WRONLY|O_NONBLOCK, S_IRUSR|S_IWUSR);
469if (fidso < 0) {
470 printf("PIApplicationX::RedirectOutStream()/ERROR creating file %s \n", flnm.c_str());
471 return;
472}
473int rdfid = open(flnm.c_str(), O_RDONLY|O_NONBLOCK, 0);
474if (rdfid < 0) {
475 printf("PIApplicationX::RedirectOutStream()/ERROR opening file %s for read \n", flnm.c_str());
476 return;
477}
478readfiledes[0] = rdfid;
479dup2(fidso, 1); // close(1=stdout), recopie fidso en fd=1
480close(fidso); // on ferme le fidso (on l'a recopie en fd=1)
481consstream[0] = cons; streamva[0] = va; fgcopieos[0] = fgcpos;
482
483#if (!defined(__GNUG__) && !defined(HPUX))
484setlinebuf(stdout);
485#endif
486ios::sync_with_stdio();
487
488int szx, szy, szf;
489XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
490intervid[0] = XtAppAddTimeOut(*appctx, tm_interv, redirectstream_timeout_callback,
491 (XtPointer)(streamno+0));
492
493//DBG if (dbgfip == NULL) dbgfip = fopen("debug.log","w");
494}
495
496/* --Methode-- */
497void PIApplicationX::RedirectErrStream(PIConsole* cons, string const & flnm, bool fgcpos, unsigned char va)
498{
499if (origfiledes[1] < 0) {
500 origfiledes[1] = dup(2);
501 if (origfiledes[1] < 0) { perror("RedirectOutStream()/ERROR ofd[1]<0 "); return; }
502}
503if (readfiledes[1] > -1) { close(readfiledes[1]); readfiledes[1] = -1;}
504if (!cons) { // requete d'annulation de redirection
505 if (origfiledes[1] > -1) dup2(origfiledes[1], 2);
506 XtRemoveTimeOut(intervid[1]);
507 consstream[1] = NULL;
508 return;
509 }
510
511int fidso = open(flnm.c_str(), O_CREAT|O_WRONLY|O_NONBLOCK, S_IRUSR|S_IWUSR);
512if (fidso < 0) {
513 printf("PIApplicationX::RedirectOutStream()/ERROR creating file %s \n", flnm.c_str());
514 return;
515}
516int rdfid = open(flnm.c_str(), O_RDONLY|O_NONBLOCK, 0);
517if (rdfid < 0) {
518 printf("PIApplicationX::RedirectOutStream()/ERROR opening file %s for read \n", flnm.c_str());
519 return;
520}
521readfiledes[1] = rdfid;
522dup2(fidso, 2); // close(2=stderr), recopie fidso en fd=2
523close(fidso); // on ferme le fidso (on l'a recopie en fd=2)
524consstream[1] = cons; streamva[1] = va; fgcopieos[1] = fgcpos;
525
526#if (!defined(__GNUG__) && !defined(HPUX))
527setlinebuf(stderr);
528#endif
529ios::sync_with_stdio();
530
531int szx, szy, szf;
532XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
533intervid[1] = XtAppAddTimeOut(*appctx, tm_interv, redirectstream_timeout_callback,
534 (XtPointer)(streamno+1));
535}
536
537#endif
538#endif
539
Note: See TracBrowser for help on using the repository browser.