1 /* Copyright (C) 2016 by Jeremy Tan */
2 /*
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are met:
5
6 * Redistributions of source code must retain the above copyright notice, this
7 * list of conditions and the following disclaimer.
8
9 * Redistributions in binary form must reproduce the above copyright notice,
10 * this list of conditions and the following disclaimer in the documentation
11 * and/or other materials provided with the distribution.
12
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
14 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
16 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
17 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
18 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
19 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
20 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
21 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25 #include <fontforge-config.h>
26
27 /**
28 * @file ggdkdrawlogger.c
29 * @brief Implement logging and error handling functions
30 */
31
32 #include "ggdkdrawP.h"
33
34 #ifdef FONTFORGE_CAN_USE_GDK
35 #include <stdarg.h>
36 #include <stdio.h>
37 #include <string.h>
38
39 static const char *unspecified_funct = "???";
40 static int log_level = LOGWARN;
41
42 /**
43 * Initialise the logger
44 */
LogInit(void)45 void LogInit(void) {
46 const char *requested = getenv("GGDK_LOGLEVEL");
47
48 if (requested) {
49 if (!strcmp(requested, "none")) {
50 log_level = LOGNONE;
51 } else if (!strcmp(requested, "error")) {
52 log_level = LOGERR;
53 } else if (!strcmp(requested, "warn")) {
54 log_level = LOGWARN;
55 } else if (!strcmp(requested, "info")) {
56 log_level = LOGINFO;
57 } else if (!strcmp(requested, "debug") || !strcmp(requested, "all")) {
58 log_level = LOGDEBUG;
59 }
60 }
61 }
62
63 /**
64 * Print a message to stderr and log it via syslog. The message must be
65 * less than BUFSIZ characters long, or it will be truncated.
66 * @param level - Specify how severe the message is.
67 If level is higher (less urgent) than the program's verbosity (see options.h) no message will be printed
68 * @param funct - String indicating the function name from which this function was called.
69 If this is NULL, Log will show the unspecified_funct string instead
70 * @param file - Source file containing the function
71 * @param line - Line in the source file at which Log is called
72 * @param fmt - A format string
73 * @param ... - Arguments to be printed according to the format string
74 */
LogEx(int level,const char * funct,const char * file,int line,const char * fmt,...)75 void LogEx(int level, const char *funct, const char *file, int line, const char *fmt, ...) {
76 char buffer[BUFSIZ];
77 va_list va;
78
79 if (level > log_level) {
80 return;
81 }
82
83 va_start(va, fmt);
84 vsnprintf(buffer, BUFSIZ, fmt, va);
85 va_end(va);
86
87 if (funct == NULL) {
88 funct = unspecified_funct;
89 }
90
91 // Make a human readable severity string
92 const char *severity;
93 switch (level) {
94 case LOGERR:
95 severity = "ERROR";
96 break;
97 case LOGWARN:
98 severity = "WARNING";
99 break;
100 case LOGINFO:
101 severity = "INFO";
102 break;
103 default:
104 severity = "DEBUG";
105 break;
106 }
107
108 GDateTime *now = g_date_time_new_now_local();
109 fprintf(stderr, "%02d:%02d:%02.3f %s: %s (%s:%d) - %s\n",
110 g_date_time_get_hour(now), g_date_time_get_minute(now),
111 g_date_time_get_seconds(now),
112 severity, funct, file, line, buffer);
113 fflush(stderr);
114 g_date_time_unref(now);
115 }
116
GdkEventName(int code)117 const char *GdkEventName(int code) {
118 switch (code) {
119 case GDK_NOTHING:
120 return "GDK_NOTHING";
121 break;
122 case GDK_DELETE:
123 return "GDK_DELETE";
124 break;
125 case GDK_DESTROY:
126 return "GDK_DESTROY";
127 break;
128 case GDK_EXPOSE:
129 return "GDK_EXPOSE";
130 break;
131 case GDK_MOTION_NOTIFY:
132 return "GDK_MOTION_NOTIFY";
133 break;
134 case GDK_BUTTON_PRESS:
135 return "GDK_BUTTON_PRESS";
136 break;
137 case GDK_2BUTTON_PRESS:
138 return "GDK_2BUTTON_PRESS";
139 break;
140 case GDK_3BUTTON_PRESS:
141 return "GDK_3BUTTON_PRESS";
142 break;
143 case GDK_BUTTON_RELEASE:
144 return "GDK_BUTTON_RELEASE";
145 break;
146 case GDK_KEY_PRESS:
147 return "GDK_KEY_PRESS";
148 break;
149 case GDK_KEY_RELEASE:
150 return "GDK_KEY_RELEASE";
151 break;
152 case GDK_ENTER_NOTIFY:
153 return "GDK_ENTER_NOTIFY";
154 break;
155 case GDK_LEAVE_NOTIFY:
156 return "GDK_LEAVE_NOTIFY";
157 break;
158 case GDK_FOCUS_CHANGE:
159 return "GDK_FOCUS_CHANGE";
160 break;
161 case GDK_CONFIGURE:
162 return "GDK_CONFIGURE";
163 break;
164 case GDK_MAP:
165 return "GDK_MAP";
166 break;
167 case GDK_UNMAP:
168 return "GDK_UNMAP";
169 break;
170 case GDK_PROPERTY_NOTIFY:
171 return "GDK_PROPERTY_NOTIFY";
172 break;
173 case GDK_SELECTION_CLEAR:
174 return "GDK_SELECTION_CLEAR";
175 break;
176 case GDK_SELECTION_REQUEST:
177 return "GDK_SELECTION_REQUEST";
178 break;
179 case GDK_SELECTION_NOTIFY:
180 return "GDK_SELECTION_NOTIFY";
181 break;
182 case GDK_PROXIMITY_IN:
183 return "GDK_PROXIMITY_IN";
184 break;
185 case GDK_PROXIMITY_OUT:
186 return "GDK_PROXIMITY_OUT";
187 break;
188 case GDK_DRAG_ENTER:
189 return "GDK_DRAG_ENTER";
190 break;
191 case GDK_DRAG_LEAVE:
192 return "GDK_DRAG_LEAVE";
193 break;
194 case GDK_DRAG_MOTION:
195 return "GDK_DRAG_MOTION";
196 break;
197 case GDK_DRAG_STATUS:
198 return "GDK_DRAG_STATUS";
199 break;
200 case GDK_DROP_START:
201 return "GDK_DROP_START";
202 break;
203 case GDK_DROP_FINISHED:
204 return "GDK_DROP_FINISHED";
205 break;
206 case GDK_CLIENT_EVENT:
207 return "GDK_CLIENT_EVENT";
208 break;
209 case GDK_VISIBILITY_NOTIFY:
210 return "GDK_VISIBILITY_NOTIFY";
211 break;
212 case GDK_SCROLL:
213 return "GDK_SCROLL";
214 break;
215 case GDK_WINDOW_STATE:
216 return "GDK_WINDOW_STATE";
217 break;
218 case GDK_SETTING:
219 return "GDK_SETTING";
220 break;
221 case GDK_OWNER_CHANGE:
222 return "GDK_OWNER_CHANGE";
223 break;
224 case GDK_GRAB_BROKEN:
225 return "GDK_GRAB_BROKEN";
226 break;
227 case GDK_DAMAGE:
228 return "GDK_DAMAGE";
229 break;
230 case GDK_TOUCH_BEGIN:
231 return "GDK_TOUCH_BEGIN";
232 break;
233 case GDK_TOUCH_UPDATE:
234 return "GDK_TOUCH_UPDATE";
235 break;
236 case GDK_TOUCH_END:
237 return "GDK_TOUCH_END";
238 break;
239 case GDK_TOUCH_CANCEL:
240 return "GDK_TOUCH_CANCEL";
241 break;
242 #ifdef GGDKDRAW_GDK_3_20
243 case GDK_TOUCHPAD_SWIPE:
244 return "GDK_TOUCHPAD_SWIPE";
245 break;
246 case GDK_TOUCHPAD_PINCH:
247 return "GDK_TOUCHPAD_PINCH";
248 break;
249 #endif
250 case GDK_EVENT_LAST:
251 return "GDK_EVENT_LAST";
252 break;
253 default:
254 return "UNKNOWN";
255 }
256 }
257
258 #endif // FONTFORGE_CAN_USE_GDK
259