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