Bring the code closer to DeforaOS Panel's menu applet

This commit is contained in:
Pierre Pronchery 2020-09-28 05:50:01 +02:00
parent 0f6bd4da3f
commit d83fe8f5b5
5 changed files with 251 additions and 118 deletions

View File

@ -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);
}

View File

@ -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);
}

View File

@ -0,0 +1,103 @@
/* $Id$ */
/* Copyright (c) 2020 Pierre Pronchery <khorben@defora.org> */
/* 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);
}

View File

@ -0,0 +1,55 @@
/* $Id$ */
/* Copyright (c) 2020 Pierre Pronchery <khorben@defora.org> */
/* 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 <System.h>
# include <Desktop/mimehandler.h>
/* 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 */

View File

@ -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