Initial check-in
[him-cellwriter] / src / common.h
1
2 /*
3
4 cellwriter -- a character recognition input method
5 Copyright (C) 2007 Michael Levin <risujin@risujin.org>
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20
21 */
22
23 #include <gtk/gtk.h>
24 #include <math.h>
25
26 /*
27         Limits
28 */
29
30 #define HISTORY_MAX 8
31 #define KEYBOARD_SIZE_MIN 480
32
33 /*
34         Single instance protection
35 */
36
37 typedef void (*SingleInstanceFunc)(const char *msg);
38
39 int single_instance_init(SingleInstanceFunc callback, const char *str);
40 void single_instance_cleanup(void);
41
42 /*
43         Unicode blocks
44 */
45
46 typedef struct {
47         short enabled;
48         const int start, end;
49         const char *name;
50 } UnicodeBlock;
51
52 extern UnicodeBlock unicode_blocks[];
53
54 /*
55         Profile
56 */
57
58 extern int profile_line, profile_read_only;
59
60 const char *profile_read(void);
61 int profile_write(const char *str);
62 int profile_sync_int(int *var);
63 int profile_sync_short(short *var);
64
65 /*
66         Window
67 */
68
69 enum {
70         WINDOW_UNDOCKED = 0,
71         WINDOW_DOCKED_TOP,
72         WINDOW_DOCKED_BOTTOM,
73 };
74
75 extern GtkWidget *window;
76 extern GtkTooltips *tooltips;
77 extern int window_force_show, window_force_hide, window_force_x, window_force_y,
78            window_force_docked, window_struts,
79            window_embedded, window_button_labels, window_show_info,
80            window_docked, style_colors;
81
82 void window_create(GtkWidget *parent);
83 void window_sync(void);
84 void window_cleanup(void);
85 void window_show(void);
86 void window_hide(void);
87 void window_toggle(void);
88 void window_pack(void);
89 void window_update_colors(void);
90 void window_set_docked(int mode);
91 void unicode_block_toggle(int block, int on);
92 void blocks_sync(void);
93 void startup_splash_show(void);
94
95
96 void read_profile();
97
98 /*
99         GTK/GDK/Glib specific
100 */
101
102 /* Multiply to convert RGB to GDK color */
103 #define COLOR_SCALE 256
104
105 /* Constants may not have been defined if GLib is not included */
106 #ifndef TRUE
107 #define TRUE 1
108 #endif
109 #ifndef FALSE
110 #define FALSE 0
111 #endif
112 #ifndef NULL
113 #define NULL ((void*)0)
114 #endif
115
116 /* A macro used to initialize GdkColor with RGB values */
117 #define RGB_TO_GDKCOLOR(r, g, b) {0, (r) * 256, (g) * 256, (b) * 256 }
118
119 static inline void cairo_set_source_gdk_color(cairo_t *cairo,
120                                               const GdkColor *color,
121                                               double alpha)
122 /* Set the cairo source color from a GdkColor */
123 {
124         cairo_set_source_rgba(cairo, color->red / 65535.,
125                                      color->green / 65535.,
126                                      color->blue / 65535., alpha);
127 }
128
129 static inline void cairo_pattern_add_gdk_color_stop(cairo_pattern_t *pattern,
130                                                     double offset,
131                                                     GdkColor *color,
132                                                     double alpha)
133 /* Add a GdkColor color stop to a cairo pattern */
134 {
135         cairo_pattern_add_color_stop_rgba(pattern, offset,
136                                           color->red / 65535.,
137                                           color->green / 65535.,
138                                           color->blue / 65535., alpha);
139 }
140
141 static inline int gdk_colors_equal(GdkColor *a, GdkColor *b)
142 /* Check if two GdkColor structures are equal */
143 {
144         return a->red == b->red && a->green == b->green && a->blue == b->blue;
145 }
146
147 void highlight_gdk_color(const GdkColor *base, GdkColor *out, double value);
148 void scale_gdk_color(const GdkColor *base, GdkColor *out, double value);
149 void shade_gdk_color(const GdkColor *base, GdkColor *out, double value);
150 void gdk_color_to_hsl(const GdkColor *src,
151                       double *hue, double *sat, double *lit);
152 void hsl_to_gdk_color(GdkColor *src, double hue, double sat, double lit);
153
154 /*
155         Error logging and variable argument parsing
156 */
157
158 /* Function traces */
159 #define LOG_LEVEL_TRACE (G_LOG_LEVEL_DEBUG << 1)
160 #define trace(...) trace_full(__FILE__, __FUNCTION__, __VA_ARGS__)
161
162 /* Log detail level */
163 extern int log_level;
164
165 #ifdef _EFISTDARG_H_
166 char *nvav(int *plen, const char *format, va_list va);
167 #endif
168 char *nva(int *length, const char *format, ...);
169 char *va(const char *format, ...);
170 void log_errno(const char *message);
171 void log_print(const char *format, ...);
172 void trace_full(const char *file, const char *func, const char *fmt, ...);
173
174 /*
175         Angles
176 */
177
178 /* Size of the ANGLE data type in bytes */
179 #define ANGLE_SIZE 2
180
181 #if (ANGLE_SIZE == 4)
182
183 /* High-precision angle type */
184 typedef int ANGLE;
185 #define ANGLE_PI 2147483648
186
187 #elif (ANGLE_SIZE == 2)
188
189 /* Medium-precision angle type */
190 typedef short ANGLE;
191 #define ANGLE_PI 32768
192
193 #else
194
195 /* Low-precision angle type */
196 typedef signed char ANGLE;
197 #define ANGLE_PI 128
198
199 #endif
200
201 /*
202         2D Vector
203 */
204
205 typedef struct Vec2 {
206         float x, y;
207 } Vec2;
208
209 static inline void vec2_set(Vec2 *dest, float x, float y)
210 {
211         dest->x = x;
212         dest->y = y;
213 }
214 #define vec2_from_coords vec2_set
215
216 static inline void vec2_copy(Vec2 *dest, const Vec2 *src)
217 {
218         dest->x = src->x;
219         dest->y = src->y;
220 }
221
222 static inline void vec2_sub(Vec2 *dest, const Vec2 *a, const Vec2 *b)
223 {
224         dest->x = a->x - b->x;
225         dest->y = a->y - b->y;
226 }
227
228 static inline void vec2_sum(Vec2 *dest, const Vec2 *a, const Vec2 *b)
229 {
230         dest->x = a->x + b->x;
231         dest->y = a->y + b->y;
232 }
233
234 static inline float vec2_dot(const Vec2 *a, const Vec2 *b)
235 {
236         return a->x * b->x + a->y * b->y;
237 }
238
239 static inline float vec2_cross(const Vec2 *a, const Vec2 *b)
240 {
241         return a->y * b->x - b->y * a->x;
242 }
243
244 static inline void vec2_scale(Vec2 *dest, const Vec2 *src, float scale)
245 {
246         dest->x = src->x * scale;
247         dest->y = src->y * scale;
248 }
249
250 static inline void vec2_avg(Vec2 *dest, const Vec2 *a, const Vec2 *b,
251                             float scale)
252 {
253         dest->x = a->x + (b->x - a->x) * scale;
254         dest->y = a->y + (b->y - a->y) * scale;
255 }
256
257 static inline float vec2_square(const Vec2 *src)
258 {
259         return src->x * src->x + src->y * src->y;
260 }
261
262 static inline float vec2_mag(const Vec2 *src)
263 {
264         return sqrt(src->x * src->x + src->y * src->y);
265 }
266
267 static inline ANGLE vec2_angle(const Vec2 *src)
268 {
269         return (ANGLE)(atan2f(src->y, src->x) * ANGLE_PI / M_PI + 0.5f);
270 }
271
272 static inline float vec2_norm(Vec2 *dest, const Vec2 *a)
273 {
274         float mag = vec2_mag(a);
275         dest->x = a->x / mag;
276         dest->y = a->y / mag;
277         return mag;
278 }
279
280 static inline void vec2_proj(Vec2 *dest, const Vec2 *a, const Vec2 *b)
281 {
282         float dist = vec2_dot(a, b), mag = vec2_mag(b), mag2 = mag * mag;
283         dest->x = dist * b->x / mag2;
284         dest->y = dist * b->y / mag2;
285 }
286
287 static inline void vec2_from_angle(Vec2 *dest, ANGLE angle, float mag)
288 {
289         dest->y = sinf(angle * M_PI / ANGLE_PI) * mag;
290         dest->x = cosf(angle * M_PI / ANGLE_PI) * mag;
291 }
292