From d83fe8f5b57c558a28a0f739be735f13015bfe12 Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Mon, 28 Sep 2020 05:50:01 +0200 Subject: [PATCH] Bring the code closer to DeforaOS Panel's menu applet --- src/desktop/handler/applications.c | 74 +++-------------- src/desktop/handler/categories.c | 123 +++++++++++++++++------------ src/desktop/handler/mimeapp.c | 103 ++++++++++++++++++++++++ src/desktop/handler/mimeapp.h | 55 +++++++++++++ src/desktop/project.conf | 14 ++-- 5 files changed, 251 insertions(+), 118 deletions(-) create mode 100644 src/desktop/handler/mimeapp.c create mode 100644 src/desktop/handler/mimeapp.h diff --git a/src/desktop/handler/applications.c b/src/desktop/handler/applications.c index 3faf14b..101be54 100644 --- a/src/desktop/handler/applications.c +++ b/src/desktop/handler/applications.c @@ -25,16 +25,11 @@ +#include "mimeapp.h" + + /* DesktopMimeApplications */ /* private */ -/* types */ -typedef struct _MimeApp -{ - MimeHandler * mime; - String * datadir; -} MimeApp; - - /* prototypes */ static void _desktophandler_applications_init(DesktopHandler * handler); static void _desktophandler_applications_destroy(DesktopHandler * handler); @@ -42,10 +37,6 @@ static void _desktophandler_applications_popup(DesktopHandler * handler, XButtonEvent * xbev); static void _desktophandler_applications_refresh(DesktopHandler * handler); -/* MimeApp */ -static MimeApp * _mimeapp_new(MimeHandler * handler, String const * path); -static void _mimeapp_delete(MimeApp * mimeapp); - /* functions */ /* desktophandler_applications_init */ @@ -100,7 +91,7 @@ static void _desktophandler_applications_destroy(DesktopHandler * handler) g_source_remove(handler->u.applications.refresh_source); if(handler->u.applications.refresh_dir != NULL) browser_vfs_closedir(handler->u.applications.refresh_dir); - g_slist_foreach(handler->u.applications.apps, (GFunc)_mimeapp_delete, + g_slist_foreach(handler->u.applications.apps, (GFunc)mimeapp_delete, NULL); g_slist_free(handler->u.applications.apps); handler->u.applications.apps = NULL; @@ -137,7 +128,7 @@ static gint _applications_apps_compare(gconstpointer a, gconstpointer b); static void _desktophandler_applications_refresh(DesktopHandler * handler) { - g_slist_foreach(handler->u.applications.apps, (GFunc)_mimeapp_delete, + g_slist_foreach(handler->u.applications.apps, (GFunc)mimeapp_delete, NULL); g_slist_free(handler->u.applications.apps); handler->u.applications.apps = NULL; @@ -174,7 +165,7 @@ static void _applications_on_refresh_done_applications(DesktopHandler * handler) GSList * p; MimeApp * mimeapp; MimeHandler * mime; - char const * name; + String const * name; DesktopCategory * dc = handler->u.applications.category; String const ** categories; size_t i; @@ -184,7 +175,7 @@ static void _applications_on_refresh_done_applications(DesktopHandler * handler) for(p = handler->u.applications.apps; p != NULL; p = p->next) { mimeapp = p->data; - mime = mimeapp->mime; + mime = mimeapp_get_mime(mimeapp); if((name = mimehandler_get_name(mime, 1)) == NULL) { desktop_serror(NULL, NULL, 1); @@ -204,7 +195,8 @@ static void _applications_on_refresh_done_applications(DesktopHandler * handler) } filename = mimehandler_get_filename(mime); if((icon = desktopicon_new_application(handler->desktop, - filename, mimeapp->datadir)) + filename, + mimeapp_get_datadir(mimeapp))) == NULL) continue; desktop_icon_add(handler->desktop, icon, FALSE); @@ -271,8 +263,7 @@ static void _applications_on_refresh_loop_path(DesktopHandler * handler, } if(mimehandler_can_display(mime) == 0 || mimehandler_can_execute(mime) == 0 - || (mimeapp = _mimeapp_new(mime, path)) - == NULL) + || (mimeapp = mimeapp_new(mime, path)) == NULL) { mimehandler_delete(mime); continue; @@ -376,47 +367,8 @@ static void _applications_on_refresh_loop_xdg_path(DesktopHandler * handler, static gint _applications_apps_compare(gconstpointer a, gconstpointer b) { - MimeApp * maa = (MimeApp *)a; - MimeApp * mab = (MimeApp *)b; - MimeHandler * mha = maa->mime; - MimeHandler * mhb = mab->mime; - String const * mhas; - String const * mhbs; + MimeApp const * maa = a; + MimeApp const * mab = b; - if((mhas = mimehandler_get_generic_name(mha, 1)) == NULL) - mhas = mimehandler_get_name(mha, 1); - if((mhbs = mimehandler_get_generic_name(mhb, 1)) == NULL) - mhbs = mimehandler_get_name(mhb, 1); - return string_compare(mhas, mhbs); -} - - -/* MimeApp */ -/* mimeapp_new */ -static MimeApp * _mimeapp_new(MimeHandler * mime, String const * datadir) -{ - MimeApp * mimeapp; - - if((mimeapp = object_new(sizeof(*mimeapp))) == NULL) - return NULL; - mimeapp->mime = NULL; - if(datadir == NULL) - mimeapp->datadir = NULL; - else if((mimeapp->datadir = string_new(datadir)) == NULL) - { - _mimeapp_delete(mimeapp); - return NULL; - } - mimeapp->mime = mime; - return mimeapp; -} - - -/* mimeapp_delete */ -static void _mimeapp_delete(MimeApp * mimeapp) -{ - if(mimeapp->mime != NULL) - mimehandler_delete(mimeapp->mime); - string_delete(mimeapp->datadir); - object_delete(mimeapp); + return mimeapp_compare(maa, mab); } diff --git a/src/desktop/handler/categories.c b/src/desktop/handler/categories.c index 2d7cce7..2b23344 100644 --- a/src/desktop/handler/categories.c +++ b/src/desktop/handler/categories.c @@ -22,9 +22,14 @@ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* FIXME: + * - the initial list has duplicates */ +#include "mimeapp.h" + + /* DesktopHandlerCategories */ /* private */ /* variables */ @@ -105,7 +110,7 @@ static void _desktophandler_categories_destroy(DesktopHandler * handler) g_source_remove(handler->u.categories.refresh_source); if(handler->u.categories.refresh_dir != NULL) browser_vfs_closedir(handler->u.categories.refresh_dir); - g_slist_foreach(handler->u.categories.apps, (GFunc)mimehandler_delete, + g_slist_foreach(handler->u.categories.apps, (GFunc)mimeapp_delete, NULL); g_slist_free(handler->u.categories.apps); } @@ -146,7 +151,7 @@ static void _desktophandler_categories_refresh(DesktopHandler * handler) for(i = 0; i < _desktop_categories_cnt; i++) _desktop_categories[i].show = FALSE; - g_slist_foreach(handler->u.categories.apps, (GFunc)mimehandler_delete, + g_slist_foreach(handler->u.categories.apps, (GFunc)mimeapp_delete, NULL); g_slist_free(handler->u.categories.apps); handler->u.categories.apps = NULL; @@ -181,7 +186,9 @@ static gboolean _categories_on_refresh_done(DesktopHandler * handler) static void _categories_on_refresh_done_categories(DesktopHandler * handler) { GSList * p; + MimeApp * mimeapp; MimeHandler * mime; + String const * name; DesktopCategory * dc; String const ** categories; size_t i; @@ -191,14 +198,20 @@ static void _categories_on_refresh_done_categories(DesktopHandler * handler) for(p = handler->u.categories.apps; p != NULL; p = p->next) { - mime = p->data; + mimeapp = p->data; + mime = mimeapp_get_mime(mimeapp); + if((name = mimehandler_get_name(mime, 1)) == NULL) + { + desktop_serror(NULL, NULL, 1); + continue; + } filename = mimehandler_get_filename(mime); if((categories = mimehandler_get_categories(mime)) == NULL || categories[0] == NULL) { - /* FIXME keep track of the datadir */ if((icon = desktopicon_new_application(handler->desktop, - filename, NULL)) + filename, + mimeapp_get_datadir(mimeapp))) != NULL) desktop_icon_add(handler->desktop, icon, FALSE); continue; @@ -215,9 +228,9 @@ static void _categories_on_refresh_done_categories(DesktopHandler * handler) } if(i == _desktop_categories_cnt) { - /* FIXME keep track of the datadir */ if((icon = desktopicon_new_application(handler->desktop, - filename, NULL)) + filename, + mimeapp_get_datadir(mimeapp))) != NULL) desktop_icon_add(handler->desktop, icon, FALSE); continue; @@ -270,7 +283,7 @@ static void _categories_on_refresh_loop_path(DesktopHandler * handler, char * name = NULL; char * p; MimeHandler * mime; - (void) path; + MimeApp * mimeapp; if((dir = browser_vfs_opendir(apppath, &st)) == NULL) { @@ -304,17 +317,20 @@ static void _categories_on_refresh_loop_path(DesktopHandler * handler, fprintf(stderr, "DEBUG: %s() name=\"%s\" path=\"%s\"\n", __func__, name, path); #endif - if((mime = mimehandler_new_load(name)) == NULL - || mimehandler_can_display(mime) == 0) + if((mime = mimehandler_new_load(name)) == NULL) { - if(mime != NULL) - mimehandler_delete(mime); - else - desktop_serror(NULL, NULL, 1); + desktop_serror(NULL, NULL, 1); + continue; + } + if(mimehandler_can_display(mime) == 0 + || mimehandler_can_execute(mime) == 0 + || (mimeapp = mimeapp_new(mime, path)) == NULL) + { + mimehandler_delete(mime); continue; } handler->u.categories.apps = g_slist_insert_sorted( - handler->u.categories.apps, mime, + handler->u.categories.apps, mimeapp, _categories_apps_compare); } free(name); @@ -329,32 +345,44 @@ static void _categories_on_refresh_loop_xdg(DesktopHandler * handler, char * p; size_t i; size_t j; + int datadir = 1; + /* read through every XDG application folder */ if((path = getenv("XDG_DATA_DIRS")) == NULL || strlen(path) == 0) - /* XXX check this at build-time instead */ - path = (strcmp(DATADIR, "/usr/local/share") == 0) - ? DATADIR ":/usr/share" - : "/usr/local/share:" DATADIR ":/usr/share"; - if((p = strdup(path)) == NULL) { - desktop_perror(NULL, NULL, 1); - return; +#if defined(__NetBSD__) + /* XXX include the default path for pkgsrc */ + path = "/usr/pkg/share:" DATADIR ":/usr/share"; +#else + path = "/usr/local/share:" DATADIR ":/usr/share"; +#endif + datadir = 0; } - for(i = 0, j = 0;; i++) - if(p[i] == '\0') - { - _categories_on_refresh_loop_xdg_path(handler, callback, - &p[j]); - break; - } - else if(p[i] == ':') - { - p[i] = '\0'; - _categories_on_refresh_loop_xdg_path(handler, callback, - &p[j]); - j = i + 1; - } + if((p = strdup(path)) == NULL) + desktop_perror(NULL, NULL, 1); + else + for(i = 0, j = 0;; i++) + if(p[i] == '\0') + { + string_rtrim(&p[j], "/"); + _categories_on_refresh_loop_xdg_path(handler, + callback, &p[j]); + datadir |= (strcmp(&p[j], DATADIR) == 0); + break; + } + else if(p[i] == ':') + { + p[i] = '\0'; + string_rtrim(&p[j], "/"); + _categories_on_refresh_loop_xdg_path(handler, + callback, &p[j]); + datadir |= (strcmp(&p[j], DATADIR) == 0); + j = i + 1; + } free(p); + if(datadir == 0) + _categories_on_refresh_loop_xdg_path(handler, callback, + DATADIR); _categories_on_refresh_loop_xdg_home(handler, callback); } @@ -365,8 +393,7 @@ static void _categories_on_refresh_loop_xdg_home(DesktopHandler * handler, char const fallback[] = ".local/share"; char const * path; char const * homedir; - size_t len; - char * p; + String * p; /* use $XDG_DATA_HOME if set and not empty */ if((path = getenv("XDG_DATA_HOME")) != NULL && strlen(path) > 0) @@ -377,15 +404,13 @@ static void _categories_on_refresh_loop_xdg_home(DesktopHandler * handler, /* fallback to "$HOME/.local/share" */ if((homedir = getenv("HOME")) == NULL) homedir = g_get_home_dir(); - len = strlen(homedir) + 1 + sizeof(fallback); - if((p = malloc(len)) == NULL) + if((p = string_new_append(homedir, "/", fallback, NULL)) == NULL) { - desktop_perror(NULL, homedir, 1); + desktop_serror(NULL, homedir, 1); return; } - snprintf(p, len, "%s/%s", homedir, fallback); _categories_on_refresh_loop_xdg_path(handler, callback, p); - free(p); + string_delete(p); } static void _categories_on_refresh_loop_xdg_path(DesktopHandler * handler, @@ -403,14 +428,8 @@ static void _categories_on_refresh_loop_xdg_path(DesktopHandler * handler, static gint _categories_apps_compare(gconstpointer a, gconstpointer b) { - MimeHandler * mha = (MimeHandler *)a; - MimeHandler * mhb = (MimeHandler *)b; - String const * mhas; - String const * mhbs; + MimeApp const * maa = a; + MimeApp const * mab = b; - if((mhas = mimehandler_get_generic_name(mha, 1)) == NULL) - mhas = mimehandler_get_name(mha, 1); - if((mhbs = mimehandler_get_generic_name(mhb, 1)) == NULL) - mhbs = mimehandler_get_name(mhb, 1); - return string_compare(mhas, mhbs); + return mimeapp_compare(maa, mab); } diff --git a/src/desktop/handler/mimeapp.c b/src/desktop/handler/mimeapp.c new file mode 100644 index 0000000..6027d69 --- /dev/null +++ b/src/desktop/handler/mimeapp.c @@ -0,0 +1,103 @@ +/* $Id$ */ +/* Copyright (c) 2020 Pierre Pronchery */ +/* This file is part of DeforaOS Desktop Browser */ +/* Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY ITS AUTHORS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + + + +#include "mimeapp.h" + + +/* MimeApp */ +/* private */ +/* types */ +struct _MimeApp +{ + MimeHandler * mime; + String * datadir; +}; + + +/* public */ +/* functions */ +/* mimeapp_new */ +MimeApp * mimeapp_new(MimeHandler * mime, String const * datadir) +{ + MimeApp * mimeapp; + + if((mimeapp = object_new(sizeof(*mimeapp))) == NULL) + return NULL; + mimeapp->mime = NULL; + if(datadir == NULL) + mimeapp->datadir = NULL; + else if((mimeapp->datadir = string_new(datadir)) == NULL) + { + mimeapp_delete(mimeapp); + return NULL; + } + mimeapp->mime = mime; + return mimeapp; +} + + +/* mimeapp_delete */ +void mimeapp_delete(MimeApp * mimeapp) +{ + if(mimeapp->mime != NULL) + mimehandler_delete(mimeapp->mime); + string_delete(mimeapp->datadir); + object_delete(mimeapp); +} + + +/* accessors */ +/* mimeapp_get_mime */ +MimeHandler * mimeapp_get_mime(MimeApp const * mimeapp) +{ + return mimeapp->mime; +} + + +/* mimeapp_get_datadir */ +String const * mimeapp_get_datadir(MimeApp const * mimeapp) +{ + return mimeapp->datadir; +} + + +/* mimeapp_compare */ +int mimeapp_compare(MimeApp const * mime, MimeApp const * to) +{ + MimeHandler * mha; + MimeHandler * mhb; + String const * mhas; + String const * mhbs; + + mha = mimeapp_get_mime(mime); + mhb = mimeapp_get_mime(to); + if((mhas = mimehandler_get_generic_name(mha, 1)) == NULL) + mhas = mimehandler_get_name(mha, 1); + if((mhbs = mimehandler_get_generic_name(mhb, 1)) == NULL) + mhbs = mimehandler_get_name(mhb, 1); + return string_compare(mhas, mhbs); +} diff --git a/src/desktop/handler/mimeapp.h b/src/desktop/handler/mimeapp.h new file mode 100644 index 0000000..e249149 --- /dev/null +++ b/src/desktop/handler/mimeapp.h @@ -0,0 +1,55 @@ +/* $Id$ */ +/* Copyright (c) 2020 Pierre Pronchery */ +/* This file is part of DeforaOS Desktop Browser */ +/* Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY ITS AUTHORS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + + + +#ifndef MIMEAPP_H +# define MIMEAPP_H + +# include +# include + + +/* MimeApp */ +/* private */ +/* types */ +typedef struct _MimeApp MimeApp; + + +/* prototypes */ +/* MimeApp */ +MimeApp * mimeapp_new(MimeHandler * mime, String const * datadir); +void mimeapp_delete(MimeApp * mimeapp); + + +/* accessors */ +MimeHandler * mimeapp_get_mime(MimeApp const * mimeapp); +String const * mimeapp_get_datadir(MimeApp const * mimeapp); + + +/* useful */ +int mimeapp_compare(MimeApp const * mime, MimeApp const * to); + +#endif /* !MIMEAPP_H */ diff --git a/src/desktop/project.conf b/src/desktop/project.conf index 332ea44..ec22f80 100644 --- a/src/desktop/project.conf +++ b/src/desktop/project.conf @@ -1,19 +1,19 @@ -targets=desktop,desktopctl +targets=desktop,desktopctl,handler/mimeapp.o cppflags_force=-I../../include #cppflags=-D EMBEDDED cflags_force=`pkg-config --cflags libDesktop` cflags=-W -Wall -g -O2 -fPIE -D_FORTIFY_SOURCE=2 -fstack-protector ldflags_force=`pkg-config --libs libDesktop` -lintl ldflags=-pie -Wl,-z,relro -Wl,-z,now -dist=Makefile,desktop.h,desktopicon.h,desktopiconwindow.h,handler.h,handler/applications.c,handler/categories.c,handler/files.c,handler/homescreen.c +dist=Makefile,desktop.h,desktopicon.h,desktopiconwindow.h,handler.h,handler/applications.c,handler/categories.c,handler/files.c,handler/homescreen.c,handler/mimeapp.h #targets [desktop] type=binary -depends=$(OBJDIR)../lib/libBrowser.a +depends=$(OBJDIR)../lib/libBrowser.a,$(OBJDIR)handler/mimeapp.o sources=desktop.c,desktopicon.c,desktopiconwindow.c,handler.c,main.c cflags=`pkg-config --cflags x11 xrandr` -ldflags=`pkg-config --libs x11 xrandr` -L$(OBJDIR)../lib -Wl,-rpath,$(LIBDIR) -lBrowser +ldflags=`pkg-config --libs x11 xrandr` -L$(OBJDIR)../lib -Wl,-rpath,$(LIBDIR) -lBrowser $(OBJDIR)handler/mimeapp.o install=$(BINDIR) [desktopctl] @@ -21,6 +21,10 @@ type=binary sources=desktopctl.c install=$(BINDIR) +[handler/mimeapp.o] +type=object +sources=handler/mimeapp.c + #sources [desktop.c] depends=../common.h,../common.c,desktopicon.h,desktop.h,../../config.h @@ -37,7 +41,7 @@ cppflags=-D PREFIX=\"$(PREFIX)\" depends=../common.h,desktop.h,desktopicon.h,desktopiconwindow.h [handler.c] -depends=desktop.h,desktopicon.h,desktopiconwindow.h,handler.h,handler/applications.c,handler/categories.c,handler/files.c,handler/homescreen.c +depends=desktop.h,desktopicon.h,desktopiconwindow.h,handler.h,handler/applications.c,handler/categories.c,handler/files.c,handler/homescreen.c,handler/mimeapp.h [main.c] depends=desktop.h,../../config.h