1 /* This file is part of the Project Athena Zephyr Notification System.
2 * It is one of the source files comprising zwgc, the Zephyr WindowGram
5 * Created by: Marc Horowitz <marc@athena.mit.edu>
7 * $Id: xmark.c,v 1.9 1999/01/22 23:20:44 ghudson Exp $
9 * Copyright (c) 1989 by the Massachusetts Institute of Technology.
10 * For copying and distribution information, see the file
14 #if (!defined(lint) && !defined(SABER))
15 static char rcsid_xmark_c[] = "$Id: xmark.c,v 1.9 1999/01/22 23:20:44 ghudson Exp $";
18 #include <zephyr/mit-copyright.h>
22 #ifndef X_DISPLAY_MISSING
29 #include "new_string.h"
31 int markblock[3] = { -1 , -1 , -1 };
32 int markchar[3] = { -1 , -1 , -1 };
33 int markpixel[3] = { -1 , -1 , -1 };
34 x_gram *markgram = NULL;
36 int oldblock[2] = { -1 , -1 };
37 int oldpixel[2] = { -1 , -1 };
38 x_gram *oldgram = NULL;
40 #define xmarkValid() \
42 (STARTBLOCK != -1) && (ENDBLOCK != -1) && \
43 (STARTCHAR != -1) && (ENDCHAR != -1) && \
44 (STARTPIXEL != -1) && (ENDPIXEL != -1))
46 void xmarkSetBound(gram,x,y,which)
58 if ((oldblock[which] != markblock[which]) || \
59 (oldpixel[which] != markpixel[which])) { \
60 printf("----- SetBound:\noldblock[%d]=%d, oldpixel[%d]=%d\nmarkblock[%d]=%d, markpixel[%d]=%d\n-----", \
61 which,oldblock[which],which,oldpixel[which], \
62 which,markblock[which],which,markpixel[which]); \
69 if (markgram != gram) {
72 } else if (which < XMARK_TEMP_BOUND) {
73 oldblock[which]=markblock[which];
74 oldpixel[which]=markpixel[which];
77 /* Start at the top, fastforward to first span not too high. */
78 for (i=0,xb=gram->blocks ;
79 (i<gram->numblocks) && (xb->y2 < y) ;
82 /* the point is after the end */
83 if (i==gram->numblocks) {
90 /* is the point before the beginning of the line? */
98 /* is the point in the nether space between this line and the last? */
106 for (yofs=xb->y1;(i<gram->numblocks) && (xb->y1 == yofs);i++,xb++) {
112 if ((x < xofs) || (y < xb->y1)) {
118 if (xb->strlen == -1) {
124 font=get_fontst_from_fid(xb->fid);
125 for (j=0,s=(unsigned char *)((gram->text)+(xb->strindex));
126 xofs<x && j<xb->strlen;
128 /* if font->per_char is NULL, then we should use min_bounds */
129 short usewidth = font->per_char ? font->per_char[*s - font->min_char_or_byte2].width : font->min_bounds.width;
130 if (x <= (xofs+=usewidth)) {
132 markpixel[which]=xofs - xb->x1 - usewidth;
139 /* The endpoint is after the end of the block if the loop ends */
146 /* needs both bounds to be valid (!= -1) */
147 static int xmarkNearest(x,y)
152 xmarkSetBound(markgram,x,y,XMARK_TEMP_BOUND);
153 middle=(ENDBLOCK+STARTBLOCK)/2;
155 if (markblock[XMARK_TEMP_BOUND] < middle)
156 return(XMARK_START_BOUND);
157 else if (markblock[XMARK_TEMP_BOUND] > middle)
158 return(XMARK_END_BOUND);
160 middle=(ENDCHAR+STARTCHAR)/2;
161 if (markchar[XMARK_TEMP_BOUND] < middle)
162 return(XMARK_START_BOUND);
164 return(XMARK_END_BOUND);
168 void xmarkExpose(dpy,w,gram,b1,p1,b2,p2)
172 unsigned int b1,p1,b2,p2;
174 #define swap(x,y) temp=(x); (x)=(y); (y)=temp
177 #define expose (event.xexpose)
179 if ((b1==-1) || (p1==-1) || (b2==-1) || (p2==-1)) return;
181 if ((b1 > b2) || ((b1 == b2) && (p1 > p2))) {
186 #if defined(_IBMR2) && !defined(__GNUC__) && defined(RS6000_OPT_BUG)
187 /* A version of the AIX 3.1 RS/6000 C compiler needs this to prevent
188 a core dump in the loop below. */
196 for (i=b1;i<=b2;i++) {
198 expose.x=gram->blocks[i].x1+p1;
199 expose.y=gram->blocks[i].y1;
201 expose.height=gram->blocks[i].y2-gram->blocks[i].y1;
204 expose.x=gram->blocks[i].x1+p1;
205 expose.y=gram->blocks[i].y1;
206 expose.width=gram->blocks[i].x2-p1;
207 expose.height=gram->blocks[i].y2-gram->blocks[i].y1;
210 expose.x=gram->blocks[i].x1;
211 expose.y=gram->blocks[i].y1;
213 expose.height=gram->blocks[i].y2-gram->blocks[i].y1;
216 expose.x=gram->blocks[i].x1;
217 expose.y=gram->blocks[i].y1;
218 expose.width=gram->blocks[i].x2-gram->blocks[i].x1;
219 expose.height=gram->blocks[i].y2-gram->blocks[i].y1;
224 if (expose.width && expose.height) {
225 printf("---- markExpose:\nb1=%d p1=%d b2=%d p2=%d\n",b1,p1,b2,p2);
226 printf("x=%d y=%d w=%d h=%d\n-----",
227 expose.x,expose.y,expose.width,expose.height);
230 if ((expose.width && expose.height) || (expose.count == 0))
231 XSendEvent(dpy,w,True,ExposureMask,&event);
235 /* Public functions: */
237 void xmarkRedraw(dpy,w,gram,range)
243 #define ob1 ((unsigned int) oldblock[XMARK_START_BOUND])
244 #define ob2 ((unsigned int) oldblock[XMARK_END_BOUND])
245 #define nb1 ((unsigned int) markblock[XMARK_START_BOUND])
246 #define nb2 ((unsigned int) markblock[XMARK_END_BOUND])
247 #define op1 ((unsigned int) oldpixel[XMARK_START_BOUND])
248 #define op2 ((unsigned int) oldpixel[XMARK_END_BOUND])
249 #define np1 ((unsigned int) markpixel[XMARK_START_BOUND])
250 #define np2 ((unsigned int) markpixel[XMARK_END_BOUND])
252 if (range==XMARK_REDRAW_CURRENT) {
253 if (!markgram) return;
254 xmarkExpose(dpy,w,gram,nb1,np1,nb2,np2);
255 } else if (range==XMARK_REDRAW_OLD) {
256 if (!oldgram) return;
257 xmarkExpose(dpy,w,gram,ob1,op1,ob2,op2);
258 } else if (range==XMARK_REDRAW_START) {
259 if (!markgram) return;
260 xmarkExpose(dpy,w,gram,ob1,op1,nb1,np1);
261 } else if (range==XMARK_REDRAW_END) {
262 if (!markgram) return;
263 xmarkExpose(dpy,w,gram,ob2,op2,nb2,np2);
267 printf("xmarkRedraw: This shouldn't happen!\n");
272 /* needs both bounds to be valid (!= -1) */
275 if (STARTBLOCK > ENDBLOCK)
276 return(XMARK_START_BOUND);
277 else if (STARTBLOCK < ENDBLOCK)
278 return(XMARK_END_BOUND);
280 if (STARTCHAR > ENDCHAR)
281 return(XMARK_START_BOUND);
282 else if (STARTCHAR < ENDCHAR)
283 return(XMARK_END_BOUND);
285 return(XMARK_END_BOUND);
291 oldblock[0]=markblock[0];
292 oldblock[1]=markblock[1];
293 oldpixel[0]=markpixel[0];
294 oldpixel[1]=markpixel[1];
306 int xmarkExtendFromFirst(gram,x,y)
310 if (markgram != gram) {
315 if (STARTBLOCK == -1) {
316 xmarkStart(gram,x,y);
318 return(XMARK_REDRAW_CURRENT);
319 } else if (ENDBLOCK == -1) {
321 return(XMARK_REDRAW_CURRENT);
323 xmarkSetBound(gram,x,y,XMARK_END_BOUND);
324 return(XMARK_REDRAW_END);
328 int xmarkExtendFromNearest(gram,x,y)
334 if (markgram != gram) {
339 if (STARTBLOCK == -1) {
340 xmarkStart(gram,x,y);
342 return(XMARK_REDRAW_CURRENT);
343 } else if (ENDBLOCK == -1) {
345 return(XMARK_REDRAW_CURRENT);
347 xmarkSetBound(gram,x,y,bound=xmarkNearest(x,y));
348 return(bound==XMARK_START_BOUND?XMARK_REDRAW_START:XMARK_REDRAW_END);
357 string text_so_far = string_Copy("");
358 char *text = markgram->text;
359 int startblock,endblock,startchar,endchar;
362 if (xmarkSecond() == XMARK_END_BOUND) {
363 startblock=STARTBLOCK;
374 for (i=startblock; i<=endblock; i++) {
375 index = markgram->blocks[i].strindex;
376 len = markgram->blocks[i].strlen;
377 if ((len == -1) && (i != endblock)) {
378 text_so_far = string_Concat2(text_so_far, "\n");
380 if (startblock == endblock)
381 temp = string_CreateFromData(text+index+startchar,
383 else if (i==startblock)
384 temp = string_CreateFromData(text+index+startchar,
386 else if (i==endblock)
387 temp = string_CreateFromData(text+index, endchar);
389 temp = string_CreateFromData(text+index, len);
390 text_so_far = string_Concat2(text_so_far, temp);
393 last_y = markgram->blocks[i].y;
400 #endif /* X_DISPLAY_MISSING */