compositor: Split backends into modules
authorKristian Høgsberg <krh@bitplanet.net>
Tue, 3 May 2011 02:09:20 +0000 (22:09 -0400)
committerKristian Høgsberg <krh@bitplanet.net>
Tue, 3 May 2011 02:09:20 +0000 (22:09 -0400)
compositor/Makefile.am
compositor/compositor-drm.c
compositor/compositor-wayland.c
compositor/compositor-x11.c
compositor/compositor.c
compositor/compositor.h
compositor/image-loader.c
compositor/meego-tablet-shell.c
compositor/shell.c
configure.ac

index a94410c..579b5f4 100644 (file)
@@ -1,69 +1,88 @@
-noinst_PROGRAMS = compositor
+bin_PROGRAMS = wayland-compositor
 
 AM_CPPFLAGS =                                  \
        -DDATADIR='"$(datadir)"'                \
-       $(COMPOSITOR_CFLAGS)                    \
-       $(X11_COMPOSITOR_CFLAGS)                \
-       $(DRM_COMPOSITOR_CFLAGS)                \
-       $(WAYLAND_COMPOSITOR_CFLAGS)            \
-       $(OPENWFD_COMPOSITOR_CFLAGS)
+       -DMODULEDIR='"$(moduledir)"'            \
+       $(COMPOSITOR_CFLAGS)
 
 AM_CFLAGS = $(GCC_CFLAGS)
 
-compositor_LDFLAGS = -export-dynamic
-compositor_LDADD =                             \
-       $(COMPOSITOR_LIBS)                      \
-       $(X11_COMPOSITOR_LIBS)                  \
-       $(DRM_COMPOSITOR_LIBS)                  \
-       $(WAYLAND_COMPOSITOR_LIBS)              \
-       $(OPENWFD_COMPOSITOR_LIBS)              \
-       $(DLOPEN_LIBS)
+wayland_compositor_LDFLAGS = -export-dynamic
+wayland_compositor_LDADD = $(COMPOSITOR_LIBS) $(DLOPEN_LIBS)
 
-if ENABLE_DRM_COMPOSITOR
-drm_compositor_sources = compositor-drm.c tty.c evdev.c
-endif
+wayland_compositor_SOURCES =                   \
+       compositor.c                            \
+       compositor.h                            \
+       image-loader.c                          \
+       screenshooter.c                         \
+       screenshooter-protocol.c                \
+       screenshooter-server-protocol.h
+
+udevrulesddir = $(sysconfdir)/udev/rules.d
+
+dist_udevrulesd_DATA =                         \
+       70-wayland.rules
+
+moduledir = @libdir@/wayland
+module_LTLIBRARIES =                           \
+       $(desktop_shell)                        \
+       $(meego_tablet_shell)                   \
+       $(x11_backend)                          \
+       $(drm_backend)                          \
+       $(wayland_backend)                      \
+       $(openwfd_backend)
 
 if ENABLE_X11_COMPOSITOR
-x11_compositor_sources = compositor-x11.c
+x11_backend = x11-backend.la
+x11_backend_la_LDFLAGS = -module -avoid-version
+x11_backend_la_LIBADD = $(COMPOSITOR_LIBS) $(X11_COMPOSITOR_LIBS)
+x11_backend_la_CFLAGS = $(X11_COMPOSITOR_CFLAGS)
+x11_backend_la_SOURCES = compositor-x11.c
+endif
+
+if ENABLE_DRM_COMPOSITOR
+drm_backend = drm-backend.la
+drm_backend_la_LDFLAGS = -module -avoid-version
+drm_backend_la_LIBADD = $(COMPOSITOR_LIBS) $(DRM_COMPOSITOR_LIBS)
+drm_backend_la_CFLAGS = $(DRM_COMPOSITOR_CFLAGS)
+drm_backend_la_SOURCES = compositor-drm.c tty.c evdev.c
 endif
 
 if ENABLE_WAYLAND_COMPOSITOR
-wayland_compositor_sources = compositor-wayland.c
+wayland_backend = wayland-backend.la
+wayland_backend_la_LDFLAGS = -module -avoid-version
+wayland_backend_la_LIBADD = $(COMPOSITOR_LIBS) $(WAYLAND_COMPOSITOR_LIBS)
+wayland_backend_la_CFLAGS = $(WAYLAND_COMPOSITOR_CFLAGS)
+wayland_backend_la_SOURCES = compositor-wayland.c
 endif
 
 if ENABLE_OPENWFD_COMPOSITOR
