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