0
|
1 /* |
|
2 * Get graphical coordinates from screen |
|
3 * |
|
4 * This contains bits of code hacked from the |
|
5 * X Consortium and from Octave. Please see the |
|
6 * appropriate licences. The rest is mine, and |
|
7 * you can do what you want with that part. |
|
8 * |
|
9 * Andy Adler <adlera@ncf.ca> (C) 1997 |
|
10 * |
|
11 * Compile like this |
|
12 * mkoctfile -L/usr/X11R6/lib -lX11 -I/usr/X11R6/include/ ginput.cc |
|
13 * |
|
14 * Please excuse the ugly code. I wrote while I was learning C. |
|
15 */ |
|
16 |
|
17 #include <octave/config.h> |
|
18 #include <iostream.h> |
|
19 |
|
20 #include <octave/pager.h> |
|
21 |
|
22 #include <octave/defun-dld.h> |
|
23 #include <octave/error.h> |
|
24 #include <octave/help.h> |
|
25 #include <octave/symtab.h> |
|
26 #include <octave/oct-obj.h> |
|
27 #include <octave/utils.h> |
|
28 |
|
29 #include <X11/Xlib.h> |
|
30 #include <X11/cursorfont.h> |
|
31 |
|
32 #define maxpoints 100 |
|
33 |
|
34 DEFUN_DLD (ginput, args, nargout , |
|
35 "[...] = ginput (...)\n\ |
|
36 \n\ |
|
37 GINPUT: gets points mouse clicks on the screen\n\ |
|
38 \n\ |
|
39 [x,y]= ginput(axis)\n\ |
|
40 x -> x coordinates of the points\n\ |
|
41 y -> y coordinates of the points\n\ |
|
42 \n\ |
|
43 axis -> if specified then the first 2 (or 4) clicks\n\ |
|
44 must be on the appropriate axes. x and y (or just x\n\ |
|
45 if only 2 points specified ) will then be normalised.\n\ |
|
46 \n\ |
|
47 for example: x=ginput([1 10]) \n\ |
|
48 the first two clicks should correspond to x=1 and x=10 \n\ |
|
49 subsequent clicks will then be normalized to graph units. \n\ |
|
50 \n\ |
|
51 for example: [x,y]=ginput; \n\ |
|
52 gives x and y in screen pixel units (upper left = 0,0 ) \n\ |
|
53 \n\ |
|
54 select points with button #1. Buttons 2 and 3 quit. ") |
|
55 { |
|
56 XEvent event; |
|
57 XButtonEvent *e; |
|
58 Cursor cursor; |
|
59 Display *dpy; |
|
60 int xc[maxpoints],yc[maxpoints],nc=0; |
|
61 octave_value_list retval; |
|
62 |
|
63 int nargin = args.length(); |
|
64 |
|
65 if (nargin > 1) { |
|
66 print_usage ("ginput"); |
|
67 return retval; |
|
68 } |
|
69 else if (nargin == 1) { |
|
70 Matrix axis= args(0).matrix_value(); |
|
71 |
|
72 nc= args(0).columns(); |
|
73 |
|
74 if (nc==2 || nc==4) |
|
75 octave_stdout << "First click on x-axis points " << |
|
76 axis(0,0) << ", " << axis(0,1) <<"\n"; |
|
77 if (nc==4) |
|
78 octave_stdout << "Then click on y-axis points " << |
|
79 axis(0,2) << ", " << axis(0,3) <<"\n"; |
|
80 flush_octave_stdout (); |
|
81 } |
|
82 |
|
83 char *displayname = NULL; |
|
84 dpy = XOpenDisplay (displayname); |
|
85 |
|
86 if (!dpy) { |
|
87 fprintf(stderr,"GINPUT: unable to open display %s\n", |
|
88 XDisplayName(displayname)); |
|
89 exit (1); |
|
90 } |
|
91 |
|
92 cursor = XCreateFontCursor(dpy, XC_crosshair); |
|
93 |
|
94 /* Grab the pointer using target cursor, letting it room all over */ |
|
95 Window root = RootWindow(dpy,0); |
|
96 int done = XGrabPointer(dpy, root, False, ButtonPressMask, |
|
97 GrabModeSync, GrabModeAsync, root, cursor, CurrentTime); |
|
98 if (done != GrabSuccess) { |
|
99 fprintf(stderr,"GINPUT: Can't grab the mouse.\n"); |
|
100 exit(1); |
|
101 }; |
|
102 |
|
103 int m=0; |
|
104 do { |
|
105 XAllowEvents(dpy, SyncPointer, CurrentTime); |
|
106 XWindowEvent(dpy, root, ButtonPressMask, &event); |
|
107 |
|
108 e = (XButtonEvent *) &event; |
|
109 |
|
110 xc[m]= e->x_root; |
|
111 yc[m]= e->y_root; |
|
112 |
|
113 /* |
|
114 printf("%d,%d,(%d,%d),B=%u,t=%lu\n", |
|
115 e->x, e->y, e->x_root, e->y_root, e->button, e->time); |
|
116 */ |
|
117 } while (e->button == 1 && ++m < maxpoints); |
|
118 |
|
119 if (m < nc) { |
|
120 fprintf(stderr,"GINPUT: Not enough points selected.\n"); |
|
121 exit(1); |
|
122 }; |
|
123 |
|
124 double xb=0, xm=1, yb=0, ym=1; |
|
125 if (nc==2 || nc==4) { |
|
126 Matrix axis= args(0).matrix_value(); |
|
127 |
|
128 xm= (axis(0,0)-axis(0,1)) / (xc[0]-xc[1]); |
|
129 xb= (xc[1]*axis(0,0)-xc[0]*axis(0,1)) / (xc[1]-xc[0]); |
|
130 |
|
131 // octave_stdout << "xm=" << xm << " xb=" << xb ; |
|
132 |
|
133 if (nc==4) { |
|
134 ym= (axis(0,2)-axis(0,3)) / (yc[2]-yc[3]); |
|
135 yb= (yc[3]*axis(0,2)-yc[2]*axis(0,3)) / (yc[3]-yc[2]); |
|
136 }; |
|
137 }; |
|
138 |
|
139 ColumnVector x(m-nc),y(m-nc); |
|
140 for(int i=nc; i<m; i++) { |
|
141 x(i-nc)= (double) xc[i]*xm + xb; |
|
142 y(i-nc)= (double) yc[i]*ym + yb; |
|
143 }; |
|
144 |
|
145 XUngrabPointer(dpy, CurrentTime); /* Done with pointer */ |
|
146 XCloseDisplay (dpy); |
|
147 |
|
148 retval(0) = x; |
|
149 if (nargout == 2) |
|
150 retval(1) = y; |
|
151 |
|
152 return retval; |
|
153 } |
|
154 |