-openwfd_compositor_sources = compositor-openwfd.c
+openwfd_backend = openwfd-backend.la
+openwfd_backend_la_LDFLAGS = -module -avoid-version
+openwfd_backend_la_LIBADD = $(COMPOSITOR_LIBS) $(OPENWFD_COMPOSITOR_LIBS)
+openwfd_backend_la_CFLAGS = $(OPENWFD_COMPOSITOR_CFLAGS)
+openwfd_backend_SOURCES = compositor-openwfd.c
 endif
 
-compositor_SOURCES =                           \
-       compositor.c                            \
-       compositor.h                            \
-       image-loader.c                          \
+if ENABLE_DESKTOP_SHELL
+desktop_shell = desktop-shell.la
+desktop_shell_la_LDFLAGS = -module -avoid-version
+desktop_shell_la_LIBADD = $(COMPOSITOR_LIBS)
+desktop_shell_la_SOURCES =                     \
        shell.c                                 \
-       switcher.c                              \
-       screenshooter.c                         \
-       screenshooter-protocol.c                \
-       screenshooter-server-protocol.h         \
-       $(drm_compositor_sources)               \
-       $(openwfd_compositor_sources)           \
-       $(x11_compositor_sources)               \
-       $(wayland_compositor_sources)
-
-udevrulesddir = $(sysconfdir)/udev/rules.d
-
-dist_udevrulesd_DATA =                         \
-       70-wayland.rules
+       switcher.c
+endif
 
-meego_tablet_shell_la_LTLIBRARIES = meego-tablet-shell.la
+if ENABLE_MEEGO_TABLET_SHELL
+meego_tablet_shell = meego-tablet-shell.la
 meego_tablet_shell_la_LDFLAGS = -module -avoid-version
-meego_tablet_shell_ladir = @libdir@/wayland
 meego_tablet_shell_la_LIBADD = $(COMPOSITOR_LIBS)
-
 meego_tablet_shell_la_SOURCES =                        \
        meego-tablet-shell.c                    \
        meego-tablet-shell.h                    \
        meego-tablet-protocol.c                 \
        meego-tablet-server-protocol.h
+endif
 
 BUILT_SOURCES =                                        \
        screenshooter-server-protocol.h         \
index fe4d85f..35ace9d 100644 (file)
@@ -742,3 +742,23 @@ drm_compositor_create(struct wl_display *display, int connector)
 
        return &ec->base;
 }
+
+struct wlsc_compositor *
+backend_init(struct wl_display *display, char *options)
+{
+       int connector, i;
+       char *p, *value;
+
+       static char * const tokens[] = { "connector", NULL };
+       
+       p = options;
+       while (i = getsubopt(&p, tokens, &value), i != -1) {
+               switch (i) {
+               case 0:
+                       connector = strol(value, NULL, 0);
+                       break;
+               }
+       }
+
+       return drm_compositor_create(display, connector);
+}
index 66581d4..37a9d66 100644 (file)
@@ -518,3 +518,26 @@ wayland_compositor_create(struct wl_display *display, int width, int height)
 
        return &c->base;
 }
+
+struct wlsc_compositor *
+backend_init(struct wl_display *display, char *options)
+{
+       int width = 1024, height = 640, i;
+       char *p, *value;
+
+       static char * const tokens[] = { "width", "height", NULL };
+       
+       p = options;
+       while (i = getsubopt(&p, tokens, &value), i != -1) {
+               switch (i) {
+               case 0:
+                       width = strtol(value, NULL, 0);
+                       break;
+               case 1:
+                       height = strtol(value, NULL, 0);
+                       break;
+               }
+       }
+
+       return wayland_compositor_create(display, width, height);
+}
index dd32061..0c4505c 100644 (file)
@@ -681,3 +681,26 @@ x11_compositor_create(struct wl_display *display, int width, int height)
 
        return &c->base;
 }
