can start programs now

This commit is contained in:
Nishi 2025-12-23 22:29:18 +09:00
commit 6f8d41fd9a
Signed by: nishi
GPG key ID: 27EF69B208EB9343
3 changed files with 128 additions and 55 deletions

View file

@ -25,6 +25,8 @@ static void resize(MwWidget handle, void* user, void* client) {
int main() { int main() {
MwRect rc; MwRect rc;
signal(SIGCHLD, SIG_IGN);
MwLibraryInit(); MwLibraryInit();
window = MwVaCreateWidget(MwWindowClass, "window", NULL, MwDEFAULT, MwDEFAULT, 0, 0, window = MwVaCreateWidget(MwWindowClass, "window", NULL, MwDEFAULT, MwDEFAULT, 0, 0,

View file

@ -12,6 +12,7 @@
/* Standard */ /* Standard */
#include <dlfcn.h> #include <dlfcn.h>
#include <unistd.h>
/* main.c */ /* main.c */
extern MwWidget window, box; extern MwWidget window, box;

View file

@ -11,6 +11,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#define TriW 5 #define TriW 5
@ -23,16 +24,19 @@ typedef struct opaque {
char* name; char* name;
char* category; char* category;
char* exec;
} opaque_t; } opaque_t;
static int dumper(void* user, const char* section, const char* name, const char* value) { static int dumper(void* user, const char* section, const char* name, const char* value) {
opaque_t* opaque = user; opaque_t* opaque = user;
if(strcmp(section, "Desktop Entry") != 0) return 1; if(strcmp(section, "Desktop Entry") != 0) return 1;
if(strcmp(name, "Name") == 0){ if(strcmp(name, "Name") == 0) {
opaque->name = MwStringDuplicate(value); opaque->name = MwStringDuplicate(value);
}else if(strcmp(name, "Categories") == 0){ } else if(strcmp(name, "Categories") == 0) {
opaque->category = MwStringDuplicate(value); opaque->category = MwStringDuplicate(value);
} else if(strcmp(name, "Exec") == 0) {
opaque->exec = MwStringDuplicate(value);
} }
return 1; return 1;
@ -56,65 +60,65 @@ enum CATEGORY {
}; };
static const char* category_mapping[] = { static const char* category_mapping[] = {
"Lost & Found", "Lost & Found",
"Multimedia", "Multimedia",
"Audio", "Audio",
"Video", "Video",
"Development", "Development",
"Education", "Education",
"Game", "Game",
"Graphics", "Graphics",
"Network", "Network",
"Office", "Office",
"Science", "Science",
"Settings", "Settings",
"System", "System",
"Utility" "Utility"};
};
static void call(const char* name, int dir, int symlink, void* user){ static void call(const char* name, int dir, int symlink, void* user) {
opaque_t* opaque = user; opaque_t* opaque = user;
int c = C_UNKNOWN; int c = C_UNKNOWN;
opaque->name = NULL; opaque->name = NULL;
opaque->category = NULL; opaque->category = NULL;
opaque->exec = NULL;
ini_parse(name, dumper, user); ini_parse(name, dumper, user);
if(opaque->category != NULL){ if(opaque->category != NULL) {
char* str = opaque->category; char* str = opaque->category;
while(str != NULL){ while(str != NULL) {
char* s = strchr(str, ';'); char* s = strchr(str, ';');
if(s != NULL){ if(s != NULL) {
s[0] = 0; s[0] = 0;
} }
if(strcasecmp(str, "AudioVideo") == 0){ if(strcasecmp(str, "AudioVideo") == 0) {
c = C_AUDIOVIDEO; c = C_AUDIOVIDEO;
}else if(strcasecmp(str, "Audio") == 0){ } else if(strcasecmp(str, "Audio") == 0) {
c = C_AUDIO; c = C_AUDIO;
}else if(strcasecmp(str, "Video") == 0){ } else if(strcasecmp(str, "Video") == 0) {
c = C_VIDEO; c = C_VIDEO;
}else if(strcasecmp(str, "Development") == 0){ } else if(strcasecmp(str, "Development") == 0) {
c = C_DEVELOPMENT; c = C_DEVELOPMENT;
}else if(strcasecmp(str, "Education") == 0){ } else if(strcasecmp(str, "Education") == 0) {
c = C_EDUCATION; c = C_EDUCATION;
}else if(strcasecmp(str, "Game") == 0){ } else if(strcasecmp(str, "Game") == 0) {
c = C_GAME; c = C_GAME;
}else if(strcasecmp(str, "Graphics") == 0){ } else if(strcasecmp(str, "Graphics") == 0) {
c = C_GRAPHICS; c = C_GRAPHICS;
}else if(strcasecmp(str, "Network") == 0){ } else if(strcasecmp(str, "Network") == 0) {
c = C_NETWORK; c = C_NETWORK;
}else if(strcasecmp(str, "Office") == 0){ } else if(strcasecmp(str, "Office") == 0) {
c = C_OFFICE; c = C_OFFICE;
}else if(strcasecmp(str, "Science") == 0){ } else if(strcasecmp(str, "Science") == 0) {
c = C_SCIENCE; c = C_SCIENCE;
}else if(strcasecmp(str, "Settings") == 0){ } else if(strcasecmp(str, "Settings") == 0) {
c = C_SETTINGS; c = C_SETTINGS;
}else if(strcasecmp(str, "System") == 0){ } else if(strcasecmp(str, "System") == 0) {
c = C_SYSTEM; c = C_SYSTEM;
}else if(strcasecmp(str, "Utility") == 0){ } else if(strcasecmp(str, "Utility") == 0) {
c = C_UTILITY; c = C_UTILITY;
} }
@ -125,45 +129,108 @@ static void call(const char* name, int dir, int symlink, void* user){
free(opaque->category); free(opaque->category);
} }
if(opaque->name != NULL){ if(opaque->name != NULL) {
int i; int i;
MwMenu mc = NULL, m; MwMenu mc = NULL, m;
for(i = 0; i < arrlen(opaque->menu->sub); i++){ for(i = 0; i < arrlen(opaque->menu->sub); i++) {
if(strcmp(opaque->menu->sub[i]->name, category_mapping[c]) == 0){ if(strcmp(opaque->menu->sub[i]->name, category_mapping[c]) == 0) {
mc = opaque->menu->sub[i]; mc = opaque->menu->sub[i];
break; break;
} }
} }
if(mc == NULL){ if(mc == NULL) {
mc = malloc(sizeof(*mc)); mc = malloc(sizeof(*mc));
mc->name = (char*)category_mapping[c]; mc->name = (char*)category_mapping[c];
mc->keep = 0; mc->keep = 0;
mc->sub = NULL; mc->sub = NULL;
mc->wsub = NULL; mc->wsub = NULL;
arrput(opaque->menu->sub, mc); arrput(opaque->menu->sub, mc);
} }
for(i = 0; i < arrlen(mc->sub); i++){ for(i = 0; i < arrlen(mc->sub); i++) {
if(strcmp(mc->sub[i]->name, opaque->name) == 0){ if(strcmp(mc->sub[i]->name, opaque->name) == 0) {
break; break;
} }
} }
if(i == arrlen(mc->sub)){ if(i == arrlen(mc->sub)) {
m = malloc(sizeof(*m)); m = malloc(sizeof(*m));
m->name = opaque->name; m->name = opaque->name;
m->keep = 0; m->keep = 0;
m->sub = NULL; m->sub = NULL;
m->wsub = NULL; m->wsub = NULL;
m->opaque = opaque->exec;
arrput(mc->sub, m); arrput(mc->sub, m);
} }
} }
} }
static char** desktop_exec(const char* exec, const char* file) {
char** a = NULL;
int i;
char* buf = malloc(1);
buf[0] = 0;
for(i = 0;; i++) {
if(exec[i] == ' ' || exec[i] == 0) {
if(strlen(buf) > 0) arrput(a, buf);
buf = malloc(1);
buf[0] = 0;
if(exec[i] == 0) break;
} else if(exec[i] == '%') {
char c = exec[++i];
if(c == 'f' && file != NULL) {
char* old = buf;
buf = malloc(strlen(old) + strlen(file) + 1);
strcpy(buf, old);
strcpy(buf + strlen(old), file);
free(old);
}
} else {
char* old = buf;
buf = malloc(strlen(old) + 2);
strcpy(buf, old);
buf[strlen(old)] = exec[i];
buf[strlen(old) + 1] = 0;
free(old);
}
}
arrput(a, NULL);
return a;
}
static void menu(MwWidget handle, void* user, void* client) { static void menu(MwWidget handle, void* user, void* client) {
opaque_t* opaque = handle->opaque; opaque_t* opaque = handle->opaque;
char* s = NULL;
MwMenu m = client;
if(m->opaque != NULL) {
char** args = desktop_exec(m->opaque, NULL);
int i;
if(fork() == 0) {
execvp(args[0], args);
_exit(-1);
}
for(i = 0; i < arrlen(args); i++) {
if(args[i] != NULL) free(args[i]);
}
arrfree(args);
}
if(opaque->is_opened) { if(opaque->is_opened) {
opaque->is_opened = 0; opaque->is_opened = 0;
@ -204,7 +271,7 @@ static void activate(MwWidget handle, void* user, void* client) {
} }
} }
int sort_alphabet(const void* a, const void* b){ int sort_alphabet(const void* a, const void* b) {
return strcmp((*((MwMenu*)a))->name, (*((MwMenu*)b))->name); return strcmp((*((MwMenu*)a))->name, (*((MwMenu*)b))->name);
} }
@ -217,7 +284,7 @@ void module(MwWidget box, config_setting_t* setting) {
unsigned char* rgb; unsigned char* rgb;
opaque_t* opaque = malloc(sizeof(*opaque)); opaque_t* opaque = malloc(sizeof(*opaque));
MwMenu m; MwMenu m;
int i; int i;
if((rgb = stbi_load(ICON64DIR "/logo.png", &w, &h, &ch, 4)) != NULL) { if((rgb = stbi_load(ICON64DIR "/logo.png", &w, &h, &ch, 4)) != NULL) {
int bw = MwGetInteger(box, MwNheight) - MwDefaultBorderWidth(box) * 2; int bw = MwGetInteger(box, MwNheight) - MwDefaultBorderWidth(box) * 2;
@ -283,9 +350,12 @@ void module(MwWidget box, config_setting_t* setting) {
MDEDirectoryScan(DATAROOTDIR "/applications", call, opaque); MDEDirectoryScan(DATAROOTDIR "/applications", call, opaque);
MDEDirectoryScan("/usr/share/applications", call, opaque); MDEDirectoryScan("/usr/share/applications", call, opaque);
#if defined(__NetBSD__)
MDEDirectoryScan("/usr/pkg/share/applications", call, opaque);
#endif
qsort(opaque->menu->sub, arrlen(opaque->menu->sub), sizeof(MwMenu), sort_alphabet); qsort(opaque->menu->sub, arrlen(opaque->menu->sub), sizeof(MwMenu), sort_alphabet);
for(i = 0; i < arrlen(opaque->menu->sub); i++){ for(i = 0; i < arrlen(opaque->menu->sub); i++) {
qsort(opaque->menu->sub[i]->sub, arrlen(opaque->menu->sub[i]->sub), sizeof(MwMenu), sort_alphabet); qsort(opaque->menu->sub[i]->sub, arrlen(opaque->menu->sub[i]->sub), sizeof(MwMenu), sort_alphabet);
} }