1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  ftserv.h                                                               */
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*    The FreeType services (specification only).                          */
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  Copyright 2003-2007, 2009, 2012, 2013 by                               */
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  This file is part of the FreeType project, and may only be used,       */
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  modified, and distributed under the terms of the FreeType project      */
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  this file you indicate that you have read the license and              */
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  understand and accept it fully.                                        */
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*  Each module can export one or more `services'.  Each service is      */
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*  identified by a constant string and modeled by a pointer; the latter */
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*  generally corresponds to a structure containing function pointers.   */
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*  Note that a service's data cannot be a mere function pointer because */
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*  in C it is possible that function pointers might be implemented      */
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*  differently than data pointers (e.g. 48 bits instead of 32).         */
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef __FTSERV_H__
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define __FTSERV_H__
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFT_BEGIN_HEADER
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   * @macro:
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *   FT_FACE_FIND_SERVICE
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   * @description:
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *   This macro is used to look up a service from a face's driver module.
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   * @input:
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *   face ::
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *     The source face handle.
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *   id ::
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *     A string describing the service as defined in the service's
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *     header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *     `multi-masters').  It is automatically prefixed with
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *     `FT_SERVICE_ID_'.
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   * @output:
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *   ptr ::
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *     A variable that receives the service pointer.  Will be NULL
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *     if not found.
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   */
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef __cplusplus
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_FACE_FIND_SERVICE( face, ptr, id )                               \
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_BEGIN_STMNT                                                            \
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Module    module = FT_MODULE( FT_FACE( face )->driver );             \
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Pointer   _tmp_  = NULL;                                             \
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Pointer*  _pptr_ = (FT_Pointer*)&(ptr);                              \
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( module->clazz->get_interface )                                     \
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *_pptr_ = _tmp_;                                                        \
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_END_STMNT
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* !C++ */
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_FACE_FIND_SERVICE( face, ptr, id )                               \
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_BEGIN_STMNT                                                            \
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Module   module = FT_MODULE( FT_FACE( face )->driver );              \
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Pointer  _tmp_  = NULL;                                              \
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( module->clazz->get_interface )                                     \
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ptr = _tmp_;                                                            \
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_END_STMNT
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* !C++ */
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   * @macro:
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *   FT_FACE_FIND_GLOBAL_SERVICE
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   * @description:
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *   This macro is used to look up a service from all modules.
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   * @input:
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *   face ::
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *     The source face handle.
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *   id ::
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *     A string describing the service as defined in the service's
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *     header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *     `multi-masters').  It is automatically prefixed with
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *     `FT_SERVICE_ID_'.
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   * @output:
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *   ptr ::
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *     A variable that receives the service pointer.  Will be NULL
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *     if not found.
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   */
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef __cplusplus
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )               \
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_BEGIN_STMNT                                                   \
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Module    module = FT_MODULE( FT_FACE( face )->driver );    \
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Pointer   _tmp_;                                            \
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Pointer*  _pptr_ = (FT_Pointer*)&(ptr);                     \
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                   \
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                   \
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *_pptr_ = _tmp_;                                               \
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_END_STMNT
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* !C++ */
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )               \
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_BEGIN_STMNT                                                   \
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Module   module = FT_MODULE( FT_FACE( face )->driver );     \
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Pointer  _tmp_;                                             \
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                   \
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                   \
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ptr   = _tmp_;                                                 \
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_END_STMNT
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* !C++ */
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*****                                                               *****/
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*****         S E R V I C E   D E S C R I P T O R S                 *****/
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*****                                                               *****/
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  The following structure is used to _describe_ a given service
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  to the library.  This is useful to build simple static service lists.
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   */
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  typedef struct  FT_ServiceDescRec_
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const char*  serv_id;     /* service name         */
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const void*  serv_data;   /* service pointer/data */
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  } FT_ServiceDescRec;
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  typedef const FT_ServiceDescRec*  FT_ServiceDesc;
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* <Macro>                                                               */
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    FT_DEFINE_SERVICEDESCREC1                                          */
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    FT_DEFINE_SERVICEDESCREC2                                          */
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    FT_DEFINE_SERVICEDESCREC3                                          */
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    FT_DEFINE_SERVICEDESCREC4                                          */
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    FT_DEFINE_SERVICEDESCREC5                                          */
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    FT_DEFINE_SERVICEDESCREC6                                          */
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    FT_DEFINE_SERVICEDESCREC7                                          */
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* <Description>                                                         */
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    Used to initialize an array of FT_ServiceDescRec structures.       */
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    When FT_CONFIG_OPTION_PIC is defined a `create' function needs to  */
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    be called with a pointer to return an allocated array.  As soon as */
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    it is no longer needed, a `destroy' function needs to be called to */
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    release that allocation.                                           */
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    These functions should be manually called from the `pic_init' and  */
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    `pic_free' functions of your module (see FT_DEFINE_MODULE).        */
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    When FT_CONFIG_OPTION_PIC is not defined the array will be         */
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    allocated in the global scope (or the scope where the macro is     */
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    used).                                                             */
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_CONFIG_OPTION_PIC
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_DEFINE_SERVICEDESCREC1( class_,                                  \
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_1, serv_data_1 )                 \
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static const FT_ServiceDescRec  class_[] =                                \
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {                                                                         \
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_1, serv_data_1 },                                             \
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { NULL, NULL }                                                          \
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_DEFINE_SERVICEDESCREC2( class_,                                  \
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_1, serv_data_1,                  \
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_2, serv_data_2 )                 \
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static const FT_ServiceDescRec  class_[] =                                \
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {                                                                         \
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_1, serv_data_1 },                                             \
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_2, serv_data_2 },                                             \
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { NULL, NULL }                                                          \
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_DEFINE_SERVICEDESCREC3( class_,                                  \
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_1, serv_data_1,                  \
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_2, serv_data_2,                  \
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_3, serv_data_3 )                 \
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static const FT_ServiceDescRec  class_[] =                                \
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {                                                                         \
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_1, serv_data_1 },                                             \
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_2, serv_data_2 },                                             \
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_3, serv_data_3 },                                             \
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { NULL, NULL }                                                          \
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_DEFINE_SERVICEDESCREC4( class_,                                  \
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_1, serv_data_1,                  \
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_2, serv_data_2,                  \
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_3, serv_data_3,                  \
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_4, serv_data_4 )                 \
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static const FT_ServiceDescRec  class_[] =                                \
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {                                                                         \
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_1, serv_data_1 },                                             \
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_2, serv_data_2 },                                             \
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_3, serv_data_3 },                                             \
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_4, serv_data_4 },                                             \
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { NULL, NULL }                                                          \
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_DEFINE_SERVICEDESCREC5( class_,                                  \
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_1, serv_data_1,                  \
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_2, serv_data_2,                  \
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_3, serv_data_3,                  \
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_4, serv_data_4,                  \
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_5, serv_data_5 )                 \
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static const FT_ServiceDescRec  class_[] =                                \
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {                                                                         \
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_1, serv_data_1 },                                             \
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_2, serv_data_2 },                                             \
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_3, serv_data_3 },                                             \
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_4, serv_data_4 },                                             \
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_5, serv_data_5 },                                             \
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { NULL, NULL }                                                          \
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_DEFINE_SERVICEDESCREC6( class_,                                  \
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_1, serv_data_1,                  \
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_2, serv_data_2,                  \
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_3, serv_data_3,                  \
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_4, serv_data_4,                  \
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_5, serv_data_5,                  \
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_6, serv_data_6 )                 \
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static const FT_ServiceDescRec  class_[] =                                \
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {                                                                         \
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_1, serv_data_1 },                                             \
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_2, serv_data_2 },                                             \
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_3, serv_data_3 },                                             \
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_4, serv_data_4 },                                             \
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_5, serv_data_5 },                                             \
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_6, serv_data_6 },                                             \
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { NULL, NULL }                                                          \
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_DEFINE_SERVICEDESCREC7( class_,                                  \
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_1, serv_data_1,                  \
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_2, serv_data_2,                  \
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_3, serv_data_3,                  \
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_4, serv_data_4,                  \
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_5, serv_data_5,                  \
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_6, serv_data_6,                  \
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_7, serv_data_7 )                 \
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static const FT_ServiceDescRec  class_[] =                                \
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {                                                                         \
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_1, serv_data_1 },                                             \
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_2, serv_data_2 },                                             \
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_3, serv_data_3 },                                             \
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_4, serv_data_4 },                                             \
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_5, serv_data_5 },                                             \
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_6, serv_data_6 },                                             \
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { serv_id_7, serv_data_7 },                                             \
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { NULL, NULL }                                                          \
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* FT_CONFIG_OPTION_PIC */
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_DEFINE_SERVICEDESCREC1( class_,                                  \
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_1, serv_data_1 )                 \
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  void                                                                      \
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_Destroy_Class_ ## class_( FT_Library          library,                 \
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               FT_ServiceDescRec*  clazz )                  \
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {                                                                         \
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Memory  memory = library->memory;                                    \
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( clazz )                                                            \
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_FREE( clazz );                                                     \
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }                                                                         \
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_Error                                                                  \
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_Create_Class_ ## class_( FT_Library           library,                 \
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              FT_ServiceDescRec**  output_class )           \
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {                                                                         \
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_ServiceDescRec*  clazz  = NULL;                                      \
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error            error;                                              \
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Memory           memory = library->memory;                           \
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 2 ) )                         \
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return error;                                                         \
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[0].serv_id   = serv_id_1;                                         \
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[0].serv_data = serv_data_1;                                       \
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[1].serv_id   = NULL;                                              \
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[1].serv_data = NULL;                                              \
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *output_class = clazz;                                                  \
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FT_Err_Ok;                                                       \
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_DEFINE_SERVICEDESCREC2( class_,                                  \
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_1, serv_data_1,                  \
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_2, serv_data_2 )                 \
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  void                                                                      \
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_Destroy_Class_ ## class_( FT_Library          library,                 \
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               FT_ServiceDescRec*  clazz )                  \
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {                                                                         \
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Memory  memory = library->memory;                                    \
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( clazz )                                                            \
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_FREE( clazz );                                                     \
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }                                                                         \
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_Error                                                                  \
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_Create_Class_ ## class_( FT_Library           library,                 \
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              FT_ServiceDescRec**  output_class )           \
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {                                                                         \
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_ServiceDescRec*  clazz  = NULL;                                      \
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error            error;                                              \
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Memory           memory = library->memory;                           \
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 3 ) )                         \
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return error;                                                         \
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[0].serv_id   = serv_id_1;                                         \
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[0].serv_data = serv_data_1;                                       \
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[1].serv_id   = serv_id_2;                                         \
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[1].serv_data = serv_data_2;                                       \
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[2].serv_id   = NULL;                                              \
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[2].serv_data = NULL;                                              \
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *output_class = clazz;                                                  \
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FT_Err_Ok;                                                       \
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_DEFINE_SERVICEDESCREC3( class_,                                  \
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_1, serv_data_1,                  \
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_2, serv_data_2,                  \
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_3, serv_data_3 )                 \
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  void                                                                      \
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_Destroy_Class_ ## class_( FT_Library          library,                 \
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               FT_ServiceDescRec*  clazz )                  \
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {                                                                         \
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Memory  memory = library->memory;                                    \
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( clazz )                                                            \
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_FREE( clazz );                                                     \
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }                                                                         \
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_Error                                                                  \
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_Create_Class_ ## class_( FT_Library           library,                 \
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              FT_ServiceDescRec**  output_class )           \
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {                                                                         \
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_ServiceDescRec*  clazz  = NULL;                                      \
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error            error;                                              \
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Memory           memory = library->memory;                           \
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 4 ) )                         \
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return error;                                                         \
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[0].serv_id   = serv_id_1;                                         \
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[0].serv_data = serv_data_1;                                       \
390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[1].serv_id   = serv_id_2;                                         \
391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[1].serv_data = serv_data_2;                                       \
392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[2].serv_id   = serv_id_3;                                         \
393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[2].serv_data = serv_data_3;                                       \
394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[3].serv_id   = NULL;                                              \
395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[3].serv_data = NULL;                                              \
396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *output_class = clazz;                                                  \
398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FT_Err_Ok;                                                       \
400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_DEFINE_SERVICEDESCREC4( class_,                                  \
403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_1, serv_data_1,                  \
404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_2, serv_data_2,                  \
405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_3, serv_data_3,                  \
406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_4, serv_data_4 )                 \
407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  void                                                                      \
408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_Destroy_Class_ ## class_( FT_Library          library,                 \
409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               FT_ServiceDescRec*  clazz )                  \
410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {                                                                         \
411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Memory  memory = library->memory;                                    \
412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( clazz )                                                            \
415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_FREE( clazz );                                                     \
416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }                                                                         \
417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_Error                                                                  \
419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_Create_Class_ ## class_( FT_Library           library,                 \
420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              FT_ServiceDescRec**  output_class )           \
421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {                                                                         \
422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_ServiceDescRec*  clazz  = NULL;                                      \
423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error            error;                                              \
424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Memory           memory = library->memory;                           \
425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 5 ) )                         \
428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return error;                                                         \
429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[0].serv_id   = serv_id_1;                                         \
431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[0].serv_data = serv_data_1;                                       \
432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[1].serv_id   = serv_id_2;                                         \
433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[1].serv_data = serv_data_2;                                       \
434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[2].serv_id   = serv_id_3;                                         \
435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[2].serv_data = serv_data_3;                                       \
436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[3].serv_id   = serv_id_4;                                         \
437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[3].serv_data = serv_data_4;                                       \
438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[4].serv_id   = NULL;                                              \
439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[4].serv_data = NULL;                                              \
440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *output_class = clazz;                                                  \
442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FT_Err_Ok;                                                       \
444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_DEFINE_SERVICEDESCREC5( class_,                                  \
447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_1, serv_data_1,                  \
448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_2, serv_data_2,                  \
449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_3, serv_data_3,                  \
450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_4, serv_data_4,                  \
451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_5, serv_data_5 )                 \
452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  void                                                                      \
453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_Destroy_Class_ ## class_( FT_Library          library,                 \
454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               FT_ServiceDescRec*  clazz )                  \
455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {                                                                         \
456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Memory  memory = library->memory;                                    \
457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( clazz )                                                            \
460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_FREE( clazz );                                                     \
461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }                                                                         \
462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_Error                                                                  \
464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_Create_Class_ ## class_( FT_Library           library,                 \
465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              FT_ServiceDescRec**  output_class )           \
466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {                                                                         \
467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_ServiceDescRec*  clazz  = NULL;                                      \
468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error            error;                                              \
469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Memory           memory = library->memory;                           \
470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 6 ) )                         \
473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return error;                                                         \
474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[0].serv_id   = serv_id_1;                                         \
476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[0].serv_data = serv_data_1;                                       \
477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[1].serv_id   = serv_id_2;                                         \
478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[1].serv_data = serv_data_2;                                       \
479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[2].serv_id   = serv_id_3;                                         \
480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[2].serv_data = serv_data_3;                                       \
481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[3].serv_id   = serv_id_4;                                         \
482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[3].serv_data = serv_data_4;                                       \
483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[4].serv_id   = serv_id_5;                                         \
484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[4].serv_data = serv_data_5;                                       \
485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[5].serv_id   = NULL;                                              \
486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[5].serv_data = NULL;                                              \
487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *output_class = clazz;                                                  \
489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FT_Err_Ok;                                                       \
491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_DEFINE_SERVICEDESCREC6( class_,                                  \
494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_1, serv_data_1,                  \
495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_2, serv_data_2,                  \
496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_3, serv_data_3,                  \
497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_4, serv_data_4,                  \
498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_5, serv_data_5,                  \
499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_6, serv_data_6 )                 \
500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  void                                                                      \
501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_Destroy_Class_ ## class_( FT_Library          library,                 \
502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               FT_ServiceDescRec*  clazz )                  \
503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {                                                                         \
504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Memory  memory = library->memory;                                    \
505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( clazz )                                                            \
508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_FREE( clazz );                                                     \
509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }                                                                         \
510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_Error                                                                  \
512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_Create_Class_ ## class_( FT_Library           library,                 \
513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              FT_ServiceDescRec**  output_class)            \
514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {                                                                         \
515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_ServiceDescRec*  clazz  = NULL;                                      \
516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error            error;                                              \
517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Memory           memory = library->memory;                           \
518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 7 ) )                         \
521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return error;                                                         \
522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[0].serv_id   = serv_id_1;                                         \
524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[0].serv_data = serv_data_1;                                       \
525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[1].serv_id   = serv_id_2;                                         \
526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[1].serv_data = serv_data_2;                                       \
527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[2].serv_id   = serv_id_3;                                         \
528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[2].serv_data = serv_data_3;                                       \
529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[3].serv_id   = serv_id_4;                                         \
530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[3].serv_data = serv_data_4;                                       \
531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[4].serv_id   = serv_id_5;                                         \
532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[4].serv_data = serv_data_5;                                       \
533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[5].serv_id   = serv_id_6;                                         \
534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[5].serv_data = serv_data_6;                                       \
535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[6].serv_id   = NULL;                                              \
536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[6].serv_data = NULL;                                              \
537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *output_class = clazz;                                                  \
539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FT_Err_Ok;                                                       \
541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_DEFINE_SERVICEDESCREC7( class_,                                  \
544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_1, serv_data_1,                  \
545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_2, serv_data_2,                  \
546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_3, serv_data_3,                  \
547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_4, serv_data_4,                  \
548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_5, serv_data_5,                  \
549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_6, serv_data_6,                  \
550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   serv_id_7, serv_data_7 )                 \
551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  void                                                                      \
552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_Destroy_Class_ ## class_( FT_Library          library,                 \
553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               FT_ServiceDescRec*  clazz )                  \
554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {                                                                         \
555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Memory  memory = library->memory;                                    \
556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( clazz )                                                            \
559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_FREE( clazz );                                                     \
560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }                                                                         \
561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_Error                                                                  \
563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_Create_Class_ ## class_( FT_Library           library,                 \
564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              FT_ServiceDescRec**  output_class)            \
565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {                                                                         \
566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_ServiceDescRec*  clazz  = NULL;                                      \
567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error            error;                                              \
568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Memory           memory = library->memory;                           \
569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 8 ) )                         \
572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return error;                                                         \
573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[0].serv_id   = serv_id_1;                                         \
575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[0].serv_data = serv_data_1;                                       \
576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[1].serv_id   = serv_id_2;                                         \
577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[1].serv_data = serv_data_2;                                       \
578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[2].serv_id   = serv_id_3;                                         \
579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[2].serv_data = serv_data_3;                                       \
580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[3].serv_id   = serv_id_4;                                         \
581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[3].serv_data = serv_data_4;                                       \
582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[4].serv_id   = serv_id_5;                                         \
583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[4].serv_data = serv_data_5;                                       \
584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[5].serv_id   = serv_id_6;                                         \
585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[5].serv_data = serv_data_6;                                       \
586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[6].serv_id   = serv_id_7;                                         \
587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[6].serv_data = serv_data_7;                                       \
588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[7].serv_id   = NULL;                                              \
589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    clazz[7].serv_data = NULL;                                              \
590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *output_class = clazz;                                                  \
592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                                            \
593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FT_Err_Ok;                                                       \
594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_CONFIG_OPTION_PIC */
597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*
600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  Parse a list of FT_ServiceDescRec descriptors and look for
601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  a specific service by ID.  Note that the last element in the
602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  array must be { NULL, NULL }, and that the function should
603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  return NULL if the service isn't available.
604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  This function can be used by modules to implement their
606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  `get_service' method.
607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   */
608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_BASE( FT_Pointer )
609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ft_service_list_lookup( FT_ServiceDesc  service_descriptors,
610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                          const char*     service_id );
611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*****                                                               *****/
616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*****             S E R V I C E S   C A C H E                       *****/
617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*****                                                               *****/
618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*
622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  This structure is used to store a cache for several frequently used
623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  services.  It is the type of `face->internal->services'.  You
624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  should only use FT_FACE_LOOKUP_SERVICE to access it.
625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  All fields should have the type FT_Pointer to relax compilation
627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  dependencies.  We assume the developer isn't completely stupid.
628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  Each field must be named `service_XXXX' where `XXX' corresponds to
630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  the correct FT_SERVICE_ID_XXXX macro.  See the definition of
631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  FT_FACE_LOOKUP_SERVICE below how this is implemented.
632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   */
634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  typedef struct  FT_ServiceCacheRec_
635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Pointer  service_POSTSCRIPT_FONT_NAME;
637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Pointer  service_MULTI_MASTERS;
638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Pointer  service_GLYPH_DICT;
639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Pointer  service_PFR_METRICS;
640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Pointer  service_WINFNT;
641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  } FT_ServiceCacheRec, *FT_ServiceCache;
643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*
646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  A magic number used within the services cache.
647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   */
648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* ensure that value `1' has the same width as a pointer */
650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_SERVICE_UNAVAILABLE  ((FT_Pointer)~(FT_PtrDist)1)
651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*
654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   * @macro:
655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *   FT_FACE_LOOKUP_SERVICE
656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   * @description:
658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *   This macro is used to lookup a service from a face's driver module
659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *   using its cache.
660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   * @input:
662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *   face::
663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *     The source face handle containing the cache.
664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *   field ::
666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *     The field name in the cache.
667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *   id ::
669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *     The service ID.
670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   * @output:
672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *   ptr ::
673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *     A variable receiving the service data.  NULL if not available.
674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   */
675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef __cplusplus
676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_FACE_LOOKUP_SERVICE( face, ptr, id )                \
678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_BEGIN_STMNT                                               \
679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Pointer   svc;                                          \
680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Pointer*  Pptr = (FT_Pointer*)&(ptr);                   \
681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                               \
682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                               \
683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    svc = FT_FACE( face )->internal->services. service_ ## id; \
684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( svc == FT_SERVICE_UNAVAILABLE )                       \
685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      svc = NULL;                                              \
686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else if ( svc == NULL )                                    \
687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {                                                          \
688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_FACE_FIND_SERVICE( face, svc, id );                   \
689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                               \
690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_FACE( face )->internal->services. service_ ## id =    \
691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        (FT_Pointer)( svc != NULL ? svc                        \
692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                  : FT_SERVICE_UNAVAILABLE );  \
693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }                                                          \
694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *Pptr = svc;                                               \
695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_END_STMNT
696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* !C++ */
698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_FACE_LOOKUP_SERVICE( face, ptr, id )                \
700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_BEGIN_STMNT                                               \
701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Pointer  svc;                                           \
702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                               \
703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                               \
704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    svc = FT_FACE( face )->internal->services. service_ ## id; \
705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( svc == FT_SERVICE_UNAVAILABLE )                       \
706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      svc = NULL;                                              \
707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else if ( svc == NULL )                                    \
708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {                                                          \
709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_FACE_FIND_SERVICE( face, svc, id );                   \
710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                               \
711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_FACE( face )->internal->services. service_ ## id =    \
712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        (FT_Pointer)( svc != NULL ? svc                        \
713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                  : FT_SERVICE_UNAVAILABLE );  \
714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }                                                          \
715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ptr = svc;                                                 \
716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_END_STMNT
717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* !C++ */
719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*
721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  A macro used to define new service structure types.
722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   */
723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_DEFINE_SERVICE( name )            \
725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  typedef struct FT_Service_ ## name ## Rec_ \
726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Service_ ## name ## Rec ;             \
727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  typedef struct FT_Service_ ## name ## Rec_ \
728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const * FT_Service_ ## name ;            \
729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  struct FT_Service_ ## name ## Rec_
730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* */
732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*
734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  The header files containing the services.
735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   */
736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_SERVICE_BDF_H                <freetype/internal/services/svbdf.h>
738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_SERVICE_CID_H                <freetype/internal/services/svcid.h>
739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_SERVICE_GLYPH_DICT_H         <freetype/internal/services/svgldict.h>
740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_SERVICE_GX_VALIDATE_H        <freetype/internal/services/svgxval.h>
741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_SERVICE_KERNING_H            <freetype/internal/services/svkern.h>
742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_SERVICE_MULTIPLE_MASTERS_H   <freetype/internal/services/svmm.h>
743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_SERVICE_OPENTYPE_VALIDATE_H  <freetype/internal/services/svotval.h>
744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_SERVICE_PFR_H                <freetype/internal/services/svpfr.h>
745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_SERVICE_POSTSCRIPT_CMAPS_H   <freetype/internal/services/svpscmap.h>
746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_SERVICE_POSTSCRIPT_INFO_H    <freetype/internal/services/svpsinfo.h>
747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_SERVICE_POSTSCRIPT_NAME_H    <freetype/internal/services/svpostnm.h>
748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_SERVICE_PROPERTIES_H         <freetype/internal/services/svprop.h>
749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_SERVICE_SFNT_H               <freetype/internal/services/svsfnt.h>
750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_SERVICE_TRUETYPE_ENGINE_H    <freetype/internal/services/svtteng.h>
751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_SERVICE_TT_CMAP_H            <freetype/internal/services/svttcmap.h>
752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_SERVICE_WINFNT_H             <freetype/internal/services/svwinfnt.h>
753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_SERVICE_XFREE86_NAME_H       <freetype/internal/services/svxf86nm.h>
754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_SERVICE_TRUETYPE_GLYF_H      <freetype/internal/services/svttglyf.h>
755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */
757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
758ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFT_END_HEADER
759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* __FTSERV_H__ */
761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* END */
764