Back to index

radiance  4R0+20100331
x11twind.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: x11twind.c,v 2.9 2003/06/30 14:59:13 schorsch Exp $";
00003 #endif
00004 /*
00005  *  x11twind.c - routines for X11 text windows.
00006  *
00007  *  Written by G. Ward
00008  *     10/30/87
00009  *
00010  *  Modified for X11 by B. V. Smith
00011  *     9/26/88
00012  */
00013 
00014 #include "copyright.h"
00015 
00016 #include  <stdio.h>
00017 #include  <stdlib.h>
00018 #include  <string.h>
00019 #include  <X11/Xlib.h>
00020 
00021 #include  "x11twind.h"
00022 
00023 #define checkcurs(t)        if ((t)->cursor) togglecurs(t)
00024 
00025 #define restorecurs         checkcurs
00026 
00027 /* width/height of a character in fontstruct f */
00028 #define       Width(f)             ((f)->max_bounds.rbearing - (f)->min_bounds.lbearing)
00029 #define       Height(f)            ((f)->ascent + (f)->descent)
00030 #define YStart(f)           ((f)->ascent)
00031 
00032 static void  togglecurs();
00033 
00034 
00035 TEXTWIND *
00036 xt_open(dpy, parent, x, y, width, height, bw, fore, back, fontname)
00037 Display  *dpy;
00038 Window  parent;
00039 int  x, y;
00040 int  width, height;
00041 int  bw;
00042 unsigned long  fore, back;
00043 char  *fontname;
00044 {
00045        register int  i;
00046        register TEXTWIND  *t;
00047 
00048        if ((t = (TEXTWIND *)malloc(sizeof(TEXTWIND))) == NULL)
00049               return(NULL);
00050 
00051        t->dpy = dpy;
00052        t->w = XCreateSimpleWindow(dpy, parent, x, y, width, height,
00053                                    bw, fore, back);
00054        if (t->w == 0)
00055               return(NULL);
00056        XMapWindow(dpy, t->w);
00057 
00058        if ((t->f = XLoadQueryFont(dpy, fontname)) == 0)
00059               return(NULL);
00060 
00061        /* if (!t->f.fixedwidth)   check for fixedwidth later 
00062               return(NULL); */
00063 
00064        t->gc = XCreateGC(dpy,t->w,0,NULL);
00065        XSetState(dpy, t->gc, fore, back, GXcopy, AllPlanes);
00066        XSetFont(dpy, t->gc, t->f->fid);
00067 
00068        t->nc = (width - LEFTMAR) / 
00069               Width(t->f);         /* number of columns */
00070        t->nr = height /
00071               Height(t->f);        /* number of rows */
00072        if (t->nc < 1 || t->nr < 1)
00073               return(NULL);
00074        if ((t->lp = (char **)calloc(t->nr, sizeof(char *))) == NULL)
00075               return(NULL);
00076        for (i = 0; i < t->nr; i++)
00077               if ((t->lp[i] = calloc(t->nc+1, 1)) == NULL)
00078                      return(NULL);
00079        t->r = t->c = 0;
00080        t->cursor = TNOCURS;
00081        return(t);
00082 
00083 }
00084 
00085 
00086 void
00087 xt_putc(c, t)                      /* output a character */
00088 int  c;
00089 register TEXTWIND  *t;
00090 {
00091        char   ch[2];
00092 
00093        checkcurs(t);
00094        switch (c) {
00095        case '\n':
00096               if (t->r >= t->nr - 1)
00097                      xt_delete(t, 0);     /* scroll up 1 line */
00098               else if (t->r < t->nr - 1)
00099                      t->r++;
00100        /* fall through */
00101        case '\r':
00102               t->c = 0;
00103               break;
00104        case '\b':
00105               while (t->c < 1 && t->r > 0)
00106                      t->c = strlen(t->lp[--t->r]);
00107               if (t->c > 0)
00108                      t->c--;
00109               break;
00110        default:
00111               if (t->c >= t->nc)
00112                      xt_putc('\n', t);
00113               ch[0] = c; ch[1] = '\0';
00114               XDrawImageString(t->dpy, t->w, t->gc, LEFTMAR+t->c*Width(t->f), 
00115                      YStart(t->f)+t->r*Height(t->f), ch, 1);
00116               t->lp[t->r][t->c++] = c;
00117               break;
00118        }
00119        restorecurs(t);
00120 }
00121 
00122 
00123 void
00124 xt_puts(s, t)                      /* output a string */
00125 register char  *s;
00126 TEXTWIND  *t;
00127 {
00128        int    oldcurs;
00129 
00130        oldcurs = xt_cursor(t, TNOCURS);   /* for efficiency */
00131        while (*s)
00132               xt_putc(*s++, t);
00133        xt_cursor(t, oldcurs);
00134 }
00135 
00136 
00137 void
00138 xt_delete(t, r)                           /* delete a line */
00139 register TEXTWIND  *t;
00140 int  r;
00141 {
00142        char  *cp;
00143        register int  i;
00144 
00145        if (r < 0 || r >= t->nr)
00146               return;
00147        checkcurs(t);
00148                                    /* move lines */
00149        XCopyArea(t->dpy, t->w, t->w, t->gc, LEFTMAR, (r+1)*Height(t->f),
00150                      t->nc*Width(t->f), (t->nr-1-r)*Height(t->f),
00151                      LEFTMAR, r*Height(t->f));
00152        cp = t->lp[r];
00153        for (i = r; i < t->nr-1; i++)
00154               t->lp[i] = t->lp[i+1];
00155        t->lp[t->nr-1] = cp;
00156                                    /* clear bottom */
00157        XClearArea(t->dpy, t->w, LEFTMAR, (t->nr-1)*Height(t->f),
00158                      t->nc*Width(t->f), Height(t->f),(Bool) 0);
00159 
00160        memset(cp, '\0', t->nc);
00161        restorecurs(t);                    /* should we reposition cursor? */
00162 }
00163 
00164 
00165 void
00166 xt_insert(t, r)                           /* insert a line */
00167 register TEXTWIND  *t;
00168 int  r;
00169 {
00170        char  *cp;
00171        register int  i;
00172 
00173        if (r < 0 || r >= t->nr)
00174               return;
00175        checkcurs(t);
00176                                    /* move lines */
00177        XCopyArea(t->dpy, t->w, t->w, t->gc, LEFTMAR, r*Height(t->f), LEFTMAR,
00178                      (r+1)*Height(t->f), t->nc*Width(t->f),
00179                      (t->nr-1-r)*Height(t->f));
00180        cp = t->lp[t->nr-1];
00181        for (i = t->nr-1; i > r; i--)
00182               t->lp[i] = t->lp[i-1];
00183        t->lp[r] = cp;
00184                                    /* clear new line */
00185        XClearArea(t->dpy, t->w, LEFTMAR, r*Height(t->f),
00186                      t->nc*Width(t->f), Height(t->f), (Bool) 0);
00187        memset(cp, '\0', t->nc);
00188        restorecurs(t);                    /* should we reposition cursor? */
00189 }
00190 
00191 
00192 void
00193 xt_redraw(t)                       /* redraw text window */
00194 register TEXTWIND  *t;
00195 {
00196        register int  i;
00197 
00198        XClearWindow(t->dpy, t->w);
00199        for (i = 0; i < t->nr; i++)
00200            if (strlen(t->lp[i]) > 0)
00201               XDrawImageString(t->dpy, t->w, t->gc, LEFTMAR, 
00202                             YStart(t->f)+i*Height(t->f),
00203                             t->lp[i], strlen(t->lp[i]));
00204        restorecurs(t);
00205 }
00206 
00207 
00208 void
00209 xt_clear(t)                        /* clear text window */
00210 register TEXTWIND  *t;
00211 {
00212        register int  i;
00213 
00214        XClearWindow(t->dpy, t->w);
00215        for (i = 0; i < t->nr; i++)
00216               memset(t->lp[i], '\0', t->nc);
00217        t->r = t->c = 0;
00218        restorecurs(t);
00219 }
00220 
00221 
00222 void
00223 xt_move(t, r, c)                   /* move to new position */
00224 register TEXTWIND  *t;
00225 int  r, c;
00226 {
00227        if (r < 0 || c < 0 || r >= t->nr || c >= t->nc)
00228               return;
00229        checkcurs(t);
00230        t->r = r;
00231        t->c = c;
00232        restorecurs(t);
00233 }
00234 
00235 
00236 int
00237 xt_cursor(t, curs)                 /* change cursor */
00238 register TEXTWIND  *t;
00239 register int  curs;
00240 {
00241        register int  oldcurs;
00242 
00243        if (curs != TNOCURS && curs != TBLKCURS)
00244               return(-1);
00245        oldcurs = t->cursor;
00246        if (curs != oldcurs)
00247               togglecurs(t);
00248        t->cursor = curs;
00249        return(oldcurs);
00250 }
00251 
00252 
00253 void
00254 xt_close(t)                        /* close text window */
00255 register TEXTWIND  *t;
00256 {
00257        register int  i;
00258 
00259        XFreeFont(t->dpy, t->f);
00260        XFreeGC(t->dpy,t->gc);
00261        XDestroyWindow(t->dpy, t->w);
00262        for (i = 0; i < t->nr; i++)
00263               free(t->lp[i]);
00264        free((void *)t->lp);
00265        free((void *)t);
00266 }
00267 
00268 
00269 static void
00270 togglecurs(t)
00271 register TEXTWIND  *t;
00272 {
00273        XSetFunction(t->dpy, t->gc, GXinvert);
00274        XSetPlaneMask(t->dpy, t->gc, 1L);
00275        XFillRectangle(t->dpy, t->w, t->gc, 
00276                      t->c*Width(t->f)+LEFTMAR, t->r*Height(t->f),
00277                      Width(t->f), Height(t->f));
00278        XSetFunction(t->dpy, t->gc, GXcopy);
00279        XSetPlaneMask(t->dpy, t->gc, ~0L);
00280 }