1 #include <stdio.h>
2 #include <string.h>
3 #include <ctype.h>
4 #include <X11/Xlib.h>
5 #include <X11/Xutil.h>
6 #include "handwave.h"
7 #include "spelllist.h"
8 #include "xspell.h"
9 
10 #define TALK_X (348)
11 #define TALK_Y (576)
12 #define TALK_W (448)
13 #define TALK_LEADING (8)
14 
15 static char bigbuf[2048], bigbuf2[2048];
16 
init_talk(py)17 void init_talk(py)
18 struct player *py;
19 {
20     py->talk_size = 128;
21     py->talk_buf = (char *)malloc(sizeof(char) * py->talk_size);
22     strcpy(py->talk_buf, "");
23     py->talk_pt = 0;
24     py->talk_xlast = (-1);
25     py->talk_x = 0;
26     py->talk_toobig = 0;
27 }
28 
redraw_talk_only(py,recomp)29 void redraw_talk_only(py, recomp)
30 struct player *py;
31 int recomp;
32 {
33     static XCharStruct overall;
34     int direction, ascent, descent;
35     int width;
36 
37     static XPoint caret[3] = {
38 	{0, 0}, {2, -3}, {2, 3}
39     };
40 
41     if (recomp) {
42 	XTextExtents(py->font, py->talk_buf, py->talk_pt, &direction, &ascent,
43 			&descent, &overall);
44 	py->talk_x = overall.width;
45     }
46 
47     if (py->talk_x != py->talk_xlast) {
48 	caret[0].x = TALK_X+py->talk_xlast - 2;
49 	caret[0].y = TALK_Y+py->lineheight + 4;
50 	XDrawLines(py->dpy, py->win, py->whitegc, caret, 3, CoordModePrevious);
51 	py->talk_xlast = py->talk_x;
52     }
53 
54     width = DrawStringField(py, py->talk_buf, TALK_X, TALK_Y+py->lineheight, TALK_W);
55 
56     caret[0].x = TALK_X+py->talk_x - 2;
57     caret[0].y = TALK_Y+py->lineheight + 4;
58     XDrawLines(py->dpy, py->win, py->blackgc, caret, 3, CoordModePrevious);
59 
60     py->talk_toobig = (width >= (TALK_W-py->lineheight));
61 }
62 
redraw_talk(py)63 void redraw_talk(py)
64 struct player *py;
65 {
66     XDrawRectangle(py->dpy, py->win, py->blackgc, TALK_X-3, TALK_Y-2, TALK_W+6,
67 		py->lineheight+TALK_LEADING+4);
68 
69     redraw_talk_only(py, 0);
70 }
71 
ensure_talk_size(py,size)72 static void ensure_talk_size(py, size)
73 struct player *py;
74 int size;
75 {
76     if (size < py->talk_size)
77 	return;
78 
79     while (size < py->talk_size)
80 	py->talk_size *= 2;
81 
82     py->talk_buf = (char *)realloc(py->talk_buf, sizeof(char) * py->talk_size);
83 }
84 
talk_handle_char(py,ch)85 void talk_handle_char(py, ch)
86 struct player *py;
87 char ch;
88 {
89     char *cp;
90     int ix;
91     int pnum;
92 
93     if (isprint(ch)) {
94 	if (!py->talk_toobig) {
95 	    ensure_talk_size(py, strlen(py->talk_buf)+1);
96 	    for (cp = &(py->talk_buf[py->talk_pt]); *cp; cp++);
97 	    for (; cp >= &(py->talk_buf[py->talk_pt]); cp--)
98 		*(cp+1) = *cp;
99 	    py->talk_buf[py->talk_pt] = ch;
100 	    py->talk_pt++;
101 	    redraw_talk_only(py, 1);
102 	}
103     }
104     else
105 	switch (ch) {
106 	    case '\n':
107 	    case '\r':
108 	    case '\023':
109 		if (py->talk_pt) {
110 		    pnum = py-players;
111 		    sprintf(bigbuf, "You say \"%s\"\n", py->talk_buf);
112 		    sprintf(bigbuf2, "%s says \"%s\"\n", NameOfBeing(gameval,
113 				QuVal_Target_Wizard, pnum), py->talk_buf);
114 		    for (ix=0; ix<numplayers; ix++)
115 			if (ix==pnum)
116 			    dump_text(ix, bigbuf);
117 			else
118 			    dump_text(ix, bigbuf2);
119 		    LogInTranscript(gameval, bigbuf2);
120 		}
121 		py->talk_pt = 0;
122 		py->talk_buf[0] = '\0';
123 		redraw_talk_only(py, 1);
124 		break;
125 	    case '\177':
126 	    case '\010':
127 		if (py->talk_pt) {
128 		    py->talk_pt--;
129 		    for (cp = &(py->talk_buf[py->talk_pt]); *cp; cp++)
130 			*cp = *(cp+1);
131 		    redraw_talk_only(py, 1);
132 		}
133 		break;
134 	    case '\013':
135 		py->talk_buf[py->talk_pt] = '\0';
136 		redraw_talk_only(py, 1);
137 		break;
138 	    case '\002':
139 		if (py->talk_pt) {
140 		    py->talk_pt--;
141 		    redraw_talk_only(py, 1);
142 		}
143 		break;
144 	    case '\006':
145 		if (py->talk_buf[py->talk_pt]) {
146 		    py->talk_pt++;
147 		    redraw_talk_only(py, 1);
148 		}
149 		break;
150 	    case '\001':
151 		py->talk_pt = 0;
152 		redraw_talk_only(py, 1);
153 		break;
154 	    case '\005':
155 		while (py->talk_buf[py->talk_pt])
156 		    py->talk_pt++;
157 		redraw_talk_only(py, 1);
158 		break;
159 	}
160 }
161