Imported evoke

This commit is contained in:
Sanel Zukan 2007-07-11 16:03:18 +00:00
parent adc3a8efcd
commit a569d78563
9 changed files with 564 additions and 0 deletions

138
evoke/EvokeService.cpp Normal file
View File

@ -0,0 +1,138 @@
/*
* $Id$
*
* Evoke, head honcho of everything
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2000-2007 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
*/
#include "Log.h"
#include "EvokeService.h"
#include <edelib/File.h>
#include <edelib/Config.h>
#include <edelib/StrUtil.h>
#include <sys/types.h> // getpid
#include <unistd.h> //
#include <stdlib.h> // free
#include <string.h> // strdup
EvokeService::EvokeService() : logfile(NULL), pidfile(NULL) {
}
EvokeService::~EvokeService() {
if(logfile)
delete logfile;
if(pidfile) {
edelib::file_remove(pidfile);
free(pidfile);
}
}
EvokeService* EvokeService::instance(void) {
static EvokeService es;
return &es;
}
bool EvokeService::setup_logging(const char* file) {
if(!file)
logfile = new DummyLog();
else
logfile = new RealLog();
if(!logfile->open(file)) {
delete logfile;
return false;
}
return true;
}
bool EvokeService::setup_pid(const char* file) {
if(!file)
return false;
if(edelib::file_exists(file))
return false;
FILE* f = fopen(file, "w");
if(!f)
return false;
fprintf(f, "%i", getpid());
fclose(f);
pidfile = strdup(file);
return true;
}
bool EvokeService::setup_config(const char* config, bool do_startup) {
// for now if is not startup mode, ignore it
if(!do_startup)
return true;
edelib::Config c;
if(!c.load(config))
return false;
char buff[1024];
if(!c.get("evoke", "Startup", buff, sizeof(buff)))
return false;
edelib::vector<edelib::String> vs;
edelib::stringtok(vs, buff, ",");
// nothing, fine, do nothing
unsigned int sz = vs.size();
if(sz == 0)
return true;
EvokeClient ec;
const char* key_name;
for(unsigned int i = 0; i < sz; i++) {
key_name = vs[i].c_str();
edelib::str_trim((char*)key_name);
// probably listed but not the same key; also Exec value must exists
if(!c.get(key_name, "Exec", buff, sizeof(buff)))
continue;
else
ec.exec = buff;
if(c.get(key_name, "Message", buff, sizeof(buff)))
ec.message = buff;
// it is no EDE app untill say so
c.get(key_name, "Core", ec.core, false);
if(c.get(key_name, "Icon", buff, sizeof(buff)))
ec.icon = buff;
clients.push_back(ec);
}
for(unsigned int i = 0; i < clients.size(); i++) {
printf("Exec: %s\n", clients[i].exec.c_str());
printf("Message: %s\n", clients[i].message.c_str());
printf("Icon: %s\n", clients[i].icon.c_str());
printf("Core: %i\n\n", clients[i].core);
}
return true;
}
void EvokeService::setup_atoms(Display* d) {
_ede_shutdown_all = XInternAtom(d, "_EDE_EVOKE_SHUTDOWN_ALL", False);
_ede_spawn = XInternAtom(d, "_EDE_EVOKE_SPAWN", False);
_ede_shutdown_client = XInternAtom(d, "_EDE_SHUTDOWN", False);
}
int EvokeService::handle(int event) {
logfile->printf("Got event %i\n", event);
return 0;
}

57
evoke/EvokeService.h Normal file
View File

@ -0,0 +1,57 @@
/*
* $Id$
*
* Evoke, head honcho of everything
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2000-2007 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
*/
#ifndef __EVOKESERVICE_H__
#define __EVOKESERVICE_H__
#include "Log.h"
#include <X11/Xlib.h>
#include <edelib/Vector.h>
#include <edelib/String.h>
struct EvokeClient {
edelib::String message; // message during startup
edelib::String icon; // icon for this client
edelib::String exec; // program name/path to run
bool core; // does understaind _EDE_SHUTDOWN_SELF (only ede apps)
};
class EvokeService {
private:
Log* logfile;
char* pidfile;
Atom _ede_shutdown_all;
Atom _ede_shutdown_client;
Atom _ede_spawn;
edelib::vector<EvokeClient> clients;
public:
EvokeService();
~EvokeService();
static EvokeService* instance(void);
bool setup_logging(const char* file);
bool setup_pid(const char* file);
bool setup_config(const char* config, bool do_startup);
void setup_atoms(Display* d);
int handle(int event);
Log* log(void) { return logfile; }
};
#define EVOKE_LOG EvokeService::instance()->log()->printf
#endif

6
evoke/Jamfile Normal file
View File

