1 /* $Header: /home/yav/catty/fkiss/RCS/comment.c,v 1.3 2000/08/24 02:10:48 yav Exp $
2  * fkiss cel comment display
3  * written by yav <yav@bigfoot.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 
20 char id_comment[] = "$Id: comment.c,v 1.3 2000/08/24 02:10:48 yav Exp $";
21 
22 #include <X11/Xlib.h>
23 #include <stdio.h>
24 
25 #include "config.h"
26 
27 #include "headers.h"
28 #include "fkiss.h"
29 #include "work.h"
30 
31 #define PUBLIC_COMMENT_C
32 #include "extern.h"
33 
34 #define COMWIN_BORDER
35 #define COMWIN_XOFS 8
36 #define COMWIN_YOFS (-8)
37 #define COMWIN_LINE_SPACE 16
38 #define COMWIN_UPPER_MARGIN 4
39 #define COMWIN_LOWER_MARGIN 6	/* within font descent */
40 #define COMWIN_LEFT_MARGIN 4
41 #define COMWIN_RIGHT_MARGIN 4
42 #define COMWIN_NUMBER_WIDTH 40
43 
44 static Bool comwin_created = False;
45 static int comment_cel = -1;
46 
expose_comment_line(d,n,x,y,mark,rw,rh)47 int expose_comment_line(d, n, x, y, mark, rw, rh)
48      Drawable d;		/* Drawable */
49      int n;			/* cel number */
50      int x, y;			/* base point position (pixel) */
51      int mark;			/* mark character */
52      int *rw;			/* width return pointer */
53      int *rh;			/* height return pointer */
54 {
55   int i, r, w, h;
56   char *p;
57   char buf[256];		/* cnf line must be shorter than 256 bytes */
58 
59   if (comment_linenum) {
60     /* with line number */
61     sprintf(buf, "%4d%c", (cell + n)->line, mark);
62     draw_string(d, x, y, buf);
63     x += COMWIN_NUMBER_WIDTH;
64   }
65   r = w = h = 0;
66   p = (cell + n)->comment;
67   if (p != NULL) {
68     while (*p) {
69       for (i = 0; i < sizeof(buf)-1; i++) {
70 	if (*p == '\0')
71 	  break;
72 	if (*p == '\n') {
73 	  p++;
74 	  break;
75 	}
76 	buf[i] = *p++;
77       }
78       buf[i] = '\0';
79       i = draw_string(d, x, y, buf);
80       if (i > w)
81 	w = i;
82       y += COMWIN_LINE_SPACE;
83       h += COMWIN_LINE_SPACE;
84       r++;
85     }
86   }
87   if (comment_linenum) {
88     w += COMWIN_NUMBER_WIDTH;
89     if (!r) {
90       r++;
91       h += COMWIN_LINE_SPACE;
92     }
93   }
94   if (rw != NULL)
95     *rw = w;
96   if (rh != NULL)
97     *rh = h;
98   return r;			/* line count */
99 }
100 
101 /* draw comment to comment window
102  * and return drawn area geometry
103  */
expose_comment_sub(d,celn,x,y,rw,rh)104 int expose_comment_sub(d, celn, x, y, rw, rh)
105      Drawable d;		/* drawing window or pixmap or None */
106      int celn;			/* cel number */
107      int x, y;			/* base point */
108      int *rw;			/* drawing area width return */
109      int *rh;			/* drawing area height return */
110 {
111   int i, n, r, w, h;
112 
113   if (celn < 0)
114     return 0;			/* illegal cel number, No line printed */
115   r = 0;
116   switch (comment_mode) {
117   case 1:
118     r = expose_comment_line(d, celn, x, y, 0, rw, rh);
119     break;
120   case 2:
121     if (rw != NULL)
122       *rw = 0;
123     if (rh != NULL)
124       *rh = 0;
125     for (i = 0; i < celcnt; i++) {
126       if ((cell + i)->width &&
127 	  ((cell + i)->obj == (cell + celn)->obj) &&
128 	  ((cell + i)->comment != NULL)) {
129 	n = expose_comment_line(d, i, x, y, (i == celn ? '*' : ' '), &w, &h);
130 	y += n * COMWIN_LINE_SPACE;
131 	r += n;
132 	if (rw != NULL && w > *rw)
133 	  *rw = w;
134 	if (rh != NULL)
135 	  *rh += h;
136       }
137     }
138     break;
139   }
140   return r;			/* line count */
141 }
142 
expose_comment(ev)143 void expose_comment(ev)
144      XExposeEvent *ev;
145 {
146   if (!ev->count) {
147     /* redraw at last event only */
148     expose_comment_sub(comwin, comment_cel,
149 		       COMWIN_LEFT_MARGIN,
150 		       COMWIN_UPPER_MARGIN + COMWIN_LINE_SPACE,
151 		       NULL, NULL);
152   }
153 }
154 
unmap_comment()155 void unmap_comment()
156 {
157   if (comwin_created)
158     XUnmapWindow(dsp, comwin);
159 }
160 
map_comment(ev)161 void map_comment(ev)
162      XButtonEvent *ev;
163 {
164   int i, x, y, w, h;
165   XSetWindowAttributes atr;
166   Window child;
167 
168   if (!comment_mode)
169     return;
170   x = ev->x;
171   y = ev->y;
172   comment_cel = search_cell(x, y);
173   if (expose_comment_sub(None, comment_cel, 0, 0, &w, &h) <= 0) {
174     unmap_comment();
175     return;
176   }
177   XTranslateCoordinates(dsp, ev->window, rootwin, x, y, &x, &y, &child);
178   w += COMWIN_LEFT_MARGIN + COMWIN_RIGHT_MARGIN;
179   h += COMWIN_UPPER_MARGIN + COMWIN_LOWER_MARGIN;
180   x += COMWIN_XOFS;
181   y += COMWIN_YOFS - h;
182   if (x + w > DisplayWidth(dsp, scr))
183     x = DisplayWidth(dsp, scr) - w;
184   if (y + h > DisplayHeight(dsp, scr))
185     y = DisplayHeight(dsp, scr) - h;
186   if (x < 0)
187     x = 0;
188   if (y < 0)
189     y = 0;
190   if (comwin_created) {
191     unmap_comment();		/* to send expose event */
192     XMoveResizeWindow(dsp, comwin, x, y, w, h);
193   } else {
194     comwin = XCreateSimpleWindow(dsp, rootwin,
195 				 x, y, w, h, combw,
196 				 spx[SPX_FG], spx[SPX_BG]);
197     XSelectInput(dsp, comwin, ExposureMask|ButtonPressMask
198 		 |EnterWindowMask|KeyPressMask);
199     XSetTransientForHint(dsp, comwin, topwin);
200     atr.override_redirect = True;
201     atr.save_under = True;
202     i = CWOverrideRedirect|CWSaveUnder;
203     XChangeWindowAttributes(dsp, comwin, i, &atr);
204     comwin_created = True;
205   }
206   XMapRaised(dsp, comwin);
207 }
208 
209 /* End of file */
210