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
RevLine 
[4077]1#ifndef __PIWQUARTZ__
2#ifndef __MWERKS__
3
[2]4#include <stdio.h>
[18]5#include <X11/cursorfont.h>
[1074]6#include <X11/IntrinsicP.h>
[1263]7#include <X11/Shell.h>
8#include <X11/StringDefs.h>
9#include <Xm/Xm.h>
[2615]10#include "sopnamsp.h"
[2]11#include "piapplx.h"
12#include "picontainerx.h"
[3475]13#include "picons.h"
[2]14
[365]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 !
[2]19
[78]20// Pour rediriger stdout
21#include <unistd.h>
22#include <fcntl.h>
[3369]23#include <sys/types.h>
24#include <sys/stat.h>
[2]25
[2322]26#include <iostream>
[78]27
[135]28
[78]29// #define DEBUG_APPLX
30
[18]31static Cursor a_curs[3];
32static bool a_fgcur=false;
33
[60]34// Voir fichier pimenux.cc , Pour resoudre certains conflits avec les WindowManagers
35void SetTopWdgForMenuX(SysDWdg mtw);
36
[111]37static PIApplication* cur_piapp = NULL;
38PIApplication* PIApplicationGetApp() { return cur_piapp; }
39
[126]40
[132]41// Classe de container special pour top-container de Application X
[126]42
[132]43class PITopContAppX : public PIContainer {
44public :
[4077]45 PITopContAppX(PIContainer *par, char *nom, PIWdg* topw,
[132]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);
[457]51
52PIWdg* mTopWdg;
[132]53};
54
[1074]55
[2]56/* --Methode-- */
[4077]57PITopContAppX::PITopContAppX(PIContainer *par, char *nom, PIWdg* topw, int sx, int sy, int px, int py)
[365]58 : PIContainer(par, nom, (sx>10)?sx:10, (sy>10)?sy:10, px, py)
[132]59{
[457]60 mTopWdg = topw;
[365]61 SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_fixed);
[132]62}
63
64/* --Methode-- */
65PITopContAppX::~PITopContAppX()
66{
67}
68
69/* --Methode-- */
70void PITopContAppX::SetSize(int sx, int sy)
71{
[365]72if ((sx <10) || (sy < 10) ) return;
[1074]73
74int px = XPos();
75int py = YPos();
[1133]76// Probleme sur Sun - Reza 10/99 , REGLE 08/2000
77
[1074]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);
[132]84}
85
[365]86
[132]87/* --Methode-- */
88void PITopContAppX::SetPos(int px, int py)
89{
90}
91
[1263]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
[132]111/* --Methode-- */
[2]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;
[365]121
122
[2]123topwdg = new PIWdgX(narg, arg);
124
[365]125int msx,msy;
[1592]126PrefCompSize(msx, msy);
[365]127msy+=5;
128topwdg->SetSize(sx, sy+msy);
[3216]129//DBG printf("PIApplicationX-DBG:: Size=%d %d \n", topwdg->XSize(), topwdg->YSize());
[365]130
[2]131intcont = new PIContainerX((PIMsgHandler *)this, topwdg, "MBCont",
[365]132 sx, sy+msy, 0, 0);
[60]133// Pb avec les Popup MenuX et certains Window Manager , voir pimenux.cc
134SetTopWdgForMenuX(intcont->XtWdg());
135
[2]136menubar = new PIMenubar(this, "DefMenubar");
[23]137Menubar()->SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_free);
[2]138sxt = ( sx > Menubar()->XSize() ) ? sx : Menubar()->XSize();
[365]139syt = ( sy > 10 ) ? sy : 10;
140// syt += Menubar()->YSize();
141// syt += msy;
142// topwdg->SetSize(sxt, syt);
143// MBCont()->SetSize(sxt, syt);
[132]144if (sx < sxt) sx = sxt;
145if (sy < 10) sy = 10;
[4077]146topcont = new PITopContAppX(MBCont(), "TopLevelCont", topwdg,
147 sx, sy, 0, msy);
[163]148MBCont()->Show();
[3216]149//DBG printf("PIApplicationX-DBG2:: MBContSize=%d %d \n", MBCont()->XSize(), MBCont()->YSize());
[2]150
[1074]151
[365]152topcont->Show();
[18]153
[365]154
[18]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
[365]164topwdg->Manage();
[1263]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
[111]194cur_piapp = this;
[18]195mState = -1;
196SetReady();
[2]197}
198
199/* --Methode-- */
200PIApplicationX::~PIApplicationX()
201{
202#ifdef DEBUG_APPLX
203puts("PIApplicationX::~PIApplicationX()_info : App delete");
204#endif
[18]205Display *mdsp;
206mdsp = XtDisplay (topwdg->XtWdg());
[52]207topwdg->UnManage();
[6]208delete menubar;
209if (topcont != MBCont()) delete topcont;
210delete intcont;
[2]211delete topwdg;
[18]212XtCloseDisplay(mdsp);
[111]213cur_piapp = NULL;
[18]214return;
[2]215}
216
217/* --Methode-- */
218void PIApplicationX::Run()
219{
220XEvent evt;
221#ifdef DEBUG_APPLX
222puts("PIApplicationX::Run()_info : App Run ");
223#endif
224
225
[114]226int szx, szy, szf;
227XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
[90]228
[110]229// Pour appeler FinishCreate() des objets dans la fenetre principale
[365]230if (mStop) { // C'est la premiere fois
[1074]231 topcont->SetSize(topcont->XSize(), topcont->YSize());
232 // topwdg->SetSize(MBCont()->XSize(), MBCont()->YSize());
[365]233 MBCont()->FinishCreate();
234 }
[141]235else mStop = true; // On rerentre apres un stop
[2]236while (mStop)
237 {
[90]238 XtAppNextEvent(*appctx, &evt);
[2]239 XtDispatchEvent(&evt);
240 }
241return;
242}
[18]243
244
245/* --Methode-- */
246void PIApplicationX::SetReady()
247{
[138]248Display * mdsp = XtDisplay (topwdg->XtWdg());
[18]249if (mState != kReadyState)
250 {
251 mState = kReadyState;
[106]252 Menubar()->SetSensitive();
[18]253 XDefineCursor(mdsp, XtWindow(topwdg->XtWdg()), a_curs[0]);
254 }
[138]255XFlush(mdsp);
[18]256}
257
258/* --Methode-- */
259void PIApplicationX::SetBusy()
260{
[138]261Display * mdsp = XtDisplay (topwdg->XtWdg());
[18]262if (mState != kBusyState)
263 {
264 mState = kBusyState;
[106]265 Menubar()->SetSensitive();
[18]266// if ( XtIsRealized(topwdg->XtWdg()) )
267 XDefineCursor(mdsp, XtWindow(topwdg->XtWdg()), a_curs[2]);
268 }
[138]269XFlush(mdsp);
[18]270}
271
272/* --Methode-- */
273void PIApplicationX::SetBlocked()
274{
[138]275Display * mdsp = XtDisplay (topwdg->XtWdg());
[18]276if (mState != kBlockedState)
277 {
278 mState = kBlockedState;
[106]279 Menubar()->SetUnSensitive();
[18]280 XDefineCursor(mdsp, XtWindow(topwdg->XtWdg()), a_curs[1]);
281 }
[138]282XFlush(mdsp);
283return;
[18]284}
[75]285
286
287/* --Methode-- */
[1592]288void PIApplicationX::PrefCompSize(int& szx, int& szy)
[75]289{
[114]290int szf;
291PIXtAppCtx(szx, szy, szf);
[90]292return;
[75]293}
294
[92]295/* --Methode-- */
[1592]296void PIApplicationX::ScreenSize(int& szx, int& szy)
[92]297{
298Display * dsp = PIXDisplay();
299szx = DisplayWidth(dsp, DefaultScreen(dsp));
300szy = DisplayHeight(dsp, DefaultScreen(dsp));
301}
[75]302
[1592]303/* --Methode-- */
304void PIApplicationX::ScreenSizeMM(int& szx, int& szy)
305{
306Display * dsp = PIXDisplay();
307szx = DisplayWidthMM(dsp, DefaultScreen(dsp));
308szy = DisplayHeightMM(dsp, DefaultScreen(dsp));
309}
[92]310
[1592]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}
[92]320
[1592]321
322
323
324
[78]325/* Call-Back - Fonction privee de ce fichier */
[81]326static void redirectstream_callback(XtPointer, int *, XtInputId*);
[78]327
[81]328static PIConsole* consstream[2] = {NULL, NULL};
329static unsigned char streamva[2] = { PIVA_Def, PIVA_Ital};
330static int streamno[2] = {0,1};
[135]331static XtInputId inputid[2];
332static int origfiledes[2]={-1, -1}; // descripteurs de fichiers de depart
[3369]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
[78]337
[3369]338//DBG static FILE * dbgfip = NULL;
339
340// call-back pour gestion de redirection stdout/stderr avec pipe
[81]341static void redirectstream_callback(XtPointer cld, int * fd, XtInputId* /*iid*/)
[78]342{
[2607]343char buff[512];
[3369]344int nr, tnr;
[81]345
346int idx = *((int*)cld);
347if (idx != 1) idx = 0;
[135]348if (!consstream[idx]) return;
[3369]349tnr = 0;
350while ( (nr=read(*fd, buff, 511)) > 0 ) {
[81]351 buff[nr] = '\0'; consstream[idx]->AddStr(buff, streamva[idx], false);
[3369]352 tnr += nr;
[78]353 }
[3369]354if (tnr > 0) consstream[idx]->Refresh();
[78]355}
356
[3369]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
[78]378/* --Methode-- */
[81]379void PIApplicationX::RedirectOutStream(PIConsole* cons, unsigned char va)
[78]380{
[3369]381if ( origfiledes[0]<0 ) origfiledes[0] = fcntl(1, F_DUPFD, 0);
382if ( cons == consstream[0]) {
383 streamva[0] = va;
384 return;
385}
[135]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 }
[78]393
[81]394consstream[0] = cons; streamva[0] = va;
395
[78]396int p[2];
397pipe(p);
[90]398// Redirection de stdout (fid=1) :
[78]399close(1);
400dup(p[1]);
401close(p[1]);
402fcntl(p[0], F_SETFL, O_NONBLOCK);
[135]403
[365]404#if (!defined(__GNUG__) && !defined(HPUX))
[85]405setlinebuf(stdout);
[163]406#endif
[135]407ios::sync_with_stdio();
[78]408
[114]409int szx, szy, szf;
410XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
[135]411inputid[0] = XtAppAddInput(*appctx, p[0], (XtPointer) XtInputReadMask,
412 redirectstream_callback, (XtPointer) streamno);
[3369]413//DBG if (dbgfip == NULL) dbgfip = fopen("debug.log","w");
[78]414}
[81]415
416/* --Methode-- */
417void PIApplicationX::RedirectErrStream(PIConsole* cons, unsigned char va)
418{
[3369]419if ( origfiledes[1]<0 ) origfiledes[1] = fcntl(2, F_DUPFD, 0);
420if ( cons == consstream[1]) {
421 streamva[1] = va;
422 return;
423}
[135]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 }
[81]431
432consstream[1] = cons; streamva[1] = va;
433
434int p[2];
435pipe(p);
[135]436// Redirection de stderr (fid=2) :
[81]437close(2);
438dup(p[1]);
439close(p[1]);
440fcntl(p[0], F_SETFL, O_NONBLOCK);
[135]441
[365]442#if (!defined(__GNUG__) && !defined(HPUX))
[85]443setlinebuf(stderr);
[163]444#endif
[135]445ios::sync_with_stdio();
[81]446
[114]447int szx, szy, szf;
448XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
[135]449inputid[1] = XtAppAddInput(*appctx, p[0], (XtPointer) XtInputReadMask,
450 redirectstream_callback, (XtPointer) (streamno+1));
[81]451}
452
[3369]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
[3372]505 if (origfiledes[1] > -1) dup2(origfiledes[1], 2);
[3369]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
[4077]537#endif
538#endif
539
Note: See TracBrowser for help on using the repository browser.