@ -0,0 +1,6 @@
LINKLIBS = -L/opt/ede/lib -ledelib -lao -lvorbis -lvorbisfile -lmad -L/usr/local/lib -L/usr/X11R6/lib -lfltk_images -lpng -lz -ljpeg -lfltk -ldl -lm -lXext -lX11 -lstdc++ ;
C++FLAGS += -I/opt/ede/include -Wall -pedantic -D_DEBUG -g3 -I/usr/local/include -I/usr/X11R6/include ;
Main evoke : evoke.cpp EvokeService.cpp Log.cpp ;

73
evoke/Log.cpp Normal file
View File

@ -0,0 +1,73 @@
/*
* $Id$
*
* Evoke, head honcho of everything
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2000-2007 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
*/
#include "Log.h"
#include <edelib/Debug.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
RealLog::RealLog() : f(NULL), buff(NULL), tbuff(NULL), bufflen(256), tbufflen(20),
to_stdout(false), to_stderr(false) {
}
RealLog::~RealLog() {
if(f) {
puts("RealLog::~RealLog()\n");
fclose(f);
}
if(buff)
delete [] buff;
if(tbuff)
delete [] tbuff;
}
bool RealLog::open(const char* file) {
EASSERT(file != NULL);
if(strcmp(file, "stdout") == 0)
to_stdout = true;
else if(strcmp(file, "stderr") == 0)
to_stderr = true;
else {
f = fopen(file, "a");
if(!f)
return false;
}
buff = new char[bufflen];
tbuff = new char[tbufflen];
return true;
}
void RealLog::printf(const char* fmt, ...) {
EASSERT(buff != NULL);
EASSERT(tbuff != NULL);
va_list ap;
va_start(ap, fmt);
vsnprintf(buff, bufflen, fmt, ap);
va_end(ap);
time_t t = time(NULL);
strftime(tbuff, tbufflen, "%F %T", localtime(&t));
if(to_stdout)
fprintf(stdout, "[%s] %s", tbuff, buff);
else if(to_stderr)
fprintf(stderr, "[%s] %s", tbuff, buff);
else {
fprintf(f, "[%s] %s", tbuff, buff);
fflush(f);
}
}

51
evoke/Log.h Normal file
View File

@ -0,0 +1,51 @@
/*
* $Id$
*
* Evoke, head honcho of everything
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2000-2007 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
*/
#ifndef __LOG_H__
#define __LOG_H__
#include <stdio.h>
class Log {
public:
Log() { }
virtual ~Log() { }
virtual bool open(const char* file) = 0;
virtual void printf(const char* fmt, ...) = 0;
};
class DummyLog : public Log {
public:
DummyLog() { }
virtual ~DummyLog() { }
virtual bool open(const char* file) { return true; }
virtual void printf(const char* fmt, ...) { }
};
class RealLog : public Log {
private:
FILE* f;
char* buff;
char* tbuff;
int bufflen;
int tbufflen;
bool to_stdout;
bool to_stderr;
public:
RealLog();
virtual ~RealLog();
virtual bool open(const char* file);
virtual void printf(const char* fmt, ...);
};
#endif

29
evoke/evoke.conf Normal file
View File

@ -0,0 +1,29 @@
# evoke configuration sample
# main section
# must be present
[evoke]
Startup = edewm,eiconman,eworkpanel,xscreensaver
[edewm]
Icon = wm.png
Exec = edewm
Core = True
Message = Starting window manager
[eiconman]
Icon = desktop.png
Exec = eiconman
Core = True
Message = Starting desktop
[eworkpanel]
Icon = workpanel.png
Exec = eworkpanel
Core = True
Message = Starting workpanel
[xscreensaver]
Icon = xscreensaver.png
Exec = xscreensaver
Message = Starting screensaver

183
evoke/evoke.cpp Normal file
View File

