1 /* The routines in this file control the cursor access (setting and getting) */
2 /* for the Figaro server version of the vista display server. */
3 
4 /* Sam Southard, Jr. */
5 /* Created: 20-Apr-1991 */
6 /* Modification History: */
7 /* 25-Apr-1991	SNS/CIT	clearcurs routine added. */
8 /* 10-May-1991	SNS/CIT	Modified to be shared between Xvideo and PGDISP */
9 /* 11-Aug-1991	SNS/CIT	xvideo hooks removed */
10 /*  5-Sep-1991	SNS/CIT	Modified to lint cleanly */
11 /*  8-Oct-1991	SNS/CIT	Globals moved to globals.h */
12 /* 17-Oct-1991	SNS/CIT	Modified to deal with 8 and 16 bit images */
13 /* 27-Nov-1991	SNS/CIT	malloc.h include deleted to make everyone happy */
14 /*  9-Jul-1992	SNS/CIT	Addkeyval and Addbuttonval modified to return 0 if a */
15 /*			modified key is pressed (so it's not recorded). */
16 /*			They were also renamed to getkeyval and ... */
17 /* 27-Sep-1992	SNS/CIT	Now puts the cursor event in the buffer in network */
18 /*			byte order. */
19 
20 /* The standard include files */
21 #include <stdio.h>
22 #include <sys/types.h>
23 #include <netinet/in.h>
24 
25 /* The X Window include files */
26 #include <X11/Xlib.h>
27 #include <X11/Xutil.h>
28 #include <X11/keysym.h>
29 
30 /* The program include files */
31 #include "figdisp.h"
32 #include "globals.h"
33 
34 struct curpos {
35 	short x;	/* x position */
36 	short y;	/* y position */
37 	short val;	/* the value of the button/key pressed. */
38 	struct curpos *next;	/* the next position */
39 };
40 
41 static struct curpos *lgcurses=NULL;	/* the line graphics cursor events */
42 static struct curpos *lastlg=NULL;	/* last in list of line graphics */
43 static int lgx,lgy;			/* line graphics cursor location */
44 
45 #ifndef PGDISP
46 static struct curpos *bmcurses=NULL;	/* the bitmap graphics cursor events */
47 static struct curpos *lastbm=NULL;	/* last in list of bitmap graphics */
48 static int bmx,bmy;			/* bitmap graphics cursor location */
49 #endif
50 
51 /* The pggcurs and bmcurs routines get the first cursor event in the line */
52 /* graphics or bitmap graphics list and returns it in the buffer buf, which */
53 /* has the format for the BM_GET_CURS and LG_CURS commands. */
54 /* Return Values: */
55 /* Whatever getcurs returns */
56 
pggcurs(buf)57 int pggcurs(buf)
58 short *buf;
59 {
60 	int getcurs ();
61 
62 	return(getcurs(buf,&lgcurses,&lastlg));
63 }
64 
65 #ifndef PGDISP
bmgcurs(buf)66 int bmgcurs(buf)
67 short *buf;
68 {
69 	int getcurs ();
70 
71 	return(getcurs(buf,&bmcurses,&lastbm));
72 }
73 #endif
74 
75 /* The getcurs routine gets the first cursor point from the given list, */
76 /* updates the buffer accordingly, and updates the given pointer. */
77 /* Return Values: */
78 /* 0	There are no cursor positions to return */
79 /* 1	The buffer was set properly */
80 
getcurs(buf,curlist,listend)81 int getcurs(buf,curlist,listend)
82 short *buf;
83 struct curpos **curlist;
84 struct curpos **listend;
85 {
86 	struct curpos *tmpptr;
87 
88 	/* the cursor hasn't yet been set */
89 	if (*curlist == NULL) return(0);
90 
91 	/* get the data */
92 	buf[1]= htons((*curlist)->x);
93 	buf[2]= htons((*curlist)->y);
94 	buf[3]= htons((*curlist)->val);
95 
96 	/* free up the used cursor point */
97 	tmpptr= *curlist;
98 	if ((*curlist= (*curlist)->next) == NULL) *listend=NULL;
99 	free((char *)tmpptr);
100 
101 	return(1);
102 }
103 
104 /* The pgcursor routine adds the specified event to the list of cursor events */
105 /* on the line graphics window. */
106 /* Return Value: 1 (no matter what) */
107 
pgcursor(event)108 int pgcursor(event)
109 XEvent event;
110 {
111 	short val;	/* the "value" of the event" */
112 
113 	void getbuttonval();
114 	int getkeyval();
115 
116 	char *malloc();
117 
118 	if (event.type == ButtonPress) getbuttonval(event.xbutton.button, &val);
119 	else if (!getkeyval(event, &val)) return(1);
120 
121 	if (lastlg != NULL)
122 	{
123 		/* if we can't get space for the next one */
124 #ifdef lint
125 		if (malloc(sizeof(struct curpos)) == NULL)
126 #else
127 		if ((lastlg->next=(struct curpos *)malloc(
128 		     sizeof(struct curpos))) == NULL)
129 #endif
130 			return(1);
131 		lastlg=lastlg->next;
132 	} else { /* This is the first one */
133 #ifdef lint
134 		if (malloc(sizeof(struct curpos)) == NULL)
135 #else
136 	    	if ((lgcurses=(struct curpos *)malloc(sizeof(struct curpos)))
137 		    == NULL)
138 #endif
139 			return(1);
140 		lastlg=lgcurses;
141 	}
142 	lastlg->next=NULL;
143 
144 	/* no translations are needed on the line graphics window */
145 	if (event.type == ButtonPress)
146 	{
147 		lgx=lastlg->x = event.xbutton.x;
148 		lgy=lastlg->y = event.xbutton.y;
149 	} else {
150 		lgx=lastlg->x = event.xkey.x;
151 		lgy=lastlg->y = event.xkey.y;
152 	}
153 	lastlg->val=val;
154 	return(1);
155 }
156 
157 #ifndef PGDISP
158 /* The bmcursor routine adds the specified event to the list of cursor events */
159 /* on the bitmap graphics window. */
160 /* Return Value: 1 (no matter what) */
161 
bmcursor(event)162 int bmcursor(event)
163 XEvent event;
164 {
165 	short val;	/* The value associated with the cursor event */
166 
167 	void getbuttonval();
168 	int getkeyval();
169 
170 	char *malloc();
171 
172 	if (event.type == ButtonPress) getbuttonval(event.xbutton.button, &val);
173 	else if (!getkeyval(event, &val)) return(1);
174 
175 	if (lastbm != NULL)
176 	{
177 		/* if we can't get space for the next one */
178 #ifdef lint
179 		if (malloc(sizeof(struct curpos)) == NULL)
180 #else
181 		if ((lastbm->next=(struct curpos *)malloc(
182 		     sizeof(struct curpos))) == NULL)
183 #endif
184 			return(1);
185 		lastbm=lastbm->next;
186 	} else { /* This is the first one */
187 #ifdef lint
188 		if (malloc(sizeof(struct curpos)) == NULL)
189 #else
190 	    	if ((bmcurses=(struct curpos *)malloc(sizeof(struct curpos)))
191 		    == NULL)
192 #endif
193 			return(1);
194 		lastbm=bmcurses;
195 	}
196 	lastbm->next=NULL;
197 
198 	/* translations are needed on the bitmap graphics window */
199 	if (event.type == ButtonPress)
200 	{
201 		bmx=lastbm->x = display_to_imagecol(event.xbutton.x);
202 		bmy=lastbm->y = display_to_imagerow(event.xbutton.y);
203 	} else {
204 		bmx=lastbm->x = display_to_imagecol(event.xkey.x);
205 		bmy=lastbm->y = display_to_imagerow(event.xkey.y);
206 	}
207 	lastbm->val=val;
208 	return(1);
209 }
210 #endif
211 
212 /* The getbuttonval routine updates val to correspond to the appropriate */
213 /* keypress. */
214 
getbuttonval(button,val)215 void getbuttonval(button,val)
216 unsigned int button;
217 short *val;
218 {
219 	switch(button)
220 	{
221 	case Button1:
222 		*val=0x0100;
223 		break;
224 	case Button2:
225 		*val=0x0101;
226 		break;
227 	case Button3:
228 		*val=0x0102;
229 		break;
230 	case Button4:
231 		*val=0x0103;
232 		break;
233 	default:
234 		*val=0x0104;
235 		break;
236 	}
237 
238 	return;
239 }
240 
241 /* The getkeyval routine updates val to correspond to the appropriate */
242 /* keypress */
243 
244 /* Return Values: */
245 /* 0	A modifier key was pressed */
246 /* 1	A regular key was pressed */
247 
getkeyval(event,val)248 int getkeyval(event,val)
249 XEvent event;
250 short *val;
251 {
252 	char tmpchr;
253 	KeySym keysym;
254 
255 	(void)XLookupString((XKeyEvent *)&event,&tmpchr,1,&keysym,
256 		(XComposeStatus *)NULL);
257 	if ((keysym >= XK_Shift_L) && (keysym <= XK_Hyper_R)) return(0);
258 	*val=tmpchr;
259 
260 	return(1);
261 }
262 
263 /* The pgscurs routine sets the current line graphics cursor position.  Note */
264 /* that this does not do anything unless there are no entries in the list of */
265 /* cursor events and does not do anything visible unless this position is */
266 /* different than the previousrecorded line graphics cursor location. */
267 
pgscurs(x,y)268 void pgscurs(x,y)
269 int x,y;
270 {
271 	if (lgcurses != NULL) return;
272 
273 	/* is this different enough to warp the cursor */
274 	if (x+1 < lgx || x-1 > lgx || y-1 > lgy || y+1 < lgy)
275 		XWarpPointer(display,None,lg.win,0,0,0,0,x,y);
276 	lgx=x;
277 	lgy=y;
278 
279 	return;
280 }
281 
282 #ifndef PGDISP
283 /* The bmscurs routine sets the current bitmap graphics cursor position.  */
284 /* Note that this does not do anything unless there are no entries in the */
285 /* list of cursor events and does not do anything visible unless this */
286 /* position is different than the previous recorded line graphics cursor */
287 /* location. */
288 
bmscurs(x,y)289 void bmscurs(x,y)
290 int x,y;
291 {
292 	if (bmcurses != NULL) return;
293 
294 	/* is this different enough to warp the cursor */
295 	if ((x+1 < bmx || x-1 > bmx || y-1 > bmy || y+1 < bmy) &&
296 	    imagecol_to_display(x) >= 0 && imagecol_to_display(x) < bm.width
297 	    && imagerow_to_display(y) >= 0 &&
298 	    imagerow_to_display(y) < bm.height)
299 		XWarpPointer(display,None,bm.win,0,0,0,0,
300 			imagecol_to_display(x),imagerow_to_display(y));
301 	bmx=x;
302 	bmy=y;
303 
304 	return;
305 }
306 #endif
307 
308 /* The clearcurs routine clears all the cursor events from both lists. */
309 
clearcurs()310 void clearcurs()
311 {
312 	struct curpos *tmpptr;
313 
314 	while (lgcurses != NULL)
315 	{
316 		tmpptr=lgcurses->next;
317 		free((char *)lgcurses);
318 		lgcurses=tmpptr;
319 	}
320 #ifndef PGDISP
321 	while (bmcurses != NULL)
322 	{
323 		tmpptr=bmcurses->next;
324 		free((char *)bmcurses);
325 		bmcurses=tmpptr;
326 	}
327 	lastbm=NULL;
328 	bmx=bmy= -1;
329 #endif
330 	lastlg=NULL;
331 	lgx=lgy -1;
332 	return;
333 }
334