From ecb407c721ee4b2732f841f82aaff0e80b86aeec Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Sun, 22 Nov 2015 18:20:41 +0100 Subject: [PATCH] Import a platform framework --- include/GServer.h | 1 + include/GServer/platform.h | 36 +++++++++ include/GServer/video.h | 2 + src/gserver.c | 28 ++++++- src/gserver.h | 2 + src/platform.c | 155 +++++++++++++++++++++++++++++++++++++ src/platform.h | 34 ++++++++ src/project.conf | 5 +- src/video/glut.c | 11 ++- src/video/glx.c | 8 +- 10 files changed, 272 insertions(+), 10 deletions(-) create mode 100644 include/GServer/platform.h create mode 100644 src/platform.c create mode 100644 src/platform.h diff --git a/include/GServer.h b/include/GServer.h index e247f54..9273d10 100644 --- a/include/GServer.h +++ b/include/GServer.h @@ -20,6 +20,7 @@ # include "GServer/gserver.h" +# include "GServer/platform.h" # include "GServer/video.h" #endif /* !GRAPHICS_GSERVER_H */ diff --git a/include/GServer/platform.h b/include/GServer/platform.h new file mode 100644 index 0000000..c021864 --- /dev/null +++ b/include/GServer/platform.h @@ -0,0 +1,36 @@ +/* $Id$ */ +/* Copyright (c) 2015 Pierre Pronchery */ +/* This file is part of DeforaOS Graphics GServer */ +/* This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + + + +#ifndef GRAPHICS_GSERVER_PLATFORM_H +# define GRAPHICS_GSERVER_PLATFORM_H + + +/* GServerPlatform */ +/* protected */ +/* types */ +typedef struct _GServerPlatform GServerPlatform; + + +/* public */ +/* accessors */ +int gserverplatform_get_video_refresh_rate(GServerPlatform * platform); + +int gserverplatform_get_video_depth(GServerPlatform * platform); +int gserverplatform_get_video_height(GServerPlatform * platform); +int gserverplatform_get_video_width(GServerPlatform * platform); + +#endif /* !GRAPHICS_GSERVER_PLATFORM_H */ diff --git a/include/GServer/video.h b/include/GServer/video.h index 6d0572c..c00efb8 100644 --- a/include/GServer/video.h +++ b/include/GServer/video.h @@ -21,6 +21,7 @@ # include # include # include "gserver.h" +# include "platform.h" /* Video */ @@ -94,6 +95,7 @@ typedef struct _GServerVideoPluginHelper char const * (*config_get)(GServer * gserver, char const * section, char const * variable); Event * (*get_event)(GServer * gserver); + GServerPlatform * (*get_platform)(GServer * gserver); void (*refresh)(GServer * gserver); } GServerVideoPluginHelper; diff --git a/src/gserver.c b/src/gserver.c index f5c4313..a0ad487 100644 --- a/src/gserver.c +++ b/src/gserver.c @@ -22,6 +22,7 @@ #include #include "GServer/video.h" #include "../data/GServer.h" +#include "platform.h" #include "gserver.h" #include "../config.h" @@ -58,6 +59,8 @@ typedef struct _GServerClient GServerClient; struct _App { + GServerPlatform * platform; + Event * event; int event_own; AppServer * appserver; @@ -167,6 +170,8 @@ GServer * gserver_new(AppServerOptions options, Event * event) static int _new_init(AppServerOptions options, GServer * gserver, Event * event) { + if((gserver->platform = gserverplatform_new()) == NULL) + return -1; gserver->video_handle = NULL; gserver->video_plugin = NULL; gserver->clients = NULL; @@ -174,11 +179,15 @@ static int _new_init(AppServerOptions options, GServer * gserver, Event * event) if((gserver->event = event) != NULL) gserver->event_own = 0; else if((gserver->event = event_new()) == NULL) + { + gserverplatform_delete(gserver->platform); return -1; + } else gserver->event_own = 1; gserver->video_helper.gserver = gserver; gserver->video_helper.get_event = gserver_get_event; + gserver->video_helper.get_platform = gserver_get_platform; gserver->video_helper.refresh = gserver_refresh; if((gserver->appserver = appserver_new_event(gserver, options, "GServer", NULL, gserver->event)) @@ -192,14 +201,18 @@ static int _new_init(AppServerOptions options, GServer * gserver, Event * event) appserver_delete(gserver->appserver); if(gserver->event_own != 0) event_delete(gserver->event); + gserverplatform_delete(gserver->platform); return -1; } static int _init_video(GServer * gserver) - /* FIXME ask Hardware what to load instead of hard-coding glut */ { - if((gserver->video_handle = plugin_new(LIBDIR, PACKAGE, "video", - "glut")) == NULL) + String const subsystem[] = "video"; + GServerPlatform * platform = gserver->platform; + + if((gserver->video_handle = plugin_new(LIBDIR, PACKAGE, subsystem, + gserverplatform_get_driver(platform, + subsystem))) == NULL) return 1; if((gserver->video_plugin = plugin_lookup(gserver->video_handle, "video_plugin")) == NULL) @@ -226,6 +239,8 @@ void gserver_delete(GServer * gserver) appserver_delete(gserver->appserver); if(gserver->event != NULL) event_delete(gserver->event); + if(gserver->platform != NULL) + gserverplatform_delete(gserver->platform); object_delete(gserver); } @@ -246,6 +261,13 @@ Event * gserver_get_event(GServer * gserver) } +/* gserver_get_platform */ +GServerPlatform * gserver_get_platform(GServer * gserver) +{ + return gserver->platform; +} + + /* useful */ /* gserver_loop */ int gserver_loop(GServer * gserver) diff --git a/src/gserver.h b/src/gserver.h index c1229de..61162ab 100644 --- a/src/gserver.h +++ b/src/gserver.h @@ -20,6 +20,7 @@ # include # include +# include "GServer/platform.h" # include "GServer/gserver.h" @@ -32,6 +33,7 @@ void gserver_delete(GServer * gserver); /* accessors */ Event * gserver_get_event(GServer * gserver); +GServerPlatform * gserver_get_platform(GServer * gserver); /* useful */ diff --git a/src/platform.c b/src/platform.c new file mode 100644 index 0000000..450f192 --- /dev/null +++ b/src/platform.c @@ -0,0 +1,155 @@ +/* $Id$ */ +/* Copyright (c) 2015 Pierre Pronchery */ +/* This file is part of DeforaOS Graphics GServer */ +/* This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + + + +#include +#include +#include +#include "GServer/platform.h" +#include "../config.h" + +#ifndef VENDOR +# define VENDOR "DeforaOS" +#endif + + +/* GServerPlatform */ +/* private */ +/* types */ +struct _GServerPlatform +{ + Config * config; +}; + + +/* prototypes */ +/* accessors */ +static int _gserverplatform_get_integer(GServerPlatform * platform, + String const * section, String const * name, int fallback); +static String const * _gserverplatform_get_string(GServerPlatform * platform, + String const * section, String const * name, + String const * fallback); + + +/* public */ +/* functions */ +/* gserverplatform_new */ +GServerPlatform * gserverplatform_new(void) +{ + GServerPlatform * platform; + + if((platform = object_new(sizeof(*platform))) == NULL) + return NULL; + if((platform->config = config_new()) == NULL) + { + object_delete(platform->config); + return NULL; + } + /* XXX report errors */ + config_load_preferences_system(platform->config, VENDOR, PACKAGE, + "platform.conf"); + return platform; +} + + +/* gserverplatform_delete */ +void gserverplatform_delete(GServerPlatform * platform) +{ + config_delete(platform->config); + object_delete(platform); +} + + +/* accessors */ +/* gserverplatform_get_driver */ +String const * gserverplatform_get_driver(GServerPlatform * platform, + String const * subsystem) +{ + struct + { + String const * subsystem; + String const * fallback; + } fallback[] = + { + { "video", "glx" } + }; + size_t i; + + for(i = 0; i < sizeof(fallback) / sizeof(*fallback); i++) + if(string_compare(fallback[i].subsystem, subsystem) == 0) + return _gserverplatform_get_string(platform, "drivers", + subsystem, fallback[i].fallback); + return _gserverplatform_get_string(platform, "drivers", subsystem, + NULL); +} + + +/* gserverplatform_get_video_depth */ +int gserverplatform_get_video_depth(GServerPlatform * platform) +{ + return _gserverplatform_get_integer(platform, "video", "depth", 24); +} + + +/* gserverplatform_get_video_height */ +int gserverplatform_get_video_height(GServerPlatform * platform) +{ + return _gserverplatform_get_integer(platform, "video", "height", 480); +} + + +/* gserverplatform_get_video_refresh_rate */ +int gserverplatform_get_video_refresh_rate(GServerPlatform * platform) +{ + return _gserverplatform_get_integer(platform, "video", "refresh_rate", + 60); +} + + +/* gserverplatform_get_video_width */ +int gserverplatform_get_video_width(GServerPlatform * platform) +{ + return _gserverplatform_get_integer(platform, "video", "width", 640); +} + + +/* private */ +/* functions */ +/* gserverplatform_get_integer */ +static int _gserverplatform_get_integer(GServerPlatform * platform, + String const * section, String const * name, int fallback) +{ + String const * p; + int d; + + if((p = config_get(platform->config, section, name)) == NULL + || (d = strtol(p, NULL, 0)) == 0) + return fallback; + return d; +} + + +/* gserverplatform_get_string */ +static String const * _gserverplatform_get_string(GServerPlatform * platform, + String const * section, String const * name, + String const * fallback) +{ + String const * s; + + if((s = config_get(platform->config, section, name)) == NULL) + return fallback; + return s; +} diff --git a/src/platform.h b/src/platform.h new file mode 100644 index 0000000..277c4fd --- /dev/null +++ b/src/platform.h @@ -0,0 +1,34 @@ +/* $Id$ */ +/* Copyright (c) 2015 Pierre Pronchery */ +/* This file is part of DeforaOS Graphics GServer */ +/* This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + + + +#ifndef GSERVER_PLATFORM_H +# define GSERVER_PLATFORM_H + +# include + + +/* GServerPlatform */ +/* public */ +/* accessors */ +GServerPlatform * gserverplatform_new(void); +void gserverplatform_delete(GServerPlatform * platform); + +/* accessors */ +String const * gserverplatform_get_driver(GServerPlatform * platform, + String const * subsystem); + +#endif /* !GSERVER_PLATFORM_H */ diff --git a/src/project.conf b/src/project.conf index eeebee2..eabe9e7 100644 --- a/src/project.conf +++ b/src/project.conf @@ -15,11 +15,14 @@ depends=../data/GServer.interface [GServer] type=binary -sources=gserver.c,main.c +sources=gserver.c,platform.c,main.c cflags=`pkg-config --cflags gl` [gserver.c] depends=gserver.h,../data/GServer.h,../config.h +[platform.c] +depends=../config.h + [main.c] depends=gserver.h,../config.h diff --git a/src/video/glut.c b/src/video/glut.c index dc2da4c..c4057a7 100644 --- a/src/video/glut.c +++ b/src/video/glut.c @@ -122,6 +122,7 @@ GServerVideoPlugin video_plugin = static int _glut_init(GServerVideoPlugin * plugin) { GLUTVideo * glut; + GServerPlatform * platform; int argc = 1; char * argv[] = { "GServer", NULL }; @@ -131,8 +132,9 @@ static int _glut_init(GServerVideoPlugin * plugin) if((glut = object_new(sizeof(*glut))) == NULL) return 1; plugin->priv = glut; - glut->width = 640; - glut->height = 480; + platform = plugin->helper->get_platform(plugin->helper->gserver); + glut->width = gserverplatform_get_video_width(platform); + glut->height = gserverplatform_get_video_height(platform); glutInit(&argc, argv); glutInitWindowSize(glut->width, glut->height); glutCreateWindow(PACKAGE " GLUT"); @@ -186,15 +188,18 @@ static int _idle_timeout(void * data); static void _glut_idle(void) { struct timeval tv; + GServerPlatform * platform; Event * event; + platform = video_plugin.helper->get_platform( + video_plugin.helper->gserver); event = video_plugin.helper->get_event(video_plugin.helper->gserver); #ifdef DEBUG tv.tv_sec = 1; tv.tv_usec = 0; #else tv.tv_sec = 0; - tv.tv_usec = 1000000 / 60; + tv.tv_usec = 1000000 / gserverplatform_get_video_refresh_rate(platform); #endif event_register_timeout(event, &tv, _idle_timeout, event); event_loop(event); diff --git a/src/video/glx.c b/src/video/glx.c index 2b8eae7..ef3f0d1 100644 --- a/src/video/glx.c +++ b/src/video/glx.c @@ -125,6 +125,7 @@ GServerVideoPlugin video_plugin = /* glx_init */ static int _glx_init(GServerVideoPlugin * plugin) { + GServerPlatform * platform; GLXVideo * glx; Event * event; Window root; @@ -146,6 +147,7 @@ static int _glx_init(GServerVideoPlugin * plugin) if((glx = object_new(sizeof(*glx))) == NULL) return 1; plugin->priv = glx; + platform = plugin->helper->get_platform(plugin->helper->gserver); event = plugin->helper->get_event(plugin->helper->gserver); glx->display = XOpenDisplay(NULL); glx->screen = DefaultScreen(glx->display); @@ -159,8 +161,8 @@ static int _glx_init(GServerVideoPlugin * plugin) vi = glXChooseVisual(glx->display, glx->screen, attributes); } glx->context = glXCreateContext(glx->display, vi, 0, GL_TRUE); - glx->width = 640; - glx->height = 480; + glx->width = gserverplatform_get_video_width(platform); + glx->height = gserverplatform_get_video_height(platform); memset(&attr, 0, sizeof(attr)); root = RootWindow(glx->display, vi->screen); attr.colormap = XCreateColormap(glx->display, root, vi->visual, @@ -211,7 +213,7 @@ static int _glx_init(GServerVideoPlugin * plugin) tv.tv_usec = 0; #else tv.tv_sec = 0; - tv.tv_usec = 1000000 / 60; + tv.tv_usec = 1000000 / gserverplatform_get_video_refresh_rate(platform); #endif if(_glx_timeout(plugin) == 0) event_register_timeout(event, &tv, _glx_timeout, plugin);