libdockapp: Use consistent code formatting.
Used uncrustify to minimize warnings and errors from checkpatch.pl in the
Window Maker source tree.
Doug Torrance authored 9 years ago
Carlos R. Mafra committed 9 years ago
18 | 18 | /* |
19 | 19 | * Prototypes for local functions |
20 | 20 | */ |
21 | void drawRelief(); | |
22 | void moveBall(); | |
23 | void destroy(); | |
21 | void drawRelief(Pixmap pixmap); | |
22 | void moveBall(void); | |
23 | void destroy(void); | |
24 | 24 | |
25 | 25 | /* |
26 | 26 | * Global variables |
35 | 35 | int |
36 | 36 | main(int argc, char **argv) |
37 | 37 | { |
38 | unsigned int x=1, y=1; | |
39 | Pixmap back; | |
40 | DACallbacks eventCallbacks = { | |
41 | destroy, /* destroy */ | |
42 | NULL, /* buttonPress */ | |
43 | NULL, /* buttonRelease */ | |
44 | NULL, /* motion (mouse) */ | |
45 | NULL, /* mouse enters window */ | |
46 | NULL, /* mouse leaves window */ | |
47 | moveBall /* timeout */ | |
48 | }; | |
49 | ||
50 | /* provide standard command-line options */ | |
51 | DAParseArguments( | |
52 | argc, argv, /* Where the options come from */ | |
53 | NULL, 0, /* Our list with options - none as you can see */ | |
54 | "This is the help text for the basic example of how to " | |
55 | "use libDockapp.\n", | |
56 | "Basic example version 1.1"); | |
57 | ||
58 | /* Tell libdockapp what version we expect it to be (a date from the | |
59 | * ChangeLog should do). | |
60 | */ | |
61 | DASetExpectedVersion(20020126); | |
62 | ||
63 | DAOpenDisplay( | |
64 | NULL /* default display */, | |
65 | argc, argv /* needed by libdockapp */ | |
66 | ); | |
67 | DACreateIcon( | |
68 | "daBasicExample" /* WM_CLASS hint; don't use chars in [.?*: ] */, | |
69 | 48, 48 /* geometry of dockapp internals */, | |
70 | argc, argv /* needed by libdockapp */ | |
71 | ); | |
72 | ||
73 | /* The pixmap that makes up the background of the dockapp */ | |
74 | back = DAMakePixmap(); | |
75 | drawRelief(back); | |
76 | DASetPixmap(back); | |
77 | XFreePixmap(DADisplay, back); | |
78 | ||
79 | /* A window(!) for the ball pixmap. | |
80 | * Moving a window is a lot easier then erasing/copying the pixmap all | |
81 | * the time. | |
82 | * | |
83 | * I use a DAShapedPixmap here, which contains all the information | |
84 | * related to the pixmap: pixmap, mask and geometry. | |
85 | */ | |
86 | ballPix = DAMakeShapedPixmapFromData(ball_red_xpm); | |
87 | ballWin = XCreateSimpleWindow(DADisplay, DAWindow, | |
88 | x, y, | |
89 | /* Use the geometry of the shaped pixmap */ | |
90 | ballPix->geometry.width, ballPix->geometry.height, | |
91 | 0, 0, 0); | |
92 | DASPSetPixmapForWindow(ballWin, ballPix); | |
93 | ||
94 | /* Respond to destroy and timeout events (the ones not NULL in the | |
95 | * eventCallbacks variable. | |
96 | */ | |
97 | DASetCallbacks(&eventCallbacks); | |
98 | ||
99 | /* Set the time for timeout events (in msec) */ | |
100 | DASetTimeout(SPEED); | |
101 | ||
102 | /* Randomize movement variation. | |
103 | * Run multiple versions of the dockapp simultaneously to see the effect | |
104 | * best. | |
105 | * (which function to use is set from the Imakefile) | |
106 | */ | |
38 | unsigned int x = 1, y = 1; | |
39 | Pixmap back; | |
40 | DACallbacks eventCallbacks = { | |
41 | destroy, /* destroy */ | |
42 | NULL, /* buttonPress */ | |
43 | NULL, /* buttonRelease */ | |
44 | NULL, /* motion (mouse) */ | |
45 | NULL, /* mouse enters window */ | |
46 | NULL, /* mouse leaves window */ | |
47 | moveBall /* timeout */ | |
48 | }; | |
49 | ||
50 | /* provide standard command-line options */ | |
51 | DAParseArguments( | |
52 | argc, argv, /* Where the options come from */ | |
53 | NULL, 0, /* Our list with options - none as you can see */ | |
54 | "This is the help text for the basic example of how to " | |
55 | "use libDockapp.\n", | |
56 | "Basic example version 1.1"); | |
57 | ||
58 | /* Tell libdockapp what version we expect it to be (a date from the | |
59 | * ChangeLog should do). | |
60 | */ | |
61 | DASetExpectedVersion(20020126); | |
62 | ||
63 | DAOpenDisplay( | |
64 | NULL /* default display */, | |
65 | argc, argv /* needed by libdockapp */ | |
66 | ); | |
67 | DACreateIcon( | |
68 | "daBasicExample" /* WM_CLASS hint; don't use chars in [.?*: ] */, | |
69 | 48, 48 /* geometry of dockapp internals */, | |
70 | argc, argv /* needed by libdockapp */ | |
71 | ); | |
72 | ||
73 | /* The pixmap that makes up the background of the dockapp */ | |
74 | back = DAMakePixmap(); | |
75 | drawRelief(back); | |
76 | DASetPixmap(back); | |
77 | XFreePixmap(DADisplay, back); | |
78 | ||
79 | /* A window(!) for the ball pixmap. | |
80 | * Moving a window is a lot easier then erasing/copying the pixmap all | |
81 | * the time. | |
82 | * | |
83 | * I use a DAShapedPixmap here, which contains all the information | |
84 | * related to the pixmap: pixmap, mask and geometry. | |
85 | */ | |
86 | ballPix = DAMakeShapedPixmapFromData(ball_red_xpm); | |
87 | ballWin = XCreateSimpleWindow(DADisplay, DAWindow, | |
88 | x, y, | |
89 | /* Use the geometry of the shaped pixmap */ | |
90 | ballPix->geometry.width, ballPix->geometry.height, | |
91 | 0, 0, 0); | |
92 | DASPSetPixmapForWindow(ballWin, ballPix); | |
93 | ||
94 | /* Respond to destroy and timeout events (the ones not NULL in the | |
95 | * eventCallbacks variable. | |
96 | */ | |
97 | DASetCallbacks(&eventCallbacks); | |
98 | ||
99 | /* Set the time for timeout events (in msec) */ | |
100 | DASetTimeout(SPEED); | |
101 | ||
102 | /* Randomize movement variation. | |
103 | * Run multiple versions of the dockapp simultaneously to see the effect | |
104 | * best. | |
105 | * (which function to use is set from the Imakefile) | |
106 | */ | |
107 | 107 | #ifdef HAS_RANDOMDEV |
108 | srandomdev(); | |
108 | srandomdev(); | |
109 | 109 | #else |
110 | srandom(time(NULL)); | |
110 | srandom(time(NULL)); | |
111 | 111 | #endif |
112 | 112 | |
113 | DAShow(); /* Show the dockapp window. */ | |
114 | ||
115 | /* Process events and keep the dockapp running */ | |
116 | DAEventLoop(); | |
117 | ||
118 | /* not reached */ | |
119 | exit(EXIT_SUCCESS); | |
113 | DAShow(); /* Show the dockapp window. */ | |
114 | ||
115 | /* Process events and keep the dockapp running */ | |
116 | DAEventLoop(); | |
117 | ||
118 | /* not reached */ | |
119 | exit(EXIT_SUCCESS); | |
120 | 120 | } |
121 | 121 | |
122 | 122 | |
123 | 123 | void |
124 | 124 | drawRelief(Pixmap pixmap) |
125 | 125 | { |
126 | XGCValues gcv; | |
127 | GC lightGrayGC, darkGrayGC; | |
128 | ||
129 | /* GC's */ | |
130 | gcv.foreground = DAGetColor("Navy"); | |
131 | XChangeGC(DADisplay, DAClearGC, GCForeground, &gcv); | |
132 | ||
133 | gcv.foreground = DAGetColor("lightGray"); | |
134 | gcv.graphics_exposures = False; | |
135 | ||
136 | lightGrayGC = XCreateGC(DADisplay, DAWindow, | |
137 | GCForeground|GCGraphicsExposures, &gcv); | |
138 | ||
139 | gcv.foreground = DAGetColor("#222222"); | |
140 | darkGrayGC = XCreateGC(DADisplay, DAWindow, | |
141 | GCForeground|GCGraphicsExposures, &gcv); | |
142 | ||
143 | /* Drawing */ | |
144 | XFillRectangle(DADisplay, pixmap, DAClearGC, 1, 1, 46, 46); | |
145 | ||
146 | XDrawLine(DADisplay, pixmap, darkGrayGC, 0, 0, 0, 46); | |
147 | XDrawLine(DADisplay, pixmap, darkGrayGC, 1, 0, 47, 0); | |
148 | ||
149 | XDrawLine(DADisplay, pixmap, lightGrayGC, 0, 47, 47, 47); | |
150 | XDrawLine(DADisplay, pixmap, lightGrayGC, 47, 1, 47, 46); | |
151 | ||
152 | /* Free the GC's, we don't use them anymore */ | |
153 | XFreeGC(DADisplay, lightGrayGC); | |
154 | XFreeGC(DADisplay, darkGrayGC); | |
126 | XGCValues gcv; | |
127 | GC lightGrayGC, darkGrayGC; | |
128 | ||
129 | /* GC's */ | |
130 | gcv.foreground = DAGetColor("Navy"); | |
131 | XChangeGC(DADisplay, DAClearGC, GCForeground, &gcv); | |
132 | ||
133 | gcv.foreground = DAGetColor("lightGray"); | |
134 | gcv.graphics_exposures = False; | |
135 | ||
136 | lightGrayGC = XCreateGC(DADisplay, DAWindow, | |
137 | GCForeground | GCGraphicsExposures, &gcv); | |
138 | ||
139 | gcv.foreground = DAGetColor("#222222"); | |
140 | darkGrayGC = XCreateGC(DADisplay, DAWindow, | |
141 | GCForeground | GCGraphicsExposures, &gcv); | |
142 | ||
143 | /* Drawing */ | |
144 | XFillRectangle(DADisplay, pixmap, DAClearGC, 1, 1, 46, 46); | |
145 | ||
146 | XDrawLine(DADisplay, pixmap, darkGrayGC, 0, 0, 0, 46); | |
147 | XDrawLine(DADisplay, pixmap, darkGrayGC, 1, 0, 47, 0); | |
148 | ||
149 | XDrawLine(DADisplay, pixmap, lightGrayGC, 0, 47, 47, 47); | |
150 | XDrawLine(DADisplay, pixmap, lightGrayGC, 47, 1, 47, 46); | |
151 | ||
152 | /* Free the GC's, we don't use them anymore */ | |
153 | XFreeGC(DADisplay, lightGrayGC); | |
154 | XFreeGC(DADisplay, darkGrayGC); | |
155 | 155 | } |
156 | 156 | |
157 | 157 | |
158 | 158 | void |
159 | moveBall() | |
160 | { | |
161 | static int x = 1; | |
162 | static int y = 1; | |
163 | static int dx = 0; | |
164 | static int dy = 0; | |
165 | signed int var = random()%3 -1; | |
166 | ||
167 | if (dx == 0) dx = var; | |
168 | if (dy == 0) dy = var; | |
169 | if (dx > MAX_MOVE) dx = MAX_MOVE; | |
170 | if (dy > MAX_MOVE) dy = MAX_MOVE; | |
171 | ||
172 | /* calculate new position */ | |
173 | x += dx; | |
174 | y += dy; | |
175 | ||
176 | if (x < 1) { | |
177 | x = 1; | |
178 | dx = -dx + var; | |
179 | } | |
180 | ||
181 | if (y < 1) { | |
182 | y = 1; | |
183 | dy = -dy + var; | |
184 | } | |
185 | ||
186 | if (x + ballPix->geometry.width > 46) { | |
187 | x = 46 - ballPix->geometry.width; | |
188 | dx = -dx + var; | |
189 | } | |
190 | ||
191 | if (y + ballPix->geometry.height > 46) { | |
192 | y = 46 - ballPix->geometry.height; | |
193 | dy = -dy + var; | |
194 | } | |
195 | ||
196 | XMoveWindow(DADisplay, ballWin, x, y); | |
159 | moveBall(void) | |
160 | { | |
161 | static int x = 1; | |
162 | static int y = 1; | |
163 | static int dx; | |
164 | static int dy; | |
165 | signed int var = random() % 3 - 1; | |
166 | ||
167 | if (dx == 0) | |
168 | dx = var; | |
169 | ||
170 | if (dy == 0) | |
171 | dy = var; | |
172 | ||
173 | if (dx > MAX_MOVE) | |
174 | dx = MAX_MOVE; | |
175 | ||
176 | if (dy > MAX_MOVE) | |
177 | dy = MAX_MOVE; | |
178 | ||
179 | /* calculate new position */ | |
180 | x += dx; | |
181 | y += dy; | |
182 | ||
183 | if (x < 1) { | |
184 | x = 1; | |
185 | dx = -dx + var; | |
186 | } | |
187 | ||
188 | if (y < 1) { | |
189 | y = 1; | |
190 | dy = -dy + var; | |
191 | } | |
192 | ||
193 | if (x + ballPix->geometry.width > 46) { | |
194 | x = 46 - ballPix->geometry.width; | |
195 | dx = -dx + var; | |
196 | } | |
197 | ||
198 | if (y + ballPix->geometry.height > 46) { | |
199 | y = 46 - ballPix->geometry.height; | |
200 | dy = -dy + var; | |
201 | } | |
202 | ||
203 | XMoveWindow(DADisplay, ballWin, x, y); | |
197 | 204 | } |
198 | 205 | |
199 | 206 | |
200 | 207 | void |
201 | 208 | destroy(void) |
202 | 209 | { |
203 | XFreePixmap(DADisplay, ballPix->pixmap); | |
204 | XFreePixmap(DADisplay, ballPix->shape); | |
205 | ||
206 | fprintf(stderr, "Destroyed!\n"); | |
207 | /* exit is done by libdockapp */ | |
208 | } | |
210 | XFreePixmap(DADisplay, ballPix->pixmap); | |
211 | XFreePixmap(DADisplay, ballPix->shape); | |
212 | ||
213 | fprintf(stderr, "Destroyed!\n"); | |
214 | /* exit is done by libdockapp */ | |
215 | } |
27 | 27 | |
28 | 28 | /* I like to keep my graphic contexts (GCs) together */ |
29 | 29 | struct Colors { |
30 | GC white; /* foreground color from X-resource, or default */ | |
31 | GC black; /* background color, idem */ | |
32 | GC lightGray; /* Some GC's we'll have to define for colors */ | |
33 | GC darkGray; | |
34 | GC slider; /* draw-color when not highlighted, | |
30 | GC white; /* foreground color from X-resource, or default */ | |
31 | GC black; /* background color, idem */ | |
32 | GC lightGray; /* Some GC's we'll have to define for colors */ | |
33 | GC darkGray; | |
34 | GC slider; /* draw-color when not highlighted, | |
35 | 35 | * dark-color when highlighted |
36 | 36 | */ |
37 | GC sliderLight; /* draw-color when highlighted */ | |
38 | GC sliderDark; /* dark-color when not highlighted */ | |
37 | GC sliderLight; /* draw-color when highlighted */ | |
38 | GC sliderDark; /* dark-color when not highlighted */ | |
39 | 39 | }; |
40 | 40 | |
41 | 41 | |
42 | 42 | /* |
43 | 43 | * Global variables |
44 | 44 | */ |
45 | Pixmap pixmap; /* pixmap pixmap */ | |
45 | Pixmap pixmap; /* pixmap pixmap */ | |
46 | 46 | DARect *buttonDown = NULL; |
47 | struct Colors *colors; /* our colors */ | |
47 | struct Colors *colors; /* our colors */ | |
48 | 48 | DAActionRect **actionRects; |
49 | 49 | float sliderPos = 0.7; |
50 | 50 | int mouseIn = 0; |
53 | 53 | /* |
54 | 54 | * Prototypes for local functions |
55 | 55 | */ |
56 | struct Colors* setGCs(Drawable d); | |
56 | struct Colors *setGCs(Drawable d); | |
57 | 57 | unsigned long adjustColor(unsigned long color, signed int adjustment); |
58 | 58 | |
59 | 59 | /* drawing routines */ |
102 | 102 | int |
103 | 103 | main(int argc, char **argv) |
104 | 104 | { |
105 | /* define the event handlers for the events */ | |
106 | DACallbacks eventCallbacks = { | |
107 | destroy, /* destroy */ | |
108 | buttonPress, /* buttonPress */ | |
109 | buttonRelease, /* buttonRelease */ | |
110 | mouseMove, /* motion (mouse) */ | |
111 | mouseEnter, /* mouse enters window */ | |
112 | mouseLeave, /* mouse leaves window */ | |
113 | NULL /* timeout */ | |
114 | }; | |
115 | ||
116 | /* define regions (x, y, width, height) that need event-handling */ | |
117 | Region clipRegion = XCreateRegion(); | |
118 | ||
119 | DARect btn = {0, 0, 16, 16}, | |
120 | square = {0, 25, 22, 22}, | |
121 | slider = {24, 0, 23, 48}; | |
122 | ||
123 | /* define what to do if an event occurs in a rectangle */ | |
124 | DAActionRect *buttonPressRects, *buttonReleaseRects, | |
125 | *mouseMoveRects, *mouseEnterRects, *mouseLeaveRects; | |
126 | ||
127 | buttonPressRects = malloc(3 * sizeof(DAActionRect)); | |
128 | buttonPressRects[0] = setRectAction(btn, btnDown); | |
129 | buttonPressRects[1] = setRectAction(square, squareDown); | |
130 | buttonPressRects[2] = setRectAction(slider, sliderDown); | |
131 | ||
132 | buttonReleaseRects = malloc(2 * sizeof(DAActionRect)); | |
133 | buttonReleaseRects[0] = setRectAction(btn, btnUp); | |
134 | buttonReleaseRects[1] = setRectAction(slider, sliderUp); | |
135 | ||
136 | mouseMoveRects = malloc(sizeof(DAActionRect)); | |
137 | mouseMoveRects[0] = setRectAction(slider, sliderMove); | |
138 | ||
139 | mouseEnterRects = malloc(sizeof(DAActionRect)); | |
140 | mouseEnterRects[0] = setRectAction(slider, sliderEnter); | |
141 | ||
142 | mouseLeaveRects = malloc(2 * sizeof(DAActionRect)); | |
143 | mouseLeaveRects[0] = setRectAction(btn, btnLeave); | |
144 | mouseLeaveRects[1] = setRectAction(slider, sliderLeave); | |
145 | ||
146 | ||
147 | /* XXX: make action rectangles available outside main() | |
148 | * ...libDockapp should be able to do this... (reminder) | |
149 | */ | |
150 | actionRects = malloc(6 * sizeof(DAActionRect*)); | |
151 | actionRects[0] = buttonPressRects; | |
152 | actionRects[1] = buttonReleaseRects; | |
153 | actionRects[2] = mouseMoveRects; | |
154 | actionRects[3] = mouseEnterRects; | |
155 | actionRects[4] = mouseLeaveRects; | |
156 | actionRects[5] = NULL; | |
157 | ||
158 | /* provide standard command-line options */ | |
159 | DAParseArguments( | |
160 | argc, argv, /* Where the options come from */ | |
161 | NULL, 0, /* Our list with options - none as you can see */ | |
162 | "This is the help text for the rectangle example of how to " | |
163 | "use libDockapp.\n", | |
164 | "Rectangle example version 1.0"); | |
165 | ||
166 | /* Tell libdockapp what version we expect it to be, so that you can use | |
167 | * older programs with newer versions of libdockapp with less risc for | |
168 | * compatibility problems. | |
169 | */ | |
170 | DASetExpectedVersion(20030126); | |
171 | ||
172 | /* Initialize a dockapp */ | |
173 | DAInitialize( | |
174 | "", /* Use default display */ | |
175 | "daRectangleExample", /* WM_CLASS hint; don't use chars in [.?*: ] */ | |
176 | 48, 48, /* geometry of dockapp internals */ | |
177 | argc, argv /* (needed internally) */ | |
178 | ); | |
179 | ||
180 | /* Create a pixmap to draw on, and to display */ | |
181 | pixmap = DAMakePixmap(); /* size == dockapp geometry (48,48) */ | |
182 | ||
183 | colors = setGCs(pixmap); | |
184 | ||
185 | XFillRectangle(DADisplay, pixmap, DAClearGC, 0, 0, 48, 48); | |
186 | XClearWindow(DADisplay, DAWindow); | |
187 | ||
188 | /* Make a "Region" from the shapes we have */ | |
189 | XUnionRectWithRegion(&btn, clipRegion, clipRegion); | |
190 | XUnionRectWithRegion(&square, clipRegion, clipRegion); | |
191 | XUnionRectWithRegion(&slider, clipRegion, clipRegion); | |
192 | ||
193 | /* Make this region a window shape mask */ | |
194 | XShapeCombineRegion(DADisplay, DAWindow, ShapeBounding, | |
195 | 0, 0, clipRegion, ShapeSet); | |
196 | ||
197 | /* We don't need the region anymore (it is copied by XShapeCombineRegion). | |
198 | * XXX: That's not certain, it is not documented. XSetRegion does so, | |
199 | * though, so it is a likely assumption that it does copy. | |
200 | */ | |
201 | XDestroyRegion(clipRegion); | |
202 | ||
203 | /* The cursor we want to use. | |
204 | * Specify 'None' for the default, | |
205 | * or one from X11/cursorfont.h | |
206 | */ | |
207 | pointer = XCreateFontCursor(DADisplay, XC_based_arrow_up); | |
208 | XDefineCursor(DADisplay, DAWindow, pointer); | |
209 | ||
210 | /* a square with an image that changes when clicked (A button). */ | |
211 | createBtn(btn); | |
212 | ||
213 | /* a square that shows the number of the mouse-button pressed on click. */ | |
214 | createSquare(square); | |
215 | ||
216 | /* a slider a using two dashed line GC's. */ | |
217 | createSlider(slider); | |
218 | ||
219 | /* Tell libdockapp this is the pixmap that we want to show */ | |
220 | DASetPixmap(pixmap); | |
221 | ||
222 | /* Process events every 100ms */ | |
223 | DASetTimeout(100); | |
224 | ||
225 | /* set event callbacks */ | |
226 | DASetCallbacks(&eventCallbacks); | |
227 | ||
228 | /* Display the pixmap we said it to show */ | |
229 | DAShow(); | |
230 | ||
231 | /* Process events and keep the dockapp running */ | |
232 | DAEventLoop(); | |
233 | ||
234 | return 0; | |
105 | /* define the event handlers for the events */ | |
106 | DACallbacks eventCallbacks = { | |
107 | destroy, /* destroy */ | |
108 | buttonPress, /* buttonPress */ | |
109 | buttonRelease, /* buttonRelease */ | |
110 | mouseMove, /* motion (mouse) */ | |
111 | mouseEnter, /* mouse enters window */ | |
112 | mouseLeave, /* mouse leaves window */ | |
113 | NULL /* timeout */ | |
114 | }; | |
115 | ||
116 | /* define regions (x, y, width, height) that need event-handling */ | |
117 | Region clipRegion = XCreateRegion(); | |
118 | ||
119 | DARect btn = {0, 0, 16, 16}, | |
120 | square = {0, 25, 22, 22}, | |
121 | slider = {24, 0, 23, 48}; | |
122 | ||
123 | /* define what to do if an event occurs in a rectangle */ | |
124 | DAActionRect *buttonPressRects, *buttonReleaseRects, | |
125 | *mouseMoveRects, *mouseEnterRects, *mouseLeaveRects; | |
126 | ||
127 | buttonPressRects = malloc(3 * sizeof(DAActionRect)); | |
128 | buttonPressRects[0] = setRectAction(btn, btnDown); | |
129 | buttonPressRects[1] = setRectAction(square, squareDown); | |
130 | buttonPressRects[2] = setRectAction(slider, sliderDown); | |
131 | ||
132 | buttonReleaseRects = malloc(2 * sizeof(DAActionRect)); | |
133 | buttonReleaseRects[0] = setRectAction(btn, btnUp); | |
134 | buttonReleaseRects[1] = setRectAction(slider, sliderUp); | |
135 | ||
136 | mouseMoveRects = malloc(sizeof(DAActionRect)); | |
137 | mouseMoveRects[0] = setRectAction(slider, sliderMove); | |
138 | ||
139 | mouseEnterRects = malloc(sizeof(DAActionRect)); | |
140 | mouseEnterRects[0] = setRectAction(slider, sliderEnter); | |
141 | ||
142 | mouseLeaveRects = malloc(2 * sizeof(DAActionRect)); | |
143 | mouseLeaveRects[0] = setRectAction(btn, btnLeave); | |
144 | mouseLeaveRects[1] = setRectAction(slider, sliderLeave); | |
145 | ||
146 | ||
147 | /* XXX: make action rectangles available outside main() | |
148 | * ...libDockapp should be able to do this... (reminder) | |
149 | */ | |
150 | actionRects = malloc(6 * sizeof(DAActionRect *)); | |
151 | actionRects[0] = buttonPressRects; | |
152 | actionRects[1] = buttonReleaseRects; | |
153 | actionRects[2] = mouseMoveRects; | |
154 | actionRects[3] = mouseEnterRects; | |
155 | actionRects[4] = mouseLeaveRects; | |
156 | actionRects[5] = NULL; | |
157 | ||
158 | /* provide standard command-line options */ | |
159 | DAParseArguments( | |
160 | argc, argv, /* Where the options come from */ | |
161 | NULL, 0, /* Our list with options - none as you can see */ | |
162 | "This is the help text for the rectangle example of how to " | |
163 | "use libDockapp.\n", | |
164 | "Rectangle example version 1.0"); | |
165 | ||
166 | /* Tell libdockapp what version we expect it to be, so that you can use | |
167 | * older programs with newer versions of libdockapp with less risc for | |
168 | * compatibility problems. | |
169 | */ | |
170 | DASetExpectedVersion(20030126); | |
171 | ||
172 | /* Initialize a dockapp */ | |
173 | DAInitialize( | |
174 | "", /* Use default display */ | |
175 | "daRectangleExample", /* WM_CLASS hint; don't use chars in [.?*: ] */ | |
176 | 48, 48, /* geometry of dockapp internals */ | |
177 | argc, argv /* (needed internally) */ | |
178 | ); | |
179 | ||
180 | /* Create a pixmap to draw on, and to display */ | |
181 | pixmap = DAMakePixmap(); /* size == dockapp geometry (48,48) */ | |
182 | ||
183 | colors = setGCs(pixmap); | |
184 | ||
185 | XFillRectangle(DADisplay, pixmap, DAClearGC, 0, 0, 48, 48); | |
186 | XClearWindow(DADisplay, DAWindow); | |
187 | ||
188 | /* Make a "Region" from the shapes we have */ | |
189 | XUnionRectWithRegion(&btn, clipRegion, clipRegion); | |
190 | XUnionRectWithRegion(&square, clipRegion, clipRegion); | |
191 | XUnionRectWithRegion(&slider, clipRegion, clipRegion); | |
192 | ||
193 | /* Make this region a window shape mask */ | |
194 | XShapeCombineRegion(DADisplay, DAWindow, ShapeBounding, | |
195 | 0, 0, clipRegion, ShapeSet); | |
196 | ||
197 | /* We don't need the region anymore (it is copied by XShapeCombineRegion). | |
198 | * XXX: That's not certain, it is not documented. XSetRegion does so, | |
199 | * though, so it is a likely assumption that it does copy. | |
200 | */ | |
201 | XDestroyRegion(clipRegion); | |
202 | ||
203 | /* The cursor we want to use. | |
204 | * Specify 'None' for the default, | |
205 | * or one from X11/cursorfont.h | |
206 | */ | |
207 | pointer = XCreateFontCursor(DADisplay, XC_based_arrow_up); | |
208 | XDefineCursor(DADisplay, DAWindow, pointer); | |
209 | ||
210 | /* a square with an image that changes when clicked (A button). */ | |
211 | createBtn(btn); | |
212 | ||
213 | /* a square that shows the number of the mouse-button pressed on click. */ | |
214 | createSquare(square); | |
215 | ||
216 | /* a slider a using two dashed line GC's. */ | |
217 | createSlider(slider); | |
218 | ||
219 | /* Tell libdockapp this is the pixmap that we want to show */ | |
220 | DASetPixmap(pixmap); | |
221 | ||
222 | /* Process events every 100ms */ | |
223 | DASetTimeout(100); | |
224 | ||
225 | /* set event callbacks */ | |
226 | DASetCallbacks(&eventCallbacks); | |
227 | ||
228 | /* Display the pixmap we said it to show */ | |
229 | DAShow(); | |
230 | ||
231 | /* Process events and keep the dockapp running */ | |
232 | DAEventLoop(); | |
233 | ||
234 | return 0; | |
235 | 235 | } |
236 | 236 | |
237 | 237 | |
238 | 238 | /* Create our GC's to draw colored lines and such */ |
239 | struct Colors* | |
239 | struct Colors * | |
240 | 240 | setGCs(Drawable d) |
241 | 241 | { |
242 | struct Colors *colors; | |
243 | XGCValues gcv; | |
244 | unsigned long origColor; | |
245 | char dashList[2] = {3, 1}; | |
246 | ||
247 | colors = malloc(sizeof(struct Colors)); | |
248 | if (colors == NULL) | |
249 | return NULL; | |
250 | ||
251 | /* Get the GC-values of the default GC */ | |
252 | XGetGCValues(DADisplay, DAGC, | |
253 | GCForeground|GCBackground|GCGraphicsExposures, &gcv); | |
254 | ||
255 | origColor = gcv.foreground; | |
256 | ||
257 | /* don't send expose events */ | |
258 | gcv.graphics_exposures = False; | |
259 | ||
260 | /* GC for white color */ | |
261 | gcv.foreground = WhitePixel(DADisplay, DefaultScreen(DADisplay)); | |
262 | colors->white = XCreateGC(DADisplay, d, | |
263 | GCForeground|GCGraphicsExposures, &gcv); | |
264 | ||
265 | /* GC for dark blue color */ | |
242 | struct Colors *colors; | |
243 | XGCValues gcv; | |
244 | unsigned long origColor; | |
245 | char dashList[2] = {3, 1}; | |
246 | ||
247 | colors = malloc(sizeof(struct Colors)); | |
248 | if (colors == NULL) | |
249 | return NULL; | |
250 | ||
251 | /* Get the GC-values of the default GC */ | |
252 | XGetGCValues(DADisplay, DAGC, | |
253 | GCForeground | GCBackground | GCGraphicsExposures, &gcv); | |
254 | ||
255 | origColor = gcv.foreground; | |
256 | ||
257 | /* don't send expose events */ | |
258 | gcv.graphics_exposures = False; | |
259 | ||
260 | /* GC for white color */ | |
261 | gcv.foreground = WhitePixel(DADisplay, DefaultScreen(DADisplay)); | |
262 | colors->white = XCreateGC(DADisplay, d, | |
263 | GCForeground | GCGraphicsExposures, &gcv); | |
264 | ||
265 | /* GC for dark blue color */ | |
266 | 266 | #if 1 |
267 | gcv.foreground = DAGetColor("navy"); | |
267 | gcv.foreground = DAGetColor("navy"); | |
268 | 268 | #else |
269 | gcv.foreground = 0; | |
269 | gcv.foreground = 0; | |
270 | 270 | #endif |
271 | colors->black = XCreateGC(DADisplay, d, | |
272 | GCForeground|GCGraphicsExposures, &gcv); | |
273 | ||
274 | /* GC for light borders */ | |
275 | gcv.foreground = DAGetColor("lightGray"); | |
276 | colors->lightGray = XCreateGC(DADisplay, d, | |
277 | GCForeground|GCGraphicsExposures, &gcv); | |
278 | ||
279 | /* GC for dark borders (note re-use of gcv-values) */ | |
280 | gcv.foreground = DAGetColor("#222222"); | |
281 | colors->darkGray = XCreateGC(DADisplay, d, | |
282 | GCForeground|GCGraphicsExposures, &gcv); | |
283 | ||
284 | /* GC for the un-/highlighted colors and dashed line of the slider */ | |
285 | gcv.foreground = origColor; | |
286 | gcv.line_width = 9; | |
287 | gcv.line_style = LineOnOffDash; | |
288 | ||
289 | colors->slider = XCreateGC(DADisplay, d, | |
290 | GCForeground|GCBackground|GCGraphicsExposures| | |
291 | GCLineWidth|GCLineStyle, &gcv); | |
292 | ||
293 | XSetDashes(DADisplay, colors->slider, 1, dashList, 2); | |
294 | ||
295 | /* light slider GC */ | |
296 | gcv.foreground = adjustColor(origColor, +0x40); | |
297 | ||
298 | colors->sliderLight = XCreateGC(DADisplay, d, | |
299 | GCForeground|GCBackground|GCGraphicsExposures| | |
300 | GCLineWidth|GCLineStyle, &gcv); | |
301 | ||
302 | XSetDashes(DADisplay, colors->sliderLight, 1, dashList, 2); | |
303 | ||
304 | /* dark slider GC */ | |
305 | gcv.foreground = adjustColor(origColor, -0x40); | |
306 | ||
307 | colors->sliderDark = XCreateGC(DADisplay, d, | |
308 | GCForeground|GCBackground|GCGraphicsExposures| | |
309 | GCLineWidth|GCLineStyle, &gcv); | |
310 | ||
311 | XSetDashes(DADisplay, colors->sliderDark, 1, dashList, 2); | |
312 | ||
313 | return colors; | |
271 | colors->black = XCreateGC(DADisplay, d, | |
272 | GCForeground | GCGraphicsExposures, &gcv); | |
273 | ||
274 | /* GC for light borders */ | |
275 | gcv.foreground = DAGetColor("lightGray"); | |
276 | colors->lightGray = XCreateGC(DADisplay, d, | |
277 | GCForeground | GCGraphicsExposures, &gcv); | |
278 | ||
279 | /* GC for dark borders (note re-use of gcv-values) */ | |
280 | gcv.foreground = DAGetColor("#222222"); | |
281 | colors->darkGray = XCreateGC(DADisplay, d, | |
282 | GCForeground | GCGraphicsExposures, &gcv); | |
283 | ||
284 | /* GC for the un-/highlighted colors and dashed line of the slider */ | |
285 | gcv.foreground = origColor; | |
286 | gcv.line_width = 9; | |
287 | gcv.line_style = LineOnOffDash; | |
288 | ||
289 | colors->slider = XCreateGC(DADisplay, d, | |
290 | GCForeground | GCBackground | GCGraphicsExposures | | |
291 | GCLineWidth | GCLineStyle, &gcv); | |
292 | ||
293 | XSetDashes(DADisplay, colors->slider, 1, dashList, 2); | |
294 | ||
295 | /* light slider GC */ | |
296 | gcv.foreground = adjustColor(origColor, +0x40); | |
297 | ||
298 | colors->sliderLight = XCreateGC(DADisplay, d, | |
299 | GCForeground | GCBackground | GCGraphicsExposures | | |
300 | GCLineWidth | GCLineStyle, &gcv); | |
301 | ||
302 | XSetDashes(DADisplay, colors->sliderLight, 1, dashList, 2); | |
303 | ||
304 | /* dark slider GC */ | |
305 | gcv.foreground = adjustColor(origColor, -0x40); | |
306 | ||
307 | colors->sliderDark = XCreateGC(DADisplay, d, | |
308 | GCForeground | GCBackground | GCGraphicsExposures | | |
309 | GCLineWidth | GCLineStyle, &gcv); | |
310 | ||
311 | XSetDashes(DADisplay, colors->sliderDark, 1, dashList, 2); | |
312 | ||
313 | return colors; | |
314 | 314 | } |
315 | 315 | |
316 | 316 | |
318 | 318 | unsigned long |
319 | 319 | adjustColor(unsigned long color, signed int adjustment) |
320 | 320 | { |
321 | signed long r, g, b; | |
322 | ||
323 | r = color >> 16; | |
324 | g = (color - (r << 16)) >> 8; | |
325 | b = (color - (g << 8) - (r << 16)); | |
326 | ||
327 | r += adjustment; | |
328 | g += adjustment; | |
329 | b += adjustment; | |
330 | ||
331 | if (r > 0xff) r = 0xff; | |
332 | if (g > 0xff) g = 0xff; | |
333 | if (b > 0xff) b = 0xff; | |
334 | ||
335 | if (r < 0) r = 0; | |
336 | if (g < 0) g = 0; | |
337 | if (b < 0) b = 0; | |
338 | ||
339 | return ((unsigned short)r << 16) + | |
340 | ((unsigned short)g << 8) + | |
341 | (unsigned short)b; | |
321 | signed long r, g, b; | |
322 | ||
323 | r = color >> 16; | |
324 | g = (color - (r << 16)) >> 8; | |
325 | b = (color - (g << 8) - (r << 16)); | |
326 | ||
327 | r += adjustment; | |
328 | g += adjustment; | |
329 | b += adjustment; | |
330 | ||
331 | if (r > 0xff) | |
332 | r = 0xff; | |
333 | ||
334 | if (g > 0xff) | |
335 | g = 0xff; | |
336 | ||
337 | if (b > 0xff) | |
338 | b = 0xff; | |
339 | ||
340 | if (r < 0) | |
341 | r = 0; | |
342 | ||
343 | if (g < 0) | |
344 | g = 0; | |
345 | ||
346 | if (b < 0) | |
347 | b = 0; | |
348 | ||
349 | return ((unsigned short)r << 16) + | |
350 | ((unsigned short)g << 8) + | |
351 | (unsigned short)b; | |
342 | 352 | } |
343 | 353 | |
344 | 354 | |
345 | 355 | void |
346 | 356 | setPointerColor(GC color) |
347 | 357 | { |
348 | XGCValues gcv; | |
349 | XColor fcolor, bcolor; | |
350 | ||
351 | XGetGCValues(DADisplay, color, GCForeground, &gcv); | |
352 | ||
353 | fcolor.pixel = gcv.foreground; | |
354 | fcolor.flags = DoRed|DoGreen|DoBlue; | |
355 | ||
356 | bcolor.red = 0; | |
357 | bcolor.green = 0; | |
358 | bcolor.blue = 0; | |
359 | ||
360 | XRecolorCursor(DADisplay, pointer, &fcolor, &bcolor); | |
358 | XGCValues gcv; | |
359 | XColor fcolor, bcolor; | |
360 | ||
361 | XGetGCValues(DADisplay, color, GCForeground, &gcv); | |
362 | ||
363 | fcolor.pixel = gcv.foreground; | |
364 | fcolor.flags = DoRed | DoGreen | DoBlue; | |
365 | ||
366 | bcolor.red = 0; | |
367 | bcolor.green = 0; | |
368 | bcolor.blue = 0; | |
369 | ||
370 | XRecolorCursor(DADisplay, pointer, &fcolor, &bcolor); | |
361 | 371 | } |
362 | 372 | |
363 | 373 | |
364 | 374 | /* event handlers functions */ |
365 | void destroy(void){} | |
375 | void destroy(void) | |
376 | { | |
377 | } | |
366 | 378 | |
367 | 379 | void buttonPress(int button, int state, int x, int y) |
368 | 380 | { |
369 | int *data = malloc(sizeof(int*)); | |
370 | ||
371 | *data = button; | |
372 | ||
373 | DAProcessActionRects(x, y, actionRects[0], 3, (void*)data); | |
374 | ||
375 | free(data); | |
381 | int *data = malloc(sizeof(int *)); | |
382 | ||
383 | *data = button; | |
384 | ||
385 | DAProcessActionRects(x, y, actionRects[0], 3, (void *)data); | |
386 | ||
387 | free(data); | |
376 | 388 | } |
377 | 389 | |
378 | 390 | void buttonRelease(int button, int state, int x, int y) |
379 | 391 | { |
380 | DAProcessActionRects(x, y, actionRects[1], 2, NULL); | |
392 | DAProcessActionRects(x, y, actionRects[1], 2, NULL); | |
381 | 393 | |
382 | 394 | } |
383 | 395 | |
384 | 396 | void |
385 | 397 | mouseMove(int x, int y) |
386 | 398 | { |
387 | DAProcessActionRects(x, y, actionRects[2], 1, NULL); | |
399 | DAProcessActionRects(x, y, actionRects[2], 1, NULL); | |
388 | 400 | } |
389 | 401 | |
390 | 402 | void |
391 | 403 | mouseEnter(void) |
392 | 404 | { |
393 | mouseIn = 1; | |
394 | ||
395 | drawSlider(actionRects[3][0].rect); | |
405 | mouseIn = 1; | |
406 | ||
407 | drawSlider(actionRects[3][0].rect); | |
396 | 408 | } |
397 | 409 | |
398 | 410 | |
399 | 411 | void |
400 | 412 | mouseLeave(void) |
401 | 413 | { |
402 | mouseIn = 0; | |
403 | ||
404 | /* mouse pointer left the dockapp window */ | |
405 | DAProcessActionRects(0, 0, actionRects[4], 2, NULL); | |
406 | ||
407 | /* if the button is still depressed, make it go up again. */ | |
414 | mouseIn = 0; | |
415 | ||
416 | /* mouse pointer left the dockapp window */ | |
417 | DAProcessActionRects(0, 0, actionRects[4], 2, NULL); | |
418 | ||
419 | /* if the button is still depressed, make it go up again. */ | |
408 | 420 | /* TODO: Use data in actionRects[4] here instead of below check */ |
409 | if (buttonDown != NULL) { | |
410 | btnUp(0, 0, *buttonDown, NULL); | |
411 | } | |
412 | ||
413 | drawSlider(actionRects[4][1].rect); | |
421 | if (buttonDown != NULL) | |
422 | btnUp(0, 0, *buttonDown, NULL); | |
423 | ||
424 | drawSlider(actionRects[4][1].rect); | |
414 | 425 | } |
415 | 426 | |
416 | 427 | /* what to do for a specific event for every 'item' in the dockapp */ |
418 | 429 | void |
419 | 430 | btnDown(int x, int y, DARect rect, void *data) |
420 | 431 | { |
421 | buttonDown = ▭ | |
422 | drawSunkenFrame(rect); | |
432 | buttonDown = ▭ | |
433 | drawSunkenFrame(rect); | |
423 | 434 | } |
424 | 435 | |
425 | 436 | |
426 | 437 | void |
427 | 438 | btnUp(int x, int y, DARect rect, void *data) |
428 | 439 | { |
429 | buttonDown = NULL; | |
430 | drawRaisedFrame(rect); | |
440 | buttonDown = NULL; | |
441 | drawRaisedFrame(rect); | |
431 | 442 | } |
432 | 443 | |
433 | 444 | |
434 | 445 | void |
435 | 446 | btnLeave(int x, int y, DARect rect, void *data) |
436 | 447 | { |
437 | if (buttonDown == NULL) return; | |
438 | drawRaisedFrame(rect); | |
448 | if (buttonDown == NULL) | |
449 | return; | |
450 | ||
451 | drawRaisedFrame(rect); | |
439 | 452 | } |
440 | 453 | |
441 | 454 | |
443 | 456 | void |
444 | 457 | squareDown(int x, int y, DARect rect, void *data) |
445 | 458 | { |
446 | int button; | |
447 | ||
448 | if (data) { | |
449 | int *tmp = (int*)data; | |
450 | ||
451 | button = *tmp; | |
452 | } else | |
453 | button = 0; | |
454 | ||
455 | drawSquare(rect, button); | |
459 | int button; | |
460 | ||
461 | if (data) { | |
462 | int *tmp = (int *)data; | |
463 | ||
464 | button = *tmp; | |
465 | } else | |
466 | button = 0; | |
467 | ||
468 | drawSquare(rect, button); | |
456 | 469 | } |
457 | 470 | |
458 | 471 | |
460 | 473 | void |
461 | 474 | sliderDown(int x, int y, DARect rect, void *data) |
462 | 475 | { |
463 | buttonDown = ▭ | |
464 | setPointerColor(colors->sliderDark); | |
476 | buttonDown = ▭ | |
477 | setPointerColor(colors->sliderDark); | |
465 | 478 | } |
466 | 479 | |
467 | 480 | |
468 | 481 | void |
469 | 482 | sliderUp(int x, int y, DARect rect, void *data) |
470 | 483 | { |
471 | buttonDown = NULL; | |
472 | setPointerColor(colors->black); | |
484 | buttonDown = NULL; | |
485 | setPointerColor(colors->black); | |
473 | 486 | } |
474 | 487 | |
475 | 488 | |
476 | 489 | void |
477 | 490 | sliderMove(int x, int y, DARect rect, void *data) |
478 | 491 | { |
479 | if (buttonDown == NULL /* || | |
480 | rect.x != buttonDown->x || | |
481 | rect.y != buttonDown->y || | |
482 | rect.width != buttonDown->width || | |
483 | rect.height != buttonDown->height */) | |
484 | { | |
485 | return; | |
486 | } | |
487 | ||
488 | sliderPos = (float)(rect.height - y)/(float)rect.height; | |
489 | if (sliderPos > 1.0) sliderPos = 1.0; | |
490 | if (sliderPos < 0.0) sliderPos = 0.0; | |
491 | ||
492 | drawSlider(rect); | |
493 | } | |
494 | ||
495 | void sliderEnter(int x, int y, DARect rect, void *data) {} | |
496 | void sliderLeave(int x, int y, DARect rect, void *data) {} | |
492 | if (buttonDown == NULL /* || | |
493 | rect.x != buttonDown->x || | |
494 | rect.y != buttonDown->y || | |
495 | rect.width != buttonDown->width || | |
496 | rect.height != buttonDown->height */) | |
497 | return; | |
498 | ||
499 | sliderPos = (float)(rect.height - y) / (float)rect.height; | |
500 | if (sliderPos > 1.0) | |
501 | sliderPos = 1.0; | |
502 | ||
503 | if (sliderPos < 0.0) | |
504 | sliderPos = 0.0; | |
505 | ||
506 | drawSlider(rect); | |
507 | } | |
508 | ||
509 | void sliderEnter(int x, int y, DARect rect, void *data) | |
510 | { | |
511 | } | |
512 | void sliderLeave(int x, int y, DARect rect, void *data) | |
513 | { | |
514 | } | |
497 | 515 | |
498 | 516 | |
499 | 517 | |
503 | 521 | void |
504 | 522 | createBtn(DARect rect) |
505 | 523 | { |
506 | /* fill square excluding borders */ | |
507 | XFillRectangle(DADisplay, pixmap, colors->lightGray, | |
508 | rect.x +1, rect.y +1, rect.width -2, rect.height -2); | |
509 | ||
510 | drawRaisedFrame(rect); | |
524 | /* fill square excluding borders */ | |
525 | XFillRectangle(DADisplay, pixmap, colors->lightGray, | |
526 | rect.x + 1, rect.y + 1, rect.width - 2, rect.height - 2); | |
527 | ||
528 | drawRaisedFrame(rect); | |
511 | 529 | } |
512 | 530 | |
513 | 531 | |
514 | 532 | void |
515 | 533 | drawRaisedFrame(DARect rect) |
516 | 534 | { |
517 | /* left border */ | |
518 | XDrawLine(DADisplay, pixmap, colors->white, | |
519 | rect.x, rect.y, rect.x, rect.y + rect.height -2); | |
520 | /* top border */ | |
521 | XDrawLine(DADisplay, pixmap, colors->white, | |
522 | rect.x +1, rect.y, rect.width -1, rect.y); | |
523 | /* bottom border */ | |
524 | XDrawLine(DADisplay, pixmap, colors->darkGray, | |
525 | rect.x, rect.y + rect.height -1, | |
526 | rect.x + rect.width -1, rect.y + rect.height -1); | |
527 | /* right border */ | |
528 | XDrawLine(DADisplay, pixmap, colors->darkGray, | |
529 | rect.x + rect.width -1, rect.y +1, | |
530 | rect.x + rect.width -1, rect.y + rect.height -2); | |
531 | ||
532 | DASetPixmap(pixmap); | |
535 | /* left border */ | |
536 | XDrawLine(DADisplay, pixmap, colors->white, | |
537 | rect.x, rect.y, rect.x, rect.y + rect.height - 2); | |
538 | /* top border */ | |
539 | XDrawLine(DADisplay, pixmap, colors->white, | |
540 | rect.x + 1, rect.y, rect.width - 1, rect.y); | |
541 | /* bottom border */ | |
542 | XDrawLine(DADisplay, pixmap, colors->darkGray, | |
543 | rect.x, rect.y + rect.height - 1, | |
544 | rect.x + rect.width - 1, rect.y + rect.height - 1); | |
545 | /* right border */ | |
546 | XDrawLine(DADisplay, pixmap, colors->darkGray, | |
547 | rect.x + rect.width - 1, rect.y + 1, | |
548 | rect.x + rect.width - 1, rect.y + rect.height - 2); | |
549 | ||
550 | DASetPixmap(pixmap); | |
533 | 551 | } |
534 | 552 | |
535 | 553 | |
536 | 554 | void |
537 | 555 | drawSunkenFrame(DARect rect) |
538 | 556 | { |
539 | /* left border */ | |
540 | XDrawLine(DADisplay, pixmap, colors->darkGray, | |
541 | rect.x, rect.y, rect.x, rect.y + rect.height -2); | |
542 | /* top border */ | |
543 | XDrawLine(DADisplay, pixmap, colors->darkGray, | |
544 | rect.x +1, rect.y, rect.width -1, rect.y); | |
545 | /* bottom border */ | |
546 | XDrawLine(DADisplay, pixmap, colors->white, | |
547 | rect.x, rect.y + rect.height -1, | |
548 | rect.x + rect.width -1, rect.y + rect.height -1); | |
549 | /* right border */ | |
550 | XDrawLine(DADisplay, pixmap, colors->white, | |
551 | rect.x + rect.width -1, rect.y +1, | |
552 | rect.x + rect.width -1, rect.y + rect.height -2); | |
553 | ||
554 | DASetPixmap(pixmap); | |
557 | /* left border */ | |
558 | XDrawLine(DADisplay, pixmap, colors->darkGray, | |
559 | rect.x, rect.y, rect.x, rect.y + rect.height - 2); | |
560 | /* top border */ | |
561 | XDrawLine(DADisplay, pixmap, colors->darkGray, | |
562 | rect.x + 1, rect.y, rect.width - 1, rect.y); | |
563 | /* bottom border */ | |
564 | XDrawLine(DADisplay, pixmap, colors->white, | |
565 | rect.x, rect.y + rect.height - 1, | |
566 | rect.x + rect.width - 1, rect.y + rect.height - 1); | |
567 | /* right border */ | |
568 | XDrawLine(DADisplay, pixmap, colors->white, | |
569 | rect.x + rect.width - 1, rect.y + 1, | |
570 | rect.x + rect.width - 1, rect.y + rect.height - 2); | |
571 | ||
572 | DASetPixmap(pixmap); | |
555 | 573 | } |
556 | 574 | |
557 | 575 | |
558 | 576 | void |
559 | 577 | createSquare(DARect rect) |
560 | 578 | { |
561 | /* fill square excluding borders */ | |
562 | XFillRectangle(DADisplay, pixmap, colors->black, | |
563 | rect.x +1, rect.y +1, rect.width -2, rect.height -2); | |
564 | ||
565 | XDrawRectangle(DADisplay, pixmap, colors->lightGray, | |
566 | rect.x, rect.y, rect.width -1, rect.height -1); | |
567 | ||
568 | drawSquare(rect, 0); | |
579 | /* fill square excluding borders */ | |
580 | XFillRectangle(DADisplay, pixmap, colors->black, | |
581 | rect.x + 1, rect.y + 1, rect.width - 2, rect.height - 2); | |
582 | ||
583 | XDrawRectangle(DADisplay, pixmap, colors->lightGray, | |
584 | rect.x, rect.y, rect.width - 1, rect.height - 1); | |
585 | ||
586 | drawSquare(rect, 0); | |
569 | 587 | } |
570 | 588 | |
571 | 589 | |
572 | 590 | void |
573 | 591 | drawSquare(DARect rect, int button) |
574 | 592 | { |
575 | char label[3]; | |
576 | ||
577 | XFillRectangle(DADisplay, pixmap, colors->black, | |
578 | rect.x +1, rect.y +1, rect.width -2, rect.height -2); | |
579 | ||
580 | snprintf(label, 3, "%2d", button); | |
581 | XDrawString(DADisplay, pixmap, colors->white, | |
582 | rect.x +3, rect.y + rect.height -5, label, 2); | |
583 | ||
584 | DASetPixmap(pixmap); | |
593 | char label[3]; | |
594 | ||
595 | XFillRectangle(DADisplay, pixmap, colors->black, | |
596 | rect.x + 1, rect.y + 1, rect.width - 2, rect.height - 2); | |
597 | ||
598 | snprintf(label, 3, "%2d", button); | |
599 | XDrawString(DADisplay, pixmap, colors->white, | |
600 | rect.x + 3, rect.y + rect.height - 5, label, 2); | |
601 | ||
602 | DASetPixmap(pixmap); | |
585 | 603 | } |
586 | 604 | |
587 | 605 | |
588 | 606 | void |
589 | 607 | createSlider(DARect rect) |
590 | 608 | { |
591 | /* fill square excluding borders */ | |
592 | XFillRectangle(DADisplay, pixmap, colors->black, | |
593 | rect.x +1, rect.y +1, rect.width -2, rect.height -2); | |
594 | ||
595 | drawSunkenFrame(rect); | |
596 | ||
597 | drawSlider(rect); | |
609 | /* fill square excluding borders */ | |
610 | XFillRectangle(DADisplay, pixmap, colors->black, | |
611 | rect.x + 1, rect.y + 1, rect.width - 2, rect.height - 2); | |
612 | ||
613 | drawSunkenFrame(rect); | |
614 | ||
615 | drawSlider(rect); | |
598 | 616 | } |
599 | 617 | |
600 | 618 | |
601 | 619 | void |
602 | 620 | drawSlider(DARect rect) |
603 | 621 | { |
604 | GC highColor, lowColor; /* determine colors to use */ | |
605 | ||
606 | if (mouseIn) { | |
607 | highColor = colors->sliderLight; | |
608 | lowColor = colors->slider; | |
609 | } else { | |
610 | highColor = colors->slider; | |
611 | lowColor = colors->sliderDark; | |
612 | } | |
613 | ||
614 | /* Draw two lines from bottom to sliderPos fraction of height */ | |
615 | if (sliderPos < 1.0) { | |
616 | XDrawLine(DADisplay, pixmap, highColor, | |
617 | rect.x + 6, rect.y + rect.height -2, | |
618 | rect.x + 6, rect.y + (1.0 - sliderPos) * (rect.height -2)); | |
619 | ||
620 | XDrawLine(DADisplay, pixmap, highColor, | |
621 | rect.x + 17, rect.y + rect.height -2, | |
622 | rect.x + 17, rect.y + (1.0 - sliderPos) * (rect.height -2)); | |
623 | } | |
624 | ||
625 | if (sliderPos > 0.0) { | |
626 | XDrawLine(DADisplay, pixmap, lowColor, | |
627 | rect.x + 6, rect.y +1, | |
628 | rect.x + 6, rect.y + (1.0 - sliderPos) * (rect.height -2)); | |
629 | ||
630 | XDrawLine(DADisplay, pixmap, lowColor, | |
631 | rect.x + 17, rect.y +1, | |
632 | rect.x + 17, rect.y + (1.0 - sliderPos) * (rect.height -2)); | |
633 | } | |
634 | ||
635 | DASetPixmap(pixmap); | |
622 | GC highColor, lowColor; /* determine colors to use */ | |
623 | ||
624 | if (mouseIn) { | |
625 | highColor = colors->sliderLight; | |
626 | lowColor = colors->slider; | |
627 | } else { | |
628 | highColor = colors->slider; | |
629 | lowColor = colors->sliderDark; | |
630 | } | |
631 | ||
632 | /* Draw two lines from bottom to sliderPos fraction of height */ | |
633 | if (sliderPos < 1.0) { | |
634 | XDrawLine(DADisplay, pixmap, highColor, | |
635 | rect.x + 6, rect.y + rect.height - 2, | |
636 | rect.x + 6, rect.y + (1.0 - sliderPos) * (rect.height - 2)); | |
637 | ||
638 | XDrawLine(DADisplay, pixmap, highColor, | |
639 | rect.x + 17, rect.y + rect.height - 2, | |
640 | rect.x + 17, rect.y + (1.0 - sliderPos) * (rect.height - 2)); | |
641 | } | |
642 | ||
643 | if (sliderPos > 0.0) { | |
644 | XDrawLine(DADisplay, pixmap, lowColor, | |
645 | rect.x + 6, rect.y + 1, | |
646 | rect.x + 6, rect.y + (1.0 - sliderPos) * (rect.height - 2)); | |
647 | ||
648 | XDrawLine(DADisplay, pixmap, lowColor, | |
649 | rect.x + 17, rect.y + 1, | |
650 | rect.x + 17, rect.y + (1.0 - sliderPos) * (rect.height - 2)); | |
651 | } | |
652 | ||
653 | DASetPixmap(pixmap); | |
636 | 654 | } |
637 | 655 | |
638 | 656 | |
639 | 657 | DAActionRect |
640 | 658 | setRectAction(DARect rect, DARectCallback action) |
641 | 659 | { |
642 | DAActionRect ar; | |
643 | ||
644 | ar.rect = rect; | |
645 | ar.action = action; | |
646 | ||
647 | return ar; | |
648 | } | |
649 | ||
660 | DAActionRect ar; | |
661 | ||
662 | ar.rect = rect; | |
663 | ar.action = action; | |
664 | ||
665 | return ar; | |
666 | } | |
667 |
33 | 33 | * Prototypes |
34 | 34 | */ |
35 | 35 | |
36 | static void _daContextAddDefaultOptions(); | |
36 | static void _daContextAddDefaultOptions(void); | |
37 | 37 | static void _daContextAddOptions(DAProgramOption *options, int count); |
38 | 38 | static void printHelp(char *description); |
39 | 39 | |
40 | 40 | int contains(char *needle, char *haystack); |
41 | int parseOption(DAProgramOption *option, int i, int argc, char** argv); | |
41 | int parseOption(DAProgramOption *option, int i, int argc, char **argv); | |
42 | 42 | int readIntOption(int index, char **argv); |
43 | 43 | |
44 | 44 | /* |
54 | 54 | char *programDescription, |
55 | 55 | char *versionDescription) |
56 | 56 | { |
57 | int i, j, size; | |
58 | int found = 0; | |
59 | ||
60 | _daContext = DAContextInit(); | |
61 | ||
62 | _daContext->argc = argc; | |
63 | _daContext->argv = argv; | |
64 | _daContext->programName = argv[0]; | |
65 | ||
66 | size = (count + DEFAULT_OPTION_COUNT) * sizeof(DAProgramOption*); | |
67 | _daContext->options = malloc(size); | |
68 | memset(_daContext->options, 0, size); | |
69 | ||
70 | _daContextAddDefaultOptions(); | |
71 | _daContextAddOptions(options, count); | |
72 | ||
73 | for (i = 1; i < argc; i++) { | |
74 | char *optStr = argv[i]; | |
75 | ||
76 | /* Handle default options */ | |
77 | if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) | |
78 | printHelp(programDescription), exit(0); | |
79 | ||
80 | if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) | |
81 | puts(versionDescription), exit(0); | |
82 | ||
83 | if (strcmp(argv[i], "-w") == 0 || strcmp(argv[i], "--windowed") == 0) { | |
84 | _daContext->windowed = 1; | |
85 | continue; | |
86 | } | |
87 | ||
88 | found = 0; | |
89 | /* options with a one-to-one mapping */ | |
90 | for (j = 0; j < count; j++) { | |
91 | DAProgramOption *option = &options[j]; | |
92 | ||
93 | if ((option->longForm && strcmp(option->longForm, optStr) == 0) | |
94 | || (option->shortForm && strcmp(option->shortForm, optStr) == 0)) { | |
95 | ||
96 | found = 1; | |
97 | i = parseOption(option, i, argc, argv); | |
98 | } | |
99 | } | |
100 | ||
101 | /* mixed options */ | |
102 | if (!found) { | |
103 | /* XXX: Parsing all options again... */ | |
104 | for (j = 0; j < count; j++) { | |
105 | DAProgramOption *option = &options[j]; | |
106 | ||
107 | if (option->shortForm && contains(option->shortForm, optStr)) { | |
108 | found = 1; | |
109 | i = parseOption(option, i, argc, argv); | |
57 | int i, j, size; | |
58 | int found = 0; | |
59 | ||
60 | _daContext = DAContextInit(); | |
61 | ||
62 | _daContext->argc = argc; | |
63 | _daContext->argv = argv; | |
64 | _daContext->programName = argv[0]; | |
65 | ||
66 | size = (count + DEFAULT_OPTION_COUNT) * sizeof(DAProgramOption *); | |
67 | _daContext->options = malloc(size); | |
68 | memset(_daContext->options, 0, size); | |
69 | ||
70 | _daContextAddDefaultOptions(); | |
71 | _daContextAddOptions(options, count); | |
72 | ||
73 | for (i = 1; i < argc; i++) { | |
74 | char *optStr = argv[i]; | |
75 | ||
76 | /* Handle default options */ | |
77 | if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) | |
78 | printHelp(programDescription), exit(0); | |
79 | ||
80 | if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) | |
81 | puts(versionDescription), exit(0); | |
82 | ||
83 | if (strcmp(argv[i], "-w") == 0 || strcmp(argv[i], "--windowed") == 0) { | |
84 | _daContext->windowed = 1; | |
85 | continue; | |
110 | 86 | } |
111 | } | |
112 | } | |
113 | ||
114 | if (!found) { | |
115 | printf("%s: unrecognized option '%s'\n", argv[0], argv[i]); | |
116 | printHelp(programDescription), exit(1); | |
117 | } | |
118 | } | |
87 | ||
88 | found = 0; | |
89 | /* options with a one-to-one mapping */ | |
90 | for (j = 0; j < count; j++) { | |
91 | DAProgramOption *option = &options[j]; | |
92 | ||
93 | if ((option->longForm && strcmp(option->longForm, optStr) == 0) | |
94 | || (option->shortForm && strcmp(option->shortForm, optStr) == 0)) { | |
95 | ||
96 | found = 1; | |
97 | i = parseOption(option, i, argc, argv); | |
98 | } | |
99 | } | |
100 | ||
101 | /* mixed options */ | |
102 | if (!found) | |
103 | /* XXX: Parsing all options again... */ | |
104 | for (j = 0; j < count; j++) { | |
105 | DAProgramOption *option = &options[j]; | |
106 | ||
107 | if (option->shortForm && contains(option->shortForm, optStr)) { | |
108 | found = 1; | |
109 | i = parseOption(option, i, argc, argv); | |
110 | } | |
111 | } | |
112 | ||
113 | if (!found) { | |
114 | printf("%s: unrecognized option '%s'\n", argv[0], argv[i]); | |
115 | printHelp(programDescription), exit(1); | |
116 | } | |
117 | } | |
119 | 118 | } |
120 | 119 | |
121 | 120 | int |
122 | 121 | contains(char *needle, char *haystack) |
123 | 122 | { |
124 | char c, *pos; | |
125 | ||
126 | assert(strlen(needle) == 2); | |
127 | ||
128 | c = needle[1]; | |
129 | ||
130 | pos = strchr(haystack, c); | |
131 | ||
132 | return (pos != NULL); | |
123 | char c, *pos; | |
124 | ||
125 | assert(strlen(needle) == 2); | |
126 | ||
127 | c = needle[1]; | |
128 | ||
129 | pos = strchr(haystack, c); | |
130 | ||
131 | return (pos != NULL); | |
133 | 132 | } |
134 | 133 | |
135 | 134 | int |
136 | parseOption(DAProgramOption *option, int i, int argc, char** argv) | |
137 | { | |
138 | option->used = True; | |
139 | ||
140 | if (option->type == DONone) | |
135 | parseOption(DAProgramOption *option, int i, int argc, char **argv) | |
136 | { | |
137 | option->used = True; | |
138 | ||
139 | if (option->type == DONone) | |
140 | return i; | |
141 | ||
142 | i++; | |
143 | if (i >= argc) | |
144 | printf("%s: missing argument for option '%s'\n", | |
145 | argv[0], | |
146 | argv[i-1]), | |
147 | exit(1); | |
148 | ||
149 | switch (option->type) { | |
150 | case DOInteger: | |
151 | *option->value.integer = readIntOption(i, argv); | |
152 | ||
153 | break; | |
154 | ||
155 | case DONatural: | |
156 | *option->value.integer = readIntOption(i, argv); | |
157 | ||
158 | if (*option->value.integer < 0) | |
159 | printf("%s: argument %s must be >= 0\n", | |
160 | argv[0], | |
161 | argv[i-1]), | |
162 | exit(1); | |
163 | break; | |
164 | ||
165 | case DOString: | |
166 | *option->value.string = argv[i]; | |
167 | break; | |
168 | } | |
169 | ||
141 | 170 | return i; |
142 | ||
143 | i++; | |
144 | if (i >= argc) | |
145 | printf("%s: missing argument for option '%s'\n", | |
146 | argv[0], | |
147 | argv[i-1]), | |
148 | exit(1); | |
149 | ||
150 | switch (option->type) { | |
151 | case DOInteger: | |
152 | *option->value.integer = readIntOption(i, argv); | |
153 | ||
154 | break; | |
155 | ||
156 | case DONatural: | |
157 | *option->value.integer = readIntOption(i, argv); | |
158 | ||
159 | if (*option->value.integer < 0) | |
160 | printf("%s: argument %s must be >= 0\n", | |
161 | argv[0], | |
162 | argv[i-1]), | |
163 | exit(1); | |
164 | break; | |
165 | ||
166 | case DOString: | |
167 | *option->value.string = argv[i]; | |
168 | break; | |
169 | } | |
170 | ||
171 | return i; | |
172 | 171 | } |
173 | 172 | |
174 | 173 | int |
175 | 174 | readIntOption(int index, char **argv) |
176 | 175 | { |
177 | int integer; | |
178 | ||
179 | if (sscanf(argv[index], "%i", &integer) != 1) | |
180 | DAError("error parsing argument for option %s\n", argv[index-1]), | |
181 | exit(1); | |
182 | ||
183 | return integer; | |
176 | int integer; | |
177 | ||
178 | if (sscanf(argv[index], "%i", &integer) != 1) | |
179 | DAError("error parsing argument for option %s\n", argv[index-1]), | |
180 | exit(1); | |
181 | ||
182 | return integer; | |
184 | 183 | } |
185 | 184 | |
186 | 185 | int |
187 | 186 | DAGetArgC() |
188 | 187 | { |
189 | return _daContext->argc; | |
190 | } | |
191 | ||
192 | char** | |
188 | return _daContext->argc; | |
189 | } | |
190 | ||
191 | char ** | |
193 | 192 | DAGetArgV() |
194 | 193 | { |
195 | return _daContext->argv; | |
196 | } | |
197 | ||
198 | char* | |
194 | return _daContext->argv; | |
195 | } | |
196 | ||
197 | char * | |
199 | 198 | DAGetProgramName() |
200 | 199 | { |
201 | return _daContext->programName; | |
200 | return _daContext->programName; | |
202 | 201 | } |
203 | 202 | |
204 | 203 | |
206 | 205 | * Local functions |
207 | 206 | */ |
208 | 207 | |
209 | struct DAContext* | |
210 | DAContextInit() | |
211 | { | |
212 | struct DAContext *context = malloc(sizeof(struct DAContext)); | |
213 | ||
214 | memset(context, 0, sizeof(struct DAContext)); | |
215 | ||
216 | return context; | |
208 | struct DAContext * | |
209 | DAContextInit(void) | |
210 | { | |
211 | struct DAContext *context = malloc(sizeof(struct DAContext)); | |
212 | ||
213 | memset(context, 0, sizeof(struct DAContext)); | |
214 | ||
215 | return context; | |
217 | 216 | } |
218 | 217 | |
219 | 218 | void |
220 | DAFreeContext() | |
221 | { | |
222 | if (_daContext->optionCount > 0) { | |
219 | DAFreeContext(void) | |
220 | { | |
221 | if (_daContext->optionCount > 0) { | |
222 | int i; | |
223 | ||
224 | for (i = 0; i < _daContext->optionCount; i++) | |
225 | free(_daContext->options[i]); | |
226 | ||
227 | free(_daContext->options); | |
228 | } | |
229 | ||
230 | free(_daContext); | |
231 | } | |
232 | ||
233 | static void | |
234 | _daContextAddOption(DAProgramOption *option) | |
235 | { | |
236 | /* If the buffer is full, double its size */ | |
237 | if (sizeof(_daContext->options) == _daContext->optionCount * sizeof(DAProgramOption)) { | |
238 | DAProgramOption **options; | |
239 | ||
240 | options = (DAProgramOption **)realloc( | |
241 | (DAProgramOption **)_daContext->options, | |
242 | 2 * sizeof(_daContext->options)); | |
243 | ||
244 | if (options == NULL) | |
245 | DAError("Out of memory"); | |
246 | ||
247 | _daContext->options = options; | |
248 | } | |
249 | ||
250 | _daContext->options[_daContext->optionCount] = option; | |
251 | _daContext->optionCount++; | |
252 | } | |
253 | ||
254 | static void | |
255 | _daContextAddOptionData(char *shortForm, char *longForm, | |
256 | char *description, short type) | |
257 | { | |
258 | DAProgramOption *option = malloc(sizeof(DAProgramOption)); | |
259 | ||
260 | option->shortForm = shortForm; | |
261 | option->longForm = longForm; | |
262 | option->description = description; | |
263 | option->type = type; | |
264 | option->used = False; | |
265 | option->value.ptr = NULL; | |
266 | ||
267 | _daContextAddOption(option); | |
268 | } | |
269 | ||
270 | static void | |
271 | _daContextAddDefaultOptions(void) | |
272 | { | |
273 | _daContextAddOptionData("-h", "--help", "show this help text and exit", DONone); | |
274 | _daContextAddOptionData("-v", "--version", "show program version and exit", DONone); | |
275 | _daContextAddOptionData("-w", "--windowed", "run the application in windowed mode", DONone); | |
276 | } | |
277 | ||
278 | static void | |
279 | _daContextAddOptions(DAProgramOption *options, int count) | |
280 | { | |
223 | 281 | int i; |
224 | 282 | |
225 | for (i = 0; i < _daContext->optionCount; i++) { | |
226 | free(_daContext->options[i]); | |
227 | } | |
228 | ||
229 | free(_daContext->options); | |
230 | } | |
231 | ||
232 | free(_daContext); | |
233 | } | |
234 | ||
235 | static void | |
236 | _daContextAddOption(DAProgramOption *option) | |
237 | { | |
238 | /* If the buffer is full, double its size */ | |
239 | if (sizeof(_daContext->options) == _daContext->optionCount * sizeof(DAProgramOption)) | |
240 | { | |
241 | DAProgramOption **options; | |
242 | ||
243 | options = (DAProgramOption**)realloc( | |
244 | (DAProgramOption**)_daContext->options, | |
245 | 2 * sizeof(_daContext->options)); | |
246 | ||
247 | if (options == NULL) | |
248 | DAError("Out of memory"); | |
249 | ||
250 | _daContext->options = options; | |
251 | } | |
252 | ||
253 | _daContext->options[_daContext->optionCount] = option; | |
254 | _daContext->optionCount++; | |
255 | } | |
256 | ||
257 | static void | |
258 | _daContextAddOptionData(char *shortForm, char *longForm, | |
259 | char *description, short type) | |
260 | { | |
261 | DAProgramOption *option = malloc(sizeof(DAProgramOption)); | |
262 | ||
263 | option->shortForm = shortForm; | |
264 | option->longForm = longForm; | |
265 | option->description = description; | |
266 | option->type = type; | |
267 | option->used = False; | |
268 | option->value.ptr = NULL; | |
269 | ||
270 | _daContextAddOption(option); | |
271 | } | |
272 | ||
273 | static void | |
274 | _daContextAddDefaultOptions() | |
275 | { | |
276 | _daContextAddOptionData("-h", "--help", "show this help text and exit", DONone); | |
277 | _daContextAddOptionData("-v", "--version", "show program version and exit", DONone); | |
278 | _daContextAddOptionData("-w", "--windowed", "run the application in windowed mode", DONone); | |
279 | } | |
280 | ||
281 | static void | |
282 | _daContextAddOptions(DAProgramOption *options, int count) | |
283 | { | |
284 | int i; | |
285 | ||
286 | for (i = 0; i < count; i++) { | |
287 | _daContextAddOptionData( | |
288 | options[i].shortForm, | |
289 | options[i].longForm, | |
290 | options[i].description, | |
291 | options[i].type); | |
292 | } | |
283 | for (i = 0; i < count; i++) | |
284 | _daContextAddOptionData( | |
285 | options[i].shortForm, | |
286 | options[i].longForm, | |
287 | options[i].description, | |
288 | options[i].type); | |
293 | 289 | } |
294 | 290 | |
295 | 291 | static void |
296 | 292 | printHelp(char *description) |
297 | 293 | { |
298 | int i; | |
299 | DAProgramOption **options = _daContext->options; | |
300 | int count = _daContext->optionCount; | |
301 | ||
302 | printf("Usage: %s [OPTIONS]\n", _daContext->programName); | |
303 | if (description) | |
304 | puts(description); | |
305 | ||
306 | for (i = 0; i < count; i++) | |
307 | { | |
308 | char blank[30]; | |
309 | int c; | |
310 | ||
311 | if (options[i]->shortForm && options[i]->longForm) | |
312 | c = printf(" %s, %s", options[i]->shortForm, options[i]->longForm); | |
313 | else if (options[i]->shortForm) | |
314 | c = printf(" %s", options[i]->shortForm); | |
315 | else if (options[i]->longForm) | |
316 | c = printf(" %s", options[i]->longForm); | |
317 | else | |
318 | continue; | |
319 | ||
320 | if (options[i]->type != DONone) { | |
321 | switch (options[i]->type) { | |
322 | case DOInteger: | |
323 | c += printf(" <integer>"); | |
324 | break; | |
325 | case DOString: | |
326 | c += printf(" <string>"); | |
327 | break; | |
328 | case DONatural: | |
329 | c += printf(" <number>"); | |
330 | break; | |
331 | } | |
332 | } | |
333 | ||
334 | memset(blank, ' ', 30); | |
335 | if (c > 29) | |
336 | c = 1; | |
337 | blank[30-c] = 0; | |
338 | printf("%s %s\n", blank, options[i]->description); | |
339 | } | |
340 | } | |
341 | ||
342 | ||
343 | ||
294 | int i; | |
295 | DAProgramOption **options = _daContext->options; | |
296 | int count = _daContext->optionCount; | |
297 | ||
298 | printf("Usage: %s [OPTIONS]\n", _daContext->programName); | |
299 | if (description) | |
300 | puts(description); | |
301 | ||
302 | for (i = 0; i < count; i++) { | |
303 | char blank[30]; | |
304 | int c; | |
305 | ||
306 | if (options[i]->shortForm && options[i]->longForm) | |
307 | c = printf(" %s, %s", options[i]->shortForm, options[i]->longForm); | |
308 | else if (options[i]->shortForm) | |
309 | c = printf(" %s", options[i]->shortForm); | |
310 | else if (options[i]->longForm) | |
311 | c = printf(" %s", options[i]->longForm); | |
312 | else | |
313 | continue; | |
314 | ||
315 | if (options[i]->type != DONone) { | |
316 | switch (options[i]->type) { | |
317 | case DOInteger: | |
318 | c += printf(" <integer>"); | |
319 | break; | |
320 | case DOString: | |
321 | c += printf(" <string>"); | |
322 | break; | |
323 | case DONatural: | |
324 | c += printf(" <number>"); | |
325 | break; | |
326 | } | |
327 | } | |
328 | ||
329 | memset(blank, ' ', 30); | |
330 | if (c > 29) | |
331 | c = 1; | |
332 | blank[30-c] = 0; | |
333 | printf("%s %s\n", blank, options[i]->description); | |
334 | } | |
335 | } | |
336 | ||
337 | ||
338 |
25 | 25 | * Context structure to keep track of globals |
26 | 26 | */ |
27 | 27 | struct DAContext { |
28 | int argc; /* Raw input data */ | |
29 | char **argv; | |
28 | int argc; /* Raw input data */ | |
29 | char **argv; | |
30 | 30 | |
31 | int windowed; | |
32 | int width, height; | |
33 | int timeOut; | |
31 | int windowed; | |
32 | int width, height; | |
33 | int timeOut; | |
34 | 34 | |
35 | DACallbacks callbacks; | |
35 | DACallbacks callbacks; | |
36 | 36 | |
37 | char *programName; /* shortcut to argv[0] */ | |
37 | char *programName; /* shortcut to argv[0] */ | |
38 | 38 | |
39 | DAProgramOption **options; /* Array of option pointers */ | |
40 | short optionCount; | |
39 | DAProgramOption **options; /* Array of option pointers */ | |
40 | short optionCount; | |
41 | 41 | }; |
42 | 42 | |
43 | 43 | |
44 | struct DAContext* DAContextInit(); | |
45 | void DAFreeContext(); | |
44 | struct DAContext *DAContextInit(void); | |
45 | void DAFreeContext(void); | |
46 | 46 |
27 | 27 | void |
28 | 28 | DASetCallbacks(DACallbacks *callbacks) |
29 | 29 | { |
30 | long mask = 0; | |
30 | long mask = 0; | |
31 | 31 | |
32 | _daContext->callbacks = *callbacks; | |
32 | _daContext->callbacks = *callbacks; | |
33 | 33 | |
34 | if (callbacks->destroy) | |
35 | mask |= StructureNotifyMask; | |
36 | if (callbacks->buttonPress) | |
37 | mask |= ButtonPressMask; | |
38 | if (callbacks->buttonRelease) | |
39 | mask |= ButtonReleaseMask; | |
40 | if (callbacks->motion) | |
41 | mask |= PointerMotionMask; | |
42 | if (callbacks->enter) | |
43 | mask |= EnterWindowMask; | |
44 | if (callbacks->leave) | |
45 | mask |= LeaveWindowMask; | |
34 | if (callbacks->destroy) | |
35 | mask |= StructureNotifyMask; | |
36 | if (callbacks->buttonPress) | |
37 | mask |= ButtonPressMask; | |
38 | if (callbacks->buttonRelease) | |
39 | mask |= ButtonReleaseMask; | |
40 | if (callbacks->motion) | |
41 | mask |= PointerMotionMask; | |
42 | if (callbacks->enter) | |
43 | mask |= EnterWindowMask; | |
44 | if (callbacks->leave) | |
45 | mask |= LeaveWindowMask; | |
46 | 46 | |
47 | XSelectInput(DADisplay, DAWindow, mask); | |
48 | XFlush(DADisplay); | |
47 | XSelectInput(DADisplay, DAWindow, mask); | |
48 | XFlush(DADisplay); | |
49 | 49 | } |
50 | 50 | |
51 | 51 | void |
52 | 52 | DASetTimeout(int milliseconds) |
53 | 53 | { |
54 | _daContext->timeOut = milliseconds; | |
54 | _daContext->timeOut = milliseconds; | |
55 | 55 | } |
56 | 56 |
28 | 28 | unsigned long |
29 | 29 | DAGetColor(char *colorName) |
30 | 30 | { |
31 | XColor color; | |
31 | XColor color; | |
32 | 32 | |
33 | if (!XParseColor(DADisplay, | |
34 | DefaultColormap(DADisplay, DefaultScreen(DADisplay)), | |
35 | colorName, &color)) | |
36 | DAError("could not parse color %s", colorName); | |
33 | if (!XParseColor(DADisplay, | |
34 | DefaultColormap(DADisplay, DefaultScreen(DADisplay)), | |
35 | colorName, &color)) | |
36 | DAError("could not parse color %s", colorName); | |
37 | 37 | |
38 | if (!XAllocColor(DADisplay, DefaultColormap(DADisplay, DefaultScreen(DADisplay)), &color)) { | |
39 | DAWarning("could not allocate color %s. Using black instead", colorName); | |
40 | return BlackPixel(DADisplay, DefaultScreen(DADisplay)); | |
41 | } | |
38 | if (!XAllocColor(DADisplay, DefaultColormap(DADisplay, DefaultScreen(DADisplay)), &color)) { | |
39 | DAWarning("could not allocate color %s. Using black instead", colorName); | |
40 | return BlackPixel(DADisplay, DefaultScreen(DADisplay)); | |
41 | } | |
42 | 42 | |
43 | return color.pixel; | |
43 | return color.pixel; | |
44 | 44 | } |
45 | 45 |
28 | 28 | #include "daargs.h" |
29 | 29 | #include "dautil.h" |
30 | 30 | |
31 | extern struct DAContext *_daContext; | |
32 | extern Atom WM_DELETE_WINDOW; | |
31 | extern struct DAContext *_daContext; | |
32 | extern Atom WM_DELETE_WINDOW; | |
33 | 33 | |
34 | 34 | Bool |
35 | 35 | DAProcessEvent(XEvent *event) |
36 | 36 | { |
37 | if (event->xany.window == DAWindow) | |
38 | return DAProcessEventForWindow(DAWindow, event); | |
39 | else if (event->xany.window == DALeader) | |
40 | /* XXX: Is this superfluous now that DAWindow always references the | |
41 | * dockapp window? | |
42 | */ | |
43 | return DAProcessEventForWindow(DALeader, event); | |
44 | else | |
45 | /* XXX: What about handling events for child windows? */ | |
46 | return False; | |
37 | if (event->xany.window == DAWindow) | |
38 | return DAProcessEventForWindow(DAWindow, event); | |
39 | else if (event->xany.window == DALeader) | |
40 | /* XXX: Is this superfluous now that DAWindow always references the | |
41 | * dockapp window? | |
42 | */ | |
43 | return DAProcessEventForWindow(DALeader, event); | |
44 | else | |
45 | /* XXX: What about handling events for child windows? */ | |
46 | return False; | |
47 | 47 | } |
48 | 48 | |
49 | 49 | Bool |
50 | 50 | DAProcessEventForWindow(Window window, XEvent *event) |
51 | 51 | { |
52 | if (event->xany.window != window) | |
53 | return False; | |
52 | if (event->xany.window != window) | |
53 | return False; | |
54 | 54 | |
55 | switch (event->type) { | |
55 | switch (event->type) { | |
56 | 56 | case ClientMessage: |
57 | if (event->xclient.data.l[0] != WM_DELETE_WINDOW) { | |
58 | break; | |
59 | } | |
60 | /* fallthrough */ | |
57 | if (event->xclient.data.l[0] != WM_DELETE_WINDOW) | |
58 | break; | |
59 | /* fallthrough */ | |
61 | 60 | case DestroyNotify: |
62 | if (_daContext->callbacks.destroy) | |
63 | (*_daContext->callbacks.destroy)(); | |
61 | if (_daContext->callbacks.destroy) | |
62 | (*_daContext->callbacks.destroy)(); | |
64 | 63 | |
65 | DAFreeContext(); | |
66 | XCloseDisplay(DADisplay); | |
64 | DAFreeContext(); | |
65 | XCloseDisplay(DADisplay); | |
67 | 66 | #ifdef DEBUG |
68 | debug("%s: DestroyNotify\n", _daContext->programName); | |
67 | debug("%s: DestroyNotify\n", _daContext->programName); | |
69 | 68 | #endif |
70 | 69 | |
71 | exit(0); | |
72 | break; | |
70 | exit(0); | |
71 | break; | |
73 | 72 | case ButtonPress: |
74 | if (_daContext->callbacks.buttonPress) | |
75 | (*_daContext->callbacks.buttonPress)(event->xbutton.button, | |
76 | event->xbutton.state, | |
77 | event->xbutton.x, | |
78 | event->xbutton.y); | |
79 | break; | |
73 | if (_daContext->callbacks.buttonPress) | |
74 | (*_daContext->callbacks.buttonPress)(event->xbutton.button, | |
75 | event->xbutton.state, | |
76 | event->xbutton.x, | |
77 | event->xbutton.y); | |
78 | break; | |
80 | 79 | case ButtonRelease: |
81 | if (_daContext->callbacks.buttonRelease) | |
82 | (*_daContext->callbacks.buttonRelease)(event->xbutton.button, | |
83 | event->xbutton.state, | |
84 | event->xbutton.x, | |
85 | event->xbutton.y); | |
86 | break; | |
80 | if (_daContext->callbacks.buttonRelease) | |
81 | (*_daContext->callbacks.buttonRelease)(event->xbutton.button, | |
82 | event->xbutton.state, | |
83 | event->xbutton.x, | |
84 | event->xbutton.y); | |
85 | break; | |
87 | 86 | case MotionNotify: |
88 | if (_daContext->callbacks.motion) | |
89 | (*_daContext->callbacks.motion)(event->xmotion.x, | |
90 | event->xmotion.y); | |
91 | break; | |
87 | if (_daContext->callbacks.motion) | |
88 | (*_daContext->callbacks.motion)(event->xmotion.x, | |
89 | event->xmotion.y); | |
90 | break; | |
92 | 91 | case EnterNotify: |
93 | if (_daContext->callbacks.enter) | |
94 | (*_daContext->callbacks.enter)(); | |
95 | break; | |
92 | if (_daContext->callbacks.enter) | |
93 | (*_daContext->callbacks.enter)(); | |
94 | break; | |
96 | 95 | case LeaveNotify: |
97 | if (_daContext->callbacks.leave) | |
98 | (*_daContext->callbacks.leave)(); | |
99 | break; | |
96 | if (_daContext->callbacks.leave) | |
97 | (*_daContext->callbacks.leave)(); | |
98 | break; | |
100 | 99 | default: |
101 | return False; | |
102 | } | |
100 | return False; | |
101 | } | |
103 | 102 | |
104 | return True; | |
103 | return True; | |
105 | 104 | } |
106 | 105 | |
107 | 106 | void |
108 | 107 | DAEventLoop(void) |
109 | 108 | { |
110 | DAEventLoopForWindow(DAWindow); | |
109 | DAEventLoopForWindow(DAWindow); | |
111 | 110 | } |
112 | 111 | |
113 | 112 | void |
114 | 113 | DAEventLoopForWindow(Window window) |
115 | 114 | { |
116 | XEvent event; | |
115 | XEvent event; | |
117 | 116 | |
118 | for (;;) { | |
119 | if (_daContext->timeOut >= 0) { | |
120 | if (!DANextEventOrTimeout(&event, _daContext->timeOut)) { | |
121 | if (_daContext->callbacks.timeout) | |
122 | (*_daContext->callbacks.timeout)(); | |
123 | continue; | |
124 | } | |
117 | for (;; ) { | |
118 | if (_daContext->timeOut >= 0) { | |
119 | if (!DANextEventOrTimeout(&event, _daContext->timeOut)) { | |
120 | if (_daContext->callbacks.timeout) | |
121 | (*_daContext->callbacks.timeout)(); | |
122 | continue; | |
123 | } | |
124 | } else | |
125 | XNextEvent(DADisplay, &event); | |
126 | ||
127 | DAProcessEventForWindow(window, &event); | |
125 | 128 | } |
126 | else | |
127 | XNextEvent(DADisplay, &event); | |
128 | ||
129 | DAProcessEventForWindow(window, &event); | |
130 | } | |
131 | 129 | } |
132 | 130 | |
133 | 131 | Bool |
134 | 132 | DANextEventOrTimeout(XEvent *event, unsigned long milliseconds) |
135 | 133 | { |
136 | struct timeval timeout; | |
137 | fd_set rset; | |
134 | struct timeval timeout; | |
135 | fd_set rset; | |
138 | 136 | |
139 | XSync(DADisplay, False); | |
140 | if (XPending(DADisplay)) { | |
141 | XNextEvent(DADisplay, event); | |
142 | return True; | |
143 | } | |
137 | XSync(DADisplay, False); | |
138 | if (XPending(DADisplay)) { | |
139 | XNextEvent(DADisplay, event); | |
140 | return True; | |
141 | } | |
144 | 142 | |
145 | timeout.tv_sec = milliseconds / 1000; | |
146 | timeout.tv_usec = (milliseconds % 1000) * 1000; | |
143 | timeout.tv_sec = milliseconds / 1000; | |
144 | timeout.tv_usec = (milliseconds % 1000) * 1000; | |
147 | 145 | |
148 | FD_ZERO(&rset); | |
149 | FD_SET(ConnectionNumber(DADisplay), &rset); | |
146 | FD_ZERO(&rset); | |
147 | FD_SET(ConnectionNumber(DADisplay), &rset); | |
150 | 148 | |
151 | if (select(ConnectionNumber(DADisplay)+1, &rset, NULL, NULL, &timeout) > 0) { | |
152 | XNextEvent(DADisplay, event); | |
153 | return True; | |
154 | } | |
149 | if (select(ConnectionNumber(DADisplay)+1, &rset, NULL, NULL, &timeout) > 0) { | |
150 | XNextEvent(DADisplay, event); | |
151 | return True; | |
152 | } | |
155 | 153 | |
156 | return False; | |
154 | return False; | |
157 | 155 | } |
158 | 156 |
23 | 23 | #include "daargs.h" |
24 | 24 | #include "dautil.h" |
25 | 25 | |
26 | #define MIN(a, b) (a < b ? a : b) | |
26 | #define MIN(a, b) (a < b ? a : b) | |
27 | 27 | |
28 | 28 | struct DAContext *_daContext; |
29 | 29 | |
30 | DARect DANoRect = {0, 0, 0, 0}; | |
31 | Display *DADisplay = NULL; | |
32 | Window DALeader = None; | |
33 | Window DAIcon = None; | |
34 | Window DAWindow = None; | |
35 | int DADepth = 0; | |
36 | Visual *DAVisual = NULL; | |
37 | unsigned long DAExpectedVersion = 0; | |
38 | GC DAGC = NULL, DAClearGC = NULL; | |
39 | DARect DAPreferredIconSizes = {-1, -1, 0, 0}; | |
40 | Atom WM_DELETE_WINDOW; | |
30 | DARect DANoRect = {0, 0, 0, 0}; | |
31 | Display *DADisplay = NULL; | |
32 | Window DALeader = None; | |
33 | Window DAIcon = None; | |
34 | Window DAWindow = None; | |
35 | int DADepth = 0; | |
36 | Visual *DAVisual = NULL; | |
37 | unsigned long DAExpectedVersion = 0; | |
38 | GC DAGC = NULL, DAClearGC = NULL; | |
39 | DARect DAPreferredIconSizes = {-1, -1, 0, 0}; | |
40 | Atom WM_DELETE_WINDOW; | |
41 | 41 | |
42 | 42 | |
43 | 43 | void |
44 | 44 | DAOpenDisplay(char *display, int argc, char **argv) |
45 | 45 | { |
46 | /* Open Connection to X Server */ | |
47 | DADisplay = XOpenDisplay(display); | |
48 | if (!DADisplay) { | |
49 | printf("%s: could not open display %s!\n", _daContext->programName, | |
50 | XDisplayName(display)); | |
51 | exit(EXIT_FAILURE); | |
52 | } | |
53 | ||
54 | DADepth = DefaultDepth(DADisplay, DefaultScreen(DADisplay)); | |
55 | DAVisual = DefaultVisual(DADisplay, DefaultScreen(DADisplay)); | |
56 | DAGC = DefaultGC(DADisplay, DefaultScreen(DADisplay)); | |
46 | /* Open Connection to X Server */ | |
47 | DADisplay = XOpenDisplay(display); | |
48 | if (!DADisplay) { | |
49 | printf("%s: could not open display %s!\n", _daContext->programName, | |
50 | XDisplayName(display)); | |
51 | exit(EXIT_FAILURE); | |
52 | } | |
53 | ||
54 | DADepth = DefaultDepth(DADisplay, DefaultScreen(DADisplay)); | |
55 | DAVisual = DefaultVisual(DADisplay, DefaultScreen(DADisplay)); | |
56 | DAGC = DefaultGC(DADisplay, DefaultScreen(DADisplay)); | |
57 | 57 | } |
58 | 58 | |
59 | 59 | |
60 | 60 | void |
61 | 61 | DAProposeIconSize(unsigned width, unsigned height) |
62 | 62 | { |
63 | XIconSize *iconSizes; | |
64 | int nrSizes = 0; | |
65 | ||
66 | _daContext->width = width; | |
67 | _daContext->height = height; | |
68 | ||
69 | /* Get the nearest allowed icon size if the WM specifies such */ | |
70 | iconSizes = XAllocIconSize(); | |
71 | if (XGetIconSizes(DADisplay, DefaultRootWindow(DADisplay), | |
72 | &iconSizes, &nrSizes)) { | |
73 | int i; | |
74 | int da = -1; | |
75 | int min_w = -1, min_h = -1; | |
76 | int max_w = 0, max_h = 0; | |
77 | ||
78 | for (i = 0; i < nrSizes; i++) { | |
79 | int w1, h1, w, h; | |
80 | ||
81 | if ((max_w < iconSizes[i].max_width) || | |
82 | (max_h < iconSizes[i].max_height)) { | |
83 | max_w = iconSizes[i].max_width; | |
84 | max_h = iconSizes[i].max_height; | |
85 | } | |
86 | ||
87 | if ((min_w > iconSizes[i].min_width) || | |
88 | (min_h > iconSizes[i].min_height) || | |
89 | (min_w == -1)) { | |
90 | min_w = iconSizes[i].min_width; | |
91 | min_h = iconSizes[i].min_height; | |
92 | } | |
93 | ||
94 | if ((width > iconSizes[i].max_width) || | |
95 | (width < iconSizes[i].min_width) || | |
96 | (height > iconSizes[i].max_height) || | |
97 | (height < iconSizes[i].min_height)) | |
98 | continue; | |
99 | ||
100 | w1 = (iconSizes[i].max_width - width ) % iconSizes[i].width_inc; | |
101 | h1 = (iconSizes[i].max_height - height) % iconSizes[i].height_inc; | |
102 | w = MIN(w1, iconSizes[i].width_inc - w1); | |
103 | h = MIN(h1, iconSizes[i].height_inc - h1); | |
104 | ||
105 | if ((w * h < da) || (da == -1)) { | |
106 | _daContext->width = width + w; | |
107 | _daContext->height = height + h; | |
108 | da = w * h; | |
109 | } | |
110 | } | |
111 | ||
112 | DAPreferredIconSizes.x = min_w; | |
113 | DAPreferredIconSizes.y = min_h; | |
114 | DAPreferredIconSizes.width = max_w; | |
115 | DAPreferredIconSizes.height = max_h; | |
116 | ||
117 | if (da == -1) { /* requested size is out of bounds */ | |
118 | DAWarning("Requested icon-size (%d x %d) is out of the range " | |
119 | "allowed by the window manager\n", | |
120 | _daContext->width, _daContext->height); | |
121 | } | |
122 | } | |
123 | XFree(iconSizes); | |
63 | XIconSize *iconSizes; | |
64 | int nrSizes = 0; | |
65 | ||
66 | _daContext->width = width; | |
67 | _daContext->height = height; | |
68 | ||
69 | /* Get the nearest allowed icon size if the WM specifies such */ | |
70 | iconSizes = XAllocIconSize(); | |
71 | if (XGetIconSizes(DADisplay, DefaultRootWindow(DADisplay), | |
72 | &iconSizes, &nrSizes)) { | |
73 | int i; | |
74 | int da = -1; | |
75 | int min_w = -1, min_h = -1; | |
76 | int max_w = 0, max_h = 0; | |
77 | ||
78 | for (i = 0; i < nrSizes; i++) { | |
79 | int w1, h1, w, h; | |
80 | ||
81 | if ((max_w < iconSizes[i].max_width) || | |
82 | (max_h < iconSizes[i].max_height)) { | |
83 | max_w = iconSizes[i].max_width; | |
84 | max_h = iconSizes[i].max_height; | |
85 | } | |
86 | ||
87 | if ((min_w > iconSizes[i].min_width) || | |
88 | (min_h > iconSizes[i].min_height) || | |
89 | (min_w == -1)) { | |
90 | min_w = iconSizes[i].min_width; | |
91 | min_h = iconSizes[i].min_height; | |
92 | } | |
93 | ||
94 | if ((width > iconSizes[i].max_width) || | |
95 | (width < iconSizes[i].min_width) || | |
96 | (height > iconSizes[i].max_height) || | |
97 | (height < iconSizes[i].min_height)) | |
98 | continue; | |
99 | ||
100 | w1 = (iconSizes[i].max_width - width) % iconSizes[i].width_inc; | |
101 | h1 = (iconSizes[i].max_height - height) % iconSizes[i].height_inc; | |
102 | w = MIN(w1, iconSizes[i].width_inc - w1); | |
103 | h = MIN(h1, iconSizes[i].height_inc - h1); | |
104 | ||
105 | if ((w * h < da) || (da == -1)) { | |
106 | _daContext->width = width + w; | |
107 | _daContext->height = height + h; | |
108 | da = w * h; | |
109 | } | |
110 | } | |
111 | ||
112 | DAPreferredIconSizes.x = min_w; | |
113 | DAPreferredIconSizes.y = min_h; | |
114 | DAPreferredIconSizes.width = max_w; | |
115 | DAPreferredIconSizes.height = max_h; | |
116 | ||
117 | if (da == -1) /* requested size is out of bounds */ | |
118 | DAWarning("Requested icon-size (%d x %d) is out of the range " | |
119 | "allowed by the window manager\n", | |
120 | _daContext->width, _daContext->height); | |
121 | } | |
122 | XFree(iconSizes); | |
124 | 123 | } |
125 | 124 | |
126 | 125 | |
127 | 126 | void |
128 | 127 | DACreateIcon(char *name, unsigned width, unsigned height, int argc, char **argv) |
129 | 128 | { |
130 | XClassHint *classHint; | |
131 | XWMHints *wmHints; | |
132 | XGCValues gcv; | |
133 | unsigned long valueMask; | |
134 | char *resourceValue; | |
135 | ||
136 | _daContext->width = width; | |
137 | _daContext->height = height; | |
138 | ||
139 | /* Create Windows */ | |
140 | DALeader = XCreateSimpleWindow(DADisplay, DefaultRootWindow(DADisplay), | |
141 | 0, 0, width, height, 0, 0, 0); | |
142 | ||
143 | if (! _daContext->windowed) { | |
144 | DAIcon = XCreateSimpleWindow(DADisplay, DefaultRootWindow(DADisplay), | |
145 | 0, 0, width, height, 0, 0, 0); | |
146 | DAWindow = DAIcon; | |
147 | } else { | |
148 | DAIcon = None; | |
149 | DAWindow = DALeader; | |
150 | } | |
151 | ||
152 | /* Set ClassHint */ | |
153 | if (!(classHint = XAllocClassHint())) | |
154 | printf("%s: can't allocate memory for class hints!\n", | |
155 | _daContext->programName), exit(1); | |
156 | classHint->res_class = RES_CLASSNAME; | |
157 | classHint->res_name = name; | |
158 | ||
159 | XSetClassHint(DADisplay, DALeader, classHint); | |
160 | XFree(classHint); | |
161 | ||
162 | /* Set WMHints */ | |
163 | if (!(wmHints = XAllocWMHints())) | |
164 | printf("%s: can't allocate memory for wm hints!\n", | |
165 | _daContext->programName), exit(1); | |
166 | ||
167 | wmHints->flags = WindowGroupHint; | |
168 | wmHints->window_group = DALeader; | |
169 | ||
170 | if (!_daContext->windowed) { | |
171 | wmHints->flags |= IconWindowHint|StateHint; | |
172 | wmHints->icon_window = DAIcon; | |
173 | wmHints->initial_state = WithdrawnState; | |
174 | } | |
175 | ||
176 | XSetWMHints(DADisplay, DALeader, wmHints); | |
177 | XFree(wmHints); | |
178 | ||
179 | /* Set WMProtocols */ | |
180 | WM_DELETE_WINDOW = XInternAtom(DADisplay, "WM_DELETE_WINDOW", True); | |
181 | XSetWMProtocols(DADisplay, DALeader, &WM_DELETE_WINDOW, 1); | |
182 | ||
183 | /* Set Command to start the app so it can be docked properly */ | |
184 | XSetCommand(DADisplay, DALeader, argv, argc); | |
185 | ||
186 | gcv.graphics_exposures = False; | |
187 | valueMask = GCGraphicsExposures; | |
188 | ||
189 | /* continue setting the foreground GC */ | |
190 | resourceValue = XGetDefault(DADisplay, RES_CLASSNAME, "foreground"); | |
191 | if (resourceValue) { | |
192 | gcv.foreground = DAGetColor(resourceValue); | |
193 | valueMask |= GCForeground; | |
194 | } | |
195 | ||
196 | XChangeGC(DADisplay, DAGC, valueMask, &gcv); | |
197 | ||
198 | /* set background GC values before setting value for foreground */ | |
199 | resourceValue = XGetDefault(DADisplay, RES_CLASSNAME, "background"); | |
200 | if (resourceValue) { | |
201 | gcv.foreground = DAGetColor(resourceValue); | |
202 | } | |
203 | ||
204 | DAClearGC = XCreateGC(DADisplay, DAWindow, | |
205 | GCGraphicsExposures|GCForeground, &gcv); | |
206 | ||
207 | XFlush(DADisplay); | |
129 | XClassHint *classHint; | |
130 | XWMHints *wmHints; | |
131 | XGCValues gcv; | |
132 | unsigned long valueMask; | |
133 | char *resourceValue; | |
134 | ||
135 | _daContext->width = width; | |
136 | _daContext->height = height; | |
137 | ||
138 | /* Create Windows */ | |
139 | DALeader = XCreateSimpleWindow(DADisplay, DefaultRootWindow(DADisplay), | |
140 | 0, 0, width, height, 0, 0, 0); | |
141 | ||
142 | if (!_daContext->windowed) { | |
143 | DAIcon = XCreateSimpleWindow(DADisplay, DefaultRootWindow(DADisplay), | |
144 | 0, 0, width, height, 0, 0, 0); | |
145 | DAWindow = DAIcon; | |
146 | } else { | |
147 | DAIcon = None; | |
148 | DAWindow = DALeader; | |
149 | } | |
150 | ||
151 | /* Set ClassHint */ | |
152 | classHint = XAllocClassHint(); | |
153 | if (!classHint) | |
154 | printf("%s: can't allocate memory for class hints!\n", | |
155 | _daContext->programName), exit(1); | |
156 | classHint->res_class = RES_CLASSNAME; | |
157 | classHint->res_name = name; | |
158 | ||
159 | XSetClassHint(DADisplay, DALeader, classHint); | |
160 | XFree(classHint); | |
161 | ||
162 | /* Set WMHints */ | |
163 | wmHints = XAllocWMHints(); | |
164 | if (!wmHints) | |
165 | printf("%s: can't allocate memory for wm hints!\n", | |
166 | _daContext->programName), exit(1); | |
167 | ||
168 | wmHints->flags = WindowGroupHint; | |
169 | wmHints->window_group = DALeader; | |
170 | ||
171 | if (!_daContext->windowed) { | |
172 | wmHints->flags |= IconWindowHint|StateHint; | |
173 | wmHints->icon_window = DAIcon; | |
174 | wmHints->initial_state = WithdrawnState; | |
175 | } | |
176 | ||
177 | XSetWMHints(DADisplay, DALeader, wmHints); | |
178 | XFree(wmHints); | |
179 | ||
180 | /* Set WMProtocols */ | |
181 | WM_DELETE_WINDOW = XInternAtom(DADisplay, "WM_DELETE_WINDOW", True); | |
182 | XSetWMProtocols(DADisplay, DALeader, &WM_DELETE_WINDOW, 1); | |
183 | ||
184 | /* Set Command to start the app so it can be docked properly */ | |
185 | XSetCommand(DADisplay, DALeader, argv, argc); | |
186 | ||
187 | gcv.graphics_exposures = False; | |
188 | valueMask = GCGraphicsExposures; | |
189 | ||
190 | /* continue setting the foreground GC */ | |
191 | resourceValue = XGetDefault(DADisplay, RES_CLASSNAME, "foreground"); | |
192 | if (resourceValue) { | |
193 | gcv.foreground = DAGetColor(resourceValue); | |
194 | valueMask |= GCForeground; | |
195 | } | |
196 | ||
197 | XChangeGC(DADisplay, DAGC, valueMask, &gcv); | |
198 | ||
199 | /* set background GC values before setting value for foreground */ | |
200 | resourceValue = XGetDefault(DADisplay, RES_CLASSNAME, "background"); | |
201 | if (resourceValue) | |
202 | gcv.foreground = DAGetColor(resourceValue); | |
203 | ||
204 | DAClearGC = XCreateGC(DADisplay, DAWindow, | |
205 | GCGraphicsExposures|GCForeground, &gcv); | |
206 | ||
207 | XFlush(DADisplay); | |
208 | 208 | } |
209 | 209 | |
210 | 210 | |
211 | 211 | void |
212 | 212 | DAShow(void) |
213 | 213 | { |
214 | DAShowWindow(DALeader); | |
214 | DAShowWindow(DALeader); | |
215 | 215 | } |
216 | 216 | |
217 | 217 | |
219 | 219 | DAShowWindow(Window window) |
220 | 220 | |
221 | 221 | { |
222 | XMapRaised(DADisplay, window); | |
223 | if ((window == DALeader) && !_daContext->windowed) { | |
224 | XMapSubwindows(DADisplay, DAIcon); | |
225 | } else { | |
226 | XMapSubwindows(DADisplay, window); | |
227 | } | |
228 | ||
229 | XFlush(DADisplay); | |
222 | XMapRaised(DADisplay, window); | |
223 | if ((window == DALeader) && !_daContext->windowed) | |
224 | XMapSubwindows(DADisplay, DAIcon); | |
225 | else | |
226 | XMapSubwindows(DADisplay, window); | |
227 | ||
228 | XFlush(DADisplay); | |
230 | 229 | } |
231 | 230 | |
232 | 231 | |
233 | 232 | /* Deprecated */ |
234 | 233 | void |
235 | 234 | DAInitialize(char *display, char *name, unsigned width, unsigned height, |
236 | int argc, char **argv) | |
237 | { | |
238 | DAOpenDisplay(display, argc, argv); | |
239 | DACreateIcon(name, width, height, argc, argv); | |
240 | } | |
235 | int argc, char **argv) | |
236 | { | |
237 | DAOpenDisplay(display, argc, argv); | |
238 | DACreateIcon(name, width, height, argc, argv); | |
239 | } |
31 | 31 | |
32 | 32 | /* Local typedef */ |
33 | 33 | typedef enum { |
34 | daXpmSourceData, | |
35 | daXpmSourceFile | |
34 | daXpmSourceData, | |
35 | daXpmSourceFile | |
36 | 36 | } daXpmSource; |
37 | 37 | |
38 | 38 | /* Function prototype */ |
39 | 39 | Bool _daMakePixmap(daXpmSource source, |
40 | char **data, Pixmap *pixmap, Pixmap *mask, | |
41 | unsigned short *width, unsigned short *height); | |
40 | char **data, Pixmap *pixmap, Pixmap *mask, | |
41 | unsigned short *width, unsigned short *height); | |
42 | 42 | |
43 | 43 | |
44 | 44 | |
45 | 45 | void |
46 | 46 | DASetShapeWithOffset(Pixmap shapeMask, int x_ofs, int y_ofs) |
47 | 47 | { |
48 | DASetShapeWithOffsetForWindow(DAWindow, shapeMask, x_ofs, y_ofs); | |
48 | DASetShapeWithOffsetForWindow(DAWindow, shapeMask, x_ofs, y_ofs); | |
49 | 49 | } |
50 | 50 | |
51 | 51 | void |
52 | 52 | DASetShapeWithOffsetForWindow(Window window, Pixmap shapeMask, |
53 | int x_ofs, int y_ofs) | |
53 | int x_ofs, int y_ofs) | |
54 | 54 | { |
55 | XShapeCombineMask(DADisplay, window, ShapeBounding, -x_ofs, -y_ofs, | |
56 | shapeMask, ShapeSet); | |
57 | XFlush(DADisplay); | |
55 | XShapeCombineMask(DADisplay, window, ShapeBounding, -x_ofs, -y_ofs, | |
56 | shapeMask, ShapeSet); | |
57 | XFlush(DADisplay); | |
58 | 58 | } |
59 | 59 | |
60 | 60 | void |
61 | 61 | DASetPixmap(Pixmap pixmap) |
62 | 62 | { |
63 | DASetPixmapForWindow(DAWindow, pixmap); | |
63 | DASetPixmapForWindow(DAWindow, pixmap); | |
64 | 64 | } |
65 | 65 | |
66 | 66 | void |
67 | 67 | DASetPixmapForWindow(Window window, Pixmap pixmap) |
68 | 68 | { |
69 | XSetWindowBackgroundPixmap(DADisplay, window, pixmap); | |
70 | XClearWindow(DADisplay, window); | |
71 | XFlush(DADisplay); | |
69 | XSetWindowBackgroundPixmap(DADisplay, window, pixmap); | |
70 | XClearWindow(DADisplay, window); | |
71 | XFlush(DADisplay); | |
72 | 72 | } |
73 | 73 | |
74 | 74 | Pixmap |
75 | 75 | DAMakePixmap(void) |
76 | 76 | { |
77 | return (XCreatePixmap(DADisplay, DAWindow, | |
78 | _daContext->width, _daContext->height, | |
79 | DADepth)); | |
77 | return (XCreatePixmap(DADisplay, DAWindow, | |
78 | _daContext->width, _daContext->height, | |
79 | DADepth)); | |
80 | 80 | } |
81 | 81 | |
82 | 82 | Pixmap |
83 | 83 | DAMakeShape(void) |
84 | 84 | { |
85 | return (XCreatePixmap(DADisplay, DAWindow, | |
86 | _daContext->width, _daContext->height, | |
87 | 1)); | |
85 | return (XCreatePixmap(DADisplay, DAWindow, | |
86 | _daContext->width, _daContext->height, | |
87 | 1)); | |
88 | 88 | } |
89 | 89 | |
90 | 90 | Bool |
91 | 91 | DAMakePixmapFromData(char **data, Pixmap *pixmap, Pixmap *mask, |
92 | unsigned short *width, unsigned short *height) | |
92 | unsigned short *width, unsigned short *height) | |
93 | 93 | { |
94 | return _daMakePixmap(daXpmSourceData, data, | |
95 | pixmap, mask, | |
96 | width, height); | |
94 | return _daMakePixmap(daXpmSourceData, data, | |
95 | pixmap, mask, | |
96 | width, height); | |
97 | 97 | } |
98 | 98 | |
99 | 99 | Bool |
100 | 100 | DAMakePixmapFromFile(char *filename, Pixmap *pixmap, Pixmap *mask, |
101 | unsigned short *width, unsigned short *height) | |
101 | unsigned short *width, unsigned short *height) | |
102 | 102 | { |
103 | if (access(filename, R_OK) < 0) | |
104 | return False; | |
103 | if (access(filename, R_OK) < 0) | |
104 | return False; | |
105 | 105 | |
106 | return _daMakePixmap(daXpmSourceFile, (char**)filename, | |
107 | pixmap, mask, | |
108 | width, height); | |
106 | return _daMakePixmap(daXpmSourceFile, (char **)filename, | |
107 | pixmap, mask, | |
108 | width, height); | |
109 | 109 | } |
110 | 110 | |
111 | 111 | |
112 | 112 | |
113 | 113 | Bool |
114 | 114 | _daMakePixmap(daXpmSource source, |
115 | char **data, Pixmap *pixmap, Pixmap *mask, | |
116 | unsigned short *width, unsigned short *height) | |
115 | char **data, Pixmap *pixmap, Pixmap *mask, | |
116 | unsigned short *width, unsigned short *height) | |
117 | 117 | { |
118 | XpmAttributes xpmAttr; | |
118 | XpmAttributes xpmAttr; | |
119 | 119 | |
120 | xpmAttr.valuemask = XpmCloseness; | |
121 | xpmAttr.closeness = 40000; | |
120 | xpmAttr.valuemask = XpmCloseness; | |
121 | xpmAttr.closeness = 40000; | |
122 | 122 | |
123 | 123 | |
124 | if (source == daXpmSourceData | |
124 | if (source == daXpmSourceData | |
125 | 125 | && (XpmCreatePixmapFromData( |
126 | DADisplay, DAWindow, data, pixmap, mask, &xpmAttr) != 0)) | |
127 | return False; | |
126 | DADisplay, DAWindow, data, pixmap, mask, &xpmAttr) != 0)) | |
127 | return False; | |
128 | 128 | |
129 | else if (source == daXpmSourceFile | |
130 | && (XpmReadFileToPixmap( | |
131 | DADisplay, DAWindow, (char*)data, pixmap, mask, &xpmAttr) != 0)) | |
132 | return False; | |
129 | else if (source == daXpmSourceFile | |
130 | && (XpmReadFileToPixmap( | |
131 | DADisplay, DAWindow, (char *)data, pixmap, mask, &xpmAttr) != 0)) | |
132 | return False; | |
133 | 133 | |
134 | *width = xpmAttr.width; | |
135 | *height = xpmAttr.height; | |
134 | *width = xpmAttr.width; | |
135 | *height = xpmAttr.height; | |
136 | 136 | |
137 | return True; | |
137 | return True; | |
138 | 138 | } |
139 | 139 |
25 | 25 | |
26 | 26 | void |
27 | 27 | DAProcessActionRects(int x, int y, DAActionRect *actionrects, int count, |
28 | void *data) | |
28 | void *data) | |
29 | 29 | { |
30 | int index = 0; | |
30 | int index = 0; | |
31 | 31 | |
32 | if (!actionrects) | |
33 | return; | |
32 | if (!actionrects) | |
33 | return; | |
34 | 34 | |
35 | while ( (index < count) && | |
36 | ((x < actionrects[index].rect.x) || | |
37 | (x > actionrects[index].rect.x + actionrects[index].rect.width) || | |
38 | (y < actionrects[index].rect.y) || | |
39 | (y > actionrects[index].rect.y + actionrects[index].rect.height))) | |
40 | index++; | |
35 | while ((index < count) && | |
36 | ((x < actionrects[index].rect.x) || | |
37 | (x > actionrects[index].rect.x + actionrects[index].rect.width) || | |
38 | (y < actionrects[index].rect.y) || | |
39 | (y > actionrects[index].rect.y + actionrects[index].rect.height))) | |
40 | index++; | |
41 | 41 | |
42 | if (index == count) | |
43 | return; | |
42 | if (index == count) | |
43 | return; | |
44 | 44 | |
45 | if (actionrects[index].action) | |
46 | (*actionrects[index].action)(x - actionrects[index].rect.x, | |
47 | y - actionrects[index].rect.y, | |
48 | actionrects[index].rect, | |
49 | data); | |
45 | if (actionrects[index].action) | |
46 | (*actionrects[index].action)(x - actionrects[index].rect.x, | |
47 | y - actionrects[index].rect.y, | |
48 | actionrects[index].rect, | |
49 | data); | |
50 | 50 | } |
51 | 51 |
31 | 31 | |
32 | 32 | /* Local typedef */ |
33 | 33 | typedef enum { |
34 | daShapeSourceData, | |
35 | daShapeSourceFile | |
34 | daShapeSourceData, | |
35 | daShapeSourceFile | |
36 | 36 | } daShapeSource; |
37 | 37 | |
38 | 38 | /* local functions */ |
39 | 39 | void setGCs(DAShapedPixmap *dasp); |
40 | DAShapedPixmap* _daMakeShapedPixmap(daShapeSource source, char **data); | |
40 | DAShapedPixmap *_daMakeShapedPixmap(daShapeSource source, char **data); | |
41 | 41 | |
42 | 42 | extern struct DAContext *_daContext; |
43 | 43 | |
44 | 44 | /* Create a new shaped pixmap with width & height of dockapp window */ |
45 | DAShapedPixmap* | |
45 | DAShapedPixmap * | |
46 | 46 | DAMakeShapedPixmap() |
47 | 47 | { |
48 | DAShapedPixmap *dasp = malloc(sizeof(DAShapedPixmap)); | |
48 | DAShapedPixmap *dasp = malloc(sizeof(DAShapedPixmap)); | |
49 | 49 | |
50 | if (dasp == NULL) | |
51 | return NULL; | |
50 | if (dasp == NULL) | |
51 | return NULL; | |
52 | 52 | |
53 | memset(dasp, 0, sizeof(DAShapedPixmap)); | |
54 | dasp->pixmap = DAMakePixmap(); | |
55 | dasp->shape = DAMakeShape(); | |
56 | dasp->geometry.width = _daContext->width; | |
57 | dasp->geometry.height = _daContext->height; | |
53 | memset(dasp, 0, sizeof(DAShapedPixmap)); | |
54 | dasp->pixmap = DAMakePixmap(); | |
55 | dasp->shape = DAMakeShape(); | |
56 | dasp->geometry.width = _daContext->width; | |
57 | dasp->geometry.height = _daContext->height; | |
58 | 58 | |
59 | setGCs(dasp); | |
60 | DASPClear(dasp); | |
59 | setGCs(dasp); | |
60 | DASPClear(dasp); | |
61 | 61 | |
62 | return dasp; | |
62 | return dasp; | |
63 | 63 | } |
64 | 64 | |
65 | 65 | |
66 | 66 | /* Create a new shaped pixmap from XPM-data */ |
67 | DAShapedPixmap* | |
67 | DAShapedPixmap * | |
68 | 68 | DAMakeShapedPixmapFromData(char **data) |
69 | 69 | { |
70 | return _daMakeShapedPixmap(daShapeSourceData, data); | |
70 | return _daMakeShapedPixmap(daShapeSourceData, data); | |
71 | 71 | } |
72 | 72 | |
73 | 73 | |
74 | 74 | /* Create a new shaped pixmap from XPM-data */ |
75 | DAShapedPixmap* | |
75 | DAShapedPixmap * | |
76 | 76 | DAMakeShapedPixmapFromFile(char *filename) |
77 | 77 | { |
78 | return _daMakeShapedPixmap(daShapeSourceFile, (char**)filename); | |
78 | return _daMakeShapedPixmap(daShapeSourceFile, (char **)filename); | |
79 | 79 | } |
80 | 80 | |
81 | 81 | |
83 | 83 | void |
84 | 84 | DAFreeShapedPixmap(DAShapedPixmap *dasp) |
85 | 85 | { |
86 | assert(dasp); | |
86 | assert(dasp); | |
87 | 87 | |
88 | XFreePixmap(DADisplay, dasp->pixmap); | |
89 | XFreePixmap(DADisplay, dasp->shape); | |
90 | XFreeGC(DADisplay, dasp->shapeGC); | |
88 | XFreePixmap(DADisplay, dasp->pixmap); | |
89 | XFreePixmap(DADisplay, dasp->shape); | |
90 | XFreeGC(DADisplay, dasp->shapeGC); | |
91 | 91 | |
92 | free(dasp); | |
92 | free(dasp); | |
93 | 93 | } |
94 | 94 | |
95 | 95 | /* Copy shape-mask and pixmap-data from an area in one shaped pixmap |
97 | 97 | void |
98 | 98 | DASPCopyArea(DAShapedPixmap *src, DAShapedPixmap *dst, int x1, int y1, int w, int h, int x2, int y2) |
99 | 99 | { |
100 | assert(src != NULL && dst != NULL); | |
100 | assert(src != NULL && dst != NULL); | |
101 | 101 | |
102 | XCopyPlane(DADisplay, src->shape, dst->shape, src->shapeGC, x1, y1, w, h, x2, y2, 1); | |
103 | XCopyArea(DADisplay, src->pixmap, dst->pixmap, src->drawGC, x1, y1, w, h, x2, y2); | |
102 | XCopyPlane(DADisplay, src->shape, dst->shape, src->shapeGC, x1, y1, w, h, x2, y2, 1); | |
103 | XCopyArea(DADisplay, src->pixmap, dst->pixmap, src->drawGC, x1, y1, w, h, x2, y2); | |
104 | 104 | } |
105 | 105 | |
106 | 106 | |
108 | 108 | void |
109 | 109 | DASPClear(DAShapedPixmap *dasp) |
110 | 110 | { |
111 | XGCValues gcv; | |
111 | XGCValues gcv; | |
112 | 112 | |
113 | assert(dasp != NULL); | |
113 | assert(dasp != NULL); | |
114 | 114 | |
115 | gcv.foreground = 0; | |
116 | XChangeGC(DADisplay, dasp->shapeGC, GCForeground, &gcv); | |
115 | gcv.foreground = 0; | |
116 | XChangeGC(DADisplay, dasp->shapeGC, GCForeground, &gcv); | |
117 | 117 | |
118 | /* Clear pixmaps */ | |
119 | XFillRectangle(DADisplay, dasp->pixmap, | |
120 | DAClearGC, 0, 0, dasp->geometry.width, dasp->geometry.height); | |
121 | XFillRectangle(DADisplay, dasp->shape, | |
122 | dasp->shapeGC, 0, 0, dasp->geometry.width, dasp->geometry.height); | |
118 | /* Clear pixmaps */ | |
119 | XFillRectangle(DADisplay, dasp->pixmap, | |
120 | DAClearGC, 0, 0, dasp->geometry.width, dasp->geometry.height); | |
121 | XFillRectangle(DADisplay, dasp->shape, | |
122 | dasp->shapeGC, 0, 0, dasp->geometry.width, dasp->geometry.height); | |
123 | 123 | |
124 | gcv.foreground = 1; | |
125 | XChangeGC(DADisplay, dasp->shapeGC, GCForeground, &gcv); | |
124 | gcv.foreground = 1; | |
125 | XChangeGC(DADisplay, dasp->shapeGC, GCForeground, &gcv); | |
126 | 126 | } |
127 | 127 | |
128 | 128 | |
130 | 130 | void |
131 | 131 | DASPSetPixmap(DAShapedPixmap *dasp) |
132 | 132 | { |
133 | DASPSetPixmapForWindow(DAWindow, dasp); | |
133 | DASPSetPixmapForWindow(DAWindow, dasp); | |
134 | 134 | } |
135 | 135 | |
136 | 136 | void |
137 | 137 | DASPSetPixmapForWindow(Window window, DAShapedPixmap *dasp) |
138 | 138 | { |
139 | assert(dasp != NULL); | |
139 | assert(dasp != NULL); | |
140 | 140 | |
141 | DASetShapeForWindow(window, dasp->shape); | |
142 | DASetPixmapForWindow(window, dasp->pixmap); | |
141 | DASetShapeForWindow(window, dasp->shape); | |
142 | DASetPixmapForWindow(window, dasp->pixmap); | |
143 | 143 | } |
144 | 144 | |
145 | 145 | |
146 | 146 | void |
147 | 147 | setGCs(DAShapedPixmap *dasp) |
148 | 148 | { |
149 | XGCValues gcv; | |
149 | XGCValues gcv; | |
150 | 150 | |
151 | dasp->drawGC = DAGC; | |
152 | dasp->clearGC = DAClearGC; | |
151 | dasp->drawGC = DAGC; | |
152 | dasp->clearGC = DAClearGC; | |
153 | 153 | |
154 | /* create GC for bit-plane operations in shapes */ | |
155 | gcv.graphics_exposures = False; | |
156 | gcv.foreground = 1; | |
157 | gcv.background = 0; | |
158 | gcv.plane_mask = 1; | |
154 | /* create GC for bit-plane operations in shapes */ | |
155 | gcv.graphics_exposures = False; | |
156 | gcv.foreground = 1; | |
157 | gcv.background = 0; | |
158 | gcv.plane_mask = 1; | |
159 | 159 | |
160 | dasp->shapeGC = XCreateGC( | |
161 | DADisplay, | |
162 | dasp->shape, | |
163 | GCGraphicsExposures|GCForeground|GCBackground|GCPlaneMask, | |
164 | &gcv); | |
160 | dasp->shapeGC = XCreateGC( | |
161 | DADisplay, | |
162 | dasp->shape, | |
163 | GCGraphicsExposures|GCForeground|GCBackground|GCPlaneMask, | |
164 | &gcv); | |
165 | 165 | |
166 | 166 | } |
167 | 167 | |
168 | 168 | |
169 | 169 | /* Create a new shaped pixmap using specified method */ |
170 | DAShapedPixmap* | |
170 | DAShapedPixmap * | |
171 | 171 | _daMakeShapedPixmap(daShapeSource source, char **data) |
172 | 172 | { |
173 | Bool success; | |
174 | DAShapedPixmap *dasp = malloc(sizeof(DAShapedPixmap)); | |
173 | Bool success; | |
174 | DAShapedPixmap *dasp = malloc(sizeof(DAShapedPixmap)); | |
175 | 175 | |
176 | if (dasp == NULL) | |
177 | return NULL; | |
176 | if (dasp == NULL) | |
177 | return NULL; | |
178 | 178 | |
179 | memset(dasp, 0, sizeof(DAShapedPixmap)); | |
179 | memset(dasp, 0, sizeof(DAShapedPixmap)); | |
180 | 180 | |
181 | if (source == daShapeSourceData) | |
182 | success = DAMakePixmapFromData(data, &dasp->pixmap, &dasp->shape, | |
183 | &dasp->geometry.width, &dasp->geometry.height); | |
184 | else | |
185 | success = DAMakePixmapFromFile((char*)data, &dasp->pixmap, &dasp->shape, | |
186 | &dasp->geometry.width, &dasp->geometry.height); | |
181 | if (source == daShapeSourceData) | |
182 | success = DAMakePixmapFromData(data, &dasp->pixmap, &dasp->shape, | |
183 | &dasp->geometry.width, &dasp->geometry.height); | |
184 | else | |
185 | success = DAMakePixmapFromFile((char *)data, &dasp->pixmap, &dasp->shape, | |
186 | &dasp->geometry.width, &dasp->geometry.height); | |
187 | 187 | |
188 | if (!success) | |
189 | return NULL; | |
188 | if (!success) | |
189 | return NULL; | |
190 | 190 | |
191 | setGCs(dasp); | |
191 | setGCs(dasp); | |
192 | 192 | |
193 | return dasp; | |
193 | return dasp; | |
194 | 194 | } |
195 | 195 |
38 | 38 | void |
39 | 39 | DASetExpectedVersion(unsigned long expectedVersion) |
40 | 40 | { |
41 | DAExpectedVersion = expectedVersion; | |
42 | ||
43 | if (expectedVersion > DA_VERSION) | |
44 | DAWarning("Version of libdockapp (%u) is older than " | |
45 | "version expected (%u)", | |
46 | DA_VERSION, | |
47 | DAExpectedVersion); | |
48 | } | |
49 | ||
50 | ||
51 | Display* | |
41 | DAExpectedVersion = expectedVersion; | |
42 | ||
43 | if (expectedVersion > DA_VERSION) | |
44 | DAWarning("Version of libdockapp (%u) is older than " | |
45 | "version expected (%u)", | |
46 | DA_VERSION, | |
47 | DAExpectedVersion); | |
48 | } | |
49 | ||
50 | ||
51 | Display * | |
52 | 52 | DAGetDisplay(char *d, ...) |
53 | 53 | { |
54 | /* Be backward compatible */ | |
55 | if (DAExpectedVersion < 20030126) { | |
56 | va_list ap; | |
57 | int argc; | |
58 | char **argv; | |
59 | ||
60 | va_start(ap, d); | |
61 | argc = va_arg(ap, int); | |
62 | argv = va_arg(ap, char**); | |
63 | va_end(ap); | |
64 | ||
65 | DAOpenDisplay(d, argc, argv); | |
66 | ||
67 | DAWarning("Expected version of libdockapp is not set."); | |
68 | DAWarning("Obsolete call to DAGetDisplay()."); | |
69 | ||
70 | return NULL; | |
71 | } | |
72 | ||
73 | return DADisplay; | |
54 | /* Be backward compatible */ | |
55 | if (DAExpectedVersion < 20030126) { | |
56 | va_list ap; | |
57 | int argc; | |
58 | char **argv; | |
59 | ||
60 | va_start(ap, d); | |
61 | argc = va_arg(ap, int); | |
62 | argv = va_arg(ap, char **); | |
63 | va_end(ap); | |
64 | ||
65 | DAOpenDisplay(d, argc, argv); | |
66 | ||
67 | DAWarning("Expected version of libdockapp is not set."); | |
68 | DAWarning("Obsolete call to DAGetDisplay()."); | |
69 | ||
70 | return NULL; | |
71 | } | |
72 | ||
73 | return DADisplay; | |
74 | 74 | } |
75 | 75 | |
76 | 76 | |
77 | 77 | void |
78 | 78 | DASetDisplay(Display *display) |
79 | 79 | { |
80 | DADisplay = display; | |
80 | DADisplay = display; | |
81 | 81 | } |
82 | 82 | |
83 | 83 | |
84 | 84 | Window |
85 | 85 | DAGetWindow(void) |
86 | 86 | { |
87 | return DAWindow; | |
87 | return DAWindow; | |
88 | 88 | } |
89 | 89 | |
90 | 90 | |
91 | 91 | void |
92 | 92 | DASetWindow(Window window) |
93 | 93 | { |
94 | DAWindow = window; | |
94 | DAWindow = window; | |
95 | 95 | } |
96 | 96 | |
97 | 97 | |
98 | 98 | Window |
99 | 99 | DAGetLeader(void) |
100 | 100 | { |
101 | return DALeader; | |
101 | return DALeader; | |
102 | 102 | } |
103 | 103 | |
104 | 104 | |
105 | 105 | void |
106 | 106 | DASetLeader(Window leader) |
107 | 107 | { |
108 | DALeader = leader; | |
108 | DALeader = leader; | |
109 | 109 | } |
110 | 110 | |
111 | 111 | |
112 | 112 | Window |
113 | 113 | DAGetIconWindow(void) |
114 | 114 | { |
115 | return DAIcon; | |
115 | return DAIcon; | |
116 | 116 | } |
117 | 117 | |
118 | 118 | |
119 | 119 | void |
120 | 120 | DASetIconWindow(Window icon_win) |
121 | 121 | { |
122 | DAIcon = icon_win; | |
122 | DAIcon = icon_win; | |
123 | 123 | } |
124 | 124 | |
125 | 125 | |
126 | 126 | int |
127 | 127 | DAGetDepth(void) |
128 | 128 | { |
129 | return DADepth; | |
129 | return DADepth; | |
130 | 130 | } |
131 | 131 | |
132 | 132 | |
133 | 133 | void |
134 | 134 | DASetDepth(int depth) |
135 | 135 | { |
136 | DADepth = depth; | |
137 | } | |
138 | ||
139 | ||
140 | Visual* | |
136 | DADepth = depth; | |
137 | } | |
138 | ||
139 | ||
140 | Visual * | |
141 | 141 | DAGetVisual(void) |
142 | 142 | { |
143 | return DAVisual; | |
143 | return DAVisual; | |
144 | 144 | } |
145 | 145 | |
146 | 146 | |
147 | 147 | void |
148 | 148 | DASetVisual(Visual *visual) |
149 | 149 | { |
150 | DAVisual = visual; | |
150 | DAVisual = visual; | |
151 | 151 | } |
152 | 152 | |
153 | 153 | void |
154 | 154 | DAWarning(const char *fmt, ...) |
155 | 155 | { |
156 | va_list args; | |
157 | ||
158 | va_start(args, fmt); | |
159 | _message("Warning", fmt, args); | |
160 | va_end(args); | |
156 | va_list args; | |
157 | ||
158 | va_start(args, fmt); | |
159 | _message("Warning", fmt, args); | |
160 | va_end(args); | |
161 | 161 | } |
162 | 162 | |
163 | 163 | void |
164 | 164 | DAError(const char *fmt, ...) |
165 | 165 | { |
166 | va_list args; | |
167 | ||
168 | va_start(args, fmt); | |
169 | _message("Error", fmt, args); | |
170 | exit(1); | |
171 | va_end(args); | |
166 | va_list args; | |
167 | ||
168 | va_start(args, fmt); | |
169 | _message("Error", fmt, args); | |
170 | exit(1); | |
171 | va_end(args); | |
172 | 172 | } |
173 | 173 | |
174 | 174 | |
179 | 179 | void |
180 | 180 | _message(const char *label, const char *fmt, va_list args) |
181 | 181 | { |
182 | char *w_fmt; | |
183 | ||
184 | if (_daContext->programName != NULL) { | |
185 | /* put default string in front of message, add newline */ | |
186 | w_fmt = malloc((strlen(_daContext->programName) + strlen(fmt) +13) * sizeof(char)); | |
187 | sprintf(w_fmt, "%s: %s: %s\n", _daContext->programName, label, fmt); | |
188 | } else { | |
189 | w_fmt = malloc((strlen(fmt) +1) * sizeof(char)); | |
190 | sprintf(w_fmt, "%s\n", fmt); | |
191 | } | |
192 | ||
193 | /* print the message */ | |
194 | vfprintf(stderr, w_fmt, args); | |
182 | char *w_fmt; | |
183 | ||
184 | if (_daContext->programName != NULL) { | |
185 | /* put default string in front of message, add newline */ | |
186 | w_fmt = malloc((strlen(_daContext->programName) + strlen(fmt) + 13) * sizeof(char)); | |
187 | sprintf(w_fmt, "%s: %s: %s\n", _daContext->programName, label, fmt); | |
188 | } else { | |
189 | w_fmt = malloc((strlen(fmt) + 1) * sizeof(char)); | |
190 | sprintf(w_fmt, "%s\n", fmt); | |
191 | } | |
192 | ||
193 | /* print the message */ | |
194 | vfprintf(stderr, w_fmt, args); | |
195 | 195 | } |
196 | 196 | |
197 | 197 | |
199 | 199 | debug(const char *fmt, ...) |
200 | 200 | { |
201 | 201 | #ifdef DEBUG |
202 | va_list args; | |
203 | ||
204 | va_start(args, fmt); | |
205 | _message("debug", fmt, args); | |
206 | va_end(args); | |
202 | va_list args; | |
203 | ||
204 | va_start(args, fmt); | |
205 | _message("debug", fmt, args); | |
206 | va_end(args); | |
207 | 207 | #endif |
208 | 208 | } |
21 | 21 | |
22 | 22 | #ifndef _DOCKAPP_H_ |
23 | 23 | #define _DOCKAPP_H_ |
24 | #define DA_VERSION 20050716 | |
24 | #define DA_VERSION 20050716 | |
25 | 25 | |
26 | 26 | /* |
27 | 27 | * This is a simple (trivial) library for writing Window Maker dock |
52 | 52 | * to handle |
53 | 53 | */ |
54 | 54 | typedef struct { |
55 | /* the dockapp window was destroyed */ | |
56 | void (*destroy)(void); | |
57 | /* button pressed */ | |
58 | void (*buttonPress)(int button, int state, int x, int y); | |
59 | /* button released */ | |
60 | void (*buttonRelease)(int button, int state, int x, int y); | |
61 | /* pointer motion */ | |
62 | void (*motion)(int x, int y); | |
63 | /* pointer entered dockapp window */ | |
64 | void (*enter)(void); | |
65 | /* pointer left dockapp window */ | |
66 | void (*leave)(void); | |
67 | /* timer expired */ | |
68 | void (*timeout)(void); | |
55 | /* the dockapp window was destroyed */ | |
56 | void (*destroy)(void); | |
57 | /* button pressed */ | |
58 | void (*buttonPress)(int button, int state, int x, int y); | |
59 | /* button released */ | |
60 | void (*buttonRelease)(int button, int state, int x, int y); | |
61 | /* pointer motion */ | |
62 | void (*motion)(int x, int y); | |
63 | /* pointer entered dockapp window */ | |
64 | void (*enter)(void); | |
65 | /* pointer left dockapp window */ | |
66 | void (*leave)(void); | |
67 | /* timer expired */ | |
68 | void (*timeout)(void); | |
69 | 69 | } DACallbacks; |
70 | 70 | |
71 | 71 | |
72 | 72 | typedef struct { |
73 | char *shortForm; /* short form for option, like -w */ | |
74 | char *longForm; /* long form for option, like --withdrawn */ | |
75 | char *description; /* description for the option */ | |
76 | ||
77 | short type; /* type of argument */ | |
78 | Bool used; /* if the argument was passed on the cmd-line */ | |
79 | ||
80 | /* the following are only set if the "used" field is True */ | |
81 | union { | |
82 | void *ptr; /* a ptr for the value that was passed */ | |
83 | int *integer; /* on the command line */ | |
84 | char **string; | |
85 | } value; | |
73 | char *shortForm; /* short form for option, like -w */ | |
74 | char *longForm; /* long form for option, like --withdrawn */ | |
75 | char *description; /* description for the option */ | |
76 | ||
77 | short type; /* type of argument */ | |
78 | Bool used; /* if the argument was passed on the cmd-line */ | |
79 | ||
80 | /* the following are only set if the "used" field is True */ | |
81 | union { | |
82 | void *ptr; /* a ptr for the value that was passed */ | |
83 | int *integer; /* on the command line */ | |
84 | char **string; | |
85 | } value; | |
86 | 86 | } DAProgramOption; |
87 | 87 | |
88 | 88 | |
97 | 97 | * The action rectangle structure |
98 | 98 | */ |
99 | 99 | typedef struct { |
100 | DARect rect; | |
101 | DARectCallback *action; | |
100 | DARect rect; | |
101 | DARectCallback *action; | |
102 | 102 | } DAActionRect; |
103 | 103 | |
104 | 104 | |
105 | 105 | /* option argument types */ |
106 | 106 | enum { |
107 | DONone, /* simple on/off flag */ | |
108 | DOInteger, /* an integer number */ | |
109 | DOString, /* a string */ | |
110 | DONatural /* positive integer number */ | |
107 | DONone, /* simple on/off flag */ | |
108 | DOInteger, /* an integer number */ | |
109 | DOString, /* a string */ | |
110 | DONatural /* positive integer number */ | |
111 | 111 | }; |
112 | 112 | |
113 | 113 | |
114 | 114 | /* Shaped pixmaps: Shapes in combination with pixmaps */ |
115 | 115 | typedef struct { |
116 | Pixmap pixmap; | |
117 | Pixmap shape; /* needs a 1-bit plane GC (shapeGC). */ | |
118 | GC drawGC, clearGC, shapeGC; | |
119 | DARect geometry; /* position and size */ | |
120 | DAActionRect *triggers; | |
116 | Pixmap pixmap; | |
117 | Pixmap shape; /* needs a 1-bit plane GC (shapeGC). */ | |
118 | GC drawGC, clearGC, shapeGC; | |
119 | DARect geometry; /* position and size */ | |
120 | DAActionRect *triggers; | |
121 | 121 | } DAShapedPixmap; |
122 | 122 | |
123 | 123 | |
124 | 124 | |
125 | extern Display *DADisplay; | |
126 | extern Window DAWindow, DALeader, DAIcon; /* see [NOTE] */ | |
127 | extern int DADepth; | |
128 | extern Visual *DAVisual; | |
129 | extern GC DAGC, DAClearGC; | |
130 | extern DARect DANoRect; | |
125 | extern Display *DADisplay; | |
126 | extern Window DAWindow, DALeader, DAIcon; /* see [NOTE] */ | |
127 | extern int DADepth; | |
128 | extern Visual *DAVisual; | |
129 | extern GC DAGC, DAClearGC; | |
130 | extern DARect DANoRect; | |
131 | 131 | extern unsigned long DAExpectedVersion; |
132 | 132 | |
133 | 133 | /* [NOTE] |
158 | 158 | * in windowed mode. |
159 | 159 | */ |
160 | 160 | void DAParseArguments(int argc, char **argv, DAProgramOption *options, |
161 | int count, char *programDescription, char *versionDescription); | |
161 | int count, char *programDescription, char *versionDescription); | |
162 | 162 | |
163 | 163 | /* |
164 | 164 | * DAInitialize- |
183 | 183 | */ |
184 | 184 | |
185 | 185 | void DAInitialize(char *display, char *name, unsigned width, unsigned height, |
186 | int argc, char **argv); | |
186 | int argc, char **argv); | |
187 | 187 | |
188 | 188 | void DAOpenDisplay(char *display, int argc, char **argv); |
189 | 189 | |
190 | 190 | void DACreateIcon(char *name, unsigned width, unsigned height, |
191 | int argc, char **argv); | |
191 | int argc, char **argv); | |
192 | 192 | |
193 | 193 | void DAProposeIconSize(unsigned width, unsigned height); |
194 | 194 | |
202 | 202 | * only. |
203 | 203 | * XXX: Argument list is a kludge. |
204 | 204 | */ |
205 | Display* DAGetDisplay(char *d, ...); | |
205 | Display *DAGetDisplay(char *d, ...); | |
206 | 206 | void DASetDisplay(Display *display); |
207 | 207 | |
208 | 208 | /* Get program name (from argv[0]). Returns a reference. */ |
209 | char* DAGetProgramName(); | |
209 | char *DAGetProgramName(); | |
210 | 210 | |
211 | 211 | /* Get/Set DAWindow and DALeader values respectively. For use with external code. */ |
212 | 212 | Window DAGetWindow(void); |
223 | 223 | void DASetDepth(int depth); |
224 | 224 | |
225 | 225 | /* Get/Set DAVisual; the visual type for the screen. For use with external code. */ |
226 | Visual* DAGetVisual(void); | |
226 | Visual *DAGetVisual(void); | |
227 | 227 | void DASetVisual(Visual *visual); |
228 | 228 | |
229 | 229 | |
236 | 236 | * This is only needed if you want the dockapp to be shaped. |
237 | 237 | */ |
238 | 238 | #define DASetShape(shapeMask) \ |
239 | (DASetShapeWithOffset((shapeMask), 0, 0)) | |
239 | (DASetShapeWithOffset((shapeMask), 0, 0)) | |
240 | 240 | #define DASetShapeForWindow(window, shapeMask) \ |
241 | (DASetShapeWithOffsetForWindow((window), (shapeMask), 0, 0)) | |
241 | (DASetShapeWithOffsetForWindow((window), (shapeMask), 0, 0)) | |
242 | 242 | |
243 | 243 | void DASetShapeWithOffset(Pixmap shapeMask, int x_ofs, int y_ofs); |
244 | 244 | void DASetShapeWithOffsetForWindow(Window window, Pixmap shapeMask, |
245 | int x_ofs, int y_ofs); | |
245 | int x_ofs, int y_ofs); | |
246 | 246 | /* |
247 | 247 | * DASetPixmap- |
248 | 248 | * Sets the image pixmap for the dockapp. Once you set the image with it, |
270 | 270 | * Returns true on success, false on failure. |
271 | 271 | */ |
272 | 272 | Bool DAMakePixmapFromData(char **data, Pixmap *pixmap, Pixmap *mask, |
273 | unsigned short *width, unsigned short *height); | |
273 | unsigned short *width, unsigned short *height); | |
274 | 274 | |
275 | 275 | /* |
276 | 276 | * DAMakePixmapFromFile- |
278 | 278 | * Returns true on success, false on failure. |
279 | 279 | */ |
280 | 280 | Bool DAMakePixmapFromFile(char *filename, Pixmap *pixmap, Pixmap *mask, |
281 | unsigned short *width, unsigned short *height); | |
281 | unsigned short *width, unsigned short *height); | |
282 | 282 | |
283 | 283 | /* |
284 | 284 | * DAMakeShapedPixmap- |
285 | 285 | * Creates a shaped pixmap with width & height of dockapp window. |
286 | 286 | */ |
287 | DAShapedPixmap* DAMakeShapedPixmap(); | |
287 | DAShapedPixmap *DAMakeShapedPixmap(); | |
288 | 288 | |
289 | 289 | /* |
290 | 290 | * DAMakeShapedPixmapFromData- |
291 | * Creates a shaped pixmap from XPM-data. | |
292 | * Returns shaped pixmap on success, NULL on failure. | |
293 | */ | |
294 | DAShapedPixmap* DAMakeShapedPixmapFromData(char **data); | |
291 | * Creates a shaped pixmap from XPM-data. | |
292 | * Returns shaped pixmap on success, NULL on failure. | |
293 | */ | |
294 | DAShapedPixmap *DAMakeShapedPixmapFromData(char **data); | |
295 | 295 | |
296 | 296 | /* |
297 | 297 | * DAMakeShapedPixmapFromFile- |
298 | * Creates a shaped pixmap from an XPM file. | |
299 | * Returns shaped pixmap on success, NULL on failure. | |
300 | */ | |
301 | DAShapedPixmap* DAMakeShapedPixmapFromFile(char *filename); | |
298 | * Creates a shaped pixmap from an XPM file. | |
299 | * Returns shaped pixmap on success, NULL on failure. | |
300 | */ | |
301 | DAShapedPixmap *DAMakeShapedPixmapFromFile(char *filename); | |
302 | 302 | |
303 | 303 | /* |
304 | 304 | * DAFreeShapedPixmap- |
305 | * Free memory reserved for a ShapedPixmap | |
305 | * Free memory reserved for a ShapedPixmap | |
306 | 306 | */ |
307 | 307 | void DAFreeShapedPixmap(DAShapedPixmap *dasp); |
308 | 308 | |
309 | 309 | /* |
310 | 310 | * DASPCopyArea- |
311 | * Copies shape-mask and pixmap-data from an area in one shaped pixmap | |
311 | * Copies shape-mask and pixmap-data from an area in one shaped pixmap | |
312 | 312 | * into another shaped pixmap. |
313 | 313 | */ |
314 | 314 | void DASPCopyArea(DAShapedPixmap *src, DAShapedPixmap *dst, |
315 | int x1, int y1, int w, int h, int x2, int y2); | |
315 | int x1, int y1, int w, int h, int x2, int y2); | |
316 | 316 | |
317 | 317 | /* |
318 | 318 | * DASPClear- |
319 | * Clears a shaped pixmaps contents. | |
319 | * Clears a shaped pixmaps contents. | |
320 | 320 | */ |
321 | 321 | void DASPClear(DAShapedPixmap *dasp); |
322 | 322 | |
323 | 323 | /* DASPShow- |
324 | * Displays the pixmap in the dockapp-window. | |
324 | * Displays the pixmap in the dockapp-window. | |
325 | 325 | */ |
326 | 326 | void DASPSetPixmap(DAShapedPixmap *dasp); |
327 | 327 | void DASPSetPixmapForWindow(Window window, DAShapedPixmap *dasp); |
342 | 342 | |
343 | 343 | /* |
344 | 344 | * DAShowWindow- |
345 | * Display a window. Also displays subwindows if it is the dockapp leader | |
346 | * window (DALeader). | |
345 | * Display a window. Also displays subwindows if it is the dockapp leader | |
346 | * window (DALeader). | |
347 | 347 | */ |
348 | 348 | void DAShowWindow(Window window); |
349 | 349 | |
390 | 390 | |
391 | 391 | /* |
392 | 392 | * DAProcessActionRects- |
393 | * Processes the current coordinates with one of the functions in | |
393 | * Processes the current coordinates with one of the functions in | |
394 | 394 | * the array of action rectangles. Coordinates are converted to relative |
395 | 395 | * coordinates in one of the rectangles. The last item in the array of |
396 | 396 | * action rectangles must be NULL. |
397 | 397 | */ |
398 | 398 | void DAProcessActionRects(int x, int y, DAActionRect *actionrects, |
399 | int count, void *data); | |
399 | int count, void *data); | |
400 | 400 | |
401 | 401 | |
402 | 402 | /* |