@ -0,0 +1,183 @@
/*
* $Id$
*
* Evoke, head honcho of everything
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2000-2007 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
*/
#include "EvokeService.h"
#include <FL/Fl.h>
#include <FL/x.h>
#include <edelib/Config.h>
#include <edelib/Debug.h>
#include <edelib/File.h>
#include <string.h>
#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#define FOREVER 1e20
#define CONFIG_FILE "evoke.conf"
#define APPNAME "evoke"
#define DEFAULT_PID "/tmp/evoke.pid"
#define CHECK_ARGV(argv, pshort, plong) ((strcmp(argv, pshort) == 0) || (strcmp(argv, plong) == 0))
bool running = false;
void quit_signal(int sig) {
EVOKE_LOG("Got quit signal %i\n", sig);
running = false;
}
int xmessage_handler(int e) {
return EvokeService::instance()->handle(e);
}
const char* next_param(int curr, char** argv, int argc) {
int j = curr + 1;
if(j >= argc)
return NULL;
if(argv[j][0] == '-')
return NULL;
return argv[j];
}
void help(void) {
puts("Usage: "APPNAME" [OPTIONS]");
puts("EDE startup manager responsible for starting, quitting and tracking");
puts("various pieces of desktop environment and external programs.");
puts("...and to popup a nice window when something crashes...\n");
puts("Options:");
puts(" -h, --help this help");
puts(" -s, --startup run in starup mode");
puts(" -f, --foreground run in foreground");
puts(" -c, --config [FILE] use FILE as config file");
puts(" -p, --pid [FILE] use FILE to store PID number");
puts(" -l, --log [FILE] log traffic to FILE\n");
}
int main(int argc, char** argv) {
const char* config_file = NULL;
const char* pid_file = NULL;
const char* log_file = NULL;
bool do_startup = false;
bool do_foreground = false;
if(argc > 1) {
const char* a;
for(int i = 1; i < argc; i++) {
a = argv[i];
if(CHECK_ARGV(a, "-h", "--help")) {
help();
return 0;
} else if(CHECK_ARGV(a, "-c", "--config")) {
config_file = next_param(i, argv, argc);
if(!config_file) {
puts("Missing configuration filename");
return 1;
}
i++;
} else if(CHECK_ARGV(a, "-p", "--pid")) {
pid_file = next_param(i, argv, argc);
if(!pid_file) {
puts("Missing pid filename");
return 1;
}
i++;
} else if(CHECK_ARGV(a, "-l", "--log")) {
log_file = next_param(i, argv, argc);
if(!log_file) {
puts("Missing log filename");
return 1;
}
i++;
}
else if(CHECK_ARGV(a, "-s", "--startup"))
do_startup = true;
else if(CHECK_ARGV(a, "-f", "--foreground"))
do_foreground = true;
else {
printf("Unknown parameter '%s'. Run '"APPNAME" -h' for options\n", a);
return 1;
}
}
}
// make sure X11 is running before fork
fl_open_display();
// start service
if(!do_foreground) {
int x;
if((x = fork()) > 0)
exit(0);
else if(x == -1) {
printf("Fatal: fork failed !\n");
return 1;
}
}
EvokeService* service = EvokeService::instance();
if(!service->setup_logging(log_file)) {
printf("Can't open %s for logging. Please choose some writeable place\n", log_file);
return 1;
}
EVOKE_LOG("= "APPNAME" started =\n");
if(!pid_file)
pid_file = DEFAULT_PID;
if(!service->setup_pid(pid_file)) {
EVOKE_LOG("Either another "APPNAME" instance is running or can't create pid file. Please correct this\n");
EVOKE_LOG("= "APPNAME" abrupted shutdown =\n");
return 1;
}
if(!config_file)
config_file = CONFIG_FILE; // TODO: XDG paths
if(!service->setup_config(config_file, do_startup)) {
EVOKE_LOG("Unable to read correctly %s. Please check it is correct config file\n");
EVOKE_LOG("= "APPNAME" abrupted shutdown =\n");
return 1;
}
service->setup_atoms(fl_display);
signal(SIGINT, quit_signal);
signal(SIGTERM, quit_signal);
signal(SIGKILL, quit_signal);
running = true;
XSelectInput(fl_display, RootWindow(fl_display, fl_screen), PropertyChangeMask | StructureNotifyMask | ClientMessage);
/*
* Register event listener and run in infinite loop. Loop will be
* interrupted from one of the received signals.
*
* I choose to use fltk for this since wait() will nicely pool events
* and pass expecting ones to xmessage_handler(). Other (non-fltk) solution would
* be to manually pool events via select() and that code could be very messy.
* So stick with the simplicity :)
*/
Fl::add_handler(xmessage_handler);
while(running)
Fl::wait(FOREVER);
EVOKE_LOG("= "APPNAME" nice shutdown =\n");
return 0;
}

BIN
evoke/splash-alpha1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

27
evoke/splash.fl Normal file
View File

@ -0,0 +1,27 @@
# data file for the Fltk User Interface Designer (fluid)
version 1.0108
header_name {.h}
code_name {.cxx}
Function {} {open selected
} {
Fl_Window {} {open
xywh {365 175 480 364} type Double visible
} {
Fl_Box {} {
image {splash-alpha1.png} xywh {0 0 480 364} labelsize 14
}
Fl_Box {} {
label {Starting window manager...}
xywh {20 322 440 23} labelsize 14 align 16
}
Fl_Box {} {
image {../../../../.icons/edeneu/32x32/actions/address-book-new.png} xywh {135 259 60 53} labelsize 14
}
Fl_Box {} {
image {../../../../.icons/edeneu/32x32/actions/appointment-new.png} xywh {200 259 60 53} labelsize 14
}
Fl_Box {} {
image {../../../../.icons/edeneu/32x32/apps/evolution.png} xywh {265 259 60 53} labelsize 14
}
}
}