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