mirror of
git://projects.qi-hardware.com/gmenu2x.git
synced 2025-02-17 01:54:42 +02:00
Monitor OPK folders using inotify and automatically add/delete links
This commit is contained in:
parent
1467c9b9d7
commit
13b3d8e0ca
@ -78,6 +78,10 @@ AC_ARG_ENABLE(cpufreq,
|
|||||||
[ --disable-cpufreq disable support for CPU frequency scaling],
|
[ --disable-cpufreq disable support for CPU frequency scaling],
|
||||||
[CPUFREQ=no],,)
|
[CPUFREQ=no],,)
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(inotify,
|
||||||
|
[ --disable-inotify disable file monitoring],
|
||||||
|
[INOTIFY=no],,)
|
||||||
|
|
||||||
AC_SUBST(PLATFORM)
|
AC_SUBST(PLATFORM)
|
||||||
AC_SUBST(SCREEN_RES)
|
AC_SUBST(SCREEN_RES)
|
||||||
AC_DEFINE_UNQUOTED(PLATFORM, "${PLATFORM}")
|
AC_DEFINE_UNQUOTED(PLATFORM, "${PLATFORM}")
|
||||||
@ -86,5 +90,9 @@ if test "x$CPUFREQ" != xno ; then
|
|||||||
AC_DEFINE(ENABLE_CPUFREQ)
|
AC_DEFINE(ENABLE_CPUFREQ)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "x$INOTIFY" != xno ; then
|
||||||
|
AC_DEFINE(ENABLE_INOTIFY)
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
AC_OUTPUT(Makefile src/Makefile data/Makefile)
|
AC_OUTPUT(Makefile src/Makefile data/Makefile)
|
||||||
|
@ -12,7 +12,7 @@ gmenu2x_SOURCES = asfont.cpp button.cpp cpu.cpp dirdialog.cpp filedialog.cpp \
|
|||||||
textdialog.cpp textmanualdialog.cpp touchscreen.cpp translator.cpp \
|
textdialog.cpp textmanualdialog.cpp touchscreen.cpp translator.cpp \
|
||||||
utilities.cpp wallpaperdialog.cpp \
|
utilities.cpp wallpaperdialog.cpp \
|
||||||
browsedialog.cpp buttonbox.cpp dialog.cpp \
|
browsedialog.cpp buttonbox.cpp dialog.cpp \
|
||||||
imageio.cpp powersaver.cpp
|
imageio.cpp powersaver.cpp monitor.cpp
|
||||||
|
|
||||||
noinst_HEADERS = asfont.h button.h cpu.h dirdialog.h FastDelegate.h \
|
noinst_HEADERS = asfont.h button.h cpu.h dirdialog.h FastDelegate.h \
|
||||||
filedialog.h filelister.h gmenu2x.h gp2x.h iconbutton.h imagedialog.h \
|
filedialog.h filelister.h gmenu2x.h gp2x.h iconbutton.h imagedialog.h \
|
||||||
@ -25,7 +25,7 @@ noinst_HEADERS = asfont.h button.h cpu.h dirdialog.h FastDelegate.h \
|
|||||||
surfacecollection.h surface.h textdialog.h textmanualdialog.h \
|
surfacecollection.h surface.h textdialog.h textmanualdialog.h \
|
||||||
touchscreen.h translator.h utilities.h wallpaperdialog.h \
|
touchscreen.h translator.h utilities.h wallpaperdialog.h \
|
||||||
browsedialog.h buttonbox.h dialog.h \
|
browsedialog.h buttonbox.h dialog.h \
|
||||||
imageio.h powersaver.h
|
imageio.h powersaver.h monitor.h
|
||||||
|
|
||||||
AM_CFLAGS= @CFLAGS@ @SDL_CFLAGS@
|
AM_CFLAGS= @CFLAGS@ @SDL_CFLAGS@
|
||||||
|
|
||||||
|
@ -244,7 +244,7 @@ GMenu2X::GMenu2X()
|
|||||||
DEBUG("Loading system input.conf file: %s.\n", input_file.c_str());
|
DEBUG("Loading system input.conf file: %s.\n", input_file.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
input.init(input_file);
|
input.init(input_file, menu);
|
||||||
|
|
||||||
if (confInt["backlightTimeout"] > 0)
|
if (confInt["backlightTimeout"] > 0)
|
||||||
PowerSaver::getInstance()->setScreenTimeout( confInt["backlightTimeout"] );
|
PowerSaver::getInstance()->setScreenTimeout( confInt["backlightTimeout"] );
|
||||||
|
@ -22,13 +22,16 @@
|
|||||||
#include "inputmanager.h"
|
#include "inputmanager.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
#include "powersaver.h"
|
#include "powersaver.h"
|
||||||
|
#include "menu.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
void InputManager::init(const string &conffile) {
|
void InputManager::init(const string &conffile, Menu *menu) {
|
||||||
|
this->menu = menu;
|
||||||
|
|
||||||
for (int i = 0; i < BUTTON_TYPE_SIZE; i++) {
|
for (int i = 0; i < BUTTON_TYPE_SIZE; i++) {
|
||||||
buttonMap[i].source = UNMAPPED;
|
buttonMap[i].source = UNMAPPED;
|
||||||
}
|
}
|
||||||
@ -174,6 +177,15 @@ bool InputManager::getEvent(ButtonEvent *bevent, bool wait) {
|
|||||||
source = JOYSTICK;
|
source = JOYSTICK;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case SDL_USEREVENT:
|
||||||
|
if (!event.user.code)
|
||||||
|
menu->removePackageLink((const char *) event.user.data1);
|
||||||
|
else
|
||||||
|
menu->openPackage((const char *) event.user.data1);
|
||||||
|
free(event.user.data1);
|
||||||
|
bevent->state = PRESSED;
|
||||||
|
bevent->button = REPAINT;
|
||||||
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
class Menu;
|
||||||
|
|
||||||
class InputManager {
|
class InputManager {
|
||||||
public:
|
public:
|
||||||
enum Button {
|
enum Button {
|
||||||
@ -32,7 +34,8 @@ public:
|
|||||||
ALTLEFT, ALTRIGHT,
|
ALTLEFT, ALTRIGHT,
|
||||||
MENU, SETTINGS,
|
MENU, SETTINGS,
|
||||||
VOLUP, VOLDOWN,
|
VOLUP, VOLDOWN,
|
||||||
POWER, LOCK
|
POWER, LOCK,
|
||||||
|
REPAINT,
|
||||||
};
|
};
|
||||||
#define BUTTON_TYPE_SIZE 14
|
#define BUTTON_TYPE_SIZE 14
|
||||||
|
|
||||||
@ -45,7 +48,7 @@ public:
|
|||||||
InputManager();
|
InputManager();
|
||||||
~InputManager();
|
~InputManager();
|
||||||
|
|
||||||
void init(const std::string &conffile);
|
void init(const std::string &conffile, Menu *menu);
|
||||||
bool waitForEvent(ButtonEvent *event);
|
bool waitForEvent(ButtonEvent *event);
|
||||||
Button waitForPressedButton();
|
Button waitForPressedButton();
|
||||||
Button waitForReleasedButton();
|
Button waitForReleasedButton();
|
||||||
@ -58,6 +61,8 @@ private:
|
|||||||
unsigned int code;
|
unsigned int code;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Menu *menu;
|
||||||
|
|
||||||
void readConfFile(const std::string &conffile);
|
void readConfFile(const std::string &conffile);
|
||||||
bool getEvent(ButtonEvent *bevent, bool wait);
|
bool getEvent(ButtonEvent *bevent, bool wait);
|
||||||
Button waitForButton(ButtonState state);
|
Button waitForButton(ButtonState state);
|
||||||
|
@ -61,6 +61,7 @@ public:
|
|||||||
#ifdef HAVE_LIBOPK
|
#ifdef HAVE_LIBOPK
|
||||||
const std::string &getCategory() { return category; }
|
const std::string &getCategory() { return category; }
|
||||||
bool isOpk() { return isOPK; }
|
bool isOpk() { return isOPK; }
|
||||||
|
const std::string &getOpkFile() { return opkFile; }
|
||||||
|
|
||||||
LinkApp(GMenu2X *gmenu2x, Touchscreen &ts, InputManager &inputMgr,
|
LinkApp(GMenu2X *gmenu2x, Touchscreen &ts, InputManager &inputMgr,
|
||||||
const char* linkfile, struct OPK *opk = NULL);
|
const char* linkfile, struct OPK *opk = NULL);
|
||||||
|
31
src/menu.cpp
31
src/menu.cpp
@ -34,6 +34,7 @@
|
|||||||
#include "gmenu2x.h"
|
#include "gmenu2x.h"
|
||||||
#include "linkapp.h"
|
#include "linkapp.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
#include "monitor.h"
|
||||||
#include "filelister.h"
|
#include "filelister.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
@ -67,6 +68,9 @@ Menu::Menu(GMenu2X *gmenu2x, Touchscreen &ts)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
readPackages(path);
|
readPackages(path);
|
||||||
|
#ifdef ENABLE_INOTIFY
|
||||||
|
monitors.push_back(new Monitor(path.c_str()));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
closedir(dirp);
|
closedir(dirp);
|
||||||
}
|
}
|
||||||
@ -533,6 +537,33 @@ void Menu::readPackages(std::string parentDir)
|
|||||||
|
|
||||||
closedir(dirp);
|
closedir(dirp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_INOTIFY
|
||||||
|
void Menu::removePackageLink(std::string path)
|
||||||
|
{
|
||||||
|
for (vector< vector<Link*> >::iterator section = links.begin();
|
||||||
|
section < links.end(); section++) {
|
||||||
|
for (vector<Link*>::iterator link = section->begin();
|
||||||
|
link < section->end(); link++) {
|
||||||
|
LinkApp *app = dynamic_cast<LinkApp *> (*link);
|
||||||
|
if (!app || !app->isOpk() || app->getOpkFile().empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (app->isOpk() && app->getOpkFile().compare(path) == 0) {
|
||||||
|
DEBUG("Removing link corresponding to package %s\n",
|
||||||
|
app->getOpkFile().c_str());
|
||||||
|
section->erase(link);
|
||||||
|
if (section - links.begin() == iSection
|
||||||
|
&& iLink == (int) section->size())
|
||||||
|
setLinkIndex(iLink - 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ERROR("Unable to find link corresponding to %s\n", path.c_str());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Menu::readLinksOfSection(std::string path, std::vector<std::string> &linkfiles)
|
void Menu::readLinksOfSection(std::string path, std::vector<std::string> &linkfiles)
|
||||||
|
12
src/menu.h
12
src/menu.h
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
class LinkApp;
|
class LinkApp;
|
||||||
class GMenu2X;
|
class GMenu2X;
|
||||||
|
class Monitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Handles the menu structure
|
Handles the menu structure
|
||||||
@ -52,7 +53,9 @@ private:
|
|||||||
#ifdef HAVE_LIBOPK
|
#ifdef HAVE_LIBOPK
|
||||||
// Load all the .opk packages of the given directory
|
// Load all the .opk packages of the given directory
|
||||||
void readPackages(std::string parentDir);
|
void readPackages(std::string parentDir);
|
||||||
void openPackage(std::string path);
|
#ifdef ENABLE_INOTIFY
|
||||||
|
std::vector<Monitor *> monitors;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Load all the links on the given section directory.
|
// Load all the links on the given section directory.
|
||||||
@ -62,6 +65,13 @@ public:
|
|||||||
Menu(GMenu2X *gmenu2x, Touchscreen &ts);
|
Menu(GMenu2X *gmenu2x, Touchscreen &ts);
|
||||||
~Menu();
|
~Menu();
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBOPK
|
||||||
|
void openPackage(std::string path);
|
||||||
|
#ifdef ENABLE_INOTIFY
|
||||||
|
void removePackageLink(std::string path);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
std::vector<Link*> *sectionLinks(int i = -1);
|
std::vector<Link*> *sectionLinks(int i = -1);
|
||||||
|
|
||||||
int selSectionIndex();
|
int selSectionIndex();
|
||||||
|
71
src/monitor.cpp
Normal file
71
src/monitor.cpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#ifdef ENABLE_INOTIFY
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <SDL.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/inotify.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "monitor.h"
|
||||||
|
|
||||||
|
static void * inotify_thd(void *p)
|
||||||
|
{
|
||||||
|
const char *path = (const char *) p;
|
||||||
|
int wd, fd;
|
||||||
|
|
||||||
|
DEBUG("Starting inotify thread for path %s...\n", path);
|
||||||
|
|
||||||
|
fd = inotify_init();
|
||||||
|
if (fd == -1) {
|
||||||
|
ERROR("Unable to start inotify\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wd = inotify_add_watch(fd, path, IN_MOVED_FROM | IN_MOVED_TO |
|
||||||
|
IN_CLOSE_WRITE | IN_DELETE);
|
||||||
|
if (wd == -1) {
|
||||||
|
ERROR("Unable to add inotify watch\n");
|
||||||
|
close(fd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG("Starting watching directory %s\n", path);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
size_t len = sizeof(struct inotify_event) + NAME_MAX + 1;
|
||||||
|
struct inotify_event event;
|
||||||
|
char buf[256];
|
||||||
|
|
||||||
|
read(fd, &event, len);
|
||||||
|
sprintf(buf, "%s/%s", path, event.name);
|
||||||
|
|
||||||
|
/* Don't bother other files than OPKs */
|
||||||
|
len = strlen(event.name);
|
||||||
|
if (len < 5 || strncmp(event.name + len - 4, ".opk", 4))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SDL_UserEvent e = {
|
||||||
|
.type = SDL_USEREVENT,
|
||||||
|
.code = (int) (event.mask & (IN_MOVED_TO | IN_CLOSE_WRITE)),
|
||||||
|
.data1 = strdup(buf),
|
||||||
|
.data2 = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Inject an user event, that will be handled as a "repaint"
|
||||||
|
* event by the InputManager */
|
||||||
|
SDL_PushEvent((SDL_Event *) &e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Monitor::Monitor(std::string path) : path(path)
|
||||||
|
{
|
||||||
|
pthread_create(&thd, NULL, inotify_thd, (void *) path.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
Monitor::~Monitor(void)
|
||||||
|
{
|
||||||
|
pthread_kill(thd, SIGINT);
|
||||||
|
}
|
||||||
|
#endif
|
17
src/monitor.h
Normal file
17
src/monitor.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef __MONITOR_H__
|
||||||
|
#define __MONITOR_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
class Monitor {
|
||||||
|
public:
|
||||||
|
Monitor(std::string path);
|
||||||
|
~Monitor();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string path;
|
||||||
|
pthread_t thd;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __MONITOR_H__ */
|
Loading…
x
Reference in New Issue
Block a user