commit a65525ad47984fc98be4f75440755f028a352bc5
parent 4589d703f7b34e0cfe226628c05a86d4741e267c
Author: Dominik Schmidt <das1993@hotmail.com>
Date: Thu, 11 Sep 2014 16:39:05 +0200
Switched to advanced GUI handling.
It is still incomplete and most likely unstable.
Diffstat:
46 files changed, 1646 insertions(+), 590 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
@@ -18,43 +18,48 @@ macro(absolute_libs dest libs)
endforeach(lib)
endmacro(absolute_libs)
-macro(include_pkgconfig)
-include(/mnt/Share/Programme/SelfBuilt/C/EGong/utils/CMakeModules/FindPkgConfig.cmake)
-endmacro(include_pkgconfig)
-
macro(EGong_link_libs libs)
set(EGONG_EXT_LIBS "${EGONG_EXT_LIBS}${libs};")
endmacro(EGong_link_libs)
-project(EGong)
+project(EGong C)
set(EGong_VERSION_MAJOR 0)
set(EGong_VERSION_MINOR 1)
set(EGONG_SRCDIR src/)
-set(EGONG_LIBS Interfaces/CMD Util/Command Interfaces Interfaces/STDIO CNC Util/Config Util/Socket Packet Util/Waiter Util/Log Util/Misc Util/Hash)
+set(EGONG_DATADIR data/)
set(EGONG_EXT_LIBS)
include_directories("${PROJECT_SOURCE_DIR}/include")
configure_file(
"${PROJECT_SOURCE_DIR}/include/Util/Config_Compiletime.h.in"
"${PROJECT_SOURCE_DIR}/include/Util/Config_Compiletime.h"
)
-add_definitions(-std=gnu99)
+set(CMAKE_CFLAGS, ${CMAKE_CFLAGS} -std=gnu99)
if(CMAKE_FIND_ROOT_PATH)
link_directories(${CMAKE_FIND_ROOT_PATH}/usr/lib)
endif(CMAKE_FIND_ROOT_PATH)
option(USE_GTK "Compile an interface for GTK" OFF)
+option(USE_LIBNOTIFY "Compile an interface for linux libnotify" OFF)
option(USE_AO "Compile an interface for Audio" OFF)
option(USE_WINGUI "Compile an interface for the Windows GUI-Shell" OFF)
-add_executable(EGong src/EGong.c)
-
if(USE_GTK)
find_package(GTK2)
if(GTK2_FOUND)
- set(EGONG_LIBS ${EGONG_LIBS} Interfaces/GTK Interfaces/GTK/Message Interfaces/GTK/TrayIcon Interfaces/GTK/NewMessage)
include_directories(${GTK2_INCLUDE_DIRS})
EGong_link_libs("${GTK2_LIBRARIES}")
- Message("${GTK2_LIBRARIES} vs ${EGONG_EXT_LIBS}")
+ if(USE_LIBNOTIFY)
+ find_package(PkgConfig)
+ if(PKGCONFIG_FOUND)
+ pkg_check_modules(LIBNOTIFY libnotify)
+ if(LIBNOTIFY_FOUND)
+ include_directories(${LIBNOTIFY_INCLUDE_DIRS})
+ EGong_link_libs("${LIBNOTIFY_LIBRARIES}")
+ else(NOT LIBNOTIFY_FOUND)
+ set(USE_LIBNOTIFY OFF)
+ endif(LIBNOTIFY_FOUND)
+ endif(PKGCONFIG_FOUND)
+ endif(USE_LIBNOTIFY)
else(NOT GTK2_FOUND)
set(USE_GTK OFF)
endif(GTK2_FOUND)
@@ -65,7 +70,6 @@ if(USE_AO)
if(PKGCONFIG_FOUND)
pkg_check_modules(LIBAO ao)
if(LIBAO_FOUND)
- set(EGONG_LIBS ${EGONG_LIBS} Interfaces/Audio)
include_directories(${LIBAO_INCLUDE_DIRS})
EGong_link_libs("${LIBAO_LIBRARIES} m")
else(NOT LIBAO_FOUND)
@@ -75,15 +79,51 @@ if(USE_AO)
endif(USE_AO)
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
+ ENABLE_LANGUAGE(RC)
EGong_link_libs("ws2_32")
if(USE_WINGUI)
- set(EGONG_LIBS ${EGONG_LIBS} Interfaces/Windows)
- EGong_link_libs("gdi32 wldap32")
+ set(WIN32_EXECUTABLE ON)
+ EGong_link_libs("gdi32")
+# SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -mwindows")
endif(USE_WINGUI)
endif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
-
-
+add_executable(EGong src/EGong.c src/Interfaces/Windows.rc)
+macro(addlibs libs)
+ set(EGONG_LIBS "${EGONG_LIBS}" "${libs}")
+endmacro(addlibs)
+set(EGONG_LIBS ${EGONG_LIBS}
+ Main
+ Util/Waiter
+ Interfaces
+ Interfaces/STDIO
+ Interfaces/CMD)
+if(USE_WINGUI)
+set(EGONG_LIBS ${EGONG_LIBS}
+ Interfaces/GUI
+ Interfaces/Windows
+)
+endif()
+if(USE_GTK)
+set(EGONG_LIBS ${EGONG_LIBS}
+ Interfaces/GUI
+ Interfaces/GTK
+)
+endif()
+set(EGONG_LIBS ${EGONG_LIBS}
+ CNC
+ Packet
+ Util/Misc
+ Util/Dependencies
+ Util/Command
+ Util/Socket
+ Util/Hash
+ Util/Array
+ Util/SAlloc
+ Util/Config
+ Util/Log
+)
+message(${EGONG_LIBS})
foreach(lib ${EGONG_LIBS})
addlib(${lib})
endforeach(lib)
@@ -92,7 +132,9 @@ target_link_libraries(EGong ${EGONG_EXT_LIBS})
#INSTALL
install(TARGETS EGong DESTINATION bin)
-
+if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows")
+ install(FILES ${EGONG_DATADIR}/EGong.ico DESTINATION share)
+endif()
#PACKING
absolute_libs(ABS_LIBS "${OPENSSL_LIBRARIES};${LIBAO_LIBRARIES}")
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS ${ABS_LIBS})
diff --git a/data/EGong.blend b/data/EGong.blend
Binary files differ.
diff --git a/data/EGong.ico b/data/EGong.ico
Binary files differ.
diff --git a/data/EGong.png b/data/EGong.png
Binary files differ.
diff --git a/include/CNC.h b/include/CNC.h
@@ -1,18 +1,8 @@
#pragma once
-
-
-extern int EGong_cnc_init(unsigned int requirements);
-extern int EGong_cnc_sendmessage(const char *msg, const char *dest);
-extern int EGong_cnc_getmessage(char **msg);
-extern void EGong_cnc_freemessage(char *msg);
+#include <EGong/Util/Misc.h>
+extern int EGong_cnc_sendmessage(const String *msg, const char *dest);
+extern int EGong_cnc_getmessage(String *msg);
+extern void EGong_cnc_freemessage(String *msg);
extern void EGong_cnc_deinit(void);
-extern int EGong_cnc_sendmessage_broad(const char *msg);
+extern int EGong_cnc_sendmessage_broad(const String *msg);
-enum EGONG_INTERFACE_REQUIREMENTS{
- EGONG_REQUIREMENT_NONE=(0),
- EGONG_REQUIREMENT_LISTENER=(1<<0),
- EGONG_REQUIREMENT_SOCKETS=(1<<1),
- EGONG_REQUIREMENT_TERMINAL=(1<<2),
- EGONG_REQUIREMENT_GTK=(1<<3),
- EGONG_REQUIREMENT_ALL=(~0)
-};
diff --git a/include/Interfaces.h b/include/Interfaces.h
@@ -1,33 +1,63 @@
#pragma once
#include <EGong/CNC.h>
+#include <EGong/Util/Misc.h>
enum EGONG_INTERFACE_STATE{
EGONG_INTERFACE_ACTIVE=(1<<0),
EGONG_INTERFACE_SETUP=(1<<1)
};
-
+struct EGong_interface;
+struct EGong_if_ptrtbl{
+ int (*setup) (struct EGong_interface *interface);
+ int (*cmd) (char *msg);
+ int (*cycle) (struct EGong_interface *interface, String *msg, char **dest);
+ int (*display) (struct EGong_interface *interface, const String *msg);
+ int (*shutdown) (struct EGong_interface *interface);
+
+ int(*sock_watch)(int socket, unsigned short int type);
+ int(*loop)(void);
+};
struct EGong_interface{
char *name;
char identifier;
unsigned int requirements;
unsigned short int state;
- int(*setup)(struct EGong_interface *interface);
- int(*shutdown)(struct EGong_interface *interface);
- int(*display_message)(struct EGong_interface *interface, const char *msg);
- int(*cycle)(struct EGong_interface *interface, char **msg, char **dest);
+ struct EGong_if_ptrtbl *funcs;
};
extern unsigned short int EGong_interfaces_userstreams;
extern int EGong_interface_init(unsigned int requirement_mask);
extern int EGong_interface_cycle(void);
-extern void EGong_interface_deinit(void);
+extern int EGong_interface_deinit(void);
extern struct EGong_interface EGong_interfaces[];
extern int EGong_interface_setup(struct EGong_interface *interface);
extern int EGong_interface_activate(struct EGong_interface *interface);
extern int EGong_interface_shutdown(struct EGong_interface *interface);
extern int EGong_interface_deactivate(struct EGong_interface *interface);
extern struct EGong_interface *EGong_interface_get_from_id(char identifier);
-
+#define IF_ACTIVE(INTERFACE) (((INTERFACE).state&EGONG_INTERFACE_ACTIVE)>0)
+#define IF_SETUP(INTERFACE) (((INTERFACE).state&EGONG_INTERFACE_SETUP)>0)
+#define IF_CAN_SHUTDOWN(INTERFACE) ((INTERFACE).funcs->shutdown!=NULL)
+#define IF_CAN_CYCLE(INTERFACE) ((INTERFACE).funcs->cycle!=NULL)
+#define IF_CAN_DISPLAY(INTERFACE) ((INTERFACE).funcs->display!=NULL)
+#define IF_CAN_SETUP(INTERFACE) ((INTERFACE).funcs->setup!=NULL)
+#define IF_TRY_SETUP(INTERFACE) ((IF_SETUP(INTERFACE)&&IF_CAN_SETUP(INTERFACE)) ? (INTERFACE).funcs->setup(&INTERFACE) : EGONG_INTERFACE_RETURN_OK)
+#define EGONG_INTERFACE_INTERPRET_RET(RET, INTERFACE)\
+if(RET==EGONG_INTERFACE_RETURN_FATAL){\
+ do_log("Couldn't run interface function, exiting", LOG_TYPE_NORMAL, LOG_LEVEL_FATAL);\
+ return -1;\
+}\
+else if(RET==EGONG_INTERFACE_RETURN_ERROR){\
+ do_log("Couldn't run interface function, skipping", LOG_TYPE_NORMAL, LOG_LEVEL_WARNING);\
+}\
+else if(RET==EGONG_INTERFACE_RETURN_EXIT){\
+ do_log_call_composite(LOG_COMPOSE_SRC, LOG_TYPE_NORMAL, LOG_LEVEL_INFO, EGong_global_configuration.log.destinations, "Interface ", (INTERFACE).name, " requested exit", NULL);\
+ return 1;\
+}\
+else if(RET==EGONG_INTERFACE_RETURN_BREAK){\
+ do_log("Interface function requested queueabortion", LOG_TYPE_NORMAL, LOG_LEVEL_INFO);\
+ break;\
+}
enum EGONG_INTERFACE_RETURN{
EGONG_INTERFACE_RETURN_FATAL=-2,
EGONG_INTERFACE_RETURN_ERROR=-1,
diff --git a/include/Interfaces/Audio.h b/include/Interfaces/Audio.h
@@ -2,5 +2,5 @@
int EGong_if_audio_setup(struct EGong_interface *interface);
-int EGong_if_audio_display(struct EGong_interface *interface, const char *msg);
+int EGong_if_audio_display(struct EGong_interface *interface, const String *msg);
int EGong_if_audio_shutdown(struct EGong_interface *interface);
diff --git a/include/Interfaces/CMD.h b/include/Interfaces/CMD.h
@@ -16,12 +16,11 @@ struct EGong_command_if_cmd{
extern int EGong_if_cmd_interfaceselect(const char *data);
extern struct EGong_command_if_cmd *EGong_if_cmd_get_from_char(const char *commandline);
-extern int EGong_if_cmd_exec(unsigned int execution, struct EGong_interface *interface, char **msg, char **dest);
+extern int EGong_if_cmd_exec(unsigned int execution, struct EGong_interface *interface, String *msg, char **dest);
extern int EGong_if_cmd_setup(struct EGong_interface *interface);
-extern int EGong_if_cmd_cycle(struct EGong_interface *interface, char **msg, char **dest);
+extern int EGong_if_cmd_cycle(struct EGong_interface *interface, String *msg, char **dest);
extern int EGong_if_cmd_shutdown(struct EGong_interface *interface);
-extern int EGong_if_cmd_gtk_msg(void);
-extern int EGong_if_cmd_windows_msg(void);
+extern int EGong_if_cmd_gui_msg(void);
extern int EGong_if_cmd_send_message(char *msg);
extern int EGong_if_cmd_help(void);
diff --git a/include/Interfaces/GTK.h b/include/Interfaces/GTK.h
@@ -1,15 +1,23 @@
#pragma once
#include <EGong/Interfaces.h>
+#include <EGong/Interfaces/GUI.h>
#include <gtk/gtk.h>
extern GtkWidget *Egong_if_gtk_root;
-int EGong_if_gtk_int_setup(unsigned int what);
-
-int EGong_if_gtk_setup(struct EGong_interface *interface);
-int EGong_if_gtk_cycle(struct EGong_interface *interface, char **msg, char **dest);
-int EGong_if_gtk_display(struct EGong_interface *interface, const char *msg);
-int EGong_if_gtk_shutdown(struct EGong_interface *interface);
+extern int EGong_if_gtk_int_setup(unsigned int what);
+
+extern int EGong_if_gtk_setup(struct EGong_interface *interface);
+extern int EGong_if_gtk_cycle(struct EGong_interface *interface, String *msg, char **dest);
+extern int EGong_if_gtk_display(struct EGong_interface *interface, const String *msg);
+extern int EGong_if_gtk_shutdown(struct EGong_interface *interface);
+extern GtkWidget *EGong_if_gtk_create_gui(struct EGong_GUI_item *parent, struct EGong_GUI_item *this);
+extern void *EGong_gtk_get_item_value(struct EGong_GUI_item *itm);
+extern int EGong_gtk_waiter_add(int sock, unsigned short int type);
+extern void EGong_if_gtk_show_element(struct EGong_GUI_item *itm);
+extern void EGong_if_gtk_free_item_value(struct EGong_GUI_item *itm, void *element);
+extern int EGong_if_gtk_main(void);
+extern struct EGong_if_ptrtbl EGong_if_gtk_ptrtbl;
enum EGONG_IF_GTK_INIT{
EGONG_IF_GTK_INIT_ROOT=(1<<0),
EGONG_IF_GTK_INIT_TRAY=(1<<1),
diff --git a/include/Interfaces/GTK/Message.h b/include/Interfaces/GTK/Message.h
@@ -1,2 +0,0 @@
-#pragma once
-extern void EGong_if_gtk_msg_display(const char *msg);
diff --git a/include/Interfaces/GTK/NewMessage.h b/include/Interfaces/GTK/NewMessage.h
@@ -1,8 +0,0 @@
-#pragma once
-#include <gtk/gtk.h>
-extern GtkWidget *EGong_if_gtk_newmsg_dialog;
-extern void EGong_if_gtk_newmsg_send_callback(GtkDialog *caller, guint button, gpointer data);
-
-extern void EGong_if_gtk_newmsg_display_construct(unsigned short int single);
-extern void EGong_if_gtk_newmsg_display_single(void);
-extern void EGong_if_gtk_newmsg_display(void);
diff --git a/include/Interfaces/GTK/TrayIcon.h b/include/Interfaces/GTK/TrayIcon.h
@@ -1,13 +0,0 @@
-#pragma once
-
-#include <gtk/gtk.h>
-extern GtkStatusIcon *EGong_if_gtk_tray_root;
-extern GtkWidget *EGong_if_gtk_tray_menu;
-extern void EGong_if_gtk_tray_popup(GtkStatusIcon *icon, guint button, guint activation_time, gpointer data);
-extern int EGong_if_gtk_tray_setup();
-
-struct EGong_if_gtk_tray_menu_call{
- char *name;
- char *tooltip;
- char *message;
-};
diff --git a/include/Interfaces/GUI.h b/include/Interfaces/GUI.h
@@ -0,0 +1,111 @@
+#pragma once
+
+#include <EGong/Util/Command.h>
+#include <EGong/Util/Config_Compiletime.h>
+#include <EGong/Interfaces.h>
+
+#ifdef USE_WINGUI
+typedef wchar_t guichar;
+#define GUIT(TEXT) L##TEXT
+#else
+typedef char guichar;
+#define GUIT(TEXT) TEXT
+#endif
+
+enum EGONG_GUI_TYPE{
+ EGONG_GUI_TYPE_NONE,
+ EGONG_GUI_TYPE_GTK,
+ EGONG_GUI_TYPE_WINGUI,
+};
+enum EGONG_GUI_EVSRC{
+ EGONG_GUI_EVSRC_ELEMENT,
+ EGONG_GUI_EVSRC_STATIC,
+};
+enum EGONG_GUI_MENUITEM_IMAGES{
+ EGUI_MIMG_EXIT,
+};
+enum EGONG_GUI_ITEM{
+ EGONG_GUI_WINDOW,
+ EGONG_GUI_BUTTON,
+ EGONG_GUI_LABEL,
+ EGONG_GUI_TEXT,
+ EGONG_GUI_MENU,
+ EGONG_GUI_MENUITEM,
+ EGONG_GUI_MENUITEM_IMAGE,
+ EGONG_GUI_MENUITEM_SEPARATOR,
+ EGONG_GUI_SYSTRAY,
+ EGONG_GUI_HBOX,
+ EGONG_GUI_VBOX,
+ EGONG_GUI_DIALOG,
+};
+struct EGong_GUI_item{
+ unsigned short int type;
+ guichar *text;
+ guichar *tooltip;
+ void *extra;
+ void *itemptr;
+ void *userdata;
+ struct EGong_GUI_item **child;
+ struct EGong_GUI_event **events;
+};
+
+struct EGong_GUI_event_source{
+ unsigned int type;
+ void *data;
+};
+struct EGong_GUI_event{
+ guichar *type;
+ struct EGong_command command;
+ struct EGong_GUI_event_source **sources;
+};
+extern void EGong_GUI_event_hide(void *gui_element);
+extern void *EGong_GUI_create(struct EGong_GUI_item *gui);
+extern void EGong_GUI_event_callback(struct EGong_GUI_event *event);
+extern int EGong_GUI_exit(void);
+
+#ifdef USE_GTK
+static const unsigned int EGong_GUI_type=EGONG_GUI_TYPE_GTK;
+#else
+#ifdef USE_WINGUI
+static const unsigned int EGong_GUI_type=EGONG_GUI_TYPE_WINGUI;
+#else
+static const unsigned int EGong_GUI_type=EGONG_GUI_TYPE_NONE;
+#endif
+#endif
+
+#define EGUI_ARR (struct EGong_GUI_item **)&(struct EGong_GUI_item *[])
+#define EGUI_EL &(struct EGong_GUI_item)
+#define EGUI_ELX(ELEMENT) (struct EGong_GUI_item*)&ELEMENT
+#define EGUI_FIN (struct EGong_GUI_item*)NULL
+
+#define EEV_ARR (struct EGong_GUI_event **)&(struct EGong_GUI_event *[])
+#define EEV_EL &(struct EGong_GUI_event)
+#define EEV_ELX(ELEMENT) (struct EGong_GUI_event*)&ELEMENT
+#define EEV_FIN (struct EGong_GUI_event*)NULL
+
+#define EES_ARR (struct EGong_GUI_event_source **)&(struct EGong_GUI_event_source *[])
+#define EES_EL &(struct EGong_GUI_event_source)
+#define EES_ELX(ELEMENT) (struct EGong_GUI_event_source*)&ELEMENT
+#define EES_FIN (struct EGong_GUI_event_source*)NULL
+
+struct EGong_if_gui_ptrtbl{
+ struct EGong_if_ptrtbl *ifptrtbl;
+ void *(*create)(struct EGong_GUI_item *parent, struct EGong_GUI_item *this);
+ void *(*get_value)(struct EGong_GUI_item *itm);
+ void (*free_value)(struct EGong_GUI_item *itm, void *value);
+ void (*show)(struct EGong_GUI_item *itm);
+};
+
+extern int EGong_if_gui_setup(struct EGong_interface *interface);
+extern int EGong_if_gui_cmd(char *msg);
+extern int EGong_if_gui_cycle(struct EGong_interface *interface, String *msg, char **dest);
+extern int EGong_if_gui_display(struct EGong_interface *interface, const String *msg);
+extern int EGong_if_gui_shutdown(struct EGong_interface *interface);
+extern int EGong_if_gui_sockwatch(int sock, unsigned short int type);
+extern int EGong_if_gui_loop(void);
+
+
+extern char *EGong_GUI_item_names[];
+
+extern struct EGong_GUI_item EGong_GUI_newmessage;
+extern struct EGong_GUI_item EGong_GUI_systray;
diff --git a/include/Interfaces/STDIO.h b/include/Interfaces/STDIO.h
@@ -3,5 +3,5 @@
extern int EGong_if_stdio_setup(struct EGong_interface *interface);
-extern int EGong_if_stdio_cycle(struct EGong_interface *interface, char **msg, char **dest);
-extern int EGong_if_stdio_display(struct EGong_interface *interface, const char *msg);
+extern int EGong_if_stdio_cycle(struct EGong_interface *interface, String *msg, char **dest);
+extern int EGong_if_stdio_display(struct EGong_interface *interface, const String *msg);
diff --git a/include/Interfaces/Windows.h b/include/Interfaces/Windows.h
@@ -1,8 +1,35 @@
#pragma once
+#define UNICODE
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <EGong/Interfaces.h>
+#include <EGong/Interfaces/GUI.h>
+#include <EGong/Util/Misc.h>
+#define WM_TRAY_ACTION WM_USER+1
+#define WM_SOCKET WM_USER+2
+extern struct EGong_if_ptrtbl EGong_if_win_ptrtbl;
+extern WNDCLASSW EGong_if_win_getmsg;
+extern HWND EGong_if_win_getmsg_editfield;
+extern struct EGong_GUI_item *EGong_if_win_global_systray;
+extern struct Array EGong_if_win_menus;
+extern struct Array EGong_if_win_windows;
+extern HWND EGong_if_win_create_wrapper(struct EGong_GUI_item *parent, struct EGong_GUI_item *this);
+extern HWND EGong_if_win_create(struct EGong_GUI_item *parent, struct EGong_GUI_item *this, unsigned int child);
+extern void EGong_if_win_show_element(struct EGong_GUI_item *itm);
+extern void EGong_if_win_show_item(HWND item);
+extern void EGong_if_win_free_item_value(struct EGong_GUI_item *item, void *value);
+extern void *EGong_if_win_get_item_value(struct EGong_GUI_item *item);
+extern void EGong_if_win_trayhandler(struct EGong_GUI_item *item, unsigned short int type, int x, int y, HWND hwnd);
+extern void EGong_if_win_actionhandler(struct EGong_GUI_item *item);
extern int EGong_if_win_setup(struct EGong_interface *interface);
-extern int EGong_if_win_cycle(struct EGong_interface *interface, char **msg, char **dest);
-extern int EGong_if_win_display(struct EGong_interface *interface, const char *msg);
-
-extern int EGong_if_win_getmsgdialog();
+extern int EGong_if_win_cmd(char *msg);
+extern int EGong_if_win_cycle(struct EGong_interface *interface, String *msg, char **dest);
+extern int EGong_if_win_display(struct EGong_interface *interface, const String *msg);
+extern void EGong_if_win_destroy(struct EGong_GUI_item *item);
+extern int EGong_if_win_waiter_add(int sock, unsigned short int type);
+extern void EGong_if_win_destroy_wrapper(struct EGong_GUI_item **item);
+extern int EGong_if_win_shutdown(struct EGong_interface *interface);
+extern int EGong_if_win_loop(void);
+extern HINSTANCE EGong_if_win_instance;
diff --git a/include/Main.h b/include/Main.h
@@ -0,0 +1,8 @@
+#pragma once
+extern int(*Egong_main_loop_ptr)(void);
+extern int EGong_main_do(void);
+extern int EGong_main_init(void);
+extern int EGong_main_loop_default(void);
+extern void EGong_main_deinit(void);
+
+extern int EGong_main_loop();
diff --git a/include/Packet.h b/include/Packet.h
@@ -3,6 +3,7 @@
#include <stddef.h>
#include <EGong/Util/Hash.h>
#include <EGong/Util/Socket.h>
+#include <EGong/Util/Misc.h>
#define EGONG_PACKET_RAND_LENGTH 10
@@ -23,7 +24,7 @@ struct EGong_packet{
extern int EGong_calculate_package_hash(struct EGong_packet *packet, unsigned char *dest, char *cookie);
-extern int EGong_generate_packet(struct EGong_packet *packet, const char *msg, unsigned int msg_length);
+extern int EGong_generate_packet(struct EGong_packet *packet, const String *msg);
extern int EGong_send_packet(struct EGong_packet *packet, const char *dest);
extern void EGong_packet_free(struct EGong_packet *packet);
extern int EGong_packet_alloc(struct EGong_packet *packet, char **dest, unsigned int additional);
diff --git a/include/Util/Command.h b/include/Util/Command.h
@@ -8,16 +8,21 @@ struct EGong_command_type{
};
enum EGONG_COMMAND_TYPE{
+ EGONG_COMMAND_ARG0,
EGONG_COMMAND_UINT_INC,
EGONG_COMMAND_UINT_DEC,
- EGONG_COMMAND_UINT_SET,
- EGONG_COMMAND_STR_SET,
EGONG_COMMAND_BOOL_TRUE,
EGONG_COMMAND_BOOL_FALSE,
- EGONG_COMMAND_BOOL_SET,
EGONG_COMMAND_FUNC_VOID,
+ EGONG_COMMAND_ARG1,
+ EGONG_COMMAND_BOOL_SET,
+ EGONG_COMMAND_UINT_SET,
+ EGONG_COMMAND_STR_SET,
EGONG_COMMAND_FUNC_UINT,
EGONG_COMMAND_FUNC_CHAR,
+ EGONG_COMMAND_FUNC_STRING,
+ EGONG_COMMAND_FUNC_POINTER,
+ EGONG_COMMAND_ARG2,
EGONG_COMMAND_FUNC_2CHAR
};
enum EGONG_COMMAND_MATCH{
@@ -42,3 +47,4 @@ struct EGong_command_array{
extern struct EGong_command *EGong_command_match(struct EGong_command_array *commands, const char *data, unsigned int match_type);
extern int EGong_command_exec(struct EGong_command *command, void **data);
extern void EGong_command_print_help(struct EGong_command_array *commands, int destination, char *appendix);
+extern unsigned int EGong_command_argc(struct EGong_command *command);
diff --git a/include/Util/Config.h b/include/Util/Config.h
@@ -13,6 +13,9 @@ struct EGong_config_packet{
size_t packet_maxlen;
char *cookie;
};
+struct EGong_config_gui{
+ unsigned int destinations;
+};
struct EGong_config_server{
unsigned int port;
char *bind_ip;
@@ -21,6 +24,7 @@ struct EGong_config{
struct EGong_config_log log;
struct EGong_config_server server;
struct EGong_config_packet packet;
+ struct EGong_config_gui gui;
};
struct EGong_config_file_entry{
@@ -44,6 +48,12 @@ enum EGONG_CONFIG_FILE_TYPE{
EGONG_CONFIG_TYPE_BITMASK,
EGONG_CONFIG_TYPE_BOOL,
};
+enum EGONG_CONFIG_GUI_DEST{
+ EGONG_CONFIG_GUI_DEST_NONE=0,
+ EGONG_CONFIG_GUI_DEST_WINDOW=(1<<0),
+ EGONG_CONFIG_GUI_DEST_NOTIFY=(1<<1),
+ EGONG_CONFIG_GUI_DEST_ALL=~0,
+};
extern struct EGong_config_file_entry EGong_configuration_file_interface[EGONG_CONFIG_FILE_ENTRYCOUNT];
extern struct EGong_config EGong_global_configuration;
diff --git a/include/Util/Config_Compiletime.h b/include/Util/Config_Compiletime.h
@@ -1,4 +0,0 @@
-/* #undef USE_GTK */
-/* #undef USE_AO */
-/* #undef USE_WINGUI */
-
diff --git a/include/Util/Config_Compiletime.h.in b/include/Util/Config_Compiletime.h.in
@@ -1,4 +1,7 @@
+#pragma once
#cmakedefine USE_GTK
+#cmakedefine USE_LIBNOTIFY
#cmakedefine USE_AO
#cmakedefine USE_WINGUI
+#define EGONG_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@"
diff --git a/include/Util/Dependencies.h b/include/Util/Dependencies.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#define DEP_REQ(NAME, DEPS) ((NAME&(DEPS)&~EGong_dep_status)>0)
+#define DEP_STOP(NAME, DEPS) ((NAME&(DEPS)&EGong_dep_status)>0)
+#define DEP_AVAIL(DEPS) ((EGong_dep_status&DEPS)>0)
+
+enum EGONG_DEPENDENCIES{
+ EGONG_DEP_NONE=(0),
+ EGONG_DEP_LISTENER=(1<<0),
+ EGONG_DEP_SOCKETS=(1<<1),
+ EGONG_DEP_ALL=(~0)
+};
+
+extern int EGong_deps_init(unsigned int dependencies);
+extern int EGong_deps_deinit(unsigned int dependencies);
+
+extern unsigned int EGong_dep_status;
diff --git a/include/Util/Misc.h b/include/Util/Misc.h
@@ -18,3 +18,11 @@ struct EGong_static_array{
ssize_t element_count;
ssize_t element_size;
};
+
+struct String{
+ char *data;
+ size_t length;
+};
+typedef struct String String;
+#define STRING_STATIC(STRING, VALUE) STRING.data=VALUE; STRING.length=sizeof(VALUE);
+#define STRING_STATIC_INIT(VALUE){.data=VALUE, .length=sizeof(VALUE)}
diff --git a/include/Util/Socket.h b/include/Util/Socket.h
@@ -3,7 +3,7 @@
#include <EGong/Util/Config.h>
#ifdef _WIN32
#include <winsock2.h>
- #define MSG_DONTWAIT 0
+ #define MSG_DONTWAIT (1<<5)
typedef short sa_family_t;
#else
#include <sys/socket.h>
diff --git a/include/Util/Waiter.h b/include/Util/Waiter.h
@@ -2,10 +2,10 @@
extern unsigned int EGong_waiter_highest_fd;
extern int EGong_waiter_init(void);
-extern int EGong_waiter_add(int sock, unsigned short int type);
+extern int EGong_waiter_add_default(int sock, unsigned short int type);
extern int EGong_waiter_del(int sock);
extern int EGong_waiter_wait(void);
-
+extern int(*EGong_waiter_add)(int, unsigned short int);
enum EGONG_WAITER_TYPE{
EGONG_WAITER_FD,
diff --git a/src/CNC.c b/src/CNC.c
@@ -6,56 +6,20 @@
#include <EGong/Util/Waiter.h>
#include <string.h>
#include <unistd.h>
-#ifdef EGONG_USE_GTK
+#ifdef USE_GTK
#include <EGong/Interfaces/GTK.h>
#endif
-
-unsigned int EGong_cnc_running=0;
-
-int EGong_cnc_init(unsigned int requirements){
- if((requirements&(EGONG_REQUIREMENT_SOCKETS|EGONG_REQUIREMENT_LISTENER)&~EGong_cnc_running)>0){
- if(EGong_sockets_setup()<0){
- do_log("Couldn't initialize sockets", LOG_TYPE_NORMAL, LOG_LEVEL_FATAL);
- return -1;
- }
- else{
- EGong_cnc_running|=EGONG_REQUIREMENT_SOCKETS;
- }
- }
- if((requirements&EGONG_REQUIREMENT_LISTENER&~EGong_cnc_running)>0){
- if(EGong_listener_init(NULL,NULL)<0){
- do_log("Couldn't initialize listener", LOG_TYPE_NORMAL, LOG_LEVEL_FATAL);
- return -1;
- }
- else{
- EGong_waiter_add(EGong_listen_sock, EGONG_WAITER_SOCKET);
- EGong_cnc_running|=EGONG_REQUIREMENT_LISTENER;
- }
- }
- #ifdef EGONG_USE_GTK
- if((requirements&EGONG_REQUIREMENT_GTK&~EGong_cnc_running)>0){
- if(EGong_if_gtk_int_setup(EGONG_IF_GTK_INIT_ROOT)<0){
- do_log("Couldn't initialize GTK", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
- return -2;
- }
- else{
- EGong_cnc_running|=EGONG_REQUIREMENT_GTK;
- }
- }
- #endif
- return 0;
-}
-int EGong_cnc_sendmessage_broad(const char *msg){
+int EGong_cnc_sendmessage_broad(const String *msg){
return EGong_cnc_sendmessage(msg, NULL);
}
-int EGong_cnc_sendmessage(const char *msg, const char *dest){
+int EGong_cnc_sendmessage(const String *msg, const char *dest){
if(dest==NULL){
dest="255.255.255.255";
}
struct EGong_packet packet;
- EGong_generate_packet(&packet, msg, strlen(msg));
+ EGong_generate_packet(&packet, msg);
if(EGong_send_packet(&packet, dest)<0){
do_log("Couldn't send packet.", LOG_TYPE_NORMAL, LOG_LEVEL_WARNING);
}
@@ -65,14 +29,15 @@ int EGong_cnc_sendmessage(const char *msg, const char *dest){
return 0;
}
-int EGong_cnc_getmessage(char **msg){
+int EGong_cnc_getmessage(String *msg){
struct EGong_packet packet;
int ret=EGong_get_packet(NULL, &packet);
if(ret!=0){
return ret;
}
if(EGong_packet_verify(&packet, NULL)){
- *msg=packet.message.data;
+ msg->data=packet.message.data;
+ msg->length=packet.message.length;
}
else{
EGong_packet_free(&packet);
@@ -81,15 +46,9 @@ int EGong_cnc_getmessage(char **msg){
}
return ret;
}
-void EGong_cnc_freemessage(char *msg){
+void EGong_cnc_freemessage(String *msg){
struct EGong_packet virtpack;
- virtpack.message.data=msg;
+ virtpack.message.data=msg->data;
EGong_packet_free(&virtpack);
}
-void EGong_cnc_deinit(void){
- if((EGong_cnc_running&EGONG_REQUIREMENT_LISTENER)>0){
- EGong_listener_close(NULL);
- EGong_sockets_shutdown();
- }
-}
diff --git a/src/EGong.c b/src/EGong.c
@@ -1,32 +1,64 @@
-#include <EGong/Util/Log.h>
-#include <EGong/Util/Misc.h>
-#include <EGong/Util/Config.h>
-#include <EGong/Interfaces.h>
-#include <EGong/Util/Waiter.h>
-#include <EGong/CNC.h>
-#include <EGong/Packet.h>
+#include <EGong/Main.h>
+#include <EGong/Interfaces/CMD.h>
+#include <EGong/Interfaces/GUI.h>
+#include <EGong/Util/Config_Compiletime.h>
+#ifdef USE_WINGUI
+#define WIN32_LEAN_AND_MEAN
+#define UNICODE
+#include <windows.h>
+#include <wchar.h>
#include <stdlib.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <unistd.h>
-int main(int argc, char **argv){
+#include <EGong/Util/Array.h>
+#include <EGong/Util/Log.h>
+#include <EGong/Interfaces/Windows.h>
+int WINAPI WinMain(HINSTANCE instance, HINSTANCE prev_instance, LPSTR argv, int commands){
+ EGong_if_win_instance=instance;
- EGong_config_init(NULL);
+ do_log("Simulating argc and argv", LOG_TYPE_NORMAL, LOG_LEVEL_INFO);
+ LPTSTR cmdlineW=GetCommandLine();
+ size_t length=wcslen(cmdlineW)+1;
+ char *cmdline=calloc(length, sizeof(char));
+ memset(cmdline, '\0', length*sizeof(char));
+ wcstombs(cmdline, cmdlineW, length);
+ struct Array argva;
+ Array_init(&argva, sizeof(char *), 5);
+ unsigned int i=0;
+ unsigned short int blind=0;
+ char *charptr;
+ while(i<length){
+ charptr=&cmdline[i];
+ if(i==0||(*charptr==' '&&*(charptr-sizeof(char))!='\\'&&!blind)){
+ if(i>0){
+ *charptr='\0';
+ i++;
+ charptr=&cmdline[i];
+ }
+ Array_add(&argva, &charptr);
+ }
+ if((*charptr=='"'||*charptr=='\'')&&*(charptr-sizeof(char))!='\\'){
+ blind=!blind;
+ }
+ if(cmdline[i]=='\0'){
+ break;
+ }
+ i++;
+ }
+ EGong_global_argc=argva.element_count;
+ EGong_global_argv=argva.memory.data;
+#else
+int main(int argc, char **argv){
EGong_global_argc=argc;
EGong_global_argv=argv;
- if(EGong_waiter_init()<0){
- return -1;
+#endif
+ if(EGong_main_init()<0){
+ return 0;
}
-
- if(EGong_interface_init(0)<0){
- return -1;
- }
-
- while(EGong_interface_cycle()==0){
- EGong_waiter_wait();
- }
-
- EGong_cnc_deinit();
+ EGong_main_loop();
+ EGong_main_deinit();
+ #ifdef USE_WINGUI
+ Array_destroy(&argva);
+ free(cmdline);
+ #endif
return 0;
}
diff --git a/src/Interfaces.c b/src/Interfaces.c
@@ -1,6 +1,9 @@
#include <EGong/CNC.h>
+#include <EGong/Util/Dependencies.h>
#include <EGong/Interfaces/STDIO.h>
#include <EGong/Interfaces/CMD.h>
+#include <EGong/Util/Waiter.h>
+#include <EGong/Main.h>
#include <EGong/Util/Config.h>
#ifdef USE_GTK
#include <EGong/Interfaces/GTK.h>
@@ -11,6 +14,9 @@
#ifdef USE_WINGUI
#include <EGong/Interfaces/Windows.h>
#endif
+#if defined(USE_GTK) || defined(USE_WINGUI)
+ #include <EGong/Interfaces/GUI.h>
+#endif
#include <EGong/Util/Log.h>
#include <EGong/Util/Misc.h>
#include <stdlib.h>
@@ -19,57 +25,61 @@ struct EGong_interface EGong_interfaces[]={
{
.name="CMD",
.identifier='C',
- .requirements=EGONG_REQUIREMENT_NONE,
+ .requirements=EGONG_DEP_NONE,
.state=EGONG_INTERFACE_ACTIVE,
- .setup=&EGong_if_cmd_setup,
- .cycle=&EGong_if_cmd_cycle,
- .display_message=NULL,
- .shutdown=NULL
+ .funcs=&(struct EGong_if_ptrtbl){
+ .setup=&EGong_if_cmd_setup,
+ .cycle=&EGong_if_cmd_cycle,
+ .display=NULL,
+ .shutdown=NULL,
+ .sock_watch=NULL,
+ .loop=NULL,
+ }
},
+ #if defined(USE_GTK) || defined(USE_WINGUI)
{
- .name="STDIO",
- .identifier='S',
- .requirements=EGONG_REQUIREMENT_LISTENER|EGONG_REQUIREMENT_TERMINAL,
+ .name="GUI",
+ .identifier='G',
+ .requirements=EGONG_DEP_LISTENER,
.state=0,
- .setup=&EGong_if_stdio_setup,
- .cycle=&EGong_if_stdio_cycle,
- .display_message=&EGong_if_stdio_display,
- .shutdown=NULL
+ .funcs=&(struct EGong_if_ptrtbl){
+ .setup=&EGong_if_gui_setup,
+ .cycle=&EGong_if_gui_cycle,
+ .display=&EGong_if_gui_display,
+ .shutdown=&EGong_if_gui_shutdown,
+ .sock_watch=&EGong_if_gui_sockwatch,
+ .loop=&EGong_if_gui_loop,
+ }
},
- #ifdef USE_GTK
+ #endif
{
- .name="GTK",
- .identifier='G',
- .requirements=EGONG_REQUIREMENT_LISTENER|EGONG_REQUIREMENT_GTK,
+ .name="STDIO",
+ .identifier='S',
+ .requirements=EGONG_DEP_LISTENER,
.state=0,
- .setup=&EGong_if_gtk_setup,
- .cycle=&EGong_if_gtk_cycle,
- .display_message=&EGong_if_gtk_display,
- .shutdown=&EGong_if_gtk_shutdown
+ .funcs=&(struct EGong_if_ptrtbl){
+ .setup=&EGong_if_stdio_setup,
+ .cycle=&EGong_if_stdio_cycle,
+ .display=&EGong_if_stdio_display,
+ .shutdown=NULL,
+ .sock_watch=NULL,
+ .loop=NULL,
+ }
},
- #endif
#ifdef USE_AO
{
.name="Audio",
.identifier='A',
- .requirements=EGONG_REQUIREMENT_LISTENER,
- .state=0,
- .setup=&EGong_if_audio_setup,
- .cycle=NULL,
- .display_message=&EGong_if_audio_display,
- .shutdown=&EGong_if_audio_shutdown
- }
- #endif
- #ifdef USE_WINGUI
- {
- .name="WinGUI",
- .identifier='W',
- .requirements=EGONG_REQUIREMENT_LISTENER,
+ .requirements=EGONG_DEP_LISTENER,
.state=0,
- .setup=&EGong_if_win_setup,
- .cycle=NULL,
- .display_message=NULL,
- .shutdown=NULL
+ .funcs=&(struct EGong_if_ptrtbl){
+ .setup=&EGong_if_audio_setup,
+ .cycle=NULL,
+ .display=&EGong_if_audio_display,
+ .shutdown=&EGong_if_audio_shutdown
+ .sock_watch=NULL,
+ .loop=NULL,
+ }
}
#endif
};
@@ -80,40 +90,42 @@ unsigned int EGong_interfaces_requirement_mask=0;
unsigned short int EGong_interface_if_count_ustream(struct EGong_interface *interface){
unsigned short int streams=0;
- if(interface->display_message!=NULL){
+ if(interface->funcs->display!=NULL){
streams++;
}
- if(interface->cycle!=NULL){
+ if(interface->funcs->cycle!=NULL){
streams++;
}
return streams;
}
int EGong_interface_setup(struct EGong_interface *interface){
- if((interface->requirements&EGong_interfaces_requirement_mask)>0){
- do_log_call_composite(LOG_COMPOSE_SRC, LOG_TYPE_NORMAL, LOG_LEVEL_ERROR, EGong_global_configuration.log.destinations, "Couldn't setup interface ", interface->name, " due to unmet dependencies", NULL);
+
+ if(!IF_CAN_SETUP(*interface)||!IF_ACTIVE(*interface)){
+ return EGONG_INTERFACE_RETURN_OK;
}
- else{
- if(EGong_cnc_init(interface->requirements&(~EGong_interfaces_requirements))<0){
- do_log("Couldn't get requirements", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
- return EGONG_INTERFACE_RETURN_ERROR;
- }
- else{
- EGong_interfaces_requirements|=interface->requirements;
- }
+ if(interface->funcs->sock_watch!=NULL){
+ EGong_waiter_add=interface->funcs->sock_watch;
+ }
+ if(interface->funcs->loop!=NULL){
+ Egong_main_loop_ptr=interface->funcs->loop;
}
- if(interface->setup!=NULL&&interface->setup(interface)<0){
+ if(interface->funcs->setup(interface)<0){
do_log_call_composite(LOG_COMPOSE_SRC, LOG_TYPE_NORMAL, LOG_LEVEL_ERROR, EGong_global_configuration.log.destinations, "Couldn't setup interface ", interface->name, NULL);
+ interface->state&=~(EGONG_INTERFACE_ACTIVE|EGONG_INTERFACE_SETUP);
+ return EGONG_INTERFACE_RETURN_ERROR;
+ }
+ if(EGong_deps_init(interface->requirements)>0){
+ do_log_call_composite(LOG_COMPOSE_SRC, LOG_TYPE_NORMAL, LOG_LEVEL_ERROR, EGong_global_configuration.log.destinations, "Couldn't setup interface ", interface->name, " due to unmet dependencies", NULL);
+ interface->state&=~(EGONG_INTERFACE_ACTIVE|EGONG_INTERFACE_SETUP);
return EGONG_INTERFACE_RETURN_ERROR;
}
interface->state|=EGONG_INTERFACE_SETUP;
EGong_interfaces_userstreams+=EGong_interface_if_count_ustream(interface);
- return 0;
+ return EGONG_INTERFACE_RETURN_OK;
}
int EGong_interface_activate(struct EGong_interface *interface){
- if((interface->state&EGONG_INTERFACE_SETUP)==0&&EGong_interfaces_global_init_done==1){
- if(EGong_interface_setup(interface)<0){
- return -1;
- }
+ if(EGong_interfaces_global_init_done==1&&!IF_TRY_SETUP(*interface)){
+ return -1;
}
if((interface->state&EGONG_INTERFACE_ACTIVE)>0){
return 1;
@@ -127,17 +139,17 @@ int EGong_interface_shutdown(struct EGong_interface *interface){
return 1;
}
int ret=0;
- if(interface->shutdown(interface)<0){
+ if(interface->funcs->shutdown(interface)<0){
do_log_call_composite(LOG_COMPOSE_SRC, LOG_TYPE_NORMAL, LOG_LEVEL_ERROR, EGong_global_configuration.log.destinations, "Couldn't shutdown interface ", interface->name, NULL);
- ret=-1;
+ ret=EGONG_INTERFACE_RETURN_ERROR;
}
interface->state&=~EGONG_INTERFACE_SETUP;
EGong_interface_deactivate(interface);
return ret;
}
int EGong_interface_deactivate(struct EGong_interface *interface){
- if((interface->state&EGONG_INTERFACE_ACTIVE)==0){
- return 1;
+ if(!IF_ACTIVE(*interface)){
+ return EGONG_INTERFACE_RETURN_OK;
}
interface->state&=~EGONG_INTERFACE_ACTIVE;
EGong_interfaces_userstreams-=EGong_interface_if_count_ustream(interface);
@@ -152,41 +164,13 @@ struct EGong_interface *EGong_interface_get_from_id(char identifier){
}
return NULL;
}
-int EGong_interface_interpret_ret(int ret){
- switch(ret){
- case EGONG_INTERFACE_RETURN_FATAL:
- do_log("Couldn't run interface function, exiting", LOG_TYPE_NORMAL, LOG_LEVEL_FATAL);
- case EGONG_INTERFACE_RETURN_ERROR:
- do_log("Couldn't run interface function, skipping", LOG_TYPE_NORMAL, LOG_LEVEL_WARNING);
- break;
- case EGONG_INTERFACE_RETURN_EXIT:
- do_log("Interface function requested exit", LOG_TYPE_NORMAL, LOG_LEVEL_INFO);
- break;
- case EGONG_INTERFACE_RETURN_BREAK:
- do_log("Interface function requested queueabortion", LOG_TYPE_NORMAL, LOG_LEVEL_INFO);
- break;
- }
- return ret;
-}
int EGong_interface_init(unsigned int requirement_mask){
+ do_log("Initializing interfaces", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
EGong_interfaces_requirement_mask=requirement_mask;
int i, ret;
for(i=0; i<CSIZEOF(EGong_interfaces); i++){
- if((EGong_interfaces[i].state&(EGONG_INTERFACE_ACTIVE))>0&&EGong_interfaces[i].setup!=NULL){
- ret=EGong_interface_interpret_ret(EGong_interface_setup(&EGong_interfaces[i]));
- if(ret>EGONG_INTERFACE_RETURN_OK){
- EGong_interfaces[i].state&=~(EGONG_INTERFACE_ACTIVE|EGONG_INTERFACE_SETUP);
- }
- if(ret==EGONG_INTERFACE_RETURN_FATAL){
- return -1;
- }
- else if(ret==EGONG_INTERFACE_RETURN_EXIT){
- return 1;
- }
- else if(ret==EGONG_INTERFACE_RETURN_BREAK){
- break;
- }
- }
+ ret=EGong_interface_setup(&EGong_interfaces[i]);
+ EGONG_INTERFACE_INTERPRET_RET(ret, EGong_interfaces[i]);
}
if(EGong_interfaces_userstreams==0){
do_log("No userstreams available", LOG_TYPE_NORMAL, LOG_LEVEL_FATAL);
@@ -202,62 +186,42 @@ int EGong_interface_cycle(void){
return 1;
}
int i, ret;
- char* msg;
+ String msg;
char *dest;
+ do_log("Checking for new input", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
for(i=0; i<CSIZEOF(EGong_interfaces); i++){
- if((EGong_interfaces[i].state&EGONG_INTERFACE_ACTIVE)>0&&EGong_interfaces[i].cycle!=NULL){
- msg=dest=NULL;
- ret=EGong_interface_interpret_ret(EGong_interfaces[i].cycle(&EGong_interfaces[i], &msg, &dest));
- if(ret==EGONG_INTERFACE_RETURN_FATAL){
- return -1;
- }
- else if(ret==EGONG_INTERFACE_RETURN_EXIT){
- return 1;
- }
- else if(ret==EGONG_INTERFACE_RETURN_BREAK){
- break;
- }
- else if(msg!=NULL){
- EGong_cnc_sendmessage(msg, NULL);
- free(msg);
+ if(IF_ACTIVE(EGong_interfaces[i]) && IF_CAN_CYCLE(EGong_interfaces[i])){
+ msg.data=dest=NULL; msg.length=0;
+ ret=EGong_interfaces[i].funcs->cycle(&EGong_interfaces[i], &msg, &dest);
+ EGONG_INTERFACE_INTERPRET_RET(ret, EGong_interfaces[i]);
+ if(msg.data!=NULL){
+ EGong_cnc_sendmessage(&msg, dest);
+ free(msg.data);
}
}
}
- msg=NULL;
- if(((EGong_interfaces_requirements&EGONG_REQUIREMENT_LISTENER)>0)&&EGong_cnc_getmessage(&msg)==0){
+ do_log("Checking for new message", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ msg.data=NULL; msg.length=0;
+ if(DEP_AVAIL(EGONG_DEP_LISTENER)&&EGong_cnc_getmessage(&msg)==0){
for(i=0; i<CSIZEOF(EGong_interfaces); i++){
- if((EGong_interfaces[i].state&EGONG_INTERFACE_ACTIVE)>0&&EGong_interfaces[i].display_message!=NULL){
- ret=EGong_interface_interpret_ret(EGong_interfaces[i].display_message(&EGong_interfaces[i],msg));
- if(ret==EGONG_INTERFACE_RETURN_FATAL){
- return -1;
- }
- else if(ret==EGONG_INTERFACE_RETURN_EXIT){
- return 1;
- }
- else if(ret==EGONG_INTERFACE_RETURN_BREAK){
- break;
- }
+ if(IF_ACTIVE(EGong_interfaces[i])&&IF_CAN_DISPLAY(EGong_interfaces[i])){
+ ret=EGong_interfaces[i].funcs->display(&EGong_interfaces[i],&msg);
+ EGONG_INTERFACE_INTERPRET_RET(ret, EGong_interfaces[i]);
}
}
}
- if(msg!=NULL){
- EGong_cnc_freemessage(msg);
+ if(msg.data!=NULL){
+ EGong_cnc_freemessage(&msg);
}
return 0;
}
-void EGong_interface_deinit(void){
- EGong_cnc_deinit();
+int EGong_interface_deinit(void){
int i, ret;
for(i=0; i<sizeof(EGong_interfaces)/sizeof(*EGong_interfaces); i++){
- if((EGong_interfaces[i].state&EGONG_INTERFACE_SETUP)>0&&EGong_interfaces[i].shutdown!=NULL){
- ret=EGong_interface_interpret_ret(EGong_interface_shutdown(&EGong_interfaces[i]));
- if(ret==EGONG_INTERFACE_RETURN_EXIT){
- return;
- }
- else if(ret==EGONG_INTERFACE_RETURN_BREAK){
- break;
- }
+ if(IF_SETUP(EGong_interfaces[i])&&IF_CAN_SHUTDOWN(EGong_interfaces[i])){
+ ret=EGong_interface_shutdown(&EGong_interfaces[i]);
+ EGONG_INTERFACE_INTERPRET_RET(ret, EGong_interfaces[i]);
}
}
}
diff --git a/src/Interfaces/Audio.c b/src/Interfaces/Audio.c
@@ -48,7 +48,7 @@ int EGong_if_audio_setup(struct EGong_interface *interface){
}
return EGONG_INTERFACE_RETURN_OK;
}
-int EGong_if_audio_display(struct EGong_interface *interface, const char *msg){
+int EGong_if_audio_display(struct EGong_interface *interface, const String *msg){
do_log("Playing Audio", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
ao_play(EGong_if_audio_device, EGong_if_audio_buffer, BUFFERSIZE);
diff --git a/src/Interfaces/CMD.c b/src/Interfaces/CMD.c
@@ -3,15 +3,13 @@
#include <EGong/Interfaces.h>
#include <EGong/Util/Log.h>
#include <EGong/Util/Misc.h>
+#include <EGong/Util/Dependencies.h>
#include <EGong/Util/Command.h>
#include <EGong/Util/Config.h>
#include <stddef.h>
#include <stdint.h>
-#ifdef USE_GTK
- #include <EGong/Interfaces/GTK/NewMessage.h>
-#endif
-#ifdef USE_WINGUI
- #include <EGong/Interfaces/Windows.h>
+#if defined(USE_GTK) || defined(USE_WINGUI)
+ #include <EGong/Interfaces/GUI.h>
#endif
#ifdef _WIN32
#include <stdio.h>
@@ -70,26 +68,14 @@ struct EGong_command_if_cmd EGong_if_cmd_commands[]={
},
.execute=EGONG_IF_CMD_CYCLE
},
- #ifdef USE_GTK
- {
- .command={
- .longname="gtk-message",
- .shortname="g",
- .description="Opens the GTK-Message dialog",
- .type={.type=EGONG_COMMAND_FUNC_VOID, .args=0},
- .pointer=&EGong_if_cmd_gtk_msg
- },
- .execute=EGONG_IF_CMD_CYCLE
- },
- #endif
- #ifdef USE_WINGUI
+ #if defined(USE_GTK) || defined(USE_WINGUI)
{
.command={
.longname="windows-message",
.shortname="w",
.description="Opens the Windows-Message dialog",
.type={.type=EGONG_COMMAND_FUNC_VOID, .args=0},
- .pointer=&EGong_if_cmd_windows_msg
+ .pointer=&EGong_if_cmd_gui_msg
},
.execute=EGONG_IF_CMD_CYCLE
},
@@ -101,24 +87,16 @@ struct EGong_command_array EGong_if_cmd_commandarray={.array={
.element_count=CSIZEOF(EGong_if_cmd_commands),
}};
-#ifdef USE_GTK
-int EGong_if_cmd_gtk_msg(void){
- EGong_cnc_init(EGONG_REQUIREMENT_GTK);
- EGong_if_gtk_newmsg_display_single();
- gtk_main();
- return EGONG_INTERFACE_RETURN_OK;
-}
-#endif
-#ifdef USE_WINGUI
-int EGong_if_cmd_windows_msg(void){
- EGong_cnc_init(EGONG_REQUIREMENT_SOCKETS);
- EGong_if_win_getmsgdialog();
+#if defined(USE_GTK) || defined(USE_WINGUI)
+int EGong_if_cmd_gui_msg(void){
+ do_log("Stub", LOG_TYPE_NORMAL, LOG_LEVEL_WARNING);
return EGONG_INTERFACE_RETURN_OK;
}
#endif
int EGong_if_cmd_send_message(char *msg){
- EGong_cnc_init(EGONG_REQUIREMENT_SOCKETS);
- EGong_cnc_sendmessage_broad(msg);
+ EGong_deps_init(EGONG_DEP_SOCKETS);
+ String mess={.data=msg, .length=strlen(msg)};
+ EGong_cnc_sendmessage_broad(&mess);
return EGONG_INTERFACE_RETURN_OK;
}
int EGong_if_cmd_help(void){
@@ -145,7 +123,7 @@ struct EGong_command_if_cmd *EGong_if_cmd_get_from_char(const char *commandline)
while(*++valptr=='-');
return (struct EGong_command_if_cmd *)EGong_command_match(&EGong_if_cmd_commandarray,valptr,EGONG_COMMAND_MATCH_ANY);
}
-int EGong_if_cmd_exec(unsigned int execution, struct EGong_interface *interface, char **msg, char **dest){
+int EGong_if_cmd_exec(unsigned int execution, struct EGong_interface *interface, String *msg, char **dest){
int i;
char *arg;
struct EGong_command_if_cmd *command=NULL;
@@ -169,7 +147,7 @@ int EGong_if_cmd_setup(struct EGong_interface *interface){
return EGONG_INTERFACE_RETURN_OK;
}
-int EGong_if_cmd_cycle(struct EGong_interface *interface, char **msg, char **dest){
+int EGong_if_cmd_cycle(struct EGong_interface *interface, String *msg, char **dest){
EGong_if_cmd_exec(EGONG_IF_CMD_CYCLE, interface, NULL, NULL);
EGong_interface_deactivate(interface);
return EGONG_INTERFACE_RETURN_OK;
diff --git a/src/Interfaces/GTK.c b/src/Interfaces/GTK.c
@@ -1,53 +1,89 @@
-#include <EGong/Interfaces/GTK/TrayIcon.h>
-#include <EGong/Interfaces/GTK/Message.h>
#include <EGong/Interfaces/GTK.h>
#include <EGong/Interfaces.h>
#include <EGong/Util/Misc.h>
#include <EGong/Util/Log.h>
+#include <EGong/Util/Waiter.h>
+#include <EGong/Main.h>
#include <EGong/Interfaces.h>
+#include <EGong/Interfaces/GUI.h>
#include <gtk/gtk.h>
+#include <EGong/Util/Config_Compiletime.h>
+#include <EGong/Util/Config.h>
+#ifdef USE_LIBNOTIFY
+ #include <libnotify/notify.h>
+#endif
-GtkWidget *Egong_if_gtk_root;
+GtkWidget *Egong_if_gtk_root=NULL;
+GdkPixbuf *EGong_if_gtk_icon=NULL;
+unsigned short int EGong_if_gtk_have_libnotify=0;
unsigned int EGong_if_gtk_initialized;
-int EGong_if_gtk_int_setup(unsigned int what){
+struct EGong_if_ptrtbl EGong_if_gtk_ptrtbl={
+ .setup=&EGong_if_gtk_setup,
+ .cycle=&EGong_if_gtk_cycle,
+ .display=&EGong_if_gtk_display,
+ .shutdown=&EGong_if_gtk_shutdown,
+ .sock_watch=&EGong_gtk_waiter_add,
+ .loop=&EGong_if_gtk_main
+};
+int EGong_if_gtk_main(void){
+ gtk_main();
+ return 1;
+}
+int EGong_if_gtk_setup(struct EGong_interface *interface){
gtk_init(&EGong_global_argc, &EGong_global_argv);
- if((what&EGONG_IF_GTK_INIT_ROOT&~EGong_if_gtk_initialized)>0){
- Egong_if_gtk_root=gtk_window_new(GTK_WINDOW_TOPLEVEL);
- if(Egong_if_gtk_root!=NULL){
- EGong_if_gtk_initialized|=EGONG_IF_GTK_INIT_ROOT;
- }
- else{
- do_log("Couldn't initialize rootwindow", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
- return -1;
- }
+ #ifdef USE_LIBNOTIFY
+ if(!notify_init("EGong")){
+ do_log("Couldn't setup libnotify", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
}
- if((what&EGONG_IF_GTK_INIT_TRAY&~EGong_if_gtk_initialized)>0){
- if(EGong_if_gtk_tray_setup()<0){
- do_log("Couldn't initialize tray", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
- return -2;
- }
- else{
- EGong_if_gtk_initialized|=EGONG_IF_GTK_INIT_TRAY;
- }
+ else{
+ EGong_if_gtk_have_libnotify=1;
}
- return 0;
-}
-int EGong_if_gtk_setup(struct EGong_interface *interface){
- if(EGong_if_gtk_int_setup(EGONG_IF_GTK_INIT_ALL)<0){
+ #endif
+ GError *err=NULL;
+ EGong_if_gtk_icon=gdk_pixbuf_new_from_file(EGONG_INSTALL_PREFIX"/share/EGong.ico", &err);
+ if(EGong_if_gtk_icon==NULL){
+ do_log("Couldn't open iconfile", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
return EGONG_INTERFACE_RETURN_ERROR;
}
- return 0;
+ return EGONG_INTERFACE_RETURN_OK;
}
-int EGong_if_gtk_cycle(struct EGong_interface *interface, char **msg, char **dest){
- interface->cycle=NULL; //Prevent any further execution
+int EGong_if_gtk_cycle(struct EGong_interface *interface, String *msg, char **dest){
+ return EGONG_INTERFACE_RETURN_OK;
+ interface->funcs->cycle=NULL; //Prevent any further execution
EGong_interfaces_userstreams--; //GTK takes over the job of cycling the interfaces.
gtk_main();
return EGONG_INTERFACE_RETURN_EXIT;
}
-int EGong_if_gtk_display(struct EGong_interface *interface, const char *msg){
- EGong_if_gtk_msg_display(msg); //Shouldn't acutally be used anyway...
+int EGong_if_gtk_display_window(struct EGong_interface *interface, const String *msg){
+ do_log("Displaying message in window", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ gtk_dialog_new_with_buttons(msg->data, GTK_WINDOW(Egong_if_gtk_root), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK);
+}
+int EGong_if_gtk_display_notify(struct EGong_interface *interface, const String *msg){
+ do_log("Displaying message with libnotify", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ #ifdef USE_LIBNOTIFY
+ if(EGong_if_gtk_have_libnotify==0){
+ do_log("Libnotify not initialized", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ }
+ NotifyNotification *notify=notify_notification_new("Egong Nachricht", msg->data, NULL);
+ notify_notification_set_image_from_pixbuf(notify, EGong_if_gtk_icon);
+ GError *err=NULL;
+ if(!notify_notification_show(notify, &err)){
+ do_log("Couldn't display notification", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ }
+ #else
+ do_log("Libnotify not compiled in...", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ #endif
+}
+int EGong_if_gtk_display(struct EGong_interface *interface, const String *msg){
+ do_log("Displaying message", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ if((EGong_global_configuration.gui.destinations&EGONG_CONFIG_GUI_DEST_NOTIFY)>0){
+ EGong_if_gtk_display_notify(interface, msg);
+ }
+ if((EGong_global_configuration.gui.destinations&EGONG_CONFIG_GUI_DEST_WINDOW)>0){
+ EGong_if_gtk_display_window(interface, msg);
+ }
return EGONG_INTERFACE_RETURN_OK;
}
@@ -55,3 +91,187 @@ int EGong_if_gtk_shutdown(struct EGong_interface *interface){
gtk_main_quit();
return EGONG_INTERFACE_RETURN_OK;
}
+void EGong_if_gtk_tray_popup(GtkStatusIcon *icon, guint button, guint activation_time, gpointer data){
+ gtk_menu_popup(GTK_MENU(data),NULL,NULL,gtk_status_icon_position_menu, icon, button, activation_time);
+}
+void EGong_if_gtk_widget_toggle(GtkWidget *caller){
+ if(gtk_widget_get_visible(caller)){
+ gtk_widget_hide_all(caller);
+ }
+ else{
+ gtk_widget_show_all(caller);
+ }
+}
+void EGong_if_gtk_show_element(struct EGong_GUI_item *itm){
+ gtk_widget_show(GTK_WIDGET(itm->itemptr));
+}
+GtkWidget *EGong_if_gtk_create_gui(struct EGong_GUI_item *parent, struct EGong_GUI_item *this){
+ unsigned int i;
+ GtkWidget *element=NULL;
+ GtkWidget *submenu;
+ struct EGong_GUI_item **children=this->child;
+ char *eventdefault;
+ switch(this->type){
+ case EGONG_GUI_WINDOW:
+ element=gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ g_signal_connect_swapped(element, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), (gpointer)element);
+ if(this->text!=NULL){
+ gtk_window_set_title(GTK_WINDOW(element),this->text);
+ }
+ gtk_window_set_icon(GTK_WINDOW(element), EGong_if_gtk_icon);
+ eventdefault="activate-focus";
+ break;
+ case EGONG_GUI_TEXT:
+ element=gtk_entry_new();
+ if(this->text!=NULL){
+ gtk_entry_set_text(GTK_ENTRY(element),this->text);
+ }
+ eventdefault="activate";
+ break;
+ case EGONG_GUI_BUTTON:
+ element=(this->text!=NULL) ? gtk_button_new_with_label(this->text) : gtk_button_new();
+ eventdefault="clicked";
+ break;
+ case EGONG_GUI_LABEL:
+ element=gtk_label_new(this->text);
+ break;
+ case EGONG_GUI_MENU:
+ submenu=element=gtk_menu_new();
+ break;
+ case EGONG_GUI_HBOX:
+ element=gtk_hbox_new(TRUE, 1);
+ break;
+ case EGONG_GUI_VBOX:
+ element=gtk_vbox_new(TRUE, 1);
+ break;
+ case EGONG_GUI_MENUITEM_IMAGE:
+ case EGONG_GUI_MENUITEM:
+
+ if(this->type==EGONG_GUI_MENUITEM_IMAGE){
+ gchar *stockid;
+ switch((unsigned int)this->extra){
+ case EGUI_MIMG_EXIT:
+ stockid=GTK_STOCK_QUIT;
+ break;
+ }
+ element=gtk_image_menu_item_new_with_label(this->text);
+ gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(element),gtk_image_new_from_icon_name((const gchar *)stockid,GTK_ICON_SIZE_MENU));
+ }
+ else{
+ element=gtk_menu_item_new_with_label(this->text);
+ }
+ if(this->child!=NULL){ //Menuitem has submenus
+ struct EGong_GUI_item subm={
+ .type=EGONG_GUI_MENU, .text=NULL, .tooltip=NULL, .child=this->child
+ };
+ submenu=EGong_if_gtk_create_gui(this, &subm);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(element), submenu);
+ children=NULL; //Children have been processed
+ }
+ eventdefault="activate";
+ break;
+ case EGONG_GUI_SYSTRAY:
+ element=(GtkWidget *)gtk_status_icon_new_from_pixbuf(EGong_if_gtk_icon);
+ eventdefault="activate";
+ break;
+ default:
+ do_log("Unknown GUI-Type specified", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ return NULL;
+ }
+ if(element==NULL){
+ do_log("Couldn't initialize element", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ return NULL;
+ }
+ if(this->tooltip!=NULL){
+ if(this->type==EGONG_GUI_SYSTRAY) gtk_status_icon_set_tooltip(GTK_STATUS_ICON(element),this->tooltip);
+ else gtk_widget_set_tooltip_text(element,this->tooltip);
+ }
+ if(this->events!=NULL){
+ struct EGong_GUI_event *ev;
+ for(i=0;this->events[i]!=NULL; i++){
+ ev=this->events[i];
+ g_signal_connect_swapped(element, eventdefault, G_CALLBACK(EGong_GUI_event_callback), (gpointer)ev);
+ }
+ }
+ if(children!=NULL){
+ GtkWidget *child_widget;
+ for(i=0;children[i]!=NULL; i++){
+ child_widget=EGong_if_gtk_create_gui(this, children[i]);
+ if(child_widget!=NULL){
+ if(children[i]->type==EGONG_GUI_WINDOW){
+ if(this->type==EGONG_GUI_SYSTRAY){
+ g_signal_connect_swapped(GTK_STATUS_ICON(element), "activate", G_CALLBACK(EGong_if_gtk_widget_toggle), child_widget);
+ }
+ else{
+ g_signal_connect_swapped(GTK_STATUS_ICON(element), "activate", G_CALLBACK(gtk_widget_show_all), child_widget);
+ }
+ }
+ else{
+ switch(this->type){
+ case EGONG_GUI_MENU:
+ case EGONG_GUI_MENUITEM:
+ gtk_menu_shell_append(GTK_MENU_SHELL(submenu), child_widget);
+ break;
+ case EGONG_GUI_HBOX:
+ case EGONG_GUI_VBOX:
+ gtk_box_pack_start(GTK_BOX(element), child_widget, TRUE, TRUE, 1);
+ break;
+ case EGONG_GUI_SYSTRAY:
+ if(children[i]->type==EGONG_GUI_MENU){
+ g_signal_connect(GTK_STATUS_ICON(element), "popup-menu", G_CALLBACK(EGong_if_gtk_tray_popup), child_widget);
+ }
+ else{
+ do_log("Unknown mapping from systray", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ gtk_widget_destroy(GTK_WIDGET(child_widget));
+ }
+ break;
+ default:
+ do_log("Assigning default", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ gtk_container_add(GTK_CONTAINER(element), child_widget);
+ break;
+ }
+ gtk_widget_show(child_widget);
+ }
+ }
+ else{
+ do_log("Couldn't initialize child Element", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ }
+ }
+ }
+ if(parent==NULL&&Egong_if_gtk_root==NULL){
+ Egong_if_gtk_root=element;
+ }
+ this->itemptr=(void *)element;
+ return element;
+}
+void *EGong_gtk_get_item_value(struct EGong_GUI_item *itm){
+ void *ret=NULL;
+ switch(itm->type){
+ case EGONG_GUI_TEXT:
+ ret=(void *)gtk_entry_get_text(itm->itemptr);
+ break;
+ case EGONG_GUI_WINDOW:
+ ret=(void *)itm->itemptr;
+ break;
+ default:
+ do_log("Event datasource specified where no data can be obtained", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ break;
+ }
+ return ret;
+}
+void EGong_if_gtk_free_item_value(struct EGong_GUI_item *itm, void *element){
+ return;
+}
+gboolean Egong_waiter_gtk_callback(GIOChannel *source, GIOCondition condition, gpointer data){
+ do_log("Trigger", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ if(EGong_interface_cycle()!=0){
+ EGong_if_gtk_shutdown(NULL);
+ }
+ return G_SOURCE_CONTINUE;
+}
+int EGong_gtk_waiter_add(int sock, unsigned short int type){
+ do_log("Adding sockwatch", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ GIOChannel *new=g_io_channel_unix_new(sock);
+ g_io_add_watch(new,G_IO_IN|G_IO_ERR|G_IO_HUP, Egong_waiter_gtk_callback, NULL);
+ return 0;
+}
diff --git a/src/Interfaces/GTK/Message.c b/src/Interfaces/GTK/Message.c
@@ -1,19 +0,0 @@
-#include <EGong/Interfaces/GTK/Message.h>
-#include <EGong/Interfaces/GTK.h>
-#include <gtk/gtk.h>
-
-void EGong_if_gtk_msg_display(const char *msg){
- GtkWidget *dialog = gtk_dialog_new_with_buttons("Nachricht",
- GTK_WINDOW(Egong_if_gtk_root),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_OK,
- GTK_RESPONSE_OK,
- NULL);
- GtkWidget *Message;
- GtkWidget *content_area=gtk_dialog_get_content_area(GTK_DIALOG (dialog));
- Message=gtk_label_new(msg);
- gtk_container_add (GTK_CONTAINER (content_area), Message);
- g_signal_connect_swapped(dialog, "response", G_CALLBACK (gtk_widget_destroy), (gpointer)dialog);
-
- gtk_widget_show_all(dialog);
-}
diff --git a/src/Interfaces/GTK/NewMessage.c b/src/Interfaces/GTK/NewMessage.c
@@ -1,47 +0,0 @@
-#include <gtk/gtk.h>
-#include <EGong/Util/Log.h>
-#include <EGong/Interfaces/GTK/NewMessage.h>
-#include <EGong/Interfaces/GTK/TrayIcon.h>
-#include <EGong/Interfaces/GTK.h>
-GtkWidget *EGong_if_gtk_newmsg_dialog;
-void EGong_if_gtk_newmsg_send_callback(GtkDialog *caller, guint button, gpointer data){
- if(button==GTK_RESPONSE_OK){
- char *message=(char *)gtk_entry_get_text((GtkEntry *)data);
- if(message[0]!='\0'){
- EGong_cnc_sendmessage(message,NULL);
- }
- }
- EGong_if_gtk_newmsg_dialog=NULL;
- gtk_widget_destroy(GTK_WIDGET(caller));
-}
-
-void EGong_if_gtk_newmsg_display_construct(unsigned short int single){
- if(EGong_if_gtk_newmsg_dialog==NULL){
- EGong_if_gtk_newmsg_dialog = gtk_dialog_new_with_buttons("Nachricht senden",
- GTK_WINDOW(Egong_if_gtk_root),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_OK,
- GTK_RESPONSE_OK,
- GTK_STOCK_CANCEL,
- GTK_RESPONSE_CANCEL,
- NULL);
- GtkWidget *Message;
- GtkWidget *content_area=gtk_dialog_get_content_area(GTK_DIALOG (EGong_if_gtk_newmsg_dialog));
- Message=gtk_entry_new();
- gtk_container_add (GTK_CONTAINER (content_area), Message);
- if(single==1){
- g_signal_connect(EGong_if_gtk_newmsg_dialog, "response", G_CALLBACK (gtk_main_quit), NULL);
- }
- g_signal_connect(EGong_if_gtk_newmsg_dialog, "response", G_CALLBACK (EGong_if_gtk_newmsg_send_callback), (gpointer)Message);
-
- }
- gtk_widget_show_all(EGong_if_gtk_newmsg_dialog);
-
-}
-void EGong_if_gtk_newmsg_display_single(void){
- EGong_if_gtk_newmsg_display_construct(1);
-}
-void EGong_if_gtk_newmsg_display(void){
- EGong_if_gtk_newmsg_display_construct(0);
-}
-
diff --git a/src/Interfaces/GTK/TrayIcon.c b/src/Interfaces/GTK/TrayIcon.c
@@ -1,51 +0,0 @@
-#include <gtk/gtk.h>
-#include <EGong/Interfaces/GTK/TrayIcon.h>
-#include <EGong/Interfaces/GTK/NewMessage.h>
-#include <EGong/Util/Log.h>
-#include <EGong/Util/Misc.h>
-#include <EGong/CNC.h>
-
-GtkStatusIcon *EGong_if_gtk_tray_root;
-GtkWidget *EGong_if_gtk_tray_menu;
-
-struct EGong_if_gtk_tray_menu_call EGong_if_gtk_tray_menu_calls[]={
- {.name="Essen", .tooltip="Zum Essen rufen", .message="Essen!"},
-};
-
-void EGong_if_gtk_tray_popup(GtkStatusIcon *icon, guint button, guint activation_time, gpointer data){
- gtk_menu_popup(GTK_MENU(EGong_if_gtk_tray_menu),NULL,NULL,gtk_status_icon_position_menu, icon, button, activation_time);
-}
-void EGong_if_gtk_tray_predef_call(GtkMenuItem *icon, const char *message){
- EGong_cnc_sendmessage_broad(message);
-}
-int EGong_if_gtk_tray_setup(){
- EGong_if_gtk_tray_root=gtk_status_icon_new_from_stock(GTK_STOCK_NETWORK);
- g_signal_connect(GTK_STATUS_ICON(EGong_if_gtk_tray_root), "activate", G_CALLBACK(EGong_if_gtk_newmsg_display), NULL);
- g_signal_connect(GTK_STATUS_ICON(EGong_if_gtk_tray_root), "popup-menu", G_CALLBACK(EGong_if_gtk_tray_popup), NULL);
-
- EGong_if_gtk_tray_menu=gtk_menu_new();
-
- GtkWidget *Exit=gtk_image_menu_item_new_with_label("Exit");
- gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(Exit),gtk_image_new_from_icon_name(GTK_STOCK_QUIT,GTK_ICON_SIZE_MENU));
- g_signal_connect(G_OBJECT(Exit), "activate", G_CALLBACK(gtk_main_quit), NULL);
- gtk_menu_shell_append(GTK_MENU_SHELL(EGong_if_gtk_tray_menu), Exit);
-
- GtkWidget *predef=gtk_menu_item_new_with_label("Rufen");
- GtkWidget *predefM=gtk_menu_new();
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(predef), predefM);
- gtk_menu_shell_prepend(GTK_MENU_SHELL(EGong_if_gtk_tray_menu), predef);
- int i;
- GtkWidget *callitem;
- struct EGong_if_gtk_tray_menu_call *call;
- for(i=0; i<CSIZEOF(EGong_if_gtk_tray_menu_calls); i++){
- call=&EGong_if_gtk_tray_menu_calls[i];
- callitem=gtk_menu_item_new_with_label(call->name);
- gtk_widget_set_tooltip_text(callitem,call->tooltip);
- g_signal_connect(G_OBJECT(callitem), "activate", G_CALLBACK(EGong_if_gtk_tray_predef_call), call->message);
- gtk_menu_shell_prepend(GTK_MENU_SHELL(predefM), callitem);
- }
-
- gtk_widget_show_all(EGong_if_gtk_tray_menu);
- do_log("Tray initialized", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
- return 0;
-}
diff --git a/src/Interfaces/GUI.c b/src/Interfaces/GUI.c
@@ -0,0 +1,167 @@
+#include <EGong/Interfaces/GUI.h>
+#include <EGong/Util/Config_Compiletime.h>
+#ifdef USE_GTK
+ #include <EGong/Interfaces/GTK.h>
+#endif
+#ifdef USE_WINGUI
+ #include <EGong/Interfaces/Windows.h>
+ #include <winuser.h>
+#endif
+#include <EGong/Util/Log.h>
+#include <stdlib.h>
+
+
+struct EGong_GUI_item EGong_GUI_systray_sendmsgfield={.type=EGONG_GUI_TEXT, .extra=(void *)20, .text=NULL, .tooltip=GUIT("Nachricht eingeben"), .child=NULL};
+struct EGong_GUI_item EGong_GUI_newmessage={.type=EGONG_GUI_WINDOW, .extra=(void *)10, .text=GUIT("Nachricht senden"), .tooltip=NULL, .child=EGUI_ARR{
+ EGUI_EL{.type=EGONG_GUI_HBOX, .extra=(void *)15, .text=NULL, .tooltip=NULL, .child=EGUI_ARR{
+ EGUI_ELX(EGong_GUI_systray_sendmsgfield),
+ EGUI_EL{.type=EGONG_GUI_BUTTON, .text=GUIT("Senden"), .tooltip=GUIT("Nachricht Senden"), .child=NULL, .events=EEV_ARR{
+ EEV_EL{.command={.type={.type=EGONG_COMMAND_FUNC_STRING, .args=1}, .pointer=&EGong_cnc_sendmessage_broad}, .sources=EES_ARR{
+ EES_EL{.type=EGONG_GUI_EVSRC_ELEMENT, .data=&EGong_GUI_systray_sendmsgfield},
+ EES_FIN
+ }},
+ EEV_EL{.command={.type={.type=EGONG_COMMAND_FUNC_POINTER, .args=1}, .pointer=&EGong_GUI_event_hide}, .sources=EES_ARR{
+ EES_EL{.type=EGONG_GUI_EVSRC_ELEMENT, .data=&EGong_GUI_newmessage},
+ EES_FIN
+ }},
+ EEV_FIN
+ }},
+ EGUI_FIN
+ }},
+ EGUI_FIN
+ }};
+struct EGong_GUI_item EGong_GUI_systray={
+ .type=EGONG_GUI_SYSTRAY, .text=NULL, .tooltip=NULL, .child=EGUI_ARR{
+ EGUI_EL{.type=EGONG_GUI_MENU, .text=NULL, .tooltip=NULL, .child=EGUI_ARR{
+ EGUI_EL{.type=EGONG_GUI_MENUITEM, .text=GUIT("Rufen"), .tooltip=GUIT("Vordefinierte Ruffunktionen"), .child=EGUI_ARR{
+ EGUI_EL{.type=EGONG_GUI_MENUITEM, .text=GUIT("Essen"), .tooltip=GUIT("Zum Essen rufen"), .child=NULL, .events=EEV_ARR{
+ EEV_EL{.command={.type={.type=EGONG_COMMAND_FUNC_STRING, .args=1}, .pointer=&EGong_cnc_sendmessage_broad}, .sources=EES_ARR{
+ EES_EL{.type=EGONG_GUI_EVSRC_STATIC, .data="Essen"},
+ EES_FIN
+ }},
+ EEV_FIN
+ }},
+ EGUI_FIN,
+ }},
+ EGUI_EL{.type=EGONG_GUI_MENUITEM_IMAGE, .extra=(void *)EGUI_MIMG_EXIT, .text=GUIT("Exit"), .tooltip=GUIT("Programm beenden"), .child=NULL, .events=EEV_ARR{
+ EEV_EL{.command={.type={.type=EGONG_COMMAND_FUNC_VOID, .args=0}, .pointer=EGong_if_gui_shutdown}},
+ EEV_FIN
+ }},
+ EGUI_FIN,
+ }},
+ EGUI_ELX(EGong_GUI_newmessage),
+ EGUI_FIN,
+ }
+};
+char *EGong_GUI_item_names[]={
+ [EGONG_GUI_BUTTON]="Button",
+ [EGONG_GUI_DIALOG]="Dialog",
+ [EGONG_GUI_HBOX]="HBox",
+ [EGONG_GUI_MENU]="Menu",
+ [EGONG_GUI_MENUITEM]="Menuitem",
+ [EGONG_GUI_MENUITEM_IMAGE]="Menuitem Image",
+ [EGONG_GUI_MENUITEM_SEPARATOR]="Menuitem Separator",
+ [EGONG_GUI_SYSTRAY]="Systray",
+ [EGONG_GUI_TEXT]="Text",
+ [EGONG_GUI_WINDOW]="Window"
+};
+#ifdef USE_GTK
+struct EGong_if_gui_ptrtbl EGong_if_gui_pointers={
+ .ifptrtbl=&EGong_if_gtk_ptrtbl,
+ .create=(void *(*)(struct EGong_GUI_item *, struct EGong_GUI_item *))&EGong_if_gtk_create_gui,
+ .get_value=&EGong_gtk_get_item_value,
+ .show=&EGong_if_gtk_show_element,
+ .free_value=&EGong_if_gtk_free_item_value
+};
+#endif
+#ifdef USE_WINGUI
+struct EGong_if_gui_ptrtbl EGong_if_gui_pointers={
+ .ifptrtbl=&EGong_if_win_ptrtbl,
+ .create=(void *(*)(struct EGong_GUI_item *, struct EGong_GUI_item *))&EGong_if_win_create_wrapper,
+ .get_value=&EGong_if_win_get_item_value,
+ .show=&EGong_if_win_show_element,
+ .free_value=&EGong_if_win_free_item_value
+};
+#endif
+void *EGong_GUI_create(struct EGong_GUI_item *gui){
+ void *newgui=EGong_if_gui_pointers.create(NULL, gui);
+ return newgui;
+}
+void EGong_GUI_event_hide(void *gui_element){
+ #ifdef USE_GTK
+ if(EGong_GUI_type==EGONG_GUI_TYPE_GTK){
+ gtk_widget_hide_on_delete(gui_element);
+ }
+ #endif
+ #ifdef USE_WINGUI
+ if(EGong_GUI_type==EGONG_GUI_TYPE_WINGUI){
+ ShowWindow(gui_element, SW_HIDE);
+ }
+ #endif
+}
+void EGong_GUI_event_callback(struct EGong_GUI_event *event){
+ void *args[event->command.type.args];
+
+ unsigned int i;
+ do_log("Constructing argarray", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ for(i=0;i<event->command.type.args;i++){
+ if(event->sources[i]->type==EGONG_GUI_EVSRC_ELEMENT){
+ args[i]=EGong_if_gui_pointers.get_value(event->sources[i]->data);
+ }
+ else if(event->sources[i]->type==EGONG_GUI_EVSRC_STATIC){
+ args[i]=event->sources[i]->data;
+ }
+ }
+ do_log("Trying to execute command", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ EGong_command_exec(&event->command, args);
+
+ for(i=0;i<event->command.type.args;i++){
+ if(event->sources[i]->type==EGONG_GUI_EVSRC_ELEMENT){
+ EGong_if_gui_pointers.free_value(event->sources[i]->data, args[i]);
+ }
+ }
+}
+
+int EGong_if_gui_setup(struct EGong_interface *interface){
+ do_log("Setting up GUI", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ EGong_if_gui_pointers.ifptrtbl->setup(interface);
+ EGong_if_gui_pointers.create(NULL, &EGong_GUI_systray);
+ EGong_if_gui_pointers.show(&EGong_GUI_systray);
+ return EGONG_INTERFACE_RETURN_OK;
+}
+unsigned short int EGong_GUI_has_been_shutdown=0;
+int EGong_if_gui_cmd(char *msg){
+ if(EGong_GUI_has_been_shutdown==1){
+ return EGONG_INTERFACE_RETURN_EXIT;
+ }
+ return EGong_if_gui_pointers.ifptrtbl->cmd(msg);
+}
+
+int EGong_if_gui_cycle(struct EGong_interface *interface, String *msg, char **dest){
+ if(EGong_GUI_has_been_shutdown==1){
+ return EGONG_INTERFACE_RETURN_EXIT;
+ }
+ return EGong_if_gui_pointers.ifptrtbl->cycle(interface,msg,dest);
+}
+
+int EGong_if_gui_display(struct EGong_interface *interface, const String *msg){
+ if(EGong_GUI_has_been_shutdown==1){
+ return EGONG_INTERFACE_RETURN_EXIT;
+ }
+ return EGong_if_gui_pointers.ifptrtbl->display(interface,msg);
+}
+int EGong_if_gui_sockwatch(int sock, unsigned short int type){
+ do_log("Adding sockwatch", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ return EGong_if_gui_pointers.ifptrtbl->sock_watch(sock, type);
+}
+int EGong_if_gui_loop(void){
+ return EGong_if_gui_pointers.ifptrtbl->loop();
+}
+int EGong_if_gui_shutdown(struct EGong_interface *interface){
+ if(EGong_GUI_has_been_shutdown==1){
+ return EGONG_INTERFACE_RETURN_EXIT;
+ }
+ EGong_GUI_has_been_shutdown=1;
+ do_log("Shutting down GUI", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ return EGong_if_gui_pointers.ifptrtbl->shutdown(interface);
+}
diff --git a/src/Interfaces/STDIO.c b/src/Interfaces/STDIO.c
@@ -46,7 +46,7 @@ int EGong_if_stdio_cmd(char *msg){
return EGONG_INTERFACE_RETURN_OK;
}
-int EGong_if_stdio_cycle(struct EGong_interface *interface, char **msg, char **dest){
+int EGong_if_stdio_cycle(struct EGong_interface *interface, String *msg, char **dest){
char buffer[50];
int ret=read(STDIN_FILENO, buffer, 50);
#ifdef _WIN32
@@ -62,15 +62,14 @@ int EGong_if_stdio_cycle(struct EGong_interface *interface, char **msg, char **d
EGong_if_stdio_cmd(&buffer[1]);
}
else{
- buffer[ret]='\0';
- *msg=malloc(ret);
- strncpy(*msg,buffer, ret);
+ msg->data=malloc(ret);
+ strncpy(msg->data, buffer, ret);
}
}
return EGONG_INTERFACE_RETURN_OK;
}
-int EGong_if_stdio_display(struct EGong_interface *interface, const char *msg){
- write(STDOUT_FILENO,msg,strlen(msg));
+int EGong_if_stdio_display(struct EGong_interface *interface, const String *msg){
+ write(STDOUT_FILENO,msg->data,msg->length);
write(STDOUT_FILENO, "\n", sizeof("\n"));
return EGONG_INTERFACE_RETURN_OK;
}
diff --git a/src/Interfaces/Windows.c b/src/Interfaces/Windows.c
@@ -1,91 +1,577 @@
+#define WINVER 0x500
+#define _WIN32_IE WINVER
+#define _WIN32_WINNT WINVER
+#define NTDDI_VERSION NTDDI_VISTA
+#define UNICODE
+#define WIN32_LEAN_AND_MEAN
+#include <EGong/Util/Config_Compiletime.h>
+#include <EGong/Util/Config.h>
#include <EGong/Interfaces.h>
+#include <EGong/Util/Array.h>
#include <EGong/Interfaces/Windows.h>
+#include <EGong/Util/Waiter.h>
+#include <winsock2.h>
+#include <EGong/Interfaces/GUI.h>
+#include <EGong/Main.h>
#include <EGong/CNC.h>
#include <EGong/Util/Log.h>
-#define UNICODE
-#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-
+#include <windowsx.h>
+#include <shellapi.h>
+#include <stdlib.h>
+struct EGong_if_ptrtbl EGong_if_win_ptrtbl={
+ .setup=&EGong_if_win_setup,
+ .cycle=&EGong_if_win_cycle,
+ .display=&EGong_if_win_display,
+ .shutdown=&EGong_if_win_shutdown,
+ .sock_watch=&EGong_if_win_waiter_add,
+ .loop=&EGong_if_win_loop
+};
+extern struct EGong_GUI_item EGong_if_win_messagegui;
+struct EGong_GUI_item EGong_if_win_messagegui_button={.type=EGONG_GUI_BUTTON, .text=GUIT("OK"), .tooltip=NULL, .child=NULL, .events=EEV_ARR{
+ EEV_EL{.command={.type={.type=EGONG_COMMAND_FUNC_VOID, .args=1}, .pointer=&EGong_if_win_destroy}, .sources=EES_ARR{
+ EES_EL{.type=EGONG_GUI_EVSRC_ELEMENT, .data=&EGong_if_win_messagegui},
+ EES_FIN
+ }},
+ EEV_FIN
+}};
+struct EGong_GUI_item EGong_if_win_messagegui_text={.type=EGONG_GUI_LABEL, .text=GUIT(""), .tooltip=NULL, .child=NULL};
+struct EGong_GUI_item EGong_if_win_messagegui={.type=EGONG_GUI_WINDOW, .extra=(void *)10, .text=GUIT("EGong Nachricht"), .tooltip=NULL, .child=EGUI_ARR{
+ EGUI_EL{.type=EGONG_GUI_VBOX, .extra=(void *)10, .text=NULL, .tooltip=NULL, .child=EGUI_ARR{
+ EGUI_ELX(EGong_if_win_messagegui_text),
+ EGUI_ELX(EGong_if_win_messagegui_button),
+ EGUI_FIN
+ }},
+ EGUI_FIN
+}};
WNDCLASSW EGong_if_win_getmsg = {0};
-HWND EGong_if_win_getmsg_editfield;
-LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
- HWND hwndButton;
- (void) hwndButton;
- switch(msg){
- case WM_CREATE:
-
- EGong_if_win_getmsg_editfield = CreateWindowW(L"Edit", NULL,
- WS_CHILD | WS_VISIBLE | WS_BORDER,
- 50, 50, 150, 20, hwnd, (HMENU) 0,
- NULL, NULL);
-
- hwndButton = CreateWindowW(L"button", L"Senden",
- WS_VISIBLE | WS_CHILD, 50, 100, 80, 25,
- hwnd, (HMENU) 1, NULL, NULL);
-
+HWND EGong_if_win_root=NULL;
+HINSTANCE EGong_if_win_instance=NULL;
+struct EGong_GUI_item *EGong_if_win_global_systray=NULL;
+struct Array EGong_if_win_menus;
+struct Array EGong_if_win_windows;
+HWND EGong_if_win_create_wrapper(struct EGong_GUI_item *parent, struct EGong_GUI_item *this){
+ EGong_if_win_create(parent, this, 0);
+}
+RECT EGong_if_win_getsize(struct EGong_GUI_item *this, unsigned short int recurse){
+ HDC hdc=GetDC(NULL);
+ RECT rect={0,0,0,0};
+ RECT childr;
+ unsigned int i;
+ switch(this->type){
+ case EGONG_GUI_WINDOW:
+ for(i=0; this->child[i]!=NULL&&recurse; i++){
+ childr=EGong_if_win_getsize(this->child[i], recurse);
+ if(childr.right>rect.right){
+ rect.right=childr.right;
+ }
+ if(childr.bottom>rect.bottom){
+ rect.bottom=childr.bottom;
+ }
+ }
+ break;
+ case EGONG_GUI_TEXT:
+ DrawText(hdc, GUIT("M"), 1, &rect, DT_CALCRECT);
+ rect.right*=(unsigned int)this->extra;
+ rect.right+=5;
+ rect.bottom+=5;
+ break;
+ case EGONG_GUI_LABEL:
+ DrawText(hdc, this->text, 1, &rect, DT_CALCRECT);
+ break;
+ case EGONG_GUI_BUTTON:
+ DrawText(hdc, this->text, -1, &rect, DT_CALCRECT);
+ rect.right+=10;
+ rect.bottom+=10;
+ break;
+ case EGONG_GUI_HBOX:
+ for(i=0; this->child[i]!=NULL&&recurse; i++){
+ childr=EGong_if_win_getsize(this->child[i], recurse);
+ rect.right+=childr.right+(unsigned int)this->extra;
+ if(childr.bottom>rect.bottom){
+ rect.bottom=childr.bottom;
+ }
+ }
+ break;
+ case EGONG_GUI_VBOX:
+ for(i=0; this->child[i]!=NULL&&recurse; i++){
+ childr=EGong_if_win_getsize(this->child[i], recurse);
+ rect.bottom+=childr.bottom+(unsigned int)this->extra;
+ if(childr.right>rect.right){
+ rect.right=childr.right;
+ }
+ }
+ break;
+ default:
+ do_log("Item has no real size", LOG_TYPE_NORMAL, LOG_LEVEL_WARNING);
+ break;
+ }
+ return rect;
+}
+HWND EGong_if_win_create(struct EGong_GUI_item *parent, struct EGong_GUI_item *this, unsigned int child){
+ HWND element=NULL;
+ HINSTANCE hInstance;
+ NOTIFYICONDATA *notify;
+ MENUITEMINFO *menu;
+ RECT dimensions, *parentd;
+ HDC hdc;
+ unsigned int i;
+ unsigned int tmp;
+ struct EGong_GUI_item **children=this->child;
+ if(parent!=this){
+ if(this->type==EGONG_GUI_TEXT||this->type==EGONG_GUI_BUTTON||this->type==EGONG_GUI_HBOX||this->type==EGONG_GUI_VBOX||this->type==EGONG_GUI_LABEL){
+ dimensions=EGong_if_win_getsize(this, 1);
+ if(parent->type==EGONG_GUI_HBOX||parent->type==EGONG_GUI_VBOX){
+ parentd=parent->userdata;
+ dimensions.top=parentd->top;
+ dimensions.left=parentd->left;
+ if(parent->type==EGONG_GUI_HBOX){
+ dimensions.top+=(parentd->bottom-dimensions.bottom)/2;
+ parentd->left+=dimensions.right+(unsigned int)parent->extra;
+ }
+ else{
+ dimensions.left+=(parentd->right-dimensions.right)/2;
+ parentd->top+=dimensions.bottom+(unsigned int)parent->extra;
+ }
+ }
+ else if(parent->type==EGONG_GUI_WINDOW){
+ dimensions.top=dimensions.left=(unsigned int)parent->extra;
+ }
+ }
+ switch(this->type){
+ case EGONG_GUI_WINDOW:
+ hInstance=(HINSTANCE)GetWindowLong( GetForegroundWindow(), GWL_HINSTANCE );
+ dimensions=EGong_if_win_getsize(this, 1);
+ element=CreateWindow(EGong_if_win_getmsg.lpszClassName, this->text, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, dimensions.right+(unsigned int)this->extra, dimensions.bottom+(unsigned int)this->extra, 0, 0, hInstance, 0);
break;
+ case EGONG_GUI_TEXT:
+ element=CreateWindow(L"Edit", this->text, WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL, dimensions.left, dimensions.top, dimensions.right, dimensions.bottom, parent->itemptr, (HMENU) child, NULL, NULL);
+ break;
+ case EGONG_GUI_BUTTON:
+ element=CreateWindow(L"Button", this->text, WS_VISIBLE | WS_CHILD, dimensions.left, dimensions.top, dimensions.right, dimensions.bottom, parent->itemptr, (HMENU) child, NULL, NULL);
+ break;
+ case EGONG_GUI_MENUITEM:
+ case EGONG_GUI_MENUITEM_IMAGE:
+ case EGONG_GUI_MENUITEM_SEPARATOR:
+ tmp=MF_BYPOSITION;
+ if(this->type==EGONG_GUI_MENUITEM_SEPARATOR){
+ tmp|=MF_SEPARATOR;
+ }
+ else{
+ tmp|=MF_STRING;
+ }
+ if(children!=NULL){
+ HMENU submenu=CreatePopupMenu();
+ for(i=0; children[i]!=NULL; i++){
+ if(children[i]->type==EGONG_GUI_MENUITEM || children[i]->type==EGONG_GUI_MENUITEM_IMAGE || children[i]->type==EGONG_GUI_MENUITEM_SEPARATOR){
+ tmp|=MF_POPUP;
+ }
+ }
+ if((tmp&MF_POPUP)>0){
+ this->userdata=submenu;
+ InsertMenu(parent->itemptr, -1, tmp, (UINT) submenu, this->text);
+ }
+ else{
+ this->userdata=NULL;
+ DestroyMenu(submenu);
+ }
+ }
+ if((tmp&MF_POPUP)==0){
+ if(parent->type==EGONG_GUI_MENUITEM||parent->type==EGONG_GUI_MENUITEM_IMAGE){
+ InsertMenu(parent->userdata, -1, tmp, EGong_if_win_menus.element_count+1, this->text);
+ }
+ else{
+ InsertMenu(parent->itemptr, -1, tmp, EGong_if_win_menus.element_count+1, this->text);
+ }
+ Array_add(&EGong_if_win_menus, &this); //Save menus for identification.
+ }
+ element=parent->itemptr;
+ break;
+ case EGONG_GUI_MENU:
+ element=(HWND)CreatePopupMenu();
+ break;
+ case EGONG_GUI_LABEL:
+ element=CreateWindow(L"Static", this->text, WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER, dimensions.left, dimensions.top, dimensions.right, dimensions.bottom, parent->itemptr, (HMENU) child, NULL, NULL);
+
+ break;
+ case EGONG_GUI_HBOX:
+ case EGONG_GUI_VBOX:
+ this->userdata=malloc(sizeof(RECT));
+ memcpy(this->userdata, &dimensions, sizeof(RECT));
+ element=parent->itemptr;
+ break;
+ case EGONG_GUI_SYSTRAY:
+ hInstance=(HINSTANCE)GetWindowLong( GetForegroundWindow(), GWL_HINSTANCE );
+ if(EGong_if_win_global_systray!=NULL){
+ do_log("Already a systray icon defined!", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ return NULL;
+ }
+ notify=malloc(sizeof(NOTIFYICONDATA));
+ if(parent==NULL){
+ //struct EGong_GUI_item virtual_parent={.type=EGONG_GUI_WINDOW, .text=NULL, .tooltip=NULL, .child=NULL};
+ //notify->hWnd=EGong_if_win_create(NULL, &virtual_parent, 0);
+ if(EGong_if_win_root==NULL){
+ notify->hWnd=CreateWindow(EGong_if_win_getmsg.lpszClassName, NULL, 0, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 0, hInstance, 0);
+ EGong_if_win_root=notify->hWnd;
+ }
+ else{
+ notify->hWnd=EGong_if_win_root;
+ }
+
+ }
+ else{
+ notify->hWnd=parent->itemptr;
+ }
+ element=notify->hWnd;
+ notify->cbSize = sizeof(NOTIFYICONDATA);
+
+ notify->uID=12+1;
+ notify->uFlags=NIF_ICON | NIF_MESSAGE;
+ notify->uCallbackMessage=WM_TRAY_ACTION;
+ //HMODULE hModule = GetModuleHandle(NULL);
+ notify->hIcon=LoadImage(GetModuleHandle(NULL), GUIT("Master_icon"), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
+ if(notify->hIcon==NULL){
+ do_log("Couldn't load Icon", LOG_TYPE_SIGNAL, LOG_LEVEL_ERROR);
+ }
+
+ #if _WIN32_IE >= 0x0500
+ notify->uVersion=NOTIFYICON_VERSION;
+ #endif
+ if(this->tooltip!=NULL){
+ wcscpy(notify->szTip, this->tooltip);
+ notify->uFlags|=NIF_TIP;
+ }
+ Shell_NotifyIcon(NIM_ADD, notify);
+ #if _WIN32_IE >= 0x0500
+ Shell_NotifyIcon(NIM_SETVERSION, notify);
+ #endif
+ this->userdata=notify;
+ EGong_if_win_global_systray=this;
+ break;
+ default:
+ do_log("Unknown GUI-Type specified", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ return NULL;
+ }
+ }
+ else{
+ element=this->itemptr;
+ }
+ if(element==NULL){
+ do_log("Could not initialize GUI Element", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ return NULL;
+ }
+ if((parent!=NULL && parent->itemptr!=element) && !(this->type==EGONG_GUI_SYSTRAY || this->type==EGONG_GUI_MENU || this->type==EGONG_GUI_MENUITEM || this->type==EGONG_GUI_MENUITEM_SEPARATOR || this->type==EGONG_GUI_LABEL)){ //if parent->itemptr==element, the item does not exist.
+ if(SetWindowLongPtr(element, GWLP_USERDATA, (LONG_PTR)this)==(LONG_PTR)NULL&&GetLastError()!=0){
+ do_log("Couldn't set userpointer", LOG_TYPE_SIGNAL, LOG_LEVEL_ERROR);
+ }
+ }
+ if(parent==NULL && EGong_if_win_root==NULL){
+ EGong_if_win_root=element;
+ }
+ this->itemptr=element;
+ if(parent==NULL){
+ Array_add(&EGong_if_win_windows, &this); //Save rootwindows for destruction
+ }
+ if(children!=NULL){
+ for(i=0; children[i]!=NULL; i++){
+ EGong_if_win_create(this, children[i], i);
+ }
+ }
+ return element;
+}
+void EGong_if_win_show_element(struct EGong_GUI_item *itm){
+ switch(itm->type){
+ case EGONG_GUI_WINDOW:
+ case EGONG_GUI_MENU:
+ EGong_if_win_show_item((HWND) itm->itemptr);
+ break;
+ }
+}
+
+void EGong_if_win_show_item(HWND item){
+ ShowWindow(item, SW_SHOW);
+ SetForegroundWindow(item);
+}
+
+void EGong_if_win_free_item_value(struct EGong_GUI_item *item, void *value){
+ String *str;
+ switch(item->type){
+ case EGONG_GUI_TEXT:
+ str=(String *)value;
+ free(str->data);
+ free(str);
+ break;
+ }
+}
+void *EGong_if_win_get_item_value(struct EGong_GUI_item *item){
+ void *ret=NULL;
+ size_t len;
+
+ switch(item->type){
+ case EGONG_GUI_TEXT:
+ len=Edit_GetTextLength(item->itemptr)+1;
+ wchar_t *text=calloc(len, sizeof(wchar_t));
+ char *msg=calloc(len, sizeof(char));
- case WM_COMMAND:
-
- if (HIWORD(wParam) == BN_CLICKED) {
- int len = GetWindowTextLengthW(EGong_if_win_getmsg_editfield) + 1;
- char text[len];
- char msg[len];
-
- GetWindowTextW(EGong_if_win_getmsg_editfield, text, 5+len);
- wcstombs(msg,text, len);
+ Edit_GetText(item->itemptr, text, len);
+ size_t bytes=wcstombs(msg, text, len);
+ if(bytes==-1){
+ do_log("Couldn't convert widecharstring to multibytestring", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ free(text);
+ free(msg);
+ break;
+ }
+ msg[bytes]='\0';
+ ret=(void *)msg;
+ free(text);
+ break;
+ case EGONG_GUI_WINDOW:
+ ret=(void *)item->itemptr;
+ break;
+ default:
+ do_log("Event datasource specified where no data can be obtained", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ break;
+ }
+ return ret;
+}
+void EGong_if_win_toggle_item(struct EGong_GUI_item *item){
+ if(IsWindowVisible(item->itemptr)){
+ ShowWindow(item->itemptr, SW_HIDE);
+ }
+ else{
+ EGong_if_win_show_element(item);
+ }
+}
+void EGong_if_win_trayhandler(struct EGong_GUI_item *item, unsigned short int type, int x, int y, HWND hwnd){
+ unsigned int i=0;
+ for(i=0; item->child[i]!=NULL; i++){
+ if(item->child[i]->type==type){
+ if(type==EGONG_GUI_MENU){
+ SetForegroundWindow(EGong_if_win_root);
+ int rightaligned=(GetSystemMetrics(SM_MENUDROPALIGNMENT)==0) ? TPM_LEFTALIGN : TPM_RIGHTALIGN;
+ int menu=TrackPopupMenu(item->child[i]->itemptr, rightaligned | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, x, y, 0, hwnd, NULL);
+ if(menu==0){
+ continue;
+ }
+ menu--;
+ struct EGong_GUI_item *win=*(struct EGong_GUI_item **)Array_get(&EGong_if_win_menus, menu);
+ EGong_if_win_actionhandler(win);
+ }
+ else{
+ EGong_if_win_toggle_item(item->child[i]);
+ }
+ }
+ }
+}
+void EGong_if_win_actionhandler(struct EGong_GUI_item *item){
+ if(item->events==NULL)
+ return;
+ do_log("We have action!1", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ unsigned int i=0;
+ for(i=0; item->events[i]!=NULL; i++){
+ EGong_GUI_event_callback(item->events[i]);
+ }
+
+}
+
+LRESULT CALLBACK EGong_if_win_callback(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
+ struct EGong_GUI_item *win=NULL;
+ POINT pt;
+ switch(msg){
+ case WM_COMMAND:
+ /*
+ if(isMenuItem){
+ win=Array_get(&EGong_if_win_menus, LOWORD(wParam));
+ }
+ else{
- msg[len]='\0';
- EGong_cnc_sendmessage_broad(msg);
- PostQuitMessage(0);
}
- break;
+ */
+ win=(struct EGong_GUI_item *)GetWindowLongPtr((HWND)lParam, GWLP_USERDATA);
+ if(win!=NULL){
+ EGong_if_win_actionhandler(win);
+ }
+ break;
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
+ case WM_TRAY_ACTION:
+ switch(lParam){
+ case WM_LBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ GetCursorPos(&pt);
+ if(lParam==WM_LBUTTONDOWN){
+ EGong_if_win_trayhandler(EGong_if_win_global_systray, EGONG_GUI_WINDOW, pt.x, pt.y, hwnd);
+ }
+ else{
+ EGong_if_win_trayhandler(EGong_if_win_global_systray, EGONG_GUI_MENU, pt.x, pt.y, hwnd);
+ }
+ break;
+ }
+ break;
+ case WM_CLOSE:
+ ShowWindow(hwnd, SW_HIDE);
+ return 0;
+ break;
+ case WM_DESTROY:
+ case WM_QUIT:
+ EGong_main_deinit();
+ exit(LOWORD(wParam));
+ break;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
-int EGong_if_win_getmsgdialog(){
+
+
+int EGong_if_win_setup(struct EGong_interface *interface){
+ do_log("Initializing WinGUI", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+
HINSTANCE hInstance = (HINSTANCE)GetWindowLong( GetForegroundWindow(), GWL_HINSTANCE );
- MSG msg;
- EGong_if_win_getmsg.lpszClassName = L"EGong Message";
+ EGong_if_win_getmsg.lpszClassName = L"EGong";
EGong_if_win_getmsg.hInstance = hInstance;
EGong_if_win_getmsg.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
- EGong_if_win_getmsg.lpfnWndProc = WndProc;
+ EGong_if_win_getmsg.lpfnWndProc = EGong_if_win_callback;
EGong_if_win_getmsg.hCursor = LoadCursor(0,IDC_ARROW);
RegisterClassW(&EGong_if_win_getmsg);
- CreateWindowW(EGong_if_win_getmsg.lpszClassName, L"EGong Message",
- WS_OVERLAPPEDWINDOW | WS_VISIBLE,
- 220, 220, 280, 200, 0, 0, hInstance, 0);
- while(GetMessage(&msg, NULL, 0, 0)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return 0;
+ Array_init(&EGong_if_win_menus, sizeof(struct EGong_GUI_item *), 0);
+ Array_init(&EGong_if_win_windows, sizeof(struct EGong_GUI_item *), 2);
+
+ return EGONG_INTERFACE_RETURN_OK;
}
-void EGong_if_win_react(){
- do_log("Windowsinterface is a stub", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+int EGong_if_win_cmd(char *msg){
+ return EGONG_INTERFACE_RETURN_OK;
}
-int EGong_if_win_setup(struct EGong_interface *interface){
- EGong_if_win_react();
- return EGONG_INTERFACE_RETURN_ERROR;
+
+int EGong_if_win_cycle(struct EGong_interface *interface, String *msg, char **dest){
+ MSG loopmsg;
+ while(PeekMessage(&loopmsg, NULL, 0, 0, PM_REMOVE)!=0){
+ TranslateMessage(&loopmsg);
+ DispatchMessage(&loopmsg);
+ }
+ return EGONG_INTERFACE_RETURN_OK;
}
-int EGong_if_win_cmd(char *msg){
- EGong_if_win_react();
- return EGONG_INTERFACE_RETURN_ERROR;
+int EGong_if_win_display_notify(struct EGong_interface *interface, const String *msg){
+ NOTIFYICONDATA *nid=EGong_if_win_global_systray->userdata;
+ mbstowcs(nid->szInfo, msg->data, msg->length);
+ nid->szInfo[msg->length]='\0';
+ nid->uFlags=NIF_INFO;
+ #if _WIN32_IE >= 0x0500
+ nid->uTimeout=5000;
+ #endif
+ wcscpy(nid->szInfoTitle, L"EGong Nachricht");
+ #if _WIN32_IE > 0x0500
+ //nid->dwInfoFlags=NIIF_USER;
+ nid->dwInfoFlags=NIIF_NONE;
+ #else
+ nid->dwInfoFlags=NIIF_NONE;
+ #endif
+
+ if(!Shell_NotifyIconW(NIM_MODIFY, nid)){
+ do_log("Couldn't notify via Systray", LOG_TYPE_SIGNAL, LOG_LEVEL_ERROR);
+ return EGONG_INTERFACE_RETURN_ERROR;
+ }
+
+ return EGONG_INTERFACE_RETURN_OK;
+}
+int EGong_if_win_display_window(struct EGong_interface *interface, const String *msg){
+ /*if((unsigned int)EGong_if_win_messagegui_text.extra==1){
+ EGong_if_win_messagegui_text.text=realloc(EGong_if_win_messagegui_text.text, msg->length+1*sizeof(wchar_t));
+ }
+ else{
+ EGong_if_win_messagegui_text.text=calloc(msg->length+1, sizeof(wchar_t));
+ EGong_if_win_messagegui_text.extra=(void *)(unsigned int)1;
+ }
+ mbstowcs(EGong_if_win_messagegui_text.text, msg->data, msg->length+1);
+ EGong_if_win_create(NULL, &EGong_if_win_messagegui, 0);
+ EGong_if_win_show_element(&EGong_if_win_messagegui);*/
+ wchar_t msgw[msg->length+1];
+ mbstowcs(msgw, msg->data, msg->length);
+ msgw[msg->length]='\0';
+ MessageBox(NULL, msgw, GUIT("EGong Nachricht"), MB_OK);
+ return EGONG_INTERFACE_RETURN_OK;
}
-int EGong_if_win_cycle(struct EGong_interface *interface, char **msg, char **dest){
- EGong_if_win_react();
- return EGONG_INTERFACE_RETURN_ERROR;
+int EGong_if_win_display(struct EGong_interface *interface, const String *msg){
+ if((EGong_global_configuration.gui.destinations&EGONG_CONFIG_GUI_DEST_NOTIFY)>0){
+ EGong_if_win_display_notify(interface, msg);
+ }
+ if((EGong_global_configuration.gui.destinations&EGONG_CONFIG_GUI_DEST_WINDOW)>0){
+ EGong_if_win_display_window(interface, msg);
+ }
+ return EGONG_INTERFACE_RETURN_OK;
}
-int EGong_if_win_display(struct EGong_interface *interface, const char *msg){
- EGong_if_win_react();
- return EGONG_INTERFACE_RETURN_ERROR;
+void EGong_if_win_destroy(struct EGong_GUI_item *item){
+ unsigned int i;
+ switch(item->type){
+ case EGONG_GUI_WINDOW:
+ DestroyWindow(item->itemptr);
+ break;
+ case EGONG_GUI_LABEL:
+ if((unsigned int)item->extra==1){
+ free(item->text);
+ }
+ break;
+ case EGONG_GUI_BUTTON:
+ break;
+ case EGONG_GUI_MENUITEM:
+ case EGONG_GUI_MENUITEM_IMAGE:
+ if(item->userdata!=NULL){
+ DestroyMenu(item->userdata);
+ }
+ break;
+ case EGONG_GUI_MENUITEM_SEPARATOR:
+ break;
+ case EGONG_GUI_MENU:
+ DestroyMenu(item->itemptr);
+ break;
+ case EGONG_GUI_HBOX:
+ case EGONG_GUI_VBOX:
+ case EGONG_GUI_SYSTRAY:
+ free(item->userdata);
+ break;
+ }
+
+
+ if(item->child!=NULL){
+ for(i=0; item->child[i]!=NULL; i++){
+ EGong_if_win_destroy(item->child[i]);
+ }
+ }
+}
+int EGong_if_win_waiter_add(int sock, unsigned short int type){
+ if(type==EGONG_WAITER_SOCKET){
+ struct EGong_GUI_item *main=*(struct EGong_GUI_item **)Array_get(&EGong_if_win_windows,0);
+ WSAAsyncSelect(sock,(HWND)main->itemptr,WM_SOCKET,FD_ACCEPT|FD_READ);
+ }
+ else{
+ do_log("Sorry, only sockets here...", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ return -1;
+ }
+ return 0;
+}
+void EGong_if_win_destroy_wrapper(struct EGong_GUI_item **item){
+ EGong_if_win_destroy(*item);
+}
+int EGong_if_win_shutdown(struct EGong_interface *interface){
+ Array_foreach(&EGong_if_win_windows, (void(*)(void*))&EGong_if_win_destroy_wrapper);
+ Array_destroy(&EGong_if_win_menus);
+ Array_destroy(&EGong_if_win_windows);
+
+ PostQuitMessage(0);
+ MSG msg;
+ while(GetMessage(&msg, NULL, 0, 0)!=0){
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ return EGONG_INTERFACE_RETURN_EXIT;
+}
+int EGong_if_win_loop(void){
+ int ret;
+ while(WaitMessage()){
+ if((ret=EGong_interface_cycle())!=EGONG_INTERFACE_RETURN_OK){
+ return ret;
+ }
+ }
}
diff --git a/src/Interfaces/Windows.rc b/src/Interfaces/Windows.rc
@@ -0,0 +1 @@
+Master_icon ICON "../../data/EGong.ico"
diff --git a/src/Main.c b/src/Main.c
@@ -0,0 +1,49 @@
+#include <EGong/Main.h>
+#include <EGong/Interfaces.h>
+#include <EGong/Util/Waiter.h>
+#include <EGong/CNC.h>
+#include <EGong/Util/Dependencies.h>
+#include <EGong/Util/Misc.h>
+#include <EGong/Util/Log.h>
+#include <EGong/Util/Config.h>
+
+int(*Egong_main_loop_ptr)(void)=&EGong_main_loop_default;
+int EGong_main_do(void){
+ return EGong_interface_cycle();
+}
+int EGong_main_init(void){
+ EGong_config_init(NULL);
+ EGong_misc_rand_init();
+ if(EGong_waiter_init()<0){
+ return -1;
+ }
+
+ if(EGong_interface_init(0)<0){
+ return -1;
+ }
+ return 0;
+}
+
+int EGong_main_loop(){
+ return Egong_main_loop_ptr();
+}
+
+int EGong_main_loop_default(void){
+ int ret;
+ EGong_main_do();
+ do_log("Entering defaultloop", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ while(1){
+ if(EGong_waiter_wait()!=0){
+ return -1;
+ }
+ ret=EGong_main_do();
+ if(ret!=0){
+ return ret;
+ }
+ }
+ return 0;
+}
+
+void EGong_main_deinit(void){
+ EGong_deps_deinit(EGONG_DEP_ALL);
+}
diff --git a/src/Packet.c b/src/Packet.c
@@ -30,11 +30,11 @@ int EGong_calculate_package_hash(struct EGong_packet *packet, unsigned char *des
return 0;
}
-int EGong_generate_packet(struct EGong_packet *packet, const char *msg, unsigned int msg_length){
+int EGong_generate_packet(struct EGong_packet *packet, const String *msg){
EGong_misc_get_rand(packet->rand,EGONG_PACKET_RAND_LENGTH);
- packet->message.length=msg_length;
- packet->message.data=(char *)msg;
+ packet->message.length=msg->length;
+ packet->message.data=(char *)msg->data;
EGong_calculate_package_hash(packet,packet->hash, NULL);
@@ -122,10 +122,11 @@ void EGong_packetbuffer_to_packet(const char *buf, struct EGong_packet *packet){
packet->message.length=ntohs(*(uint16_t *)buf);
buf+=EGONG_PACKET_LENGTH_LENGTH;
packet->message.data=(char *)buf;
+ packet->message.data[packet->message.length]='\0';
}
void EGong_drop_packet(SOCKET *sock){
do_log("Dropping packet.", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
- EGong_listener_get(sock,NULL,0, NULL, 0);
+ EGong_listener_get(sock,NULL,0, NULL, MSG_DONTWAIT);
}
int EGong_get_packet(SOCKET *sock, struct EGong_packet *packet){
if(sock==NULL){
@@ -149,7 +150,7 @@ int EGong_get_packet(SOCKET *sock, struct EGong_packet *packet){
uint16_t rawsize=*(uint16_t*)(packetbuf+EGONG_PACKET_RAND_LENGTH+EGONG_PACKET_HASH_LENGTH);
size_t size=ntohs(rawsize);
char *dest;
- if(EGong_packetbuf_alloc(size+EGONG_PACKET_MSGHEADLEN,&dest, 1)<0){
+ if(EGong_packetbuf_alloc(size+EGONG_PACKET_MSGHEADLEN+1,&dest, 1)<0){
do_log("Couldn't allocate packetbuffer",LOG_TYPE_NORMAL, LOG_LEVEL_WARNING);
EGong_drop_packet(sock);
return -2;
diff --git a/src/Util/Command.c b/src/Util/Command.c
@@ -5,6 +5,18 @@
#include <stdint.h>
#include <stdio.h>
+unsigned int EGong_command_argc(struct EGong_command *command){
+ if(command->type.type>EGONG_COMMAND_ARG2){
+ return 2;
+ }
+ else if(command->type.type>EGONG_COMMAND_ARG1){
+ return 1;
+ }
+ else if(command->type.type>EGONG_COMMAND_ARG0){
+ return 0;
+ }
+ return 0;
+}
struct EGong_command *EGong_command_match(struct EGong_command_array *commands, const char *data, unsigned int match_type){
unsigned int i;
struct EGong_command *command=NULL;
@@ -37,6 +49,7 @@ void EGong_command_print_help(struct EGong_command_array *commands, int destinat
}
}
int EGong_command_exec(struct EGong_command *command, void **data){
+ String str;
switch(command->type.type){
case EGONG_COMMAND_BOOL_FALSE:
*(unsigned int *)command->pointer=0;
@@ -55,12 +68,26 @@ int EGong_command_exec(struct EGong_command *command, void **data){
if(*(unsigned int *)command->pointer>(unsigned int)0)
(*(unsigned int *)command->pointer)--;
break;
+ case EGONG_COMMAND_UINT_SET:
+ (*(unsigned int *)command->pointer)=*(unsigned int *)data;
+ break;
case EGONG_COMMAND_FUNC_VOID:
((int(*)(void))command->pointer)();
break;
+ case EGONG_COMMAND_FUNC_UINT:
+ ((int(*)(unsigned int))command->pointer)(*(unsigned int*)data);
+ break;
case EGONG_COMMAND_FUNC_CHAR:
((int(*)(char *))command->pointer)(*(char **)data);
break;
+ case EGONG_COMMAND_FUNC_STRING:
+ str.data=*(char **)data;
+ str.length=strlen(str.data);
+ ((int(*)(String *))command->pointer)(&str);
+ break;
+ case EGONG_COMMAND_FUNC_POINTER:
+ ((void(*)(void *))command->pointer)(*(void **)data);
+ break;
case EGONG_COMMAND_FUNC_2CHAR:
((int(*)(char *, char *))command->pointer)(((char **)data)[0],((char **)data)[1]);
break;
diff --git a/src/Util/Config.c b/src/Util/Config.c
@@ -1,5 +1,6 @@
#include <EGong/Util/Config.h>
#include <EGong/Util/Log.h>
+#include <EGong/Util/Misc.h>
#include <stdlib.h>
struct EGong_config EGong_global_configuration;
@@ -18,7 +19,7 @@ struct EGong_config_file_entry EGong_configuration_file_interface[EGONG_CONFIG_F
[EGONG_CONFIG_FILE_LOG_DEST]={
.type=EGONG_CONFIG_TYPE_BITMASK,
.name="Logdestinationsbitmaske",
- .data_offset=offsetof(struct EGong_config,log.level)
+ .data_offset=offsetof(struct EGong_config,log.destinations)
},
[EGONG_CONFIG_FILE_PACKET_COOKIE]={
.type=EGONG_CONFIG_TYPE_STRING,
@@ -43,7 +44,7 @@ struct EGong_config_file_entry EGong_configuration_file_interface[EGONG_CONFIG_F
};
void EGong_config_set_defaults(struct EGong_config *conf){
conf->log.color=0;
- conf->log.level=LOG_LEVEL_DEBUG;
+ conf->log.level=LOG_LEVEL_INFO;
conf->log.destinations=LOG_DEST_STDIO;
conf->server.port=4242;
@@ -51,11 +52,13 @@ void EGong_config_set_defaults(struct EGong_config *conf){
conf->packet.packet_maxlen=1000;
conf->packet.cookie="Derpaherp";
+
+ conf->gui.destinations=EGONG_CONFIG_GUI_DEST_NOTIFY;
}
int EGong_config_write(struct EGong_config *conf, int file){
unsigned int i;
- for(i=0;i<EGONG_CONFIG_FILE_ENTRYCOUNT; i++){
+ for(i=0;i<CSIZEOF(EGong_configuration_file_interface); i++){
}
return 0;
diff --git a/src/Util/Dependencies.c b/src/Util/Dependencies.c
@@ -0,0 +1,50 @@
+#include <EGong/Util/Dependencies.h>
+#include <EGong/Util/Log.h>
+#include <stdlib.h>
+#include <EGong/Util/Socket.h>
+#include <EGong/Util/Waiter.h>
+
+unsigned int EGong_dep_status=0;
+
+
+int EGong_deps_init(unsigned int dependencies){
+ if(DEP_REQ(dependencies, EGONG_DEP_SOCKETS)){
+ do_log("Initializing sockets", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ if(EGong_sockets_setup()<0){
+ do_log("Couldn't initialize sockets", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ return -1;
+ }
+ else{
+ EGong_dep_status|=EGONG_DEP_SOCKETS;
+ }
+ }
+ if(DEP_REQ(dependencies, EGONG_DEP_LISTENER)){
+ do_log("Initializing Listener", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ if(EGong_deps_init(EGONG_DEP_SOCKETS)<0){
+ return -1;
+ }
+ if(EGong_listener_init(NULL,NULL)<0){
+ do_log("Couldn't initialize listener", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
+ return -1;
+ }
+ else{
+ EGong_waiter_add(EGong_listen_sock, EGONG_WAITER_SOCKET);
+ EGong_dep_status|=EGONG_DEP_LISTENER;
+ }
+ }
+ return 0;
+}
+
+int EGong_deps_deinit(unsigned int dependencies){
+ if(DEP_STOP(dependencies, EGONG_DEP_SOCKETS)){
+ do_log("Deinitializing sockets", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ EGong_sockets_shutdown();
+ EGong_dep_status&=~EGONG_DEP_SOCKETS;
+ dependencies|=EGONG_DEP_LISTENER;
+ }
+ if(DEP_STOP(dependencies, EGONG_DEP_LISTENER)){
+ do_log("Deinitializing Listener", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
+ EGong_listener_close(NULL);
+ EGong_dep_status&=~EGONG_DEP_LISTENER;
+ }
+}
diff --git a/src/Util/Log.c b/src/Util/Log.c
@@ -85,28 +85,27 @@ void do_log_call(const struct log_source src, const char *msg, unsigned int msgl
STRCAT(msgbuf,": ");
STRNCAT(msgbuf, msg, msglength);
- if(type==LOG_TYPE_SIGNAL){
- char *err=strerror(error);
- STRCAT(msgbuf,"(");
- STRNCAT(msgbuf, err,strlen(err));
- STRCAT(msgbuf,")");
- }
#ifdef _WIN32
- else if(type==LOG_TYPE_SOCKET){
- STRCAT(msgbuf,"(");
- LPVOID lpMsgBuf;
- int e;
-
- lpMsgBuf = (LPVOID)"Unknown error";
- e = WSAGetLastError();
- if (FormatMessage(
+ if(type==LOG_TYPE_SIGNAL||type==LOG_TYPE_SOCKET){
+ STRCAT(msgbuf,"(");
+ DWORD error;
+ if(type==LOG_TYPE_SIGNAL){
+ error=GetLastError();
+ }
+ else{
+ error = WSAGetLastError();
+ }
+ LPTSTR lpMsgBuf = (LPTSTR)"Unknown error";
+ size_t ret=FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, e,
+ NULL, error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR)&lpMsgBuf, 0, NULL)) {
- STRNCAT(msgbuf, lpMsgBuf,strlen(lpMsgBuf));
+ (LPTSTR)&lpMsgBuf, 0, NULL);
+ if(ret){
+ lpMsgBuf[ret-2]='\0';
+ STRNCAT(msgbuf, lpMsgBuf,ret);
LocalFree(lpMsgBuf);
}
else{
@@ -114,6 +113,13 @@ void do_log_call(const struct log_source src, const char *msg, unsigned int msgl
}
STRCAT(msgbuf,")");
}
+ #else
+ if(type==LOG_TYPE_SIGNAL){
+ char *err=strerror(error);
+ STRCAT(msgbuf,"(");
+ STRNCAT(msgbuf, err,strlen(err));
+ STRCAT(msgbuf,")");
+ }
#endif
STRCAT(msgbuf,"\n\0");
length=(unsigned int)(msgbuf-msgptr);
diff --git a/src/Util/Socket.c b/src/Util/Socket.c
@@ -36,6 +36,7 @@ int inet_aton(const char *cp, struct in_addr *inp){
#endif
int EGong_sockets_setup(void){
+ do_log("Setting up sockets...", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
#ifdef _WIN32
int res=WSAStartup(MAKEWORD(2,2), &wsaData);
if(res!=0) {
@@ -46,6 +47,7 @@ int EGong_sockets_setup(void){
return 0;
}
int EGong_sockets_shutdown(void){
+ do_log("Shutting down sockets...", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
#ifdef _WIN32
WSACleanup();
#endif
@@ -60,9 +62,14 @@ void EGong_socket_close(SOCKET *sock){
#endif
}
int EGong_socket_open(SOCKET *sock){
+ do_log("Opening UDP-Socket...", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
*sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ #ifdef _WIN32
+ if(*sock==INVALID_SOCKET){
+ #else
if(*sock<0){
- do_log("Couldn't initialize socket",LOG_TYPE_SIGNAL, LOG_LEVEL_ERROR);
+ #endif
+ do_log("Couldn't initialize socket",LOG_TYPE_SOCKET, LOG_LEVEL_ERROR);
EGong_socket_close(sock);
return -1;
}
@@ -86,12 +93,14 @@ int EGong_listener_init(SOCKET *sock, struct EGong_config_server *config){
if(sock==NULL)
sock=&EGong_listen_sock;
+ do_log("Initializing listener...", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
if(EGong_socket_open(sock)<0){
do_log("Couldn't open socket",LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
return -1;
}
#ifdef _WIN32
unsigned long nonblocking_long=1;
+ do_log("Setting socket nonblocking...", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
if (ioctlsocket(*sock, FIONBIO, &nonblocking_long)==SOCKET_ERROR){
do_log("Couldn't set listensocket nonblocking",LOG_TYPE_SIGNAL, LOG_LEVEL_ERROR);
}
@@ -101,7 +110,7 @@ int EGong_listener_init(SOCKET *sock, struct EGong_config_server *config){
EGong_socket_close(sock);
return -2;
}
-
+ do_log("Binding socket...", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
if(bind(*sock, (struct sockaddr *) &listen_server, sizeof(listen_server))<0){
do_log("Couldn't bind to sock", LOG_TYPE_SOCKET, LOG_LEVEL_ERROR);
EGong_socket_close(sock);
@@ -120,13 +129,14 @@ int EGong_listener_get(SOCKET *sock, char *dest, int length, struct sockaddr *so
source=&test;
}
do_log("Receiving on socket...",LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
- ret=recvfrom(*sock,dest,length, flags, source, &size);
#ifdef _WIN32
- if((flags&MSG_PEEK)>0&&ret==-1&&WSAGetLastError()==WSAEMSGSIZE){
+ ret=recvfrom(*sock,dest,length, flags&(~MSG_DONTWAIT), source, &size);
+ if((flags&MSG_PEEK)>0&&ret==SOCKET_ERROR&&WSAGetLastError()==WSAEMSGSIZE){
return length;
}
- else if((flags&MSG_DONTWAIT)>0&&ret==-1&&(WSAGetLastError()==WSAEWOULDBLOCK)) {
+ else if((flags&MSG_DONTWAIT)>0&&ret==SOCKET_ERROR&&(WSAGetLastError()==WSAEWOULDBLOCK)) {
#else
+ ret=recvfrom(*sock,dest,length, flags, source, &size);
if((flags&MSG_DONTWAIT)>0&&ret==-1&&(errno==EAGAIN||errno==EWOULDBLOCK)) {
#endif
return 0;
diff --git a/src/Util/Waiter.c b/src/Util/Waiter.c
@@ -8,16 +8,8 @@
#ifdef _WIN32
#include <winsock2.h>
#endif
-#ifdef USE_GTK
- #include <gtk/gtk.h>
-
- gboolean Egong_waiter_gtk_callback(GIOChannel *source, GIOCondition condition, gpointer data){
- EGong_interface_cycle();
- return G_SOURCE_CONTINUE;
- }
-#endif
-
+int(*EGong_waiter_add)(int, unsigned short int)=&EGong_waiter_add_default;
fd_set EGong_waiter_fds;
unsigned int EGong_waiter_highest_fd;
unsigned int EGong_waiter_cnt=0;
@@ -25,7 +17,7 @@ int EGong_waiter_init(void){
FD_ZERO(&EGong_waiter_fds);
return 0;
}
-int EGong_waiter_add(int sock, unsigned short int type){
+int EGong_waiter_add_default(int sock, unsigned short int type){
EGong_waiter_cnt++;
#ifdef _WIN32
if(type==EGONG_WAITER_FD){
@@ -38,10 +30,6 @@ int EGong_waiter_add(int sock, unsigned short int type){
if(EGong_waiter_highest_fd<sock){
EGong_waiter_highest_fd=sock;
}
- #ifdef USE_GTK
- GIOChannel *new=g_io_channel_unix_new(sock);
- g_io_add_watch(new,G_IO_IN|G_IO_ERR|G_IO_HUP, Egong_waiter_gtk_callback, NULL);
- #endif
return 0;
}
int EGong_waiter_del(int sock){