00001
00002
00003
00004
00005
00006
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
00056 for (i = 0, xb = gram->blocks;
00057 (i < gram->numblocks) && (xb->y2 < y);
00058 i++, xb++);
00059
00060
00061 if (i == gram->numblocks) {
00062 markblock[which] = i;
00063 markchar[which] = 0;
00064 markpixel[which] = 0;
00065 return;
00066 }
00067
00068
00069 if (x <= xb->x1) {
00070 markblock[which] = i;
00071 markchar[which] = 0;
00072 markpixel[which] = 0;
00073 return;
00074 }
00075
00076
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
00100
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
00113 markblock[which] = i;
00114 markchar[which] = 0;
00115 markpixel[which] = 0;
00116 return;
00117 }
00118
00119
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
00165
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
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
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