aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-03-14 11:21:53 +0100
committerDavid Robillard <d@drobilla.net>2020-03-14 11:21:53 +0100
commit554ac923e8973b7496f96e30a56eaaf9d30b6108 (patch)
treea0a3070325edd6e9f89a6267c2c5fd107cf0ae37
parente09f204aca2393ba0f78867eb2e284ab00091205 (diff)
Add logging API
-rw-r--r--pugl/detail/implementation.c44
-rw-r--r--pugl/detail/types.h2
-rw-r--r--pugl/detail/win.c1
-rw-r--r--pugl/detail/x11.c9
-rw-r--r--pugl/detail/x11_cairo.c1
-rw-r--r--pugl/detail/x11_gl.c27
-rw-r--r--pugl/pugl.h38
-rw-r--r--wscript7
8 files changed, 105 insertions, 24 deletions
diff --git a/pugl/detail/implementation.c b/pugl/detail/implementation.c
index 7764bbd..9d3d6b4 100644
--- a/pugl/detail/implementation.c
+++ b/pugl/detail/implementation.c
@@ -22,9 +22,34 @@
#include "pugl/pugl.h"
#include <stdbool.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+static const char*
+puglLogLevelPrefix(const PuglLogLevel level)
+{
+ switch (level) {
+ case PUGL_LOG_LEVEL_ERR:
+ return "error: ";
+ case PUGL_LOG_LEVEL_WARNING:
+ return "warning: ";
+ case PUGL_LOG_LEVEL_INFO:
+ case PUGL_LOG_LEVEL_DEBUG:
+ return "";
+ }
+
+ return "";
+}
+
+static void
+puglDefaultLogFunc(PuglWorld* PUGL_UNUSED(world),
+ PuglLogLevel level,
+ const char* msg)
+{
+ fprintf(stderr, "%s%s", puglLogLevelPrefix(level), msg);
+}
+
const char*
puglStrerror(const PuglStatus status)
{
@@ -98,6 +123,9 @@ puglNewWorld(void)
}
world->startTime = puglGetTime(world);
+ world->logFunc = puglDefaultLogFunc;
+ world->logLevel = PUGL_LOG_LEVEL_INFO;
+
puglSetString(&world->className, "Pugl");
return world;
@@ -125,6 +153,22 @@ puglGetWorldHandle(PuglWorld* world)
}
PuglStatus
+puglSetLogFunc(PuglWorld* world, PuglLogFunc logFunc)
+{
+ world->logFunc = logFunc;
+
+ return PUGL_SUCCESS;
+}
+
+PuglStatus
+puglSetLogLevel(PuglWorld* world, PuglLogLevel level)
+{
+ world->logLevel = level;
+
+ return PUGL_SUCCESS;
+}
+
+PuglStatus
puglSetClassName(PuglWorld* const world, const char* const name)
{
puglSetString(&world->className, name);
diff --git a/pugl/detail/types.h b/pugl/detail/types.h
index 2e41003..08a7854 100644
--- a/pugl/detail/types.h
+++ b/pugl/detail/types.h
@@ -78,10 +78,12 @@ struct PuglViewImpl {
struct PuglWorldImpl {
PuglWorldInternals* impl;
PuglWorldHandle handle;
+ PuglLogFunc logFunc;
char* className;
double startTime;
size_t numViews;
PuglView** views;
+ PuglLogLevel logLevel;
};
/** Opaque surface used by graphics backend. */
diff --git a/pugl/detail/win.c b/pugl/detail/win.c
index bf60ddb..0c8078f 100644
--- a/pugl/detail/win.c
+++ b/pugl/detail/win.c
@@ -29,7 +29,6 @@
#include <math.h>
#include <stdbool.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wctype.h>
diff --git a/pugl/detail/x11.c b/pugl/detail/x11.c
index 25693a2..ee5fb69 100644
--- a/pugl/detail/x11.c
+++ b/pugl/detail/x11.c
@@ -41,7 +41,6 @@
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
@@ -94,9 +93,7 @@ puglInitWorldInternals(void)
XSetLocaleModifiers("");
if (!(impl->xim = XOpenIM(display, NULL, NULL, NULL))) {
XSetLocaleModifiers("@im=");
- if (!(impl->xim = XOpenIM(display, NULL, NULL, NULL))) {
- fprintf(stderr, "warning: XOpenIM failed\n");
- }
+ impl->xim = XOpenIM(display, NULL, NULL, NULL);
}
XFlush(display);
@@ -252,7 +249,9 @@ puglCreateWindow(PuglView* view, const char* title)
XNClientWindow, win,
XNFocusWindow, win,
NULL))) {
- fprintf(stderr, "warning: XCreateIC failed\n");
+ view->world->logFunc(view->world,
+ PUGL_LOG_LEVEL_WARNING,
+ "XCreateID failed\n");
}
const PuglEvent createEvent = {{PUGL_CREATE, 0}};
diff --git a/pugl/detail/x11_cairo.c b/pugl/detail/x11_cairo.c
index b084f5a..d06c0d5 100644
--- a/pugl/detail/x11_cairo.c
+++ b/pugl/detail/x11_cairo.c
@@ -28,7 +28,6 @@
#include <cairo-xlib.h>
#include <cairo.h>
-#include <stdio.h>
#include <stdlib.h>
typedef struct {
diff --git a/pugl/detail/x11_gl.c b/pugl/detail/x11_gl.c
index 5e4a5ca..fec0899 100644
--- a/pugl/detail/x11_gl.c
+++ b/pugl/detail/x11_gl.c
@@ -85,23 +85,28 @@ puglX11GlConfigure(PuglView* view)
int n_fbc = 0;
GLXFBConfig* fbc = glXChooseFBConfig(display, screen, attrs, &n_fbc);
if (n_fbc <= 0) {
- fprintf(stderr, "error: Failed to create GL context\n");
return PUGL_CREATE_CONTEXT_FAILED;
}
surface->fb_config = fbc[0];
impl->vi = glXGetVisualFromFBConfig(impl->display, fbc[0]);
- printf("Using visual 0x%lX: R=%d G=%d B=%d A=%d D=%d"
- " DOUBLE=%d SAMPLES=%d\n",
- impl->vi->visualid,
- puglX11GlGetAttrib(display, fbc[0], GLX_RED_SIZE),
- puglX11GlGetAttrib(display, fbc[0], GLX_GREEN_SIZE),
- puglX11GlGetAttrib(display, fbc[0], GLX_BLUE_SIZE),
- puglX11GlGetAttrib(display, fbc[0], GLX_ALPHA_SIZE),
- puglX11GlGetAttrib(display, fbc[0], GLX_DEPTH_SIZE),
- puglX11GlGetAttrib(display, fbc[0], GLX_DOUBLEBUFFER),
- puglX11GlGetAttrib(display, fbc[0], GLX_SAMPLES));
+ char msg[128];
+
+ snprintf(
+ msg,
+ sizeof(msg),
+ "Using visual 0x%lX: R=%d G=%d B=%d A=%d D=%d DOUBLE=%d SAMPLES=%d\n",
+ impl->vi->visualid,
+ puglX11GlGetAttrib(display, fbc[0], GLX_RED_SIZE),
+ puglX11GlGetAttrib(display, fbc[0], GLX_GREEN_SIZE),
+ puglX11GlGetAttrib(display, fbc[0], GLX_BLUE_SIZE),
+ puglX11GlGetAttrib(display, fbc[0], GLX_ALPHA_SIZE),
+ puglX11GlGetAttrib(display, fbc[0], GLX_DEPTH_SIZE),
+ puglX11GlGetAttrib(display, fbc[0], GLX_DOUBLEBUFFER),
+ puglX11GlGetAttrib(display, fbc[0], GLX_SAMPLES));
+
+ view->world->logFunc(view->world, PUGL_LOG_LEVEL_INFO, msg);
XFree(fbc);
diff --git a/pugl/pugl.h b/pugl/pugl.h
index 718e76a..c5f8969 100644
--- a/pugl/pugl.h
+++ b/pugl/pugl.h
@@ -491,6 +491,27 @@ typedef struct PuglWorldImpl PuglWorld;
typedef void* PuglWorldHandle;
/**
+ A log message level, compatible with syslog.
+*/
+typedef enum {
+ PUGL_LOG_LEVEL_ERR = 3, ///< Error
+ PUGL_LOG_LEVEL_WARNING = 4, ///< Warning
+ PUGL_LOG_LEVEL_INFO = 6, ///< Informational message
+ PUGL_LOG_LEVEL_DEBUG = 7 ///< Debug message
+} PuglLogLevel;
+
+/**
+ A function called to report log messages.
+
+ @param world The world that produced this log message.
+ @param level Log level.
+ @param msg Message string.
+*/
+typedef void (*PuglLogFunc)(PuglWorld* world,
+ PuglLogLevel level,
+ const char* msg);
+
+/**
Create a new world.
@return A new world, which must be later freed with puglFreeWorld().
@@ -533,6 +554,23 @@ PUGL_API void*
puglGetNativeWorld(PuglWorld* world);
/**
+ Set the function to call to log a message.
+
+ This will be called to report any log messages generated internally by Pugl
+ which are enabled according to the log level.
+*/
+PUGL_API PuglStatus
+puglSetLogFunc(PuglWorld* world, PuglLogFunc logFunc);
+
+/**
+ Set the level of log messages to emit.
+
+ Any log messages with a level less than or equal to `level` will be emitted.
+*/
+PUGL_API PuglStatus
+puglSetLogLevel(PuglWorld* world, PuglLogLevel level);
+
+/**
Set the class name of the application.
This is a stable identifier for the application, used as the window
diff --git a/wscript b/wscript
index a80492d..b197d29 100644
--- a/wscript
+++ b/wscript
@@ -34,7 +34,6 @@ def options(ctx):
'no-cairo': 'do not build Cairo support',
'no-static': 'do not build static library',
'no-shared': 'do not build shared library',
- 'log': 'print GL information to console',
'grab-focus': 'work around keyboard issues by grabbing focus'})
ctx.get_option_group('Test options').add_option(
@@ -126,9 +125,6 @@ def configure(conf):
system = True,
mandatory = False)
- if Options.options.log:
- conf.define('PUGL_VERBOSE', 1)
-
conf.env.update({
'BUILD_SHARED': not Options.options.no_shared,
'BUILD_STATIC': conf.env.BUILD_TESTS or not Options.options.no_static})
@@ -141,8 +137,7 @@ def configure(conf):
{"Build static library": bool(conf.env.BUILD_STATIC),
"Build shared library": bool(conf.env.BUILD_SHARED),
"OpenGL support": bool(conf.env.HAVE_GL),
- "Cairo support": bool(conf.env.HAVE_CAIRO),
- "Verbose console output": conf.is_defined('PUGL_VERBOSE')})
+ "Cairo support": bool(conf.env.HAVE_CAIRO)})
def _build_pc_file(bld, name, desc, target, libname, deps={}, requires=[]):