#include #include #include #include #include #include #include #include #include // A cause des container XmForm #include // Idem #include "piwdgx.h" #include "picontainerx.h" // #define DEBUG_PIWdgX // Quelques variables statiques globales, Connection Display, Top Widget Xt, AppContext Xt ... // et leurs fonctions d'acces static SysDWdg top = NULL; static Display * dpy = NULL; // static char appname[64]; static char appclass[64]; static XtAppContext appctx; static int appSzX = 10; static int appSzY = 10; static XFontStruct * stdfnt = NULL; /* Nouvelle-Fonction */ XtAppContext* PIXtAppCtx(int& szx, int& szy) { szx = appSzX; szy = appSzY; return(&appctx); } /* Nouvelle-Fonction */ SysDWdg PIXtTopWdg() { return (top); } /* Nouvelle-Fonction */ Display * PIXDisplay() { return(dpy); } /* Nouvelle-Fonction */ void PIBeep() { XBell(dpy, 0); return; } /* Nouvelle-Fonction */ int CStrFrXmStr(XmString xms, char* buff, int nmx) /* Pour recuperer le contenu d'un string Motif */ { int n,l,m; XmStringContext cntx; char *txs; XmStringDirection dir; XmStringCharSet cset; Boolean sep; if (nmx < 2) return(0); n = 0; m = nmx-1; buff[0] = buff[m] = '\0'; XmStringInitContext (&cntx, xms); while (m > 0) { if (XmStringGetNextSegment( cntx, &txs, &cset, &dir, &sep) ) { l = strlen(txs); if (m < l) txs[m] = '\0'; strcpy(buff+n, txs); n += l; m -= l; if (sep) m = -2; XtFree(txs); } else m = -1; } return(n); } /* --Methode-- */ PIWdgX::PIWdgX(int narg, char *arg[]) :PIWdgGen(NULL, "PITopLevel") { if (top == NULL) InitXt(narg, arg); sdw = top; wmis = k_wmi_appshell; stmng = false; #ifdef DEBUG_PIWdgX printf("Debug_PIWdgX::PIWdgX(int , char * []) this=%lx top=%lx \n", (long)this, (long)sdw); #endif } /* --Methode-- */ PIWdgX::PIWdgX(PIContainerGen *par, char *nom, int sx, int sy, int px, int py) :PIWdgGen(par, nom, sx, sy, px, py) { sdw = NULL; wmis = k_wmi_unknown; } /* --Methode-- */ int PIWdgX::CreateXtWdg(char *nom, SysDWdgClass wdgcl, SysDWdg pwdg, int sx, int sy, int px, int py) { Arg wargs[5]; int n=0; if (pwdg == NULL) { if (parent == NULL) { if (top == NULL) InitXt(); pwdg = top; } // else pwdg = ((PIContainerX *)parent)->sdw; else pwdg = ((PIWdgX *)parent)->sdw; } n=0; if ((sx >= 0) && (sy >= 0)) { XtSetArg(wargs[n],XtNwidth,sx); n++; XtSetArg(wargs[n],XtNheight,sy); n++; } XtSetArg(wargs[n],XtNx,px); n++; XtSetArg(wargs[n],XtNy,py); n++; if (wdgcl == NULL) wdgcl = coreWidgetClass; if ( (wdgcl == topLevelShellWidgetClass) || (wdgcl == transientShellWidgetClass) || (wdgcl == overrideShellWidgetClass) ) { sdw = XtCreatePopupShell(nom, wdgcl, pwdg, wargs, n); } else { sdw = XtCreateWidget(nom, wdgcl, pwdg, wargs, n); } if (wdgcl == topLevelShellWidgetClass) wmis = k_wmi_toplevel; else if (wdgcl == transientShellWidgetClass) wmis = k_wmi_transient; else if (wdgcl == overrideShellWidgetClass) wmis = k_wmi_override; else wmis = k_wmi_normal ; stmng = false; #ifdef DEBUG_PIWdgX printf("Debug_PIWdgX::CreateXtWdg(%s) this=%lx sdw=%lx pere=%lx wmis=%d\n", nom, (long)this, (long)sdw, (long)pwdg, wmis); #endif SetBinding(PIBK_free, PIBK_free, PIBK_free, PIBK_free); return(0); } /* --Methode-- */ PIWdgX::~PIWdgX() { #ifdef DEBUG_PIWdgX printf("Debug_PIWdgX::~PIWdgX() %lx %lx \n", (long)this, (long)sdw); #endif if (!sdw) XtDestroyWidget(sdw); } /* --Methode-- */ void PIWdgX::FinishCreate() { #ifdef DEBUG_PIWdgX printf("Debug_PIWdgX::FinishCreate() ne fait rien ! \n"); #endif return; } /* --Methode-- */ void PIWdgX::Manage() { #ifdef DEBUG_PIWdgX printf("Debug_PIWdgX::Manage this=%lx sdw=%lx \n", (long)this, (long)sdw); #endif if (!sdw) return; if (wmis != k_wmi_appshell) XtManageChild(sdw); else if (!XtIsRealized(sdw)) XtRealizeWidget(sdw); stmng = true; return; } /* --Methode-- */ void PIWdgX::UnManage() { #ifdef DEBUG_PIWdgX printf("Debug_PIWdgX::UnManage this=%lx sdw=%lx \n", (long)this, (long)sdw); #endif if (!sdw) return; if (wmis != k_wmi_appshell) XtUnmanageChild(sdw); stmng = false; return; } /* --Methode-- */ bool PIWdgX::IfManaged() { return(stmng); } /* --Methode-- */ bool PIWdgX::IsVisible() { if ( (XtIsRealized(XtWdg())) && ( (this->XtWdg())->core.visible) ) return(true); else return(false); } /* --Methode-- */ void PIWdgX::SetSensitive() { XtSetSensitive(XtWdg(), TRUE); } /* --Methode-- */ void PIWdgX::SetUnSensitive() { XtSetSensitive(XtWdg(), FALSE); } /* --Methode-- */ bool PIWdgX::IfSensitive() { if (XtIsSensitive(XtWdg()) == TRUE) return(true); else return(false); } /* --Methode-- */ void PIWdgX::SetSize(int sx, int sy) { #ifdef DEBUG_PIWdgX printf("Debug_PIWdgX::SetSize this=%lx sdw=%lx \n", (long)this, (long)sdw); #endif if (!sdw) return; /* Arg wargs[2]; XtSetArg(wargs[0],XtNwidth,sx); XtSetArg(wargs[1],XtNheight,sy); XtSetValues(this->sdw, wargs, 2); */ XtResizeWidget(sdw, sx, sy, BorderWidth()); return; } /* --Methode-- */ void PIWdgX::SetPos(int px, int py) { if (!sdw) return; /* Arg wargs[2]; XtSetArg(wargs[0],XtNx,px); XtSetArg(wargs[1],XtNy,py); XtSetValues(this->sdw, wargs, 2); */ XtMoveWidget(sdw, px, py); return; } /* --Methode-- */ void PIWdgX::SetBinding(PIBindingKind left, PIBindingKind top, PIBindingKind right, PIBindingKind bottom) { Arg wargs[9]; int n=0; if (!sdw) return; if (!parent) return; int fbase = 1000 ; // Valeur de XmNfractionBase des XmForm ds PIContainerX int frpos = 0; float frac; n = 0; XtSetArg(wargs[n],XmNfractionBase, fbase); n++; XtSetValues(parent->XtWdg(), wargs, n); // printf(" DEBUG_SetBinding: C-Sz= %d %d - Sz=%d %d , Pos= %d %d \n", parent->XSize(), // parent->YSize(), XSize(), YSize(), XPos(), YPos()); switch (left) { case PIBK_free : XtSetArg(wargs[n],XmNleftAttachment, XmATTACH_NONE); n++; break; case PIBK_fixed : XtSetArg(wargs[n],XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(wargs[n],XmNleftOffset, XPos() ); n++; break; case PIBK_elastic : XtSetArg(wargs[n],XmNleftAttachment, XmATTACH_POSITION); n++; frac = (float)(XPos())/(float)parent->XSize() ; frpos = frac*fbase; XtSetArg(wargs[n],XmNleftPosition, frpos ); n++; break; } switch (top) { case PIBK_free : XtSetArg(wargs[n],XmNtopAttachment, XmATTACH_NONE); n++; break; case PIBK_fixed : XtSetArg(wargs[n],XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(wargs[n],XmNtopOffset, YPos() ); n++; break; case PIBK_elastic : XtSetArg(wargs[n],XmNtopAttachment, XmATTACH_POSITION); n++; frac = (float)(YPos())/(float)parent->YSize() ; frpos = frac*fbase; XtSetArg(wargs[n],XmNtopPosition, frpos ); n++; break; } switch (right) { case PIBK_free : XtSetArg(wargs[n],XmNrightAttachment, XmATTACH_NONE); n++; break; case PIBK_fixed : XtSetArg(wargs[n],XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(wargs[n],XmNrightOffset, parent->XSize()-(XSize()+XPos()) ); n++; break; case PIBK_elastic : XtSetArg(wargs[n],XmNrightAttachment, XmATTACH_POSITION); n++; frac = (float)(XPos()+XSize())/(float)parent->XSize() ; frpos = frac*fbase; XtSetArg(wargs[n],XmNrightPosition, frpos ); n++; break; } switch (bottom) { case PIBK_free : XtSetArg(wargs[n],XmNbottomAttachment, XmATTACH_NONE); n++; break; case PIBK_fixed : XtSetArg(wargs[n],XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(wargs[n],XmNbottomOffset, parent->YSize()-(YSize()+YPos()) ); n++; break; case PIBK_elastic : XtSetArg(wargs[n],XmNbottomAttachment, XmATTACH_POSITION); n++; frac = (float)(YPos()+YSize())/(float)parent->YSize() ; frpos = frac*fbase; XtSetArg(wargs[n],XmNbottomPosition, frpos ); n++; break; } XtSetValues(this->sdw, wargs, n); // printf(" Out_SetBinding: C-Sz= %d %d - Sz=%d %d , Pos= %d %d \n", parent->XSize(), // parent->YSize(), XSize(), YSize(), XPos(), YPos()); return; } /* --Methode-- */ void PIWdgX::SetBorderWidth(int bw) { if (!sdw) return; Arg wargs[2]; int n=0; XtSetArg(wargs[n],XtNborderWidth,bw); n++; XtSetValues(this->sdw, wargs, n); return; } /* --Methode-- */ void PIWdgX::SetLabel(string const& lab) { XmString xmstr; xmstr = XmStringLtoRCreate((char *)lab.c_str(), XmSTRING_DEFAULT_CHARSET); int n=0; Arg warg[2]; XtSetArg(warg[n], XmNlabelString, xmstr); n++; XtSetValues(XtWdg(), warg, n); XmStringFree(xmstr); return; } /* --Methode-- */ int PIWdgX::XSize() { if (!sdw) return(-1); else return((int)this->sdw->core.width); } /* --Methode-- */ int PIWdgX::YSize() { if (!sdw) return(-1); else return((int)this->sdw->core.height); } /* --Methode-- */ int PIWdgX::XPos() { if (!sdw) return(-1); else return((int)this->sdw->core.x); } /* --Methode-- */ int PIWdgX::YPos() { if (!sdw) return(-1); else return((int)this->sdw->core.y); } /* --Methode-- */ int PIWdgX::BorderWidth() { if (!sdw) return(-1); Arg wargs[2]; int bw; XtSetArg(wargs[0],XtNborderWidth, &bw); XtGetValues(this->sdw, wargs, 1); return(bw); } /* --Methode-- */ string PIWdgX::Nom() { return(XtName(this->sdw)); } /* --Methode-- */ void PIWdgX::GetScreenPos(int & spx, int & spy) { PIWdgX * wc; Display *mdsp; Window w, rw, pw, *cw; unsigned int ncw; Status st; int x,y; unsigned int bw, l, h, d; spx = 0; spy = 0; wc = this; while (wc) { spx += wc->XPos(); spy += wc->YPos(); wc = (PIWdgX *)wc->Parent(); } mdsp = XtDisplay(XtWdg()); w = XtWindow(XtWdg()); ncw = 0; st = XQueryTree(mdsp, w, &rw, &pw, &cw, &ncw); if (st) { XFree(cw); if (pw == rw) return; } while (st && (pw != rw)) { w = pw; st = XQueryTree(mdsp, w, &rw, &pw, &cw, &ncw); if (st) XFree(cw); XGetGeometry(mdsp, w, &rw, &x, &y, &l, &h, &bw, &d); spy += y; spx += x; } return; } // Ressources X si non definis static String fallback_res[22] = { "PeidaInt*default*background: LightGrey" , "PeidaInt*background: LightGrey" , "PeidaInt*bottomShadowColor: Black" , "PeidaInt*default*bottomShadowColor: Black" , "PeidaInt*Foreground: Black", "PeidaInt*default*Foreground: Black", "PeidaInt*topShadowColor: White", "PeidaInt*default*topShadowColor: White", "PeidaInt*borderColor: Black", "PeidaInt*XmLabel.borderWidth: 0", "PeidaInt*XmScrollBar*background: LightGrey", "PeidaInt*XmDrawingArea*background: Black", "PeidaInt*XmPushButton*borderWidth: 0", "PeidaInt*XmText*shadowThickness: 2", "PeidaInt*XmText*highlightThickness: 0", "PeidaInt*XmText*marginHeigt: 0", "PeidaInt*XmText*marginWidth: 3", // "PeidaInt*DefMenubar*XtNwidth: 250", // "PeidaInt*DefMenubar*XtNheight: 30", "PeidaInt*fontList: -*-courier-bold-r-normal-*-12-*-*-*-*-*-ISO8859-1", "PeidaInt*default*fontList: -*-courier-bold-r-normal-*-12-*-*-*-*-*-ISO8859-1" "PeidaInt*fontFamilyName: *-courier", // Pas de blanc apres le nom de font "PeidaInt*XmToggleButton*selectColor: Red", "" }; /* --Methode-- */ int PIWdgX::InitXt(int narg, char *arg[]) { if (top != NULL) return(0); // Initialisation ... int n; char *pc = "PIWdgX"; char **ppc; if (narg > 0) { n = narg, ppc = arg; } else { ppc = &pc; n = 1; } // strncpy(appname, ppc[0], 63); appname[63] = '\0'; strncpy(appclass,"PeidaInt",63); appclass[63] = '\0'; // top = XtAppInitialize(&appctx, appclass, NULL, 0, &n, ppc); top = XtVaAppInitialize(&appctx, appclass, NULL, 0, &n, ppc, fallback_res, NULL); dpy = XtDisplay(top); // On va recuperer la fonte par defaut des composantes Motif XtResource res[] = { { "fontList", "FontList", XtRString, sizeof(String), 0, XtRString, "-*-courier-bold-*-*-*-*-*-*-*-*-*-*-*" } }; String fntname; XtGetApplicationResources(top, &fntname, res, XtNumber(res), NULL, 0); // scr = XDefaultScreen(dpy); int count; char **list; char buff[256]; strcpy(buff, fntname); list = XListFonts(dpy, buff, 15, &count); XFreeFontNames(list); if (count < 1) strcpy(buff,"-*-*-*-*-*-*-*-*-*-*-*-*-*-*" ); stdfnt = XLoadQueryFont(dpy, buff); // On calcule la taille de la chaine CANCEL (6 caracteres) char a[2]; XCharStruct ovr; int hd, fa, fd, len; // direction, font-ascent, font-descent len("CANCEL") XTextExtents(stdfnt, a, 0, &hd, &fa, &fd, &ovr); len = XTextWidth(stdfnt, "CANCEL", 6); appSzY = (float)(fa+fd)*1.4+10; // pour les shadow appSzX = (float)len*1.5; // Taille multiple de 5 pixels if ( (appSzX % 5) != 0 ) appSzX = 5*(appSzX/5 + 1); if ( (appSzY % 5) != 0 ) appSzY = 5*(appSzY/5 + 1); if(appSzY < 10) appSzY = 10; if(appSzX < 30) appSzX = 30; // printf("PIWdgX::InitXt(Font=%s- %d %d , %d ) SzX,Y= %d %d \n", buff, fa,fd,len,appSzX, appSzY); return(0); } /* .................................................................*/ /* ................... Gestion de Copier/Coller ....................*/ /* .................................................................*/ // Les Call-Backs Xt static Boolean forXt_ConvertSelection(Widget w, Atom* sel, Atom *targ, Atom* typ, XtPointer* value, unsigned long* len, int* format); static void forXt_LoseSelection(Widget w, Atom* sel); static void forXt_DoneSelection(Widget w, Atom* sel, Atom *targ); static void forXt_SelectionValue(Widget w, XtPointer usd, Atom* sel, Atom* typ, XtPointer value, unsigned long* len, int* format ); static PIWdgX* curselwdg = NULL; // Le PIWdg qui possede la selection static unsigned int curseltype = PICP_string; // Type de selcetion qu'il peut fournir static unsigned int reqseltype = PICP_string; // Type de selection demande static unsigned int provseltype = PICP_string; // Type de selection fourni /* Nouvelle-Fonction */ Boolean forXt_ConvertSelection(Widget w, Atom* sel, Atom *targ, Atom* typ, XtPointer* value, unsigned long* len, int* format) { if (*targ != XA_STRING) return(FALSE); if (!curselwdg) return(FALSE); unsigned int ll = 0; unsigned int styp = reqseltype; *value = curselwdg->ProvideSelection(styp, ll); *len=ll; *typ = XA_STRING; *format = 8; provseltype = (styp != 0) ? styp : PICP_string; return(TRUE); } /* Nouvelle-Fonction */ void forXt_LoseSelection(Widget w, Atom* sel) { if (curselwdg) curselwdg->SelectionLost(); curselwdg = NULL; curseltype = PICP_string; } /* Nouvelle-Fonction */ void forXt_DoneSelection(Widget w, Atom* sel, Atom *targ) { if (curselwdg) curselwdg->SelectionTransferEnd(); } /* Nouvelle-Fonction */ void forXt_SelectionValue(Widget w, XtPointer usd, Atom* sel, Atom* typ, XtPointer value, unsigned long* len, int* format ) { if ( (value != NULL) && (*len > 0) ) ((PIWdgX*)usd)->PasteSelection(provseltype, (void*)value, (*len)) ; } // Gestion de Copier/Coller /* --Methode-- */ bool PIWdgX::ClaimSelection(unsigned int typ) // Pour prendre possession du buffer copier/coller { if (XtOwnSelection(XtWdg(), XA_PRIMARY, PIXGetLastEventTime(), forXt_ConvertSelection, forXt_LoseSelection, forXt_DoneSelection) ) { #ifdef DEBUG_PIWdgX printf("PIWdgX::ClaimSelection(%d) - OK (Wdg= %lx)\n", typ, (unsigned long)this); #endif curselwdg = this; curseltype = (typ != 0) ? typ : PICP_string; return (true); } else { #ifdef DEBUG_PIWdgX printf("PIWdgX::ClaimSelection() - Probleme (Wdg= %lx)\n", (unsigned long)this); #endif curselwdg = NULL; curseltype = PICP_string; return (false); } } /* --Methode-- */ void PIWdgX::SelectionLost() // Appele quand le PIWdg perd la possession du buffer copier/coller { return; } /* --Methode-- */ unsigned int PIWdgX::RequestSelection(unsigned int typ) { // Pour demander le contenu du buffer de copier/coller #ifdef DEBUG_PIWdgX printf("PIWdgX::RequestSelection(%d) (Wdg= %lx - %lx) \n", typ, (unsigned long)this, (unsigned long)curselwdg); #endif reqseltype = (typ != 0) ? typ : PICP_string; XtGetSelectionValue(XtWdg(), XA_PRIMARY, XA_STRING, forXt_SelectionValue, (XtPointer)this, PIXGetLastEventTime()); return(reqseltype); } static char* rs = NULL; /* --Methode-- */ void* PIWdgX::ProvideSelection(unsigned int& typ, unsigned int& len) // Le widget doit fournier une l zone memoire contenant la selection // en un type donne // Renvoie le pointeur de cette zone, sa taille et son typ { rs = new char[128]; sprintf(rs, "Test-of-PIWdgX::ProvideSelection(%d)- %lx", typ,(long)rs); len = strlen(rs); return(rs); } /* --Methode-- */ void PIWdgX::SelectionTransferEnd() { delete[] rs; } /* --Methode-- */ void PIWdgX::PasteSelection(unsigned int typ, void *buff, unsigned int l) { // Methode appele apres que le widget ait fait RequestSelection // Le typ de donnees fourni ainsi que les donnees et leur taille // sont en argument #ifdef DEBUG_PIWdgX char* mbuff = new char[l+1]; strncpy(mbuff, (char *)buff, l); mbuff[l] = '\0'; printf("PIWdgX::PasteSelection(%d, %lx, %d) [%s] \n", typ, (long)buff, l, mbuff); delete[] mbuff; #endif return; }