Jabber WindowGram Client (JWGC)

Introduction Screenshots Installation Downloads
Documentation Browse Source Resources Project Site

Stable Version
-none-

Latest Version
beta5



Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

xmark.c

Go to the documentation of this file.
00001 /*
00002  *      Copyright (c) 1989 by the Massachusetts Institute of Technology.
00003  *      For copying and distribution information, see the file
00004  *      "mit-copyright.h".
00005  *
00006  *      Modified for jwgc by Daniel Henninger.
00007  */
00008 
00009 #include "mit-copyright.h"
00010 
00011 #ifndef X_DISPLAY_MISSING
00012 
00013 #include <X11/X.h>
00014 #include <X11/Xlib.h>
00015 #include "X_gram.h"
00016 #include "X_fonts.h"
00017 #include "xmark.h"
00018 #include "new_string.h"
00019 
00020 int markblock[3] = {-1, -1, -1};
00021 int markchar[3] = {-1, -1, -1};
00022 int markpixel[3] = {-1, -1, -1};
00023 x_gram *markgram = NULL;
00024 
00025 int oldblock[2] = {-1, -1};
00026 int oldpixel[2] = {-1, -1};
00027 x_gram *oldgram = NULL;
00028 
00029 #define xmarkValid() \
00030    ((markgram) && \
00031    (STARTBLOCK != -1) && (ENDBLOCK != -1) && \
00032    (STARTCHAR != -1) && (ENDCHAR != -1) && \
00033    (STARTPIXEL != -1) && (ENDPIXEL != -1))
00034 
00035 void 
00036 xmarkSetBound(gram, x, y, which)
00037         x_gram *gram;
00038         int x, y;
00039         int which;
00040 {
00041         int i, xofs, yofs;
00042         XFontStruct *font;
00043         xblock *xb;
00044         unsigned char *s;
00045 
00046         if (markgram != gram) {
00047                 xmarkClear();
00048                 markgram = gram;
00049         }
00050         else if (which < XMARK_TEMP_BOUND) {
00051                 oldblock[which] = markblock[which];
00052                 oldpixel[which] = markpixel[which];
00053         }
00054 
00055         /* Start at the top, fastforward to first span not too high. */
00056         for (i = 0, xb = gram->blocks;
00057              (i < gram->numblocks) && (xb->y2 < y);
00058              i++, xb++);
00059 
00060         /* the point is after the end */
00061         if (i == gram->numblocks) {
00062                 markblock[which] = i;
00063                 markchar[which] = 0;
00064                 markpixel[which] = 0;
00065                 return;
00066         }
00067 
00068         /* is the point before the beginning of the line? */
00069         if (x <= xb->x1) {
00070                 markblock[which] = i;
00071                 markchar[which] = 0;
00072                 markpixel[which] = 0;
00073                 return;
00074         }
00075 
00076         /* is the point in the nether space between this line and the last? */
00077         if (y < xb->y1) {
00078                 markblock[which] = i;
00079                 markchar[which] = 0;
00080                 markpixel[which] = 0;
00081                 return;
00082         }
00083 
00084         for (yofs = xb->y1; (i < gram->numblocks) && (xb->y1 == yofs); i++, xb++) {
00085 
00086                 if (x <= xb->x2) {
00087                         markblock[which] = i;
00088 
00089                         xofs = xb->x1;
00090                         if ((x < xofs) || (y < xb->y1)) {
00091                                 markchar[which] = 0;
00092                                 return;
00093                         }
00094                         font = get_fontst_from_fid(xb->fid);
00095                         for (i = 0, s = (unsigned char *) ((gram->text) + (xb->strindex));
00096                              xofs < x && i < xb->strlen;
00097                              i++, s++) {
00098                                 /*
00099                                  * if font->per_char is NULL, then we should
00100                                  * use min_bounds
00101                                  */
00102                                 short usewidth = font->per_char ? font->per_char[*s - font->min_char_or_byte2].width : font->min_bounds.width;
00103                                 if (x <= (xofs += usewidth)) {
00104                                         markchar[which] = i;
00105                                         markpixel[which] = xofs - xb->x1 - usewidth;
00106                                         return;
00107                                 }
00108                         }
00109                 }
00110         }
00111 
00112         /* The endpoint is after the end of the block if the loop ends */
00113         markblock[which] = i;
00114         markchar[which] = 0;
00115         markpixel[which] = 0;
00116         return;
00117 }
00118 
00119 /* needs both bounds to be valid (!= -1) */
00120 static int 
00121 xmarkNearest(x, y)
00122         int x, y;
00123 {
00124         int middle;
00125 
00126         xmarkSetBound(markgram, x, y, XMARK_TEMP_BOUND);
00127         middle = (ENDBLOCK + STARTBLOCK) / 2;
00128 
00129         if (markblock[XMARK_TEMP_BOUND] < middle)
00130                 return (XMARK_START_BOUND);
00131         else if (markblock[XMARK_TEMP_BOUND] > middle)
00132                 return (XMARK_END_BOUND);
00133         else {
00134                 middle = (ENDCHAR + STARTCHAR) / 2;
00135                 if (markchar[XMARK_TEMP_BOUND] < middle)
00136                         return (XMARK_START_BOUND);
00137                 else
00138                         return (XMARK_END_BOUND);
00139         }
00140 }
00141 
00142 void 
00143 xmarkExpose(dpy, w, gram, b1, p1, b2, p2)
00144         Display *dpy;
00145         Window w;
00146         x_gram *gram;
00147         unsigned int b1, p1, b2, p2;
00148 {
00149 #define swap(x,y) temp=(x); (x)=(y); (y)=temp
00150         int i, temp;
00151         XEvent event;
00152 #define expose (event.xexpose)
00153 
00154         if ((b1 == -1) || (p1 == -1) || (b2 == -1) || (p2 == -1))
00155                 return;
00156 
00157         if ((b1 > b2) || ((b1 == b2) && (p1 > p2))) {
00158                 swap(b1, b2);
00159                 swap(p1, p2);
00160         }
00161 
00162 #if defined(_IBMR2) && !defined(__GNUC__) && defined(RS6000_OPT_BUG)
00163         /*
00164          * A version of the AIX 3.1 RS/6000 C compiler needs this to prevent
00165          * a core dump in the loop below.
00166          */
00167         &b1;
00168 #endif
00169 
00170         expose.type = Expose;
00171         expose.display = dpy;
00172         expose.window = w;
00173 
00174         for (i = b1; i <= b2; i++) {
00175                 if (b1 == b2) {
00176                         expose.x = gram->blocks[i].x1 + p1;
00177                         expose.y = gram->blocks[i].y1;
00178                         expose.width = p2 - p1;
00179                         expose.height = gram->blocks[i].y2 - gram->blocks[i].y1;
00180                         expose.count = 0;
00181                 }
00182                 else if (i == b1) {
00183                         expose.x = gram->blocks[i].x1 + p1;
00184                         expose.y = gram->blocks[i].y1;
00185                         expose.width = gram->blocks[i].x2 - p1;
00186                         expose.height = gram->blocks[i].y2 - gram->blocks[i].y1;
00187                         expose.count = b2 - i;
00188                 }
00189                 else if (i == b2) {
00190                         expose.x = gram->blocks[i].x1;
00191                         expose.y = gram->blocks[i].y1;
00192                         expose.width = p2;
00193                         expose.height = gram->blocks[i].y2 - gram->blocks[i].y1;
00194                         expose.count = b2 - i;
00195                 }
00196                 else {
00197                         expose.x = gram->blocks[i].x1;
00198                         expose.y = gram->blocks[i].y1;
00199                         expose.width = gram->blocks[i].x2 - gram->blocks[i].x1;
00200                         expose.height = gram->blocks[i].y2 - gram->blocks[i].y1;
00201                         expose.count = b2 - i;
00202                 }
00203 
00204                 if ((expose.width && expose.height) || (expose.count == 0))
00205                         XSendEvent(dpy, w, True, ExposureMask, &event);
00206         }
00207 }
00208 
00209 /* Public functions: */
00210 
00211 void 
00212 xmarkRedraw(dpy, w, gram, range)
00213         Display *dpy;
00214         Window w;
00215         x_gram *gram;
00216         int range;
00217 {
00218 #define ob1 ((unsigned int) oldblock[XMARK_START_BOUND])
00219 #define ob2 ((unsigned int) oldblock[XMARK_END_BOUND])
00220 #define nb1 ((unsigned int) markblock[XMARK_START_BOUND])
00221 #define nb2 ((unsigned int) markblock[XMARK_END_BOUND])
00222 #define op1 ((unsigned int) oldpixel[XMARK_START_BOUND])
00223 #define op2 ((unsigned int) oldpixel[XMARK_END_BOUND])
00224 #define np1 ((unsigned int) markpixel[XMARK_START_BOUND])
00225 #define np2 ((unsigned int) markpixel[XMARK_END_BOUND])
00226 
00227         if (range == XMARK_REDRAW_CURRENT) {
00228                 if (!markgram)
00229                         return;
00230                 xmarkExpose(dpy, w, gram, nb1, np1, nb2, np2);
00231         }
00232         else if (range == XMARK_REDRAW_OLD) {
00233                 if (!oldgram)
00234                         return;
00235                 xmarkExpose(dpy, w, gram, ob1, op1, ob2, op2);
00236         }
00237         else if (range == XMARK_REDRAW_START) {
00238                 if (!markgram)
00239                         return;
00240                 xmarkExpose(dpy, w, gram, ob1, op1, nb1, np1);
00241         }
00242         else if (range == XMARK_REDRAW_END) {
00243                 if (!markgram)
00244                         return;
00245                 xmarkExpose(dpy, w, gram, ob2, op2, nb2, np2);
00246         }
00247 }
00248 
00249 /* needs both bounds to be valid (!= -1) */
00250 int 
00251 xmarkSecond()
00252 {
00253         if (STARTBLOCK > ENDBLOCK)
00254                 return (XMARK_START_BOUND);
00255         else if (STARTBLOCK < ENDBLOCK)
00256                 return (XMARK_END_BOUND);
00257         else {
00258                 if (STARTCHAR > ENDCHAR)
00259                         return (XMARK_START_BOUND);
00260                 else if (STARTCHAR < ENDCHAR)
00261                         return (XMARK_END_BOUND);
00262                 else
00263                         return (XMARK_END_BOUND);
00264         }
00265 }
00266 
00267 void 
00268 xmarkClear()
00269 {
00270         oldblock[0] = markblock[0];
00271         oldblock[1] = markblock[1];
00272         oldpixel[0] = markpixel[0];
00273         oldpixel[1] = markpixel[1];
00274         oldgram = markgram;
00275 
00276         markblock[0] = -1;
00277         markblock[1] = -1;
00278         markchar[0] = -1;
00279         markchar[1] = -1;
00280         markpixel[0] = -1;
00281         markpixel[1] = -1;
00282         markgram = NULL;
00283 }
00284 
00285 int 
00286 xmarkExtendFromFirst(gram, x, y)
00287         x_gram *gram;
00288         int x, y;
00289 {
00290         if (markgram != gram) {
00291                 xmarkClear();
00292                 markgram = gram;
00293         }
00294 
00295         if (STARTBLOCK == -1) {
00296                 xmarkStart(gram, x, y);
00297                 xmarkEnd(gram, x, y);
00298                 return (XMARK_REDRAW_CURRENT);
00299         }
00300         else if (ENDBLOCK == -1) {
00301                 xmarkEnd(gram, x, y);
00302                 return (XMARK_REDRAW_CURRENT);
00303         }
00304         else {
00305                 xmarkSetBound(gram, x, y, XMARK_END_BOUND);
00306                 return (XMARK_REDRAW_END);
00307         }
00308 }
00309 
00310 int 
00311 xmarkExtendFromNearest(gram, x, y)
00312         x_gram *gram;
00313         int x, y;
00314 {
00315         int bound;
00316 
00317         if (markgram != gram) {
00318                 xmarkClear();
00319                 markgram = gram;
00320         }
00321 
00322         if (STARTBLOCK == -1) {
00323                 xmarkStart(gram, x, y);
00324                 xmarkEnd(gram, x, y);
00325                 return (XMARK_REDRAW_CURRENT);
00326         }
00327         else if (ENDBLOCK == -1) {
00328                 xmarkEnd(gram, x, y);
00329                 return (XMARK_REDRAW_CURRENT);
00330         }
00331         else {
00332                 xmarkSetBound(gram, x, y, bound = xmarkNearest(x, y));
00333                 return (bound == XMARK_START_BOUND ? XMARK_REDRAW_START : XMARK_REDRAW_END);
00334         }
00335 }
00336 
00337 char *
00338 xmarkGetText()
00339 {
00340         int i, index, len;
00341         int last_y = -1;
00342         string temp;
00343         string text_so_far = string_Copy("");
00344         char *text = markgram->text;
00345         int startblock, endblock, startchar, endchar;
00346 
00347         if (xmarkValid()) {
00348                 if (xmarkSecond() == XMARK_END_BOUND) {
00349                         startblock = STARTBLOCK;
00350                         endblock = ENDBLOCK;
00351                         startchar = STARTCHAR;
00352                         endchar = ENDCHAR;
00353                 }
00354                 else {
00355                         startblock = ENDBLOCK;
00356                         endblock = STARTBLOCK;
00357                         startchar = ENDCHAR;
00358                         endchar = STARTCHAR;
00359                 }
00360 
00361                 for (i = startblock; i <= endblock; i++) {
00362                         if (last_y != -1 && last_y != markgram->blocks[i].y)
00363                                 text_so_far = string_Concat2(text_so_far, "\n");
00364                         index = markgram->blocks[i].strindex;
00365                         len = markgram->blocks[i].strlen;
00366                         if (startblock == endblock)
00367                                 temp = string_CreateFromData(text + index + startchar,
00368                                                        endchar - startchar);
00369                         else if (i == startblock)
00370                                 temp = string_CreateFromData(text + index + startchar, len - startchar);
00371                         else if (i == endblock)
00372                                 temp = string_CreateFromData(text + index, endchar);
00373                         else
00374                                 temp = string_CreateFromData(text + index, len);
00375                         text_so_far = string_Concat2(text_so_far, temp);
00376                         free(temp);
00377                         last_y = markgram->blocks[i].y;
00378                 }
00379         }
00380 
00381         return (text_so_far);
00382 }
00383 
00384 #endif                          /* X_DISPLAY_MISSING */


Last updated at Tue Dec 18 21:07:42 PST 2007. This site and project hosted by...SourceForge.net Logo
Source Perspective by Fisheye