+
+struct wlsc_compositor *
+backend_init(struct wl_display *display, char *options)
+{
+       int width = 1024, height = 640, i;
+       char *p, *value;
+
+       static char * const tokens[] = { "width", "height", NULL };
+       
+       p = options;
+       while (i = getsubopt(&p, tokens, &value), i != -1) {
+               switch (i) {
+               case 0:
+                       width = strtol(value, NULL, 0);
+                       break;
+               case 1:
+                       height = strtol(value, NULL, 0);
+                       break;
+               }
+       }
+
+       return x11_compositor_create(display, width, height);
+}
index ab5b28d..15dc600 100644 (file)
@@ -43,9 +43,7 @@
  */
 static const char *option_socket_name = NULL;
 static const char *option_background = "background.jpg";
-static const char *option_shell = NULL;
 static int option_idle_time = 300;
-static int option_connector = 0;
 
 WL_EXPORT void
 wlsc_matrix_init(struct wlsc_matrix *matrix)
@@ -1032,7 +1030,7 @@ wlsc_input_device_attach_sprite(struct wlsc_input_device *device,
        wlsc_input_device_attach(device, x, y, sprite->width, sprite->height);
 }
 
-void
+WL_EXPORT void
 wlsc_input_device_set_pointer_image(struct wlsc_input_device *device,
                                    enum wlsc_pointer_type type)
 {
@@ -1081,7 +1079,7 @@ wlsc_surface_transform(struct wlsc_surface *surface,
        *sy = y - surface->y;
 }
 
-struct wlsc_surface *
+WL_EXPORT struct wlsc_surface *
 pick_surface(struct wl_input_device *device, int32_t *sx, int32_t *sy)
 {
        struct wlsc_compositor *ec =
@@ -1177,7 +1175,7 @@ idle_handler(void *data)
        return 1;
 }
 
-void
+WL_EXPORT void
 notify_motion(struct wl_input_device *device, uint32_t time, int x, int y)
 {
        struct wlsc_surface *es;
@@ -1254,10 +1252,13 @@ WL_EXPORT void
 wlsc_surface_activate(struct wlsc_surface *surface,
                      struct wlsc_input_device *device, uint32_t time)
 {
+       struct wlsc_shell *shell = surface->compositor->shell;
+
        wlsc_surface_raise(surface);
        if (device->selection)
-               wlsc_selection_set_focus(device->selection,
-                                        &surface->surface, time);
+               shell->set_selection_focus(shell,
+                                          device->selection,
+                                          &surface->surface, time);
 
        wl_input_device_set_keyboard_focus(&device->input_device,
                                           &surface->surface,
@@ -1273,7 +1274,7 @@ struct wlsc_binding {
        struct wl_list link;
 };
 
-void
+WL_EXPORT void
 notify_button(struct wl_input_device *device,
              uint32_t time, int32_t button, int32_t state)
 {
@@ -1384,7 +1385,7 @@ update_modifier_state(struct wlsc_input_device *device,
                device->modifier_state &= ~modifier;
 }
 
-void
+WL_EXPORT void
 notify_key(struct wl_input_device *device,
           uint32_t time, uint32_t key, uint32_t state)
 {
@@ -1426,7 +1427,7 @@ notify_key(struct wl_input_device *device,
                                     WL_INPUT_DEVICE_KEY, time, key, state);
 }
 
-void
+WL_EXPORT void
 notify_pointer_focus(struct wl_input_device *device,
                     uint32_t time, struct wlsc_output *output,
                     int32_t x, int32_t y)
@@ -1458,7 +1459,7 @@ notify_pointer_focus(struct wl_input_device *device,
        wlsc_surface_damage(wd->sprite);
 }
 
-void
+WL_EXPORT void
 notify_keyboard_focus(struct wl_input_device *device,
                      uint32_t time, struct wlsc_output *output,
                      struct wl_array *keys)
@@ -1528,7 +1529,7 @@ const static struct wl_input_device_interface input_device_interface = {
        input_device_attach,
 };
 
-void
+WL_EXPORT void
 wlsc_input_device_init(struct wlsc_input_device *device,
                       struct wlsc_compositor *ec)
 {
@@ -1679,13 +1680,13 @@ init_solid_shader(struct wlsc_shader *shader,
        return 0;
 }
 
-void
+WL_EXPORT void
 wlsc_output_destroy(struct wlsc_output *output)
 {
        destroy_surface(&output->background->surface.resource, NULL);
 }
 
-void
+WL_EXPORT void
 wlsc_output_move(struct wlsc_output *output, int x, int y)
 {
        struct wlsc_compositor *c = output->compositor;
@@ -1716,7 +1717,7 @@ wlsc_output_move(struct wlsc_output *output, int x, int y)
                                   x, y, output->width, output->height);
 }
 
-void
+WL_EXPORT void
 wlsc_output_init(struct wlsc_output *output, struct wlsc_compositor *c,
                 int x, int y, int width, int height, uint32_t flags)
 {
@@ -1794,7 +1795,7 @@ const static struct wl_shm_callbacks shm_callbacks = {
        shm_buffer_destroyed
 };
 
-int
+WL_EXPORT int
 wlsc_compositor_init(struct wlsc_compositor *ec, struct wl_display *display)
 {
        struct wl_event_loop *loop;
@@ -1878,51 +1879,70 @@ static int on_term_signal(int signal_number, void *data)
        return 1;
 }
 
+static void *
+load_module(const char *name, const char *entrypoint, void **handle)
+{
+       char path[PATH_MAX];
+       void *module, *init;
+
+       if (name[0] != '/')
+               snprintf(path, sizeof path, MODULEDIR "/%s", name);
+       else
+               snprintf(path, sizeof path, name);
+
+       module = dlopen(path, RTLD_LAZY);
+       if (!module) {
+               fprintf(stderr,
+                       "failed to load module: %s\n", dlerror());
+               return NULL;
+       }
+
+       init = dlsym(module, entrypoint);
+       if (!init) {
+               fprintf(stderr,
+                       "failed to lookup init function: %s\n", dlerror());
+               return NULL;
+       }
+
+       return init;
+}
+
 int main(int argc, char *argv[])
 {
        struct wl_display *display;
        struct wlsc_compositor *ec;
        struct wl_event_loop *loop;
-       int width, height, o;
-       void *shell_module;
+       int o;
+       void *shell_module, *backend_module;
        int (*shell_init)(struct wlsc_compositor *ec);
+       struct wlsc_compositor
+               *(*backend_init)(struct wl_display *display, char *options);
+       char *backend = NULL;
+       char *backend_options = "";
+       char *shell = NULL;
        char *p;
 
-       static const char opts[] = "b:c:g:S:i:s:";
+       static const char opts[] = "B:b:o:S:i:s:";
        static const struct option longopts[ ] = {
+               { "backend", 1, NULL, 'B' },
+               { "backend-options", 1, NULL, 'o' },
                { "background", 1, NULL, 'b' },
-               { "connector", 1, NULL, 'c' },
-               { "geometry", 1, NULL, 'g' },
                { "socket", 1, NULL, 'S' },
                { "idle-time", 1, NULL, 'i' },
                { "shell", 1, NULL, 's' },
                { NULL, }
        };
 
-       width = 1024;
-       height = 640;
-
        while (o = getopt_long(argc, argv, opts, longopts, &o), o > 0) {
                switch (o) {
                case 'b':
                        option_background = optarg;
                        break;
-               case 'c':
-                       option_connector = strtol(optarg, &p, 0);
-                       if (*p != '\0') {
-                               fprintf(stderr,
-                                       "invalid connection option: %s\n",
-                                       optarg);
-                               exit(EXIT_FAILURE);
-                       }
+               case 'B':
+                       backend = optarg;
                        break;
-               case 'g':
-                       if (sscanf(optarg, "%dx%d", &width, &height) != 2) {
-                               fprintf(stderr,
-                                       "invalid geometry option: %s\n",
-                                       optarg);
-                               exit(EXIT_FAILURE);
-                       }
+               case 'o':
+                       backend_options = optarg;
                        break;
                case 'S':
                        option_socket_name = optarg;
@@ -1937,7 +1957,7 @@ int main(int argc, char *argv[])
                        }
                        break;
                case 's':
-                       option_shell = optarg;
+                       shell = optarg;
                        break;
                }
        }
@@ -1946,41 +1966,29 @@ int main(int argc, char *argv[])
 
        ec = NULL;
 
-       shell_init = desktop_shell_init;
-       if (option_shell) {
-               shell_module = dlopen(option_shell, RTLD_LAZY);
-               if (!shell_module) {
-                       fprintf(stderr, "failed to load shell module: %m\n");
-                       exit(EXIT_FAILURE);
-               }
-               shell_init = dlsym(shell_module, "shell_init");
-               if (!shell_init) {
-                       fprintf(stderr,
-                               "failed to lookup shell init function: %m\n");
-                       exit(EXIT_FAILURE);
-               }
+       if (!backend) {
+               if (getenv("WAYLAND_DISPLAY"))
+                       backend = "wayland-backend.so";
+               else if (getenv("DISPLAY"))
+                       backend = "x11-backend.so";
+               else if (getenv("OPENWFD"))
+                       backend = "openwfd-backend.so";
+               else
+                       backend = "drm-backend.so";
        }
 
-#if BUILD_WAYLAND_COMPOSITOR
-       if (getenv("WAYLAND_DISPLAY"))
-               ec = wayland_compositor_create(display, width, height);
-#endif
+       if (!shell)
+               shell = "desktop-shell.so";
 
-#if BUILD_X11_COMPOSITOR
-       if (ec == NULL && getenv("DISPLAY"))
-               ec = x11_compositor_create(display, width, height);
-#endif
-
-#if BUILD_OPENWFD_COMPOSITOR
-       if (ec == NULL && getenv("OPENWFD"))
-               ec = wfd_compositor_create(display, option_connector);
-#endif
+       backend_init = load_module(backend, "backend_init", &backend_module);
+       if (!backend_init)
+               exit(EXIT_FAILURE);
 
-#if BUILD_DRM_COMPOSITOR
-       if (ec == NULL)
-               ec = drm_compositor_create(display, option_connector);
-#endif
+       shell_init = load_module(shell, "shell_init", &shell_module);
+       if (!shell_init)
+               exit(EXIT_FAILURE);
 
+       ec = backend_init(display, backend_options);
        if (ec == NULL) {
                fprintf(stderr, "failed to create compositor\n");
                exit(EXIT_FAILURE);
index 735d376..93de793 100644 (file)
@@ -129,6 +129,9 @@ struct wlsc_spring {
 struct wlsc_shell {
        void (*lock)(struct wlsc_shell *shell);
        void (*attach)(struct wlsc_shell *shell, struct wlsc_surface *surface);
+       void (*set_selection_focus)(struct wlsc_shell *shell,
+                                   struct wl_selection *selection,
+                                   struct wl_surface *surface, uint32_t time);
 };
 
 enum {
@@ -314,10 +317,6 @@ wlsc_input_device_set_pointer_image(struct wlsc_input_device *device,
 struct wlsc_surface *
 pick_surface(struct wl_input_device *device, int32_t *sx, int32_t *sy);
 
-void
-wlsc_selection_set_focus(struct wl_selection *selection,
-                        struct wl_surface *surface, uint32_t time);
-
 uint32_t
 wlsc_compositor_get_time(void);
 
@@ -335,24 +334,9 @@ void
 wlsc_input_device_init(struct wlsc_input_device *device,
                       struct wlsc_compositor *ec);
 
-int
-desktop_shell_init(struct wlsc_compositor *ec);
-
 void
 wlsc_switcher_init(struct wlsc_compositor *compositor);
 
-struct wlsc_compositor *
-x11_compositor_create(struct wl_display *display, int width, int height);
-
-struct wlsc_compositor *
-drm_compositor_create(struct wl_display *display, int connector);
-
-struct wlsc_compositor *
-wfd_compositor_create(struct wl_display *display, int connector);
-
-struct wlsc_compositor *
-wayland_compositor_create(struct wl_display *display, int width, int height);
-
 void
 evdev_input_add_devices(struct wlsc_compositor *c, struct udev *udev);
 
index 26d116b..f6dec25 100644 (file)
@@ -76,7 +76,7 @@ read_func(png_structp png, png_bytep data, png_size_t size)
                png_error(png, NULL);
 }
 
-uint32_t *
+WL_EXPORT uint32_t *
 wlsc_load_image(const char *filename,
                int32_t *width_arg, int32_t *height_arg, uint32_t *stride_arg)
 {
index 8cc9565..e01cc67 100644 (file)
@@ -511,6 +511,14 @@ tablet_shell_bind(struct wl_client *client,
                             MEEGO_TABLET_SHELL_SHOW_LOCKSCREEN);
 }
 
+static void
+meego_tablet_shell_set_selection_focus(struct wlsc_shell *shell,
+                                      struct wl_selection *selection,
+                                      struct wl_surface *surface,
+                                      uint32_t time)
+{
+}
+
 void
 shell_init(struct wlsc_compositor *compositor);
 
@@ -556,7 +564,8 @@ shell_init(struct wlsc_compositor *compositor)
 
        shell->shell.lock = meego_tablet_shell_lock;
        shell->shell.attach = meego_tablet_shell_attach;
-
+       shell->shell.set_selection_focus =
+               meego_tablet_shell_set_selection_focus;
        launch_switcher(shell);
 
        wlsc_spring_init(&compositor->fade.spring, 40.0, 1.0, 1.0);
index ea03e3c..1dc2427 100644 (file)
@@ -496,8 +496,9 @@ shell_create_drag(struct wl_client *client,
        wl_client_add_resource(client, &drag->resource);
 }
 
-void
-wlsc_selection_set_focus(struct wl_selection *selection,
+static void
+wlsc_selection_set_focus(struct wlsc_shell *shell,
+                        struct wl_selection *selection,
                         struct wl_surface *surface, uint32_t time)
 {
        char **p, **end;
@@ -577,6 +578,8 @@ selection_activate(struct wl_client *client,
 {
        struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
        struct wl_display *display = wl_client_get_display (client);
+       struct wlsc_compositor *compositor =
+               (struct wlsc_compositor *) device->compositor;
 
        selection->input_device = device;
 
@@ -594,7 +597,8 @@ selection_activate(struct wl_client *client,
        }
        wd->selection = selection;
 
-       wlsc_selection_set_focus(selection, device->keyboard_focus, time);
+       wlsc_selection_set_focus(compositor->shell,
+                                selection, device->keyboard_focus, time);
 }
 
 static void
@@ -616,10 +620,13 @@ destroy_selection(struct wl_resource *resource, struct wl_client *client)
                container_of(resource, struct wl_selection, resource);
        struct wlsc_input_device *wd =
                (struct wlsc_input_device *) selection->input_device;
+       struct wlsc_compositor *compositor =
+               (struct wlsc_compositor *) wd->input_device.compositor;
 
        if (wd && wd->selection == selection) {
                wd->selection = NULL;
-               wlsc_selection_set_focus(selection, NULL,
+               wlsc_selection_set_focus(compositor->shell, 
+                                        selection, NULL,
                                         wlsc_compositor_get_time());
        }
 
@@ -726,8 +733,8 @@ attach(struct wlsc_shell *shell, struct wlsc_surface *surface)
 {
 }
 
-int
-desktop_shell_init(struct wlsc_compositor *ec)
+WL_EXPORT int
+shell_init(struct wlsc_compositor *ec)
 {
        struct wl_shell *shell;
 
@@ -737,6 +744,7 @@ desktop_shell_init(struct wlsc_compositor *ec)
 
        shell->shell.lock = lock;
        shell->shell.attach = attach;
+       shell->shell.set_selection_focus = wlsc_selection_set_focus;
 
        shell->object.interface = &wl_shell_interface;
        shell->object.implementation = (void (**)(void)) &shell_interface;
index a75039c..4e451d9 100644 (file)
@@ -13,11 +13,10 @@ AM_SILENT_RULES([yes])
 
 # Check for programs
 AC_PROG_CC
-AC_PROG_RANLIB
 
 # Initialize libtool
 LT_PREREQ([2.2])
-LT_INIT
+LT_INIT([disable-static])
 
 PKG_PROG_PKG_CONFIG()
 
@@ -97,6 +96,13 @@ fi
 
 AM_CONDITIONAL(HAVE_POPPLER, test "x$have_poppler" = "xyes")
 
+AM_CONDITIONAL(ENABLE_DESKTOP_SHELL, true)
+
+AC_ARG_ENABLE(meego-tablet-shell, [  --enable-meego-tablet-shell],,
+             enable_meego_tablet_shell=yes)
+AM_CONDITIONAL(ENABLE_MEEGO_TABLET_SHELL,
+              test x$enable_meego_tablet_shell == xyes)
+
 if test "x$GCC" = "xyes"; then
        GCC_CFLAGS="-Wall -g -Wstrict-prototypes -Wmissing-prototypes -fvisibility=hidden"
 fi