1 /* pro_digipad.c: digipad digitizing tablet emulator
2
3 Copyright (c) 1997-2003, Tarik Isani (xhomer@isani.org)
4
5 This file is part of Xhomer.
6
7 Xhomer is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2
9 as published by the Free Software Foundation.
10
11 Xhomer is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Xhomer; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21
22 /* TBD:
23 -suppressed mode crashes P/OS
24 -only emulates remote and suppressed modes
25 -slow down remote mode responses?
26 */
27
28 #ifdef PRO
29 #include "pdp11_defs.h"
30
31 #define PRO_DIGIPAD_FIFO_DEPTH 1024
32
33 #define PRO_DIGIPAD_FAR 0x04 /* pen not near tablet */
34 #define PRO_DIGIPAD_G 0x08 /* green button */
35 #define PRO_DIGIPAD_B 0x10 /* blue button */
36 #define PRO_DIGIPAD_R 0x20 /* red button */
37 #define PRO_DIGIPAD_BUTTON 0x40 /* valid button */
38
39
40 /* Keyboard code entry points */
41
42 struct sercall pro_digipad = {&pro_digipad_get, &pro_digipad_put,
43 &pro_digipad_ctrl_get, &pro_digipad_ctrl_put,
44 &pro_digipad_reset, &pro_digipad_exit};
45
46
47 LOCAL int pro_digipad_s0 = -1; /* previous commmand character */
48 LOCAL int pro_digipad_s1 = -1;
49 LOCAL int pro_digipad_remote = 0; /* remote mode */
50 LOCAL int pro_digipad_suppressed = 0; /* suppressed mode */
51 LOCAL int pro_digipad_enable = 0; /* enable flow */
52 LOCAL int pro_digipad_last_x = -1; /* previous x */
53 LOCAL int pro_digipad_last_y = -1; /* previous y */
54 LOCAL int pro_digipad_last_l = -1;
55 LOCAL int pro_digipad_last_m = -1;
56 LOCAL int pro_digipad_last_r = -1;
57 LOCAL int pro_digipad_last_in = -1;
58
59 LOCAL int pro_digipad_fifo_h = 0;
60 LOCAL int pro_digipad_fifo_t = 0;
61 LOCAL int pro_digipad_fifo[PRO_DIGIPAD_FIFO_DEPTH];
62
63
64 /* Put character in digipad FIFO */
65
pro_digipad_fifo_put(int schar)66 LOCAL void pro_digipad_fifo_put (int schar)
67 {
68 int fullness;
69
70 /* First check if FIFO is full */
71
72 fullness = pro_digipad_fifo_h - pro_digipad_fifo_t;
73
74 if (fullness < 0)
75 fullness += PRO_DIGIPAD_FIFO_DEPTH;
76
77 if (fullness < PRO_DIGIPAD_FIFO_DEPTH)
78 {
79 pro_digipad_fifo[pro_digipad_fifo_h] = schar;
80 pro_digipad_fifo_h++;
81 if (pro_digipad_fifo_h == PRO_DIGIPAD_FIFO_DEPTH)
82 pro_digipad_fifo_h = 0;
83 }
84 }
85
86
87 /* Calculate button and coordinate codes and load into FIFO */
88
pro_digipad_coord()89 void pro_digipad_coord ()
90 {
91 int mb, tx, ty;
92
93
94 /* Calculate translated X,Y coordinates */
95
96 if (pro_digipad_remote)
97 {
98 tx = 2*(pro_mouse_x-32);
99 ty = 2100 - 2*(600*pro_mouse_y/240);
100 }
101 else
102 {
103 tx = (2200*(pro_mouse_x-32))/960;
104 ty = 2200 - (600*2200*pro_mouse_y/960)/240;
105 }
106
107 if (tx < 0)
108 tx = 0;
109
110 /* Calculate button code */
111
112 mb = PRO_DIGIPAD_BUTTON;
113
114 if (pro_mouse_l)
115 mb |= PRO_DIGIPAD_R;
116
117 if (pro_mouse_m)
118 mb |= PRO_DIGIPAD_B;
119
120 if (pro_mouse_r)
121 mb |= PRO_DIGIPAD_G;
122
123 if (!pro_mouse_in)
124 {
125 mb |= PRO_DIGIPAD_FAR;
126
127 /* Digipad returns (0,0) coordinates when pen not near */
128
129 tx = 0;
130 ty = 0;
131 }
132
133 pro_digipad_fifo_put(mb|0x80);
134 pro_digipad_fifo_put((tx&0x3f)|0x80);
135 pro_digipad_fifo_put(((tx>>6)&0x3f)|0x80);
136 pro_digipad_fifo_put((ty&0x3f)|0x80);
137 pro_digipad_fifo_put(((ty>>6)&0x3f)|0x80);
138 }
139
140
141 /* Get character from digipad */
142
pro_digipad_get(int dev)143 int pro_digipad_get (int dev)
144 {
145 int schar;
146
147 /* Check if in suppressed mode and (coordinate or button) has changed */
148
149 if ((pro_digipad_suppressed)
150 && (pro_digipad_enable)
151 && ((pro_mouse_x != pro_digipad_last_x)
152 || (pro_mouse_y != pro_digipad_last_y)
153 || (pro_mouse_l != pro_digipad_last_l)
154 || (pro_mouse_m != pro_digipad_last_m)
155 || (pro_mouse_r != pro_digipad_last_r)
156 || (pro_mouse_in != pro_digipad_last_in)))
157 {
158 pro_digipad_coord();
159
160 pro_digipad_last_x = pro_mouse_x;
161 pro_digipad_last_y = pro_mouse_y;
162 pro_digipad_last_l = pro_mouse_l;
163 pro_digipad_last_m = pro_mouse_m;
164 pro_digipad_last_r = pro_mouse_r;
165 pro_digipad_last_in = pro_mouse_in;
166 }
167
168 /* Check if FIFO is empty and Digipad is enabled */
169
170 if ((pro_digipad_fifo_h == pro_digipad_fifo_t)
171 || (!pro_digipad_enable))
172 schar = PRO_NOCHAR;
173 else
174 {
175 schar = pro_digipad_fifo[pro_digipad_fifo_t];
176 pro_digipad_fifo_t++;
177 if (pro_digipad_fifo_t == PRO_DIGIPAD_FIFO_DEPTH)
178 pro_digipad_fifo_t = 0;
179 }
180
181 return schar;
182 }
183
184
185 /* Send character to digipad */
186
pro_digipad_put(int dev,int schar)187 int pro_digipad_put (int dev, int schar)
188 {
189 /* XXX
190 printf("CHAR %d!!!\r\n",schar);
191 */
192
193 /* Decode Digipad commands */
194
195 /* XOFF */
196
197 if (schar == 19)
198 pro_digipad_enable = 0;
199
200 /* XON */
201
202 else if (schar == 17)
203 pro_digipad_enable = 1;
204 else
205 {
206 /* Echo command character */
207
208 /* XXX should msb be set?
209 */
210 pro_digipad_fifo_put(schar|0x80);
211
212 /* STX - request for coordinate in remote mode */
213
214 if ((schar == 2) && pro_digipad_remote)
215 pro_digipad_coord();
216
217 else if (pro_digipad_s1 == 1)
218 {
219 /* Reset Digipad */
220
221 if ((pro_digipad_s0 == 82) && (schar == 83))
222 {
223 pro_digipad_remote = 0;
224 pro_digipad_suppressed = 0;
225 pro_digipad_last_x = -1;
226 pro_digipad_last_y = -1;
227 pro_digipad_enable = 1;
228 /* XXX
229 */
230 pro_digipad_fifo_put(0xff);
231 pro_digipad_fifo_put(0xff);
232 pro_digipad_fifo_put(0xff);
233 pro_digipad_fifo_put(0xff);
234 pro_digipad_fifo_put(0xff);
235 }
236
237 /* Remote mode */
238
239 else if ((pro_digipad_s0 == 82) && (schar == 77))
240 {
241 pro_digipad_remote = 1;
242 pro_digipad_suppressed = 0;
243 }
244
245 /* Suppressed mode */
246
247 else if (pro_digipad_s0 == 83)
248 {
249 pro_digipad_remote = 0;
250 pro_digipad_suppressed = 1;
251 }
252
253 /* Continuous/Diagnostic/Line mode unsupported */
254
255 else if ((pro_digipad_s0 == 67) || (pro_digipad_s0 == 68)
256 || (pro_digipad_s0 == 76))
257 {
258 pro_digipad_remote = 0;
259 pro_digipad_suppressed = 0;
260 }
261 }
262 }
263
264 pro_digipad_s1 = pro_digipad_s0;
265 pro_digipad_s0 = schar;
266
267 return PRO_SUCCESS;
268 }
269
270
271 /* Return serial line parameters */
272
pro_digipad_ctrl_get(int dev,struct serctrl * sctrl)273 void pro_digipad_ctrl_get (int dev, struct serctrl *sctrl)
274 {
275 /* These are hardwired */
276
277 sctrl->dsr = 1;
278 sctrl->cts = 1;
279 sctrl->ri = 0;
280 sctrl->cd = 0;
281 }
282
283
284 /* Set serial line parameters */
285
pro_digipad_ctrl_put(int dev,struct serctrl * sctrl)286 void pro_digipad_ctrl_put (int dev, struct serctrl *sctrl)
287 {
288 }
289
290
291 /* Reset digipad */
292
pro_digipad_reset(int dev,int portnum)293 void pro_digipad_reset (int dev, int portnum)
294 {
295 }
296
297
298 /* Exit routine */
299
pro_digipad_exit(int dev)300 void pro_digipad_exit (int dev)
301 {
302 }
303 #endif
304