1 /*
2  * $Id: cdk_objs.h,v 1.42 2019/02/21 01:31:12 tom Exp $
3  */
4 
5 #ifndef CDKINCLUDES
6 #ifndef CDK_OBJS_H
7 #define CDK_OBJS_H
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 #ifndef CDK_H
14 #define CDKINCLUDES
15 #include <cdk.h>
16 #undef CDKINCLUDES
17 #include <binding.h>
18 #include <cdkscreen.h>
19 #endif
20 
21 /*
22  * Copyright 1999-2012,2019 Thomas E. Dickey
23  * All rights reserved.
24  *
25  * Redistribution and use in source and binary forms, with or without
26  * modification, are permitted provided that the following conditions
27  * are met:
28  * 1. Redistributions of source code must retain the above copyright
29  *    notice, this list of conditions and the following disclaimer.
30  * 2. Redistributions in binary form must reproduce the above copyright
31  *    notice, this list of conditions and the following disclaimer in the
32  *    documentation and/or other materials provided with the distribution.
33  * 3. All advertising materials mentioning features or use of this software
34  *    must display the following acknowledgment:
35  * 	This product includes software developed by Thomas Dickey
36  * 	and contributors.
37  * 4. Neither the name of Thomas Dickey, nor the names of contributors
38  *    may be used to endorse or promote products derived from this software
39  *    without specific prior written permission.
40  *
41  * THIS SOFTWARE IS PROVIDED BY THOMAS DICKEY AND CONTRIBUTORS ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THOMAS DICKEY OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  */
53 
54 typedef struct CDKBINDING {
55    BINDFN       bindFunction;
56    void *       bindData;
57    PROCESSFN    callbackfn;
58 } CDKBINDING;
59 
60 struct CDKOBJS;
61 
62 /*
63  * Types for CDKFUNCS.returnType
64  */
65 typedef enum {
66    DataTypeUnknown = 0
67    , DataTypeString
68    , DataTypeInt
69    , DataTypeFloat
70    , DataTypeDouble
71    , DataTypeUnsigned
72 } CDKDataType;
73 
74 typedef union {
75    char * valueString;
76    int    valueInt;
77    float  valueFloat;
78    double valueDouble;
79    unsigned valueUnsigned;
80 } CDKDataUnion;
81 
82 #define unknownString   (char *)0
83 #define unknownInt      (-1)
84 #define unknownFloat    (0.0)
85 #define unknownDouble   (0.0)
86 #define unknownUnsigned (0)
87 
88 /*
89  * Methods common to all widgets.
90  */
91 typedef struct CDKFUNCS {
92    EObjectType  objectType;
93    CDKDataType  returnType;
94    void         (*drawObj)         (struct CDKOBJS *, boolean);
95    void         (*eraseObj)        (struct CDKOBJS *);
96    void         (*moveObj)         (struct CDKOBJS *, int, int, boolean, boolean);
97    int          (*injectObj)       (struct CDKOBJS *, chtype);
98    void         (*focusObj)        (struct CDKOBJS *);
99    void         (*unfocusObj)      (struct CDKOBJS *);
100    void         (*saveDataObj)     (struct CDKOBJS *);
101    void         (*refreshDataObj)  (struct CDKOBJS *);
102    void         (*destroyObj)      (struct CDKOBJS *);
103    /* line-drawing */
104    void         (*setULcharObj)    (struct CDKOBJS *, chtype);
105    void         (*setURcharObj)    (struct CDKOBJS *, chtype);
106    void         (*setLLcharObj)    (struct CDKOBJS *, chtype);
107    void         (*setLRcharObj)    (struct CDKOBJS *, chtype);
108    void         (*setVTcharObj)    (struct CDKOBJS *, chtype);
109    void         (*setHZcharObj)    (struct CDKOBJS *, chtype);
110    void         (*setBXattrObj)    (struct CDKOBJS *, chtype);
111    /* background attribute */
112    void         (*setBKattrObj)    (struct CDKOBJS *, chtype);
113 } CDKFUNCS;
114 
115 /* The cast is needed because traverse.c wants to use CDKOBJS pointers */
116 #define ObjPtr(p)           ((CDKOBJS*)(p))
117 
118 #define MethodPtr(p,m)      ((ObjPtr(p))->fn->m)
119 
120 /* Use these when we're certain it is a CDKOBJS pointer */
121 #define ObjTypeOf(p)            MethodPtr(p,objectType)
122 #define DataTypeOf(p)           MethodPtr(p,returnType)
123 #define DrawObj(p)              MethodPtr(p,drawObj)         (p,p->box)
124 #define EraseObj(p)             MethodPtr(p,eraseObj)        (p)
125 #define DestroyObj(p)           MethodPtr(p,destroyObj)      (p)
126 #define InjectObj(p,k)          MethodPtr(p,injectObj)       (p,(k))
127 #define InputWindowObj(p)       MethodPtr(p,inputWindowObj)  (p)
128 #define FocusObj(p)             MethodPtr(p,focusObj)        (p)
129 #define UnfocusObj(p)           MethodPtr(p,unfocusObj)      (p)
130 #define SaveDataObj(p)          MethodPtr(p,saveDataObj)     (p)
131 #define RefreshDataObj(p)       MethodPtr(p,refreshDataObj)  (p)
132 #define SetBackAttrObj(p,c)     MethodPtr(p,setBKattrObj)    (p,c)
133 
134 #define AcceptsFocusObj(p)      (ObjPtr(p)->acceptsFocus)
135 #define HasFocusObj(p)          (ObjPtr(p)->hasFocus)
136 #define IsVisibleObj(p)         (ObjPtr(p)->isVisible)
137 #define InputWindowOf(p)        (ObjPtr(p)->inputWindow)
138 
139 /*
140  * Data common to all objects (widget instances).  This appears first in
141  * each widget's struct to allow us to use generic functions in binding.c,
142  * cdkscreen.c, position.c, etc.
143  */
144 typedef struct CDKOBJS {
145    int          screenIndex;
146    CDKSCREEN *  screen;
147    const CDKFUNCS * fn;
148    boolean      box;
149    int          borderSize;
150    boolean      acceptsFocus;
151    boolean      hasFocus;
152    boolean      isVisible;
153    WINDOW *     inputWindow;
154    void *       dataPtr;
155    CDKDataUnion resultData;
156    unsigned     bindingCount;
157    CDKBINDING * bindingList;
158    /* title-drawing */
159    chtype **	title;
160    int *	titlePos;
161    int *	titleLen;
162    int		titleLines;
163    /* line-drawing (see 'box') */
164    chtype       ULChar;		/* lines: upper-left */
165    chtype       URChar;		/* lines: upper-right */
166    chtype       LLChar;		/* lines: lower-left */
167    chtype       LRChar;		/* lines: lower-right */
168    chtype       VTChar;		/* lines: vertical */
169    chtype       HZChar;		/* lines: horizontal */
170    chtype       BXAttr;
171    /* events */
172    EExitType	exitType;
173    EExitType	earlyExit;
174    /* pre/post-processing */
175    PROCESSFN	preProcessFunction;
176    void *	preProcessData;
177    PROCESSFN	postProcessFunction;
178    void *	postProcessData;
179 } CDKOBJS;
180 
181 #define ObjOf(ptr)              (&(ptr)->obj)
182 #define MethodOf(ptr)           (ObjOf(ptr)->fn)
183 #define ScreenOf(ptr)           (ObjOf(ptr)->screen)
184 #define WindowOf(ptr)           (ScreenOf(ptr)->window)
185 #define BorderOf(p)             (ObjOf(p)->borderSize)
186 #define ResultOf(p)             (ObjOf(p)->resultData)
187 #define ExitTypeOf(p)           (ObjOf(p)->exitType)
188 #define EarlyExitOf(p)          (ObjOf(p)->earlyExit)
189 
190 /* titles */
191 #define TitleOf(w)              ObjOf(w)->title
192 #define TitlePosOf(w)           ObjOf(w)->titlePos
193 #define TitleLenOf(w)           ObjOf(w)->titleLen
194 #define TitleLinesOf(w)         ObjOf(w)->titleLines
195 
196 /* line-drawing characters */
197 #define ULCharOf(w)             ObjOf(w)->ULChar
198 #define URCharOf(w)             ObjOf(w)->URChar
199 #define LLCharOf(w)             ObjOf(w)->LLChar
200 #define LRCharOf(w)             ObjOf(w)->LRChar
201 #define VTCharOf(w)             ObjOf(w)->VTChar
202 #define HZCharOf(w)             ObjOf(w)->HZChar
203 #define BXAttrOf(w)             ObjOf(w)->BXAttr
204 
205 #define setULCharOf(o,c)        MethodOf(o)->setULcharObj(ObjOf(o),c)
206 #define setURCharOf(o,c)        MethodOf(o)->setURcharObj(ObjOf(o),c)
207 #define setLLCharOf(o,c)        MethodOf(o)->setLLcharObj(ObjOf(o),c)
208 #define setLRCharOf(o,c)        MethodOf(o)->setLRcharObj(ObjOf(o),c)
209 #define setVTCharOf(o,c)        MethodOf(o)->setVTcharObj(ObjOf(o),c)
210 #define setHZCharOf(o,c)        MethodOf(o)->setHZcharObj(ObjOf(o),c)
211 #define setBXAttrOf(o,c)        MethodOf(o)->setBXattrObj(ObjOf(o),c)
212 #define setBKAttrOf(o,c)        MethodOf(o)->setBKattrObj(ObjOf(o),c)
213 
214    /* pre/post-processing */
215 #define PreProcessFuncOf(w)	(ObjOf(w)->preProcessFunction)
216 #define PreProcessDataOf(w)	(ObjOf(w)->preProcessData)
217 #define PostProcessFuncOf(w)	(ObjOf(w)->postProcessFunction)
218 #define PostProcessDataOf(w)	(ObjOf(w)->postProcessData)
219 
220 /* FIXME - remove this */
221 #define ReturnOf(p)   (ObjPtr(p)->dataPtr)
222 
223 bool validCDKObject (CDKOBJS *);
224 
225 void *  _newCDKObject(unsigned, const CDKFUNCS *);
226 #define newCDKObject(type,funcs) (type *)_newCDKObject(sizeof(type),funcs)
227 
228 void _destroyCDKObject (CDKOBJS *);
229 #define destroyCDKObject(o)            _destroyCDKObject(ObjOf(o))
230 
231 /* Use these for widgets that have an obj member which is a CDKOBJS struct */
232 #define drawCDKObject(o,box)           MethodOf(o)->drawObj       (ObjOf(o),box)
233 #define eraseCDKObject(o)              MethodOf(o)->eraseObj      (ObjOf(o))
234 #define moveCDKObject(o,x,y,rel,ref)   MethodOf(o)->moveObj       (ObjOf(o),x,y,rel,ref)
235 #define injectCDKObject(o,c,type)      (MethodOf(o)->injectObj    (ObjOf(o),c) ? ResultOf(o).value ## type : unknown ## type)
236 
237 /* functions to set line-drawing are bound to cdk_objs.c if the widget is
238  * simple, but are built into the widget for complex widgets.
239  */
240 #define DeclareSetXXchar(storage,line) \
241 storage void line ## ULchar(struct CDKOBJS *, chtype); \
242 storage void line ## URchar(struct CDKOBJS *, chtype); \
243 storage void line ## LLchar(struct CDKOBJS *, chtype); \
244 storage void line ## LRchar(struct CDKOBJS *, chtype); \
245 storage void line ## VTchar(struct CDKOBJS *, chtype); \
246 storage void line ## HZchar(struct CDKOBJS *, chtype); \
247 storage void line ## BXattr(struct CDKOBJS *, chtype)
248 
249 DeclareSetXXchar(extern,setCdk);
250 
251 #define DeclareCDKObjects(upper, mixed, line, type) \
252 static int  _injectCDK ## mixed        (struct CDKOBJS *, chtype); \
253 static void _destroyCDK ## mixed       (struct CDKOBJS *); \
254 static void _drawCDK ## mixed          (struct CDKOBJS *, boolean); \
255 static void _eraseCDK ## mixed         (struct CDKOBJS *); \
256 static void _focusCDK ## mixed         (struct CDKOBJS *); \
257 static void _moveCDK ## mixed          (struct CDKOBJS *, int, int, boolean, boolean); \
258 static void _refreshDataCDK ## mixed   (struct CDKOBJS *); \
259 static void _saveDataCDK ## mixed      (struct CDKOBJS *); \
260 static void _unfocusCDK ## mixed       (struct CDKOBJS *); \
261 static void _setBKattr ## mixed        (struct CDKOBJS *, chtype); \
262 static const CDKFUNCS my_funcs = { \
263    v ## upper, \
264    DataType ## type, \
265    _drawCDK ## mixed, \
266    _eraseCDK ## mixed, \
267    _moveCDK ## mixed, \
268    _injectCDK ## mixed, \
269    _focusCDK ## mixed, \
270    _unfocusCDK ## mixed, \
271    _saveDataCDK ## mixed, \
272    _refreshDataCDK ## mixed, \
273    _destroyCDK ## mixed, \
274    line ## ULchar, \
275    line ## URchar, \
276    line ## LLchar, \
277    line ## LRchar, \
278    line ## VTchar, \
279    line ## HZchar, \
280    line ## BXattr, \
281    _setBKattr ## mixed, \
282 }
283 
284 /*
285  * Some methods are unused.  Define macros to represent dummy methods
286  * to make it simple to maintain them.
287  */
288 #define dummyInject(mixed) \
289 static int _injectCDK ## mixed (CDKOBJS * object GCC_UNUSED, chtype input GCC_UNUSED) \
290 { \
291    return 0; \
292 }
293 
294 #define dummyFocus(mixed) \
295 static void _focusCDK ## mixed (CDKOBJS * object GCC_UNUSED) \
296 { \
297 }
298 
299 #define dummyUnfocus(mixed) \
300 static void _unfocusCDK ## mixed (CDKOBJS * object GCC_UNUSED) \
301 { \
302 }
303 
304 #define dummySaveData(mixed) \
305 static void _saveDataCDK ## mixed (CDKOBJS * object GCC_UNUSED) \
306 { \
307 }
308 
309 #define dummyRefreshData(mixed) \
310 static void _refreshDataCDK ## mixed (CDKOBJS * object GCC_UNUSED) \
311 { \
312 }
313 
314 /*
315  * Read keycode from object, optionally translating bindings.
316  * Depcrecated: use getchCDKObject().
317  */
318 extern int getcCDKObject (
319 		CDKOBJS *	/* object */);
320 
321 /*
322  * Read keycode from object, optionally translating bindings.  Set a flag to
323  * tell if the keycode is a function key.
324  */
325 extern int getchCDKObject (
326 		CDKOBJS *	/* object */,
327 		boolean *	/* functionKey */);
328 
329 /*
330  * Interactively reposition an object within a window.
331  */
332 extern void positionCDKObject (
333 		CDKOBJS *	/* object */,
334 		WINDOW *	/* win */);
335 
336 /*
337  * Pre/postprocessing.
338  */
339 extern void setCDKObjectPreProcess (
340 		CDKOBJS *	/* object */,
341 	        PROCESSFN	/* func */,
342 		void *		/* data */);
343 
344 extern void setCDKObjectPostProcess (
345 		CDKOBJS *	/* object */,
346 	        PROCESSFN	/* func */,
347 		void *		/* data */);
348 
349 /*
350  * Background color.
351  */
352 extern void setCDKObjectBackgroundColor (
353 		CDKOBJS *	/* object */,
354 		const char *	/* color */);
355 
356 /* title-storage is implemented identically with all widgets */
357 extern char * getCdkTitle (CDKOBJS *);
358 extern int setCdkTitle (CDKOBJS *, const char *, int);
359 extern void drawCdkTitle (WINDOW *, CDKOBJS *);
360 extern void cleanCdkTitle (CDKOBJS *);
361 
362 #define setCdkEarlyExit(p,q)    EarlyExitOf(p) = q
363 
364 extern void setCdkExitType(
365 		CDKOBJS *	/* obj */,
366 		EExitType *	/* type */,
367 		chtype		/* ch */);
368 
369 #ifdef __cplusplus
370 }
371 #endif
372 
373 #endif /* CDK_OBJS_H */
374 #endif /* CDKINCLUDES */
375