1
2 #include <stdio.h>
3
4 #include <X11/StringDefs.h>
5 #include <X11/Intrinsic.h>
6 #include <X11/Core.h>
7 #include <X11/Object.h>
8 #include <X11/Shell.h>
9
10 #include <X11/Xaw/Form.h>
11
12 #include <Mowitz/Mowitz.h>
13
14 /* X11 stuff */
15
16 static Display *dpy ;
17 static Atom wm_protocols ;
18 static Atom wm_delete_window ;
19
20 static GC canvasGc ;
21 static Bool canvas_init = False ;
22 static Pixel black, yellow ;
23
24 /* Xt stuff */
25
26 static XtAppContext app_ctx ;
27
28 static Widget topLevel ;
29 static Widget mainPanel ;
30 static Widget leftRuler, topRuler ;
31 static Widget leftFrame, topFrame ;
32 static Widget canvas ;
33
34 static void CanvasCB(Widget, XtPointer, XEvent *, Boolean *) ;
35
36 static String fallback[] = {
37 "*background: gray",
38 "*borderWidth: 0",
39 "*Frame.shadowWidth: 1",
40 "*Frame.shadowType: raised",
41 "*MwRuler.font: -*-lucida-medium-r-normal-sans-12-*-*-*-*-*-iso8859-*",
42 "*MwRuler.fracFont: -*-lucida-medium-r-normal-sans-8-*-*-*-*-*-iso8859-*",
43 "*mainPanel.defaultDistance: 0",
44 "*canvas.width: 300",
45 "*canvas.height: 300",
46 "*topRuler.width: 300",
47 "*leftRuler.height: 300",
48 "*topRuler.scale: 100",
49 "*leftRuler.scale: -100",
50 "Rulerdemo.baseTranslations: #augment <Message>WM_PROTOCOLS: WMProtocols()",
51 NULL
52 };
53
54 static void RulerCB(Widget, XtPointer, XtPointer) ;
55
56 static void WMProtocols(Widget, XEvent *, String *, Cardinal *) ;
57
58
59 /* define global actions table for the application. This is done
60 * to catch messages. This could also be done through the main
61 * event loop if we wrote one. It would be nice if Xt had a way
62 * of regestering a callback proc for specific kinds of events.
63 */
64
65 XtActionsRec rulerdemo_actions[] = {
66 {"WMProtocols", WMProtocols},
67 } ;
68
69
70 int
main(int argc,char ** argv)71 main(int argc, char **argv)
72 {
73 Dimension len, bwid ;
74
75 topLevel = XtAppInitialize(&app_ctx, "Rulerdemo", NULL,0,
76 &argc, argv, fallback, NULL,0) ;
77 dpy = XtDisplay(topLevel) ;
78
79 XtAppAddActions(app_ctx,
80 rulerdemo_actions, XtNumber(rulerdemo_actions));
81
82 mainPanel = XtVaCreateManagedWidget("mainPanel",
83 formWidgetClass, topLevel,
84 0) ;
85
86 topFrame = XtVaCreateManagedWidget("topFrame",
87 mwFrameWidgetClass, mainPanel,
88 XtNleft, XtChainLeft,
89 XtNright, XtChainRight,
90 XtNtop, XtChainTop,
91 XtNbottom, XtChainTop,
92 0) ;
93
94 topRuler = XtVaCreateManagedWidget("topRuler",
95 mwRulerWidgetClass, topFrame,
96 XtNorientation, NorthGravity,
97 0) ;
98 XtAddCallback(topRuler, XtNcallback, RulerCB, NULL) ;
99
100 leftFrame = XtVaCreateManagedWidget("leftFrame",
101 mwFrameWidgetClass, mainPanel,
102 XtNleft, XtChainLeft,
103 XtNright, XtChainLeft,
104 XtNtop, XtChainTop,
105 XtNbottom, XtChainBottom,
106 XtNfromVert, topFrame,
107 0) ;
108
109 leftRuler = XtVaCreateManagedWidget("leftRuler",
110 mwRulerWidgetClass, leftFrame,
111 XtNorientation, WestGravity,
112 0) ;
113 XtAddCallback(leftRuler, XtNcallback, RulerCB, NULL) ;
114
115
116 /* yuk. Athena Form widget really sucks; I shouldn't have
117 * to go through these gyrations.
118 */
119
120 XtVaGetValues(leftRuler, XtNwidth, &len, 0) ;
121 XtVaGetValues(leftFrame, XtNshadowWidth, &bwid, 0) ;
122 XtVaSetValues(topFrame, XtNhorizDistance, len+bwid*2, 0) ;
123
124 canvas = XtVaCreateManagedWidget("canvas",
125 coreWidgetClass, mainPanel,
126 XtNleft, XtChainLeft,
127 XtNright, XtChainRight,
128 XtNtop, XtChainTop,
129 XtNbottom, XtChainBottom,
130 XtNfromHoriz, leftFrame,
131 XtNfromVert, topFrame,
132 0) ;
133 XtAddEventHandler(canvas,
134 ExposureMask | ButtonPressMask | PointerMotionMask |
135 EnterWindowMask | LeaveWindowMask,
136 True, CanvasCB, NULL) ;
137
138 XtRealizeWidget(topLevel) ;
139
140 /* tell window system we're willing to handle window-delete messages */
141 wm_protocols = XInternAtom(dpy, "WM_PROTOCOLS", False);
142 wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
143 (void) XSetWMProtocols(dpy, XtWindow(topLevel), &wm_delete_window,1);
144
145 MwRulerSetMinPosition(topRuler, 0., 0) ;
146 XtVaGetValues(leftRuler, XtNheight, &len, 0) ;
147 MwRulerSetMinPosition(leftRuler, 0., len-1) ;
148
149 XtAppMainLoop(app_ctx) ;
150
151 exit(0) ;
152 }
153
154
155
156
157
158
159
160
161
162 static void
RulerCB(Widget r,XtPointer client,XtPointer call_data)163 RulerCB(Widget r, XtPointer client, XtPointer call_data)
164 {
165 MwRulerReport *rep = (MwRulerReport *)call_data ;
166 Display *dpy = XtDisplay(canvas) ;
167 Window win = XtWindow(canvas) ;
168 Position sx,sy ;
169 Dimension wid,hgt ;
170
171 switch( rep->what ) {
172 case SCROLL:
173 case STOP:
174 XtVaGetValues(canvas, XtNwidth, &wid, XtNheight, &hgt, 0) ;
175 sx = -rep->dx ;
176 sy = -rep->dy ;
177 XCopyArea(dpy, win,win, canvasGc,
178 (int)sx, (int)sy, (u_int)wid, (u_int)hgt, 0, 0 ) ;
179 break ;
180 default:
181 break ;
182 }
183 }
184
185
186 static void
CanvasCB(Widget canvas,XtPointer client,XEvent * ev,Boolean * cont)187 CanvasCB(Widget canvas, XtPointer client, XEvent *ev, Boolean *cont)
188 {
189 Display *dpy = XtDisplay(canvas) ;
190 Window win = XtWindow(canvas) ;
191 int x0,y0 ;
192
193 if( !canvas_init )
194 {
195 Colormap cmap ;
196 XColor y,b, dummy ;
197 XtVaGetValues(canvas, XtNcolormap, &cmap, 0) ;
198 canvasGc = XCreateGC(dpy,win, 0,NULL) ;
199 XSetLineAttributes(dpy, canvasGc, 8, LineSolid, CapButt, JoinRound);
200 XSetGraphicsExposures(dpy, canvasGc, True) ;
201 XAllocNamedColor(dpy, cmap, "yellow", &y, &dummy) ; yellow = y.pixel ;
202 XAllocNamedColor(dpy, cmap, "black", &b, &dummy) ; black = b.pixel ;
203 canvas_init = True ;
204 }
205
206 switch( ev->type ) {
207 case GraphicsExpose:
208 case Expose:
209 x0 = MwRulerValue2Position(topRuler, 1.) ;
210 y0 = MwRulerValue2Position(leftRuler, 1.) - 100 ;
211 XSetForeground(dpy,canvasGc, yellow) ;
212 XFillArc(dpy,win,canvasGc, x0,y0, 100,100, 0,360*64) ;
213 XSetForeground(dpy,canvasGc, black) ;
214 XDrawArc(dpy,win,canvasGc, x0,y0, 100,100, 0,360*64) ;
215 XFillArc(dpy,win,canvasGc, x0+30,y0+30, 10,10, 0,360*64) ;
216 XFillArc(dpy,win,canvasGc, x0+60,y0+30, 10,10, 0,360*64) ;
217 XDrawArc(dpy,win,canvasGc, x0+20,y0+20, 60,60, 225*64,90*64) ;
218 break ;
219 case EnterNotify:
220 MwRulerShowPointer(leftRuler, True) ;
221 MwRulerShowPointer(topRuler, True) ;
222 break ;
223 case LeaveNotify:
224 MwRulerShowPointer(leftRuler, False) ;
225 MwRulerShowPointer(topRuler, False) ;
226 break ;
227 case MotionNotify:
228 MwRulerSetIValue(leftRuler, ev->xmotion.y) ;
229 MwRulerSetIValue(topRuler, ev->xmotion.x) ;
230 break ;
231 }
232
233 }
234
235
236 static void
WMProtocols(w,ev,params,nparams)237 WMProtocols(w, ev, params, nparams)
238 Widget w ;
239 XEvent *ev ;
240 String *params ;
241 Cardinal *nparams ;
242 {
243 if( ev->type == ClientMessage &&
244 ev->xclient.message_type == wm_protocols &&
245 ev->xclient.data.l[0] == wm_delete_window )
246 {
247 if( w == topLevel )
248 exit(0) ;
249 }
250 }
251