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
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 :
[4083]45 PITopContAppX(PIContainer *par, const 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-- */
[4083]57PITopContAppX::PITopContAppX(PIContainer *par, const 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);
[4086]129printf("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;
[4083]146topcont = new PITopContAppX(MBCont(), "TopLevelCont", topwdg,sx, sy, 0, msy);
[163]147MBCont()->Show();
[3216]148//DBG printf("PIApplicationX-DBG2:: MBContSize=%d %d \n", MBCont()->XSize(), MBCont()->YSize());
[2]149
[1074]150
[365]151topcont->Show();
[18]152
[365]153
[18]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
[365]163topwdg->Manage();
[1263]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
[111]193cur_piapp = this;
[18]194mState = -1;
195SetReady();
[2]196}
197
198/* --Methode-- */
199PIApplicationX::~PIApplicationX()
200{
201#ifdef DEBUG_APPLX
202puts("PIApplicationX::~PIApplicationX()_info : App delete");
203#endif
[18]204Display *mdsp;
205mdsp = XtDisplay (topwdg->XtWdg());
[52]206topwdg->UnManage();
[6]207delete menubar;
208if (topcont != MBCont()) delete topcont;
209delete intcont;
[2]210delete topwdg;
[18]211XtCloseDisplay(mdsp);
[111]212cur_piapp = NULL;
[18]213return;
[2]214}
215
216/* --Methode-- */
217void PIApplicationX::Run()
218{
219XEvent evt;
220#ifdef DEBUG_APPLX
221puts("PIApplicationX::Run()_info : App Run ");
222#endif
223
224
[114]225int szx, szy, szf;
226XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
[90]227
[110]228// Pour appeler FinishCreate() des objets dans la fenetre principale
[365]229if (mStop) { // C'est la premiere fois
[1074]230 topcont->SetSize(topcont->XSize(), topcont->YSize());
231 // topwdg->SetSize(MBCont()->XSize(), MBCont()->YSize());
[365]232 MBCont()->FinishCreate();
233 }
[141]234else mStop = true; // On rerentre apres un stop
[2]235while (mStop)
236 {
[90]237 XtAppNextEvent(*appctx, &evt);
[2]238 XtDispatchEvent(&evt);
239 }
240return;
241}
[18]242
243
244/* --Methode-- */
245void PIApplicationX::SetReady()
246{
[138]247Display * mdsp = XtDisplay (topwdg->XtWdg());
[18]248if (mState != kReadyState)
249 {
250 mState = kReadyState;
[106]251 Menubar()->SetSensitive();
[18]252 XDefineCursor(mdsp, XtWindow(topwdg->XtWdg()), a_curs[0]);
253 }
[138]254XFlush(mdsp);
[18]255}
256
257/* --Methode-- */
258void PIApplicationX::SetBusy()
259{
[138]260Display * mdsp = XtDisplay (topwdg->XtWdg());
[18]261if (mState != kBusyState)
262 {
263 mState = kBusyState;
[106]264 Menubar()->SetSensitive();
[18]265// if ( XtIsRealized(topwdg->XtWdg()) )
266 XDefineCursor(mdsp, XtWindow(topwdg->XtWdg()), a_curs[2]);
267 }
[138]268XFlush(mdsp);
[18]269}
270
271/* --Methode-- */
272void PIApplicationX::SetBlocked()
273{
[138]274Display * mdsp = XtDisplay (topwdg->XtWdg());
[18]275if (mState != kBlockedState)
276 {
277 mState = kBlockedState;
[106]278 Menubar()->SetUnSensitive();
[18]279 XDefineCursor(mdsp, XtWindow(topwdg->XtWdg()), a_curs[1]);
280 }
[138]281XFlush(mdsp);
282return;
[18]283}
[75]284
285
286/* --Methode-- */
[1592]287void PIApplicationX::PrefCompSize(int& szx, int& szy)
[75]288{
[114]289int szf;
[4083]290 printf("XtAppContext* PIXtAppCtx :szx=%d szy=%d szf=%d\n",szx,szy,szf);
[114]291PIXtAppCtx(szx, szy, szf);
[4083]292 printf("XtAppContext* PIXtAppCtx :szx=%d szy=%d szf=%d\n",szx,szy,szf);
[90]293return;
[75]294}
295
[92]296/* --Methode-- */
[1592]297void PIApplicationX::ScreenSize(int& szx, int& szy)
[92]298{
299Display * dsp = PIXDisplay();
300szx = DisplayWidth(dsp, DefaultScreen(dsp));
301szy = DisplayHeight(dsp, DefaultScreen(dsp));
302}
[75]303
[1592]304/* --Methode-- */
305void PIApplicationX::ScreenSizeMM(int& szx, int& szy)
306{
307Display * dsp = PIXDisplay();
308szx = DisplayWidthMM(dsp, DefaultScreen(dsp));
309szy = DisplayHeightMM(dsp, DefaultScreen(dsp));
310}
[92]311
[1592]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}
[92]321
[1592]322
323
324
325
[78]326/* Call-Back - Fonction privee de ce fichier */
[81]327static void redirectstream_callback(XtPointer, int *, XtInputId*);
[78]328
[81]329static PIConsole* consstream[2] = {NULL, NULL};
330static unsigned char streamva[2] = { PIVA_Def, PIVA_Ital};
331static int streamno[2] = {0,1};
[135]332static XtInputId inputid[2];
333static int origfiledes[2]={-1, -1}; // descripteurs de fichiers de depart
[3369]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
[78]338
[3369]339//DBG static FILE * dbgfip = NULL;
340
341// call-back pour gestion de redirection stdout/stderr avec pipe
[81]342static void redirectstream_callback(XtPointer cld, int * fd, XtInputId* /*iid*/)
[78]343{
[2607]344char buff[512];
[3369]345int nr, tnr;
[81]346
347int idx = *((int*)cld);
348if (idx != 1) idx = 0;
[135]349if (!consstream[idx]) return;
[3369]350tnr = 0;
351while ( (nr=read(*fd, buff, 511)) > 0 ) {
[81]352 buff[nr] = '\0'; consstream[idx]->AddStr(buff, streamva[idx], false);
[3369]353 tnr += nr;
[78]354 }
[3369]355if (tnr > 0) consstream[idx]->Refresh();
[78]356}
357
[3369]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
[78]379/* --Methode-- */
[81]380void PIApplicationX::RedirectOutStream(PIConsole* cons, unsigned char va)
[78]381{
[3369]382if ( origfiledes[0]<0 ) origfiledes[0] = fcntl(1, F_DUPFD, 0);
383if ( cons == consstream[0]) {
384 streamva[0] = va;
385 return;
386}
[135]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 }
[78]394
[81]395consstream[0] = cons; streamva[0] = va;
396
[78]397int p[2];
398pipe(p);
[90]399// Redirection de stdout (fid=1) :
[78]400close(1);
401dup(p[1]);
402close(p[1]);
403fcntl(p[0], F_SETFL, O_NONBLOCK);
[135]404
[365]405#if (!defined(__GNUG__) && !defined(HPUX))
[85]406setlinebuf(stdout);
[163]407#endif
[135]408ios::sync_with_stdio();
[78]409
[114]410int szx, szy, szf;
411XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
[135]412inputid[0] = XtAppAddInput(*appctx, p[0], (XtPointer) XtInputReadMask,
413 redirectstream_callback, (XtPointer) streamno);
[3369]414//DBG if (dbgfip == NULL) dbgfip = fopen("debug.log","w");
[78]415}
[81]416
417/* --Methode-- */
418void PIApplicationX::RedirectErrStream(PIConsole* cons, unsigned char va)
419{
[3369]420if ( origfiledes[1]<0 ) origfiledes[1] = fcntl(2, F_DUPFD, 0);
421if ( cons == consstream[1]) {
422 streamva[1] = va;
423 return;
424}
[135]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 }
[81]432
433consstream[1] = cons; streamva[1] = va;
434
435int p[2];
436pipe(p);
[135]437// Redirection de stderr (fid=2) :
[81]438close(2);
439dup(p[1]);
440close(p[1]);
441fcntl(p[0], F_SETFL, O_NONBLOCK);
[135]442
[365]443#if (!defined(__GNUG__) && !defined(HPUX))
[85]444setlinebuf(stderr);
[163]445#endif
[135]446ios::sync_with_stdio();
[81]447
[114]448int szx, szy, szf;
449XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
[135]450inputid[1] = XtAppAddInput(*appctx, p[0], (XtPointer) XtInputReadMask,
451 redirectstream_callback, (XtPointer) (streamno+1));
[81]452}
453
[3369]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
[3372]506 if (origfiledes[1] > -1) dup2(origfiledes[1], 2);
[3369]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
[4077]538#endif
539#endif
540
Note: See TracBrowser for help on using the repository browser.