I don't like the GNU coding style and I'm not sure why I chose it.
This commit changes things over to use 8 space tabs and 'if () {'
style braces.
This commit is contained in:
Ray Strode 2014-05-20 14:40:51 -04:00
parent 5e55bdb33e
commit 85704145ee
112 changed files with 22421 additions and 23820 deletions

File diff suppressed because it is too large Load diff

View file

@ -30,128 +30,128 @@
#include "ply-event-loop.h"
typedef struct _ply_boot_client ply_boot_client_t;
typedef void (* ply_boot_client_response_handler_t) (void *user_data,
ply_boot_client_t *client);
typedef void (* ply_boot_client_answer_handler_t) (void *user_data,
const char *answer,
ply_boot_client_t *client);
typedef void (*ply_boot_client_response_handler_t) (void *user_data,
ply_boot_client_t *client);
typedef void (*ply_boot_client_answer_handler_t) (void *user_data,
const char *answer,
ply_boot_client_t *client);
typedef void (* ply_boot_client_multiple_answers_handler_t) (void *user_data,
const char * const *answers,
ply_boot_client_t *client);
typedef void (* ply_boot_client_disconnect_handler_t) (void *user_data,
ply_boot_client_t *client);
typedef void (*ply_boot_client_multiple_answers_handler_t) (void *user_data,
const char *const *answers,
ply_boot_client_t *client);
typedef void (*ply_boot_client_disconnect_handler_t) (void *user_data,
ply_boot_client_t *client);
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
ply_boot_client_t *ply_boot_client_new (void);
void ply_boot_client_free (ply_boot_client_t *client);
bool ply_boot_client_connect (ply_boot_client_t *client,
ply_boot_client_disconnect_handler_t disconnect_handler,
void *user_data);
void ply_boot_client_ping_daemon (ply_boot_client_t *client,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_update_daemon (ply_boot_client_t *client,
const char *new_status,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_change_mode (ply_boot_client_t *client,
const char *new_mode,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_system_update (ply_boot_client_t *client,
const char *progress,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_to_change_root (ply_boot_client_t *client,
const char *chroot_dir,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_to_display_message (ply_boot_client_t *client,
const char *message,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_to_hide_message (ply_boot_client_t *client,
const char *message,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_ask_daemon_for_password (ply_boot_client_t *client,
const char *prompt,
ply_boot_client_answer_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_ask_daemon_for_cached_passwords (ply_boot_client_t *client,
ply_boot_client_multiple_answers_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_ask_daemon_question (ply_boot_client_t *client,
const char *prompt,
ply_boot_client_answer_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_ask_daemon_to_watch_for_keystroke (ply_boot_client_t *client,
const char *keys,
ply_boot_client_answer_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_ask_daemon_to_ignore_keystroke (ply_boot_client_t *client,
const char *keys,
ply_boot_client_answer_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_system_is_initialized (ply_boot_client_t *client,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_to_show_splash (ply_boot_client_t *client,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_to_hide_splash (ply_boot_client_t *client,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_to_deactivate (ply_boot_client_t *client,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_to_reactivate (ply_boot_client_t *client,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_to_quit (ply_boot_client_t *client,
bool retain_splash,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_to_progress_pause (ply_boot_client_t *client,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_to_progress_unpause (ply_boot_client_t *client,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_ask_daemon_has_active_vt (ply_boot_client_t *client,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
bool ply_boot_client_connect (ply_boot_client_t *client,
ply_boot_client_disconnect_handler_t disconnect_handler,
void *user_data);
void ply_boot_client_ping_daemon (ply_boot_client_t *client,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_update_daemon (ply_boot_client_t *client,
const char *new_status,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_change_mode (ply_boot_client_t *client,
const char *new_mode,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_system_update (ply_boot_client_t *client,
const char *progress,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_to_change_root (ply_boot_client_t *client,
const char *chroot_dir,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_to_display_message (ply_boot_client_t *client,
const char *message,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_to_hide_message (ply_boot_client_t *client,
const char *message,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_ask_daemon_for_password (ply_boot_client_t *client,
const char *prompt,
ply_boot_client_answer_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_ask_daemon_for_cached_passwords (ply_boot_client_t *client,
ply_boot_client_multiple_answers_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_ask_daemon_question (ply_boot_client_t *client,
const char *prompt,
ply_boot_client_answer_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_ask_daemon_to_watch_for_keystroke (ply_boot_client_t *client,
const char *keys,
ply_boot_client_answer_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_ask_daemon_to_ignore_keystroke (ply_boot_client_t *client,
const char *keys,
ply_boot_client_answer_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_system_is_initialized (ply_boot_client_t *client,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_to_show_splash (ply_boot_client_t *client,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_to_hide_splash (ply_boot_client_t *client,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_to_deactivate (ply_boot_client_t *client,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_to_reactivate (ply_boot_client_t *client,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_to_quit (ply_boot_client_t *client,
bool retain_splash,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_to_progress_pause (ply_boot_client_t *client,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_to_progress_unpause (ply_boot_client_t *client,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_ask_daemon_has_active_vt (ply_boot_client_t *client,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_flush (ply_boot_client_t *client);
void ply_boot_client_disconnect (ply_boot_client_t *client);
void ply_boot_client_attach_to_event_loop (ply_boot_client_t *client,
ply_event_loop_t *loop);
void ply_boot_client_tell_daemon_about_error (ply_boot_client_t *client,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
void ply_boot_client_tell_daemon_about_error (ply_boot_client_t *client,
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
#endif

File diff suppressed because it is too large Load diff

View file

@ -36,61 +36,61 @@
typedef enum
{
PLY_BOOT_SPLASH_MODE_BOOT_UP,
PLY_BOOT_SPLASH_MODE_SHUTDOWN,
PLY_BOOT_SPLASH_MODE_UPDATES,
PLY_BOOT_SPLASH_MODE_INVALID
PLY_BOOT_SPLASH_MODE_BOOT_UP,
PLY_BOOT_SPLASH_MODE_SHUTDOWN,
PLY_BOOT_SPLASH_MODE_UPDATES,
PLY_BOOT_SPLASH_MODE_INVALID
} ply_boot_splash_mode_t;
typedef struct _ply_boot_splash_plugin ply_boot_splash_plugin_t;
typedef struct
{
ply_boot_splash_plugin_t * (* create_plugin) (ply_key_file_t *key_file);
void (* destroy_plugin) (ply_boot_splash_plugin_t *plugin);
ply_boot_splash_plugin_t * (*create_plugin)(ply_key_file_t * key_file);
void (*destroy_plugin)(ply_boot_splash_plugin_t *plugin);
void (* set_keyboard) (ply_boot_splash_plugin_t *plugin,
ply_keyboard_t *keyboard);
void (* unset_keyboard) (ply_boot_splash_plugin_t *plugin,
ply_keyboard_t *keyboard);
void (* add_pixel_display) (ply_boot_splash_plugin_t *plugin,
ply_pixel_display_t *display);
void (* remove_pixel_display) (ply_boot_splash_plugin_t *plugin,
ply_pixel_display_t *display);
void (* add_text_display) (ply_boot_splash_plugin_t *plugin,
ply_text_display_t *display);
void (* remove_text_display) (ply_boot_splash_plugin_t *plugin,
ply_text_display_t *display);
bool (* show_splash_screen) (ply_boot_splash_plugin_t *plugin,
ply_event_loop_t *loop,
ply_buffer_t *boot_buffer,
ply_boot_splash_mode_t mode);
void (* system_update) (ply_boot_splash_plugin_t *plugin,
int progress);
void (* update_status) (ply_boot_splash_plugin_t *plugin,
const char *status);
void (* on_boot_output) (ply_boot_splash_plugin_t *plugin,
const char *output,
size_t size);
void (* on_boot_progress) (ply_boot_splash_plugin_t *plugin,
double duration,
double percent_done);
void (* on_root_mounted) (ply_boot_splash_plugin_t *plugin);
void (* hide_splash_screen) (ply_boot_splash_plugin_t *plugin,
ply_event_loop_t *loop);
void (* display_message) (ply_boot_splash_plugin_t *plugin,
const char *message);
void (* hide_message) (ply_boot_splash_plugin_t *plugin,
const char *message);
void (* display_normal) (ply_boot_splash_plugin_t *plugin);
void (* display_password) (ply_boot_splash_plugin_t *plugin,
const char *prompt,
int bullets);
void (* display_question) (ply_boot_splash_plugin_t *plugin,
const char *prompt,
const char *entry_text);
void (* become_idle) (ply_boot_splash_plugin_t *plugin,
ply_trigger_t *idle_trigger);
void (*set_keyboard)(ply_boot_splash_plugin_t *plugin,
ply_keyboard_t *keyboard);
void (*unset_keyboard)(ply_boot_splash_plugin_t *plugin,
ply_keyboard_t *keyboard);
void (*add_pixel_display)(ply_boot_splash_plugin_t *plugin,
ply_pixel_display_t *display);
void (*remove_pixel_display)(ply_boot_splash_plugin_t *plugin,
ply_pixel_display_t *display);
void (*add_text_display)(ply_boot_splash_plugin_t *plugin,
ply_text_display_t *display);
void (*remove_text_display)(ply_boot_splash_plugin_t *plugin,
ply_text_display_t *display);
bool (*show_splash_screen)(ply_boot_splash_plugin_t *plugin,
ply_event_loop_t *loop,
ply_buffer_t *boot_buffer,
ply_boot_splash_mode_t mode);
void (*system_update)(ply_boot_splash_plugin_t *plugin,
int progress);
void (*update_status)(ply_boot_splash_plugin_t *plugin,
const char *status);
void (*on_boot_output)(ply_boot_splash_plugin_t *plugin,
const char *output,
size_t size);
void (*on_boot_progress)(ply_boot_splash_plugin_t *plugin,
double duration,
double percent_done);
void (*on_root_mounted)(ply_boot_splash_plugin_t *plugin);
void (*hide_splash_screen)(ply_boot_splash_plugin_t *plugin,
ply_event_loop_t *loop);
void (*display_message)(ply_boot_splash_plugin_t *plugin,
const char *message);
void (*hide_message)(ply_boot_splash_plugin_t *plugin,
const char *message);
void (*display_normal)(ply_boot_splash_plugin_t *plugin);
void (*display_password)(ply_boot_splash_plugin_t *plugin,
const char *prompt,
int bullets);
void (*display_question)(ply_boot_splash_plugin_t *plugin,
const char *prompt,
const char *entry_text);
void (*become_idle)(ply_boot_splash_plugin_t *plugin,
ply_trigger_t *idle_trigger);
} ply_boot_splash_plugin_interface_t;
#endif /* PLY_BOOT_SPLASH_PLUGIN_H */

File diff suppressed because it is too large Load diff

View file

@ -40,12 +40,12 @@
typedef struct _ply_boot_splash ply_boot_splash_t;
typedef struct _ply_seat ply_seat_t;
typedef void (* ply_boot_splash_on_idle_handler_t) (void *user_data);
typedef void (*ply_boot_splash_on_idle_handler_t) (void *user_data);
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
ply_boot_splash_t *ply_boot_splash_new (const char * theme_path,
const char * plugin_dir,
ply_buffer_t * boot_buffer);
ply_boot_splash_t *ply_boot_splash_new (const char *theme_path,
const char *plugin_dir,
ply_buffer_t *boot_buffer);
bool ply_boot_splash_load (ply_boot_splash_t *splash);
bool ply_boot_splash_load_built_in (ply_boot_splash_t *splash);
@ -55,7 +55,7 @@ void ply_boot_splash_attach_to_seat (ply_boot_splash_t *splash,
void ply_boot_splash_detach_from_seat (ply_boot_splash_t *splash,
ply_seat_t *seat);
void ply_boot_splash_free (ply_boot_splash_t *splash);
bool ply_boot_splash_show (ply_boot_splash_t *splash,
bool ply_boot_splash_show (ply_boot_splash_t *splash,
ply_boot_splash_mode_t mode);
bool ply_boot_splash_system_update (ply_boot_splash_t *splash,
int progress);
@ -70,7 +70,7 @@ void ply_boot_splash_display_message (ply_boot_splash_t *splash,
void ply_boot_splash_hide_message (ply_boot_splash_t *splash,
const char *message);
void ply_boot_splash_hide (ply_boot_splash_t *splash);
void ply_boot_splash_display_normal (ply_boot_splash_t *splash);
void ply_boot_splash_display_normal (ply_boot_splash_t *splash);
void ply_boot_splash_display_password (ply_boot_splash_t *splash,
const char *prompt,
int bullets);
@ -81,9 +81,9 @@ void ply_boot_splash_attach_to_event_loop (ply_boot_splash_t *splash,
ply_event_loop_t *loop);
void ply_boot_splash_attach_progress (ply_boot_splash_t *splash,
ply_progress_t *progress);
void ply_boot_splash_become_idle (ply_boot_splash_t *splash,
ply_boot_splash_on_idle_handler_t idle_handler,
void *user_data);
void ply_boot_splash_become_idle (ply_boot_splash_t *splash,
ply_boot_splash_on_idle_handler_t idle_handler,
void *user_data);
#endif

File diff suppressed because it is too large Load diff

View file

@ -25,22 +25,24 @@
typedef enum
{
PLY_DEVICE_MANAGER_FLAGS_NONE = 0,
PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES = 1 << 0,
PLY_DEVICE_MANAGER_FLAGS_IGNORE_UDEV = 1 << 1
PLY_DEVICE_MANAGER_FLAGS_NONE = 0,
PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES = 1 << 0,
PLY_DEVICE_MANAGER_FLAGS_IGNORE_UDEV = 1 << 1
} ply_device_manager_flags_t;
typedef struct _ply_device_manager ply_device_manager_t;
typedef void (* ply_seat_added_handler_t) (void *, ply_seat_t *);
typedef void (* ply_seat_removed_handler_t) (void *, ply_seat_t *);
typedef void (*ply_seat_added_handler_t) (void *,
ply_seat_t *);
typedef void (*ply_seat_removed_handler_t) (void *,
ply_seat_t *);
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
ply_device_manager_t *ply_device_manager_new (const char *default_tty,
ply_device_manager_flags_t flags);
void ply_device_manager_watch_seats (ply_device_manager_t *manager,
ply_seat_added_handler_t seat_added_handler,
ply_device_manager_t *ply_device_manager_new (const char *default_tty,
ply_device_manager_flags_t flags);
void ply_device_manager_watch_seats (ply_device_manager_t *manager,
ply_seat_added_handler_t seat_added_handler,
ply_seat_removed_handler_t seat_removed_handler,
void *data);
void *data);
bool ply_device_manager_has_open_seats (ply_device_manager_t *manager);
ply_list_t *ply_device_manager_get_seats (ply_device_manager_t *manager);
void ply_device_manager_free (ply_device_manager_t *manager);

View file

@ -41,57 +41,58 @@
#include "ply-terminal.h"
#include "ply-utils.h"
#define KEY_CTRL_U ('\100' ^'U')
#define KEY_CTRL_W ('\100' ^'W')
#define KEY_CTRL_V ('\100' ^'V')
#define KEY_ESCAPE ('\100' ^'[')
#define KEY_CTRL_U ('\100' ^ 'U')
#define KEY_CTRL_W ('\100' ^ 'W')
#define KEY_CTRL_V ('\100' ^ 'V')
#define KEY_ESCAPE ('\100' ^ '[')
#define KEY_RETURN '\n'
#define KEY_BACKSPACE '\177'
typedef void (* ply_keyboard_handler_t) (void *);
typedef void (*ply_keyboard_handler_t) (void *);
typedef struct
{
ply_keyboard_handler_t function;
void *user_data;
ply_keyboard_handler_t function;
void *user_data;
} ply_keyboard_closure_t;
typedef enum
{
PLY_KEYBOARD_PROVIDER_TYPE_TERMINAL,
PLY_KEYBOARD_PROVIDER_TYPE_RENDERER
PLY_KEYBOARD_PROVIDER_TYPE_TERMINAL,
PLY_KEYBOARD_PROVIDER_TYPE_RENDERER
} ply_keyboard_provider_type_t;
typedef struct
{
ply_terminal_t *terminal;
ply_buffer_t *key_buffer;
ply_terminal_t *terminal;
ply_buffer_t *key_buffer;
} ply_keyboard_terminal_provider_t;
typedef struct
{
ply_renderer_t *renderer;
ply_renderer_input_source_t *input_source;
ply_renderer_t *renderer;
ply_renderer_input_source_t *input_source;
} ply_keyboard_renderer_provider_t;
typedef union {
ply_keyboard_renderer_provider_t *if_renderer;
ply_keyboard_terminal_provider_t *if_terminal;
typedef union
{
ply_keyboard_renderer_provider_t *if_renderer;
ply_keyboard_terminal_provider_t *if_terminal;
} ply_keyboard_provider_t;
struct _ply_keyboard
{
ply_event_loop_t *loop;
ply_event_loop_t *loop;
ply_keyboard_provider_type_t provider_type;
ply_keyboard_provider_t provider;
ply_keyboard_provider_type_t provider_type;
ply_keyboard_provider_t provider;
ply_buffer_t *line_buffer;
ply_buffer_t *line_buffer;
ply_list_t *keyboard_input_handler_list;
ply_list_t *backspace_handler_list;
ply_list_t *escape_handler_list;
ply_list_t *enter_handler_list;
ply_list_t *keyboard_input_handler_list;
ply_list_t *backspace_handler_list;
ply_list_t *escape_handler_list;
ply_list_t *enter_handler_list;
};
static bool ply_keyboard_watch_for_terminal_input (ply_keyboard_t *keyboard);
@ -99,495 +100,473 @@ static bool ply_keyboard_watch_for_terminal_input (ply_keyboard_t *keyboard);
ply_keyboard_t *
ply_keyboard_new_for_terminal (ply_terminal_t *terminal)
{
ply_keyboard_t *keyboard;
ply_keyboard_t *keyboard;
keyboard = calloc (1, sizeof (ply_keyboard_t));
keyboard->line_buffer = ply_buffer_new ();
keyboard->keyboard_input_handler_list = ply_list_new ();
keyboard->backspace_handler_list = ply_list_new ();
keyboard->escape_handler_list = ply_list_new ();
keyboard->enter_handler_list = ply_list_new ();
keyboard->provider_type = PLY_KEYBOARD_PROVIDER_TYPE_TERMINAL;
keyboard->provider.if_terminal = calloc (1, sizeof (ply_keyboard_terminal_provider_t));
keyboard->provider.if_terminal->terminal = terminal;
keyboard->provider.if_terminal->key_buffer = ply_buffer_new ();
keyboard = calloc (1, sizeof(ply_keyboard_t));
keyboard->line_buffer = ply_buffer_new ();
keyboard->keyboard_input_handler_list = ply_list_new ();
keyboard->backspace_handler_list = ply_list_new ();
keyboard->escape_handler_list = ply_list_new ();
keyboard->enter_handler_list = ply_list_new ();
keyboard->provider_type = PLY_KEYBOARD_PROVIDER_TYPE_TERMINAL;
keyboard->provider.if_terminal = calloc (1, sizeof(ply_keyboard_terminal_provider_t));
keyboard->provider.if_terminal->terminal = terminal;
keyboard->provider.if_terminal->key_buffer = ply_buffer_new ();
keyboard->loop = ply_event_loop_get_default ();
keyboard->loop = ply_event_loop_get_default ();
return keyboard;
return keyboard;
}
ply_keyboard_t *
ply_keyboard_new_for_renderer (ply_renderer_t *renderer)
{
ply_keyboard_t *keyboard;
ply_renderer_input_source_t *input_source;
ply_keyboard_t *keyboard;
ply_renderer_input_source_t *input_source;
keyboard = calloc (1, sizeof (ply_keyboard_t));
keyboard->line_buffer = ply_buffer_new ();
keyboard->keyboard_input_handler_list = ply_list_new ();
keyboard->backspace_handler_list = ply_list_new ();
keyboard->escape_handler_list = ply_list_new ();
keyboard->enter_handler_list = ply_list_new ();
keyboard->provider_type = PLY_KEYBOARD_PROVIDER_TYPE_RENDERER;
keyboard->provider.if_renderer = calloc (1, sizeof (ply_keyboard_renderer_provider_t));
keyboard->provider.if_renderer->renderer = renderer;
keyboard = calloc (1, sizeof(ply_keyboard_t));
keyboard->line_buffer = ply_buffer_new ();
keyboard->keyboard_input_handler_list = ply_list_new ();
keyboard->backspace_handler_list = ply_list_new ();
keyboard->escape_handler_list = ply_list_new ();
keyboard->enter_handler_list = ply_list_new ();
keyboard->provider_type = PLY_KEYBOARD_PROVIDER_TYPE_RENDERER;
keyboard->provider.if_renderer = calloc (1, sizeof(ply_keyboard_renderer_provider_t));
keyboard->provider.if_renderer->renderer = renderer;
input_source = ply_renderer_get_input_source (renderer);
input_source = ply_renderer_get_input_source (renderer);
keyboard->provider.if_renderer->input_source = input_source;
keyboard->provider.if_renderer->input_source = input_source;
keyboard->loop = ply_event_loop_get_default ();
keyboard->loop = ply_event_loop_get_default ();
return keyboard;
return keyboard;
}
static void
process_backspace (ply_keyboard_t *keyboard)
{
size_t bytes_to_remove;
ssize_t previous_character_size;
const char *bytes;
size_t size;
ply_list_node_t *node;
size_t bytes_to_remove;
ssize_t previous_character_size;
const char *bytes;
size_t size;
ply_list_node_t *node;
bytes = ply_buffer_get_bytes (keyboard->line_buffer);
size = ply_buffer_get_size (keyboard->line_buffer);
bytes = ply_buffer_get_bytes (keyboard->line_buffer);
size = ply_buffer_get_size (keyboard->line_buffer);
bytes_to_remove = MIN (size, PLY_UTF8_CHARACTER_SIZE_MAX);
while ((previous_character_size = ply_utf8_character_get_size (bytes + size - bytes_to_remove, bytes_to_remove)) < (ssize_t) bytes_to_remove)
{
if (previous_character_size > 0)
bytes_to_remove -= previous_character_size;
else
bytes_to_remove--;
}
bytes_to_remove = MIN (size, PLY_UTF8_CHARACTER_SIZE_MAX);
while ((previous_character_size = ply_utf8_character_get_size (bytes + size - bytes_to_remove, bytes_to_remove)) < (ssize_t) bytes_to_remove) {
if (previous_character_size > 0)
bytes_to_remove -= previous_character_size;
else
bytes_to_remove--;
}
if (bytes_to_remove <= size)
ply_buffer_remove_bytes_at_end (keyboard->line_buffer, bytes_to_remove);
if (bytes_to_remove <= size)
ply_buffer_remove_bytes_at_end (keyboard->line_buffer, bytes_to_remove);
for (node = ply_list_get_first_node(keyboard->backspace_handler_list);
node; node = ply_list_get_next_node(keyboard->backspace_handler_list, node))
{
ply_keyboard_closure_t *closure = ply_list_node_get_data (node);
ply_keyboard_backspace_handler_t backspace_handler =
(ply_keyboard_backspace_handler_t) closure->function;
backspace_handler (closure->user_data);
}
for (node = ply_list_get_first_node (keyboard->backspace_handler_list);
node; node = ply_list_get_next_node (keyboard->backspace_handler_list, node)) {
ply_keyboard_closure_t *closure = ply_list_node_get_data (node);
ply_keyboard_backspace_handler_t backspace_handler =
(ply_keyboard_backspace_handler_t) closure->function;
backspace_handler (closure->user_data);
}
}
static void
process_line_erase (ply_keyboard_t *keyboard)
{
size_t size;
size_t size;
while ((size = ply_buffer_get_size (keyboard->line_buffer)) > 0)
process_backspace (keyboard);
while ((size = ply_buffer_get_size (keyboard->line_buffer)) > 0) {
process_backspace (keyboard);
}
}
static void
process_keyboard_input (ply_keyboard_t *keyboard,
const char *keyboard_input,
size_t character_size)
const char *keyboard_input,
size_t character_size)
{
wchar_t key;
ply_list_node_t *node;
wchar_t key;
ply_list_node_t *node;
if ((ssize_t) mbrtowc (&key, keyboard_input, character_size, NULL) > 0)
{
switch (key)
{
case KEY_CTRL_U:
case KEY_CTRL_W:
ply_trace ("erase line!");
process_line_erase (keyboard);
return;
if ((ssize_t) mbrtowc (&key, keyboard_input, character_size, NULL) > 0) {
switch (key) {
case KEY_CTRL_U:
case KEY_CTRL_W:
ply_trace ("erase line!");
process_line_erase (keyboard);
return;
case KEY_CTRL_V:
ply_trace ("toggle verbose mode!");
ply_toggle_tracing ();
ply_trace ("verbose mode toggled!");
return;
case KEY_CTRL_V:
ply_trace ("toggle verbose mode!");
ply_toggle_tracing ();
ply_trace ("verbose mode toggled!");
return;
case KEY_ESCAPE:
ply_trace ("escape key!");
for (node = ply_list_get_first_node(keyboard->escape_handler_list);
node; node = ply_list_get_next_node(keyboard->escape_handler_list, node))
{
ply_keyboard_closure_t *closure = ply_list_node_get_data (node);
ply_keyboard_escape_handler_t escape_handler = (ply_keyboard_escape_handler_t) closure->function;
escape_handler (closure->user_data);
}
case KEY_ESCAPE:
ply_trace ("escape key!");
for (node = ply_list_get_first_node (keyboard->escape_handler_list);
node; node = ply_list_get_next_node (keyboard->escape_handler_list, node)) {
ply_keyboard_closure_t *closure = ply_list_node_get_data (node);
ply_keyboard_escape_handler_t escape_handler = (ply_keyboard_escape_handler_t) closure->function;
escape_handler (closure->user_data);
}
ply_trace ("end escape key handler");
return;
ply_trace ("end escape key handler");
return;
case KEY_BACKSPACE:
ply_trace ("backspace key!");
process_backspace (keyboard);
return;
case KEY_BACKSPACE:
ply_trace ("backspace key!");
process_backspace (keyboard);
return;
case KEY_RETURN:
ply_trace ("return key!");
case KEY_RETURN:
ply_trace ("return key!");
for (node = ply_list_get_first_node(keyboard->enter_handler_list);
node; node = ply_list_get_next_node(keyboard->enter_handler_list, node))
{
ply_keyboard_closure_t *closure = ply_list_node_get_data (node);
ply_keyboard_enter_handler_t enter_handler = (ply_keyboard_enter_handler_t) closure->function;
enter_handler (closure->user_data, ply_buffer_get_bytes (keyboard->line_buffer));
}
ply_buffer_clear (keyboard->line_buffer);
return;
for (node = ply_list_get_first_node (keyboard->enter_handler_list);
node; node = ply_list_get_next_node (keyboard->enter_handler_list, node)) {
ply_keyboard_closure_t *closure = ply_list_node_get_data (node);
ply_keyboard_enter_handler_t enter_handler = (ply_keyboard_enter_handler_t) closure->function;
enter_handler (closure->user_data, ply_buffer_get_bytes (keyboard->line_buffer));
}
ply_buffer_clear (keyboard->line_buffer);
return;
default:
ply_buffer_append_bytes (keyboard->line_buffer,
keyboard_input, character_size);
break;
default:
ply_buffer_append_bytes (keyboard->line_buffer,
keyboard_input, character_size);
break;
}
}
}
for (node = ply_list_get_first_node(keyboard->keyboard_input_handler_list);
node; node = ply_list_get_next_node(keyboard->keyboard_input_handler_list, node))
{
ply_keyboard_closure_t *closure = ply_list_node_get_data (node);
ply_keyboard_input_handler_t keyboard_input_handler =
(ply_keyboard_input_handler_t) closure->function;
for (node = ply_list_get_first_node (keyboard->keyboard_input_handler_list);
node; node = ply_list_get_next_node (keyboard->keyboard_input_handler_list, node)) {
ply_keyboard_closure_t *closure = ply_list_node_get_data (node);
ply_keyboard_input_handler_t keyboard_input_handler =
(ply_keyboard_input_handler_t) closure->function;
keyboard_input_handler (closure->user_data,
keyboard_input, character_size);
}
keyboard_input_handler (closure->user_data,
keyboard_input, character_size);
}
}
static void
on_key_event (ply_keyboard_t *keyboard,
ply_buffer_t *buffer)
on_key_event (ply_keyboard_t *keyboard,
ply_buffer_t *buffer)
{
const char *bytes;
size_t size, i;
const char *bytes;
size_t size, i;
bytes = ply_buffer_get_bytes (buffer);
size = ply_buffer_get_size (buffer);
bytes = ply_buffer_get_bytes (buffer);
size = ply_buffer_get_size (buffer);
i = 0;
while (i < size)
{
ssize_t character_size;
char *keyboard_input;
i = 0;
while (i < size) {
ssize_t character_size;
char *keyboard_input;
character_size = (ssize_t) ply_utf8_character_get_size (bytes + i, size - i);
character_size = (ssize_t) ply_utf8_character_get_size (bytes + i, size - i);
if (character_size < 0)
break;
if (character_size < 0)
break;
/* If we're at a NUL character walk through it
*/
if (character_size == 0)
{
i++;
continue;
/* If we're at a NUL character walk through it
*/
if (character_size == 0) {
i++;
continue;
}
keyboard_input = strndup (bytes + i, character_size);
process_keyboard_input (keyboard, keyboard_input, character_size);
i += character_size;
free (keyboard_input);
}
keyboard_input = strndup (bytes + i, character_size);
process_keyboard_input (keyboard, keyboard_input, character_size);
i += character_size;
free (keyboard_input);
}
if (i > 0)
ply_buffer_remove_bytes (buffer, i);
if (i > 0)
ply_buffer_remove_bytes (buffer, i);
}
static bool
ply_keyboard_watch_for_renderer_input (ply_keyboard_t *keyboard)
{
assert (keyboard != NULL);
assert (keyboard != NULL);
if (!ply_renderer_open_input_source (keyboard->provider.if_renderer->renderer,
keyboard->provider.if_renderer->input_source))
return false;
if (!ply_renderer_open_input_source (keyboard->provider.if_renderer->renderer,
keyboard->provider.if_renderer->input_source))
return false;
ply_renderer_set_handler_for_input_source (keyboard->provider.if_renderer->renderer,
keyboard->provider.if_renderer->input_source,
(ply_renderer_input_source_handler_t)
on_key_event,
keyboard);
return true;
ply_renderer_set_handler_for_input_source (keyboard->provider.if_renderer->renderer,
keyboard->provider.if_renderer->input_source,
(ply_renderer_input_source_handler_t)
on_key_event,
keyboard);
return true;
}
static void
ply_keyboard_stop_watching_for_renderer_input (ply_keyboard_t *keyboard)
{
ply_renderer_set_handler_for_input_source (keyboard->provider.if_renderer->renderer,
keyboard->provider.if_renderer->input_source,
(ply_renderer_input_source_handler_t)
NULL, NULL);
ply_renderer_set_handler_for_input_source (keyboard->provider.if_renderer->renderer,
keyboard->provider.if_renderer->input_source,
(ply_renderer_input_source_handler_t)
NULL, NULL);
ply_renderer_close_input_source (keyboard->provider.if_renderer->renderer,
keyboard->provider.if_renderer->input_source);
ply_renderer_close_input_source (keyboard->provider.if_renderer->renderer,
keyboard->provider.if_renderer->input_source);
}
static void
on_terminal_data (ply_keyboard_t *keyboard)
{
int terminal_fd;
int terminal_fd;
terminal_fd = ply_terminal_get_fd (keyboard->provider.if_terminal->terminal);
ply_buffer_append_from_fd (keyboard->provider.if_terminal->key_buffer,
terminal_fd);
on_key_event (keyboard, keyboard->provider.if_terminal->key_buffer);
terminal_fd = ply_terminal_get_fd (keyboard->provider.if_terminal->terminal);
ply_buffer_append_from_fd (keyboard->provider.if_terminal->key_buffer,
terminal_fd);
on_key_event (keyboard, keyboard->provider.if_terminal->key_buffer);
}
static bool
ply_keyboard_watch_for_terminal_input (ply_keyboard_t *keyboard)
{
int terminal_fd;
int terminal_fd;
assert (keyboard != NULL);
assert (keyboard != NULL);
terminal_fd = ply_terminal_get_fd (keyboard->provider.if_terminal->terminal);
terminal_fd = ply_terminal_get_fd (keyboard->provider.if_terminal->terminal);
if (terminal_fd < 0 || !ply_terminal_is_open (keyboard->provider.if_terminal->terminal))
{
ply_trace ("terminal associated with keyboard isn't open");
return false;
}
if (terminal_fd < 0 || !ply_terminal_is_open (keyboard->provider.if_terminal->terminal)) {
ply_trace ("terminal associated with keyboard isn't open");
return false;
}
ply_terminal_watch_for_input (keyboard->provider.if_terminal->terminal,
(ply_terminal_input_handler_t) on_terminal_data,
keyboard);
ply_terminal_watch_for_input (keyboard->provider.if_terminal->terminal,
(ply_terminal_input_handler_t) on_terminal_data,
keyboard);
return true;
return true;
}
static void
ply_keyboard_stop_watching_for_terminal_input (ply_keyboard_t *keyboard)
{
ply_terminal_stop_watching_for_input (keyboard->provider.if_terminal->terminal,
(ply_terminal_input_handler_t)
on_terminal_data,
keyboard);
ply_terminal_stop_watching_for_input (keyboard->provider.if_terminal->terminal,
(ply_terminal_input_handler_t)
on_terminal_data,
keyboard);
}
bool
ply_keyboard_watch_for_input (ply_keyboard_t *keyboard)
{
assert (keyboard != NULL);
assert (keyboard != NULL);
switch (keyboard->provider_type)
{
case PLY_KEYBOARD_PROVIDER_TYPE_RENDERER:
return ply_keyboard_watch_for_renderer_input (keyboard);
switch (keyboard->provider_type) {
case PLY_KEYBOARD_PROVIDER_TYPE_RENDERER:
return ply_keyboard_watch_for_renderer_input (keyboard);
case PLY_KEYBOARD_PROVIDER_TYPE_TERMINAL:
return ply_keyboard_watch_for_terminal_input (keyboard);
}
case PLY_KEYBOARD_PROVIDER_TYPE_TERMINAL:
return ply_keyboard_watch_for_terminal_input (keyboard);
}
return false;
return false;
}
void
ply_keyboard_stop_watching_for_input (ply_keyboard_t *keyboard)
{
assert (keyboard != NULL);
assert (keyboard != NULL);
switch (keyboard->provider_type)
{
case PLY_KEYBOARD_PROVIDER_TYPE_RENDERER:
ply_keyboard_stop_watching_for_renderer_input (keyboard);
break;
case PLY_KEYBOARD_PROVIDER_TYPE_TERMINAL:
ply_keyboard_stop_watching_for_terminal_input (keyboard);
break;
}
switch (keyboard->provider_type) {
case PLY_KEYBOARD_PROVIDER_TYPE_RENDERER:
ply_keyboard_stop_watching_for_renderer_input (keyboard);
break;
case PLY_KEYBOARD_PROVIDER_TYPE_TERMINAL:
ply_keyboard_stop_watching_for_terminal_input (keyboard);
break;
}
}
void
ply_keyboard_free (ply_keyboard_t *keyboard)
{
if (keyboard == NULL)
return;
if (keyboard == NULL)
return;
ply_keyboard_stop_watching_for_input (keyboard);
ply_keyboard_stop_watching_for_input (keyboard);
ply_buffer_free (keyboard->line_buffer);
ply_buffer_free (keyboard->line_buffer);
if (keyboard->provider_type == PLY_KEYBOARD_PROVIDER_TYPE_RENDERER)
{
free (keyboard->provider.if_renderer);
}
else
{
ply_buffer_free (keyboard->provider.if_terminal->key_buffer);
free (keyboard->provider.if_terminal);
}
if (keyboard->provider_type == PLY_KEYBOARD_PROVIDER_TYPE_RENDERER) {
free (keyboard->provider.if_renderer);
} else {
ply_buffer_free (keyboard->provider.if_terminal->key_buffer);
free (keyboard->provider.if_terminal);
}
free (keyboard);
free (keyboard);
}
static ply_keyboard_closure_t *
ply_keyboard_closure_new (ply_keyboard_handler_t function,
void *user_data)
ply_keyboard_closure_new (ply_keyboard_handler_t function,
void *user_data)
{
ply_keyboard_closure_t *closure = calloc (1, sizeof (ply_keyboard_closure_t));
closure->function = function;
closure->user_data = user_data;
return closure;
ply_keyboard_closure_t *closure = calloc (1, sizeof(ply_keyboard_closure_t));
closure->function = function;
closure->user_data = user_data;
return closure;
}
static void
ply_keyboard_closure_free (ply_keyboard_closure_t *closure)
{
free (closure);
free (closure);
}
void
ply_keyboard_add_input_handler (ply_keyboard_t *keyboard,
ply_keyboard_input_handler_t input_handler,
void *user_data)
ply_keyboard_add_input_handler (ply_keyboard_t *keyboard,
ply_keyboard_input_handler_t input_handler,
void *user_data)
{
ply_keyboard_closure_t *closure;
ply_keyboard_closure_t *closure;
assert (keyboard != NULL);
assert (keyboard != NULL);
closure = ply_keyboard_closure_new ((ply_keyboard_handler_t) input_handler,
user_data);
ply_list_append_data (keyboard->keyboard_input_handler_list, closure);
closure = ply_keyboard_closure_new ((ply_keyboard_handler_t) input_handler,
user_data);
ply_list_append_data (keyboard->keyboard_input_handler_list, closure);
}
void
ply_keyboard_remove_input_handler (ply_keyboard_t *keyboard,
ply_keyboard_input_handler_t input_handler)
ply_keyboard_remove_input_handler (ply_keyboard_t *keyboard,
ply_keyboard_input_handler_t input_handler)
{
ply_list_node_t *node;
ply_list_node_t *node;
assert (keyboard != NULL);
assert (keyboard != NULL);
for (node = ply_list_get_first_node(keyboard->keyboard_input_handler_list);
node; node = ply_list_get_next_node(keyboard->keyboard_input_handler_list, node))
{
ply_keyboard_closure_t *closure = ply_list_node_get_data (node);
if ((ply_keyboard_input_handler_t) closure->function == input_handler)
{
ply_keyboard_closure_free (closure);
ply_list_remove_node (keyboard->keyboard_input_handler_list, node);
return;
for (node = ply_list_get_first_node (keyboard->keyboard_input_handler_list);
node; node = ply_list_get_next_node (keyboard->keyboard_input_handler_list, node)) {
ply_keyboard_closure_t *closure = ply_list_node_get_data (node);
if ((ply_keyboard_input_handler_t) closure->function == input_handler) {
ply_keyboard_closure_free (closure);
ply_list_remove_node (keyboard->keyboard_input_handler_list, node);
return;
}
}
}
}
void
ply_keyboard_add_backspace_handler (ply_keyboard_t *keyboard,
ply_keyboard_backspace_handler_t backspace_handler,
void *user_data)
ply_keyboard_add_backspace_handler (ply_keyboard_t *keyboard,
ply_keyboard_backspace_handler_t backspace_handler,
void *user_data)
{
ply_keyboard_closure_t *closure;
ply_keyboard_closure_t *closure;
assert (keyboard != NULL);
assert (keyboard != NULL);
closure = ply_keyboard_closure_new ((ply_keyboard_handler_t) backspace_handler,
user_data);
ply_list_append_data (keyboard->backspace_handler_list, closure);
closure = ply_keyboard_closure_new ((ply_keyboard_handler_t) backspace_handler,
user_data);
ply_list_append_data (keyboard->backspace_handler_list, closure);
}
void
ply_keyboard_remove_backspace_handler (ply_keyboard_t *keyboard,
ply_keyboard_backspace_handler_t backspace_handler)
ply_keyboard_remove_backspace_handler (ply_keyboard_t *keyboard,
ply_keyboard_backspace_handler_t backspace_handler)
{
ply_list_node_t *node;
ply_list_node_t *node;
assert (keyboard != NULL);
assert (keyboard != NULL);
for (node = ply_list_get_first_node(keyboard->backspace_handler_list);
node; node = ply_list_get_next_node(keyboard->backspace_handler_list, node))
{
ply_keyboard_closure_t *closure = ply_list_node_get_data (node);
if ((ply_keyboard_backspace_handler_t) closure->function == backspace_handler)
{
ply_keyboard_closure_free (closure);
ply_list_remove_node (keyboard->backspace_handler_list, node);
return;
for (node = ply_list_get_first_node (keyboard->backspace_handler_list);
node; node = ply_list_get_next_node (keyboard->backspace_handler_list, node)) {
ply_keyboard_closure_t *closure = ply_list_node_get_data (node);
if ((ply_keyboard_backspace_handler_t) closure->function == backspace_handler) {
ply_keyboard_closure_free (closure);
ply_list_remove_node (keyboard->backspace_handler_list, node);
return;
}
}
}
}
void
ply_keyboard_add_escape_handler (ply_keyboard_t *keyboard,
ply_keyboard_escape_handler_t escape_handler,
void *user_data)
ply_keyboard_add_escape_handler (ply_keyboard_t *keyboard,
ply_keyboard_escape_handler_t escape_handler,
void *user_data)
{
ply_keyboard_closure_t *closure;
ply_keyboard_closure_t *closure;
assert (keyboard != NULL);
assert (keyboard != NULL);
closure = ply_keyboard_closure_new ((ply_keyboard_handler_t) escape_handler,
user_data);
ply_list_append_data (keyboard->escape_handler_list, closure);
closure = ply_keyboard_closure_new ((ply_keyboard_handler_t) escape_handler,
user_data);
ply_list_append_data (keyboard->escape_handler_list, closure);
}
void
ply_keyboard_remove_escape_handler (ply_keyboard_t *keyboard,
ply_keyboard_escape_handler_t escape_handler)
ply_keyboard_remove_escape_handler (ply_keyboard_t *keyboard,
ply_keyboard_escape_handler_t escape_handler)
{
ply_list_node_t *node;
ply_list_node_t *node;
assert (keyboard != NULL);
assert (keyboard != NULL);
for (node = ply_list_get_first_node(keyboard->escape_handler_list);
node; node = ply_list_get_next_node(keyboard->escape_handler_list, node))
{
ply_keyboard_closure_t *closure = ply_list_node_get_data (node);
if ((ply_keyboard_escape_handler_t) closure->function == escape_handler)
{
ply_keyboard_closure_free (closure);
ply_list_remove_node (keyboard->escape_handler_list, node);
return;
for (node = ply_list_get_first_node (keyboard->escape_handler_list);
node; node = ply_list_get_next_node (keyboard->escape_handler_list, node)) {
ply_keyboard_closure_t *closure = ply_list_node_get_data (node);
if ((ply_keyboard_escape_handler_t) closure->function == escape_handler) {
ply_keyboard_closure_free (closure);
ply_list_remove_node (keyboard->escape_handler_list, node);
return;
}
}
}
}
void
ply_keyboard_add_enter_handler (ply_keyboard_t *keyboard,
ply_keyboard_enter_handler_t enter_handler,
void *user_data)
ply_keyboard_add_enter_handler (ply_keyboard_t *keyboard,
ply_keyboard_enter_handler_t enter_handler,
void *user_data)
{
ply_keyboard_closure_t *closure;
ply_keyboard_closure_t *closure;
assert (keyboard != NULL);
assert (keyboard != NULL);
closure = ply_keyboard_closure_new ((ply_keyboard_handler_t) enter_handler,
user_data);
closure = ply_keyboard_closure_new ((ply_keyboard_handler_t) enter_handler,
user_data);
ply_list_append_data (keyboard->enter_handler_list, closure);
ply_list_append_data (keyboard->enter_handler_list, closure);
}
void
ply_keyboard_remove_enter_handler (ply_keyboard_t *keyboard,
ply_keyboard_enter_handler_t enter_handler)
ply_keyboard_remove_enter_handler (ply_keyboard_t *keyboard,
ply_keyboard_enter_handler_t enter_handler)
{
ply_list_node_t *node;
ply_list_node_t *node;
assert (keyboard != NULL);
assert (keyboard != NULL);
for (node = ply_list_get_first_node(keyboard->enter_handler_list);
node; node = ply_list_get_next_node(keyboard->enter_handler_list, node))
{
ply_keyboard_closure_t *closure = ply_list_node_get_data (node);
if ((ply_keyboard_enter_handler_t) closure->function == enter_handler)
{
ply_keyboard_closure_free (closure);
ply_list_remove_node (keyboard->enter_handler_list, node);
return;
for (node = ply_list_get_first_node (keyboard->enter_handler_list);
node; node = ply_list_get_next_node (keyboard->enter_handler_list, node)) {
ply_keyboard_closure_t *closure = ply_list_node_get_data (node);
if ((ply_keyboard_enter_handler_t) closure->function == enter_handler) {
ply_keyboard_closure_free (closure);
ply_list_remove_node (keyboard->enter_handler_list, node);
return;
}
}
}
}
/* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */

View file

@ -32,42 +32,42 @@
typedef struct _ply_keyboard ply_keyboard_t;
typedef void (* ply_keyboard_input_handler_t) (void *user_data,
const char *keyboard_input,
size_t character_size);
typedef void (*ply_keyboard_input_handler_t) (void *user_data,
const char *keyboard_input,
size_t character_size);
typedef void (* ply_keyboard_backspace_handler_t) (void *user_data);
typedef void (*ply_keyboard_backspace_handler_t) (void *user_data);
typedef void (* ply_keyboard_escape_handler_t) (void *user_data);
typedef void (*ply_keyboard_escape_handler_t) (void *user_data);
typedef void (* ply_keyboard_enter_handler_t) (void *user_data,
const char *line);
typedef void (*ply_keyboard_enter_handler_t) (void *user_data,
const char *line);
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
ply_keyboard_t *ply_keyboard_new_for_terminal (ply_terminal_t *terminal);
ply_keyboard_t *ply_keyboard_new_for_renderer (ply_renderer_t *renderer);
void ply_keyboard_free (ply_keyboard_t *keyboard);
void ply_keyboard_add_input_handler (ply_keyboard_t *keyboard,
ply_keyboard_input_handler_t input_handler,
void *user_data);
void ply_keyboard_remove_input_handler (ply_keyboard_t *keyboard,
ply_keyboard_input_handler_t input_handler);
void ply_keyboard_add_backspace_handler (ply_keyboard_t *keyboard,
ply_keyboard_backspace_handler_t backspace_handler,
void *user_data);
void ply_keyboard_remove_backspace_handler (ply_keyboard_t *keyboard,
ply_keyboard_backspace_handler_t backspace_handler);
void ply_keyboard_add_escape_handler (ply_keyboard_t *keyboard,
ply_keyboard_escape_handler_t escape_handler,
void *user_data);
void ply_keyboard_remove_escape_handler (ply_keyboard_t *keyboard,
ply_keyboard_escape_handler_t escape_handler);
void ply_keyboard_add_enter_handler (ply_keyboard_t *keyboard,
ply_keyboard_enter_handler_t enter_handler,
void *user_data);
void ply_keyboard_remove_enter_handler (ply_keyboard_t *keyboard,
ply_keyboard_enter_handler_t enter_handler);
void ply_keyboard_add_input_handler (ply_keyboard_t *keyboard,
ply_keyboard_input_handler_t input_handler,
void *user_data);
void ply_keyboard_remove_input_handler (ply_keyboard_t *keyboard,
ply_keyboard_input_handler_t input_handler);
void ply_keyboard_add_backspace_handler (ply_keyboard_t *keyboard,
ply_keyboard_backspace_handler_t backspace_handler,
void *user_data);
void ply_keyboard_remove_backspace_handler (ply_keyboard_t *keyboard,
ply_keyboard_backspace_handler_t backspace_handler);
void ply_keyboard_add_escape_handler (ply_keyboard_t *keyboard,
ply_keyboard_escape_handler_t escape_handler,
void *user_data);
void ply_keyboard_remove_escape_handler (ply_keyboard_t *keyboard,
ply_keyboard_escape_handler_t escape_handler);
void ply_keyboard_add_enter_handler (ply_keyboard_t *keyboard,
ply_keyboard_enter_handler_t enter_handler,
void *user_data);
void ply_keyboard_remove_enter_handler (ply_keyboard_t *keyboard,
ply_keyboard_enter_handler_t enter_handler);
bool ply_keyboard_watch_for_input (ply_keyboard_t *keyboard);
void ply_keyboard_stop_watching_for_input (ply_keyboard_t *keyboard);

File diff suppressed because it is too large Load diff

View file

@ -31,11 +31,11 @@
typedef struct _ply_pixel_buffer ply_pixel_buffer_t;
#define PLY_PIXEL_BUFFER_COLOR_TO_PIXEL_VALUE(r,g,b,a) \
(((uint8_t) (CLAMP (a * 255.0, 0.0, 255.0)) << 24) \
| ((uint8_t) (CLAMP (r * 255.0, 0.0, 255.0)) << 16) \
| ((uint8_t) (CLAMP (g * 255.0, 0.0, 255.0)) << 8) \
| ((uint8_t) (CLAMP (b * 255.0, 0.0, 255.0))))
#define PLY_PIXEL_BUFFER_COLOR_TO_PIXEL_VALUE(r, g, b, a) \
(((uint8_t) (CLAMP (a * 255.0, 0.0, 255.0)) << 24) \
| ((uint8_t) (CLAMP (r * 255.0, 0.0, 255.0)) << 16) \
| ((uint8_t) (CLAMP (g * 255.0, 0.0, 255.0)) << 8) \
| ((uint8_t) (CLAMP (b * 255.0, 0.0, 255.0))))
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
ply_pixel_buffer_t *ply_pixel_buffer_new (unsigned long width,

View file

@ -44,81 +44,80 @@
struct _ply_pixel_display
{
ply_event_loop_t *loop;
ply_event_loop_t *loop;
ply_renderer_t *renderer;
ply_renderer_head_t *head;
ply_renderer_t *renderer;
ply_renderer_head_t *head;
unsigned long width;
unsigned long height;
unsigned long width;
unsigned long height;
ply_pixel_display_draw_handler_t draw_handler;
void *draw_handler_user_data;
int pause_count;
ply_pixel_display_draw_handler_t draw_handler;
void *draw_handler_user_data;
int pause_count;
};
ply_pixel_display_t *
ply_pixel_display_new (ply_renderer_t *renderer,
ply_renderer_head_t *head)
{
ply_pixel_display_t *display;
ply_pixel_buffer_t *pixel_buffer;
ply_rectangle_t size;
ply_pixel_display_t *display;
ply_pixel_buffer_t *pixel_buffer;
ply_rectangle_t size;
display = calloc (1, sizeof (ply_pixel_display_t));
display = calloc (1, sizeof(ply_pixel_display_t));
display->loop = ply_event_loop_get_default ();
display->renderer = renderer;
display->head = head;
display->loop = ply_event_loop_get_default ();
display->renderer = renderer;
display->head = head;
pixel_buffer = ply_renderer_get_buffer_for_head (renderer, head);
ply_pixel_buffer_get_size (pixel_buffer, &size);
pixel_buffer = ply_renderer_get_buffer_for_head (renderer, head);
ply_pixel_buffer_get_size (pixel_buffer, &size);
display->width = size.width;
display->height = size.height;
display->width = size.width;
display->height = size.height;
return display;
return display;
}
unsigned long
ply_pixel_display_get_width (ply_pixel_display_t *display)
{
return display->width;
return display->width;
}
unsigned long
ply_pixel_display_get_height (ply_pixel_display_t *display)
{
return display->height;
return display->height;
}
static void
ply_pixel_display_flush (ply_pixel_display_t *display)
{
if (display->pause_count > 0)
return;
if (display->pause_count > 0)
return;
ply_renderer_flush_head (display->renderer, display->head);
ply_renderer_flush_head (display->renderer, display->head);
}
void
ply_pixel_display_pause_updates (ply_pixel_display_t *display)
{
assert (display != NULL);
assert (display != NULL);
display->pause_count++;
display->pause_count++;
}
void
ply_pixel_display_unpause_updates (ply_pixel_display_t *display)
{
assert (display != NULL);
assert (display != NULL);
display->pause_count--;
display->pause_count--;
ply_pixel_display_flush (display);
ply_pixel_display_flush (display);
}
void
@ -128,48 +127,46 @@ ply_pixel_display_draw_area (ply_pixel_display_t *display,
int width,
int height)
{
ply_pixel_buffer_t *pixel_buffer;
ply_pixel_buffer_t *pixel_buffer;
pixel_buffer = ply_renderer_get_buffer_for_head (display->renderer,
display->head);
pixel_buffer = ply_renderer_get_buffer_for_head (display->renderer,
display->head);
if (display->draw_handler != NULL) {
ply_rectangle_t clip_area;
if (display->draw_handler != NULL)
{
ply_rectangle_t clip_area;
clip_area.x = x;
clip_area.y = y;
clip_area.width = width;
clip_area.height = height;
ply_pixel_buffer_push_clip_area (pixel_buffer, &clip_area);
display->draw_handler (display->draw_handler_user_data,
pixel_buffer,
x, y, width, height, display);
ply_pixel_buffer_pop_clip_area (pixel_buffer);
}
clip_area.x = x;
clip_area.y = y;
clip_area.width = width;
clip_area.height = height;
ply_pixel_buffer_push_clip_area (pixel_buffer, &clip_area);
display->draw_handler (display->draw_handler_user_data,
pixel_buffer,
x, y, width, height, display);
ply_pixel_buffer_pop_clip_area (pixel_buffer);
}
ply_pixel_display_flush (display);
ply_pixel_display_flush (display);
}
void
ply_pixel_display_free (ply_pixel_display_t *display)
{
if (display == NULL)
return;
if (display == NULL)
return;
free (display);
free (display);
}
void
ply_pixel_display_set_draw_handler (ply_pixel_display_t *display,
ply_pixel_display_set_draw_handler (ply_pixel_display_t *display,
ply_pixel_display_draw_handler_t draw_handler,
void *user_data)
void *user_data)
{
assert (display != NULL);
assert (display != NULL);
display->draw_handler = draw_handler;
display->draw_handler_user_data = user_data;
display->draw_handler = draw_handler;
display->draw_handler_user_data = user_data;
}
/* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */

View file

@ -32,13 +32,13 @@
typedef struct _ply_pixel_display ply_pixel_display_t;
typedef void (* ply_pixel_display_draw_handler_t) (void *user_data,
ply_pixel_buffer_t *pixel_buffer,
int x,
int y,
int width,
int height,
ply_pixel_display_t *pixel_display);
typedef void (*ply_pixel_display_draw_handler_t) (void *user_data,
ply_pixel_buffer_t *pixel_buffer,
int x,
int y,
int width,
int height,
ply_pixel_display_t *pixel_display);
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
ply_pixel_display_t *ply_pixel_display_new (ply_renderer_t *renderer,
@ -46,12 +46,12 @@ ply_pixel_display_t *ply_pixel_display_new (ply_renderer_t *renderer,
void ply_pixel_display_free (ply_pixel_display_t *display);
unsigned long ply_pixel_display_get_width (ply_pixel_display_t *display);
unsigned long ply_pixel_display_get_width (ply_pixel_display_t *display);
unsigned long ply_pixel_display_get_height (ply_pixel_display_t *display);
void ply_pixel_display_set_draw_handler (ply_pixel_display_t *display,
ply_pixel_display_draw_handler_t draw_handler,
void *user_data);
void ply_pixel_display_set_draw_handler (ply_pixel_display_t *display,
ply_pixel_display_draw_handler_t draw_handler,
void *user_data);
void ply_pixel_display_draw_area (ply_pixel_display_t *display,
int x,

View file

@ -37,35 +37,35 @@ typedef struct _ply_renderer_backend ply_renderer_backend_t;
typedef struct
{
ply_renderer_backend_t * (* create_backend) (const char *device_name,
ply_terminal_t *terminal);
void (* destroy_backend) (ply_renderer_backend_t *backend);
bool (* open_device) (ply_renderer_backend_t *backend);
void (* close_device) (ply_renderer_backend_t *backend);
bool (* query_device) (ply_renderer_backend_t *backend);
bool (* map_to_device) (ply_renderer_backend_t *backend);
void (* unmap_from_device) (ply_renderer_backend_t *backend);
void (* activate) (ply_renderer_backend_t *backend);
void (* deactivate) (ply_renderer_backend_t *backend);
void (* flush_head) (ply_renderer_backend_t *backend,
ply_renderer_head_t *head);
ply_renderer_backend_t * (*create_backend)(const char *device_name,
ply_terminal_t * terminal);
void (*destroy_backend)(ply_renderer_backend_t *backend);
bool (*open_device)(ply_renderer_backend_t *backend);
void (*close_device)(ply_renderer_backend_t *backend);
bool (*query_device)(ply_renderer_backend_t *backend);
bool (*map_to_device)(ply_renderer_backend_t *backend);
void (*unmap_from_device)(ply_renderer_backend_t *backend);
void (*activate)(ply_renderer_backend_t *backend);
void (*deactivate)(ply_renderer_backend_t *backend);
void (*flush_head)(ply_renderer_backend_t *backend,
ply_renderer_head_t *head);
ply_list_t * (* get_heads) (ply_renderer_backend_t *backend);
ply_list_t * (*get_heads)(ply_renderer_backend_t * backend);
ply_pixel_buffer_t * (* get_buffer_for_head) (ply_renderer_backend_t *backend,
ply_renderer_head_t *head);
ply_pixel_buffer_t * (*get_buffer_for_head)(ply_renderer_backend_t * backend,
ply_renderer_head_t * head);
ply_renderer_input_source_t * (* get_input_source) (ply_renderer_backend_t *backend);
bool (* open_input_source) (ply_renderer_backend_t *backend,
ply_renderer_input_source_t *input_source);
ply_renderer_input_source_t * (*get_input_source)(ply_renderer_backend_t * backend);
bool (*open_input_source)(ply_renderer_backend_t *backend,
ply_renderer_input_source_t *input_source);
void (* set_handler_for_input_source) (ply_renderer_backend_t *backend,
ply_renderer_input_source_t *input_source,
ply_renderer_input_source_handler_t handler,
void *user_data);
void (*set_handler_for_input_source)(ply_renderer_backend_t *backend,
ply_renderer_input_source_t *input_source,
ply_renderer_input_source_handler_t handler,
void *user_data);
void (* close_input_source) (ply_renderer_backend_t *backend,
ply_renderer_input_source_t *input_source);
void (*close_input_source)(ply_renderer_backend_t *backend,
ply_renderer_input_source_t *input_source);
} ply_renderer_plugin_interface_t;
#endif /* PLY_RENDERER_PLUGIN_H */

View file

@ -44,357 +44,348 @@
struct _ply_renderer
{
ply_event_loop_t *loop;
ply_module_handle_t *module_handle;
const ply_renderer_plugin_interface_t *plugin_interface;
ply_renderer_backend_t *backend;
ply_event_loop_t *loop;
ply_module_handle_t *module_handle;
const ply_renderer_plugin_interface_t *plugin_interface;
ply_renderer_backend_t *backend;
ply_renderer_type_t type;
char *device_name;
ply_terminal_t *terminal;
ply_renderer_type_t type;
char *device_name;
ply_terminal_t *terminal;
uint32_t input_source_is_open : 1;
uint32_t is_mapped : 1;
uint32_t input_source_is_open : 1;
uint32_t is_mapped : 1;
};
typedef const ply_renderer_plugin_interface_t *
(* get_backend_interface_function_t) (void);
(*get_backend_interface_function_t) (void);
static void ply_renderer_unload_plugin (ply_renderer_t *renderer);
ply_renderer_t *
ply_renderer_new (ply_renderer_type_t renderer_type,
const char *device_name,
ply_terminal_t *terminal)
ply_renderer_new (ply_renderer_type_t renderer_type,
const char *device_name,
ply_terminal_t *terminal)
{
ply_renderer_t *renderer;
ply_renderer_t *renderer;
renderer = calloc (1, sizeof (struct _ply_renderer));
renderer = calloc (1, sizeof(struct _ply_renderer));
renderer->type = renderer_type;
renderer->type = renderer_type;
if (device_name != NULL)
renderer->device_name = strdup (device_name);
if (device_name != NULL)
renderer->device_name = strdup (device_name);
renderer->terminal = terminal;
renderer->terminal = terminal;
return renderer;
return renderer;
}
void
ply_renderer_free (ply_renderer_t *renderer)
{
if (renderer == NULL)
return;
if (renderer == NULL)
return;
if (renderer->plugin_interface != NULL)
{
ply_trace ("Unloading renderer backend plugin");
ply_renderer_unload_plugin (renderer);
}
if (renderer->plugin_interface != NULL) {
ply_trace ("Unloading renderer backend plugin");
ply_renderer_unload_plugin (renderer);
}
free (renderer->device_name);
free (renderer);
free (renderer->device_name);
free (renderer);
}
const char *
ply_renderer_get_device_name (ply_renderer_t *renderer)
{
return renderer->device_name;
return renderer->device_name;
}
static bool
ply_renderer_load_plugin (ply_renderer_t *renderer,
const char *module_path)
{
assert (renderer != NULL);
assert (renderer != NULL);
get_backend_interface_function_t get_renderer_backend_interface;
get_backend_interface_function_t get_renderer_backend_interface;
renderer->module_handle = ply_open_module (module_path);
renderer->module_handle = ply_open_module (module_path);
if (renderer->module_handle == NULL)
return false;
if (renderer->module_handle == NULL)
return false;
get_renderer_backend_interface = (get_backend_interface_function_t)
ply_module_look_up_function (renderer->module_handle,
"ply_renderer_backend_get_interface");
get_renderer_backend_interface = (get_backend_interface_function_t)
ply_module_look_up_function (renderer->module_handle,
"ply_renderer_backend_get_interface");
if (get_renderer_backend_interface == NULL)
{
ply_save_errno ();
ply_trace ("module '%s' is not a renderer plugin",
module_path);
ply_close_module (renderer->module_handle);
renderer->module_handle = NULL;
ply_restore_errno ();
return false;
}
if (get_renderer_backend_interface == NULL) {
ply_save_errno ();
ply_trace ("module '%s' is not a renderer plugin",
module_path);
ply_close_module (renderer->module_handle);
renderer->module_handle = NULL;
ply_restore_errno ();
return false;
}
renderer->plugin_interface = get_renderer_backend_interface ();
renderer->plugin_interface = get_renderer_backend_interface ();
if (renderer->plugin_interface == NULL)
{
ply_trace ("module '%s' is not a valid renderer plugin",
module_path);
ply_save_errno ();
ply_close_module (renderer->module_handle);
renderer->module_handle = NULL;
ply_restore_errno ();
return false;
}
if (renderer->plugin_interface == NULL) {
ply_trace ("module '%s' is not a valid renderer plugin",
module_path);
ply_save_errno ();
ply_close_module (renderer->module_handle);
renderer->module_handle = NULL;
ply_restore_errno ();
return false;
}
renderer->backend = renderer->plugin_interface->create_backend (renderer->device_name,
renderer->terminal);
renderer->backend = renderer->plugin_interface->create_backend (renderer->device_name,
renderer->terminal);
if (renderer->backend == NULL)
{
ply_save_errno ();
ply_trace ("module '%s' renderer backend could not be created",
module_path);
ply_close_module (renderer->module_handle);
renderer->module_handle = NULL;
ply_restore_errno ();
return false;
}
if (renderer->backend == NULL) {
ply_save_errno ();
ply_trace ("module '%s' renderer backend could not be created",
module_path);
ply_close_module (renderer->module_handle);
renderer->module_handle = NULL;
ply_restore_errno ();
return false;
}
return true;
return true;
}
static void
ply_renderer_unload_plugin (ply_renderer_t *renderer)
{
assert (renderer != NULL);
assert (renderer->plugin_interface != NULL);
assert (renderer->module_handle != NULL);
assert (renderer != NULL);
assert (renderer->plugin_interface != NULL);
assert (renderer->module_handle != NULL);
ply_close_module (renderer->module_handle);
renderer->plugin_interface = NULL;
renderer->module_handle = NULL;
ply_close_module (renderer->module_handle);
renderer->plugin_interface = NULL;
renderer->module_handle = NULL;
}
static bool
ply_renderer_open_device (ply_renderer_t *renderer)
{
assert (renderer != NULL);
assert (renderer->plugin_interface != NULL);
assert (renderer != NULL);
assert (renderer->plugin_interface != NULL);
return renderer->plugin_interface->open_device (renderer->backend);
return renderer->plugin_interface->open_device (renderer->backend);
}
static void
ply_renderer_close_device (ply_renderer_t *renderer)
{
assert (renderer != NULL);
assert (renderer->plugin_interface != NULL);
assert (renderer != NULL);
assert (renderer->plugin_interface != NULL);
renderer->plugin_interface->close_device (renderer->backend);
renderer->plugin_interface->close_device (renderer->backend);
}
static bool
ply_renderer_query_device (ply_renderer_t *renderer)
{
assert (renderer != NULL);
assert (renderer->plugin_interface != NULL);
assert (renderer != NULL);
assert (renderer->plugin_interface != NULL);
return renderer->plugin_interface->query_device (renderer->backend);
return renderer->plugin_interface->query_device (renderer->backend);
}
static bool
ply_renderer_map_to_device (ply_renderer_t *renderer)
{
assert (renderer != NULL);
assert (renderer->plugin_interface != NULL);
assert (renderer != NULL);
assert (renderer->plugin_interface != NULL);
if (renderer->is_mapped)
return true;
if (renderer->is_mapped)
return true;
renderer->is_mapped = renderer->plugin_interface->map_to_device (renderer->backend);
renderer->is_mapped = renderer->plugin_interface->map_to_device (renderer->backend);
return renderer->is_mapped;
return renderer->is_mapped;
}
static void
ply_renderer_unmap_from_device (ply_renderer_t *renderer)
{
assert (renderer != NULL);
assert (renderer->plugin_interface != NULL);
assert (renderer != NULL);
assert (renderer->plugin_interface != NULL);
if (!renderer->is_mapped)
return;
if (!renderer->is_mapped)
return;
renderer->plugin_interface->unmap_from_device (renderer->backend);
renderer->is_mapped = false;
renderer->plugin_interface->unmap_from_device (renderer->backend);
renderer->is_mapped = false;
}
static bool
ply_renderer_open_plugin (ply_renderer_t *renderer,
const char *plugin_path)
{
ply_trace ("trying to open renderer plugin %s", plugin_path);
ply_trace ("trying to open renderer plugin %s", plugin_path);
if (!ply_renderer_load_plugin (renderer, plugin_path))
return false;
if (!ply_renderer_load_plugin (renderer, plugin_path))
return false;
if (!ply_renderer_open_device (renderer))
{
ply_trace ("could not open rendering device for plugin %s",
plugin_path);
ply_renderer_unload_plugin (renderer);
return false;
}
if (!ply_renderer_open_device (renderer)) {
ply_trace ("could not open rendering device for plugin %s",
plugin_path);
ply_renderer_unload_plugin (renderer);
return false;
}
if (!ply_renderer_query_device (renderer))
{
ply_trace ("could not query rendering device for plugin %s",
plugin_path);
ply_renderer_close_device (renderer);
ply_renderer_unload_plugin (renderer);
return false;
}
if (!ply_renderer_query_device (renderer)) {
ply_trace ("could not query rendering device for plugin %s",
plugin_path);
ply_renderer_close_device (renderer);
ply_renderer_unload_plugin (renderer);
return false;
}
ply_trace ("opened renderer plugin %s", plugin_path);
return true;
ply_trace ("opened renderer plugin %s", plugin_path);
return true;
}
bool
ply_renderer_open (ply_renderer_t *renderer)
{
int i;
int i;
struct
{
ply_renderer_type_t type;
const char *path;
} known_plugins[] =
{
{ PLY_RENDERER_TYPE_X11, PLYMOUTH_PLUGIN_PATH "renderers/x11.so" },
{ PLY_RENDERER_TYPE_DRM, PLYMOUTH_PLUGIN_PATH "renderers/drm.so" },
{ PLY_RENDERER_TYPE_FRAME_BUFFER, PLYMOUTH_PLUGIN_PATH "renderers/frame-buffer.so" },
{ PLY_RENDERER_TYPE_NONE, NULL }
};
for (i = 0; known_plugins[i].type != PLY_RENDERER_TYPE_NONE; i++)
{
if (renderer->type == known_plugins[i].type ||
renderer->type == PLY_RENDERER_TYPE_AUTO)
struct
{
if (ply_renderer_open_plugin (renderer, known_plugins[i].path))
return true;
}
}
ply_renderer_type_t type;
const char *path;
} known_plugins[] =
{
{ PLY_RENDERER_TYPE_X11, PLYMOUTH_PLUGIN_PATH "renderers/x11.so" },
{ PLY_RENDERER_TYPE_DRM, PLYMOUTH_PLUGIN_PATH "renderers/drm.so" },
{ PLY_RENDERER_TYPE_FRAME_BUFFER, PLYMOUTH_PLUGIN_PATH "renderers/frame-buffer.so" },
{ PLY_RENDERER_TYPE_NONE, NULL }
};
ply_trace ("could not find suitable rendering plugin");
return false;
for (i = 0; known_plugins[i].type != PLY_RENDERER_TYPE_NONE; i++) {
if (renderer->type == known_plugins[i].type ||
renderer->type == PLY_RENDERER_TYPE_AUTO)
if (ply_renderer_open_plugin (renderer, known_plugins[i].path))
return true;
}
ply_trace ("could not find suitable rendering plugin");
return false;
}
void
ply_renderer_close (ply_renderer_t *renderer)
{
ply_renderer_unmap_from_device (renderer);
ply_renderer_close_device (renderer);
ply_renderer_unmap_from_device (renderer);
ply_renderer_close_device (renderer);
}
void
ply_renderer_activate (ply_renderer_t *renderer)
{
assert (renderer->plugin_interface != NULL);
assert (renderer->plugin_interface != NULL);
return renderer->plugin_interface->activate (renderer->backend);
return renderer->plugin_interface->activate (renderer->backend);
}
void
ply_renderer_deactivate (ply_renderer_t *renderer)
{
assert (renderer->plugin_interface != NULL);
assert (renderer->plugin_interface != NULL);
return renderer->plugin_interface->deactivate (renderer->backend);
return renderer->plugin_interface->deactivate (renderer->backend);
}
ply_list_t *
ply_renderer_get_heads (ply_renderer_t *renderer)
{
assert (renderer->plugin_interface != NULL);
assert (renderer->plugin_interface != NULL);
return renderer->plugin_interface->get_heads (renderer->backend);
return renderer->plugin_interface->get_heads (renderer->backend);
}
ply_pixel_buffer_t *
ply_renderer_get_buffer_for_head (ply_renderer_t *renderer,
ply_renderer_head_t *head)
{
assert (renderer != NULL);
assert (renderer->plugin_interface != NULL);
assert (head != NULL);
assert (renderer != NULL);
assert (renderer->plugin_interface != NULL);
assert (head != NULL);
return renderer->plugin_interface->get_buffer_for_head (renderer->backend,
head);
return renderer->plugin_interface->get_buffer_for_head (renderer->backend,
head);
}
void
ply_renderer_flush_head (ply_renderer_t *renderer,
ply_renderer_head_t *head)
{
assert (renderer != NULL);
assert (renderer->plugin_interface != NULL);
assert (head != NULL);
assert (renderer != NULL);
assert (renderer->plugin_interface != NULL);
assert (head != NULL);
if (!ply_renderer_map_to_device (renderer))
return;
if (!ply_renderer_map_to_device (renderer))
return;
renderer->plugin_interface->flush_head (renderer->backend, head);
renderer->plugin_interface->flush_head (renderer->backend, head);
}
ply_renderer_input_source_t *
ply_renderer_get_input_source (ply_renderer_t *renderer)
{
assert (renderer != NULL);
assert (renderer->plugin_interface != NULL);
assert (renderer != NULL);
assert (renderer->plugin_interface != NULL);
return renderer->plugin_interface->get_input_source (renderer->backend);
return renderer->plugin_interface->get_input_source (renderer->backend);
}
bool
ply_renderer_open_input_source (ply_renderer_t *renderer,
ply_renderer_input_source_t *input_source)
{
assert (renderer != NULL);
assert (input_source != NULL);
assert (renderer != NULL);
assert (input_source != NULL);
renderer->input_source_is_open = renderer->plugin_interface->open_input_source (renderer->backend,
input_source);
renderer->input_source_is_open = renderer->plugin_interface->open_input_source (renderer->backend,
input_source);
return renderer->input_source_is_open;
return renderer->input_source_is_open;
}
void
ply_renderer_set_handler_for_input_source (ply_renderer_t *renderer,
ply_renderer_input_source_t *input_source,
ply_renderer_input_source_handler_t handler,
void *user_data)
ply_renderer_set_handler_for_input_source (ply_renderer_t *renderer,
ply_renderer_input_source_t *input_source,
ply_renderer_input_source_handler_t handler,
void *user_data)
{
assert (renderer != NULL);
assert (input_source != NULL);
assert (renderer != NULL);
assert (input_source != NULL);
renderer->plugin_interface->set_handler_for_input_source (renderer->backend,
input_source,
handler,
user_data);
renderer->plugin_interface->set_handler_for_input_source (renderer->backend,
input_source,
handler,
user_data);
}
void
ply_renderer_close_input_source (ply_renderer_t *renderer,
ply_renderer_input_source_t *input_source)
{
assert (renderer != NULL);
assert (input_source != NULL);
assert (renderer != NULL);
assert (input_source != NULL);
if (!renderer->input_source_is_open)
return;
if (!renderer->input_source_is_open)
return;
renderer->plugin_interface->close_input_source (renderer->backend,
input_source);
renderer->input_source_is_open = false;
renderer->plugin_interface->close_input_source (renderer->backend,
input_source);
renderer->input_source_is_open = false;
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -37,21 +37,21 @@ typedef struct _ply_renderer_input_source ply_renderer_input_source_t;
typedef enum
{
PLY_RENDERER_TYPE_NONE = -1,
PLY_RENDERER_TYPE_AUTO,
PLY_RENDERER_TYPE_DRM,
PLY_RENDERER_TYPE_FRAME_BUFFER,
PLY_RENDERER_TYPE_X11
PLY_RENDERER_TYPE_NONE = -1,
PLY_RENDERER_TYPE_AUTO,
PLY_RENDERER_TYPE_DRM,
PLY_RENDERER_TYPE_FRAME_BUFFER,
PLY_RENDERER_TYPE_X11
} ply_renderer_type_t;
typedef void (* ply_renderer_input_source_handler_t) (void *user_data,
ply_buffer_t *key_buffer,
ply_renderer_input_source_t *input_source);
typedef void (*ply_renderer_input_source_handler_t) (void *user_data,
ply_buffer_t *key_buffer,
ply_renderer_input_source_t *input_source);
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
ply_renderer_t *ply_renderer_new (ply_renderer_type_t renderer_type,
const char *device_name,
ply_terminal_t *terminal);
const char *device_name,
ply_terminal_t *terminal);
void ply_renderer_free (ply_renderer_t *renderer);
bool ply_renderer_open (ply_renderer_t *renderer);
void ply_renderer_close (ply_renderer_t *renderer);
@ -68,10 +68,10 @@ void ply_renderer_flush_head (ply_renderer_t *renderer,
ply_renderer_input_source_t *ply_renderer_get_input_source (ply_renderer_t *renderer);
bool ply_renderer_open_input_source (ply_renderer_t *renderer,
ply_renderer_input_source_t *input_source);
void ply_renderer_set_handler_for_input_source (ply_renderer_t *renderer,
ply_renderer_input_source_t *input_source,
ply_renderer_input_source_handler_t handler,
void *user_data);
void ply_renderer_set_handler_for_input_source (ply_renderer_t *renderer,
ply_renderer_input_source_t *input_source,
ply_renderer_input_source_handler_t handler,
void *user_data);
void ply_renderer_close_input_source (ply_renderer_t *renderer,
ply_renderer_input_source_t *input_source);

View file

@ -40,348 +40,333 @@
struct _ply_seat
{
ply_event_loop_t *loop;
ply_event_loop_t *loop;
ply_boot_splash_t *splash;
ply_terminal_t *terminal;
ply_renderer_t *renderer;
ply_keyboard_t *keyboard;
ply_list_t *text_displays;
ply_list_t *pixel_displays;
ply_boot_splash_t *splash;
ply_terminal_t *terminal;
ply_renderer_t *renderer;
ply_keyboard_t *keyboard;
ply_list_t *text_displays;
ply_list_t *pixel_displays;
uint32_t renderer_active : 1;
uint32_t keyboard_active : 1;
uint32_t renderer_active : 1;
uint32_t keyboard_active : 1;
};
ply_seat_t *
ply_seat_new (ply_terminal_t *terminal)
{
ply_seat_t *seat;
ply_seat_t *seat;
seat = calloc (1, sizeof (ply_seat_t));
seat = calloc (1, sizeof(ply_seat_t));
seat->loop = ply_event_loop_get_default ();
seat->terminal = terminal;
seat->text_displays = ply_list_new ();
seat->pixel_displays = ply_list_new ();
seat->loop = ply_event_loop_get_default ();
seat->terminal = terminal;
seat->text_displays = ply_list_new ();
seat->pixel_displays = ply_list_new ();
return seat;
return seat;
}
static void
add_pixel_displays (ply_seat_t *seat)
{
ply_list_t *heads;
ply_list_node_t *node;
ply_list_t *heads;
ply_list_node_t *node;
heads = ply_renderer_get_heads (seat->renderer);
heads = ply_renderer_get_heads (seat->renderer);
ply_trace ("Adding displays for %d heads",
ply_list_get_length (heads));
ply_trace ("Adding displays for %d heads",
ply_list_get_length (heads));
node = ply_list_get_first_node (heads);
while (node != NULL)
{
ply_list_node_t *next_node;
ply_renderer_head_t *head;
ply_pixel_display_t *display;
node = ply_list_get_first_node (heads);
while (node != NULL) {
ply_list_node_t *next_node;
ply_renderer_head_t *head;
ply_pixel_display_t *display;
head = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (heads, node);
head = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (heads, node);
display = ply_pixel_display_new (seat->renderer, head);
display = ply_pixel_display_new (seat->renderer, head);
ply_list_append_data (seat->pixel_displays, display);
ply_list_append_data (seat->pixel_displays, display);
node = next_node;
}
node = next_node;
}
}
static void
add_text_displays (ply_seat_t *seat)
{
ply_text_display_t *display;
ply_text_display_t *display;
if (!ply_terminal_is_open (seat->terminal))
{
if (!ply_terminal_open (seat->terminal))
{
ply_trace ("could not add terminal %s: %m",
ply_terminal_get_name (seat->terminal));
return;
if (!ply_terminal_is_open (seat->terminal)) {
if (!ply_terminal_open (seat->terminal)) {
ply_trace ("could not add terminal %s: %m",
ply_terminal_get_name (seat->terminal));
return;
}
}
}
ply_trace ("adding text display for terminal %s",
ply_terminal_get_name (seat->terminal));
ply_trace ("adding text display for terminal %s",
ply_terminal_get_name (seat->terminal));
display = ply_text_display_new (seat->terminal);
ply_list_append_data (seat->text_displays, display);
display = ply_text_display_new (seat->terminal);
ply_list_append_data (seat->text_displays, display);
}
bool
ply_seat_open (ply_seat_t *seat,
ply_renderer_type_t renderer_type,
const char *device)
ply_seat_open (ply_seat_t *seat,
ply_renderer_type_t renderer_type,
const char *device)
{
if (renderer_type != PLY_RENDERER_TYPE_NONE)
{
ply_renderer_t *renderer;
if (renderer_type != PLY_RENDERER_TYPE_NONE) {
ply_renderer_t *renderer;
renderer = ply_renderer_new (renderer_type, device, seat->terminal);
renderer = ply_renderer_new (renderer_type, device, seat->terminal);
if (!ply_renderer_open (renderer))
{
ply_trace ("could not open renderer for %s", device);
ply_renderer_free (renderer);
if (!ply_renderer_open (renderer)) {
ply_trace ("could not open renderer for %s", device);
ply_renderer_free (renderer);
seat->renderer = NULL;
seat->renderer_active = false;
seat->renderer = NULL;
seat->renderer_active = false;
if (renderer_type != PLY_RENDERER_TYPE_AUTO)
return false;
if (renderer_type != PLY_RENDERER_TYPE_AUTO)
return false;
} else {
seat->renderer = renderer;
seat->renderer_active = true;
}
}
else
{
seat->renderer = renderer;
seat->renderer_active = true;
if (seat->renderer != NULL) {
seat->keyboard = ply_keyboard_new_for_renderer (seat->renderer);
add_pixel_displays (seat);
} else {
seat->keyboard = ply_keyboard_new_for_terminal (seat->terminal);
}
}
add_text_displays (seat);
if (seat->renderer != NULL)
{
seat->keyboard = ply_keyboard_new_for_renderer (seat->renderer);
add_pixel_displays (seat);
ply_keyboard_watch_for_input (seat->keyboard);
seat->keyboard_active = true;
}
else
{
seat->keyboard = ply_keyboard_new_for_terminal (seat->terminal);
}
add_text_displays (seat);
ply_keyboard_watch_for_input (seat->keyboard);
seat->keyboard_active = true;
return true;
return true;
}
bool
ply_seat_is_open (ply_seat_t *seat)
{
return ply_list_get_length (seat->pixel_displays) > 0 ||
ply_list_get_length (seat->text_displays) > 0;
return ply_list_get_length (seat->pixel_displays) > 0 ||
ply_list_get_length (seat->text_displays) > 0;
}
void
ply_seat_deactivate_keyboard (ply_seat_t *seat)
{
if (!seat->keyboard_active)
return;
if (!seat->keyboard_active)
return;
seat->keyboard_active = false;
seat->keyboard_active = false;
if (seat->keyboard == NULL)
return;
if (seat->keyboard == NULL)
return;
ply_trace ("deactivating keybord");
ply_keyboard_stop_watching_for_input (seat->keyboard);
ply_trace ("deactivating keybord");
ply_keyboard_stop_watching_for_input (seat->keyboard);
}
void
ply_seat_deactivate_renderer (ply_seat_t *seat)
{
if (!seat->renderer_active)
return;
if (!seat->renderer_active)
return;
seat->renderer_active = false;
seat->renderer_active = false;
if (seat->renderer == NULL)
return;
if (seat->renderer == NULL)
return;
ply_trace ("deactivating renderer");
ply_renderer_deactivate (seat->renderer);
ply_trace ("deactivating renderer");
ply_renderer_deactivate (seat->renderer);
}
void
ply_seat_activate_keyboard (ply_seat_t *seat)
{
if (seat->keyboard_active)
return;
if (seat->keyboard_active)
return;
if (seat->keyboard == NULL)
return;
if (seat->keyboard == NULL)
return;
ply_trace ("activating keyboard");
ply_keyboard_watch_for_input (seat->keyboard);
ply_trace ("activating keyboard");
ply_keyboard_watch_for_input (seat->keyboard);
seat->keyboard_active = true;
seat->keyboard_active = true;
}
void
ply_seat_activate_renderer (ply_seat_t *seat)
{
if (seat->renderer_active)
return;
if (seat->renderer_active)
return;
if (seat->renderer == NULL)
return;
if (seat->renderer == NULL)
return;
ply_trace ("activating renderer");
ply_renderer_activate (seat->renderer);
ply_trace ("activating renderer");
ply_renderer_activate (seat->renderer);
seat->renderer_active = true;
seat->renderer_active = true;
}
void
ply_seat_refresh_displays (ply_seat_t *seat)
{
ply_list_node_t *node;
ply_list_node_t *node;
node = ply_list_get_first_node (seat->pixel_displays);
while (node != NULL)
{
ply_pixel_display_t *display;
ply_list_node_t *next_node;
unsigned long width, height;
node = ply_list_get_first_node (seat->pixel_displays);
while (node != NULL) {
ply_pixel_display_t *display;
ply_list_node_t *next_node;
unsigned long width, height;
display = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (seat->pixel_displays, node);
display = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (seat->pixel_displays, node);
width = ply_pixel_display_get_width (display);
height = ply_pixel_display_get_height (display);
width = ply_pixel_display_get_width (display);
height = ply_pixel_display_get_height (display);
ply_pixel_display_draw_area (display, 0, 0, width, height);
node = next_node;
}
ply_pixel_display_draw_area (display, 0, 0, width, height);
node = next_node;
}
node = ply_list_get_first_node (seat->text_displays);
while (node != NULL)
{
ply_text_display_t *display;
ply_list_node_t *next_node;
int number_of_columns, number_of_rows;
node = ply_list_get_first_node (seat->text_displays);
while (node != NULL) {
ply_text_display_t *display;
ply_list_node_t *next_node;
int number_of_columns, number_of_rows;
display = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (seat->text_displays, node);
display = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (seat->text_displays, node);
number_of_columns = ply_text_display_get_number_of_columns (display);
number_of_rows = ply_text_display_get_number_of_rows (display);
number_of_columns = ply_text_display_get_number_of_columns (display);
number_of_rows = ply_text_display_get_number_of_rows (display);
ply_text_display_draw_area (display, 0, 0,
number_of_columns,
number_of_rows);
node = next_node;
}
ply_text_display_draw_area (display, 0, 0,
number_of_columns,
number_of_rows);
node = next_node;
}
}
void
ply_seat_close (ply_seat_t *seat)
{
if (seat->renderer == NULL)
return;
if (seat->renderer == NULL)
return;
ply_trace ("destroying renderer");
ply_renderer_close (seat->renderer);
ply_renderer_free (seat->renderer);
seat->renderer = NULL;
ply_trace ("destroying renderer");
ply_renderer_close (seat->renderer);
ply_renderer_free (seat->renderer);
seat->renderer = NULL;
}
void
ply_seat_set_splash (ply_seat_t *seat,
ply_boot_splash_t *splash)
{
if (seat->splash == splash)
return;
if (seat->splash == splash)
return;
if (seat->splash != NULL)
ply_boot_splash_detach_from_seat (splash, seat);
if (seat->splash != NULL)
ply_boot_splash_detach_from_seat (splash, seat);
if (splash != NULL)
ply_boot_splash_attach_to_seat (splash, seat);
if (splash != NULL)
ply_boot_splash_attach_to_seat (splash, seat);
seat->splash = splash;
seat->splash = splash;
}
static void
free_pixel_displays (ply_seat_t *seat)
{
ply_list_node_t *node;
ply_list_node_t *node;
ply_trace ("freeing %d pixel displays", ply_list_get_length (seat->pixel_displays));
node = ply_list_get_first_node (seat->pixel_displays);
while (node != NULL)
{
ply_list_node_t *next_node;
ply_pixel_display_t *display;
ply_trace ("freeing %d pixel displays", ply_list_get_length (seat->pixel_displays));
node = ply_list_get_first_node (seat->pixel_displays);
while (node != NULL) {
ply_list_node_t *next_node;
ply_pixel_display_t *display;
next_node = ply_list_get_next_node (seat->pixel_displays, node);
display = ply_list_node_get_data (node);
ply_pixel_display_free (display);
next_node = ply_list_get_next_node (seat->pixel_displays, node);
display = ply_list_node_get_data (node);
ply_pixel_display_free (display);
ply_list_remove_node (seat->pixel_displays, node);
ply_list_remove_node (seat->pixel_displays, node);
node = next_node;
}
node = next_node;
}
}
static void
free_text_displays (ply_seat_t *seat)
{
ply_list_node_t *node;
ply_list_node_t *node;
ply_trace ("freeing %d text displays", ply_list_get_length (seat->text_displays));
node = ply_list_get_first_node (seat->text_displays);
while (node != NULL)
{
ply_list_node_t *next_node;
ply_text_display_t *display;
ply_trace ("freeing %d text displays", ply_list_get_length (seat->text_displays));
node = ply_list_get_first_node (seat->text_displays);
while (node != NULL) {
ply_list_node_t *next_node;
ply_text_display_t *display;
next_node = ply_list_get_next_node (seat->text_displays, node);
display = ply_list_node_get_data (node);
ply_text_display_free (display);
next_node = ply_list_get_next_node (seat->text_displays, node);
display = ply_list_node_get_data (node);
ply_text_display_free (display);
ply_list_remove_node (seat->text_displays, node);
ply_list_remove_node (seat->text_displays, node);
node = next_node;
}
node = next_node;
}
}
void
ply_seat_free (ply_seat_t *seat)
{
if (seat == NULL)
return;
if (seat == NULL)
return;
free_pixel_displays (seat);
free_text_displays (seat);
ply_keyboard_free (seat->keyboard);
free_pixel_displays (seat);
free_text_displays (seat);
ply_keyboard_free (seat->keyboard);
free (seat);
free (seat);
}
ply_list_t *
ply_seat_get_pixel_displays (ply_seat_t *seat)
{
return seat->pixel_displays;
return seat->pixel_displays;
}
ply_list_t *
ply_seat_get_text_displays (ply_seat_t *seat)
{
return seat->text_displays;
return seat->text_displays;
}
ply_keyboard_t *
ply_seat_get_keyboard (ply_seat_t *seat)
{
return seat->keyboard;
return seat->keyboard;
}
ply_renderer_t *
ply_seat_get_renderer (ply_seat_t *seat)
{
return seat->renderer;
return seat->renderer;
}
/* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */

View file

@ -43,9 +43,9 @@ typedef struct _ply_seat ply_seat_t;
ply_seat_t *ply_seat_new (ply_terminal_t *terminal);
void ply_seat_free (ply_seat_t *seat);
bool ply_seat_open (ply_seat_t *seat,
ply_renderer_type_t renderer_type,
const char *device);
bool ply_seat_open (ply_seat_t *seat,
ply_renderer_type_t renderer_type,
const char *device);
bool ply_seat_is_open (ply_seat_t *seat);
void ply_seat_deactivate_keyboard (ply_seat_t *seat);
void ply_seat_activate_keyboard (ply_seat_t *seat);

File diff suppressed because it is too large Load diff

View file

@ -31,27 +31,27 @@
#include "ply-event-loop.h"
typedef struct _ply_terminal ply_terminal_t;
typedef void (* ply_terminal_active_vt_changed_handler_t) (void *user_data,
ply_terminal_t *terminal);
typedef void (* ply_terminal_input_handler_t) (void *user_data,
ply_terminal_t *terminal);
typedef void (*ply_terminal_active_vt_changed_handler_t) (void *user_data,
ply_terminal_t *terminal);
typedef void (*ply_terminal_input_handler_t) (void *user_data,
ply_terminal_t *terminal);
typedef enum
{
PLY_TERMINAL_COLOR_BLACK = 0,
PLY_TERMINAL_COLOR_RED,
PLY_TERMINAL_COLOR_GREEN,
PLY_TERMINAL_COLOR_BROWN,
PLY_TERMINAL_COLOR_BLUE,
PLY_TERMINAL_COLOR_MAGENTA,
PLY_TERMINAL_COLOR_CYAN,
PLY_TERMINAL_COLOR_WHITE,
PLY_TERMINAL_COLOR_DEFAULT = PLY_TERMINAL_COLOR_WHITE + 2
PLY_TERMINAL_COLOR_BLACK = 0,
PLY_TERMINAL_COLOR_RED,
PLY_TERMINAL_COLOR_GREEN,
PLY_TERMINAL_COLOR_BROWN,
PLY_TERMINAL_COLOR_BLUE,
PLY_TERMINAL_COLOR_MAGENTA,
PLY_TERMINAL_COLOR_CYAN,
PLY_TERMINAL_COLOR_WHITE,
PLY_TERMINAL_COLOR_DEFAULT = PLY_TERMINAL_COLOR_WHITE + 2
} ply_terminal_color_t;
typedef enum
{
PLY_TERMINAL_MODE_TEXT,
PLY_TERMINAL_MODE_GRAPHICS
PLY_TERMINAL_MODE_TEXT,
PLY_TERMINAL_MODE_GRAPHICS
} ply_terminal_mode_t;
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
@ -78,12 +78,12 @@ int ply_terminal_get_number_of_columns (ply_terminal_t *terminal);
int ply_terminal_get_number_of_rows (ply_terminal_t *terminal);
bool ply_terminal_supports_color (ply_terminal_t *terminal);
uint32_t ply_terminal_get_color_hex_value (ply_terminal_t *terminal,
ply_terminal_color_t color);
uint32_t ply_terminal_get_color_hex_value (ply_terminal_t *terminal,
ply_terminal_color_t color);
void ply_terminal_set_color_hex_value (ply_terminal_t *terminal,
ply_terminal_color_t color,
uint32_t hex_value);
void ply_terminal_set_color_hex_value (ply_terminal_t *terminal,
ply_terminal_color_t color,
uint32_t hex_value);
void ply_terminal_set_mode (ply_terminal_t *terminal,
ply_terminal_mode_t mode);
@ -99,19 +99,19 @@ bool ply_terminal_deactivate_vt (ply_terminal_t *terminal);
void ply_terminal_watch_for_vt_changes (ply_terminal_t *terminal);
void ply_terminal_stop_watching_for_vt_changes (ply_terminal_t *terminal);
void ply_terminal_watch_for_active_vt_change (ply_terminal_t *terminal,
void ply_terminal_watch_for_active_vt_change (ply_terminal_t *terminal,
ply_terminal_active_vt_changed_handler_t active_vt_changed_handler,
void *user_data);
void ply_terminal_stop_watching_for_active_vt_change (ply_terminal_t *terminal,
void *user_data);
void ply_terminal_stop_watching_for_active_vt_change (ply_terminal_t *terminal,
ply_terminal_active_vt_changed_handler_t active_vt_changed_handler,
void *user_data);
void *user_data);
void ply_terminal_watch_for_input (ply_terminal_t *terminal,
void ply_terminal_watch_for_input (ply_terminal_t *terminal,
ply_terminal_input_handler_t input_handler,
void *user_data);
void ply_terminal_stop_watching_for_input (ply_terminal_t *terminal,
void *user_data);
void ply_terminal_stop_watching_for_input (ply_terminal_t *terminal,
ply_terminal_input_handler_t input_handler,
void *user_data);
void *user_data);
#endif

View file

@ -92,40 +92,40 @@
struct _ply_text_display
{
ply_event_loop_t *loop;
ply_event_loop_t *loop;
ply_terminal_t *terminal;
ply_terminal_t *terminal;
ply_terminal_color_t foreground_color;
ply_terminal_color_t background_color;
ply_terminal_color_t foreground_color;
ply_terminal_color_t background_color;
ply_text_display_draw_handler_t draw_handler;
void *draw_handler_user_data;
ply_text_display_draw_handler_t draw_handler;
void *draw_handler_user_data;
};
ply_text_display_t *
ply_text_display_new (ply_terminal_t *terminal)
{
ply_text_display_t *display;
ply_text_display_t *display;
display = calloc (1, sizeof (ply_text_display_t));
display = calloc (1, sizeof(ply_text_display_t));
display->loop = NULL;
display->terminal = terminal;
display->loop = NULL;
display->terminal = terminal;
return display;
return display;
}
int
ply_text_display_get_number_of_columns (ply_text_display_t *display)
{
return ply_terminal_get_number_of_columns (display->terminal);
return ply_terminal_get_number_of_columns (display->terminal);
}
int
ply_text_display_get_number_of_rows (ply_text_display_t *display)
{
return ply_terminal_get_number_of_rows (display->terminal);
return ply_terminal_get_number_of_rows (display->terminal);
}
void
@ -133,80 +133,78 @@ ply_text_display_set_cursor_position (ply_text_display_t *display,
int column,
int row)
{
int number_of_columns;
int number_of_rows;
int number_of_columns;
int number_of_rows;
number_of_columns = ply_text_display_get_number_of_columns (display);
number_of_rows = ply_text_display_get_number_of_rows (display);
number_of_columns = ply_text_display_get_number_of_columns (display);
number_of_rows = ply_text_display_get_number_of_rows (display);
column = CLAMP (column, 0, number_of_columns - 1);
row = CLAMP (row, 0, number_of_rows - 1);
column = CLAMP (column, 0, number_of_columns - 1);
row = CLAMP (row, 0, number_of_rows - 1);
ply_terminal_write (display->terminal,
MOVE_CURSOR_SEQUENCE,
row, column);
ply_terminal_write (display->terminal,
MOVE_CURSOR_SEQUENCE,
row, column);
}
void
ply_text_display_clear_screen (ply_text_display_t *display)
{
if (ply_is_tracing ())
return;
if (ply_is_tracing ())
return;
ply_terminal_write (display->terminal,
CLEAR_SCREEN_SEQUENCE);
ply_terminal_write (display->terminal,
CLEAR_SCREEN_SEQUENCE);
ply_text_display_set_cursor_position (display, 0, 0);
ply_text_display_set_cursor_position (display, 0, 0);
}
void
ply_text_display_clear_line (ply_text_display_t *display)
{
ply_terminal_write (display->terminal,
CLEAR_LINE_SEQUENCE);
ply_terminal_write (display->terminal,
CLEAR_LINE_SEQUENCE);
}
void
ply_text_display_remove_character (ply_text_display_t *display)
{
ply_terminal_write (display->terminal,
BACKSPACE);
ply_terminal_write (display->terminal,
BACKSPACE);
}
void
ply_text_display_set_background_color (ply_text_display_t *display,
ply_terminal_color_t color)
ply_text_display_set_background_color (ply_text_display_t *display,
ply_terminal_color_t color)
{
ply_terminal_write (display->terminal,
COLOR_SEQUENCE_FORMAT,
BACKGROUND_COLOR_BASE + color);
ply_terminal_write (display->terminal,
COLOR_SEQUENCE_FORMAT,
BACKGROUND_COLOR_BASE + color);
display->background_color = color;
display->background_color = color;
}
void
ply_text_display_set_foreground_color (ply_text_display_t *display,
ply_terminal_color_t color)
ply_text_display_set_foreground_color (ply_text_display_t *display,
ply_terminal_color_t color)
{
ply_terminal_write (display->terminal,
COLOR_SEQUENCE_FORMAT,
FOREGROUND_COLOR_BASE + color);
ply_terminal_write (display->terminal,
COLOR_SEQUENCE_FORMAT,
FOREGROUND_COLOR_BASE + color);
display->foreground_color = color;
display->foreground_color = color;
}
ply_terminal_color_t
ply_text_display_get_background_color (ply_text_display_t *display)
{
return display->background_color;
return display->background_color;
}
ply_terminal_color_t
ply_text_display_get_foreground_color (ply_text_display_t *display)
{
return display->foreground_color;
return display->foreground_color;
}
void
@ -216,17 +214,17 @@ ply_text_display_draw_area (ply_text_display_t *display,
int width,
int height)
{
if (display->draw_handler != NULL)
display->draw_handler (display->draw_handler_user_data,
display->terminal,
x, y, width, height);
if (display->draw_handler != NULL)
display->draw_handler (display->draw_handler_user_data,
display->terminal,
x, y, width, height);
}
void
ply_text_display_hide_cursor (ply_text_display_t *display)
{
ply_terminal_write (display->terminal,
HIDE_CURSOR_SEQUENCE);
ply_terminal_write (display->terminal,
HIDE_CURSOR_SEQUENCE);
}
void
@ -234,104 +232,105 @@ ply_text_display_write (ply_text_display_t *display,
const char *format,
...)
{
int fd;
int fd;
va_list args;
char *string;
va_list args;
char *string;
assert (display != NULL);
assert (format != NULL);
assert (display != NULL);
assert (format != NULL);
fd = ply_terminal_get_fd (display->terminal);
fd = ply_terminal_get_fd (display->terminal);
string = NULL;
va_start (args, format);
vasprintf (&string, format, args);
va_end (args);
string = NULL;
va_start (args, format);
vasprintf (&string, format, args);
va_end (args);
write (fd, string, strlen (string));
free (string);
write (fd, string, strlen (string));
free (string);
}
void
ply_text_display_show_cursor (ply_text_display_t *display)
{
ply_terminal_write (display->terminal,
SHOW_CURSOR_SEQUENCE);
ply_terminal_write (display->terminal,
SHOW_CURSOR_SEQUENCE);
}
bool
ply_text_display_supports_color (ply_text_display_t *display)
{
return ply_terminal_supports_color (display->terminal);
return ply_terminal_supports_color (display->terminal);
}
static void
ply_text_display_detach_from_event_loop (ply_text_display_t *display)
{
assert (display != NULL);
display->loop = NULL;
assert (display != NULL);
display->loop = NULL;
}
void
ply_text_display_free (ply_text_display_t *display)
{
if (display == NULL)
return;
if (display == NULL)
return;
if (display->loop != NULL)
ply_event_loop_stop_watching_for_exit (display->loop,
(ply_event_loop_exit_handler_t)
ply_text_display_detach_from_event_loop,
display);
if (display->loop != NULL) {
ply_event_loop_stop_watching_for_exit (display->loop,
(ply_event_loop_exit_handler_t)
ply_text_display_detach_from_event_loop,
display);
}
free (display);
free (display);
}
void
ply_text_display_set_draw_handler (ply_text_display_t *display,
ply_text_display_set_draw_handler (ply_text_display_t *display,
ply_text_display_draw_handler_t draw_handler,
void *user_data)
void *user_data)
{
assert (display != NULL);
assert (display != NULL);
display->draw_handler = draw_handler;
display->draw_handler_user_data = user_data;
display->draw_handler = draw_handler;
display->draw_handler_user_data = user_data;
}
void
ply_text_display_pause_updates (ply_text_display_t *display)
{
ply_terminal_write (display->terminal,
PAUSE_SEQUENCE);
ply_terminal_write (display->terminal,
PAUSE_SEQUENCE);
}
void
ply_text_display_unpause_updates (ply_text_display_t *display)
{
ply_terminal_write (display->terminal,
UNPAUSE_SEQUENCE);
ply_terminal_write (display->terminal,
UNPAUSE_SEQUENCE);
}
void
ply_text_display_attach_to_event_loop (ply_text_display_t *display,
ply_event_loop_t *loop)
{
assert (display != NULL);
assert (loop != NULL);
assert (display->loop == NULL);
assert (display != NULL);
assert (loop != NULL);
assert (display->loop == NULL);
display->loop = loop;
display->loop = loop;
ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t)
ply_text_display_detach_from_event_loop,
display);
ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t)
ply_text_display_detach_from_event_loop,
display);
}
ply_terminal_t *
ply_text_display_get_terminal (ply_text_display_t *display)
{
return display->terminal;
return display->terminal;
}
/* vim: set ts= 4 sw= 4 et ai ci cino= {.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */

View file

@ -32,12 +32,12 @@
typedef struct _ply_text_display ply_text_display_t;
typedef void (* ply_text_display_draw_handler_t) (void *user_data,
ply_terminal_t *terminal,
int column,
int row,
int number_of_columns,
int number_of_rows);
typedef void (*ply_text_display_draw_handler_t) (void *user_data,
ply_terminal_t *terminal,
int column,
int row,
int number_of_columns,
int number_of_rows);
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
ply_text_display_t *ply_text_display_new (ply_terminal_t *terminal);
@ -64,22 +64,22 @@ void ply_text_display_clear_screen (ply_text_display_t *display);
void ply_text_display_clear_line (ply_text_display_t *display);
void ply_text_display_remove_character (ply_text_display_t *display);
bool ply_text_display_supports_color (ply_text_display_t *display);
void ply_text_display_set_background_color (ply_text_display_t *display,
ply_terminal_color_t color);
void ply_text_display_set_foreground_color (ply_text_display_t *display,
ply_terminal_color_t color);
void ply_text_display_set_background_color (ply_text_display_t *display,
ply_terminal_color_t color);
void ply_text_display_set_foreground_color (ply_text_display_t *display,
ply_terminal_color_t color);
ply_terminal_color_t ply_text_display_get_background_color (ply_text_display_t *display);
ply_terminal_color_t ply_text_display_get_foreground_color (ply_text_display_t *display);
void ply_text_display_draw_area (ply_text_display_t *display,
int column,
int row,
int number_of_columns,
int number_of_rows);
int column,
int row,
int number_of_columns,
int number_of_rows);
void ply_text_display_set_draw_handler (ply_text_display_t *display,
ply_text_display_draw_handler_t draw_handler,
void *user_data);
void ply_text_display_set_draw_handler (ply_text_display_t *display,
ply_text_display_draw_handler_t draw_handler,
void *user_data);
void ply_text_display_pause_updates (ply_text_display_t *display);
void ply_text_display_unpause_updates (ply_text_display_t *display);

View file

@ -61,233 +61,229 @@ static char *os_string;
struct _ply_text_progress_bar
{
ply_text_display_t *display;
ply_text_display_t *display;
int column, row;
int number_of_rows;
int number_of_columns;
int column, row;
int number_of_rows;
int number_of_columns;
double percent_done;
uint32_t is_hidden : 1;
double percent_done;
uint32_t is_hidden : 1;
};
ply_text_progress_bar_t *
ply_text_progress_bar_new (void)
{
ply_text_progress_bar_t *progress_bar;
ply_text_progress_bar_t *progress_bar;
progress_bar = calloc (1, sizeof (ply_text_progress_bar_t));
progress_bar = calloc (1, sizeof(ply_text_progress_bar_t));
progress_bar->row = 0;
progress_bar->column = 0;
progress_bar->number_of_columns = 0;
progress_bar->number_of_rows = 0;
progress_bar->row = 0;
progress_bar->column = 0;
progress_bar->number_of_columns = 0;
progress_bar->number_of_rows = 0;
return progress_bar;
return progress_bar;
}
void
ply_text_progress_bar_free (ply_text_progress_bar_t *progress_bar)
{
if (progress_bar == NULL)
return;
if (progress_bar == NULL)
return;
free (progress_bar);
free (progress_bar);
}
static void
get_os_string (void)
{
int fd;
char *buf, *pos, *pos2;
struct stat sbuf;
int fd;
char *buf, *pos, *pos2;
struct stat sbuf;
buf = NULL;
buf = NULL;
fd = open (RELEASE_FILE, O_RDONLY|O_CLOEXEC);
if (fd == -1)
goto out;
fd = open (RELEASE_FILE, O_RDONLY | O_CLOEXEC);
if (fd == -1)
goto out;
if (fstat (fd, &sbuf) == -1) {
close (fd);
goto out;
}
buf = calloc (sbuf.st_size + 1, sizeof(char));
read (fd, buf, sbuf.st_size);
close (fd);
if (strcmp (RELEASE_FILE, "/etc/os-release") == 0)
{
char key[] = "PRETTY_NAME=";
for (pos = strstr (buf, key);
pos != NULL;
pos = strstr (pos, key))
{
if (pos == buf || pos[-1] == '\n')
break;
if (fstat (fd, &sbuf) == -1) {
close (fd);
goto out;
}
if (pos != NULL)
{
pos += strlen (key);
pos2 = strstr (pos, "\n");
buf = calloc (sbuf.st_size + 1, sizeof(char));
read (fd, buf, sbuf.st_size);
close (fd);
if (pos2 != NULL)
*pos2 = '\0';
else
pos2 = pos + strlen(pos) - 1;
if (strcmp (RELEASE_FILE, "/etc/os-release") == 0) {
char key[] = "PRETTY_NAME=";
if ((*pos == '\"' && pos2[-1] == '\"') ||
(*pos == '\'' && pos2[-1] == '\''))
{
pos++;
pos2--;
for (pos = strstr (buf, key);
pos != NULL;
pos = strstr (pos, key)) {
if (pos == buf || pos[-1] == '\n')
break;
}
*pos2 = '\0';
}
asprintf (&os_string, " %s", pos);
if (pos != NULL) {
pos += strlen (key);
pos2 = strstr (pos, "\n");
if (pos2 != NULL)
*pos2 = '\0';
else
pos2 = pos + strlen (pos) - 1;
if ((*pos == '\"' && pos2[-1] == '\"') ||
(*pos == '\'' && pos2[-1] == '\'')) {
pos++;
pos2--;
*pos2 = '\0';
}
asprintf (&os_string, " %s", pos);
}
goto out;
}
goto out;
}
pos = strstr (buf, " release ");
pos = strstr (buf, " release ");
if (pos == NULL)
goto out;
if (pos == NULL)
goto out;
pos2 = strstr (pos, " (");
pos2 = strstr (pos, " (");
if (pos2 == NULL)
goto out;
if (pos2 == NULL)
goto out;
*pos = '\0';
pos += strlen (" release ");
*pos = '\0';
pos += strlen (" release ");
*pos2 = '\0';
asprintf (&os_string, " %s %s", buf, pos);
*pos2 = '\0';
asprintf (&os_string, " %s %s", buf, pos);
out:
free (buf);
free (buf);
if (os_string == NULL)
os_string = strdup ("");
if (os_string == NULL)
os_string = strdup ("");
}
void
ply_text_progress_bar_draw (ply_text_progress_bar_t *progress_bar)
{
int i, width;
double brown_fraction, blue_fraction, white_fraction;
int i, width;
double brown_fraction, blue_fraction, white_fraction;
if (progress_bar->is_hidden)
return;
if (progress_bar->is_hidden)
return;
width = progress_bar->number_of_columns - 2 - strlen (os_string);
ply_text_display_set_cursor_position (progress_bar->display,
progress_bar->column,
progress_bar->row);
brown_fraction = - (progress_bar->percent_done * progress_bar->percent_done) + 2 * progress_bar->percent_done;
blue_fraction = progress_bar->percent_done;
white_fraction = progress_bar->percent_done * progress_bar->percent_done;
for (i = 0; i < width; i++) {
double f;
f = (double) i / (double) width;
if (f < white_fraction)
ply_text_display_set_background_color (progress_bar->display,
PLY_TERMINAL_COLOR_WHITE);
else if (f < blue_fraction)
ply_text_display_set_background_color (progress_bar->display,
PLY_TERMINAL_COLOR_BLUE);
else if (f < brown_fraction)
ply_text_display_set_background_color (progress_bar->display,
PLY_TERMINAL_COLOR_BROWN);
else
break;
ply_text_display_write (progress_bar->display, "%c", ' ');
}
ply_text_display_set_background_color (progress_bar->display,
PLY_TERMINAL_COLOR_BLACK);
if (brown_fraction > 0.5) {
if (white_fraction > 0.875)
ply_text_display_set_foreground_color (progress_bar->display,
PLY_TERMINAL_COLOR_WHITE);
else if (blue_fraction > 0.66)
ply_text_display_set_foreground_color (progress_bar->display,
PLY_TERMINAL_COLOR_BLUE);
else
ply_text_display_set_foreground_color (progress_bar->display,
PLY_TERMINAL_COLOR_BROWN);
width = progress_bar->number_of_columns - 2 - strlen (os_string);
ply_text_display_set_cursor_position (progress_bar->display,
progress_bar->column + width,
progress_bar->column,
progress_bar->row);
ply_text_display_write (progress_bar->display, "%s", os_string);
brown_fraction = -(progress_bar->percent_done * progress_bar->percent_done) + 2 * progress_bar->percent_done;
blue_fraction = progress_bar->percent_done;
white_fraction = progress_bar->percent_done * progress_bar->percent_done;
ply_text_display_set_foreground_color (progress_bar->display,
PLY_TERMINAL_COLOR_DEFAULT);
}
for (i = 0; i < width; i++) {
double f;
f = (double) i / (double) width;
if (f < white_fraction)
ply_text_display_set_background_color (progress_bar->display,
PLY_TERMINAL_COLOR_WHITE);
else if (f < blue_fraction)
ply_text_display_set_background_color (progress_bar->display,
PLY_TERMINAL_COLOR_BLUE);
else if (f < brown_fraction)
ply_text_display_set_background_color (progress_bar->display,
PLY_TERMINAL_COLOR_BROWN);
else
break;
ply_text_display_write (progress_bar->display, "%c", ' ');
}
ply_text_display_set_background_color (progress_bar->display,
PLY_TERMINAL_COLOR_BLACK);
if (brown_fraction > 0.5) {
if (white_fraction > 0.875)
ply_text_display_set_foreground_color (progress_bar->display,
PLY_TERMINAL_COLOR_WHITE);
else if (blue_fraction > 0.66)
ply_text_display_set_foreground_color (progress_bar->display,
PLY_TERMINAL_COLOR_BLUE);
else
ply_text_display_set_foreground_color (progress_bar->display,
PLY_TERMINAL_COLOR_BROWN);
ply_text_display_set_cursor_position (progress_bar->display,
progress_bar->column + width,
progress_bar->row);
ply_text_display_write (progress_bar->display, "%s", os_string);
ply_text_display_set_foreground_color (progress_bar->display,
PLY_TERMINAL_COLOR_DEFAULT);
}
}
void
ply_text_progress_bar_show (ply_text_progress_bar_t *progress_bar,
ply_text_display_t *display)
ply_text_progress_bar_show (ply_text_progress_bar_t *progress_bar,
ply_text_display_t *display)
{
assert (progress_bar != NULL);
assert (progress_bar != NULL);
progress_bar->display = display;
progress_bar->display = display;
progress_bar->number_of_rows = ply_text_display_get_number_of_rows (display);
progress_bar->row = progress_bar->number_of_rows - 1;
progress_bar->number_of_columns = ply_text_display_get_number_of_columns (display);
progress_bar->column = 2;
progress_bar->number_of_rows = ply_text_display_get_number_of_rows (display);
progress_bar->row = progress_bar->number_of_rows - 1;
progress_bar->number_of_columns = ply_text_display_get_number_of_columns (display);
progress_bar->column = 2;
get_os_string ();
get_os_string ();
progress_bar->is_hidden = false;
progress_bar->is_hidden = false;
ply_text_progress_bar_draw (progress_bar);
ply_text_progress_bar_draw (progress_bar);
}
void
ply_text_progress_bar_hide (ply_text_progress_bar_t *progress_bar)
{
progress_bar->display = NULL;
progress_bar->is_hidden = true;
progress_bar->display = NULL;
progress_bar->is_hidden = true;
}
void
ply_text_progress_bar_set_percent_done (ply_text_progress_bar_t *progress_bar,
double percent_done)
ply_text_progress_bar_set_percent_done (ply_text_progress_bar_t *progress_bar,
double percent_done)
{
progress_bar->percent_done = percent_done;
progress_bar->percent_done = percent_done;
}
double
ply_text_progress_bar_get_percent_done (ply_text_progress_bar_t *progress_bar)
ply_text_progress_bar_get_percent_done (ply_text_progress_bar_t *progress_bar)
{
return progress_bar->percent_done;
return progress_bar->percent_done;
}
int
ply_text_progress_bar_get_number_of_columns (ply_text_progress_bar_t *progress_bar)
{
return progress_bar->number_of_columns;
return progress_bar->number_of_columns;
}
int
ply_text_progress_bar_get_number_of_rows (ply_text_progress_bar_t *progress_bar)
{
return progress_bar->number_of_rows;
return progress_bar->number_of_rows;
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -38,14 +38,14 @@ ply_text_progress_bar_t *ply_text_progress_bar_new (void);
void ply_text_progress_bar_free (ply_text_progress_bar_t *progress_bar);
void ply_text_progress_bar_draw (ply_text_progress_bar_t *progress_bar);
void ply_text_progress_bar_show (ply_text_progress_bar_t *progress_bar,
ply_text_display_t *display);
void ply_text_progress_bar_show (ply_text_progress_bar_t *progress_bar,
ply_text_display_t *display);
void ply_text_progress_bar_hide (ply_text_progress_bar_t *progress_bar);
void ply_text_progress_bar_set_percent_done (ply_text_progress_bar_t *progress_bar,
double percent_done);
void ply_text_progress_bar_set_percent_done (ply_text_progress_bar_t *progress_bar,
double percent_done);
double ply_text_progress_bar_get_percent_done (ply_text_progress_bar_t *progress_bar);
double ply_text_progress_bar_get_percent_done (ply_text_progress_bar_t *progress_bar);
int ply_text_progress_bar_get_number_of_rows (ply_text_progress_bar_t *progress_bar);
int ply_text_progress_bar_get_number_of_columns (ply_text_progress_bar_t *progress_bar);

View file

@ -30,135 +30,130 @@
struct _ply_text_step_bar
{
ply_text_display_t *display;
ply_text_display_t *display;
int column;
int row;
int number_of_rows;
int number_of_columns;
int column;
int row;
int number_of_rows;
int number_of_columns;
double percent_done;
uint32_t is_hidden : 1;
double percent_done;
uint32_t is_hidden : 1;
};
ply_text_step_bar_t *
ply_text_step_bar_new (void)
{
ply_text_step_bar_t *step_bar;
ply_text_step_bar_t *step_bar;
step_bar = calloc (1, sizeof (ply_text_step_bar_t));
step_bar = calloc (1, sizeof(ply_text_step_bar_t));
step_bar->row = 0;
step_bar->column = 0;
step_bar->number_of_columns = 0;
step_bar->number_of_rows = 0;
step_bar->row = 0;
step_bar->column = 0;
step_bar->number_of_columns = 0;
step_bar->number_of_rows = 0;
return step_bar;
return step_bar;
}
void
ply_text_step_bar_free (ply_text_step_bar_t *step_bar)
{
if (step_bar == NULL)
return;
if (step_bar == NULL)
return;
free (step_bar);
free (step_bar);
}
void
ply_text_step_bar_draw (ply_text_step_bar_t *step_bar)
{
int i;
int cur;
int i;
int cur;
if (step_bar->is_hidden)
return;
if (step_bar->is_hidden)
return;
ply_text_display_set_background_color (step_bar->display,
PLY_TERMINAL_COLOR_BLACK);
ply_text_display_set_background_color (step_bar->display,
PLY_TERMINAL_COLOR_BLACK);
ply_text_display_set_cursor_position (step_bar->display,
step_bar->column,
step_bar->row);
ply_text_display_set_cursor_position (step_bar->display,
step_bar->column,
step_bar->row);
cur = step_bar->percent_done * step_bar->number_of_columns;
for (i = 0; i < step_bar->number_of_columns; i++)
{
if (i == cur)
{
ply_text_display_set_foreground_color (step_bar->display,
PLY_TERMINAL_COLOR_WHITE);
}
else
{
ply_text_display_set_foreground_color (step_bar->display,
PLY_TERMINAL_COLOR_BROWN);
cur = step_bar->percent_done * step_bar->number_of_columns;
for (i = 0; i < step_bar->number_of_columns; i++) {
if (i == cur)
ply_text_display_set_foreground_color (step_bar->display,
PLY_TERMINAL_COLOR_WHITE);
else
ply_text_display_set_foreground_color (step_bar->display,
PLY_TERMINAL_COLOR_BROWN);
/* U+25A0 BLACK SQUARE */
ply_text_display_write (step_bar->display, "%s", "\x25\x96\xa0");
ply_text_display_write (step_bar->display, "%c", ' ');
}
/* U+25A0 BLACK SQUARE */
ply_text_display_write (step_bar->display, "%s", "\x25\x96\xa0");
ply_text_display_write (step_bar->display, "%c", ' ');
}
ply_text_display_set_foreground_color (step_bar->display,
PLY_TERMINAL_COLOR_DEFAULT);
ply_text_display_set_foreground_color (step_bar->display,
PLY_TERMINAL_COLOR_DEFAULT);
}
void
ply_text_step_bar_show (ply_text_step_bar_t *step_bar,
ply_text_display_t *display)
ply_text_step_bar_show (ply_text_step_bar_t *step_bar,
ply_text_display_t *display)
{
int screen_rows;
int screen_cols;
int screen_rows;
int screen_cols;
assert (step_bar != NULL);
assert (step_bar != NULL);
step_bar->display = display;
step_bar->display = display;
screen_rows = ply_text_display_get_number_of_rows (display);
screen_cols = ply_text_display_get_number_of_columns (display);
screen_rows = ply_text_display_get_number_of_rows (display);
screen_cols = ply_text_display_get_number_of_columns (display);
step_bar->number_of_rows = 1;
step_bar->row = screen_rows * .66;
step_bar->number_of_columns = 3;
step_bar->column = screen_cols / 2.0 - step_bar->number_of_columns / 2.0;
step_bar->number_of_rows = 1;
step_bar->row = screen_rows * .66;
step_bar->number_of_columns = 3;
step_bar->column = screen_cols / 2.0 - step_bar->number_of_columns / 2.0;
step_bar->is_hidden = false;
step_bar->is_hidden = false;
ply_text_step_bar_draw (step_bar);
ply_text_step_bar_draw (step_bar);
}
void
ply_text_step_bar_hide (ply_text_step_bar_t *step_bar)
{
step_bar->display = NULL;
step_bar->is_hidden = true;
step_bar->display = NULL;
step_bar->is_hidden = true;
}
void
ply_text_step_bar_set_percent_done (ply_text_step_bar_t *step_bar,
double percent_done)
ply_text_step_bar_set_percent_done (ply_text_step_bar_t *step_bar,
double percent_done)
{
step_bar->percent_done = percent_done;
step_bar->percent_done = percent_done;
}
double
ply_text_step_bar_get_percent_done (ply_text_step_bar_t *step_bar)
ply_text_step_bar_get_percent_done (ply_text_step_bar_t *step_bar)
{
return step_bar->percent_done;
return step_bar->percent_done;
}
int
ply_text_step_bar_get_number_of_columns (ply_text_step_bar_t *step_bar)
{
return step_bar->number_of_columns;
return step_bar->number_of_columns;
}
int
ply_text_step_bar_get_number_of_rows (ply_text_step_bar_t *step_bar)
{
return step_bar->number_of_rows;
return step_bar->number_of_rows;
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -33,11 +33,11 @@ void ply_text_step_bar_free (ply_text_step_bar_t *step_bar);
void ply_text_step_bar_draw (ply_text_step_bar_t *step_bar);
void ply_text_step_bar_show (ply_text_step_bar_t *step_bar,
ply_text_display_t *display);
ply_text_display_t *display);
void ply_text_step_bar_hide (ply_text_step_bar_t *step_bar);
void ply_text_step_bar_set_percent_done (ply_text_step_bar_t *step_bar,
double percent_done);
double percent_done);
double ply_text_step_bar_get_percent_done (ply_text_step_bar_t *step_bar);

View file

@ -56,21 +56,21 @@
struct _ply_animation
{
ply_array_t *frames;
ply_event_loop_t *loop;
char *image_dir;
char *frames_prefix;
ply_array_t *frames;
ply_event_loop_t *loop;
char *image_dir;
char *frames_prefix;
ply_pixel_display_t *display;
ply_rectangle_t frame_area;
ply_trigger_t *stop_trigger;
ply_pixel_display_t *display;
ply_rectangle_t frame_area;
ply_trigger_t *stop_trigger;
int frame_number;
long x, y;
long width, height;
double start_time, previous_time, now;
uint32_t is_stopped : 1;
uint32_t stop_requested : 1;
int frame_number;
long x, y;
long width, height;
double start_time, previous_time, now;
uint32_t is_stopped : 1;
uint32_t stop_requested : 1;
};
static void ply_animation_stop_now (ply_animation_t *animation);
@ -80,315 +80,298 @@ ply_animation_t *
ply_animation_new (const char *image_dir,
const char *frames_prefix)
{
ply_animation_t *animation;
ply_animation_t *animation;
assert (image_dir != NULL);
assert (frames_prefix != NULL);
assert (image_dir != NULL);
assert (frames_prefix != NULL);
animation = calloc (1, sizeof (ply_animation_t));
animation = calloc (1, sizeof(ply_animation_t));
animation->frames = ply_array_new (PLY_ARRAY_ELEMENT_TYPE_POINTER);
animation->frames_prefix = strdup (frames_prefix);
animation->image_dir = strdup (image_dir);
animation->frame_number = 0;
animation->is_stopped = true;
animation->stop_requested = false;
animation->width = 0;
animation->height = 0;
animation->frame_area.width = 0;
animation->frame_area.height = 0;
animation->frame_area.x = 0;
animation->frame_area.y = 0;
animation->frames = ply_array_new (PLY_ARRAY_ELEMENT_TYPE_POINTER);
animation->frames_prefix = strdup (frames_prefix);
animation->image_dir = strdup (image_dir);
animation->frame_number = 0;
animation->is_stopped = true;
animation->stop_requested = false;
animation->width = 0;
animation->height = 0;
animation->frame_area.width = 0;
animation->frame_area.height = 0;
animation->frame_area.x = 0;
animation->frame_area.y = 0;
return animation;
return animation;
}
static void
ply_animation_remove_frames (ply_animation_t *animation)
{
int i;
ply_pixel_buffer_t **frames;
int i;
ply_pixel_buffer_t **frames;
frames = (ply_pixel_buffer_t **) ply_array_steal_pointer_elements (animation->frames);
for (i = 0; frames[i] != NULL; i++)
ply_pixel_buffer_free (frames[i]);
free (frames);
frames = (ply_pixel_buffer_t **) ply_array_steal_pointer_elements (animation->frames);
for (i = 0; frames[i] != NULL; i++) {
ply_pixel_buffer_free (frames[i]);
}
free (frames);
}
void
ply_animation_free (ply_animation_t *animation)
{
if (animation == NULL)
return;
if (animation == NULL)
return;
if (!animation->is_stopped)
ply_animation_stop_now (animation);
if (!animation->is_stopped)
ply_animation_stop_now (animation);
ply_animation_remove_frames (animation);
ply_array_free (animation->frames);
ply_animation_remove_frames (animation);
ply_array_free (animation->frames);
free (animation->frames_prefix);
free (animation->image_dir);
free (animation);
free (animation->frames_prefix);
free (animation->image_dir);
free (animation);
}
static bool
animate_at_time (ply_animation_t *animation,
double time)
{
int number_of_frames;
ply_pixel_buffer_t * const * frames;
bool should_continue;
int number_of_frames;
ply_pixel_buffer_t *const *frames;
bool should_continue;
number_of_frames = ply_array_get_size (animation->frames);
number_of_frames = ply_array_get_size (animation->frames);
if (number_of_frames == 0)
return false;
if (number_of_frames == 0)
return false;
should_continue = true;
should_continue = true;
if (animation->frame_number > number_of_frames - 1)
{
ply_trace ("reached last frame of animation");
return false;
}
if (animation->frame_number > number_of_frames - 1) {
ply_trace ("reached last frame of animation");
return false;
}
if (animation->stop_requested)
{
ply_trace ("stopping animation in the middle of sequence");
should_continue = false;
}
if (animation->stop_requested) {
ply_trace ("stopping animation in the middle of sequence");
should_continue = false;
}
frames = (ply_pixel_buffer_t * const *) ply_array_get_pointer_elements (animation->frames);
ply_pixel_buffer_get_size (frames[animation->frame_number], &animation->frame_area);
animation->frame_area.x = animation->x;
animation->frame_area.y = animation->y;
frames = (ply_pixel_buffer_t *const *) ply_array_get_pointer_elements (animation->frames);
ply_pixel_buffer_get_size (frames[animation->frame_number], &animation->frame_area);
animation->frame_area.x = animation->x;
animation->frame_area.y = animation->y;
ply_pixel_display_draw_area (animation->display,
animation->x, animation->y,
animation->frame_area.width,
animation->frame_area.height);
ply_pixel_display_draw_area (animation->display,
animation->x, animation->y,
animation->frame_area.width,
animation->frame_area.height);
animation->frame_number++;
animation->frame_number++;
return should_continue;
return should_continue;
}
static void
on_timeout (ply_animation_t *animation)
{
double sleep_time;
bool should_continue;
animation->previous_time = animation->now;
animation->now = ply_get_timestamp ();
double sleep_time;
bool should_continue;
should_continue = animate_at_time (animation,
animation->now - animation->start_time);
animation->previous_time = animation->now;
animation->now = ply_get_timestamp ();
sleep_time = 1.0 / FRAMES_PER_SECOND;
sleep_time = MAX (sleep_time - (ply_get_timestamp () - animation->now),
0.005);
should_continue = animate_at_time (animation,
animation->now - animation->start_time);
if (!should_continue)
{
if (animation->stop_trigger != NULL)
{
ply_trace ("firing off stop trigger");
ply_trigger_pull (animation->stop_trigger, NULL);
animation->stop_trigger = NULL;
sleep_time = 1.0 / FRAMES_PER_SECOND;
sleep_time = MAX (sleep_time - (ply_get_timestamp () - animation->now),
0.005);
if (!should_continue) {
if (animation->stop_trigger != NULL) {
ply_trace ("firing off stop trigger");
ply_trigger_pull (animation->stop_trigger, NULL);
animation->stop_trigger = NULL;
}
} else {
ply_event_loop_watch_for_timeout (animation->loop,
sleep_time,
(ply_event_loop_timeout_handler_t)
on_timeout, animation);
}
}
else
{
ply_event_loop_watch_for_timeout (animation->loop,
sleep_time,
(ply_event_loop_timeout_handler_t)
on_timeout, animation);
}
}
static bool
ply_animation_add_frame (ply_animation_t *animation,
const char *filename)
{
ply_image_t *image;
ply_pixel_buffer_t *frame;
ply_image_t *image;
ply_pixel_buffer_t *frame;
image = ply_image_new (filename);
image = ply_image_new (filename);
if (!ply_image_load (image))
{
ply_image_free (image);
return false;
}
if (!ply_image_load (image)) {
ply_image_free (image);
return false;
}
frame = ply_image_convert_to_pixel_buffer (image);
frame = ply_image_convert_to_pixel_buffer (image);
ply_array_add_pointer_element (animation->frames, frame);
ply_array_add_pointer_element (animation->frames, frame);
animation->width = MAX (animation->width, (long) ply_pixel_buffer_get_width (frame));
animation->height = MAX (animation->height, (long) ply_pixel_buffer_get_height (frame));
animation->width = MAX (animation->width, (long) ply_pixel_buffer_get_width (frame));
animation->height = MAX (animation->height, (long) ply_pixel_buffer_get_height (frame));
return true;
return true;
}
static bool
ply_animation_add_frames (ply_animation_t *animation)
{
struct dirent **entries;
int number_of_entries;
int number_of_frames;
int i;
bool load_finished;
struct dirent **entries;
int number_of_entries;
int number_of_frames;
int i;
bool load_finished;
entries = NULL;
entries = NULL;
number_of_entries = scandir (animation->image_dir, &entries, NULL, versionsort);
number_of_entries = scandir (animation->image_dir, &entries, NULL, versionsort);
if (number_of_entries <= 0)
return false;
if (number_of_entries <= 0)
return false;
load_finished = false;
for (i = 0; i < number_of_entries; i++)
{
if (strncmp (entries[i]->d_name,
animation->frames_prefix,
strlen (animation->frames_prefix)) == 0
&& (strlen (entries[i]->d_name) > 4)
&& strcmp (entries[i]->d_name + strlen (entries[i]->d_name) - 4, ".png") == 0)
{
char *filename;
load_finished = false;
for (i = 0; i < number_of_entries; i++) {
if (strncmp (entries[i]->d_name,
animation->frames_prefix,
strlen (animation->frames_prefix)) == 0
&& (strlen (entries[i]->d_name) > 4)
&& strcmp (entries[i]->d_name + strlen (entries[i]->d_name) - 4, ".png") == 0) {
char *filename;
filename = NULL;
asprintf (&filename, "%s/%s", animation->image_dir, entries[i]->d_name);
filename = NULL;
asprintf (&filename, "%s/%s", animation->image_dir, entries[i]->d_name);
if (!ply_animation_add_frame (animation, filename))
goto out;
if (!ply_animation_add_frame (animation, filename))
goto out;
free (filename);
free (filename);
}
free (entries[i]);
entries[i] = NULL;
}
free (entries[i]);
entries[i] = NULL;
}
number_of_frames = ply_array_get_size (animation->frames);
if (number_of_frames == 0) {
ply_trace ("%s directory had no files starting with %s\n",
animation->image_dir, animation->frames_prefix);
goto out;
} else {
ply_trace ("animation has %d frames\n", number_of_frames);
}
number_of_frames = ply_array_get_size (animation->frames);
if (number_of_frames == 0)
{
ply_trace ("%s directory had no files starting with %s\n",
animation->image_dir, animation->frames_prefix);
goto out;
}
else
{
ply_trace ("animation has %d frames\n", number_of_frames);
}
load_finished = true;
load_finished = true;
out:
if (!load_finished)
{
ply_animation_remove_frames (animation);
if (!load_finished) {
ply_animation_remove_frames (animation);
while (i < number_of_entries)
{
free (entries[i]);
i++;
while (i < number_of_entries) {
free (entries[i]);
i++;
}
}
}
free (entries);
free (entries);
return load_finished;
return load_finished;
}
bool
ply_animation_load (ply_animation_t *animation)
{
if (ply_array_get_size (animation->frames) != 0)
{
ply_animation_remove_frames (animation);
ply_trace ("reloading animation with new set of frames");
}
else
{
ply_trace ("loading frames for animation");
}
if (ply_array_get_size (animation->frames) != 0) {
ply_animation_remove_frames (animation);
ply_trace ("reloading animation with new set of frames");
} else {
ply_trace ("loading frames for animation");
}
if (!ply_animation_add_frames (animation))
return false;
if (!ply_animation_add_frames (animation))
return false;
return true;
return true;
}
bool
ply_animation_start (ply_animation_t *animation,
ply_animation_start (ply_animation_t *animation,
ply_pixel_display_t *display,
ply_trigger_t *stop_trigger,
long x,
long y)
ply_trigger_t *stop_trigger,
long x,
long y)
{
assert (animation != NULL);
assert (animation != NULL);
if (!animation->is_stopped)
return true;
if (!animation->is_stopped)
return true;
ply_trace ("starting animation");
ply_trace ("starting animation");
animation->loop = ply_event_loop_get_default ();
animation->display = display;
animation->stop_trigger = stop_trigger;
animation->is_stopped = false;
animation->stop_requested = false;
animation->loop = ply_event_loop_get_default ();
animation->display = display;
animation->stop_trigger = stop_trigger;
animation->is_stopped = false;
animation->stop_requested = false;
animation->x = x;
animation->y = y;
animation->x = x;
animation->y = y;
animation->start_time = ply_get_timestamp ();
animation->start_time = ply_get_timestamp ();
ply_event_loop_watch_for_timeout (animation->loop,
1.0 / FRAMES_PER_SECOND,
(ply_event_loop_timeout_handler_t)
on_timeout, animation);
ply_event_loop_watch_for_timeout (animation->loop,
1.0 / FRAMES_PER_SECOND,
(ply_event_loop_timeout_handler_t)
on_timeout, animation);
return true;
return true;
}
static void
ply_animation_stop_now (ply_animation_t *animation)
{
animation->is_stopped = true;
animation->is_stopped = true;
ply_trace ("stopping animation now");
ply_trace ("stopping animation now");
if (animation->loop != NULL)
{
ply_event_loop_stop_watching_for_timeout (animation->loop,
(ply_event_loop_timeout_handler_t)
on_timeout, animation);
animation->loop = NULL;
}
if (animation->loop != NULL) {
ply_event_loop_stop_watching_for_timeout (animation->loop,
(ply_event_loop_timeout_handler_t)
on_timeout, animation);
animation->loop = NULL;
}
animation->display = NULL;
animation->display = NULL;
}
void
ply_animation_stop (ply_animation_t *animation)
{
if (animation->stop_trigger == NULL)
{
ply_animation_stop_now (animation);
return;
}
if (animation->stop_trigger == NULL) {
ply_animation_stop_now (animation);
return;
}
ply_trace ("stopping animation next time through the loop");
animation->stop_requested = true;
ply_trace ("stopping animation next time through the loop");
animation->stop_requested = true;
}
bool
ply_animation_is_stopped (ply_animation_t *animation)
{
return animation->is_stopped;
return animation->is_stopped;
}
void
@ -399,33 +382,33 @@ ply_animation_draw_area (ply_animation_t *animation,
unsigned long width,
unsigned long height)
{
ply_pixel_buffer_t * const * frames;
int number_of_frames;
int frame_index;
if (animation->is_stopped)
return;
ply_pixel_buffer_t *const *frames;
int number_of_frames;
int frame_index;
number_of_frames = ply_array_get_size (animation->frames);
frame_index = MIN(animation->frame_number, number_of_frames - 1);
if (animation->is_stopped)
return;
frames = (ply_pixel_buffer_t * const *) ply_array_get_pointer_elements (animation->frames);
ply_pixel_buffer_fill_with_buffer (buffer,
frames[frame_index],
animation->frame_area.x,
animation->frame_area.y);
number_of_frames = ply_array_get_size (animation->frames);
frame_index = MIN (animation->frame_number, number_of_frames - 1);
frames = (ply_pixel_buffer_t *const *) ply_array_get_pointer_elements (animation->frames);
ply_pixel_buffer_fill_with_buffer (buffer,
frames[frame_index],
animation->frame_area.x,
animation->frame_area.y);
}
long
ply_animation_get_width (ply_animation_t *animation)
{
return animation->width;
return animation->width;
}
long
ply_animation_get_height (ply_animation_t *animation)
{
return animation->height;
return animation->height;
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -38,11 +38,11 @@ ply_animation_t *ply_animation_new (const char *image_dir,
void ply_animation_free (ply_animation_t *animation);
bool ply_animation_load (ply_animation_t *animation);
bool ply_animation_start (ply_animation_t *animation,
bool ply_animation_start (ply_animation_t *animation,
ply_pixel_display_t *display,
ply_trigger_t *stop_trigger,
long x,
long y);
ply_trigger_t *stop_trigger,
long x,
long y);
void ply_animation_stop (ply_animation_t *animation);
bool ply_animation_is_stopped (ply_animation_t *animation);

View file

@ -58,103 +58,102 @@
struct _ply_entry
{
ply_event_loop_t *loop;
ply_event_loop_t *loop;
ply_pixel_display_t *display;
ply_rectangle_t area;
ply_image_t *text_field_image;
ply_image_t *bullet_image;
ply_label_t *label;
ply_pixel_display_t *display;
ply_rectangle_t area;
ply_image_t *text_field_image;
ply_image_t *bullet_image;
ply_label_t *label;
char* text;
int number_of_bullets;
int max_number_of_visible_bullets;
char *text;
int number_of_bullets;
int max_number_of_visible_bullets;
uint32_t is_hidden : 1;
uint32_t is_password : 1;
uint32_t is_hidden : 1;
uint32_t is_password : 1;
};
ply_entry_t *
ply_entry_new (const char *image_dir)
{
ply_entry_t *entry;
char *image_path;
ply_entry_t *entry;
char *image_path;
assert (image_dir != NULL);
assert (image_dir != NULL);
entry = calloc (1, sizeof (ply_entry_t));
entry = calloc (1, sizeof(ply_entry_t));
image_path = NULL;
asprintf (&image_path, "%s/entry.png", image_dir);
entry->text_field_image = ply_image_new (image_path);
free (image_path);
image_path = NULL;
asprintf (&image_path, "%s/entry.png", image_dir);
entry->text_field_image = ply_image_new (image_path);
free (image_path);
image_path = NULL;
asprintf (&image_path, "%s/bullet.png", image_dir);
entry->bullet_image = ply_image_new (image_path);
free (image_path);
entry->label = ply_label_new ();
ply_label_set_color (entry->label, 0, 0, 0, 1);
image_path = NULL;
asprintf (&image_path, "%s/bullet.png", image_dir);
entry->bullet_image = ply_image_new (image_path);
free (image_path);
entry->label = ply_label_new ();
ply_label_set_color (entry->label, 0, 0, 0, 1);
entry->number_of_bullets = 0;
entry->text = strdup("");
entry->is_hidden = true;
entry->is_password = true;
entry->number_of_bullets = 0;
entry->text = strdup ("");
return entry;
entry->is_hidden = true;
entry->is_password = true;
return entry;
}
void
ply_entry_free (ply_entry_t *entry)
{
if (entry == NULL)
return;
ply_image_free (entry->text_field_image);
ply_image_free (entry->bullet_image);
ply_label_free (entry->label);
free (entry->text);
if (entry == NULL)
return;
ply_image_free (entry->text_field_image);
ply_image_free (entry->bullet_image);
ply_label_free (entry->label);
free (entry->text);
free (entry);
free (entry);
}
static int
get_max_number_of_visible_bullets (ply_entry_t *entry)
{
long bullet_width, text_field_width;
long bullet_width, text_field_width;
bullet_width = ply_image_get_width (entry->bullet_image);
text_field_width = ply_image_get_width (entry->text_field_image);
bullet_width = ply_image_get_width (entry->bullet_image);
text_field_width = ply_image_get_width (entry->text_field_image);
return (int) (text_field_width / bullet_width) - ((text_field_width % bullet_width) < (bullet_width / 2)? 1 : 0);
return (int) (text_field_width / bullet_width) - ((text_field_width % bullet_width) < (bullet_width / 2) ? 1 : 0);
}
bool
ply_entry_load (ply_entry_t *entry)
{
if (!ply_image_load (entry->text_field_image))
return false;
if (!ply_image_load (entry->text_field_image))
return false;
if (!ply_image_load (entry->bullet_image))
return false;
if (!ply_image_load (entry->bullet_image))
return false;
entry->area.width = ply_image_get_width (entry->text_field_image);
entry->area.height = ply_image_get_height (entry->text_field_image);
entry->area.width = ply_image_get_width (entry->text_field_image);
entry->area.height = ply_image_get_height (entry->text_field_image);
entry->max_number_of_visible_bullets = get_max_number_of_visible_bullets (entry);
entry->max_number_of_visible_bullets = get_max_number_of_visible_bullets (entry);
return true;
return true;
}
static void
ply_entry_draw (ply_entry_t *entry)
{
ply_pixel_display_draw_area (entry->display,
entry->area.x,
entry->area.y,
entry->area.width,
entry->area.height);
ply_pixel_display_draw_area (entry->display,
entry->area.x,
entry->area.y,
entry->area.width,
entry->area.height);
}
void
@ -165,118 +164,111 @@ ply_entry_draw_area (ply_entry_t *entry,
unsigned long width,
unsigned long height)
{
ply_rectangle_t bullet_area;
ply_rectangle_t clip_area;
ply_pixel_buffer_t *bullet_buffer, *text_field_buffer;
int i, number_of_visible_bullets;
ply_rectangle_t bullet_area;
ply_rectangle_t clip_area;
ply_pixel_buffer_t *bullet_buffer, *text_field_buffer;
int i, number_of_visible_bullets;
if (entry->is_hidden)
return;
if (entry->is_hidden)
return;
text_field_buffer = ply_image_get_buffer (entry->text_field_image);
text_field_buffer = ply_image_get_buffer (entry->text_field_image);
ply_pixel_buffer_fill_with_buffer (pixel_buffer,
text_field_buffer,
entry->area.x,
entry->area.y);
ply_pixel_buffer_fill_with_buffer (pixel_buffer,
text_field_buffer,
entry->area.x,
entry->area.y);
if (entry->is_password)
{
bullet_buffer = ply_image_get_buffer (entry->bullet_image);
ply_pixel_buffer_get_size (bullet_buffer, &bullet_area);
if (entry->is_password) {
bullet_buffer = ply_image_get_buffer (entry->bullet_image);
ply_pixel_buffer_get_size (bullet_buffer, &bullet_area);
if (entry->number_of_bullets <= entry->max_number_of_visible_bullets)
number_of_visible_bullets = entry->number_of_bullets;
else
{
number_of_visible_bullets = entry->max_number_of_visible_bullets;
if (entry->number_of_bullets <= entry->max_number_of_visible_bullets) {
number_of_visible_bullets = entry->number_of_bullets;
} else {
number_of_visible_bullets = entry->max_number_of_visible_bullets;
/* We've got more bullets than we can show in the available space, so
* draw a little half bullet to indicate some bullets are offscreen
*/
bullet_area.x = entry->area.x - bullet_area.width / 2.0;
bullet_area.y = entry->area.y + entry->area.height / 2.0 - bullet_area.height / 2.0;
clip_area = bullet_area;
clip_area.x = entry->area.x;
ply_pixel_buffer_fill_with_buffer_with_clip (pixel_buffer,
bullet_buffer,
bullet_area.x,
bullet_area.y,
&clip_area);
/* We've got more bullets than we can show in the available space, so
* draw a little half bullet to indicate some bullets are offscreen
*/
bullet_area.x = entry->area.x - bullet_area.width / 2.0;
bullet_area.y = entry->area.y + entry->area.height / 2.0 - bullet_area.height / 2.0;
clip_area = bullet_area;
clip_area.x = entry->area.x;
ply_pixel_buffer_fill_with_buffer_with_clip (pixel_buffer,
bullet_buffer,
bullet_area.x,
bullet_area.y,
&clip_area);
}
for (i = 0; i < number_of_visible_bullets; i++) {
bullet_area.x = entry->area.x + i * bullet_area.width + bullet_area.width / 2.0;
bullet_area.y = entry->area.y + entry->area.height / 2.0 - bullet_area.height / 2.0;
ply_pixel_buffer_fill_with_buffer (pixel_buffer,
bullet_buffer,
bullet_area.x,
bullet_area.y);
}
} else {
ply_label_set_text (entry->label, entry->text);
ply_label_show (entry->label,
NULL,
entry->area.x,
entry->area.y + entry->area.height / 2
- ply_label_get_height (entry->label) / 2);
ply_label_draw_area (entry->label, pixel_buffer,
entry->area.x, entry->area.y,
entry->area.width, entry->area.height);
}
for (i = 0; i < number_of_visible_bullets; i++)
{
bullet_area.x = entry->area.x + i * bullet_area.width + bullet_area.width / 2.0;
bullet_area.y = entry->area.y + entry->area.height / 2.0 - bullet_area.height / 2.0;
ply_pixel_buffer_fill_with_buffer (pixel_buffer,
bullet_buffer,
bullet_area.x,
bullet_area.y);
}
}
else
{
ply_label_set_text (entry->label, entry->text);
ply_label_show (entry->label,
NULL,
entry->area.x,
entry->area.y + entry->area.height / 2
- ply_label_get_height (entry->label) / 2);
ply_label_draw_area (entry->label, pixel_buffer,
entry->area.x, entry->area.y,
entry->area.width, entry->area.height);
}
}
void
ply_entry_set_bullet_count (ply_entry_t *entry, int count)
{
count = MAX(0, count);
if (!entry->is_password || entry->number_of_bullets != count)
{
entry->is_password = true;
entry->number_of_bullets = count;
ply_entry_draw (entry);
}
count = MAX (0, count);
if (!entry->is_password || entry->number_of_bullets != count) {
entry->is_password = true;
entry->number_of_bullets = count;
ply_entry_draw (entry);
}
}
int
ply_entry_get_bullet_count (ply_entry_t *entry)
{
return entry->number_of_bullets;
return entry->number_of_bullets;
}
void
ply_entry_add_bullet (ply_entry_t *entry)
{
ply_entry_set_bullet_count (entry, ply_entry_get_bullet_count (entry)+1);
ply_entry_set_bullet_count (entry, ply_entry_get_bullet_count (entry) + 1);
}
void
ply_entry_remove_bullet (ply_entry_t *entry)
{
ply_entry_set_bullet_count (entry, ply_entry_get_bullet_count (entry)-1);
ply_entry_set_bullet_count (entry, ply_entry_get_bullet_count (entry) - 1);
}
void
ply_entry_remove_all_bullets (ply_entry_t *entry)
{
ply_entry_set_bullet_count (entry, 0);
ply_entry_set_bullet_count (entry, 0);
}
void
ply_entry_set_text (ply_entry_t *entry, const char* text)
ply_entry_set_text (ply_entry_t *entry, const char *text)
{
if (entry->is_password || strcmp(entry->text, text) != 0)
{
entry->is_password = false;
free(entry->text);
entry->text = strdup(text);
ply_entry_draw (entry);
}
if (entry->is_password || strcmp (entry->text, text) != 0) {
entry->is_password = false;
free (entry->text);
entry->text = strdup (text);
ply_entry_draw (entry);
}
}
void
@ -286,7 +278,7 @@ ply_entry_set_text_color (ply_entry_t *entry,
float blue,
float alpha)
{
ply_label_set_color (entry->label, red, green, blue, alpha);
ply_label_set_color (entry->label, red, green, blue, alpha);
}
@ -294,49 +286,49 @@ void
ply_entry_show (ply_entry_t *entry,
ply_event_loop_t *loop,
ply_pixel_display_t *display,
long x,
long y)
long x,
long y)
{
assert (entry != NULL);
assert (entry->loop == NULL);
assert (entry != NULL);
assert (entry->loop == NULL);
entry->loop = loop;
entry->display = display;
entry->loop = loop;
entry->display = display;
entry->area.x = x;
entry->area.y = y;
entry->area.x = x;
entry->area.y = y;
entry->is_hidden = false;
entry->is_hidden = false;
ply_entry_draw (entry);
ply_entry_draw (entry);
}
void
ply_entry_hide (ply_entry_t *entry)
{
entry->is_hidden = true;
ply_entry_draw (entry);
entry->is_hidden = true;
ply_entry_draw (entry);
entry->display = NULL;
entry->loop = NULL;
entry->display = NULL;
entry->loop = NULL;
}
bool
ply_entry_is_hidden (ply_entry_t *entry)
{
return entry->is_hidden;
return entry->is_hidden;
}
long
ply_entry_get_width (ply_entry_t *entry)
{
return entry->area.width;
return entry->area.width;
}
long
ply_entry_get_height (ply_entry_t *entry)
{
return entry->area.height;
return entry->area.height;
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -54,12 +54,14 @@ bool ply_entry_is_hidden (ply_entry_t *entry);
long ply_entry_get_width (ply_entry_t *entry);
long ply_entry_get_height (ply_entry_t *entry);
void ply_entry_set_bullet_count (ply_entry_t *entry, int count);
void ply_entry_set_bullet_count (ply_entry_t *entry,
int count);
int ply_entry_get_bullet_count (ply_entry_t *entry);
void ply_entry_add_bullet (ply_entry_t *entry);
void ply_entry_remove_bullet (ply_entry_t *entry);
void ply_entry_remove_all_bullets (ply_entry_t *entry);
void ply_entry_set_text (ply_entry_t *entry, const char* text);
void ply_entry_set_text (ply_entry_t *entry,
const char *text);
void ply_entry_set_text_color (ply_entry_t *entry,
float red,
float green,

View file

@ -51,36 +51,36 @@
struct _ply_image
{
char *filename;
ply_pixel_buffer_t *buffer;
char *filename;
ply_pixel_buffer_t *buffer;
};
ply_image_t *
ply_image_new (const char *filename)
{
ply_image_t *image;
ply_image_t *image;
assert (filename != NULL);
assert (filename != NULL);
image = calloc (1, sizeof (ply_image_t));
image = calloc (1, sizeof(ply_image_t));
image->filename = strdup (filename);
image->buffer = NULL;
image->filename = strdup (filename);
image->buffer = NULL;
return image;
return image;
}
void
ply_image_free (ply_image_t *image)
{
if (image == NULL)
return;
if (image == NULL)
return;
assert (image->filename != NULL);
ply_pixel_buffer_free (image->buffer);
free (image->filename);
free (image);
assert (image->filename != NULL);
ply_pixel_buffer_free (image->buffer);
free (image->filename);
free (image);
}
static void
@ -88,138 +88,137 @@ transform_to_argb32 (png_struct *png,
png_row_info *row_info,
png_byte *data)
{
unsigned int i;
unsigned int i;
for (i = 0; i < row_info->rowbytes; i += 4)
{
uint8_t red, green, blue, alpha;
uint32_t pixel_value;
for (i = 0; i < row_info->rowbytes; i += 4) {
uint8_t red, green, blue, alpha;
uint32_t pixel_value;
red = data[i + 0];
green = data[i + 1];
blue = data[i + 2];
alpha = data[i + 3];
red = data[i + 0];
green = data[i + 1];
blue = data[i + 2];
alpha = data[i + 3];
red = (uint8_t) CLAMP (((red / 255.0) * (alpha / 255.0)) * 255.0, 0, 255.0);
green = (uint8_t) CLAMP (((green / 255.0) * (alpha / 255.0)) * 255.0,
0, 255.0);
blue = (uint8_t) CLAMP (((blue / 255.0) * (alpha / 255.0)) * 255.0, 0, 255.0);
red = (uint8_t) CLAMP (((red / 255.0) * (alpha / 255.0)) * 255.0, 0, 255.0);
green = (uint8_t) CLAMP (((green / 255.0) * (alpha / 255.0)) * 255.0,
0, 255.0);
blue = (uint8_t) CLAMP (((blue / 255.0) * (alpha / 255.0)) * 255.0, 0, 255.0);
pixel_value = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
memcpy (data + i, &pixel_value, sizeof (uint32_t));
}
pixel_value = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
memcpy (data + i, &pixel_value, sizeof(uint32_t));
}
}
bool
ply_image_load (ply_image_t *image)
{
png_struct *png;
png_info *info;
png_uint_32 width, height, row;
int bits_per_pixel, color_type, interlace_method;
png_byte **rows;
uint32_t *bytes;
FILE *fp;
assert (image != NULL);
fp = fopen (image->filename, "re");
if (fp == NULL)
return false;
png = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
assert (png != NULL);
png_struct *png;
png_info *info;
png_uint_32 width, height, row;
int bits_per_pixel, color_type, interlace_method;
png_byte **rows;
uint32_t *bytes;
FILE *fp;
info = png_create_info_struct (png);
assert (info != NULL);
assert (image != NULL);
png_init_io (png, fp);
fp = fopen (image->filename, "re");
if (fp == NULL)
return false;
if (setjmp (png_jmpbuf (png)) != 0)
{
fclose (fp);
return false;
}
png = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
assert (png != NULL);
png_read_info (png, info);
png_get_IHDR (png, info,
&width, &height, &bits_per_pixel,
&color_type, &interlace_method, NULL, NULL);
info = png_create_info_struct (png);
assert (info != NULL);
if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb (png);
png_init_io (png, fp);
if ((color_type == PNG_COLOR_TYPE_GRAY) && (bits_per_pixel < 8))
png_set_expand_gray_1_2_4_to_8 (png);
if (setjmp (png_jmpbuf (png)) != 0) {
fclose (fp);
return false;
}
if (png_get_valid (png, info, PNG_INFO_tRNS))
png_set_tRNS_to_alpha (png);
png_read_info (png, info);
png_get_IHDR (png, info,
&width, &height, &bits_per_pixel,
&color_type, &interlace_method, NULL, NULL);
if (bits_per_pixel == 16)
png_set_strip_16 (png);
if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb (png);
if (bits_per_pixel < 8)
png_set_packing (png);
if ((color_type == PNG_COLOR_TYPE_GRAY) && (bits_per_pixel < 8))
png_set_expand_gray_1_2_4_to_8 (png);
if ((color_type == PNG_COLOR_TYPE_GRAY)
|| (color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
png_set_gray_to_rgb (png);
if (png_get_valid (png, info, PNG_INFO_tRNS))
png_set_tRNS_to_alpha (png);
if (interlace_method != PNG_INTERLACE_NONE)
png_set_interlace_handling (png);
if (bits_per_pixel == 16)
png_set_strip_16 (png);
png_set_filler (png, 0xff, PNG_FILLER_AFTER);
if (bits_per_pixel < 8)
png_set_packing (png);
png_set_read_user_transform_fn (png, transform_to_argb32);
if ((color_type == PNG_COLOR_TYPE_GRAY)
|| (color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
png_set_gray_to_rgb (png);
png_read_update_info (png, info);
if (interlace_method != PNG_INTERLACE_NONE)
png_set_interlace_handling (png);
rows = malloc (height * sizeof (png_byte *));
image->buffer = ply_pixel_buffer_new (width, height);
bytes = ply_pixel_buffer_get_argb32_data (image->buffer);
png_set_filler (png, 0xff, PNG_FILLER_AFTER);
for (row = 0; row < height; row++)
rows[row] = (png_byte*) &bytes[row * width];
png_set_read_user_transform_fn (png, transform_to_argb32);
png_read_image (png, rows);
png_read_update_info (png, info);
free (rows);
png_read_end (png, info);
fclose (fp);
png_destroy_read_struct (&png, &info, NULL);
rows = malloc (height * sizeof(png_byte *));
image->buffer = ply_pixel_buffer_new (width, height);
return true;
bytes = ply_pixel_buffer_get_argb32_data (image->buffer);
for (row = 0; row < height; row++) {
rows[row] = (png_byte *) &bytes[row * width];
}
png_read_image (png, rows);
free (rows);
png_read_end (png, info);
fclose (fp);
png_destroy_read_struct (&png, &info, NULL);
return true;
}
uint32_t *
ply_image_get_data (ply_image_t *image)
{
assert (image != NULL);
assert (image != NULL);
return ply_pixel_buffer_get_argb32_data (image->buffer);
return ply_pixel_buffer_get_argb32_data (image->buffer);
}
long
ply_image_get_width (ply_image_t *image)
{
ply_rectangle_t size;
assert (image != NULL);
ply_pixel_buffer_get_size (image->buffer, &size);
ply_rectangle_t size;
return size.width;
assert (image != NULL);
ply_pixel_buffer_get_size (image->buffer, &size);
return size.width;
}
long
ply_image_get_height (ply_image_t *image)
{
ply_rectangle_t size;
assert (image != NULL);
ply_pixel_buffer_get_size (image->buffer, &size);
ply_rectangle_t size;
return size.height;
assert (image != NULL);
ply_pixel_buffer_get_size (image->buffer, &size);
return size.height;
}
ply_image_t *
@ -227,14 +226,14 @@ ply_image_resize (ply_image_t *image,
long width,
long height)
{
ply_image_t *new_image;
new_image = ply_image_new (image->filename);
ply_image_t *new_image;
new_image->buffer = ply_pixel_buffer_resize (image->buffer,
width,
height);
return new_image;
new_image = ply_image_new (image->filename);
new_image->buffer = ply_pixel_buffer_resize (image->buffer,
width,
height);
return new_image;
}
ply_image_t *
@ -243,15 +242,15 @@ ply_image_rotate (ply_image_t *image,
long center_y,
double theta_offset)
{
ply_image_t *new_image;
new_image = ply_image_new (image->filename);
new_image->buffer = ply_pixel_buffer_rotate (image->buffer,
center_x,
center_y,
theta_offset);
return new_image;
ply_image_t *new_image;
new_image = ply_image_new (image->filename);
new_image->buffer = ply_pixel_buffer_rotate (image->buffer,
center_x,
center_y,
theta_offset);
return new_image;
}
ply_image_t *
@ -259,36 +258,36 @@ ply_image_tile (ply_image_t *image,
long width,
long height)
{
ply_image_t *new_image;
ply_image_t *new_image;
new_image = ply_image_new (image->filename);
new_image = ply_image_new (image->filename);
new_image->buffer = ply_pixel_buffer_tile (image->buffer,
width,
height);
return new_image;
new_image->buffer = ply_pixel_buffer_tile (image->buffer,
width,
height);
return new_image;
}
ply_pixel_buffer_t *
ply_image_get_buffer (ply_image_t *image)
{
assert (image != NULL);
assert (image != NULL);
return image->buffer;
return image->buffer;
}
ply_pixel_buffer_t *
ply_image_convert_to_pixel_buffer (ply_image_t *image)
{
ply_pixel_buffer_t *buffer;
ply_pixel_buffer_t *buffer;
assert (image != NULL);
assert (image != NULL);
buffer = image->buffer;
image->buffer = NULL;
ply_image_free (image);
return buffer;
buffer = image->buffer;
image->buffer = NULL;
ply_image_free (image);
return buffer;
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -1,4 +1,4 @@
/* ply-image.h - png file loader
/* ply-image.h - png file loader
*
* Copyright (C) 2007 Red Hat, Inc.
*
@ -37,9 +37,16 @@ bool ply_image_load (ply_image_t *image);
uint32_t *ply_image_get_data (ply_image_t *image);
long ply_image_get_width (ply_image_t *image);
long ply_image_get_height (ply_image_t *image);
ply_image_t *ply_image_resize (ply_image_t *image, long width, long height);
ply_image_t *ply_image_rotate (ply_image_t *oldimage, long center_x, long center_y, double theta_offset);
ply_image_t *ply_image_tile (ply_image_t *image, long width, long height);
ply_image_t *ply_image_resize (ply_image_t *image,
long width,
long height);
ply_image_t *ply_image_rotate (ply_image_t *oldimage,
long center_x,
long center_y,
double theta_offset);
ply_image_t *ply_image_tile (ply_image_t *image,
long width,
long height);
ply_pixel_buffer_t *ply_image_get_buffer (ply_image_t *image);
ply_pixel_buffer_t *ply_image_convert_to_pixel_buffer (ply_image_t *image);

View file

@ -36,38 +36,38 @@ typedef struct _ply_label_plugin_control ply_label_plugin_control_t;
typedef struct
{
ply_label_plugin_control_t * (* create_control) (void);
void (* destroy_control) (ply_label_plugin_control_t *label);
bool (* show_control) (ply_label_plugin_control_t *label,
ply_pixel_display_t *display,
long x,
long y);
void (* hide_control) (ply_label_plugin_control_t *label);
void (* draw_control) (ply_label_plugin_control_t *label,
ply_pixel_buffer_t *pixel_buffer,
long x,
long y,
unsigned long width,
unsigned long height);
bool (* is_control_hidden) (ply_label_plugin_control_t *label);
ply_label_plugin_control_t * (*create_control)(void);
void (*destroy_control)(ply_label_plugin_control_t *label);
bool (*show_control)(ply_label_plugin_control_t *label,
ply_pixel_display_t *display,
long x,
long y);
void (*hide_control)(ply_label_plugin_control_t *label);
void (*draw_control)(ply_label_plugin_control_t *label,
ply_pixel_buffer_t *pixel_buffer,
long x,
long y,
unsigned long width,
unsigned long height);
bool (*is_control_hidden)(ply_label_plugin_control_t *label);
void (* set_text_for_control) (ply_label_plugin_control_t *label,
const char *text);
void (* set_font_for_control) (ply_label_plugin_control_t *label,
const char *fontdesc);
void (* set_color_for_control) (ply_label_plugin_control_t *label,
float red,
float green,
float blue,
float alpha);
void (*set_text_for_control)(ply_label_plugin_control_t *label,
const char *text);
void (*set_font_for_control)(ply_label_plugin_control_t *label,
const char *fontdesc);
void (*set_color_for_control)(ply_label_plugin_control_t *label,
float red,
float green,
float blue,
float alpha);
long (* get_width_of_control) (ply_label_plugin_control_t *label);
long (* get_height_of_control) (ply_label_plugin_control_t *label);
long (*get_width_of_control)(ply_label_plugin_control_t *label);
long (*get_height_of_control)(ply_label_plugin_control_t *label);
void (* set_alignment_for_control) (ply_label_plugin_control_t *label,
ply_label_alignment_t alignment);
void (* set_width_for_control) (ply_label_plugin_control_t *label,
long width);
void (*set_alignment_for_control)(ply_label_plugin_control_t *label,
ply_label_alignment_t alignment);
void (*set_width_for_control)(ply_label_plugin_control_t *label,
long width);
} ply_label_plugin_interface_t;
#endif /* PLY_LABEL_PLUGIN_H */

View file

@ -40,147 +40,141 @@
struct _ply_label
{
ply_event_loop_t *loop;
ply_module_handle_t *module_handle;
const ply_label_plugin_interface_t *plugin_interface;
ply_label_plugin_control_t *control;
ply_event_loop_t *loop;
ply_module_handle_t *module_handle;
const ply_label_plugin_interface_t *plugin_interface;
ply_label_plugin_control_t *control;
char *text;
ply_label_alignment_t alignment;
long width;
char *fontdesc;
float red;
float green;
float blue;
float alpha;
char *text;
ply_label_alignment_t alignment;
long width;
char *fontdesc;
float red;
float green;
float blue;
float alpha;
};
typedef const ply_label_plugin_interface_t *
(* get_plugin_interface_function_t) (void);
(*get_plugin_interface_function_t) (void);
static void ply_label_unload_plugin (ply_label_t *label);
ply_label_t *
ply_label_new (void)
{
ply_label_t *label;
ply_label_t *label;
label = calloc (1, sizeof (struct _ply_label));
label->red = 1;
label->green = 1;
label->blue = 1;
label->alpha = 1;
label->alignment = PLY_LABEL_ALIGN_LEFT;
label->width = -1;
return label;
label = calloc (1, sizeof(struct _ply_label));
label->red = 1;
label->green = 1;
label->blue = 1;
label->alpha = 1;
label->alignment = PLY_LABEL_ALIGN_LEFT;
label->width = -1;
return label;
}
void
ply_label_free (ply_label_t *label)
{
if (label == NULL)
return;
if (label == NULL)
return;
if (label->plugin_interface != NULL)
{
ply_trace ("Unloading label control plugin");
ply_label_unload_plugin (label);
}
free (label);
if (label->plugin_interface != NULL) {
ply_trace ("Unloading label control plugin");
ply_label_unload_plugin (label);
}
free (label);
}
static bool
ply_label_load_plugin (ply_label_t *label)
{
assert (label != NULL);
assert (label != NULL);
get_plugin_interface_function_t get_label_plugin_interface;
get_plugin_interface_function_t get_label_plugin_interface;
label->module_handle = ply_open_module (PLYMOUTH_PLUGIN_PATH "label.so");
label->module_handle = ply_open_module (PLYMOUTH_PLUGIN_PATH "label.so");
if (label->module_handle == NULL)
return false;
if (label->module_handle == NULL)
return false;
get_label_plugin_interface = (get_plugin_interface_function_t)
ply_module_look_up_function (label->module_handle,
"ply_label_plugin_get_interface");
get_label_plugin_interface = (get_plugin_interface_function_t)
ply_module_look_up_function (label->module_handle,
"ply_label_plugin_get_interface");
if (get_label_plugin_interface == NULL)
{
ply_save_errno ();
ply_close_module (label->module_handle);
label->module_handle = NULL;
ply_restore_errno ();
return false;
}
if (get_label_plugin_interface == NULL) {
ply_save_errno ();
ply_close_module (label->module_handle);
label->module_handle = NULL;
ply_restore_errno ();
return false;
}
label->plugin_interface = get_label_plugin_interface ();
label->plugin_interface = get_label_plugin_interface ();
if (label->plugin_interface == NULL)
{
ply_save_errno ();
ply_close_module (label->module_handle);
label->module_handle = NULL;
ply_restore_errno ();
return false;
}
if (label->plugin_interface == NULL) {
ply_save_errno ();
ply_close_module (label->module_handle);
label->module_handle = NULL;
ply_restore_errno ();
return false;
}
label->control = label->plugin_interface->create_control ();
label->control = label->plugin_interface->create_control ();
if (label->text != NULL)
label->plugin_interface->set_text_for_control (label->control,
label->text);
label->plugin_interface->set_alignment_for_control (label->control,
label->alignment);
label->plugin_interface->set_width_for_control (label->control,
label->width);
if (label->fontdesc != NULL)
label->plugin_interface->set_font_for_control (label->control,
label->fontdesc);
if (label->text != NULL)
label->plugin_interface->set_text_for_control (label->control,
label->text);
label->plugin_interface->set_alignment_for_control (label->control,
label->alignment);
label->plugin_interface->set_width_for_control (label->control,
label->width);
if (label->fontdesc != NULL)
label->plugin_interface->set_font_for_control (label->control,
label->fontdesc);
label->plugin_interface->set_color_for_control (label->control,
label->red,
label->green,
label->blue,
label->alpha);
return true;
label->plugin_interface->set_color_for_control (label->control,
label->red,
label->green,
label->blue,
label->alpha);
return true;
}
static void
ply_label_unload_plugin (ply_label_t *label)
{
assert (label != NULL);
assert (label->plugin_interface != NULL);
assert (label->module_handle != NULL);
assert (label != NULL);
assert (label->plugin_interface != NULL);
assert (label->module_handle != NULL);
ply_close_module (label->module_handle);
label->plugin_interface = NULL;
label->module_handle = NULL;
ply_close_module (label->module_handle);
label->plugin_interface = NULL;
label->module_handle = NULL;
}
bool
ply_label_show (ply_label_t *label,
ply_label_show (ply_label_t *label,
ply_pixel_display_t *display,
long x,
long y)
long x,
long y)
{
if (label->plugin_interface == NULL)
{
if (!ply_label_load_plugin (label))
return false;
}
if (label->plugin_interface == NULL)
if (!ply_label_load_plugin (label))
return false;
return label->plugin_interface->show_control (label->control,
display, x, y);
return label->plugin_interface->show_control (label->control,
display, x, y);
}
void
ply_label_draw (ply_label_t *label)
{
if (label->plugin_interface == NULL)
return;
if (label->plugin_interface == NULL)
return;
}
void
@ -191,71 +185,70 @@ ply_label_draw_area (ply_label_t *label,
unsigned long width,
unsigned long height)
{
if (label->plugin_interface == NULL)
return;
if (label->plugin_interface == NULL)
return;
label->plugin_interface->draw_control (label->control,
buffer,
x, y, width, height);
label->plugin_interface->draw_control (label->control,
buffer,
x, y, width, height);
}
void
ply_label_hide (ply_label_t *label)
{
if (label->plugin_interface == NULL)
return;
if (label->plugin_interface == NULL)
return;
label->plugin_interface->hide_control (label->control);
label->plugin_interface->hide_control (label->control);
}
bool
ply_label_is_hidden (ply_label_t *label)
{
if (label->plugin_interface == NULL)
return true;
if (label->plugin_interface == NULL)
return true;
return label->plugin_interface->is_control_hidden (label->control);
return label->plugin_interface->is_control_hidden (label->control);
}
void
ply_label_set_text (ply_label_t *label,
const char *text)
{
free (label->text);
label->text = strdup (text);
free (label->text);
label->text = strdup (text);
if (label->plugin_interface == NULL)
return;
if (label->plugin_interface == NULL)
return;
label->plugin_interface->set_text_for_control (label->control,
text);
label->plugin_interface->set_text_for_control (label->control,
text);
}
void
ply_label_set_alignment (ply_label_t *label,
ply_label_alignment_t alignment)
ply_label_set_alignment (ply_label_t *label,
ply_label_alignment_t alignment)
{
label->alignment = alignment;
label->alignment = alignment;
if (label->plugin_interface == NULL)
return;
if (label->plugin_interface == NULL)
return;
label->plugin_interface->set_alignment_for_control (label->control,
alignment);
label->plugin_interface->set_alignment_for_control (label->control,
alignment);
}
void
ply_label_set_width (ply_label_t *label,
long width)
ply_label_set_width (ply_label_t *label,
long width)
{
label->width = width;
label->width = width;
if (label->plugin_interface == NULL)
return;
if (label->plugin_interface == NULL)
return;
label->plugin_interface->set_width_for_control (label->control,
width);
label->plugin_interface->set_width_for_control (label->control,
width);
}
/*
@ -267,18 +260,17 @@ void
ply_label_set_font (ply_label_t *label,
const char *fontdesc)
{
free (label->fontdesc);
if (fontdesc)
label->fontdesc = strdup (fontdesc);
else
label->fontdesc = NULL;
free (label->fontdesc);
if (fontdesc)
label->fontdesc = strdup (fontdesc);
else
label->fontdesc = NULL;
if (label->plugin_interface == NULL)
return;
if (label->plugin_interface == NULL)
return;
label->plugin_interface->set_font_for_control (label->control,
fontdesc);
label->plugin_interface->set_font_for_control (label->control,
fontdesc);
}
void
@ -288,36 +280,36 @@ ply_label_set_color (ply_label_t *label,
float blue,
float alpha)
{
label->red = red;
label->green = green;
label->blue = blue;
label->alpha = alpha;
label->red = red;
label->green = green;
label->blue = blue;
label->alpha = alpha;
if (label->plugin_interface == NULL)
return;
if (label->plugin_interface == NULL)
return;
label->plugin_interface->set_color_for_control (label->control,
red,
green,
blue,
alpha);
label->plugin_interface->set_color_for_control (label->control,
red,
green,
blue,
alpha);
}
long
ply_label_get_width (ply_label_t *label)
{
if (label->plugin_interface == NULL)
return 0;
if (label->plugin_interface == NULL)
return 0;
return label->plugin_interface->get_width_of_control (label->control);
return label->plugin_interface->get_width_of_control (label->control);
}
long
ply_label_get_height (ply_label_t *label)
{
if (label->plugin_interface == NULL)
return 0;
if (label->plugin_interface == NULL)
return 0;
return label->plugin_interface->get_height_of_control (label->control);
return label->plugin_interface->get_height_of_control (label->control);
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -32,23 +32,24 @@
typedef struct _ply_label ply_label_t;
typedef enum {
PLY_LABEL_ALIGN_LEFT,
PLY_LABEL_ALIGN_CENTER,
PLY_LABEL_ALIGN_RIGHT
typedef enum
{
PLY_LABEL_ALIGN_LEFT,
PLY_LABEL_ALIGN_CENTER,
PLY_LABEL_ALIGN_RIGHT
} ply_label_alignment_t;
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
ply_label_t *ply_label_new (void);
void ply_label_free (ply_label_t *label);
bool ply_label_show (ply_label_t *label,
bool ply_label_show (ply_label_t *label,
ply_pixel_display_t *display,
long x,
long y);
long x,
long y);
void ply_label_hide (ply_label_t *label);
void ply_label_draw (ply_label_t *label);
void ply_label_draw (ply_label_t *label);
void ply_label_draw_area (ply_label_t *label,
ply_pixel_buffer_t *buffer,
long x,
@ -59,10 +60,10 @@ bool ply_label_is_hidden (ply_label_t *label);
void ply_label_set_text (ply_label_t *label,
const char *text);
void ply_label_set_alignment (ply_label_t *label,
ply_label_alignment_t alignment);
void ply_label_set_width (ply_label_t *label,
long width);
void ply_label_set_alignment (ply_label_t *label,
ply_label_alignment_t alignment);
void ply_label_set_width (ply_label_t *label,
long width);
void ply_label_set_font (ply_label_t *label,
const char *fontdesc);
void ply_label_set_color (ply_label_t *label,

View file

@ -51,138 +51,136 @@
struct _ply_progress_animation
{
ply_array_t *frames;
char *image_dir;
char *frames_prefix;
ply_array_t *frames;
char *image_dir;
char *frames_prefix;
ply_progress_animation_transition_t transition;
double transition_duration;
ply_progress_animation_transition_t transition;
double transition_duration;
ply_pixel_display_t *display;
ply_rectangle_t area;
ply_rectangle_t frame_area;
ply_pixel_display_t *display;
ply_rectangle_t area;
ply_rectangle_t frame_area;
double percent_done;
int previous_frame_number;
double percent_done;
int previous_frame_number;
double transition_start_time;
double transition_start_time;
ply_pixel_buffer_t *last_rendered_frame;
ply_pixel_buffer_t *last_rendered_frame;
uint32_t is_hidden : 1;
uint32_t is_transitioning : 1;
uint32_t is_hidden : 1;
uint32_t is_transitioning : 1;
};
ply_progress_animation_t *
ply_progress_animation_new (const char *image_dir,
const char *frames_prefix)
{
ply_progress_animation_t *progress_animation;
ply_progress_animation_t *progress_animation;
assert (image_dir != NULL);
assert (frames_prefix != NULL);
assert (image_dir != NULL);
assert (frames_prefix != NULL);
progress_animation = calloc (1, sizeof (ply_progress_animation_t));
progress_animation = calloc (1, sizeof(ply_progress_animation_t));
progress_animation->frames = ply_array_new (PLY_ARRAY_ELEMENT_TYPE_POINTER);
progress_animation->frames_prefix = strdup (frames_prefix);
progress_animation->image_dir = strdup (image_dir);
progress_animation->is_hidden = true;
progress_animation->percent_done = 0.0;
progress_animation->area.x = 0;
progress_animation->area.y = 0;
progress_animation->area.width = 0;
progress_animation->area.height = 0;
progress_animation->frame_area.x = 0;
progress_animation->frame_area.y = 0;
progress_animation->frame_area.width = 0;
progress_animation->frame_area.height = 0;
progress_animation->previous_frame_number = 0;
progress_animation->last_rendered_frame = NULL;
progress_animation->frames = ply_array_new (PLY_ARRAY_ELEMENT_TYPE_POINTER);
progress_animation->frames_prefix = strdup (frames_prefix);
progress_animation->image_dir = strdup (image_dir);
progress_animation->is_hidden = true;
progress_animation->percent_done = 0.0;
progress_animation->area.x = 0;
progress_animation->area.y = 0;
progress_animation->area.width = 0;
progress_animation->area.height = 0;
progress_animation->frame_area.x = 0;
progress_animation->frame_area.y = 0;
progress_animation->frame_area.width = 0;
progress_animation->frame_area.height = 0;
progress_animation->previous_frame_number = 0;
progress_animation->last_rendered_frame = NULL;
return progress_animation;
return progress_animation;
}
void
ply_progress_animation_set_transition (ply_progress_animation_t *progress_animation,
ply_progress_animation_set_transition (ply_progress_animation_t *progress_animation,
ply_progress_animation_transition_t transition,
double duration)
double duration)
{
progress_animation->transition = transition;
progress_animation->transition_duration = duration;
progress_animation->transition = transition;
progress_animation->transition_duration = duration;
}
static void
ply_progress_animation_remove_frames (ply_progress_animation_t *progress_animation)
{
int i;
ply_image_t **frames;
int i;
ply_image_t **frames;
frames = (ply_image_t **) ply_array_steal_pointer_elements (progress_animation->frames);
for (i = 0; frames[i] != NULL; i++)
ply_image_free (frames[i]);
free (frames);
frames = (ply_image_t **) ply_array_steal_pointer_elements (progress_animation->frames);
for (i = 0; frames[i] != NULL; i++) {
ply_image_free (frames[i]);
}
free (frames);
}
void
ply_progress_animation_free (ply_progress_animation_t *progress_animation)
{
if (progress_animation == NULL)
return;
if (progress_animation == NULL)
return;
ply_progress_animation_remove_frames (progress_animation);
ply_array_free (progress_animation->frames);
ply_progress_animation_remove_frames (progress_animation);
ply_array_free (progress_animation->frames);
free (progress_animation->frames_prefix);
free (progress_animation->image_dir);
free (progress_animation);
free (progress_animation->frames_prefix);
free (progress_animation->image_dir);
free (progress_animation);
}
static void
image_fade_merge (ply_image_t* frame0,
ply_image_t* frame1,
image_fade_merge (ply_image_t *frame0,
ply_image_t *frame1,
float fade,
int width,
int height,
uint32_t *reply_data)
{
int frame0_width = ply_image_get_width (frame0);
int frame0_height = ply_image_get_height (frame0);
int frame1_width = ply_image_get_width (frame1);
int frame1_height = ply_image_get_height (frame1);
int frame0_width = ply_image_get_width (frame0);
int frame0_height = ply_image_get_height (frame0);
int frame1_width = ply_image_get_width (frame1);
int frame1_height = ply_image_get_height (frame1);
uint32_t *frame0_data = ply_image_get_data (frame0);
uint32_t *frame1_data = ply_image_get_data (frame1);
uint32_t *frame0_data = ply_image_get_data (frame0);
uint32_t *frame1_data = ply_image_get_data (frame1);
int x, y, i;
int x, y, i;
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
uint32_t pixel0, pixel1, pixelout;
if (y < frame0_height && x < frame0_width)
pixel0 = frame0_data[y*frame0_width+x];
else
pixel0 = 0;
if (y < frame1_height && x < frame1_width)
pixel1 = frame1_data[y*frame1_width+x];
else
pixel1 = 0;
pixelout = 0;
for (i = 0; i < 4; i++)
{
int subval0 = (pixel0 >> (i * 8)) & 0xFF;
int subval1 = (pixel1 >> (i * 8)) & 0xFF;
int subvalout = subval0 * (1-fade) + subval1 * fade;
pixelout |= (subvalout & 0xFF) << (i * 8);
}
reply_data[y*width+x] = pixelout;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
uint32_t pixel0, pixel1, pixelout;
if (y < frame0_height && x < frame0_width)
pixel0 = frame0_data[y * frame0_width + x];
else
pixel0 = 0;
if (y < frame1_height && x < frame1_width)
pixel1 = frame1_data[y * frame1_width + x];
else
pixel1 = 0;
pixelout = 0;
for (i = 0; i < 4; i++) {
int subval0 = (pixel0 >> (i * 8)) & 0xFF;
int subval1 = (pixel1 >> (i * 8)) & 0xFF;
int subvalout = subval0 * (1 - fade) + subval1 * fade;
pixelout |= (subvalout & 0xFF) << (i * 8);
}
reply_data[y * width + x] = pixelout;
}
}
}
}
void
@ -193,234 +191,216 @@ ply_progress_animation_draw_area (ply_progress_animation_t *progress_animation,
unsigned long width,
unsigned long height)
{
if (progress_animation->is_hidden)
return;
if (progress_animation->is_hidden)
return;
ply_pixel_buffer_fill_with_buffer (buffer,
progress_animation->last_rendered_frame,
progress_animation->frame_area.x,
progress_animation->frame_area.y);
ply_pixel_buffer_fill_with_buffer (buffer,
progress_animation->last_rendered_frame,
progress_animation->frame_area.x,
progress_animation->frame_area.y);
}
void
ply_progress_animation_draw (ply_progress_animation_t *progress_animation)
{
int number_of_frames;
int frame_number;
ply_image_t * const * frames;
ply_pixel_buffer_t *previous_frame_buffer, *current_frame_buffer;
int number_of_frames;
int frame_number;
ply_image_t *const *frames;
ply_pixel_buffer_t *previous_frame_buffer, *current_frame_buffer;
if (progress_animation->is_hidden)
return;
if (progress_animation->is_hidden)
return;
number_of_frames = ply_array_get_size (progress_animation->frames);
number_of_frames = ply_array_get_size (progress_animation->frames);
if (number_of_frames == 0)
return;
if (number_of_frames == 0)
return;
frame_number = progress_animation->percent_done * (number_of_frames - 1);
frame_number = progress_animation->percent_done * (number_of_frames - 1);
if (progress_animation->previous_frame_number != frame_number &&
progress_animation->transition != PLY_PROGRESS_ANIMATION_TRANSITION_NONE &&
progress_animation->transition_duration > 0.0)
{
progress_animation->is_transitioning = true;
progress_animation->transition_start_time = ply_get_timestamp ();
}
frames = (ply_image_t * const *) ply_array_get_pointer_elements (progress_animation->frames);
progress_animation->frame_area.x = progress_animation->area.x;
progress_animation->frame_area.y = progress_animation->area.y;
current_frame_buffer = ply_image_get_buffer (frames[frame_number]);
if (progress_animation->is_transitioning)
{
double now;
double fade_percentage;
double fade_out_opacity;
int width, height;
uint32_t* faded_data;
now = ply_get_timestamp ();
fade_percentage = (now - progress_animation->transition_start_time) / progress_animation->transition_duration;
if (fade_percentage >= 1.0)
progress_animation->is_transitioning = false;
fade_percentage = CLAMP (fade_percentage, 0.0, 1.0);
if (progress_animation->transition == PLY_PROGRESS_ANIMATION_TRANSITION_MERGE_FADE)
{
width = MAX(ply_image_get_width (frames[frame_number]), ply_image_get_width (frames[frame_number - 1]));
height = MAX(ply_image_get_height (frames[frame_number]), ply_image_get_height (frames[frame_number - 1]));
progress_animation->frame_area.width = width;
progress_animation->frame_area.height = height;
ply_pixel_buffer_free (progress_animation->last_rendered_frame);
progress_animation->last_rendered_frame = ply_pixel_buffer_new (width, height);
faded_data = ply_pixel_buffer_get_argb32_data (progress_animation->last_rendered_frame);
image_fade_merge (frames[frame_number - 1], frames[frame_number], fade_percentage, width, height, faded_data);
if (progress_animation->previous_frame_number != frame_number &&
progress_animation->transition != PLY_PROGRESS_ANIMATION_TRANSITION_NONE &&
progress_animation->transition_duration > 0.0) {
progress_animation->is_transitioning = true;
progress_animation->transition_start_time = ply_get_timestamp ();
}
else
{
previous_frame_buffer = ply_image_get_buffer (frames[frame_number - 1]);
if (progress_animation->transition == PLY_PROGRESS_ANIMATION_TRANSITION_FADE_OVER)
{
ply_pixel_buffer_free (progress_animation->last_rendered_frame);
progress_animation->last_rendered_frame = ply_pixel_buffer_new (ply_image_get_width (frames[frame_number - 1]),
ply_image_get_height (frames[frame_number - 1]));
ply_pixel_buffer_fill_with_buffer (progress_animation->last_rendered_frame,
previous_frame_buffer,
0,
0);
}
else
{
fade_out_opacity = 1.0 - fade_percentage;
ply_pixel_buffer_fill_with_buffer_at_opacity (progress_animation->last_rendered_frame,
previous_frame_buffer,
0,
0,
fade_out_opacity);
}
ply_pixel_buffer_fill_with_buffer_at_opacity (progress_animation->last_rendered_frame,
current_frame_buffer,
0,
0,
fade_percentage);
frames = (ply_image_t *const *) ply_array_get_pointer_elements (progress_animation->frames);
width = MAX(ply_image_get_width (frames[frame_number]), ply_image_get_width (frames[frame_number - 1]));
height = MAX(ply_image_get_height (frames[frame_number]), ply_image_get_height (frames[frame_number - 1]));
progress_animation->frame_area.width = width;
progress_animation->frame_area.height = height;
progress_animation->frame_area.x = progress_animation->area.x;
progress_animation->frame_area.y = progress_animation->area.y;
current_frame_buffer = ply_image_get_buffer (frames[frame_number]);
if (progress_animation->is_transitioning) {
double now;
double fade_percentage;
double fade_out_opacity;
int width, height;
uint32_t *faded_data;
now = ply_get_timestamp ();
fade_percentage = (now - progress_animation->transition_start_time) / progress_animation->transition_duration;
if (fade_percentage >= 1.0)
progress_animation->is_transitioning = false;
fade_percentage = CLAMP (fade_percentage, 0.0, 1.0);
if (progress_animation->transition == PLY_PROGRESS_ANIMATION_TRANSITION_MERGE_FADE) {
width = MAX (ply_image_get_width (frames[frame_number]), ply_image_get_width (frames[frame_number - 1]));
height = MAX (ply_image_get_height (frames[frame_number]), ply_image_get_height (frames[frame_number - 1]));
progress_animation->frame_area.width = width;
progress_animation->frame_area.height = height;
ply_pixel_buffer_free (progress_animation->last_rendered_frame);
progress_animation->last_rendered_frame = ply_pixel_buffer_new (width, height);
faded_data = ply_pixel_buffer_get_argb32_data (progress_animation->last_rendered_frame);
image_fade_merge (frames[frame_number - 1], frames[frame_number], fade_percentage, width, height, faded_data);
} else {
previous_frame_buffer = ply_image_get_buffer (frames[frame_number - 1]);
if (progress_animation->transition == PLY_PROGRESS_ANIMATION_TRANSITION_FADE_OVER) {
ply_pixel_buffer_free (progress_animation->last_rendered_frame);
progress_animation->last_rendered_frame = ply_pixel_buffer_new (ply_image_get_width (frames[frame_number - 1]),
ply_image_get_height (frames[frame_number - 1]));
ply_pixel_buffer_fill_with_buffer (progress_animation->last_rendered_frame,
previous_frame_buffer,
0,
0);
} else {
fade_out_opacity = 1.0 - fade_percentage;
ply_pixel_buffer_fill_with_buffer_at_opacity (progress_animation->last_rendered_frame,
previous_frame_buffer,
0,
0,
fade_out_opacity);
}
ply_pixel_buffer_fill_with_buffer_at_opacity (progress_animation->last_rendered_frame,
current_frame_buffer,
0,
0,
fade_percentage);
width = MAX (ply_image_get_width (frames[frame_number]), ply_image_get_width (frames[frame_number - 1]));
height = MAX (ply_image_get_height (frames[frame_number]), ply_image_get_height (frames[frame_number - 1]));
progress_animation->frame_area.width = width;
progress_animation->frame_area.height = height;
}
} else {
ply_pixel_buffer_free (progress_animation->last_rendered_frame);
progress_animation->frame_area.width = ply_image_get_width (frames[frame_number]);
progress_animation->frame_area.height = ply_image_get_height (frames[frame_number]);
progress_animation->last_rendered_frame = ply_pixel_buffer_new (progress_animation->frame_area.width,
progress_animation->frame_area.height);
ply_pixel_buffer_fill_with_buffer (progress_animation->last_rendered_frame,
current_frame_buffer,
0,
0);
}
}
else
{
ply_pixel_buffer_free (progress_animation->last_rendered_frame);
progress_animation->frame_area.width = ply_image_get_width (frames[frame_number]);
progress_animation->frame_area.height = ply_image_get_height (frames[frame_number]);
progress_animation->last_rendered_frame = ply_pixel_buffer_new (progress_animation->frame_area.width,
progress_animation->frame_area.height);
ply_pixel_buffer_fill_with_buffer (progress_animation->last_rendered_frame,
current_frame_buffer,
0,
0);
}
progress_animation->previous_frame_number = frame_number;
progress_animation->previous_frame_number = frame_number;
ply_pixel_display_draw_area (progress_animation->display,
progress_animation->frame_area.x,
progress_animation->frame_area.y,
progress_animation->frame_area.width,
progress_animation->frame_area.height);
ply_pixel_display_draw_area (progress_animation->display,
progress_animation->frame_area.x,
progress_animation->frame_area.y,
progress_animation->frame_area.width,
progress_animation->frame_area.height);
}
static bool
ply_progress_animation_add_frame (ply_progress_animation_t *progress_animation,
const char *filename)
{
ply_image_t *image;
ply_image_t *image;
image = ply_image_new (filename);
image = ply_image_new (filename);
if (!ply_image_load (image))
{
ply_image_free (image);
return false;
}
if (!ply_image_load (image)) {
ply_image_free (image);
return false;
}
ply_array_add_pointer_element (progress_animation->frames, image);
ply_array_add_pointer_element (progress_animation->frames, image);
progress_animation->area.width = MAX (progress_animation->area.width, (size_t) ply_image_get_width (image));
progress_animation->area.height = MAX (progress_animation->area.height, (size_t) ply_image_get_height (image));
progress_animation->area.width = MAX (progress_animation->area.width, (size_t) ply_image_get_width (image));
progress_animation->area.height = MAX (progress_animation->area.height, (size_t) ply_image_get_height (image));
return true;
return true;
}
static bool
ply_progress_animation_add_frames (ply_progress_animation_t *progress_animation)
{
struct dirent **entries;
int number_of_entries;
int number_of_frames;
int i;
bool load_finished;
struct dirent **entries;
int number_of_entries;
int number_of_frames;
int i;
bool load_finished;
entries = NULL;
entries = NULL;
number_of_entries = scandir (progress_animation->image_dir, &entries, NULL, versionsort);
number_of_entries = scandir (progress_animation->image_dir, &entries, NULL, versionsort);
if (number_of_entries < 0)
return false;
if (number_of_entries < 0)
return false;
load_finished = false;
for (i = 0; i < number_of_entries; i++)
{
if (strncmp (entries[i]->d_name,
progress_animation->frames_prefix,
strlen (progress_animation->frames_prefix)) == 0
&& (strlen (entries[i]->d_name) > 4)
&& strcmp (entries[i]->d_name + strlen (entries[i]->d_name) - 4, ".png") == 0)
{
char *filename;
bool r;
load_finished = false;
for (i = 0; i < number_of_entries; i++) {
if (strncmp (entries[i]->d_name,
progress_animation->frames_prefix,
strlen (progress_animation->frames_prefix)) == 0
&& (strlen (entries[i]->d_name) > 4)
&& strcmp (entries[i]->d_name + strlen (entries[i]->d_name) - 4, ".png") == 0) {
char *filename;
bool r;
filename = NULL;
asprintf (&filename, "%s/%s", progress_animation->image_dir, entries[i]->d_name);
filename = NULL;
asprintf (&filename, "%s/%s", progress_animation->image_dir, entries[i]->d_name);
r = ply_progress_animation_add_frame (progress_animation, filename);
free (filename);
if (!r)
goto out;
r = ply_progress_animation_add_frame (progress_animation, filename);
free (filename);
if (!r)
goto out;
}
free (entries[i]);
entries[i] = NULL;
}
free (entries[i]);
entries[i] = NULL;
}
number_of_frames = ply_array_get_size (progress_animation->frames);
if (number_of_frames == 0)
{
ply_trace ("could not find any progress animation frames");
load_finished = false;
}
else
{
ply_trace ("found %d progress animation frames", number_of_frames);
load_finished = true;
}
number_of_frames = ply_array_get_size (progress_animation->frames);
if (number_of_frames == 0) {
ply_trace ("could not find any progress animation frames");
load_finished = false;
} else {
ply_trace ("found %d progress animation frames", number_of_frames);
load_finished = true;
}
out:
if (!load_finished)
{
ply_progress_animation_remove_frames (progress_animation);
if (!load_finished) {
ply_progress_animation_remove_frames (progress_animation);
while (i < number_of_entries)
{
free (entries[i]);
i++;
while (i < number_of_entries) {
free (entries[i]);
i++;
}
}
}
free (entries);
free (entries);
return load_finished;
return load_finished;
}
bool
ply_progress_animation_load (ply_progress_animation_t *progress_animation)
{
if (ply_array_get_size (progress_animation->frames) != 0)
ply_progress_animation_remove_frames (progress_animation);
if (ply_array_get_size (progress_animation->frames) != 0)
ply_progress_animation_remove_frames (progress_animation);
if (!ply_progress_animation_add_frames (progress_animation))
return false;
if (!ply_progress_animation_add_frames (progress_animation))
return false;
return true;
return true;
}
void
@ -429,65 +409,64 @@ ply_progress_animation_show (ply_progress_animation_t *progress_animation,
long x,
long y)
{
assert (progress_animation != NULL);
assert (progress_animation != NULL);
progress_animation->display = display;
progress_animation->display = display;
progress_animation->area.x = x;
progress_animation->area.y = y;
progress_animation->area.x = x;
progress_animation->area.y = y;
progress_animation->is_hidden = false;
ply_progress_animation_draw (progress_animation);
progress_animation->is_hidden = false;
ply_progress_animation_draw (progress_animation);
}
void
ply_progress_animation_hide (ply_progress_animation_t *progress_animation)
{
if (progress_animation->is_hidden)
return;
if (progress_animation->is_hidden)
return;
progress_animation->is_hidden = true;
if (progress_animation->frame_area.width > 0)
{
ply_pixel_display_draw_area (progress_animation->display,
progress_animation->area.x, progress_animation->area.y,
progress_animation->frame_area.width,
progress_animation->frame_area.height);
}
progress_animation->is_hidden = true;
if (progress_animation->frame_area.width > 0) {
ply_pixel_display_draw_area (progress_animation->display,
progress_animation->area.x, progress_animation->area.y,
progress_animation->frame_area.width,
progress_animation->frame_area.height);
}
progress_animation->display = NULL;
progress_animation->display = NULL;
}
bool
ply_progress_animation_is_hidden (ply_progress_animation_t *progress_animation)
{
return progress_animation->is_hidden;
return progress_animation->is_hidden;
}
long
ply_progress_animation_get_width (ply_progress_animation_t *progress_animation)
{
return progress_animation->area.width;
return progress_animation->area.width;
}
long
ply_progress_animation_get_height (ply_progress_animation_t *progress_animation)
{
return progress_animation->area.height;
return progress_animation->area.height;
}
void
ply_progress_animation_set_percent_done (ply_progress_animation_t *progress_animation,
double percent_done)
double percent_done)
{
progress_animation->percent_done = percent_done;
ply_progress_animation_draw (progress_animation);
progress_animation->percent_done = percent_done;
ply_progress_animation_draw (progress_animation);
}
double
ply_progress_animation_get_percent_done (ply_progress_animation_t *progress_animation)
{
return progress_animation->percent_done;
return progress_animation->percent_done;
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -32,10 +32,10 @@ typedef struct _ply_progress_animation ply_progress_animation_t;
typedef enum
{
PLY_PROGRESS_ANIMATION_TRANSITION_NONE,
PLY_PROGRESS_ANIMATION_TRANSITION_FADE_OVER,
PLY_PROGRESS_ANIMATION_TRANSITION_CROSS_FADE,
PLY_PROGRESS_ANIMATION_TRANSITION_MERGE_FADE,
PLY_PROGRESS_ANIMATION_TRANSITION_NONE,
PLY_PROGRESS_ANIMATION_TRANSITION_FADE_OVER,
PLY_PROGRESS_ANIMATION_TRANSITION_CROSS_FADE,
PLY_PROGRESS_ANIMATION_TRANSITION_MERGE_FADE,
} ply_progress_animation_transition_t;
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
@ -44,9 +44,9 @@ ply_progress_animation_t *ply_progress_animation_new (const char *image_dir,
void ply_progress_animation_free (ply_progress_animation_t *progress_animation);
bool ply_progress_animation_load (ply_progress_animation_t *progress_animation);
void ply_progress_animation_set_transition (ply_progress_animation_t *progress_animation,
void ply_progress_animation_set_transition (ply_progress_animation_t *progress_animation,
ply_progress_animation_transition_t transition,
double duration);
double duration);
void ply_progress_animation_show (ply_progress_animation_t *progress_animation,
ply_pixel_display_t *display,
long x,

View file

@ -60,37 +60,37 @@
struct _ply_progress_bar
{
ply_pixel_display_t *display;
ply_rectangle_t area;
ply_pixel_display_t *display;
ply_rectangle_t area;
double percent_done;
double percent_done;
uint32_t is_hidden : 1;
uint32_t is_hidden : 1;
};
ply_progress_bar_t *
ply_progress_bar_new (void)
{
ply_progress_bar_t *progress_bar;
ply_progress_bar_t *progress_bar;
progress_bar = calloc (1, sizeof (ply_progress_bar_t));
progress_bar = calloc (1, sizeof(ply_progress_bar_t));
progress_bar->is_hidden = true;
progress_bar->percent_done = 0.0;
progress_bar->area.x = 0;
progress_bar->area.y = 0;
progress_bar->area.width = 0;
progress_bar->area.height = BAR_HEIGHT;
progress_bar->is_hidden = true;
progress_bar->percent_done = 0.0;
progress_bar->area.x = 0;
progress_bar->area.y = 0;
progress_bar->area.width = 0;
progress_bar->area.height = BAR_HEIGHT;
return progress_bar;
return progress_bar;
}
void
ply_progress_bar_free (ply_progress_bar_t *progress_bar)
{
if (progress_bar == NULL)
return;
free (progress_bar);
if (progress_bar == NULL)
return;
free (progress_bar);
}
static void
@ -98,14 +98,14 @@ ply_progress_bar_update_area (ply_progress_bar_t *progress_bar,
long x,
long y)
{
unsigned long display_width;
unsigned long display_width;
progress_bar->area.x = x;
progress_bar->area.y = y;
progress_bar->area.height = BAR_HEIGHT;
progress_bar->area.x = x;
progress_bar->area.y = y;
progress_bar->area.height = BAR_HEIGHT;
display_width = ply_pixel_display_get_width (progress_bar->display);
progress_bar->area.width = (long) (display_width * progress_bar->percent_done);
display_width = ply_pixel_display_get_width (progress_bar->display);
progress_bar->area.width = (long) (display_width * progress_bar->percent_done);
}
void
@ -116,34 +116,34 @@ ply_progress_bar_draw_area (ply_progress_bar_t *progress_bar,
unsigned long width,
unsigned long height)
{
ply_rectangle_t paint_area;
ply_rectangle_t paint_area;
if (progress_bar->is_hidden)
return;
if (progress_bar->is_hidden)
return;
paint_area.x = x;
paint_area.y = y;
paint_area.width = width;
paint_area.height = height;
paint_area.x = x;
paint_area.y = y;
paint_area.width = width;
paint_area.height = height;
ply_rectangle_intersect (&progress_bar->area, &paint_area, &paint_area);
ply_pixel_buffer_fill_with_hex_color (buffer,
&paint_area,
0xffffff); /* white */
ply_rectangle_intersect (&progress_bar->area, &paint_area, &paint_area);
ply_pixel_buffer_fill_with_hex_color (buffer,
&paint_area,
0xffffff); /* white */
}
void
ply_progress_bar_draw (ply_progress_bar_t *progress_bar)
{
if (progress_bar->is_hidden)
return;
if (progress_bar->is_hidden)
return;
ply_progress_bar_update_area (progress_bar, progress_bar->area.x, progress_bar->area.y);
ply_pixel_display_draw_area (progress_bar->display,
progress_bar->area.x,
progress_bar->area.y,
progress_bar->area.width,
progress_bar->area.height);
ply_progress_bar_update_area (progress_bar, progress_bar->area.x, progress_bar->area.y);
ply_pixel_display_draw_area (progress_bar->display,
progress_bar->area.x,
progress_bar->area.y,
progress_bar->area.width,
progress_bar->area.height);
}
void
@ -152,60 +152,59 @@ ply_progress_bar_show (ply_progress_bar_t *progress_bar,
long x,
long y)
{
assert (progress_bar != NULL);
assert (progress_bar != NULL);
progress_bar->display = display;
progress_bar->display = display;
ply_progress_bar_update_area (progress_bar, x, y);
ply_progress_bar_update_area (progress_bar, x, y);
progress_bar->is_hidden = false;
ply_progress_bar_draw (progress_bar);
progress_bar->is_hidden = false;
ply_progress_bar_draw (progress_bar);
}
void
ply_progress_bar_hide (ply_progress_bar_t *progress_bar)
{
if (progress_bar->is_hidden)
return;
if (progress_bar->is_hidden)
return;
progress_bar->is_hidden = true;
ply_pixel_display_draw_area (progress_bar->display,
progress_bar->area.x, progress_bar->area.y,
progress_bar->area.width, progress_bar->area.height);
progress_bar->display = NULL;
progress_bar->is_hidden = true;
ply_pixel_display_draw_area (progress_bar->display,
progress_bar->area.x, progress_bar->area.y,
progress_bar->area.width, progress_bar->area.height);
progress_bar->display = NULL;
}
bool
ply_progress_bar_is_hidden (ply_progress_bar_t *progress_bar)
{
return progress_bar->is_hidden;
return progress_bar->is_hidden;
}
long
ply_progress_bar_get_width (ply_progress_bar_t *progress_bar)
{
return progress_bar->area.width;
return progress_bar->area.width;
}
long
ply_progress_bar_get_height (ply_progress_bar_t *progress_bar)
{
return progress_bar->area.height;
return progress_bar->area.height;
}
void
ply_progress_bar_set_percent_done (ply_progress_bar_t *progress_bar,
double percent_done)
{
progress_bar->percent_done = percent_done;
progress_bar->percent_done = percent_done;
}
double
ply_progress_bar_get_percent_done (ply_progress_bar_t *progress_bar)
{
return progress_bar->percent_done;
return progress_bar->percent_done;
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -61,306 +61,294 @@
struct _ply_throbber
{
ply_array_t *frames;
ply_event_loop_t *loop;
char *image_dir;
char *frames_prefix;
ply_array_t *frames;
ply_event_loop_t *loop;
char *image_dir;
char *frames_prefix;
ply_pixel_display_t *display;
ply_rectangle_t frame_area;
ply_trigger_t *stop_trigger;
ply_pixel_display_t *display;
ply_rectangle_t frame_area;
ply_trigger_t *stop_trigger;
long x, y;
long width, height;
double start_time, now;
long x, y;
long width, height;
double start_time, now;
int frame_number;
uint32_t is_stopped : 1;
int frame_number;
uint32_t is_stopped : 1;
};
static void ply_throbber_stop_now (ply_throbber_t *throbber);
ply_throbber_t *
ply_throbber_new (const char *image_dir,
const char *frames_prefix)
const char *frames_prefix)
{
ply_throbber_t *throbber;
ply_throbber_t *throbber;
assert (image_dir != NULL);
assert (frames_prefix != NULL);
assert (image_dir != NULL);
assert (frames_prefix != NULL);
throbber = calloc (1, sizeof (ply_throbber_t));
throbber = calloc (1, sizeof(ply_throbber_t));
throbber->frames = ply_array_new (PLY_ARRAY_ELEMENT_TYPE_POINTER);
throbber->frames_prefix = strdup (frames_prefix);
throbber->image_dir = strdup (image_dir);
throbber->is_stopped = true;
throbber->width = 0;
throbber->height = 0;
throbber->frame_area.width = 0;
throbber->frame_area.height = 0;
throbber->frame_area.x = 0;
throbber->frame_area.y = 0;
throbber->frame_number = 0;
throbber->frames = ply_array_new (PLY_ARRAY_ELEMENT_TYPE_POINTER);
throbber->frames_prefix = strdup (frames_prefix);
throbber->image_dir = strdup (image_dir);
throbber->is_stopped = true;
throbber->width = 0;
throbber->height = 0;
throbber->frame_area.width = 0;
throbber->frame_area.height = 0;
throbber->frame_area.x = 0;
throbber->frame_area.y = 0;
throbber->frame_number = 0;
return throbber;
return throbber;
}
static void
ply_throbber_remove_frames (ply_throbber_t *throbber)
{
int i;
ply_pixel_buffer_t **frames;
int i;
ply_pixel_buffer_t **frames;
frames = (ply_pixel_buffer_t **) ply_array_steal_pointer_elements (throbber->frames);
for (i = 0; frames[i] != NULL; i++)
ply_pixel_buffer_free (frames[i]);
free (frames);
frames = (ply_pixel_buffer_t **) ply_array_steal_pointer_elements (throbber->frames);
for (i = 0; frames[i] != NULL; i++) {
ply_pixel_buffer_free (frames[i]);
}
free (frames);
}
void
ply_throbber_free (ply_throbber_t *throbber)
{
if (throbber == NULL)
return;
if (throbber == NULL)
return;
if (!throbber->is_stopped)
ply_throbber_stop_now (throbber);
if (!throbber->is_stopped)
ply_throbber_stop_now (throbber);
ply_throbber_remove_frames (throbber);
ply_array_free (throbber->frames);
ply_throbber_remove_frames (throbber);
ply_array_free (throbber->frames);
free (throbber->frames_prefix);
free (throbber->image_dir);
free (throbber);
free (throbber->frames_prefix);
free (throbber->image_dir);
free (throbber);
}
static bool
animate_at_time (ply_throbber_t *throbber,
double time)
double time)
{
int number_of_frames;
ply_pixel_buffer_t * const * frames;
bool should_continue;
double percent_in_sequence;
int number_of_frames;
ply_pixel_buffer_t *const *frames;
bool should_continue;
double percent_in_sequence;
number_of_frames = ply_array_get_size (throbber->frames);
number_of_frames = ply_array_get_size (throbber->frames);
if (number_of_frames == 0)
return true;
if (number_of_frames == 0)
return true;
should_continue = true;
percent_in_sequence = fmod (time, THROBBER_DURATION) / THROBBER_DURATION;
throbber->frame_number = (int) (number_of_frames * percent_in_sequence);
should_continue = true;
percent_in_sequence = fmod (time, THROBBER_DURATION) / THROBBER_DURATION;
throbber->frame_number = (int) (number_of_frames * percent_in_sequence);
if (throbber->stop_trigger != NULL)
{
if (throbber->frame_number == number_of_frames - 1)
should_continue = false;
}
if (throbber->stop_trigger != NULL)
if (throbber->frame_number == number_of_frames - 1)
should_continue = false;
frames = (ply_pixel_buffer_t * const *) ply_array_get_pointer_elements (throbber->frames);
ply_pixel_buffer_get_size (frames[throbber->frame_number], &throbber->frame_area);
throbber->frame_area.x = throbber->x;
throbber->frame_area.y = throbber->y;
ply_pixel_display_draw_area (throbber->display,
throbber->x, throbber->y,
throbber->frame_area.width,
throbber->frame_area.height);
frames = (ply_pixel_buffer_t *const *) ply_array_get_pointer_elements (throbber->frames);
ply_pixel_buffer_get_size (frames[throbber->frame_number], &throbber->frame_area);
throbber->frame_area.x = throbber->x;
throbber->frame_area.y = throbber->y;
ply_pixel_display_draw_area (throbber->display,
throbber->x, throbber->y,
throbber->frame_area.width,
throbber->frame_area.height);
return should_continue;
return should_continue;
}
static void
on_timeout (ply_throbber_t *throbber)
{
double sleep_time;
bool should_continue;
throbber->now = ply_get_timestamp ();
double sleep_time;
bool should_continue;
should_continue = animate_at_time (throbber,
throbber->now - throbber->start_time);
throbber->now = ply_get_timestamp ();
sleep_time = 1.0 / FRAMES_PER_SECOND;
sleep_time = MAX (sleep_time - (ply_get_timestamp () - throbber->now),
0.005);
should_continue = animate_at_time (throbber,
throbber->now - throbber->start_time);
if (!should_continue)
{
throbber->is_stopped = true;
if (throbber->stop_trigger != NULL)
{
ply_trigger_pull (throbber->stop_trigger, NULL);
throbber->stop_trigger = NULL;
sleep_time = 1.0 / FRAMES_PER_SECOND;
sleep_time = MAX (sleep_time - (ply_get_timestamp () - throbber->now),
0.005);
if (!should_continue) {
throbber->is_stopped = true;
if (throbber->stop_trigger != NULL) {
ply_trigger_pull (throbber->stop_trigger, NULL);
throbber->stop_trigger = NULL;
}
} else {
ply_event_loop_watch_for_timeout (throbber->loop,
sleep_time,
(ply_event_loop_timeout_handler_t)
on_timeout, throbber);
}
}
else
{
ply_event_loop_watch_for_timeout (throbber->loop,
sleep_time,
(ply_event_loop_timeout_handler_t)
on_timeout, throbber);
}
}
static bool
ply_throbber_add_frame (ply_throbber_t *throbber,
const char *filename)
{
ply_image_t *image;
ply_pixel_buffer_t *frame;
ply_image_t *image;
ply_pixel_buffer_t *frame;
image = ply_image_new (filename);
image = ply_image_new (filename);
if (!ply_image_load (image))
{
ply_image_free (image);
return false;
}
if (!ply_image_load (image)) {
ply_image_free (image);
return false;
}
frame = ply_image_convert_to_pixel_buffer (image);
frame = ply_image_convert_to_pixel_buffer (image);
ply_array_add_pointer_element (throbber->frames, frame);
ply_array_add_pointer_element (throbber->frames, frame);
throbber->width = MAX (throbber->width, (long) ply_pixel_buffer_get_width (frame));
throbber->height = MAX (throbber->height, (long)ply_pixel_buffer_get_height (frame));
throbber->width = MAX (throbber->width, (long) ply_pixel_buffer_get_width (frame));
throbber->height = MAX (throbber->height, (long) ply_pixel_buffer_get_height (frame));
return true;
return true;
}
static bool
ply_throbber_add_frames (ply_throbber_t *throbber)
{
struct dirent **entries;
int number_of_entries;
int i;
bool load_finished;
struct dirent **entries;
int number_of_entries;
int i;
bool load_finished;
entries = NULL;
entries = NULL;
number_of_entries = scandir (throbber->image_dir, &entries, NULL, versionsort);
number_of_entries = scandir (throbber->image_dir, &entries, NULL, versionsort);
if (number_of_entries < 0)
return false;
if (number_of_entries < 0)
return false;
load_finished = false;
for (i = 0; i < number_of_entries; i++)
{
if (strncmp (entries[i]->d_name,
throbber->frames_prefix,
strlen (throbber->frames_prefix)) == 0
&& (strlen (entries[i]->d_name) > 4)
&& strcmp (entries[i]->d_name + strlen (entries[i]->d_name) - 4, ".png") == 0)
{
char *filename;
load_finished = false;
for (i = 0; i < number_of_entries; i++) {
if (strncmp (entries[i]->d_name,
throbber->frames_prefix,
strlen (throbber->frames_prefix)) == 0
&& (strlen (entries[i]->d_name) > 4)
&& strcmp (entries[i]->d_name + strlen (entries[i]->d_name) - 4, ".png") == 0) {
char *filename;
filename = NULL;
asprintf (&filename, "%s/%s", throbber->image_dir, entries[i]->d_name);
filename = NULL;
asprintf (&filename, "%s/%s", throbber->image_dir, entries[i]->d_name);
if (!ply_throbber_add_frame (throbber, filename))
goto out;
if (!ply_throbber_add_frame (throbber, filename))
goto out;
free (filename);
free (filename);
}
free (entries[i]);
entries[i] = NULL;
}
free (entries[i]);
entries[i] = NULL;
}
load_finished = true;
load_finished = true;
out:
if (!load_finished)
{
ply_throbber_remove_frames (throbber);
if (!load_finished) {
ply_throbber_remove_frames (throbber);
while (entries[i] != NULL)
{
free (entries[i]);
i++;
while (entries[i] != NULL) {
free (entries[i]);
i++;
}
}
}
free (entries);
free (entries);
return load_finished;
return load_finished;
}
bool
ply_throbber_load (ply_throbber_t *throbber)
{
if (ply_array_get_size (throbber->frames) != 0)
ply_throbber_remove_frames (throbber);
if (ply_array_get_size (throbber->frames) != 0)
ply_throbber_remove_frames (throbber);
if (!ply_throbber_add_frames (throbber))
return false;
if (!ply_throbber_add_frames (throbber))
return false;
return true;
return true;
}
bool
ply_throbber_start (ply_throbber_t *throbber,
ply_event_loop_t *loop,
ply_pixel_display_t *display,
long x,
long y)
ply_throbber_start (ply_throbber_t *throbber,
ply_event_loop_t *loop,
ply_pixel_display_t *display,
long x,
long y)
{
assert (throbber != NULL);
assert (throbber->loop == NULL);
assert (throbber != NULL);
assert (throbber->loop == NULL);
throbber->loop = loop;
throbber->display = display;
throbber->is_stopped = false;
throbber->loop = loop;
throbber->display = display;
throbber->is_stopped = false;
throbber->x = x;
throbber->y = y;
throbber->x = x;
throbber->y = y;
throbber->start_time = ply_get_timestamp ();
throbber->start_time = ply_get_timestamp ();
ply_event_loop_watch_for_timeout (throbber->loop,
1.0 / FRAMES_PER_SECOND,
(ply_event_loop_timeout_handler_t)
on_timeout, throbber);
ply_event_loop_watch_for_timeout (throbber->loop,
1.0 / FRAMES_PER_SECOND,
(ply_event_loop_timeout_handler_t)
on_timeout, throbber);
return true;
return true;
}
static void
ply_throbber_stop_now (ply_throbber_t *throbber)
{
throbber->is_stopped = true;
throbber->is_stopped = true;
ply_pixel_display_draw_area (throbber->display,
throbber->x,
throbber->y,
throbber->frame_area.width,
throbber->frame_area.height);
if (throbber->loop != NULL)
{
ply_event_loop_stop_watching_for_timeout (throbber->loop,
(ply_event_loop_timeout_handler_t)
on_timeout, throbber);
throbber->loop = NULL;
}
throbber->display = NULL;
ply_pixel_display_draw_area (throbber->display,
throbber->x,
throbber->y,
throbber->frame_area.width,
throbber->frame_area.height);
if (throbber->loop != NULL) {
ply_event_loop_stop_watching_for_timeout (throbber->loop,
(ply_event_loop_timeout_handler_t)
on_timeout, throbber);
throbber->loop = NULL;
}
throbber->display = NULL;
}
void
ply_throbber_stop (ply_throbber_t *throbber,
ply_trigger_t *stop_trigger)
{
if (stop_trigger == NULL) {
ply_throbber_stop_now (throbber);
return;
}
if (stop_trigger == NULL)
{
ply_throbber_stop_now (throbber);
return;
}
throbber->stop_trigger = stop_trigger;
throbber->stop_trigger = stop_trigger;
}
bool
ply_throbber_is_stopped (ply_throbber_t *throbber)
{
return throbber->is_stopped;
return throbber->is_stopped;
}
void
@ -371,28 +359,28 @@ ply_throbber_draw_area (ply_throbber_t *throbber,
unsigned long width,
unsigned long height)
{
ply_pixel_buffer_t * const * frames;
ply_pixel_buffer_t *const *frames;
if (throbber->is_stopped)
return;
if (throbber->is_stopped)
return;
frames = (ply_pixel_buffer_t * const *) ply_array_get_pointer_elements (throbber->frames);
ply_pixel_buffer_fill_with_buffer (buffer,
frames[throbber->frame_number],
throbber->x,
throbber->y);
frames = (ply_pixel_buffer_t *const *) ply_array_get_pointer_elements (throbber->frames);
ply_pixel_buffer_fill_with_buffer (buffer,
frames[throbber->frame_number],
throbber->x,
throbber->y);
}
long
ply_throbber_get_width (ply_throbber_t *throbber)
{
return throbber->width;
return throbber->width;
}
long
ply_throbber_get_height (ply_throbber_t *throbber)
{
return throbber->height;
return throbber->height;
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -39,7 +39,7 @@ ply_throbber_t *ply_throbber_new (const char *image_dir,
void ply_throbber_free (ply_throbber_t *throbber);
bool ply_throbber_load (ply_throbber_t *throbber);
bool ply_throbber_start (ply_throbber_t *throbber,
bool ply_throbber_start (ply_throbber_t *throbber,
ply_event_loop_t *loop,
ply_pixel_display_t *display,
long x,

View file

@ -34,141 +34,139 @@ static const uint32_t uint32_terminator = 0;
struct _ply_array
{
ply_buffer_t *buffer;
ply_array_element_type_t element_type;
ply_buffer_t *buffer;
ply_array_element_type_t element_type;
};
ply_array_t *
ply_array_new (ply_array_element_type_t element_type)
{
ply_array_t *array;
ply_array_t *array;
array = calloc (1, sizeof (ply_array_t));
array = calloc (1, sizeof(ply_array_t));
array->buffer = ply_buffer_new ();
array->element_type = element_type;
array->buffer = ply_buffer_new ();
array->element_type = element_type;
switch (array->element_type)
{
case PLY_ARRAY_ELEMENT_TYPE_POINTER:
ply_buffer_append_bytes (array->buffer, &pointer_terminator, sizeof (pointer_terminator));
break;
switch (array->element_type) {
case PLY_ARRAY_ELEMENT_TYPE_POINTER:
ply_buffer_append_bytes (array->buffer, &pointer_terminator, sizeof(pointer_terminator));
break;
case PLY_ARRAY_ELEMENT_TYPE_UINT32:
ply_buffer_append_bytes (array->buffer, &uint32_terminator, sizeof (uint32_terminator));
break;
}
case PLY_ARRAY_ELEMENT_TYPE_UINT32:
ply_buffer_append_bytes (array->buffer, &uint32_terminator, sizeof(uint32_terminator));
break;
}
return array;
return array;
}
void
ply_array_free (ply_array_t *array)
{
if (array == NULL)
return;
if (array == NULL)
return;
ply_buffer_free (array->buffer);
ply_buffer_free (array->buffer);
free (array);
free (array);
}
int
ply_array_get_size (ply_array_t *array)
{
int size;
int size;
assert (array->element_type == PLY_ARRAY_ELEMENT_TYPE_POINTER ||
array->element_type == PLY_ARRAY_ELEMENT_TYPE_UINT32);
assert (array->element_type == PLY_ARRAY_ELEMENT_TYPE_POINTER ||
array->element_type == PLY_ARRAY_ELEMENT_TYPE_UINT32);
switch (array->element_type)
{
case PLY_ARRAY_ELEMENT_TYPE_POINTER:
size = (ply_buffer_get_size (array->buffer) / sizeof (const void *)) - 1;
break;
switch (array->element_type) {
case PLY_ARRAY_ELEMENT_TYPE_POINTER:
size = (ply_buffer_get_size (array->buffer) / sizeof(const void *)) - 1;
break;
case PLY_ARRAY_ELEMENT_TYPE_UINT32:
size = (ply_buffer_get_size (array->buffer) / sizeof (const uint32_t)) - 1;
break;
}
case PLY_ARRAY_ELEMENT_TYPE_UINT32:
size = (ply_buffer_get_size (array->buffer) / sizeof(const uint32_t)) - 1;
break;
}
return size;
return size;
}
void
ply_array_add_pointer_element (ply_array_t *array,
const void *data)
{
assert (array->element_type == PLY_ARRAY_ELEMENT_TYPE_POINTER);
assert (array->element_type == PLY_ARRAY_ELEMENT_TYPE_POINTER);
/* Temporarily remove NULL terminator
*/
ply_buffer_remove_bytes_at_end (array->buffer, sizeof (pointer_terminator));
/* Temporarily remove NULL terminator
*/
ply_buffer_remove_bytes_at_end (array->buffer, sizeof(pointer_terminator));
ply_buffer_append_bytes (array->buffer, &data, sizeof (const void *));
ply_buffer_append_bytes (array->buffer, &data, sizeof(const void *));
/* Add NULL terminator back
*/
ply_buffer_append_bytes (array->buffer, &pointer_terminator, sizeof (pointer_terminator));
/* Add NULL terminator back
*/
ply_buffer_append_bytes (array->buffer, &pointer_terminator, sizeof(pointer_terminator));
}
void
ply_array_add_uint32_element (ply_array_t *array,
const uint32_t data)
ply_array_add_uint32_element (ply_array_t *array,
const uint32_t data)
{
assert (array->element_type == PLY_ARRAY_ELEMENT_TYPE_UINT32);
assert (array->element_type == PLY_ARRAY_ELEMENT_TYPE_UINT32);
/* Temporarily remove 0 terminator
*/
ply_buffer_remove_bytes_at_end (array->buffer, sizeof (uint32_terminator));
/* Temporarily remove 0 terminator
*/
ply_buffer_remove_bytes_at_end (array->buffer, sizeof(uint32_terminator));
ply_buffer_append_bytes (array->buffer, &data, sizeof (const uint32_t));
ply_buffer_append_bytes (array->buffer, &data, sizeof(const uint32_t));
/* Add 0 terminator back
*/
ply_buffer_append_bytes (array->buffer, &uint32_terminator, sizeof (uint32_terminator));
/* Add 0 terminator back
*/
ply_buffer_append_bytes (array->buffer, &uint32_terminator, sizeof(uint32_terminator));
}
void * const *
void *const *
ply_array_get_pointer_elements (ply_array_t *array)
{
assert (array->element_type == PLY_ARRAY_ELEMENT_TYPE_POINTER);
return (void * const *) ply_buffer_get_bytes (array->buffer);
assert (array->element_type == PLY_ARRAY_ELEMENT_TYPE_POINTER);
return (void *const *) ply_buffer_get_bytes (array->buffer);
}
uint32_t const *
ply_array_get_uint32_elements (ply_array_t *array)
{
assert (array->element_type == PLY_ARRAY_ELEMENT_TYPE_UINT32);
return (uint32_t const *) ply_buffer_get_bytes (array->buffer);
assert (array->element_type == PLY_ARRAY_ELEMENT_TYPE_UINT32);
return (uint32_t const *) ply_buffer_get_bytes (array->buffer);
}
void **
ply_array_steal_pointer_elements (ply_array_t *array)
{
void **data;
void **data;
assert (array->element_type == PLY_ARRAY_ELEMENT_TYPE_POINTER);
assert (array->element_type == PLY_ARRAY_ELEMENT_TYPE_POINTER);
data = (void **) ply_buffer_steal_bytes (array->buffer);
data = (void **) ply_buffer_steal_bytes (array->buffer);
ply_buffer_append_bytes (array->buffer, &pointer_terminator, sizeof (const void *));
ply_buffer_append_bytes (array->buffer, &pointer_terminator, sizeof(const void *));
return data;
return data;
}
uint32_t *
ply_array_steal_uint32_elements (ply_array_t *array)
{
uint32_t *data;
uint32_t *data;
assert (array->element_type == PLY_ARRAY_ELEMENT_TYPE_UINT32);
assert (array->element_type == PLY_ARRAY_ELEMENT_TYPE_UINT32);
data = (uint32_t *) ply_buffer_steal_bytes (array->buffer);
data = (uint32_t *) ply_buffer_steal_bytes (array->buffer);
ply_buffer_append_bytes (array->buffer, &uint32_terminator, sizeof (const uint32_t));
ply_buffer_append_bytes (array->buffer, &uint32_terminator, sizeof(const uint32_t));
return data;
return data;
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -29,8 +29,8 @@ typedef enum _ply_array_element_type ply_array_element_type_t;
enum _ply_array_element_type
{
PLY_ARRAY_ELEMENT_TYPE_POINTER,
PLY_ARRAY_ELEMENT_TYPE_UINT32
PLY_ARRAY_ELEMENT_TYPE_POINTER,
PLY_ARRAY_ELEMENT_TYPE_UINT32
};
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
@ -39,9 +39,9 @@ void ply_array_free (ply_array_t *array);
int ply_array_get_size (ply_array_t *array);
void ply_array_add_pointer_element (ply_array_t *array,
const void *element);
void ply_array_add_uint32_element (ply_array_t *array,
const uint32_t element);
void * const *ply_array_get_pointer_elements (ply_array_t *array);
void ply_array_add_uint32_element (ply_array_t *array,
const uint32_t element);
void *const *ply_array_get_pointer_elements (ply_array_t *array);
uint32_t const *ply_array_get_uint32_elements (ply_array_t *array);
void **ply_array_steal_pointer_elements (ply_array_t *array);

View file

@ -34,12 +34,13 @@ int
ply_bitarray_count (ply_bitarray_t *bitarray,
int size)
{
int count = 0;
int i;
for (i = 0; i < size; i++){
count += ply_bitarray_lookup(bitarray, i);
}
return count;
int count = 0;
int i;
for (i = 0; i < size; i++) {
count += ply_bitarray_lookup (bitarray, i);
}
return count;
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -26,12 +26,12 @@
#include <stdbool.h>
#define PLY_BITARRAY_BASE_SIZE 32
#define PLY_BITARRAY_BASE_MASK (PLY_BITARRAY_BASE_SIZE-1)
#define PLY_BITARRAY_BASE_MASK (PLY_BITARRAY_BASE_SIZE - 1)
typedef uint32_t ply_bitarray_t;
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
#define ply_bitarray_new(size) calloc ((size + PLY_BITARRAY_BASE_SIZE - 1) / PLY_BITARRAY_BASE_SIZE, sizeof (ply_bitarray_t))
#define ply_bitarray_new(size) calloc ((size + PLY_BITARRAY_BASE_SIZE - 1) / PLY_BITARRAY_BASE_SIZE, sizeof(ply_bitarray_t))
#define ply_bitarray_free(bitarray) free (bitarray)
#define ply_bitarray_lookup(bitarray, index) ((bitarray[index / PLY_BITARRAY_BASE_SIZE] >> (index & PLY_BITARRAY_BASE_MASK)) & 1)
#define ply_bitarray_set(bitarray, index) (bitarray[index / PLY_BITARRAY_BASE_SIZE] |= 1 << (index & PLY_BITARRAY_BASE_MASK))

View file

@ -48,132 +48,130 @@
struct _ply_buffer
{
char *data;
size_t size;
size_t capacity;
char *data;
size_t size;
size_t capacity;
};
static bool
ply_buffer_increase_capacity (ply_buffer_t *buffer)
{
assert (buffer != NULL);
assert (buffer != NULL);
if ((buffer->capacity * 2) > PLY_BUFFER_MAX_BUFFER_CAPACITY)
return false;
if ((buffer->capacity * 2) > PLY_BUFFER_MAX_BUFFER_CAPACITY)
return false;
buffer->capacity *= 2;
buffer->capacity *= 2;
buffer->data = realloc (buffer->data, buffer->capacity);
return true;
buffer->data = realloc (buffer->data, buffer->capacity);
return true;
}
void
ply_buffer_remove_bytes (ply_buffer_t *buffer,
size_t bytes_to_remove)
{
assert (buffer != NULL);
assert (buffer != NULL);
bytes_to_remove = MIN (buffer->size, bytes_to_remove);
bytes_to_remove = MIN (buffer->size, bytes_to_remove);
if (bytes_to_remove == buffer->size)
buffer->size = 0;
else
{
memmove (buffer->data, buffer->data + bytes_to_remove,
buffer->size - bytes_to_remove);
buffer->size -= bytes_to_remove;
}
buffer->data[buffer->size] = '\0';
if (bytes_to_remove == buffer->size) {
buffer->size = 0;
} else {
memmove (buffer->data, buffer->data + bytes_to_remove,
buffer->size - bytes_to_remove);
buffer->size -= bytes_to_remove;
}
buffer->data[buffer->size] = '\0';
}
void
ply_buffer_remove_bytes_at_end (ply_buffer_t *buffer,
size_t bytes_to_remove)
{
assert (buffer != NULL);
assert (buffer != NULL);
bytes_to_remove = MIN (buffer->size, bytes_to_remove);
bytes_to_remove = MIN (buffer->size, bytes_to_remove);
buffer->size -= bytes_to_remove;
buffer->data[buffer->size] = '\0';
buffer->size -= bytes_to_remove;
buffer->data[buffer->size] = '\0';
}
ply_buffer_t *
ply_buffer_new (void)
{
ply_buffer_t *buffer;
ply_buffer_t *buffer;
buffer = calloc (1, sizeof (ply_buffer_t));
buffer = calloc (1, sizeof(ply_buffer_t));
buffer->capacity = 4096;
buffer->data = calloc (1, buffer->capacity);
buffer->size = 0;
buffer->capacity = 4096;
buffer->data = calloc (1, buffer->capacity);
buffer->size = 0;
return buffer;
return buffer;
}
void
ply_buffer_free (ply_buffer_t *buffer)
{
if (buffer == NULL)
return;
if (buffer == NULL)
return;
free (buffer->data);
free (buffer);
free (buffer->data);
free (buffer);
}
static bool
ply_buffer_validate_format_string (ply_buffer_t *buffer,
const char *format)
ply_buffer_validate_format_string (ply_buffer_t *buffer,
const char *format)
{
char *n, *p;
char *n, *p;
p = (char *) format;
p = (char *) format;
/* lame checks to limit the damage
* of some potential exploits.
*/
while ((n = strstr (p, "%n")) != NULL)
{
if (n == format)
return false;
/* lame checks to limit the damage
* of some potential exploits.
*/
while ((n = strstr (p, "%n")) != NULL) {
if (n == format)
return false;
if (n[-1] != '%')
return false;
if (n[-1] != '%')
return false;
p = n + 1;
}
p = n + 1;
}
return true;
return true;
}
void
ply_buffer_append_with_non_literal_format_string (ply_buffer_t *buffer,
const char *format,
ply_buffer_append_with_non_literal_format_string (ply_buffer_t *buffer,
const char *format,
...)
{
va_list args;
size_t string_size;
char write_buffer[PLY_BUFFER_MAX_APPEND_SIZE] = "";
va_list args;
size_t string_size;
char write_buffer[PLY_BUFFER_MAX_APPEND_SIZE] = "";
assert (buffer != NULL);
assert (buffer != NULL);
if (!ply_buffer_validate_format_string (buffer, format))
return;
if (!ply_buffer_validate_format_string (buffer, format))
return;
va_start (args, format);
string_size = vsnprintf (write_buffer, 0, format, args) + 1;
va_end (args);
va_start (args, format);
string_size = vsnprintf (write_buffer, 0, format, args) + 1;
va_end (args);
if (string_size > PLY_BUFFER_MAX_APPEND_SIZE)
return;
if (string_size > PLY_BUFFER_MAX_APPEND_SIZE)
return;
va_start (args, format);
vsnprintf (write_buffer, PLY_BUFFER_MAX_APPEND_SIZE,
format, args);
va_end (args);
va_start (args, format);
vsnprintf (write_buffer, PLY_BUFFER_MAX_APPEND_SIZE,
format, args);
va_end (args);
ply_buffer_append_bytes (buffer, write_buffer, string_size - 1);
ply_buffer_append_bytes (buffer, write_buffer, string_size - 1);
}
void
@ -181,86 +179,83 @@ ply_buffer_append_bytes (ply_buffer_t *buffer,
const void *bytes_in,
size_t length)
{
assert (buffer != NULL);
assert (bytes_in != NULL);
assert (length != 0);
const uint8_t *bytes = bytes_in;
if (length >PLY_BUFFER_MAX_BUFFER_CAPACITY){
bytes += length - (PLY_BUFFER_MAX_BUFFER_CAPACITY-1);
length = (PLY_BUFFER_MAX_BUFFER_CAPACITY-1);
}
while ((buffer->size + length) >= buffer->capacity)
{
if (!ply_buffer_increase_capacity (buffer))
{
ply_buffer_remove_bytes (buffer, length);
assert (buffer != NULL);
assert (bytes_in != NULL);
assert (length != 0);
const uint8_t *bytes = bytes_in;
if (length > PLY_BUFFER_MAX_BUFFER_CAPACITY) {
bytes += length - (PLY_BUFFER_MAX_BUFFER_CAPACITY - 1);
length = (PLY_BUFFER_MAX_BUFFER_CAPACITY - 1);
}
}
assert (buffer->size + length < buffer->capacity);
while ((buffer->size + length) >= buffer->capacity) {
if (!ply_buffer_increase_capacity (buffer))
ply_buffer_remove_bytes (buffer, length);
}
memcpy (buffer->data + buffer->size,
bytes, length);
assert (buffer->size + length < buffer->capacity);
buffer->size += length;
buffer->data[buffer->size] = '\0';
memcpy (buffer->data + buffer->size,
bytes, length);
buffer->size += length;
buffer->data[buffer->size] = '\0';
}
void
ply_buffer_append_from_fd (ply_buffer_t *buffer,
int fd)
{
char bytes[PLY_BUFFER_MAX_APPEND_SIZE] = "";
ssize_t bytes_read;
char bytes[PLY_BUFFER_MAX_APPEND_SIZE] = "";
ssize_t bytes_read;
assert (buffer != NULL);
assert (fd >= 0);
assert (buffer != NULL);
assert (fd >= 0);
if (!ply_fd_has_data (fd))
return;
if (!ply_fd_has_data (fd))
return;
bytes_read = read (fd, bytes, sizeof(bytes));
bytes_read = read (fd, bytes, sizeof (bytes));
if (bytes_read > 0)
ply_buffer_append_bytes (buffer, bytes, bytes_read);
if (bytes_read > 0)
ply_buffer_append_bytes (buffer, bytes, bytes_read);
}
const char *
ply_buffer_get_bytes (ply_buffer_t *buffer)
{
assert (buffer != NULL);
return buffer->data;
assert (buffer != NULL);
return buffer->data;
}
char *
ply_buffer_steal_bytes (ply_buffer_t *buffer)
{
char *bytes;
assert (buffer != NULL);
char *bytes;
bytes = buffer->data;
assert (buffer != NULL);
buffer->data = calloc (1, buffer->capacity);
buffer->size = 0;
bytes = buffer->data;
return bytes;
buffer->data = calloc (1, buffer->capacity);
buffer->size = 0;
return bytes;
}
size_t
ply_buffer_get_size (ply_buffer_t *buffer)
{
return buffer->size;
return buffer->size;
}
void
ply_buffer_clear (ply_buffer_t *buffer)
{
memset (buffer->data, '\0', buffer->capacity);
buffer->size = 0;
memset (buffer->data, '\0', buffer->capacity);
buffer->size = 0;
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -33,16 +33,17 @@ ply_buffer_t *ply_buffer_new (void);
void ply_buffer_free (ply_buffer_t *buffer);
void ply_buffer_append_bytes (ply_buffer_t *buffer,
const void *bytes,
size_t number_of_bytes);
size_t number_of_bytes);
void ply_buffer_append_from_fd (ply_buffer_t *buffer,
int fd);
#define ply_buffer_append(buffer, format, args...) \
#define ply_buffer_append(buffer, format, args ...) \
ply_buffer_append_with_non_literal_format_string (buffer, \
format "", ##args)
format "", ## args)
__attribute__((__format__ (__printf__, 2, 3)))
void ply_buffer_append_with_non_literal_format_string (ply_buffer_t *buffer,
const char *format, ...);
void ply_buffer_append_with_non_literal_format_string (ply_buffer_t *buffer,
const char *format,
...);
void ply_buffer_remove_bytes (ply_buffer_t *buffer,
size_t number_of_bytes);
void ply_buffer_remove_bytes_at_end (ply_buffer_t *buffer,

File diff suppressed because it is too large Load diff

View file

@ -27,15 +27,15 @@
#include "ply-event-loop.h"
typedef struct _ply_command_parser ply_command_parser_t;
typedef void (* ply_command_handler_t) (void *data,
const char *command);
typedef void (*ply_command_handler_t) (void *data,
const char *command);
typedef enum
{
PLY_COMMAND_OPTION_TYPE_FLAG = 0,
PLY_COMMAND_OPTION_TYPE_BOOLEAN,
PLY_COMMAND_OPTION_TYPE_STRING,
PLY_COMMAND_OPTION_TYPE_INTEGER
PLY_COMMAND_OPTION_TYPE_FLAG = 0,
PLY_COMMAND_OPTION_TYPE_BOOLEAN,
PLY_COMMAND_OPTION_TYPE_STRING,
PLY_COMMAND_OPTION_TYPE_INTEGER
} ply_command_option_type_t;
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
@ -43,34 +43,35 @@ ply_command_parser_t *ply_command_parser_new (const char *name,
const char *description);
void ply_command_parser_add_options (ply_command_parser_t *parser,
const char *option_name, /*
const char *option_description,
ply_option_argument_type_t option_type */
const char *option_name, /*
* const char *option_description,
* ply_option_argument_type_t option_type */
...);
void ply_command_parser_add_command (ply_command_parser_t *parser,
const char *name, const char *description,
const char *name,
const char *description,
ply_command_handler_t handler,
void *handler_data,
const char *option_name, /*
const char *option_description,
ply_option_argument_type_t option_type */
void *handler_data,
const char *option_name, /*
* const char *option_description,
* ply_option_argument_type_t option_type */
...);
void ply_command_parser_add_command_alias (ply_command_parser_t *parser,
const char *name,
const char *alias);
void ply_command_parser_get_options (ply_command_parser_t *parser,
const char *option_name, /*
void * option_result */
const char *option_name, /*
* void * option_result */
...);
void ply_command_parser_get_option (ply_command_parser_t *parser,
const char *option_name,
void *option_result,
bool *option_is_set);
void ply_command_parser_get_command_options (ply_command_parser_t *parser,
const char *command_name,
const char *option_name, /*
void * option_result,
bool * option_was_set */
const char *command_name,
const char *option_name, /*
* void * option_result,
* bool * option_was_set */
...);
void ply_command_parser_get_command_option (ply_command_parser_t *parser,
const char *command_name,
@ -83,7 +84,7 @@ char *ply_command_parser_get_help_string (ply_command_parser_t *parser);
bool ply_command_parser_parse_arguments (ply_command_parser_t *parser,
ply_event_loop_t *loop,
char * const *arguments,
char *const *arguments,
int number_of_arguments);
void ply_command_parser_free (ply_command_parser_t *command_parser);
#endif

File diff suppressed because it is too large Load diff

View file

@ -29,55 +29,56 @@
typedef struct _ply_event_loop ply_event_loop_t;
typedef struct _ply_fd_watch ply_fd_watch_t;
typedef enum {
PLY_EVENT_LOOP_FD_STATUS_NONE = 0,
PLY_EVENT_LOOP_FD_STATUS_HAS_DATA = 0x1,
PLY_EVENT_LOOP_FD_STATUS_HAS_CONTROL_DATA = 0x2,
PLY_EVENT_LOOP_FD_STATUS_CAN_TAKE_DATA = 0x4,
typedef enum
{
PLY_EVENT_LOOP_FD_STATUS_NONE = 0,
PLY_EVENT_LOOP_FD_STATUS_HAS_DATA = 0x1,
PLY_EVENT_LOOP_FD_STATUS_HAS_CONTROL_DATA = 0x2,
PLY_EVENT_LOOP_FD_STATUS_CAN_TAKE_DATA = 0x4,
} ply_event_loop_fd_status_t;
typedef void (* ply_event_handler_t) (void *user_data,
int source_fd);
typedef void (*ply_event_handler_t) (void *user_data,
int source_fd);
typedef void (* ply_event_loop_exit_handler_t) (void *user_data,
int exit_code,
ply_event_loop_t *loop);
typedef void (* ply_event_loop_timeout_handler_t) (void *user_data,
ply_event_loop_t *loop);
typedef void (*ply_event_loop_exit_handler_t) (void *user_data,
int exit_code,
ply_event_loop_t *loop);
typedef void (*ply_event_loop_timeout_handler_t) (void *user_data,
ply_event_loop_t *loop);
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
ply_event_loop_t *ply_event_loop_new (void);
void ply_event_loop_free (ply_event_loop_t *loop);
ply_event_loop_t *ply_event_loop_get_default (void);
ply_fd_watch_t *ply_event_loop_watch_fd (ply_event_loop_t *loop,
int fd,
ply_fd_watch_t *ply_event_loop_watch_fd (ply_event_loop_t *loop,
int fd,
ply_event_loop_fd_status_t status,
ply_event_handler_t status_met_handler,
ply_event_handler_t disconnected_handler,
void *user_data);
void ply_event_loop_stop_watching_fd (ply_event_loop_t *loop,
ply_event_handler_t status_met_handler,
ply_event_handler_t disconnected_handler,
void *user_data);
void ply_event_loop_stop_watching_fd (ply_event_loop_t *loop,
ply_fd_watch_t *watch);
void ply_event_loop_watch_signal (ply_event_loop_t *loop,
int signal_number,
ply_event_handler_t signal_handler,
void *user_data);
void ply_event_loop_watch_signal (ply_event_loop_t *loop,
int signal_number,
ply_event_handler_t signal_handler,
void *user_data);
void ply_event_loop_stop_watching_signal (ply_event_loop_t *loop,
int signal_number);
void ply_event_loop_watch_for_exit (ply_event_loop_t *loop,
ply_event_loop_exit_handler_t exit_handler,
void *user_data);
void ply_event_loop_stop_watching_for_exit (ply_event_loop_t *loop,
ply_event_loop_exit_handler_t exit_handler,
void *user_data);
void ply_event_loop_watch_for_timeout (ply_event_loop_t *loop,
double seconds,
void ply_event_loop_watch_for_exit (ply_event_loop_t *loop,
ply_event_loop_exit_handler_t exit_handler,
void *user_data);
void ply_event_loop_stop_watching_for_exit (ply_event_loop_t *loop,
ply_event_loop_exit_handler_t exit_handler,
void *user_data);
void ply_event_loop_watch_for_timeout (ply_event_loop_t *loop,
double seconds,
ply_event_loop_timeout_handler_t timeout_handler,
void *user_data);
void *user_data);
void ply_event_loop_stop_watching_for_timeout (ply_event_loop_t *loop,
void ply_event_loop_stop_watching_for_timeout (ply_event_loop_t *loop,
ply_event_loop_timeout_handler_t timeout_handler,
void *user_data);
void *user_data);
int ply_event_loop_run (ply_event_loop_t *loop);
void ply_event_loop_exit (ply_event_loop_t *loop,

View file

@ -31,95 +31,91 @@
#include <stdbool.h>
#include <string.h>
#define MASKGEN(x) {x |= x >> 16; x |= x >> 8; x |= x >> 4; x |= x >> 2; x |= x >> 1;}
#define MASKGEN(x) { x |= x >> 16; x |= x >> 8; x |= x >> 4; x |= x >> 2; x |= x >> 1; }
struct _ply_hashtable_node
{
void *data;
void *key;
void *data;
void *key;
};
struct _ply_hashtable
{
struct _ply_hashtable_node *nodes;
unsigned int total_node_count; /* must be a 2^X */
ply_bitarray_t *dirty_node_bitmap;
unsigned int dirty_node_count; /* live + dead nodes */
ply_bitarray_t *live_node_bitmap;
unsigned int live_node_count;
ply_hashtable_compare_func_t *compare_func;
ply_hashtable_hash_func_t *hash_func;
struct _ply_hashtable_node *nodes;
unsigned int total_node_count; /* must be a 2^X */
ply_bitarray_t *dirty_node_bitmap;
unsigned int dirty_node_count; /* live + dead nodes */
ply_bitarray_t *live_node_bitmap;
unsigned int live_node_count;
ply_hashtable_compare_func_t *compare_func;
ply_hashtable_hash_func_t *hash_func;
};
unsigned int
ply_hashtable_direct_hash (void *element)
{
return (unsigned int) (intptr_t) element;
return (unsigned int) (intptr_t) element;
}
int
ply_hashtable_direct_compare (void *elementa,
void *elementb)
{
return (int) ((intptr_t) elementa - (intptr_t) elementb);
return (int) ((intptr_t) elementa - (intptr_t) elementb);
}
unsigned int
ply_hashtable_string_hash (void *element)
{
char* strptr;
unsigned int hash = 0;
for (strptr = element; *strptr; strptr++)
{
hash ^= *strptr;
hash ^= hash << 1;
}
return hash;
char *strptr;
unsigned int hash = 0;
for (strptr = element; *strptr; strptr++) {
hash ^= *strptr;
hash ^= hash << 1;
}
return hash;
}
int
ply_hashtable_string_compare (void *elementa,
void *elementb)
{
return strcmp (elementa, elementb);
return strcmp (elementa, elementb);
}
ply_hashtable_t *
ply_hashtable_new (ply_hashtable_hash_func_t *hash_func,
ply_hashtable_compare_func_t *compare_func)
{
ply_hashtable_t *hashtable;
ply_hashtable_t *hashtable;
hashtable = malloc (sizeof (ply_hashtable_t));
hashtable->total_node_count = 0;
hashtable->dirty_node_count = 0;
hashtable->live_node_count = 0;
hashtable->nodes = NULL;
hashtable->dirty_node_bitmap = NULL;
hashtable->live_node_bitmap = NULL;
hashtable->compare_func = compare_func;
hashtable->hash_func = hash_func;
hashtable = malloc (sizeof(ply_hashtable_t));
hashtable->total_node_count = 0;
hashtable->dirty_node_count = 0;
hashtable->live_node_count = 0;
hashtable->nodes = NULL;
hashtable->dirty_node_bitmap = NULL;
hashtable->live_node_bitmap = NULL;
hashtable->compare_func = compare_func;
hashtable->hash_func = hash_func;
if (hashtable->compare_func == NULL)
{
hashtable->compare_func = ply_hashtable_direct_compare;
}
if (hashtable->hash_func == NULL)
{
hashtable->hash_func = ply_hashtable_direct_hash;
}
ply_hashtable_resize (hashtable);
return hashtable;
if (hashtable->compare_func == NULL)
hashtable->compare_func = ply_hashtable_direct_compare;
if (hashtable->hash_func == NULL)
hashtable->hash_func = ply_hashtable_direct_hash;
ply_hashtable_resize (hashtable);
return hashtable;
}
void
ply_hashtable_free (ply_hashtable_t *hashtable)
{
if (hashtable == NULL) return;
ply_bitarray_free (hashtable->dirty_node_bitmap);
ply_bitarray_free (hashtable->live_node_bitmap);
free(hashtable->nodes);
free(hashtable);
if (hashtable == NULL) return;
ply_bitarray_free (hashtable->dirty_node_bitmap);
ply_bitarray_free (hashtable->live_node_bitmap);
free (hashtable->nodes);
free (hashtable);
}
@ -128,65 +124,63 @@ ply_hashtable_insert_internal (ply_hashtable_t *hashtable,
void *key,
void *data)
{
unsigned int hash_index;
int step = 0;
unsigned int hash_index;
int step = 0;
hash_index = hashtable->hash_func (key);
hash_index &= hashtable->total_node_count - 1;
hash_index = hashtable->hash_func (key);
hash_index &= hashtable->total_node_count - 1;
while (ply_bitarray_lookup (hashtable->dirty_node_bitmap, hash_index))
{
step++;
hash_index += step;
hash_index &= hashtable->total_node_count - 1;
}
ply_bitarray_set (hashtable->dirty_node_bitmap, hash_index);
ply_bitarray_set (hashtable->live_node_bitmap, hash_index);
hashtable->nodes[hash_index].key = key;
hashtable->nodes[hash_index].data = data;
while (ply_bitarray_lookup (hashtable->dirty_node_bitmap, hash_index)) {
step++;
hash_index += step;
hash_index &= hashtable->total_node_count - 1;
}
ply_bitarray_set (hashtable->dirty_node_bitmap, hash_index);
ply_bitarray_set (hashtable->live_node_bitmap, hash_index);
hashtable->nodes[hash_index].key = key;
hashtable->nodes[hash_index].data = data;
hashtable->live_node_count++;
hashtable->dirty_node_count++;
hashtable->live_node_count++;
hashtable->dirty_node_count++;
}
void
ply_hashtable_resize (ply_hashtable_t *hashtable)
{
unsigned int newsize, oldsize;
unsigned int i;
struct _ply_hashtable_node *oldnodes;
ply_bitarray_t *old_live_node_bitmap;
unsigned int newsize, oldsize;
unsigned int i;
struct _ply_hashtable_node *oldnodes;
ply_bitarray_t *old_live_node_bitmap;
newsize = (hashtable->live_node_count + 1) * 4; /* make table 4x to 8x the number of live elements (at least 8) */
MASKGEN (newsize);
newsize++;
oldsize = hashtable->total_node_count;
oldnodes = hashtable->nodes;
newsize = (hashtable->live_node_count + 1) * 4; /* make table 4x to 8x the number of live elements (at least 8) */
MASKGEN (newsize);
newsize++;
oldsize = hashtable->total_node_count;
oldnodes = hashtable->nodes;
hashtable->total_node_count = newsize;
hashtable->nodes = malloc (newsize * sizeof (struct _ply_hashtable_node));
ply_bitarray_free (hashtable->dirty_node_bitmap);
hashtable->dirty_node_bitmap = ply_bitarray_new(newsize);
old_live_node_bitmap = hashtable->live_node_bitmap;
hashtable->live_node_bitmap = ply_bitarray_new(newsize);
hashtable->dirty_node_count = 0;
hashtable->live_node_count = 0;
hashtable->total_node_count = newsize;
hashtable->nodes = malloc (newsize * sizeof(struct _ply_hashtable_node));
ply_bitarray_free (hashtable->dirty_node_bitmap);
hashtable->dirty_node_bitmap = ply_bitarray_new (newsize);
old_live_node_bitmap = hashtable->live_node_bitmap;
hashtable->live_node_bitmap = ply_bitarray_new (newsize);
hashtable->dirty_node_count = 0;
hashtable->live_node_count = 0;
for (i=0; i<oldsize; i++)
{
if (ply_bitarray_lookup (old_live_node_bitmap, i))
ply_hashtable_insert_internal (hashtable, oldnodes[i].key, oldnodes[i].data);
}
ply_bitarray_free (old_live_node_bitmap);
free (oldnodes);
for (i = 0; i < oldsize; i++) {
if (ply_bitarray_lookup (old_live_node_bitmap, i))
ply_hashtable_insert_internal (hashtable, oldnodes[i].key, oldnodes[i].data);
}
ply_bitarray_free (old_live_node_bitmap);
free (oldnodes);
}
static inline void
ply_hashtable_resize_check (ply_hashtable_t *hashtable)
{
if (hashtable->total_node_count < (hashtable->dirty_node_count * 2))
ply_hashtable_resize (hashtable); /* hash tables work best below 50% occupancy */
if (hashtable->total_node_count < (hashtable->dirty_node_count * 2))
ply_hashtable_resize (hashtable); /* hash tables work best below 50% occupancy */
}
void
@ -194,55 +188,56 @@ ply_hashtable_insert (ply_hashtable_t *hashtable,
void *key,
void *data)
{
ply_hashtable_resize_check (hashtable);
ply_hashtable_insert_internal (hashtable, key, data);
ply_hashtable_resize_check (hashtable);
ply_hashtable_insert_internal (hashtable, key, data);
}
static int
ply_hashtable_lookup_index (ply_hashtable_t *hashtable,
void *key)
{
unsigned int hash_index;
int step = 0;
unsigned int hash_index;
int step = 0;
hash_index = hashtable->hash_func (key);
while (1)
{
hash_index &= hashtable->total_node_count - 1;
if (!ply_bitarray_lookup (hashtable->dirty_node_bitmap, hash_index))
break;
if (ply_bitarray_lookup (hashtable->live_node_bitmap, hash_index))
if (!hashtable->compare_func (hashtable->nodes[hash_index].key, key))
return hash_index;
hash_index += step;
step++;
}
return -1;
hash_index = hashtable->hash_func (key);
while (1) {
hash_index &= hashtable->total_node_count - 1;
if (!ply_bitarray_lookup (hashtable->dirty_node_bitmap, hash_index))
break;
if (ply_bitarray_lookup (hashtable->live_node_bitmap, hash_index))
if (!hashtable->compare_func (hashtable->nodes[hash_index].key, key))
return hash_index;
hash_index += step;
step++;
}
return -1;
}
void *
ply_hashtable_remove (ply_hashtable_t *hashtable,
void *key)
{
int index;
index = ply_hashtable_lookup_index (hashtable, key);
if (index < 0)
return NULL;
ply_bitarray_clear (hashtable->live_node_bitmap, index);
hashtable->live_node_count--;
return hashtable->nodes[index].data;
int index;
index = ply_hashtable_lookup_index (hashtable, key);
if (index < 0)
return NULL;
ply_bitarray_clear (hashtable->live_node_bitmap, index);
hashtable->live_node_count--;
return hashtable->nodes[index].data;
}
void *
ply_hashtable_lookup (ply_hashtable_t *hashtable,
void *key)
{
int index;
index = ply_hashtable_lookup_index (hashtable, key);
if (index < 0)
return NULL;
return hashtable->nodes[index].data;
int index;
index = ply_hashtable_lookup_index (hashtable, key);
if (index < 0)
return NULL;
return hashtable->nodes[index].data;
}
int
@ -251,32 +246,33 @@ ply_hashtable_lookup_full (ply_hashtable_t *hashtable,
void **reply_key,
void **reply_data)
{
int index;
index = ply_hashtable_lookup_index (hashtable, key);
if (index < 0)
return false;
*reply_key = hashtable->nodes[index].key;
*reply_data = hashtable->nodes[index].data;
return true;
int index;
index = ply_hashtable_lookup_index (hashtable, key);
if (index < 0)
return false;
*reply_key = hashtable->nodes[index].key;
*reply_data = hashtable->nodes[index].data;
return true;
}
void
ply_hashtable_foreach (ply_hashtable_t *hashtable,
ply_hashtable_foreach_func_t func,
void *user_data)
ply_hashtable_foreach (ply_hashtable_t *hashtable,
ply_hashtable_foreach_func_t func,
void *user_data)
{
unsigned int i;
for (i = 0; i < hashtable->total_node_count; i++)
{
if (ply_bitarray_lookup (hashtable->live_node_bitmap, i))
func(hashtable->nodes[i].key, hashtable->nodes[i].data, user_data);
}
unsigned int i;
for (i = 0; i < hashtable->total_node_count; i++) {
if (ply_bitarray_lookup (hashtable->live_node_bitmap, i))
func (hashtable->nodes[i].key, hashtable->nodes[i].data, user_data);
}
}
int
ply_hashtable_get_size (ply_hashtable_t *hashtable)
{
return hashtable->live_node_count;
return hashtable->live_node_count;
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -34,7 +34,7 @@ typedef void (ply_hashtable_foreach_func_t) (void *key,
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
int ply_hashtable_direct_compare (void *elementa,
void *elementb);
void *elementb);
unsigned int ply_hashtable_direct_hash (void *element);
unsigned int ply_hashtable_string_hash (void *element);
int ply_hashtable_string_compare (void *elementa,
@ -44,19 +44,19 @@ ply_hashtable_t *ply_hashtable_new (ply_hashtable_hash_func_t *hash_func,
void ply_hashtable_free (ply_hashtable_t *hashtable);
void ply_hashtable_resize (ply_hashtable_t *hashtable);
void ply_hashtable_insert (ply_hashtable_t *hashtable,
void *key,
void *data);
void *key,
void *data);
void *ply_hashtable_remove (ply_hashtable_t *hashtable,
void *key);
void *key);
void *ply_hashtable_lookup (ply_hashtable_t *hashtable,
void *key);
void *key);
int ply_hashtable_lookup_full (ply_hashtable_t *hashtable,
void *key,
void **reply_key,
void **reply_data);
void ply_hashtable_foreach (ply_hashtable_t *hashtable,
ply_hashtable_foreach_func_t func,
void *user_data);
void *key,
void **reply_key,
void **reply_data);
void ply_hashtable_foreach (ply_hashtable_t *hashtable,
ply_hashtable_foreach_func_t func,
void *user_data);
int ply_hashtable_get_size (ply_hashtable_t *hashtable);
#endif

View file

@ -43,29 +43,29 @@
typedef struct
{
char *key;
char *value;
char *key;
char *value;
} ply_key_file_entry_t;
typedef struct
{
char *name;
ply_hashtable_t *entries;
char *name;
ply_hashtable_t *entries;
} ply_key_file_group_t;
struct _ply_key_file
{
char *filename;
FILE *fp;
char *filename;
FILE *fp;
ply_hashtable_t *groups;
ply_hashtable_t *groups;
};
typedef struct
{
ply_key_file_foreach_func_t *func;
void *user_data;
char *group_name;
ply_key_file_foreach_func_t *func;
void *user_data;
char *group_name;
} ply_key_file_foreach_func_data_t;
static bool ply_key_file_open_file (ply_key_file_t *key_file);
@ -74,249 +74,235 @@ static void ply_key_file_close_file (ply_key_file_t *key_file);
static bool
ply_key_file_open_file (ply_key_file_t *key_file)
{
assert (key_file != NULL);
assert (key_file != NULL);
key_file->fp = fopen (key_file->filename, "re");
key_file->fp = fopen (key_file->filename, "re");
if (key_file->fp == NULL)
{
ply_trace ("Failed to open key file %s: %m",
key_file->filename);
return false;
}
return true;
if (key_file->fp == NULL) {
ply_trace ("Failed to open key file %s: %m",
key_file->filename);
return false;
}
return true;
}
static void
ply_key_file_close_file (ply_key_file_t *key_file)
{
assert (key_file != NULL);
assert (key_file != NULL);
if (key_file->fp == NULL)
return;
fclose (key_file->fp);
key_file->fp = NULL;
if (key_file->fp == NULL)
return;
fclose (key_file->fp);
key_file->fp = NULL;
}
ply_key_file_t *
ply_key_file_new (const char *filename)
{
ply_key_file_t *key_file;
ply_key_file_t *key_file;
assert (filename != NULL);
assert (filename != NULL);
key_file = calloc (1, sizeof (ply_key_file_t));
key_file = calloc (1, sizeof(ply_key_file_t));
key_file->filename = strdup (filename);
key_file->fp = NULL;
key_file->groups = ply_hashtable_new (ply_hashtable_string_hash, ply_hashtable_string_compare);
key_file->filename = strdup (filename);
key_file->fp = NULL;
key_file->groups = ply_hashtable_new (ply_hashtable_string_hash, ply_hashtable_string_compare);
return key_file;
return key_file;
}
static void
ply_key_file_free_entry_foreach (void *key,
ply_key_file_free_entry_foreach (void *key,
void *data,
void *user_data)
{
ply_key_file_entry_t *entry = data;
free (entry->key);
free (entry->value);
free (entry);
ply_key_file_entry_t *entry = data;
free (entry->key);
free (entry->value);
free (entry);
}
static void
ply_key_file_free_group (void *key,
ply_key_file_free_group (void *key,
void *data,
void *user_data)
{
ply_key_file_group_t *group = data;
ply_hashtable_foreach (group->entries,
ply_key_file_free_entry_foreach,
NULL);
ply_hashtable_free (group->entries);
free (group->name);
free (group);
ply_key_file_group_t *group = data;
ply_hashtable_foreach (group->entries,
ply_key_file_free_entry_foreach,
NULL);
ply_hashtable_free (group->entries);
free (group->name);
free (group);
}
void
ply_key_file_free (ply_key_file_t *key_file)
{
if (key_file == NULL)
return;
if (key_file == NULL)
return;
assert (key_file->filename != NULL);
ply_hashtable_foreach (key_file->groups,
ply_key_file_free_group,
NULL);
ply_hashtable_free (key_file->groups);
free (key_file->filename);
free (key_file);
assert (key_file->filename != NULL);
ply_hashtable_foreach (key_file->groups,
ply_key_file_free_group,
NULL);
ply_hashtable_free (key_file->groups);
free (key_file->filename);
free (key_file);
}
static ply_key_file_group_t *
ply_key_file_load_group (ply_key_file_t *key_file,
const char *group_name)
{
int items_matched;
ply_key_file_group_t *group;
int items_matched;
ply_key_file_group_t *group;
group = calloc (1, sizeof (ply_key_file_group_t));
group->name = strdup (group_name);
group->entries = ply_hashtable_new (ply_hashtable_string_hash, ply_hashtable_string_compare);
group = calloc (1, sizeof(ply_key_file_group_t));
group->name = strdup (group_name);
group->entries = ply_hashtable_new (ply_hashtable_string_hash, ply_hashtable_string_compare);
ply_trace ("trying to load group %s", group_name);
do
{
ply_key_file_entry_t *entry;
char *key;
char *value;
off_t offset;
int first_byte;
ply_trace ("trying to load group %s", group_name);
do {
ply_key_file_entry_t *entry;
char *key;
char *value;
off_t offset;
int first_byte;
key = NULL;
value = NULL;
key = NULL;
value = NULL;
do
{
first_byte = fgetc (key_file->fp);
}
while (isspace (first_byte));
do {
first_byte = fgetc (key_file->fp);
} while (isspace (first_byte));
if (first_byte == '#')
{
char *line_to_toss;
size_t number_of_bytes;
if (first_byte == '#') {
char *line_to_toss;
size_t number_of_bytes;
line_to_toss = NULL;
number_of_bytes = 0;
line_to_toss = NULL;
number_of_bytes = 0;
getline (&line_to_toss, &number_of_bytes,
key_file->fp);
free (line_to_toss);
items_matched = 0;
continue;
}
ungetc (first_byte, key_file->fp);
getline (&line_to_toss, &number_of_bytes,
key_file->fp);
free (line_to_toss);
items_matched = 0;
continue;
}
ungetc (first_byte, key_file->fp);
offset = ftello (key_file->fp);
items_matched = fscanf (key_file->fp, " %m[^= \t\n] = %m[^\n] ", &key, &value);
offset = ftello (key_file->fp);
items_matched = fscanf (key_file->fp, " %m[^= \t\n] = %m[^\n] ", &key, &value);
if (items_matched != 2)
{
if (items_matched == 1)
fseeko (key_file->fp, offset, SEEK_SET);
if (items_matched != 2) {
if (items_matched == 1)
fseeko (key_file->fp, offset, SEEK_SET);
free (key);
free (value);
break;
}
free (key);
free (value);
break;
}
entry = calloc (1, sizeof (ply_key_file_entry_t));
entry = calloc (1, sizeof(ply_key_file_entry_t));
entry->key = key;
entry->value = value;
entry->key = key;
entry->value = value;
ply_hashtable_insert (group->entries, entry->key, entry);
}
while (items_matched != EOF);
ply_hashtable_insert (group->entries, entry->key, entry);
} while (items_matched != EOF);
return group;
return group;
}
static bool
ply_key_file_load_groups (ply_key_file_t *key_file)
{
int items_matched;
bool added_group = false;
bool has_comments = false;
int items_matched;
bool added_group = false;
bool has_comments = false;
do
{
char *group_name;
int first_byte;
do {
char *group_name;
int first_byte;
ply_key_file_group_t *group;
ply_key_file_group_t *group;
first_byte = fgetc (key_file->fp);
if (first_byte == '#')
{
char *line_to_toss;
size_t number_of_bytes;
first_byte = fgetc (key_file->fp);
if (first_byte == '#') {
char *line_to_toss;
size_t number_of_bytes;
line_to_toss = NULL;
number_of_bytes = 0;
line_to_toss = NULL;
number_of_bytes = 0;
getline (&line_to_toss, &number_of_bytes,
key_file->fp);
free (line_to_toss);
has_comments = true;
items_matched = 0;
continue;
}
ungetc (first_byte, key_file->fp);
getline (&line_to_toss, &number_of_bytes,
key_file->fp);
free (line_to_toss);
has_comments = true;
items_matched = 0;
continue;
}
ungetc (first_byte, key_file->fp);
group_name = NULL;
items_matched = fscanf (key_file->fp, " [ %m[^]] ] ", &group_name);
group_name = NULL;
items_matched = fscanf (key_file->fp, " [ %m[^]] ] ", &group_name);
if (items_matched <= 0)
{
ply_trace ("key file has no %sgroups",
added_group? "more " : "");
break;
}
if (items_matched <= 0) {
ply_trace ("key file has no %sgroups",
added_group ? "more " : "");
break;
}
assert (group_name != NULL);
group = ply_key_file_load_group (key_file, group_name);
assert (group_name != NULL);
group = ply_key_file_load_group (key_file, group_name);
free (group_name);
free (group_name);
if (group == NULL)
break;
if (group == NULL)
break;
ply_hashtable_insert (key_file->groups, group->name, group);
added_group = true;
}
while (items_matched != EOF);
ply_hashtable_insert (key_file->groups, group->name, group);
added_group = true;
} while (items_matched != EOF);
if (!added_group && has_comments)
{
ply_trace ("key file has comments but no groups");
}
if (!added_group && has_comments)
ply_trace ("key file has comments but no groups");
return added_group;
return added_group;
}
bool
ply_key_file_load (ply_key_file_t *key_file)
{
bool was_loaded;
bool was_loaded;
assert (key_file != NULL);
assert (key_file != NULL);
if (!ply_key_file_open_file (key_file))
return false;
if (!ply_key_file_open_file (key_file))
return false;
was_loaded = ply_key_file_load_groups (key_file);
was_loaded = ply_key_file_load_groups (key_file);
if (!was_loaded)
{
ply_trace ("was unable to load any groups");
}
if (!was_loaded)
ply_trace ("was unable to load any groups");
ply_key_file_close_file (key_file);
ply_key_file_close_file (key_file);
return was_loaded;
return was_loaded;
}
static ply_key_file_group_t *
ply_key_file_find_group (ply_key_file_t *key_file,
const char *group_name)
{
return ply_hashtable_lookup (key_file->groups, (void *) group_name);
return ply_hashtable_lookup (key_file->groups, (void *) group_name);
}
static ply_key_file_entry_t *
@ -324,7 +310,7 @@ ply_key_file_find_entry (ply_key_file_t *key_file,
ply_key_file_group_t *group,
const char *key)
{
return ply_hashtable_lookup (group->entries, (void *) key);
return ply_hashtable_lookup (group->entries, (void *) key);
}
bool
@ -332,17 +318,17 @@ ply_key_file_has_key (ply_key_file_t *key_file,
const char *group_name,
const char *key)
{
ply_key_file_group_t *group;
ply_key_file_entry_t *entry;
ply_key_file_group_t *group;
ply_key_file_entry_t *entry;
group = ply_key_file_find_group (key_file, group_name);
group = ply_key_file_find_group (key_file, group_name);
if (group == NULL)
return false;
if (group == NULL)
return false;
entry = ply_key_file_find_entry (key_file, group, key);
entry = ply_key_file_find_entry (key_file, group, key);
return entry != NULL;
return entry != NULL;
}
char *
@ -350,26 +336,24 @@ ply_key_file_get_value (ply_key_file_t *key_file,
const char *group_name,
const char *key)
{
ply_key_file_group_t *group;
ply_key_file_entry_t *entry;
ply_key_file_group_t *group;
ply_key_file_entry_t *entry;
group = ply_key_file_find_group (key_file, group_name);
group = ply_key_file_find_group (key_file, group_name);
if (group == NULL)
{
ply_trace ("key file does not have group '%s'", group_name);
return NULL;
}
if (group == NULL) {
ply_trace ("key file does not have group '%s'", group_name);
return NULL;
}
entry = ply_key_file_find_entry (key_file, group, key);
entry = ply_key_file_find_entry (key_file, group, key);
if (entry == NULL)
{
ply_trace ("key file does not have entry for key '%s'", key);
return NULL;
}
if (entry == NULL) {
ply_trace ("key file does not have entry for key '%s'", key);
return NULL;
}
return strdup (entry->value);
return strdup (entry->value);
}
static void
@ -377,16 +361,16 @@ ply_key_file_foreach_entry_entries (void *key,
void *data,
void *user_data)
{
ply_key_file_entry_t *entry;
ply_key_file_foreach_func_data_t *func_data;
ply_key_file_entry_t *entry;
ply_key_file_foreach_func_data_t *func_data;
func_data = user_data;
entry = data;
func_data = user_data;
entry = data;
func_data->func(func_data->group_name,
entry->key,
entry->value,
func_data->user_data);
func_data->func (func_data->group_name,
entry->key,
entry->value,
func_data->user_data);
}
static void
@ -394,30 +378,30 @@ ply_key_file_foreach_entry_groups (void *key,
void *data,
void *user_data)
{
ply_key_file_group_t *group;
ply_key_file_foreach_func_data_t *func_data;
ply_key_file_group_t *group;
ply_key_file_foreach_func_data_t *func_data;
func_data = user_data;
group = data;
func_data->group_name = group->name;
func_data = user_data;
group = data;
func_data->group_name = group->name;
ply_hashtable_foreach (group->entries,
ply_key_file_foreach_entry_entries,
func_data);
ply_hashtable_foreach (group->entries,
ply_key_file_foreach_entry_entries,
func_data);
}
void
ply_key_file_foreach_entry (ply_key_file_t *key_file,
ply_key_file_foreach_func_t func,
void *user_data)
ply_key_file_foreach_entry (ply_key_file_t *key_file,
ply_key_file_foreach_func_t func,
void *user_data)
{
ply_key_file_foreach_func_data_t func_data;
ply_key_file_foreach_func_data_t func_data;
func_data.func = func;
func_data.user_data = user_data;
ply_hashtable_foreach (key_file->groups,
ply_key_file_foreach_entry_groups,
&func_data);
func_data.func = func;
func_data.user_data = user_data;
ply_hashtable_foreach (key_file->groups,
ply_key_file_foreach_entry_groups,
&func_data);
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -1,4 +1,4 @@
/* ply-key-file.h - key file loader
/* ply-key-file.h - key file loader
*
* Copyright (C) 2009 Red Hat, Inc.
*
@ -42,9 +42,9 @@ bool ply_key_file_has_key (ply_key_file_t *key_file,
char *ply_key_file_get_value (ply_key_file_t *key_file,
const char *group_name,
const char *key);
void ply_key_file_foreach_entry (ply_key_file_t *key_file,
ply_key_file_foreach_func_t func,
void *user_data);
void ply_key_file_foreach_entry (ply_key_file_t *key_file,
ply_key_file_foreach_func_t func,
void *user_data);
#endif
#endif /* PLY_KEY_FILE_H */

View file

@ -31,83 +31,82 @@
struct _ply_list
{
ply_list_node_t *first_node;
ply_list_node_t *last_node;
ply_list_node_t *first_node;
ply_list_node_t *last_node;
int number_of_nodes;
int number_of_nodes;
};
struct _ply_list_node
{
void *data;
struct _ply_list_node *previous;
struct _ply_list_node *next;
void *data;
struct _ply_list_node *previous;
struct _ply_list_node *next;
};
ply_list_t *
ply_list_new (void)
{
ply_list_t *list;
ply_list_t *list;
list = calloc (1, sizeof (ply_list_t));
list = calloc (1, sizeof(ply_list_t));
list->first_node = NULL;
list->last_node = NULL;
list->number_of_nodes = 0;
list->first_node = NULL;
list->last_node = NULL;
list->number_of_nodes = 0;
return list;
return list;
}
void
ply_list_free (ply_list_t *list)
{
ply_list_remove_all_nodes (list);
free (list);
ply_list_remove_all_nodes (list);
free (list);
}
static ply_list_node_t *
ply_list_node_new (void *data)
{
ply_list_node_t *node;
ply_list_node_t *node;
node = calloc (1, sizeof (ply_list_node_t));
node->data = data;
node = calloc (1, sizeof(ply_list_node_t));
node->data = data;
return node;
return node;
}
static void
ply_list_node_free (ply_list_node_t *node)
{
if (node == NULL)
return;
if (node == NULL)
return;
assert ((node->previous == NULL) && (node->next == NULL));
assert ((node->previous == NULL) && (node->next == NULL));
free (node);
free (node);
}
int
ply_list_get_length (ply_list_t *list)
{
return list->number_of_nodes;
return list->number_of_nodes;
}
ply_list_node_t *
ply_list_find_node (ply_list_t *list,
void *data)
{
ply_list_node_t *node;
ply_list_node_t *node;
node = list->first_node;
while (node != NULL)
{
if (node->data == data)
break;
node = list->first_node;
while (node != NULL) {
if (node->data == data)
break;
node = node->next;
}
return node;
node = node->next;
}
return node;
}
static void
@ -115,39 +114,32 @@ ply_list_insert_node (ply_list_t *list,
ply_list_node_t *node_before,
ply_list_node_t *new_node)
{
if (new_node == NULL)
return;
if (new_node == NULL)
return;
if (node_before == NULL) {
if (list->first_node == NULL) {
assert (list->last_node == NULL);
if (node_before == NULL)
{
if (list->first_node == NULL)
{
assert (list->last_node == NULL);
list->first_node = new_node;
list->last_node = new_node;
} else {
list->first_node->previous = new_node;
new_node->next = list->first_node;
list->first_node = new_node;
}
} else {
new_node->next = node_before->next;
if (node_before->next != NULL)
node_before->next->previous = new_node;
node_before->next = new_node;
new_node->previous = node_before;
list->first_node = new_node;
list->last_node = new_node;
if (node_before == list->last_node)
list->last_node = new_node;
}
else
{
list->first_node->previous = new_node;
new_node->next = list->first_node;
list->first_node = new_node;
}
}
else
{
new_node->next = node_before->next;
if (node_before->next != NULL)
node_before->next->previous = new_node;
node_before->next = new_node;
new_node->previous = node_before;
if (node_before == list->last_node)
list->last_node = new_node;
}
list->number_of_nodes++;
list->number_of_nodes++;
}
ply_list_node_t *
@ -155,224 +147,217 @@ ply_list_insert_data (ply_list_t *list,
void *data,
ply_list_node_t *node_before)
{
ply_list_node_t *node;
ply_list_node_t *node;
node = ply_list_node_new (data);
node = ply_list_node_new (data);
ply_list_insert_node (list, node_before, node);
ply_list_insert_node (list, node_before, node);
return node;
return node;
}
ply_list_node_t *
ply_list_append_data (ply_list_t *list,
void *data)
{
return ply_list_insert_data (list, data, list->last_node);
return ply_list_insert_data (list, data, list->last_node);
}
ply_list_node_t *
ply_list_prepend_data (ply_list_t *list,
void *data)
{
return ply_list_insert_data (list, data, NULL);
return ply_list_insert_data (list, data, NULL);
}
void
ply_list_remove_data (ply_list_t *list,
void *data)
{
ply_list_node_t *node;
ply_list_node_t *node;
if (data == NULL)
return;
if (data == NULL)
return;
node = ply_list_find_node (list, data);
node = ply_list_find_node (list, data);
if (node != NULL)
ply_list_remove_node (list, node);
if (node != NULL)
ply_list_remove_node (list, node);
}
static void
ply_list_unlink_node (ply_list_t *list,
ply_list_node_t *node)
{
ply_list_node_t *node_before, *node_after;
ply_list_node_t *node_before, *node_after;
assert (list != NULL);
assert (list != NULL);
if (node == NULL)
return;
if (node == NULL)
return;
node_before = node->previous;
node_after = node->next;
node_before = node->previous;
node_after = node->next;
if (node_before != NULL)
node_before->next = node_after;
if (node_before != NULL)
node_before->next = node_after;
if (node_after != NULL)
node_after->previous = node_before;
if (node_after != NULL)
node_after->previous = node_before;
if (list->first_node == node)
list->first_node = node_after;
if (list->first_node == node)
list->first_node = node_after;
if (list->last_node == node)
list->last_node = node_before;
if (list->last_node == node)
list->last_node = node_before;
node->previous = NULL;
node->next = NULL;
node->previous = NULL;
node->next = NULL;
list->number_of_nodes--;
assert (ply_list_find_node (list, node->data) != node);
list->number_of_nodes--;
assert (ply_list_find_node (list, node->data) != node);
}
void
ply_list_remove_node (ply_list_t *list,
ply_list_node_t *node)
{
ply_list_unlink_node (list, node);
ply_list_node_free (node);
ply_list_unlink_node (list, node);
ply_list_node_free (node);
}
void
ply_list_remove_all_nodes (ply_list_t *list)
{
ply_list_node_t *node;
ply_list_node_t *node;
if (list == NULL)
return;
if (list == NULL)
return;
node = list->first_node;
while (node != NULL)
{
ply_list_node_t *next_node;
next_node = node->next;
ply_list_remove_node (list, node);
node = next_node;
}
node = list->first_node;
while (node != NULL) {
ply_list_node_t *next_node;
next_node = node->next;
ply_list_remove_node (list, node);
node = next_node;
}
}
ply_list_node_t *
ply_list_get_first_node (ply_list_t *list)
{
return list->first_node;
return list->first_node;
}
ply_list_node_t *
ply_list_get_last_node (ply_list_t *list)
{
return list->last_node;
return list->last_node;
}
ply_list_node_t *
ply_list_get_nth_node (ply_list_t *list,
int index)
{
ply_list_node_t *node;
node = list->first_node;
if (index < 0)
return NULL;
if (index >= list->number_of_nodes)
return NULL;
while (index--)
{
node = node->next;
}
return node;
ply_list_node_t *node;
node = list->first_node;
if (index < 0)
return NULL;
if (index >= list->number_of_nodes)
return NULL;
while (index--) {
node = node->next;
}
return node;
}
ply_list_node_t *
ply_list_get_next_node (ply_list_t *list,
ply_list_node_t *node)
ply_list_get_next_node (ply_list_t *list,
ply_list_node_t *node)
{
return node->next;
return node->next;
}
static void
static void
ply_list_sort_swap (void **element_a,
void **element_b)
{
void *temp;
temp = *element_a;
*element_a = *element_b;
*element_b = temp;
void *temp;
temp = *element_a;
*element_a = *element_b;
*element_b = temp;
}
static void
static void
ply_list_sort_body (ply_list_node_t *node_start,
ply_list_node_t *node_end,
ply_list_compare_func_t *compare)
{
if (node_start == node_end) return;
ply_list_node_t *cur_node = node_start;
ply_list_node_t *top_node = node_end;
ply_list_node_t *next_node = cur_node->next;
while (cur_node != top_node)
{
int diff = compare(cur_node->data, next_node->data);
if (diff > 0)
{
ply_list_sort_swap (&next_node->data,
&cur_node->data);
cur_node = next_node;
next_node = cur_node->next;
if (node_start == node_end) return;
ply_list_node_t *cur_node = node_start;
ply_list_node_t *top_node = node_end;
ply_list_node_t *next_node = cur_node->next;
while (cur_node != top_node) {
int diff = compare (cur_node->data, next_node->data);
if (diff > 0) {
ply_list_sort_swap (&next_node->data,
&cur_node->data);
cur_node = next_node;
next_node = cur_node->next;
} else {
ply_list_sort_swap (&next_node->data,
&top_node->data);
top_node = top_node->previous;
}
}
else
{
ply_list_sort_swap (&next_node->data,
&top_node->data);
top_node = top_node->previous;
}
}
if (cur_node != node_end)
ply_list_sort_body (cur_node->next,
node_end,
compare);
if (cur_node != node_start)
ply_list_sort_body (node_start,
cur_node->previous,
compare);
if (cur_node != node_end)
ply_list_sort_body (cur_node->next,
node_end,
compare);
if (cur_node != node_start)
ply_list_sort_body (node_start,
cur_node->previous,
compare);
}
void
ply_list_sort (ply_list_t *list,
ply_list_compare_func_t *compare)
{
ply_list_sort_body (ply_list_get_first_node (list),
ply_list_get_last_node (list),
compare);
ply_list_sort_body (ply_list_get_first_node (list),
ply_list_get_last_node (list),
compare);
}
void
ply_list_sort_stable (ply_list_t *list,
ply_list_compare_func_t *compare)
{
ply_list_node_t *top_node;
ply_list_node_t *cur_node;
ply_list_node_t *top_node;
ply_list_node_t *cur_node;
top_node = ply_list_get_first_node (list);
if (top_node == NULL) return;
top_node = top_node->next;
top_node = ply_list_get_first_node (list);
if (top_node == NULL) return;
top_node = top_node->next;
while (top_node)
{
cur_node = top_node->previous;
while (cur_node && compare(cur_node->data, cur_node->next->data) > 0)
{
ply_list_sort_swap (&cur_node->data,
&cur_node->next->data);
cur_node = cur_node->previous;
while (top_node) {
cur_node = top_node->previous;
while (cur_node && compare (cur_node->data, cur_node->next->data) > 0) {
ply_list_sort_swap (&cur_node->data,
&cur_node->next->data);
cur_node = cur_node->previous;
}
top_node = top_node->next;
}
top_node = top_node->next;
}
}
void *
ply_list_node_get_data (ply_list_node_t *node)
{
return node->data;
return node->data;
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -24,7 +24,8 @@
typedef struct _ply_list_node ply_list_node_t;
typedef struct _ply_list ply_list_t;
typedef int (ply_list_compare_func_t) (void *elementa, void *elementb);
typedef int (ply_list_compare_func_t) (void *elementa,
void *elementb);
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
ply_list_t *ply_list_new (void);
@ -32,15 +33,15 @@ void ply_list_free (ply_list_t *list);
int ply_list_get_length (ply_list_t *list);
ply_list_node_t *ply_list_find_node (ply_list_t *list,
void *data);
ply_list_node_t *ply_list_insert_data (ply_list_t *list,
void *data,
ply_list_node_t *node_before);
ply_list_node_t *ply_list_insert_data (ply_list_t *list,
void *data,
ply_list_node_t *node_before);
ply_list_node_t *ply_list_append_data (ply_list_t *list,
void *data);
ply_list_node_t *ply_list_prepend_data (ply_list_t *list,
void *data);
void ply_list_remove_data (ply_list_t *list,
void *data);
void *data);
void ply_list_remove_node (ply_list_t *list,
ply_list_node_t *node);
void ply_list_remove_all_nodes (ply_list_t *list);

View file

@ -53,70 +53,70 @@
typedef struct
{
ply_logger_filter_handler_t handler;
void *user_data;
ply_logger_filter_handler_t handler;
void *user_data;
} ply_logger_filter_t;
struct _ply_logger
{
int output_fd;
char *filename;
int output_fd;
char *filename;
char *buffer;
size_t buffer_size;
size_t buffer_capacity;
char *buffer;
size_t buffer_size;
size_t buffer_capacity;
ply_logger_flush_policy_t flush_policy;
ply_list_t *filters;
ply_logger_flush_policy_t flush_policy;
ply_list_t *filters;
uint32_t is_enabled : 1;
uint32_t tracing_is_enabled : 1;
uint32_t is_enabled : 1;
uint32_t tracing_is_enabled : 1;
};
static bool ply_text_is_loggable (const char *string,
ssize_t length);
static void ply_logger_write_exception (ply_logger_t *logger,
const char *string);
static bool ply_logger_write (ply_logger_t *logger,
const char *string,
size_t length,
bool should_report_failures);
static void ply_logger_write_exception (ply_logger_t *logger,
const char *string);
static bool ply_logger_write (ply_logger_t *logger,
const char *string,
size_t length,
bool should_report_failures);
static bool ply_logger_buffer (ply_logger_t *logger,
const char *string,
size_t length);
static bool ply_logger_buffer (ply_logger_t *logger,
const char *string,
size_t length);
static bool ply_logger_flush_buffer (ply_logger_t *logger);
static bool
ply_text_is_loggable (const char *string,
ssize_t length)
{
/* I guess we should let everything through since there
* isn't really any specified encoding
*/
/* I guess we should let everything through since there
* isn't really any specified encoding
*/
return true;
return true;
}
static void
ply_logger_write_exception (ply_logger_t *logger,
const char *string)
ply_logger_write_exception (ply_logger_t *logger,
const char *string)
{
char *message;
int number_of_bytes;
char *message;
int number_of_bytes;
if (!ply_text_is_loggable (string, -1))
return;
if (!ply_text_is_loggable (string, -1))
return;
message = NULL;
asprintf (&message,
"[couldn't write a log entry: %s]\n%n",
string, &number_of_bytes);
message = NULL;
asprintf (&message,
"[couldn't write a log entry: %s]\n%n",
string, &number_of_bytes);
assert (message != NULL);
assert (message != NULL);
ply_logger_write (logger, message, number_of_bytes, false);
free (message);
ply_logger_write (logger, message, number_of_bytes, false);
free (message);
}
static bool
@ -125,75 +125,72 @@ ply_logger_write (ply_logger_t *logger,
size_t length,
bool should_report_failures)
{
if (!ply_text_is_loggable (string, length))
{
if (should_report_failures)
ply_logger_write_exception (logger,
"log text contains unloggable bytes");
/* we return true here, because returning false would mean
* "you aren't allowed to write to the log file anymore"
*/
return true;
}
if (!ply_text_is_loggable (string, length)) {
if (should_report_failures)
ply_logger_write_exception (logger,
"log text contains unloggable bytes");
/* we return true here, because returning false would mean
* "you aren't allowed to write to the log file anymore"
*/
return true;
}
if (!ply_write (logger->output_fd, string, length))
{
if (should_report_failures)
ply_logger_write_exception (logger, strerror (errno));
if (!ply_write (logger->output_fd, string, length)) {
if (should_report_failures)
ply_logger_write_exception (logger, strerror (errno));
return false;
}
return false;
}
return true;
return true;
}
static bool
ply_logger_flush_buffer (ply_logger_t *logger)
{
assert (logger != NULL);
assert (logger != NULL);
if (logger->buffer_size == 0)
return true;
if (logger->buffer_size == 0)
return true;
if (!ply_logger_write (logger, logger->buffer, logger->buffer_size, true))
return false;
if (!ply_logger_write (logger, logger->buffer, logger->buffer_size, true))
return false;
memset (logger->buffer, '\0', logger->buffer_size);
logger->buffer_size = 0;
memset (logger->buffer, '\0', logger->buffer_size);
logger->buffer_size = 0;
return true;
return true;
}
static bool
ply_logger_increase_buffer_size (ply_logger_t *logger)
{
assert (logger != NULL);
assert (logger != NULL);
if ((logger->buffer_capacity * 2) > PLY_LOGGER_MAX_BUFFER_CAPACITY)
return false;
if ((logger->buffer_capacity * 2) > PLY_LOGGER_MAX_BUFFER_CAPACITY)
return false;
logger->buffer_capacity *= 2;
logger->buffer_capacity *= 2;
logger->buffer = realloc (logger->buffer, logger->buffer_capacity);
return true;
logger->buffer = realloc (logger->buffer, logger->buffer_capacity);
return true;
}
static void
ply_logger_decapitate_buffer (ply_logger_t *logger,
size_t bytes_in_head)
{
assert (logger != NULL);
assert (logger != NULL);
bytes_in_head = MIN (logger->buffer_size, bytes_in_head);
bytes_in_head = MIN (logger->buffer_size, bytes_in_head);
if (bytes_in_head == logger->buffer_size)
logger->buffer_size = 0;
else
{
memmove (logger->buffer, logger->buffer + bytes_in_head,
logger->buffer_size - bytes_in_head);
logger->buffer_size -= bytes_in_head;
}
if (bytes_in_head == logger->buffer_size) {
logger->buffer_size = 0;
} else {
memmove (logger->buffer, logger->buffer + bytes_in_head,
logger->buffer_size - bytes_in_head);
logger->buffer_size -= bytes_in_head;
}
}
static bool
@ -201,304 +198,294 @@ ply_logger_buffer (ply_logger_t *logger,
const char *string,
size_t length)
{
assert (logger != NULL);
assert (logger != NULL);
if ((logger->buffer_size + length) >= logger->buffer_capacity)
{
if (!ply_logger_increase_buffer_size (logger))
{
ply_logger_decapitate_buffer (logger, length);
if ((logger->buffer_size + length) >= logger->buffer_capacity) {
if (!ply_logger_increase_buffer_size (logger)) {
ply_logger_decapitate_buffer (logger, length);
if ((logger->buffer_size + length) >= logger->buffer_capacity)
if (!ply_logger_increase_buffer_size (logger))
return false;
if ((logger->buffer_size + length) >= logger->buffer_capacity)
if (!ply_logger_increase_buffer_size (logger))
return false;
}
}
}
assert (logger->buffer_size + length < logger->buffer_capacity);
assert (logger->buffer_size + length < logger->buffer_capacity);
memcpy (logger->buffer + logger->buffer_size,
string, length);
memcpy (logger->buffer + logger->buffer_size,
string, length);
logger->buffer_size += length;
logger->buffer_size += length;
return true;
return true;
}
ply_logger_t *
ply_logger_new (void)
{
ply_logger_t *logger;
ply_logger_t *logger;
logger = calloc (1, sizeof (ply_logger_t));
logger = calloc (1, sizeof(ply_logger_t));
logger->output_fd = -1;
logger->filename = NULL;
logger->is_enabled = true;
logger->tracing_is_enabled = false;
logger->output_fd = -1;
logger->filename = NULL;
logger->is_enabled = true;
logger->tracing_is_enabled = false;
logger->buffer_capacity = 4096;
logger->buffer = calloc (1, logger->buffer_capacity);
logger->buffer_size = 0;
logger->buffer_capacity = 4096;
logger->buffer = calloc (1, logger->buffer_capacity);
logger->buffer_size = 0;
logger->filters = ply_list_new ();
logger->filters = ply_list_new ();
return logger;
return logger;
}
ply_logger_t *
ply_logger_get_default (void)
{
static ply_logger_t *logger = NULL;
static ply_logger_t *logger = NULL;
if (logger == NULL)
{
logger = ply_logger_new ();
ply_logger_set_output_fd (logger, STDOUT_FILENO);
}
if (logger == NULL) {
logger = ply_logger_new ();
ply_logger_set_output_fd (logger, STDOUT_FILENO);
}
return logger;
return logger;
}
ply_logger_t *
ply_logger_get_error_default (void)
{
static ply_logger_t *logger = NULL;
static ply_logger_t *logger = NULL;
if (logger == NULL)
{
logger = ply_logger_new ();
ply_logger_set_output_fd (logger, STDERR_FILENO);
ply_logger_set_flush_policy (logger,
PLY_LOGGER_FLUSH_POLICY_EVERY_TIME);
}
if (logger == NULL) {
logger = ply_logger_new ();
ply_logger_set_output_fd (logger, STDERR_FILENO);
ply_logger_set_flush_policy (logger,
PLY_LOGGER_FLUSH_POLICY_EVERY_TIME);
}
return logger;
return logger;
}
static void
ply_logger_free_filters (ply_logger_t *logger)
{
ply_list_node_t *node;
ply_list_node_t *node;
node = ply_list_get_first_node (logger->filters);
while (node != NULL)
{
ply_list_node_t *next_node;
ply_logger_filter_t *filter;
node = ply_list_get_first_node (logger->filters);
while (node != NULL) {
ply_list_node_t *next_node;
ply_logger_filter_t *filter;
filter = (ply_logger_filter_t *) ply_list_node_get_data (node);
filter = (ply_logger_filter_t *) ply_list_node_get_data (node);
next_node = ply_list_get_next_node (logger->filters, node);
free (filter);
node = next_node;
}
next_node = ply_list_get_next_node (logger->filters, node);
free (filter);
node = next_node;
}
ply_list_free (logger->filters);
ply_list_free (logger->filters);
}
void
ply_logger_free (ply_logger_t *logger)
{
if (logger == NULL)
return;
if (logger == NULL)
return;
if (logger->output_fd >= 0)
{
if (ply_logger_is_logging (logger))
ply_logger_flush (logger);
close (logger->output_fd);
}
if (logger->output_fd >= 0) {
if (ply_logger_is_logging (logger))
ply_logger_flush (logger);
close (logger->output_fd);
}
ply_logger_free_filters (logger);
ply_logger_free_filters (logger);
free (logger->filename);
free (logger->buffer);
free (logger);
free (logger->filename);
free (logger->buffer);
free (logger);
}
bool
ply_logger_open_file (ply_logger_t *logger,
const char *filename,
bool world_readable)
ply_logger_open_file (ply_logger_t *logger,
const char *filename,
bool world_readable)
{
int fd;
mode_t mode;
int fd;
mode_t mode;
assert (logger != NULL);
assert (filename != NULL);
assert (logger != NULL);
assert (filename != NULL);
if (world_readable)
mode = 0644;
else
mode = 0600;
if (world_readable)
mode = 0644;
else
mode = 0600;
fd = open (filename, PLY_LOGGER_OPEN_FLAGS, mode);
fd = open (filename, PLY_LOGGER_OPEN_FLAGS, mode);
if (fd < 0)
return false;
if (fd < 0)
return false;
if (fchmod (fd, mode) < 0) {
close (fd);
return false;
}
if (fchmod (fd, mode) < 0) {
close (fd);
return false;
}
ply_logger_set_output_fd (logger, fd);
ply_logger_set_output_fd (logger, fd);
free (logger->filename);
free (logger->filename);
logger->filename = strdup (filename);
logger->filename = strdup (filename);
return true;
return true;
}
void
ply_logger_close_file (ply_logger_t *logger)
{
assert (logger != NULL);
assert (logger != NULL);
if (logger->output_fd < 0)
return;
if (logger->output_fd < 0)
return;
close (logger->output_fd);
ply_logger_set_output_fd (logger, -1);
close (logger->output_fd);
ply_logger_set_output_fd (logger, -1);
}
void
ply_logger_set_output_fd (ply_logger_t *logger,
int fd)
{
assert (logger != NULL);
assert (logger != NULL);
logger->output_fd = fd;
logger->output_fd = fd;
}
int
ply_logger_get_output_fd (ply_logger_t *logger)
{
assert (logger != NULL);
assert (logger != NULL);
return logger->output_fd;
return logger->output_fd;
}
bool
ply_logger_flush (ply_logger_t *logger)
{
assert (logger != NULL);
assert (logger != NULL);
if (!ply_logger_is_logging (logger))
return false;
if (!ply_logger_is_logging (logger))
return false;
if (logger->output_fd < 0)
return false;
if (logger->output_fd < 0)
return false;
if (!ply_logger_flush_buffer (logger))
return false;
if (!ply_logger_flush_buffer (logger))
return false;
#ifdef SYNC_ON_FLUSH
if ((fdatasync (logger->output_fd) < 0) &&
((errno != EROFS) && (errno != EINVAL)))
return false;
if ((fdatasync (logger->output_fd) < 0) &&
((errno != EROFS) && (errno != EINVAL)))
return false;
#endif
return true;
return true;
}
void
ply_logger_set_flush_policy (ply_logger_t *logger,
ply_logger_flush_policy_t policy)
ply_logger_set_flush_policy (ply_logger_t *logger,
ply_logger_flush_policy_t policy)
{
assert (logger != NULL);
assert (logger != NULL);
logger->flush_policy = policy;
logger->flush_policy = policy;
}
ply_logger_flush_policy_t
ply_logger_get_flush_policy (ply_logger_t *logger)
{
assert (logger != NULL);
assert (logger != NULL);
return logger->flush_policy;
return logger->flush_policy;
}
void
ply_logger_toggle_logging (ply_logger_t *logger)
{
assert (logger != NULL);
assert (logger != NULL);
logger->is_enabled = !logger->is_enabled;
logger->is_enabled = !logger->is_enabled;
}
bool
ply_logger_is_logging (ply_logger_t *logger)
{
assert (logger != NULL);
assert (logger != NULL);
return logger->is_enabled != false;
return logger->is_enabled != false;
}
static bool
ply_logger_validate_format_string (ply_logger_t *logger,
const char *format)
ply_logger_validate_format_string (ply_logger_t *logger,
const char *format)
{
char *n, *p;
char *n, *p;
p = (char *) format;
p = (char *) format;
/* lame checks to limit the damage
* of some potential exploits.
*/
while ((n = strstr (p, "%n")) != NULL)
{
if (n == format)
return false;
/* lame checks to limit the damage
* of some potential exploits.
*/
while ((n = strstr (p, "%n")) != NULL) {
if (n == format)
return false;
if (n[-1] != '%')
return false;
if (n[-1] != '%')
return false;
p = n + 1;
}
p = n + 1;
}
return true;
return true;
}
void
ply_logger_inject_with_non_literal_format_string (ply_logger_t *logger,
const char *format,
ply_logger_inject_with_non_literal_format_string (ply_logger_t *logger,
const char *format,
...)
{
va_list args;
size_t string_size;
char write_buffer[PLY_LOGGER_MAX_INJECTION_SIZE] = "";
va_list args;
size_t string_size;
char write_buffer[PLY_LOGGER_MAX_INJECTION_SIZE] = "";
assert (logger != NULL);
assert (logger != NULL);
if (!ply_logger_is_logging (logger))
return;
if (!ply_logger_is_logging (logger))
return;
if (!ply_logger_validate_format_string (logger, format))
{
ply_logger_write_exception (logger, "log format string invalid");
return;
}
if (!ply_logger_validate_format_string (logger, format)) {
ply_logger_write_exception (logger, "log format string invalid");
return;
}
va_start (args, format);
string_size = vsnprintf (write_buffer, 0, format, args) + 1;
va_end (args);
va_start (args, format);
string_size = vsnprintf (write_buffer, 0, format, args) + 1;
va_end (args);
if (string_size > PLY_LOGGER_MAX_INJECTION_SIZE)
{
ply_logger_write_exception (logger, "log text too long");
return;
}
if (string_size > PLY_LOGGER_MAX_INJECTION_SIZE) {
ply_logger_write_exception (logger, "log text too long");
return;
}
va_start (args, format);
vsnprintf (write_buffer, PLY_LOGGER_MAX_INJECTION_SIZE,
format, args);
va_end (args);
ply_logger_inject_bytes (logger, write_buffer, string_size - 1);
va_start (args, format);
vsnprintf (write_buffer, PLY_LOGGER_MAX_INJECTION_SIZE,
format, args);
va_end (args);
ply_logger_inject_bytes (logger, write_buffer, string_size - 1);
}
void
@ -506,95 +493,91 @@ ply_logger_inject_bytes (ply_logger_t *logger,
const void *bytes,
size_t number_of_bytes)
{
ply_list_node_t *node;
void *filtered_bytes;
size_t filtered_size;
ply_list_node_t *node;
void *filtered_bytes;
size_t filtered_size;
assert (logger != NULL);
assert (bytes != NULL);
assert (number_of_bytes != 0);
assert (logger != NULL);
assert (bytes != NULL);
assert (number_of_bytes != 0);
filtered_bytes = NULL;
filtered_size = 0;
node = ply_list_get_first_node (logger->filters);
while (node != NULL)
{
ply_list_node_t *next_node;
ply_logger_filter_t *filter;
filtered_bytes = NULL;
filtered_size = 0;
node = ply_list_get_first_node (logger->filters);
while (node != NULL) {
ply_list_node_t *next_node;
ply_logger_filter_t *filter;
filter = (ply_logger_filter_t *) ply_list_node_get_data (node);
filter = (ply_logger_filter_t *) ply_list_node_get_data (node);
next_node = ply_list_get_next_node (logger->filters, node);
next_node = ply_list_get_next_node (logger->filters, node);
if (filtered_bytes == NULL)
filter->handler (filter->user_data, bytes, number_of_bytes,
&filtered_bytes, &filtered_size, logger);
else
{
void *new_bytes;
size_t new_size;
if (filtered_bytes == NULL) {
filter->handler (filter->user_data, bytes, number_of_bytes,
&filtered_bytes, &filtered_size, logger);
} else {
void *new_bytes;
size_t new_size;
new_bytes = NULL;
new_size = 0;
filter->handler (filter->user_data, filtered_bytes, filtered_size,
&new_bytes, &new_size, logger);
new_bytes = NULL;
new_size = 0;
filter->handler (filter->user_data, filtered_bytes, filtered_size,
&new_bytes, &new_size, logger);
if (new_bytes != NULL)
{
free (filtered_bytes);
filtered_bytes = new_bytes;
filtered_size = new_size;
}
if (new_bytes != NULL) {
free (filtered_bytes);
filtered_bytes = new_bytes;
filtered_size = new_size;
}
}
node = next_node;
}
node = next_node;
}
if (filtered_bytes == NULL) {
ply_logger_buffer (logger, bytes, number_of_bytes);
} else {
ply_logger_buffer (logger, filtered_bytes, filtered_size);
free (filtered_bytes);
}
if (filtered_bytes == NULL)
ply_logger_buffer (logger, bytes, number_of_bytes);
else
{
ply_logger_buffer (logger, filtered_bytes, filtered_size);
free (filtered_bytes);
}
assert ((logger->flush_policy == PLY_LOGGER_FLUSH_POLICY_WHEN_ASKED)
|| (logger->flush_policy == PLY_LOGGER_FLUSH_POLICY_EVERY_TIME));
assert ((logger->flush_policy == PLY_LOGGER_FLUSH_POLICY_WHEN_ASKED)
|| (logger->flush_policy == PLY_LOGGER_FLUSH_POLICY_EVERY_TIME));
if (logger->flush_policy == PLY_LOGGER_FLUSH_POLICY_EVERY_TIME)
ply_logger_flush (logger);
if (logger->flush_policy == PLY_LOGGER_FLUSH_POLICY_EVERY_TIME)
ply_logger_flush (logger);
}
void
ply_logger_add_filter (ply_logger_t *logger,
ply_logger_filter_handler_t filter_handler,
void *user_data)
ply_logger_add_filter (ply_logger_t *logger,
ply_logger_filter_handler_t filter_handler,
void *user_data)
{
ply_logger_filter_t *filter;
ply_logger_filter_t *filter;
filter = calloc (1, sizeof (ply_logger_filter_t));
filter = calloc (1, sizeof(ply_logger_filter_t));
filter->handler = filter_handler;
filter->user_data = user_data;
filter->handler = filter_handler;
filter->user_data = user_data;
ply_list_append_data (logger->filters, filter);
ply_list_append_data (logger->filters, filter);
}
#ifdef PLY_ENABLE_TRACING
void
ply_logger_toggle_tracing (ply_logger_t *logger)
{
assert (logger != NULL);
assert (logger != NULL);
logger->tracing_is_enabled = !logger->tracing_is_enabled;
logger->tracing_is_enabled = !logger->tracing_is_enabled;
}
bool
ply_logger_is_tracing_enabled (ply_logger_t *logger)
{
assert (logger != NULL);
assert (logger != NULL);
return logger->tracing_is_enabled != false;
return logger->tracing_is_enabled != false;
}
#endif /* PLY_ENABLE_TRACING */

View file

@ -31,16 +31,16 @@ typedef struct _ply_logger ply_logger_t;
typedef enum
{
PLY_LOGGER_FLUSH_POLICY_WHEN_ASKED = 0,
PLY_LOGGER_FLUSH_POLICY_EVERY_TIME
PLY_LOGGER_FLUSH_POLICY_WHEN_ASKED = 0,
PLY_LOGGER_FLUSH_POLICY_EVERY_TIME
} ply_logger_flush_policy_t;
typedef void (* ply_logger_filter_handler_t) (void *user_data,
const void *in_bytes,
size_t in_size,
void **out_bytes,
size_t *out_size,
ply_logger_t *logger);
typedef void (*ply_logger_filter_handler_t) (void *user_data,
const void *in_bytes,
size_t in_size,
void **out_bytes,
size_t *out_size,
ply_logger_t *logger);
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
ply_logger_t *ply_logger_new (void);
@ -48,28 +48,29 @@ void ply_logger_free (ply_logger_t *logger);
bool ply_logger_open_file (ply_logger_t *logger,
const char *filename,
bool world_readable);
void ply_logger_close_file (ply_logger_t *logger);
void ply_logger_close_file (ply_logger_t *logger);
void ply_logger_set_output_fd (ply_logger_t *logger,
int fd);
int ply_logger_get_output_fd (ply_logger_t *logger);
bool ply_logger_flush (ply_logger_t *logger);
void ply_logger_set_flush_policy (ply_logger_t *logger,
ply_logger_flush_policy_t policy);
void ply_logger_set_flush_policy (ply_logger_t *logger,
ply_logger_flush_policy_t policy);
ply_logger_flush_policy_t ply_logger_get_flush_policy (ply_logger_t *logger);
void ply_logger_toggle_logging (ply_logger_t *logger);
bool ply_logger_is_logging (ply_logger_t *logger);
void ply_logger_inject_bytes (ply_logger_t *logger,
const void *bytes,
size_t number_of_bytes);
void ply_logger_add_filter (ply_logger_t *logger,
ply_logger_filter_handler_t filter_handler,
void *user_data);
#define ply_logger_inject(logger, format, args...) \
size_t number_of_bytes);
void ply_logger_add_filter (ply_logger_t *logger,
ply_logger_filter_handler_t filter_handler,
void *user_data);
#define ply_logger_inject(logger, format, args ...) \
ply_logger_inject_with_non_literal_format_string (logger, \
format "", ##args)
format "", ## args)
__attribute__((__format__ (__printf__, 2, 3)))
void ply_logger_inject_with_non_literal_format_string (ply_logger_t *logger,
const char *format, ...);
void ply_logger_inject_with_non_literal_format_string (ply_logger_t *logger,
const char *format,
...);
ply_logger_t *ply_logger_get_default (void);
ply_logger_t *ply_logger_get_error_default (void);
@ -81,25 +82,25 @@ ply_logger_t *ply_logger_get_error_default (void);
void ply_logger_toggle_tracing (ply_logger_t *logger);
bool ply_logger_is_tracing_enabled (ply_logger_t *logger);
#define ply_logger_trace(logger, format, args...) \
do \
{ \
int _old_errno; \
_old_errno = errno; \
if (ply_logger_is_tracing_enabled (logger)) \
{ \
ply_logger_flush (logger); \
errno = _old_errno; \
ply_logger_inject (logger, \
"[%s:%d] %45.45s:" format "\r\n", \
__FILE__, __LINE__, __func__, ##args); \
ply_logger_flush (logger); \
errno = _old_errno; \
} \
} \
while (0)
#define ply_logger_trace(logger, format, args ...) \
do \
{ \
int _old_errno; \
_old_errno = errno; \
if (ply_logger_is_tracing_enabled (logger)) \
{ \
ply_logger_flush (logger); \
errno = _old_errno; \
ply_logger_inject (logger, \
"[%s:%d] %45.45s:" format "\r\n", \
__FILE__, __LINE__, __func__, ## args); \
ply_logger_flush (logger); \
errno = _old_errno; \
} \
} \
while (0)
#else
#define ply_logger_trace(logger, format, args...)
#define ply_logger_trace(logger, format, args ...)
#define ply_logger_toggle_tracing(logger)
#define ply_logger_is_tracing_enabled(logger) (false)
#endif /* PLY_ENABLE_TRACING */
@ -114,14 +115,14 @@ while (0)
ply_logger_flush (ply_logger_get_default ())
#define ply_free_log() \
ply_logger_free (ply_logger_get_default ())
#define ply_log(format, args...) \
ply_logger_inject (ply_logger_get_default (), format "\n", ##args)
#define ply_log_without_new_line(format, args...) \
ply_logger_inject (ply_logger_get_default (), format, ##args)
#define ply_error(format, args...) \
ply_logger_inject (ply_logger_get_error_default (), format "\n", ##args)
#define ply_error_without_new_line(format, args...) \
ply_logger_inject (ply_logger_get_error_default (), format, ##args)
#define ply_log(format, args ...) \
ply_logger_inject (ply_logger_get_default (), format "\n", ## args)
#define ply_log_without_new_line(format, args ...) \
ply_logger_inject (ply_logger_get_default (), format, ## args)
#define ply_error(format, args ...) \
ply_logger_inject (ply_logger_get_error_default (), format "\n", ## args)
#define ply_error_without_new_line(format, args ...) \
ply_logger_inject (ply_logger_get_error_default (), format, ## args)
#define ply_free_error_log() \
ply_logger_free (ply_logger_get_error_default ())
@ -129,8 +130,8 @@ while (0)
ply_logger_toggle_tracing (ply_logger_get_error_default ())
#define ply_is_tracing() \
ply_logger_is_tracing_enabled (ply_logger_get_error_default ())
#define ply_trace(format, args...) \
ply_logger_trace (ply_logger_get_error_default (), format, ##args)
#define ply_trace(format, args ...) \
ply_logger_trace (ply_logger_get_error_default (), format, ## args)
#endif

View file

@ -1,4 +1,4 @@
/* ply-progress.c - calculats boot progress
/* ply-progress.c - calculats boot progress
*
* Copyright (C) 2007 Red Hat, Inc.
*
@ -53,287 +53,274 @@
struct _ply_progress
{
double start_time;
double pause_time;
double scalar;
double last_percentage;
double last_percentage_time;
double dead_time;
double next_message_percentage;
ply_list_t *current_message_list;
ply_list_t *previous_message_list;
uint32_t paused : 1;
double start_time;
double pause_time;
double scalar;
double last_percentage;
double last_percentage_time;
double dead_time;
double next_message_percentage;
ply_list_t *current_message_list;
ply_list_t *previous_message_list;
uint32_t paused : 1;
};
typedef struct
typedef struct
{
double time;
char* string;
uint32_t disabled : 1;
double time;
char *string;
uint32_t disabled : 1;
} ply_progress_message_t;
ply_progress_t*
ply_progress_t *
ply_progress_new (void)
{
ply_progress_t *progress = calloc (1, sizeof (ply_progress_t));
progress->start_time = ply_get_timestamp();
progress->pause_time=0;
progress->scalar=1.0/DEFAULT_BOOT_DURATION;
progress->pause_time=0.0;
progress->last_percentage=0.0;
progress->last_percentage_time=0.0;
progress->dead_time=0.0;
progress->next_message_percentage=0.25;
progress->current_message_list = ply_list_new ();
progress->previous_message_list = ply_list_new ();
progress->paused = false;
return progress;
ply_progress_t *progress = calloc (1, sizeof(ply_progress_t));
progress->start_time = ply_get_timestamp ();
progress->pause_time = 0;
progress->scalar = 1.0 / DEFAULT_BOOT_DURATION;
progress->pause_time = 0.0;
progress->last_percentage = 0.0;
progress->last_percentage_time = 0.0;
progress->dead_time = 0.0;
progress->next_message_percentage = 0.25;
progress->current_message_list = ply_list_new ();
progress->previous_message_list = ply_list_new ();
progress->paused = false;
return progress;
}
void
ply_progress_free (ply_progress_t* progress)
ply_progress_free (ply_progress_t *progress)
{
ply_list_node_t *node;
node = ply_list_get_first_node (progress->current_message_list);
ply_list_node_t *node;
while (node)
{
ply_list_node_t *next_node;
ply_progress_message_t *message = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (progress->current_message_list, node);
node = ply_list_get_first_node (progress->current_message_list);
free (message->string);
free (message);
node = next_node;
}
ply_list_free (progress->current_message_list);
while (node) {
ply_list_node_t *next_node;
ply_progress_message_t *message = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (progress->current_message_list, node);
node = ply_list_get_first_node (progress->previous_message_list);
free (message->string);
free (message);
node = next_node;
}
ply_list_free (progress->current_message_list);
while (node)
{
ply_list_node_t *next_node;
ply_progress_message_t *message = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (progress->previous_message_list, node);
node = ply_list_get_first_node (progress->previous_message_list);
free (message->string);
free (message);
node = next_node;
}
ply_list_free (progress->previous_message_list);
free(progress);
return;
while (node) {
ply_list_node_t *next_node;
ply_progress_message_t *message = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (progress->previous_message_list, node);
free (message->string);
free (message);
node = next_node;
}
ply_list_free (progress->previous_message_list);
free (progress);
return;
}
static ply_progress_message_t*
ply_progress_message_search (ply_list_t *message_list, const char* string)
static ply_progress_message_t *
ply_progress_message_search (ply_list_t *message_list, const char *string)
{
ply_list_node_t *node;
node = ply_list_get_first_node (message_list);
ply_list_node_t *node;
while (node)
{
ply_progress_message_t *message = ply_list_node_get_data (node);
if (strcmp(string, message->string)==0)
return message;
node = ply_list_get_next_node (message_list, node);
}
return NULL;
node = ply_list_get_first_node (message_list);
while (node) {
ply_progress_message_t *message = ply_list_node_get_data (node);
if (strcmp (string, message->string) == 0)
return message;
node = ply_list_get_next_node (message_list, node);
}
return NULL;
}
static ply_progress_message_t*
static ply_progress_message_t *
ply_progress_message_search_next (ply_list_t *message_list, double time)
{
ply_list_node_t *node;
node = ply_list_get_first_node (message_list);
ply_progress_message_t *best=NULL;
while (node)
{
ply_progress_message_t *message = ply_list_node_get_data (node);
if (message->time > time && (!best || message->time < best->time))
best = message;
node = ply_list_get_next_node (message_list, node);
}
return best;
}
ply_list_node_t *node;
void
ply_progress_load_cache (ply_progress_t* progress,
const char *filename)
{
FILE *fp;
fp = fopen (filename,"r");
if (fp == NULL)
return;
while (1)
{
int items_matched;
double time;
int string_size=81;
char *string;
char colon;
int i=0;
items_matched = fscanf (fp, "%lf", &time);
if (items_matched<1) break;
items_matched = fscanf (fp, "%c", &colon);
if (items_matched<1 || colon != ':') break;
string = malloc(sizeof(char)*string_size);
while (1)
{
if (i>=string_size)
{
string_size*=2;
string = realloc(string, sizeof(char)*string_size);
}
items_matched = fscanf (fp, "%c", &string[i]);
if (items_matched<1 || string[i] == '\n')
{
string[i] = '\0';
break;
}
i++;
node = ply_list_get_first_node (message_list);
ply_progress_message_t *best = NULL;
while (node) {
ply_progress_message_t *message = ply_list_node_get_data (node);
if (message->time > time && (!best || message->time < best->time))
best = message;
node = ply_list_get_next_node (message_list, node);
}
ply_progress_message_t* message = malloc(sizeof(ply_progress_message_t));
message->time = time;
message->string = string;
ply_list_append_data(progress->previous_message_list, message);
}
fclose (fp);
return best;
}
void
ply_progress_save_cache (ply_progress_t* progress,
const char *filename)
ply_progress_load_cache (ply_progress_t *progress,
const char *filename)
{
FILE *fp;
ply_list_node_t *node;
double cur_time = ply_progress_get_time(progress);
FILE *fp;
ply_trace ("saving progress cache to %s", filename);
fp = fopen (filename, "r");
if (fp == NULL)
return;
fp = fopen (filename,"w");
if (fp == NULL)
{
ply_trace ("failed to save cache: %m");
return;
}
while (1) {
int items_matched;
double time;
int string_size = 81;
char *string;
char colon;
int i = 0;
node = ply_list_get_first_node (progress->current_message_list);
items_matched = fscanf (fp, "%lf", &time);
if (items_matched < 1) break;
items_matched = fscanf (fp, "%c", &colon);
if (items_matched < 1 || colon != ':') break;
while (node)
{
ply_progress_message_t *message = ply_list_node_get_data (node);
double percentage = message->time / cur_time;
if (!message->disabled)
fprintf (fp, "%.3lf:%s\n", percentage, message->string);
node = ply_list_get_next_node (progress->current_message_list, node);
}
fclose (fp);
string = malloc (sizeof(char) * string_size);
while (1) {
if (i >= string_size) {
string_size *= 2;
string = realloc (string, sizeof(char) * string_size);
}
items_matched = fscanf (fp, "%c", &string[i]);
if (items_matched < 1 || string[i] == '\n') {
string[i] = '\0';
break;
}
i++;
}
ply_progress_message_t *message = malloc (sizeof(ply_progress_message_t));
message->time = time;
message->string = string;
ply_list_append_data (progress->previous_message_list, message);
}
fclose (fp);
}
void
ply_progress_save_cache (ply_progress_t *progress,
const char *filename)
{
FILE *fp;
ply_list_node_t *node;
double cur_time = ply_progress_get_time (progress);
ply_trace ("saving progress cache to %s", filename);
fp = fopen (filename, "w");
if (fp == NULL) {
ply_trace ("failed to save cache: %m");
return;
}
node = ply_list_get_first_node (progress->current_message_list);
while (node) {
ply_progress_message_t *message = ply_list_node_get_data (node);
double percentage = message->time / cur_time;
if (!message->disabled)
fprintf (fp, "%.3lf:%s\n", percentage, message->string);
node = ply_list_get_next_node (progress->current_message_list, node);
}
fclose (fp);
}
double
ply_progress_get_percentage (ply_progress_t* progress)
ply_progress_get_percentage (ply_progress_t *progress)
{
double percentage;
double cur_time = ply_progress_get_time (progress);
if ((progress->last_percentage_time-progress->dead_time)*progress->scalar<0.999)
{
percentage = progress->last_percentage
+ (((cur_time - progress->last_percentage_time)*progress->scalar)
/ (1 - (progress->last_percentage_time-progress->dead_time)*progress->scalar))
* (1 - progress->last_percentage);
if ((percentage - progress->next_message_percentage)/progress->scalar > 1){
percentage = progress->last_percentage
+ (cur_time - progress->last_percentage_time) / (DEFAULT_BOOT_DURATION * 10);
progress->dead_time += cur_time - progress->last_percentage_time;
double percentage;
double cur_time = ply_progress_get_time (progress);
if ((progress->last_percentage_time - progress->dead_time) * progress->scalar < 0.999) {
percentage = progress->last_percentage
+ (((cur_time - progress->last_percentage_time) * progress->scalar)
/ (1 - (progress->last_percentage_time - progress->dead_time) * progress->scalar))
* (1 - progress->last_percentage);
if ((percentage - progress->next_message_percentage) / progress->scalar > 1) {
percentage = progress->last_percentage
+ (cur_time - progress->last_percentage_time) / (DEFAULT_BOOT_DURATION * 10);
progress->dead_time += cur_time - progress->last_percentage_time;
}
percentage = CLAMP (percentage, 0.0, 1.0);
} else {
percentage = 1.0;
}
percentage = CLAMP(percentage, 0.0, 1.0);
}
else
percentage = 1.0;
progress->last_percentage_time = cur_time;
progress->last_percentage = percentage;
return percentage;
progress->last_percentage_time = cur_time;
progress->last_percentage = percentage;
return percentage;
}
void
ply_progress_set_percentage (ply_progress_t* progress, double percentage)
ply_progress_set_percentage (ply_progress_t *progress, double percentage)
{
progress->next_message_percentage = 1;
progress->scalar += percentage / (ply_progress_get_time(progress)-progress->dead_time);
progress->scalar /= 2;
return;
progress->next_message_percentage = 1;
progress->scalar += percentage / (ply_progress_get_time (progress) - progress->dead_time);
progress->scalar /= 2;
return;
}
double
ply_progress_get_time (ply_progress_t* progress)
ply_progress_get_time (ply_progress_t *progress)
{
if (progress->paused)
{
return progress->pause_time - progress->start_time;
}
return ply_get_timestamp() - progress->start_time;
if (progress->paused)
return progress->pause_time - progress->start_time;
return ply_get_timestamp () - progress->start_time;
}
void
ply_progress_pause (ply_progress_t* progress)
ply_progress_pause (ply_progress_t *progress)
{
progress->pause_time = ply_get_timestamp ();
progress->paused = true;
return;
progress->pause_time = ply_get_timestamp ();
progress->paused = true;
return;
}
void
ply_progress_unpause (ply_progress_t* progress)
ply_progress_unpause (ply_progress_t *progress)
{
progress->start_time += ply_get_timestamp() - progress->pause_time;
progress->paused = false;
return;
progress->start_time += ply_get_timestamp () - progress->pause_time;
progress->paused = false;
return;
}
void
ply_progress_status_update (ply_progress_t* progress,
const char *status)
ply_progress_status_update (ply_progress_t *progress,
const char *status)
{
ply_progress_message_t *message, *message_next;
message = ply_progress_message_search(progress->current_message_list, status);
if (message)
{
message->disabled = true;
} /* Remove duplicates as they confuse things*/
else
{
message = ply_progress_message_search(progress->previous_message_list, status);
if (message)
{
message_next = ply_progress_message_search_next(progress->previous_message_list, message->time);
if (message_next)
progress->next_message_percentage = message_next->time;
else
progress->next_message_percentage = 1;
progress->scalar += message->time / (ply_progress_get_time(progress)-progress->dead_time);
progress->scalar /= 2;
ply_progress_message_t *message, *message_next;
message = ply_progress_message_search (progress->current_message_list, status);
if (message) {
message->disabled = true;
} /* Remove duplicates as they confuse things*/
else {
message = ply_progress_message_search (progress->previous_message_list, status);
if (message) {
message_next = ply_progress_message_search_next (progress->previous_message_list, message->time);
if (message_next)
progress->next_message_percentage = message_next->time;
else
progress->next_message_percentage = 1;
progress->scalar += message->time / (ply_progress_get_time (progress) - progress->dead_time);
progress->scalar /= 2;
}
message = malloc (sizeof(ply_progress_message_t));
message->time = ply_progress_get_time (progress);
message->string = strdup (status);
message->disabled = false;
ply_list_append_data (progress->current_message_list, message);
}
message = malloc(sizeof(ply_progress_message_t));
message->time = ply_progress_get_time (progress);
message->string = strdup(status);
message->disabled = false;
ply_list_append_data(progress->current_message_list, message);
}
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -1,4 +1,4 @@
/* ply-progress.h - calculats boot progress
/* ply-progress.h - calculats boot progress
*
* Copyright (C) 2007 Red Hat, Inc.
*
@ -28,15 +28,19 @@
typedef struct _ply_progress ply_progress_t;
ply_progress_t *ply_progress_new (void);
void ply_progress_free (ply_progress_t* progress);
void ply_progress_load_cache (ply_progress_t* progress, const char *filename);
double ply_progress_get_percentage (ply_progress_t* progress);
void ply_progress_set_percentage (ply_progress_t* progress, double percentage);
double ply_progress_get_time (ply_progress_t* progress);
void ply_progress_pause (ply_progress_t* progress);
void ply_progress_unpause (ply_progress_t* progress);
void ply_progress_save_cache (ply_progress_t* progress, const char *filename);
void ply_progress_status_update (ply_progress_t* progress, const char *status);
void ply_progress_free (ply_progress_t *progress);
void ply_progress_load_cache (ply_progress_t *progress,
const char *filename);
double ply_progress_get_percentage (ply_progress_t *progress);
void ply_progress_set_percentage (ply_progress_t *progress,
double percentage);
double ply_progress_get_time (ply_progress_t *progress);
void ply_progress_pause (ply_progress_t *progress);
void ply_progress_unpause (ply_progress_t *progress);
void ply_progress_save_cache (ply_progress_t *progress,
const char *filename);
void ply_progress_status_update (ply_progress_t *progress,
const char *status);
#endif /* PLY_PROGRESS_H */
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -32,180 +32,165 @@ ply_rectangle_contains_point (ply_rectangle_t *rectangle,
long x,
long y)
{
long top_edge;
long left_edge;
long right_edge;
long bottom_edge;
long top_edge;
long left_edge;
long right_edge;
long bottom_edge;
top_edge = rectangle->y;
left_edge = rectangle->x;
right_edge = rectangle->x + rectangle->width - 1;
bottom_edge = rectangle->y + rectangle->height - 1;
top_edge = rectangle->y;
left_edge = rectangle->x;
right_edge = rectangle->x + rectangle->width - 1;
bottom_edge = rectangle->y + rectangle->height - 1;
if (x < left_edge)
return false;
if (x < left_edge)
return false;
if (y < top_edge)
return false;
if (y < top_edge)
return false;
if (x > right_edge)
return false;
if (x > right_edge)
return false;
if (y > bottom_edge)
return false;
if (y > bottom_edge)
return false;
return true;
return true;
}
bool
ply_rectangle_is_empty (ply_rectangle_t *rectangle)
{
return rectangle->width == 0 || rectangle->height == 0;
return rectangle->width == 0 || rectangle->height == 0;
}
ply_rectangle_overlap_t
ply_rectangle_find_overlap (ply_rectangle_t *rectangle1,
ply_rectangle_t *rectangle2)
{
enum {H_COLLISION_NONE, H_COLLISION_LEFT, H_COLLISION_RIGHT, H_COLLISION_BOTH, H_COLLISION_CONTAINED, H_COLLISION_EXACT}
enum { H_COLLISION_NONE, H_COLLISION_LEFT, H_COLLISION_RIGHT, H_COLLISION_BOTH, H_COLLISION_CONTAINED, H_COLLISION_EXACT }
h_collision = H_COLLISION_NONE;
enum {V_COLLISION_NONE, V_COLLISION_TOP, V_COLLISION_BOTTOM, V_COLLISION_BOTH, V_COLLISION_CONTAINED, V_COLLISION_EXACT}
enum { V_COLLISION_NONE, V_COLLISION_TOP, V_COLLISION_BOTTOM, V_COLLISION_BOTH, V_COLLISION_CONTAINED, V_COLLISION_EXACT }
v_collision = V_COLLISION_NONE;
if (rectangle2->x >= rectangle1->x && (rectangle2->x + (int)rectangle2->width) <= (rectangle1->x + (int)rectangle1->width))
{
if (rectangle2->x == rectangle1->x && rectangle2->width == rectangle1->width)
h_collision = H_COLLISION_EXACT;
else
h_collision = H_COLLISION_CONTAINED;
}
else
{ /* Remember: x+width points to the first pixel outside the rectangle*/
if (rectangle2->x < rectangle1->x &&
(rectangle2->x + (int)rectangle2->width) > rectangle1->x)
h_collision = H_COLLISION_LEFT; /* rectangle2 colllided with the left edge of rectangle1 */
if (rectangle2->x >= rectangle1->x && (rectangle2->x + (int) rectangle2->width) <= (rectangle1->x + (int) rectangle1->width)) {
if (rectangle2->x == rectangle1->x && rectangle2->width == rectangle1->width)
h_collision = H_COLLISION_EXACT;
else
h_collision = H_COLLISION_CONTAINED;
} else { /* Remember: x+width points to the first pixel outside the rectangle*/
if (rectangle2->x < rectangle1->x &&
(rectangle2->x + (int) rectangle2->width) > rectangle1->x)
h_collision = H_COLLISION_LEFT; /* rectangle2 colllided with the left edge of rectangle1 */
if (rectangle2->x < (rectangle1->x + (int)rectangle1->width) &&
(rectangle2->x + (int)rectangle2->width) >= (rectangle1->x + (int)rectangle1->width))
{ /* rectangle2 colllided with the right edge of rectangle1 */
if (h_collision == H_COLLISION_LEFT)
h_collision = H_COLLISION_BOTH;
else
h_collision = H_COLLISION_RIGHT;
if (rectangle2->x < (rectangle1->x + (int) rectangle1->width) &&
(rectangle2->x + (int) rectangle2->width) >= (rectangle1->x + (int) rectangle1->width)) { /* rectangle2 colllided with the right edge of rectangle1 */
if (h_collision == H_COLLISION_LEFT)
h_collision = H_COLLISION_BOTH;
else
h_collision = H_COLLISION_RIGHT;
}
}
}
if (h_collision != H_COLLISION_NONE)
{
if (rectangle2->y >= rectangle1->y && (rectangle2->y + (int)rectangle2->height) <= (rectangle1->y + (int)rectangle1->height))
{
if (rectangle2->y == rectangle1->y && rectangle2->height == rectangle1->height)
v_collision = V_COLLISION_EXACT;
else
v_collision = V_COLLISION_CONTAINED;
if (h_collision != H_COLLISION_NONE) {
if (rectangle2->y >= rectangle1->y && (rectangle2->y + (int) rectangle2->height) <= (rectangle1->y + (int) rectangle1->height)) {
if (rectangle2->y == rectangle1->y && rectangle2->height == rectangle1->height)
v_collision = V_COLLISION_EXACT;
else
v_collision = V_COLLISION_CONTAINED;
} else {
if (rectangle2->y < rectangle1->y &&
(rectangle2->y + (int) rectangle2->height) > rectangle1->y)
v_collision = V_COLLISION_TOP;
if (rectangle2->y < (rectangle1->y + (int) rectangle1->height) &&
(rectangle2->y + (int) rectangle2->height) >= (rectangle1->y + (int) rectangle1->height)) {
if (v_collision == V_COLLISION_TOP)
v_collision = V_COLLISION_BOTH;
else
v_collision = V_COLLISION_BOTTOM;
}
}
}
else
{
if (rectangle2->y < rectangle1->y &&
(rectangle2->y + (int)rectangle2->height) > rectangle1->y)
v_collision = V_COLLISION_TOP;
if (rectangle2->y < (rectangle1->y + (int)rectangle1->height) &&
(rectangle2->y + (int)rectangle2->height) >= (rectangle1->y + (int)rectangle1->height))
{
if (v_collision == V_COLLISION_TOP)
v_collision = V_COLLISION_BOTH;
else
v_collision = V_COLLISION_BOTTOM;
}
}
}
switch (h_collision)
{
case H_COLLISION_NONE:
switch (h_collision) {
case H_COLLISION_NONE:
return PLY_RECTANGLE_OVERLAP_NONE;
case H_COLLISION_LEFT:
switch (v_collision) {
case V_COLLISION_NONE:
return PLY_RECTANGLE_OVERLAP_NONE;
case V_COLLISION_TOP:
return PLY_RECTANGLE_OVERLAP_TOP_AND_LEFT_EDGES;
case V_COLLISION_BOTTOM:
return PLY_RECTANGLE_OVERLAP_BOTTOM_AND_LEFT_EDGES;
case V_COLLISION_BOTH:
return PLY_RECTANGLE_OVERLAP_TOP_LEFT_AND_BOTTOM_EDGES;
case V_COLLISION_CONTAINED:
return PLY_RECTANGLE_OVERLAP_LEFT_EDGE;
case V_COLLISION_EXACT:
return PLY_RECTANGLE_OVERLAP_EXACT_LEFT_EDGE;
}
case H_COLLISION_RIGHT:
switch (v_collision) {
case V_COLLISION_NONE:
return PLY_RECTANGLE_OVERLAP_NONE;
case V_COLLISION_TOP:
return PLY_RECTANGLE_OVERLAP_TOP_AND_RIGHT_EDGES;
case V_COLLISION_BOTTOM:
return PLY_RECTANGLE_OVERLAP_BOTTOM_AND_RIGHT_EDGES;
case V_COLLISION_BOTH:
return PLY_RECTANGLE_OVERLAP_TOP_RIGHT_AND_BOTTOM_EDGES;
case V_COLLISION_CONTAINED:
return PLY_RECTANGLE_OVERLAP_RIGHT_EDGE;
case V_COLLISION_EXACT:
return PLY_RECTANGLE_OVERLAP_EXACT_RIGHT_EDGE;
}
case H_COLLISION_BOTH:
switch (v_collision) {
case V_COLLISION_NONE:
return PLY_RECTANGLE_OVERLAP_NONE;
case V_COLLISION_TOP:
return PLY_RECTANGLE_OVERLAP_TOP_AND_SIDE_EDGES;
case V_COLLISION_BOTTOM:
return PLY_RECTANGLE_OVERLAP_BOTTOM_AND_SIDE_EDGES;
case V_COLLISION_BOTH:
return PLY_RECTANGLE_OVERLAP_ALL_EDGES;
case V_COLLISION_CONTAINED:
return PLY_RECTANGLE_OVERLAP_SIDE_EDGES;
case V_COLLISION_EXACT:
return PLY_RECTANGLE_OVERLAP_ALL_EDGES;
}
case H_COLLISION_CONTAINED:
switch (v_collision) {
case V_COLLISION_NONE:
return PLY_RECTANGLE_OVERLAP_NONE;
case V_COLLISION_TOP:
return PLY_RECTANGLE_OVERLAP_TOP_EDGE;
case V_COLLISION_BOTTOM:
return PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE;
case V_COLLISION_BOTH:
return PLY_RECTANGLE_OVERLAP_TOP_AND_BOTTOM_EDGES;
case V_COLLISION_CONTAINED:
return PLY_RECTANGLE_OVERLAP_NO_EDGES;
case V_COLLISION_EXACT:
return PLY_RECTANGLE_OVERLAP_NO_EDGES;
}
case H_COLLISION_EXACT:
switch (v_collision) {
case V_COLLISION_NONE:
return PLY_RECTANGLE_OVERLAP_NONE;
case V_COLLISION_TOP:
return PLY_RECTANGLE_OVERLAP_EXACT_TOP_EDGE;
case V_COLLISION_BOTTOM:
return PLY_RECTANGLE_OVERLAP_EXACT_BOTTOM_EDGE;
case V_COLLISION_BOTH:
return PLY_RECTANGLE_OVERLAP_ALL_EDGES;
case V_COLLISION_CONTAINED:
return PLY_RECTANGLE_OVERLAP_NO_EDGES;
case V_COLLISION_EXACT:
return PLY_RECTANGLE_OVERLAP_NO_EDGES;
}
}
return PLY_RECTANGLE_OVERLAP_NONE;
case H_COLLISION_LEFT:
switch (v_collision)
{
case V_COLLISION_NONE:
return PLY_RECTANGLE_OVERLAP_NONE;
case V_COLLISION_TOP:
return PLY_RECTANGLE_OVERLAP_TOP_AND_LEFT_EDGES;
case V_COLLISION_BOTTOM:
return PLY_RECTANGLE_OVERLAP_BOTTOM_AND_LEFT_EDGES;
case V_COLLISION_BOTH:
return PLY_RECTANGLE_OVERLAP_TOP_LEFT_AND_BOTTOM_EDGES;
case V_COLLISION_CONTAINED:
return PLY_RECTANGLE_OVERLAP_LEFT_EDGE;
case V_COLLISION_EXACT:
return PLY_RECTANGLE_OVERLAP_EXACT_LEFT_EDGE;
}
case H_COLLISION_RIGHT:
switch (v_collision)
{
case V_COLLISION_NONE:
return PLY_RECTANGLE_OVERLAP_NONE;
case V_COLLISION_TOP:
return PLY_RECTANGLE_OVERLAP_TOP_AND_RIGHT_EDGES;
case V_COLLISION_BOTTOM:
return PLY_RECTANGLE_OVERLAP_BOTTOM_AND_RIGHT_EDGES;
case V_COLLISION_BOTH:
return PLY_RECTANGLE_OVERLAP_TOP_RIGHT_AND_BOTTOM_EDGES;
case V_COLLISION_CONTAINED:
return PLY_RECTANGLE_OVERLAP_RIGHT_EDGE;
case V_COLLISION_EXACT:
return PLY_RECTANGLE_OVERLAP_EXACT_RIGHT_EDGE;
}
case H_COLLISION_BOTH:
switch (v_collision)
{
case V_COLLISION_NONE:
return PLY_RECTANGLE_OVERLAP_NONE;
case V_COLLISION_TOP:
return PLY_RECTANGLE_OVERLAP_TOP_AND_SIDE_EDGES;
case V_COLLISION_BOTTOM:
return PLY_RECTANGLE_OVERLAP_BOTTOM_AND_SIDE_EDGES;
case V_COLLISION_BOTH:
return PLY_RECTANGLE_OVERLAP_ALL_EDGES;
case V_COLLISION_CONTAINED:
return PLY_RECTANGLE_OVERLAP_SIDE_EDGES;
case V_COLLISION_EXACT:
return PLY_RECTANGLE_OVERLAP_ALL_EDGES;
}
case H_COLLISION_CONTAINED:
switch (v_collision)
{
case V_COLLISION_NONE:
return PLY_RECTANGLE_OVERLAP_NONE;
case V_COLLISION_TOP:
return PLY_RECTANGLE_OVERLAP_TOP_EDGE;
case V_COLLISION_BOTTOM:
return PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE;
case V_COLLISION_BOTH:
return PLY_RECTANGLE_OVERLAP_TOP_AND_BOTTOM_EDGES;
case V_COLLISION_CONTAINED:
return PLY_RECTANGLE_OVERLAP_NO_EDGES;
case V_COLLISION_EXACT:
return PLY_RECTANGLE_OVERLAP_NO_EDGES;
}
case H_COLLISION_EXACT:
switch (v_collision)
{
case V_COLLISION_NONE:
return PLY_RECTANGLE_OVERLAP_NONE;
case V_COLLISION_TOP:
return PLY_RECTANGLE_OVERLAP_EXACT_TOP_EDGE;
case V_COLLISION_BOTTOM:
return PLY_RECTANGLE_OVERLAP_EXACT_BOTTOM_EDGE;
case V_COLLISION_BOTH:
return PLY_RECTANGLE_OVERLAP_ALL_EDGES;
case V_COLLISION_CONTAINED:
return PLY_RECTANGLE_OVERLAP_NO_EDGES;
case V_COLLISION_EXACT:
return PLY_RECTANGLE_OVERLAP_NO_EDGES;
}
}
return PLY_RECTANGLE_OVERLAP_NONE;
}
void
@ -213,65 +198,61 @@ ply_rectangle_intersect (ply_rectangle_t *rectangle1,
ply_rectangle_t *rectangle2,
ply_rectangle_t *result)
{
long rectangle1_top_edge;
long rectangle1_left_edge;
long rectangle1_right_edge;
long rectangle1_bottom_edge;
long rectangle2_top_edge;
long rectangle2_left_edge;
long rectangle2_right_edge;
long rectangle2_bottom_edge;
long result_top_edge;
long result_left_edge;
long result_right_edge;
long result_bottom_edge;
long rectangle1_top_edge;
long rectangle1_left_edge;
long rectangle1_right_edge;
long rectangle1_bottom_edge;
long rectangle2_top_edge;
long rectangle2_left_edge;
long rectangle2_right_edge;
long rectangle2_bottom_edge;
long result_top_edge;
long result_left_edge;
long result_right_edge;
long result_bottom_edge;
if (ply_rectangle_is_empty (rectangle1)) {
*result = *rectangle1;
return;
}
if (ply_rectangle_is_empty (rectangle1))
{
*result = *rectangle1;
return;
}
if (ply_rectangle_is_empty (rectangle2)) {
*result = *rectangle2;
return;
}
if (ply_rectangle_is_empty (rectangle2))
{
*result = *rectangle2;
return;
}
rectangle1_top_edge = rectangle1->y;
rectangle1_left_edge = rectangle1->x;
rectangle1_right_edge = rectangle1->x + rectangle1->width - 1;
rectangle1_bottom_edge = rectangle1->y + rectangle1->height - 1;
rectangle1_top_edge = rectangle1->y;
rectangle1_left_edge = rectangle1->x;
rectangle1_right_edge = rectangle1->x + rectangle1->width - 1;
rectangle1_bottom_edge = rectangle1->y + rectangle1->height - 1;
rectangle2_top_edge = rectangle2->y;
rectangle2_left_edge = rectangle2->x;
rectangle2_right_edge = rectangle2->x + rectangle2->width - 1;
rectangle2_bottom_edge = rectangle2->y + rectangle2->height - 1;
rectangle2_top_edge = rectangle2->y;
rectangle2_left_edge = rectangle2->x;
rectangle2_right_edge = rectangle2->x + rectangle2->width - 1;
rectangle2_bottom_edge = rectangle2->y + rectangle2->height - 1;
result_top_edge = MAX (rectangle1_top_edge, rectangle2_top_edge);
result_left_edge = MAX (rectangle1_left_edge, rectangle2_left_edge);
result_right_edge = MIN (rectangle1_right_edge, rectangle2_right_edge);
result_bottom_edge = MIN (rectangle1_bottom_edge, rectangle2_bottom_edge);
result_top_edge = MAX (rectangle1_top_edge, rectangle2_top_edge);
result_left_edge = MAX (rectangle1_left_edge, rectangle2_left_edge);
result_right_edge = MIN (rectangle1_right_edge, rectangle2_right_edge);
result_bottom_edge = MIN (rectangle1_bottom_edge, rectangle2_bottom_edge);
result->x = result_left_edge;
result->y = result_top_edge;
result->x = result_left_edge;
result->y = result_top_edge;
if (result_right_edge >= result_left_edge)
result->width = result_right_edge - result_left_edge + 1;
else
result->width = 0;
if (result_right_edge >= result_left_edge)
result->width = result_right_edge - result_left_edge + 1;
else
result->width = 0;
if (result_bottom_edge >= result_top_edge)
result->height = result_bottom_edge - result_top_edge + 1;
else
result->height = 0;
if (result_bottom_edge >= result_top_edge)
result->height = result_bottom_edge - result_top_edge + 1;
else
result->height = 0;
if (ply_rectangle_is_empty (result))
{
result->width = 0;
result->height = 0;
}
if (ply_rectangle_is_empty (result)) {
result->width = 0;
result->height = 0;
}
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -31,64 +31,63 @@ typedef struct _ply_rectangle ply_rectangle_t;
struct _ply_rectangle
{
long x;
long y;
unsigned long width;
unsigned long height;
long x;
long y;
unsigned long width;
unsigned long height;
};
typedef enum
{
PLY_RECTANGLE_OVERLAP_NONE = 0,
PLY_RECTANGLE_OVERLAP_TOP_EDGE = 1 << 0,
PLY_RECTANGLE_OVERLAP_LEFT_EDGE = 1 << 1,
PLY_RECTANGLE_OVERLAP_RIGHT_EDGE = 1 << 2,
PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE = 1 << 3,
PLY_RECTANGLE_OVERLAP_TOP_AND_LEFT_EDGES =
PLY_RECTANGLE_OVERLAP_TOP_EDGE |
PLY_RECTANGLE_OVERLAP_LEFT_EDGE,
PLY_RECTANGLE_OVERLAP_TOP_AND_RIGHT_EDGES =
PLY_RECTANGLE_OVERLAP_TOP_EDGE |
PLY_RECTANGLE_OVERLAP_RIGHT_EDGE,
PLY_RECTANGLE_OVERLAP_TOP_AND_SIDE_EDGES =
PLY_RECTANGLE_OVERLAP_TOP_EDGE |
PLY_RECTANGLE_OVERLAP_LEFT_EDGE |
PLY_RECTANGLE_OVERLAP_RIGHT_EDGE,
PLY_RECTANGLE_OVERLAP_BOTTOM_AND_LEFT_EDGES =
PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE |
PLY_RECTANGLE_OVERLAP_LEFT_EDGE,
PLY_RECTANGLE_OVERLAP_BOTTOM_AND_RIGHT_EDGES =
PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE |
PLY_RECTANGLE_OVERLAP_RIGHT_EDGE,
PLY_RECTANGLE_OVERLAP_BOTTOM_AND_SIDE_EDGES =
PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE |
PLY_RECTANGLE_OVERLAP_LEFT_EDGE |
PLY_RECTANGLE_OVERLAP_RIGHT_EDGE,
PLY_RECTANGLE_OVERLAP_SIDE_EDGES =
PLY_RECTANGLE_OVERLAP_LEFT_EDGE |
PLY_RECTANGLE_OVERLAP_RIGHT_EDGE,
PLY_RECTANGLE_OVERLAP_TOP_AND_BOTTOM_EDGES =
PLY_RECTANGLE_OVERLAP_TOP_EDGE |
PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE,
PLY_RECTANGLE_OVERLAP_TOP_LEFT_AND_BOTTOM_EDGES =
PLY_RECTANGLE_OVERLAP_TOP_EDGE |
PLY_RECTANGLE_OVERLAP_LEFT_EDGE |
PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE,
PLY_RECTANGLE_OVERLAP_TOP_RIGHT_AND_BOTTOM_EDGES =
PLY_RECTANGLE_OVERLAP_TOP_EDGE |
PLY_RECTANGLE_OVERLAP_RIGHT_EDGE |
PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE,
PLY_RECTANGLE_OVERLAP_ALL_EDGES =
PLY_RECTANGLE_OVERLAP_TOP_EDGE |
PLY_RECTANGLE_OVERLAP_LEFT_EDGE |
PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE |
PLY_RECTANGLE_OVERLAP_RIGHT_EDGE,
PLY_RECTANGLE_OVERLAP_NO_EDGES = 1 << 4,
PLY_RECTANGLE_OVERLAP_EXACT_TOP_EDGE,
PLY_RECTANGLE_OVERLAP_EXACT_LEFT_EDGE,
PLY_RECTANGLE_OVERLAP_EXACT_RIGHT_EDGE,
PLY_RECTANGLE_OVERLAP_EXACT_BOTTOM_EDGE,
PLY_RECTANGLE_OVERLAP_NONE = 0,
PLY_RECTANGLE_OVERLAP_TOP_EDGE = 1 << 0,
PLY_RECTANGLE_OVERLAP_LEFT_EDGE = 1 << 1,
PLY_RECTANGLE_OVERLAP_RIGHT_EDGE = 1 << 2,
PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE = 1 << 3,
PLY_RECTANGLE_OVERLAP_TOP_AND_LEFT_EDGES =
PLY_RECTANGLE_OVERLAP_TOP_EDGE |
PLY_RECTANGLE_OVERLAP_LEFT_EDGE,
PLY_RECTANGLE_OVERLAP_TOP_AND_RIGHT_EDGES =
PLY_RECTANGLE_OVERLAP_TOP_EDGE |
PLY_RECTANGLE_OVERLAP_RIGHT_EDGE,
PLY_RECTANGLE_OVERLAP_TOP_AND_SIDE_EDGES =
PLY_RECTANGLE_OVERLAP_TOP_EDGE |
PLY_RECTANGLE_OVERLAP_LEFT_EDGE |
PLY_RECTANGLE_OVERLAP_RIGHT_EDGE,
PLY_RECTANGLE_OVERLAP_BOTTOM_AND_LEFT_EDGES =
PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE |
PLY_RECTANGLE_OVERLAP_LEFT_EDGE,
PLY_RECTANGLE_OVERLAP_BOTTOM_AND_RIGHT_EDGES =
PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE |
PLY_RECTANGLE_OVERLAP_RIGHT_EDGE,
PLY_RECTANGLE_OVERLAP_BOTTOM_AND_SIDE_EDGES =
PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE |
PLY_RECTANGLE_OVERLAP_LEFT_EDGE |
PLY_RECTANGLE_OVERLAP_RIGHT_EDGE,
PLY_RECTANGLE_OVERLAP_SIDE_EDGES =
PLY_RECTANGLE_OVERLAP_LEFT_EDGE |
PLY_RECTANGLE_OVERLAP_RIGHT_EDGE,
PLY_RECTANGLE_OVERLAP_TOP_AND_BOTTOM_EDGES =
PLY_RECTANGLE_OVERLAP_TOP_EDGE |
PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE,
PLY_RECTANGLE_OVERLAP_TOP_LEFT_AND_BOTTOM_EDGES =
PLY_RECTANGLE_OVERLAP_TOP_EDGE |
PLY_RECTANGLE_OVERLAP_LEFT_EDGE |
PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE,
PLY_RECTANGLE_OVERLAP_TOP_RIGHT_AND_BOTTOM_EDGES =
PLY_RECTANGLE_OVERLAP_TOP_EDGE |
PLY_RECTANGLE_OVERLAP_RIGHT_EDGE |
PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE,
PLY_RECTANGLE_OVERLAP_ALL_EDGES =
PLY_RECTANGLE_OVERLAP_TOP_EDGE |
PLY_RECTANGLE_OVERLAP_LEFT_EDGE |
PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE |
PLY_RECTANGLE_OVERLAP_RIGHT_EDGE,
PLY_RECTANGLE_OVERLAP_NO_EDGES = 1 << 4,
PLY_RECTANGLE_OVERLAP_EXACT_TOP_EDGE,
PLY_RECTANGLE_OVERLAP_EXACT_LEFT_EDGE,
PLY_RECTANGLE_OVERLAP_EXACT_RIGHT_EDGE,
PLY_RECTANGLE_OVERLAP_EXACT_BOTTOM_EDGE,
} ply_rectangle_overlap_t;
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS

View file

@ -34,61 +34,59 @@
struct _ply_region
{
ply_list_t *rectangle_list;
ply_list_t *rectangle_list;
};
ply_region_t *
ply_region_new (void)
{
ply_region_t *region;
ply_region_t *region;
region = calloc (1, sizeof (ply_region_t));
region = calloc (1, sizeof(ply_region_t));
region->rectangle_list = ply_list_new ();
region->rectangle_list = ply_list_new ();
return region;
return region;
}
void
ply_region_clear (ply_region_t *region)
{
ply_list_node_t *node;
ply_list_node_t *node;
node = ply_list_get_first_node (region->rectangle_list);
while (node != NULL)
{
ply_list_node_t *next_node;
ply_rectangle_t *rectangle;
node = ply_list_get_first_node (region->rectangle_list);
while (node != NULL) {
ply_list_node_t *next_node;
ply_rectangle_t *rectangle;
rectangle = (ply_rectangle_t *) ply_list_node_get_data (node);
rectangle = (ply_rectangle_t *) ply_list_node_get_data (node);
next_node = ply_list_get_next_node (region->rectangle_list, node);
next_node = ply_list_get_next_node (region->rectangle_list, node);
free (rectangle);
ply_list_remove_node (region->rectangle_list, node);
free (rectangle);
ply_list_remove_node (region->rectangle_list, node);
node = next_node;
}
node = next_node;
}
}
void
ply_region_free (ply_region_t *region)
{
ply_region_clear (region);
ply_list_free (region->rectangle_list);
free (region);
ply_region_clear (region);
ply_list_free (region->rectangle_list);
free (region);
}
static ply_rectangle_t *
copy_rectangle (ply_rectangle_t *rectangle)
{
ply_rectangle_t *new_rectangle;
ply_rectangle_t *new_rectangle;
new_rectangle = malloc (sizeof (*rectangle));
*new_rectangle = *rectangle;
new_rectangle = malloc (sizeof(*rectangle));
*new_rectangle = *rectangle;
return new_rectangle;
return new_rectangle;
}
static void
@ -96,375 +94,370 @@ merge_rectangle_with_sub_list (ply_region_t *region,
ply_rectangle_t *new_area,
ply_list_node_t *node)
{
if (ply_rectangle_is_empty (new_area))
{
free (new_area);
return;
}
while (node != NULL)
{
ply_list_node_t *next_node;
ply_rectangle_t *old_area;
ply_rectangle_overlap_t overlap;
old_area = (ply_rectangle_t *) ply_list_node_get_data (node);
next_node = ply_list_get_next_node (region->rectangle_list, node);
if (ply_rectangle_is_empty (new_area))
overlap = PLY_RECTANGLE_OVERLAP_NO_EDGES;
else if (ply_rectangle_is_empty (old_area))
overlap = PLY_RECTANGLE_OVERLAP_ALL_EDGES;
else
overlap = ply_rectangle_find_overlap (old_area, new_area);
switch (overlap)
{
/* NNNN The new rectangle and node rectangle don't touch,
* NNNN OOOO so let's move on to the next one.
* OOOO
*/
case PLY_RECTANGLE_OVERLAP_NONE:
break;
/* NNNNN We need to split the new rectangle into
* NNOOOOO two rectangles: The top row of Ns and
* NNOOOOO the left side of Ns.
* OOOOO
*/
case PLY_RECTANGLE_OVERLAP_TOP_AND_LEFT_EDGES:
{
ply_rectangle_t *rectangle;
rectangle = copy_rectangle (new_area);
rectangle->y = old_area->y;
rectangle->width = old_area->x - new_area->x;
rectangle->height = (new_area->y + new_area->height) - old_area->y;
merge_rectangle_with_sub_list (region, rectangle, next_node);
new_area->height = old_area->y - new_area->y;
}
break;
/* NNNNN We need to split the new rectangle into
* OOOOONN two rectangles: The top row of Ns and
* OOOOONN the right side of Ns.
* OOOOO
*/
case PLY_RECTANGLE_OVERLAP_TOP_AND_RIGHT_EDGES:
{
ply_rectangle_t *rectangle;
rectangle = copy_rectangle (new_area);
rectangle->x = old_area->x + old_area->width;
rectangle->y = old_area->y;
rectangle->width = (new_area->x + new_area->width) - (old_area->x + old_area->width);
rectangle->height = (new_area->y + new_area->height) - old_area->y;
merge_rectangle_with_sub_list (region, rectangle, next_node);
new_area->height = old_area->y - new_area->y;
}
break;
/* NNNNNNN We need to trim out the part of
* NOOOOON old rectangle that overlaps the new
* NOOOOON rectangle by shrinking and moving it
* OOOOO and then we need to add the new rectangle.
*/
case PLY_RECTANGLE_OVERLAP_TOP_AND_SIDE_EDGES:
{
old_area->height = (old_area->y + old_area->height)
- (new_area->y + new_area->height);
old_area->y = new_area->y + new_area->height;
}
break;
/* NNN We only care about the top row of Ns,
* ONNNO everything below that is already handled by
* ONNNO the old rectangle.
* OOOOO
*/
case PLY_RECTANGLE_OVERLAP_TOP_EDGE:
new_area->height = old_area->y - new_area->y;
break;
/* OOOOO We need to split the new rectangle into
* NNOOOOO two rectangles: The left side of Ns and
* NNOOOOO the bottom row of Ns.
* NNOOOOO
* NNNNN
*/
case PLY_RECTANGLE_OVERLAP_BOTTOM_AND_LEFT_EDGES:
{
ply_rectangle_t *rectangle;
rectangle = copy_rectangle (new_area);
rectangle->width = old_area->x - new_area->x;
rectangle->height = (old_area->y + old_area->height) - new_area->y;
merge_rectangle_with_sub_list (region, rectangle, next_node);
new_area->height = (new_area->y + new_area->height) - (old_area->y + old_area->height);
new_area->y = old_area->y + old_area->height;
}
break;
/* OOOOO We need to split the new rectangle into
* OOOOONN two rectangles: The right side of Ns and
* OOOOONN the bottom row of Ns.
* OOOOONN
* NNNNN
*/
case PLY_RECTANGLE_OVERLAP_BOTTOM_AND_RIGHT_EDGES:
{
ply_rectangle_t *rectangle;
rectangle = copy_rectangle (new_area);
rectangle->x = old_area->x + old_area->width;
rectangle->width = (new_area->x + new_area->width) - (old_area->x + old_area->width);
rectangle->height = (old_area->y + old_area->height) - new_area->y;
merge_rectangle_with_sub_list (region, rectangle, next_node);
new_area->height = (new_area->y + new_area->height) - (old_area->y + old_area->height);
new_area->y = old_area->y + old_area->height;
}
break;
/* OOOOO We need to trim out the part of
* NOOOOON old rectangle that overlaps the new
* NOOOOON rectangle by shrinking it
* NNNNNNN and then we need to add the new rectangle.
*/
case PLY_RECTANGLE_OVERLAP_BOTTOM_AND_SIDE_EDGES:
{
old_area->height = new_area->y - old_area->y;
}
break;
/* OOOOO We only care about the bottom row of Ns,
* ONNNO everything above that is already handled by
* ONNNO the old rectangle.
* NNN
*/
case PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE:
{
new_area->height = (new_area->y + new_area->height) - (old_area->y + old_area->height);
new_area->y = old_area->y + old_area->height;
}
break;
/* NNNN We need to trim out the part of
* NNNNO old rectangle that overlaps the new
* NNNNO rectangle by shrinking it and moving it
* NNNN and then we need to add the new rectangle.
*/
case PLY_RECTANGLE_OVERLAP_TOP_LEFT_AND_BOTTOM_EDGES:
{
old_area->width = (old_area->x + old_area->width)
- (new_area->x + new_area->width);
old_area->x = new_area->x + new_area->width;
}
break;
/* NNNN We need to trim out the part of
* ONNNN old rectangle that overlaps the new
* ONNNN rectangle by shrinking it and then we
* NNNN need to add the new rectangle.
*/
case PLY_RECTANGLE_OVERLAP_TOP_RIGHT_AND_BOTTOM_EDGES:
old_area->width = new_area->x - old_area->x;
break;
/* NNNNNNN The old rectangle is completely inside the new rectangle
* NOOOOON so replace the old rectangle with the new rectangle.
* NOOOOON
* NNNNNNN
*/
case PLY_RECTANGLE_OVERLAP_ALL_EDGES:
merge_rectangle_with_sub_list (region, new_area, next_node);
free (old_area);
ply_list_remove_node (region->rectangle_list, node);
return;
/* NNN We need to split the new rectangle into
* ONNNO two rectangles: the top and bottom row of Ns
* ONNNO
* NNN
*/
case PLY_RECTANGLE_OVERLAP_TOP_AND_BOTTOM_EDGES:
{
ply_rectangle_t *rectangle;
rectangle = copy_rectangle (new_area);
rectangle->y = old_area->y + old_area->height;
rectangle->width = new_area->width;
rectangle->height = (new_area->y + new_area->height) - (old_area->y + old_area->height);
merge_rectangle_with_sub_list (region, rectangle, next_node);
new_area->height = old_area->y - new_area->y;
}
break;
/* OOOOO We only care about the side row of Ns,
* NNNNOO everything rigth of that is already handled by
* NNNNOO the old rectangle.
* OOOOO
*/
case PLY_RECTANGLE_OVERLAP_LEFT_EDGE:
new_area->width = old_area->x - new_area->x;
break;
/* OOOOO We only care about the side row of Ns,
* NNNNNN everything left of that is already handled by
* NNNNNN the old rectangle.
* OOOOO
*/
case PLY_RECTANGLE_OVERLAP_RIGHT_EDGE:
{
long temp = new_area->x;
new_area->x = old_area->x + old_area->width;
new_area->width = (temp + new_area->width) - (old_area->x + old_area->width);
}
break;
/* OOOOO We need to split the new rectangle into
* NNNNNNN two rectangles: the side columns of Ns
* NNNNNNN
* OOOOO
*/
case PLY_RECTANGLE_OVERLAP_SIDE_EDGES:
{
ply_rectangle_t *rectangle;
rectangle = copy_rectangle (new_area);
rectangle->x = old_area->x + old_area->width;
rectangle->width = (new_area->x + new_area->width) - (old_area->x + old_area->width);
merge_rectangle_with_sub_list (region, rectangle, next_node);
new_area->width = old_area->x - new_area->x;
}
break;
/* OOOOOOO The new rectangle is completely inside an old rectangle
* ONNNNNO so return early without adding the new rectangle.
* ONNNNNO
* OOOOOOO
*/
case PLY_RECTANGLE_OVERLAP_NO_EDGES:
free (new_area);
return;
/* NNNNN We expand the old rectangle up and throw away the new.
* NNNNN We must merge it because the new region may have overlapped
* NNNNN something further down the list.
* OOOOO
*/
case PLY_RECTANGLE_OVERLAP_EXACT_TOP_EDGE:
{
old_area->height = (old_area->y + old_area->height) - new_area->y;
old_area->y = new_area->y;
free (new_area);
merge_rectangle_with_sub_list (region, old_area, next_node);
ply_list_remove_node (region->rectangle_list, node);
}
return;
/* OOOOO We expand the old rectangle down and throw away the new.
* NNNNN We must merge it because the new region may have overlapped
* NNNNN something further down the list.
* NNNNN
*/
case PLY_RECTANGLE_OVERLAP_EXACT_BOTTOM_EDGE:
{
old_area->height = (new_area->y + new_area->height) - old_area->y;
free (new_area);
merge_rectangle_with_sub_list (region, old_area, next_node);
ply_list_remove_node (region->rectangle_list, node);
}
return;
/* NNNNNO We expand the old rectangle left and throw away the new.
* NNNNNO We must merge it because the new region may have overlapped
* NNNNNO something further down the list.
*/
case PLY_RECTANGLE_OVERLAP_EXACT_LEFT_EDGE:
{
old_area->width = (old_area->x + old_area->width) - new_area->x;
old_area->x = new_area->x;
free (new_area);
merge_rectangle_with_sub_list (region, old_area, next_node);
ply_list_remove_node (region->rectangle_list, node);
}
return;
/* ONNNNN We expand the old rectangle right and throw away the new.
* ONNNNN We must merge it because the new region may have overlapped
* ONNNNN something further down the list.
*/
case PLY_RECTANGLE_OVERLAP_EXACT_RIGHT_EDGE:
{
old_area->width = (new_area->x + new_area->width) - old_area->x;
free (new_area);
merge_rectangle_with_sub_list (region, old_area, next_node);
ply_list_remove_node (region->rectangle_list, node);
}
return;
if (ply_rectangle_is_empty (new_area)) {
free (new_area);
return;
}
node = ply_list_get_next_node (region->rectangle_list, node);
}
while (node != NULL) {
ply_list_node_t *next_node;
ply_rectangle_t *old_area;
ply_rectangle_overlap_t overlap;
ply_list_append_data (region->rectangle_list, new_area);
old_area = (ply_rectangle_t *) ply_list_node_get_data (node);
next_node = ply_list_get_next_node (region->rectangle_list, node);
if (ply_rectangle_is_empty (new_area))
overlap = PLY_RECTANGLE_OVERLAP_NO_EDGES;
else if (ply_rectangle_is_empty (old_area))
overlap = PLY_RECTANGLE_OVERLAP_ALL_EDGES;
else
overlap = ply_rectangle_find_overlap (old_area, new_area);
switch (overlap) {
/* NNNN The new rectangle and node rectangle don't touch,
* NNNN OOOO so let's move on to the next one.
* OOOO
*/
case PLY_RECTANGLE_OVERLAP_NONE:
break;
/* NNNNN We need to split the new rectangle into
* NNOOOOO two rectangles: The top row of Ns and
* NNOOOOO the left side of Ns.
* OOOOO
*/
case PLY_RECTANGLE_OVERLAP_TOP_AND_LEFT_EDGES:
{
ply_rectangle_t *rectangle;
rectangle = copy_rectangle (new_area);
rectangle->y = old_area->y;
rectangle->width = old_area->x - new_area->x;
rectangle->height = (new_area->y + new_area->height) - old_area->y;
merge_rectangle_with_sub_list (region, rectangle, next_node);
new_area->height = old_area->y - new_area->y;
}
break;
/* NNNNN We need to split the new rectangle into
* OOOOONN two rectangles: The top row of Ns and
* OOOOONN the right side of Ns.
* OOOOO
*/
case PLY_RECTANGLE_OVERLAP_TOP_AND_RIGHT_EDGES:
{
ply_rectangle_t *rectangle;
rectangle = copy_rectangle (new_area);
rectangle->x = old_area->x + old_area->width;
rectangle->y = old_area->y;
rectangle->width = (new_area->x + new_area->width) - (old_area->x + old_area->width);
rectangle->height = (new_area->y + new_area->height) - old_area->y;
merge_rectangle_with_sub_list (region, rectangle, next_node);
new_area->height = old_area->y - new_area->y;
}
break;
/* NNNNNNN We need to trim out the part of
* NOOOOON old rectangle that overlaps the new
* NOOOOON rectangle by shrinking and moving it
* OOOOO and then we need to add the new rectangle.
*/
case PLY_RECTANGLE_OVERLAP_TOP_AND_SIDE_EDGES:
{
old_area->height = (old_area->y + old_area->height)
- (new_area->y + new_area->height);
old_area->y = new_area->y + new_area->height;
}
break;
/* NNN We only care about the top row of Ns,
* ONNNO everything below that is already handled by
* ONNNO the old rectangle.
* OOOOO
*/
case PLY_RECTANGLE_OVERLAP_TOP_EDGE:
new_area->height = old_area->y - new_area->y;
break;
/* OOOOO We need to split the new rectangle into
* NNOOOOO two rectangles: The left side of Ns and
* NNOOOOO the bottom row of Ns.
* NNOOOOO
* NNNNN
*/
case PLY_RECTANGLE_OVERLAP_BOTTOM_AND_LEFT_EDGES:
{
ply_rectangle_t *rectangle;
rectangle = copy_rectangle (new_area);
rectangle->width = old_area->x - new_area->x;
rectangle->height = (old_area->y + old_area->height) - new_area->y;
merge_rectangle_with_sub_list (region, rectangle, next_node);
new_area->height = (new_area->y + new_area->height) - (old_area->y + old_area->height);
new_area->y = old_area->y + old_area->height;
}
break;
/* OOOOO We need to split the new rectangle into
* OOOOONN two rectangles: The right side of Ns and
* OOOOONN the bottom row of Ns.
* OOOOONN
* NNNNN
*/
case PLY_RECTANGLE_OVERLAP_BOTTOM_AND_RIGHT_EDGES:
{
ply_rectangle_t *rectangle;
rectangle = copy_rectangle (new_area);
rectangle->x = old_area->x + old_area->width;
rectangle->width = (new_area->x + new_area->width) - (old_area->x + old_area->width);
rectangle->height = (old_area->y + old_area->height) - new_area->y;
merge_rectangle_with_sub_list (region, rectangle, next_node);
new_area->height = (new_area->y + new_area->height) - (old_area->y + old_area->height);
new_area->y = old_area->y + old_area->height;
}
break;
/* OOOOO We need to trim out the part of
* NOOOOON old rectangle that overlaps the new
* NOOOOON rectangle by shrinking it
* NNNNNNN and then we need to add the new rectangle.
*/
case PLY_RECTANGLE_OVERLAP_BOTTOM_AND_SIDE_EDGES:
{
old_area->height = new_area->y - old_area->y;
}
break;
/* OOOOO We only care about the bottom row of Ns,
* ONNNO everything above that is already handled by
* ONNNO the old rectangle.
* NNN
*/
case PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE:
{
new_area->height = (new_area->y + new_area->height) - (old_area->y + old_area->height);
new_area->y = old_area->y + old_area->height;
}
break;
/* NNNN We need to trim out the part of
* NNNNO old rectangle that overlaps the new
* NNNNO rectangle by shrinking it and moving it
* NNNN and then we need to add the new rectangle.
*/
case PLY_RECTANGLE_OVERLAP_TOP_LEFT_AND_BOTTOM_EDGES:
{
old_area->width = (old_area->x + old_area->width)
- (new_area->x + new_area->width);
old_area->x = new_area->x + new_area->width;
}
break;
/* NNNN We need to trim out the part of
* ONNNN old rectangle that overlaps the new
* ONNNN rectangle by shrinking it and then we
* NNNN need to add the new rectangle.
*/
case PLY_RECTANGLE_OVERLAP_TOP_RIGHT_AND_BOTTOM_EDGES:
old_area->width = new_area->x - old_area->x;
break;
/* NNNNNNN The old rectangle is completely inside the new rectangle
* NOOOOON so replace the old rectangle with the new rectangle.
* NOOOOON
* NNNNNNN
*/
case PLY_RECTANGLE_OVERLAP_ALL_EDGES:
merge_rectangle_with_sub_list (region, new_area, next_node);
free (old_area);
ply_list_remove_node (region->rectangle_list, node);
return;
/* NNN We need to split the new rectangle into
* ONNNO two rectangles: the top and bottom row of Ns
* ONNNO
* NNN
*/
case PLY_RECTANGLE_OVERLAP_TOP_AND_BOTTOM_EDGES:
{
ply_rectangle_t *rectangle;
rectangle = copy_rectangle (new_area);
rectangle->y = old_area->y + old_area->height;
rectangle->width = new_area->width;
rectangle->height = (new_area->y + new_area->height) - (old_area->y + old_area->height);
merge_rectangle_with_sub_list (region, rectangle, next_node);
new_area->height = old_area->y - new_area->y;
}
break;
/* OOOOO We only care about the side row of Ns,
* NNNNOO everything rigth of that is already handled by
* NNNNOO the old rectangle.
* OOOOO
*/
case PLY_RECTANGLE_OVERLAP_LEFT_EDGE:
new_area->width = old_area->x - new_area->x;
break;
/* OOOOO We only care about the side row of Ns,
* NNNNNN everything left of that is already handled by
* NNNNNN the old rectangle.
* OOOOO
*/
case PLY_RECTANGLE_OVERLAP_RIGHT_EDGE:
{
long temp = new_area->x;
new_area->x = old_area->x + old_area->width;
new_area->width = (temp + new_area->width) - (old_area->x + old_area->width);
}
break;
/* OOOOO We need to split the new rectangle into
* NNNNNNN two rectangles: the side columns of Ns
* NNNNNNN
* OOOOO
*/
case PLY_RECTANGLE_OVERLAP_SIDE_EDGES:
{
ply_rectangle_t *rectangle;
rectangle = copy_rectangle (new_area);
rectangle->x = old_area->x + old_area->width;
rectangle->width = (new_area->x + new_area->width) - (old_area->x + old_area->width);
merge_rectangle_with_sub_list (region, rectangle, next_node);
new_area->width = old_area->x - new_area->x;
}
break;
/* OOOOOOO The new rectangle is completely inside an old rectangle
* ONNNNNO so return early without adding the new rectangle.
* ONNNNNO
* OOOOOOO
*/
case PLY_RECTANGLE_OVERLAP_NO_EDGES:
free (new_area);
return;
/* NNNNN We expand the old rectangle up and throw away the new.
* NNNNN We must merge it because the new region may have overlapped
* NNNNN something further down the list.
* OOOOO
*/
case PLY_RECTANGLE_OVERLAP_EXACT_TOP_EDGE:
{
old_area->height = (old_area->y + old_area->height) - new_area->y;
old_area->y = new_area->y;
free (new_area);
merge_rectangle_with_sub_list (region, old_area, next_node);
ply_list_remove_node (region->rectangle_list, node);
}
return;
/* OOOOO We expand the old rectangle down and throw away the new.
* NNNNN We must merge it because the new region may have overlapped
* NNNNN something further down the list.
* NNNNN
*/
case PLY_RECTANGLE_OVERLAP_EXACT_BOTTOM_EDGE:
{
old_area->height = (new_area->y + new_area->height) - old_area->y;
free (new_area);
merge_rectangle_with_sub_list (region, old_area, next_node);
ply_list_remove_node (region->rectangle_list, node);
}
return;
/* NNNNNO We expand the old rectangle left and throw away the new.
* NNNNNO We must merge it because the new region may have overlapped
* NNNNNO something further down the list.
*/
case PLY_RECTANGLE_OVERLAP_EXACT_LEFT_EDGE:
{
old_area->width = (old_area->x + old_area->width) - new_area->x;
old_area->x = new_area->x;
free (new_area);
merge_rectangle_with_sub_list (region, old_area, next_node);
ply_list_remove_node (region->rectangle_list, node);
}
return;
/* ONNNNN We expand the old rectangle right and throw away the new.
* ONNNNN We must merge it because the new region may have overlapped
* ONNNNN something further down the list.
*/
case PLY_RECTANGLE_OVERLAP_EXACT_RIGHT_EDGE:
{
old_area->width = (new_area->x + new_area->width) - old_area->x;
free (new_area);
merge_rectangle_with_sub_list (region, old_area, next_node);
ply_list_remove_node (region->rectangle_list, node);
}
return;
}
node = ply_list_get_next_node (region->rectangle_list, node);
}
ply_list_append_data (region->rectangle_list, new_area);
}
void
ply_region_add_rectangle (ply_region_t *region,
ply_rectangle_t *rectangle)
{
ply_list_node_t *first_node;
ply_rectangle_t *rectangle_copy;
ply_list_node_t *first_node;
ply_rectangle_t *rectangle_copy;
assert (region != NULL);
assert (rectangle != NULL);
assert (region != NULL);
assert (rectangle != NULL);
first_node = ply_list_get_first_node (region->rectangle_list);
first_node = ply_list_get_first_node (region->rectangle_list);
rectangle_copy = copy_rectangle (rectangle);
merge_rectangle_with_sub_list (region,
rectangle_copy,
first_node);
rectangle_copy = copy_rectangle (rectangle);
merge_rectangle_with_sub_list (region,
rectangle_copy,
first_node);
}
ply_list_t *
ply_region_get_rectangle_list (ply_region_t *region)
{
return region->rectangle_list;
return region->rectangle_list;
}
static int
rectangle_compare_y (void *element_a, void *element_b)
{
ply_rectangle_t *rectangle_a = element_a;
ply_rectangle_t *rectangle_b = element_b;
return rectangle_a->y - rectangle_b->y;
ply_rectangle_t *rectangle_a = element_a;
ply_rectangle_t *rectangle_b = element_b;
return rectangle_a->y - rectangle_b->y;
}
ply_list_t *
ply_region_get_sorted_rectangle_list (ply_region_t *region)
{
ply_list_sort (region->rectangle_list, &rectangle_compare_y);
return region->rectangle_list;
ply_list_sort (region->rectangle_list, &rectangle_compare_y);
return region->rectangle_list;
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -43,20 +43,20 @@
struct _ply_terminal_session
{
int pseudoterminal_master_fd;
ply_logger_t *logger;
ply_event_loop_t *loop;
char **argv;
ply_fd_watch_t *fd_watch;
ply_terminal_session_flags_t attach_flags;
int pseudoterminal_master_fd;
ply_logger_t *logger;
ply_event_loop_t *loop;
char **argv;
ply_fd_watch_t *fd_watch;
ply_terminal_session_flags_t attach_flags;
ply_terminal_session_output_handler_t output_handler;
ply_terminal_session_hangup_handler_t hangup_handler;
void *user_data;
ply_terminal_session_output_handler_t output_handler;
ply_terminal_session_hangup_handler_t hangup_handler;
void *user_data;
uint32_t is_running : 1;
uint32_t console_is_redirected : 1;
uint32_t created_terminal_device : 1;
uint32_t is_running : 1;
uint32_t console_is_redirected : 1;
uint32_t created_terminal_device : 1;
};
static bool ply_terminal_session_open_console (ply_terminal_session_t *session);
@ -68,375 +68,361 @@ static void ply_terminal_session_stop_logging (ply_terminal_session_t *session);
static bool
ply_terminal_session_open_console (ply_terminal_session_t *session)
{
int fd;
const char *terminal_name;
int fd;
const char *terminal_name;
terminal_name = ptsname (session->pseudoterminal_master_fd);
terminal_name = ptsname (session->pseudoterminal_master_fd);
fd = open (terminal_name, O_RDONLY);
fd = open (terminal_name, O_RDONLY);
if (fd < 0)
return false;
if (fd < 0)
return false;
assert (fd == STDIN_FILENO);
assert (ttyname (fd) != NULL);
assert (strcmp (ttyname (fd), terminal_name) == 0);
assert (fd == STDIN_FILENO);
assert (ttyname (fd) != NULL);
assert (strcmp (ttyname (fd), terminal_name) == 0);
fd = open (terminal_name, O_WRONLY);
fd = open (terminal_name, O_WRONLY);
if (fd < 0)
return false;
if (fd < 0)
return false;
assert (fd == STDOUT_FILENO);
assert (ttyname (fd) != NULL);
assert (strcmp (ttyname (fd), terminal_name) == 0);
assert (fd == STDOUT_FILENO);
assert (ttyname (fd) != NULL);
assert (strcmp (ttyname (fd), terminal_name) == 0);
fd = open (terminal_name, O_WRONLY);
fd = open (terminal_name, O_WRONLY);
if (fd < 0)
return false;
if (fd < 0)
return false;
assert (fd == STDERR_FILENO);
assert (ttyname (fd) != NULL);
assert (strcmp (ttyname (fd), terminal_name) == 0);
assert (fd == STDERR_FILENO);
assert (ttyname (fd) != NULL);
assert (strcmp (ttyname (fd), terminal_name) == 0);
return true;
return true;
}
static bool
ply_terminal_session_execute (ply_terminal_session_t *session,
bool look_in_path)
{
ply_close_all_fds ();
ply_close_all_fds ();
if (!ply_terminal_session_open_console (session))
return false;
if (!ply_terminal_session_open_console (session))
return false;
if (look_in_path)
execvp (session->argv[0], session->argv);
else
execv (session->argv[0], session->argv);
if (look_in_path)
execvp (session->argv[0], session->argv);
else
execv (session->argv[0], session->argv);
return false;
return false;
}
ply_terminal_session_t *
ply_terminal_session_new (const char * const *argv)
ply_terminal_session_new (const char *const *argv)
{
ply_terminal_session_t *session;
ply_terminal_session_t *session;
assert (argv == NULL || argv[0] != NULL);
assert (argv == NULL || argv[0] != NULL);
session = calloc (1, sizeof (ply_terminal_session_t));
session->pseudoterminal_master_fd = -1;
session->argv = argv == NULL ? NULL : ply_copy_string_array (argv);
session->logger = ply_logger_new ();
session->is_running = false;
session->console_is_redirected = false;
session = calloc (1, sizeof(ply_terminal_session_t));
session->pseudoterminal_master_fd = -1;
session->argv = argv == NULL ? NULL : ply_copy_string_array (argv);
session->logger = ply_logger_new ();
session->is_running = false;
session->console_is_redirected = false;
return session;
return session;
}
void
ply_terminal_session_free (ply_terminal_session_t *session)
{
if (session == NULL)
return;
if (session == NULL)
return;
ply_terminal_session_stop_logging (session);
ply_logger_free (session->logger);
ply_terminal_session_stop_logging (session);
ply_logger_free (session->logger);
ply_free_string_array (session->argv);
ply_free_string_array (session->argv);
if (session->pseudoterminal_master_fd >= 0)
close (session->pseudoterminal_master_fd);
free (session);
if (session->pseudoterminal_master_fd >= 0)
close (session->pseudoterminal_master_fd);
free (session);
}
static void
ply_terminal_session_detach_from_event_loop (ply_terminal_session_t *session)
{
assert (session != NULL);
session->loop = NULL;
assert (session != NULL);
session->loop = NULL;
}
void
void
ply_terminal_session_attach_to_event_loop (ply_terminal_session_t *session,
ply_event_loop_t *loop)
{
assert (session != NULL);
assert (loop != NULL);
assert (session->loop == NULL);
assert (session != NULL);
assert (loop != NULL);
assert (session->loop == NULL);
session->loop = loop;
session->loop = loop;
ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t)
ply_terminal_session_detach_from_event_loop,
session);
ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t)
ply_terminal_session_detach_from_event_loop,
session);
}
static bool
ply_terminal_session_redirect_console (ply_terminal_session_t *session)
{
const char *terminal_name;
int fd;
const char *terminal_name;
int fd;
assert (session != NULL);
assert (session != NULL);
terminal_name = ptsname (session->pseudoterminal_master_fd);
terminal_name = ptsname (session->pseudoterminal_master_fd);
assert (terminal_name != NULL);
assert (terminal_name != NULL);
fd = open (terminal_name, O_RDWR | O_NOCTTY);
fd = open (terminal_name, O_RDWR | O_NOCTTY);
if (fd < 0)
return false;
if (fd < 0)
return false;
if (ioctl (fd, TIOCCONS) < 0)
{
ply_save_errno ();
close (fd);
ply_restore_errno ();
return false;
}
if (ioctl (fd, TIOCCONS) < 0) {
ply_save_errno ();
close (fd);
ply_restore_errno ();
return false;
}
close (fd);
session->console_is_redirected = true;
return true;
close (fd);
session->console_is_redirected = true;
return true;
}
static void
ply_terminal_session_unredirect_console (ply_terminal_session_t *session)
{
int fd;
int fd;
assert (session != NULL);
assert (session->console_is_redirected);
assert (session != NULL);
assert (session->console_is_redirected);
fd = open ("/dev/console", O_RDWR | O_NOCTTY);
if (fd >= 0) {
ioctl (fd, TIOCCONS);
close (fd);
} else {
ply_trace ("couldn't open /dev/console to stop redirecting it: %m");
}
fd = open ("/dev/console", O_RDWR | O_NOCTTY);
if (fd >= 0) {
ioctl (fd, TIOCCONS);
close (fd);
} else {
ply_trace ("couldn't open /dev/console to stop redirecting it: %m");
}
session->console_is_redirected = false;
session->console_is_redirected = false;
}
static void
close_pseudoterminal (ply_terminal_session_t *session)
{
close (session->pseudoterminal_master_fd);
session->pseudoterminal_master_fd = -1;
close (session->pseudoterminal_master_fd);
session->pseudoterminal_master_fd = -1;
}
static bool
open_pseudoterminal (ply_terminal_session_t *session)
{
ply_trace ("opening device '/dev/ptmx'");
session->pseudoterminal_master_fd = posix_openpt (O_RDWR | O_NOCTTY);
ply_trace ("opening device '/dev/ptmx'");
session->pseudoterminal_master_fd = posix_openpt (O_RDWR | O_NOCTTY);
if (session->pseudoterminal_master_fd < 0)
return false;
if (session->pseudoterminal_master_fd < 0)
return false;
ply_trace (" opened device '/dev/ptmx'");
ply_trace (" opened device '/dev/ptmx'");
ply_trace ("creating pseudoterminal");
if (grantpt (session->pseudoterminal_master_fd) < 0)
{
ply_save_errno ();
ply_trace ("could not create psuedoterminal: %m");
close_pseudoterminal (session);
ply_restore_errno ();
return false;
}
ply_trace ("done creating pseudoterminal");
ply_trace ("creating pseudoterminal");
if (grantpt (session->pseudoterminal_master_fd) < 0) {
ply_save_errno ();
ply_trace ("could not create psuedoterminal: %m");
close_pseudoterminal (session);
ply_restore_errno ();
return false;
}
ply_trace ("done creating pseudoterminal");
ply_trace ("unlocking pseudoterminal");
if (unlockpt (session->pseudoterminal_master_fd) < 0)
{
ply_save_errno ();
close_pseudoterminal (session);
ply_restore_errno ();
return false;
}
ply_trace ("unlocked pseudoterminal");
ply_trace ("unlocking pseudoterminal");
if (unlockpt (session->pseudoterminal_master_fd) < 0) {
ply_save_errno ();
close_pseudoterminal (session);
ply_restore_errno ();
return false;
}
ply_trace ("unlocked pseudoterminal");
return true;
return true;
}
bool
ply_terminal_session_run (ply_terminal_session_t *session,
ply_terminal_session_flags_t flags,
ply_terminal_session_begin_handler_t begin_handler,
bool
ply_terminal_session_run (ply_terminal_session_t *session,
ply_terminal_session_flags_t flags,
ply_terminal_session_begin_handler_t begin_handler,
ply_terminal_session_output_handler_t output_handler,
ply_terminal_session_hangup_handler_t hangup_handler,
void *user_data)
void *user_data)
{
pid_t pid;
bool run_in_parent, look_in_path, should_redirect_console;
pid_t pid;
bool run_in_parent, look_in_path, should_redirect_console;
assert (session != NULL);
assert (session->loop != NULL);
assert (!session->is_running);
assert (session->hangup_handler == NULL);
assert (session != NULL);
assert (session->loop != NULL);
assert (!session->is_running);
assert (session->hangup_handler == NULL);
run_in_parent = (flags & PLY_TERMINAL_SESSION_FLAGS_RUN_IN_PARENT) != 0;
look_in_path = (flags & PLY_TERMINAL_SESSION_FLAGS_LOOK_IN_PATH) != 0;
should_redirect_console =
(flags & PLY_TERMINAL_SESSION_FLAGS_REDIRECT_CONSOLE) != 0;
run_in_parent = (flags & PLY_TERMINAL_SESSION_FLAGS_RUN_IN_PARENT) != 0;
look_in_path = (flags & PLY_TERMINAL_SESSION_FLAGS_LOOK_IN_PATH) != 0;
should_redirect_console =
(flags & PLY_TERMINAL_SESSION_FLAGS_REDIRECT_CONSOLE) != 0;
ply_trace ("creating terminal device");
if (!open_pseudoterminal (session))
return false;
ply_trace ("done creating terminal device");
ply_trace ("creating terminal device");
if (!open_pseudoterminal (session))
return false;
ply_trace ("done creating terminal device");
if (should_redirect_console)
ply_trace ("redirecting system console to terminal device");
if (should_redirect_console &&
!ply_terminal_session_redirect_console (session))
{
ply_save_errno ();
close_pseudoterminal (session);
ply_restore_errno ();
return false;
}
if (should_redirect_console)
ply_trace ("done redirecting system console to terminal device");
if (should_redirect_console)
ply_trace ("redirecting system console to terminal device");
if (should_redirect_console &&
!ply_terminal_session_redirect_console (session)) {
ply_save_errno ();
close_pseudoterminal (session);
ply_restore_errno ();
return false;
}
if (should_redirect_console)
ply_trace ("done redirecting system console to terminal device");
ply_trace ("creating subprocess");
pid = fork ();
ply_trace ("creating subprocess");
pid = fork ();
if (pid < 0)
{
ply_save_errno ();
ply_terminal_session_unredirect_console (session);
close_pseudoterminal (session);
ply_restore_errno ();
return false;
}
if (pid < 0) {
ply_save_errno ();
ply_terminal_session_unredirect_console (session);
close_pseudoterminal (session);
ply_restore_errno ();
return false;
}
if (((pid == 0) && run_in_parent) ||
((pid != 0) && !run_in_parent))
{
session->is_running = true;
session->output_handler = output_handler;
session->hangup_handler = hangup_handler;
session->user_data = user_data;
ply_terminal_session_start_logging (session);
if (((pid == 0) && run_in_parent) ||
((pid != 0) && !run_in_parent)) {
session->is_running = true;
session->output_handler = output_handler;
session->hangup_handler = hangup_handler;
session->user_data = user_data;
ply_terminal_session_start_logging (session);
return true;
}
return true;
}
if (begin_handler != NULL)
{
ply_trace ("running 'begin handler'");
begin_handler (user_data, session);
ply_trace ("ran 'begin handler'");
}
if (begin_handler != NULL) {
ply_trace ("running 'begin handler'");
begin_handler (user_data, session);
ply_trace ("ran 'begin handler'");
}
ply_trace ("beginning session");
ply_terminal_session_execute (session, look_in_path);
ply_trace ("beginning session");
ply_terminal_session_execute (session, look_in_path);
_exit (errno);
return false;
_exit (errno);
return false;
}
bool
ply_terminal_session_attach (ply_terminal_session_t *session,
ply_terminal_session_flags_t flags,
ply_terminal_session_output_handler_t output_handler,
ply_terminal_session_hangup_handler_t hangup_handler,
ply_terminal_session_hangup_handler_t hangup_handler,
int ptmx,
void *user_data)
{
bool should_redirect_console;
bool should_redirect_console;
assert (session != NULL);
assert (session->loop != NULL);
assert (!session->is_running);
assert (session->hangup_handler == NULL);
assert (session != NULL);
assert (session->loop != NULL);
assert (!session->is_running);
assert (session->hangup_handler == NULL);
should_redirect_console =
(flags & PLY_TERMINAL_SESSION_FLAGS_REDIRECT_CONSOLE) != 0;
should_redirect_console =
(flags & PLY_TERMINAL_SESSION_FLAGS_REDIRECT_CONSOLE) != 0;
if (ptmx >= 0)
{
ply_trace ("ptmx passed in, using it");
session->pseudoterminal_master_fd = ptmx;
}
else
{
ply_trace ("ptmx not passed in, creating one");
if (!open_pseudoterminal (session))
{
ply_trace ("could not create pseudo-terminal: %m");
return false;
if (ptmx >= 0) {
ply_trace ("ptmx passed in, using it");
session->pseudoterminal_master_fd = ptmx;
} else {
ply_trace ("ptmx not passed in, creating one");
if (!open_pseudoterminal (session)) {
ply_trace ("could not create pseudo-terminal: %m");
return false;
}
session->created_terminal_device = true;
}
session->created_terminal_device = true;
}
if (should_redirect_console)
ply_trace ("redirecting system console to terminal device");
if (should_redirect_console &&
!ply_terminal_session_redirect_console (session)) {
ply_save_errno ();
close_pseudoterminal (session);
ply_restore_errno ();
return false;
}
if (should_redirect_console)
ply_trace ("done redirecting system console to terminal device");
if (should_redirect_console)
ply_trace ("redirecting system console to terminal device");
if (should_redirect_console &&
!ply_terminal_session_redirect_console (session))
{
ply_save_errno ();
close_pseudoterminal (session);
ply_restore_errno ();
return false;
}
if (should_redirect_console)
ply_trace ("done redirecting system console to terminal device");
session->is_running = true;
session->output_handler = output_handler;
session->hangup_handler = hangup_handler;
session->user_data = user_data;
session->attach_flags = flags;
ply_terminal_session_start_logging (session);
session->is_running = true;
session->output_handler = output_handler;
session->hangup_handler = hangup_handler;
session->user_data = user_data;
session->attach_flags = flags;
ply_terminal_session_start_logging (session);
return true;
return true;
}
void
ply_terminal_session_detach (ply_terminal_session_t *session)
ply_terminal_session_detach (ply_terminal_session_t *session)
{
assert (session != NULL);
assert (session != NULL);
ply_trace ("stopping terminal logger");
ply_trace ("stopping terminal logger");
ply_terminal_session_stop_logging (session);
ply_terminal_session_stop_logging (session);
if (session->console_is_redirected)
{
ply_trace ("unredirecting console messages");
ply_terminal_session_unredirect_console (session);
}
if (session->console_is_redirected) {
ply_trace ("unredirecting console messages");
ply_terminal_session_unredirect_console (session);
}
if (session->created_terminal_device)
{
ply_trace ("ptmx wasn't originally passed in, destroying created one");
close_pseudoterminal (session);
session->created_terminal_device = false;
}
if (session->created_terminal_device) {
ply_trace ("ptmx wasn't originally passed in, destroying created one");
close_pseudoterminal (session);
session->created_terminal_device = false;
}
session->output_handler = NULL;
session->hangup_handler = NULL;
session->user_data = NULL;
session->output_handler = NULL;
session->hangup_handler = NULL;
session->user_data = NULL;
session->is_running = false;
session->is_running = false;
}
int
ply_terminal_session_get_fd (ply_terminal_session_t *session)
{
assert (session != NULL);
assert (session != NULL);
return session->pseudoterminal_master_fd;
return session->pseudoterminal_master_fd;
}
static void
@ -444,147 +430,146 @@ ply_terminal_session_log_bytes (ply_terminal_session_t *session,
const uint8_t *bytes,
size_t number_of_bytes)
{
assert (session != NULL);
assert (session->logger != NULL);
assert (bytes != NULL);
assert (number_of_bytes != 0);
assert (session != NULL);
assert (session->logger != NULL);
assert (bytes != NULL);
assert (number_of_bytes != 0);
ply_logger_inject_bytes (session->logger, bytes, number_of_bytes);
ply_logger_inject_bytes (session->logger, bytes, number_of_bytes);
if (session->output_handler != NULL)
session->output_handler (session->user_data,
bytes, number_of_bytes, session);
if (session->output_handler != NULL)
session->output_handler (session->user_data,
bytes, number_of_bytes, session);
}
static void
ply_terminal_session_on_new_data (ply_terminal_session_t *session,
int session_fd)
{
uint8_t buffer[4096];
ssize_t bytes_read;
uint8_t buffer[4096];
ssize_t bytes_read;
assert (session != NULL);
assert (session_fd >= 0);
assert (session != NULL);
assert (session_fd >= 0);
bytes_read = read (session_fd, buffer, sizeof (buffer));
bytes_read = read (session_fd, buffer, sizeof(buffer));
if (bytes_read > 0)
ply_terminal_session_log_bytes (session, buffer, bytes_read);
if (bytes_read > 0)
ply_terminal_session_log_bytes (session, buffer, bytes_read);
ply_logger_flush (session->logger);
ply_logger_flush (session->logger);
}
static void
ply_terminal_session_on_hangup (ply_terminal_session_t *session)
{
ply_terminal_session_hangup_handler_t hangup_handler;
ply_terminal_session_output_handler_t output_handler;
void *user_data;
ply_terminal_session_flags_t attach_flags;
bool created_terminal_device;
ply_terminal_session_hangup_handler_t hangup_handler;
ply_terminal_session_output_handler_t output_handler;
void *user_data;
ply_terminal_session_flags_t attach_flags;
bool created_terminal_device;
assert (session != NULL);
assert (session != NULL);
ply_trace ("got hang up on terminal session fd");
hangup_handler = session->hangup_handler;
output_handler = session->output_handler;
user_data = session->user_data;
attach_flags = session->attach_flags;
created_terminal_device = session->created_terminal_device;
ply_trace ("got hang up on terminal session fd");
hangup_handler = session->hangup_handler;
output_handler = session->output_handler;
user_data = session->user_data;
attach_flags = session->attach_flags;
created_terminal_device = session->created_terminal_device;
ply_logger_flush (session->logger);
ply_logger_flush (session->logger);
session->is_running = false;
ply_trace ("stopping terminal logging");
ply_terminal_session_stop_logging (session);
session->hangup_handler = NULL;
session->is_running = false;
ply_trace ("stopping terminal logging");
ply_terminal_session_stop_logging (session);
session->hangup_handler = NULL;
if (hangup_handler != NULL)
hangup_handler (session->user_data, session);
if (hangup_handler != NULL)
hangup_handler (session->user_data, session);
ply_terminal_session_detach (session);
ply_terminal_session_detach (session);
/* session ripped away, try to take it back
*/
if (created_terminal_device)
{
ply_trace ("Attempting to reattach to console");
ply_terminal_session_attach (session, attach_flags,
output_handler, hangup_handler,
-1, user_data);
}
/* session ripped away, try to take it back
*/
if (created_terminal_device) {
ply_trace ("Attempting to reattach to console");
ply_terminal_session_attach (session, attach_flags,
output_handler, hangup_handler,
-1, user_data);
}
}
static void
static void
ply_terminal_session_start_logging (ply_terminal_session_t *session)
{
int session_fd;
int session_fd;
assert (session != NULL);
assert (session->logger != NULL);
assert (session != NULL);
assert (session->logger != NULL);
ply_trace ("logging incoming console messages");
if (!ply_logger_is_logging (session->logger))
ply_logger_toggle_logging (session->logger);
ply_trace ("logging incoming console messages");
if (!ply_logger_is_logging (session->logger))
ply_logger_toggle_logging (session->logger);
session_fd = ply_terminal_session_get_fd (session);
session_fd = ply_terminal_session_get_fd (session);
assert (session_fd >= 0);
assert (session_fd >= 0);
session->fd_watch = ply_event_loop_watch_fd (session->loop,
session_fd,
PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
(ply_event_handler_t)
ply_terminal_session_on_new_data,
(ply_event_handler_t)
ply_terminal_session_on_hangup,
session);
session->fd_watch = ply_event_loop_watch_fd (session->loop,
session_fd,
PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
(ply_event_handler_t)
ply_terminal_session_on_new_data,
(ply_event_handler_t)
ply_terminal_session_on_hangup,
session);
}
static void
ply_terminal_session_stop_logging (ply_terminal_session_t *session)
{
assert (session != NULL);
assert (session->logger != NULL);
assert (session != NULL);
assert (session->logger != NULL);
ply_trace ("stopping logging of incoming console messages");
if (ply_logger_is_logging (session->logger))
ply_logger_toggle_logging (session->logger);
ply_trace ("stopping logging of incoming console messages");
if (ply_logger_is_logging (session->logger))
ply_logger_toggle_logging (session->logger);
if (session->loop != NULL &&
session->fd_watch != NULL)
ply_event_loop_stop_watching_fd (session->loop,
session->fd_watch);
session->fd_watch = NULL;
if (session->loop != NULL &&
session->fd_watch != NULL)
ply_event_loop_stop_watching_fd (session->loop,
session->fd_watch);
session->fd_watch = NULL;
}
bool
bool
ply_terminal_session_open_log (ply_terminal_session_t *session,
const char *filename)
{
bool log_is_opened;
bool log_is_opened;
assert (session != NULL);
assert (filename != NULL);
assert (session->logger != NULL);
assert (session != NULL);
assert (filename != NULL);
assert (session->logger != NULL);
ply_save_errno ();
unlink (filename);
log_is_opened = ply_logger_open_file (session->logger, filename, true);
if (log_is_opened)
ply_logger_flush (session->logger);
ply_restore_errno ();
ply_save_errno ();
unlink (filename);
log_is_opened = ply_logger_open_file (session->logger, filename, true);
if (log_is_opened)
ply_logger_flush (session->logger);
ply_restore_errno ();
return log_is_opened;
return log_is_opened;
}
void
void
ply_terminal_session_close_log (ply_terminal_session_t *session)
{
assert (session != NULL);
assert (session->logger != NULL);
assert (session != NULL);
assert (session->logger != NULL);
return ply_logger_close_file (session->logger);
return ply_logger_close_file (session->logger);
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -31,42 +31,44 @@
typedef struct _ply_terminal_session ply_terminal_session_t;
typedef void (* ply_terminal_session_begin_handler_t)
(void *user_data, ply_terminal_session_t *session);
typedef void (*ply_terminal_session_begin_handler_t)(void *user_data,
ply_terminal_session_t *session);
typedef void (* ply_terminal_session_output_handler_t)
(void *user_data, const uint8_t *output, size_t size, ply_terminal_session_t *session);
typedef void (* ply_terminal_session_hangup_handler_t)
(void *user_data, ply_terminal_session_t *session);
typedef void (*ply_terminal_session_output_handler_t)(void *user_data,
const uint8_t *output,
size_t size,
ply_terminal_session_t *session);
typedef void (*ply_terminal_session_hangup_handler_t)(void *user_data,
ply_terminal_session_t *session);
typedef enum
{
PLY_TERMINAL_SESSION_FLAGS_NONE = 0x0,
PLY_TERMINAL_SESSION_FLAGS_RUN_IN_PARENT = 0x1,
PLY_TERMINAL_SESSION_FLAGS_LOOK_IN_PATH = 0x2,
PLY_TERMINAL_SESSION_FLAGS_REDIRECT_CONSOLE = 0x4,
PLY_TERMINAL_SESSION_FLAGS_NONE = 0x0,
PLY_TERMINAL_SESSION_FLAGS_RUN_IN_PARENT = 0x1,
PLY_TERMINAL_SESSION_FLAGS_LOOK_IN_PATH = 0x2,
PLY_TERMINAL_SESSION_FLAGS_REDIRECT_CONSOLE = 0x4,
} ply_terminal_session_flags_t;
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
ply_terminal_session_t *ply_terminal_session_new (const char * const *argv);
ply_terminal_session_t *ply_terminal_session_new (const char *const *argv);
void ply_terminal_session_free (ply_terminal_session_t *session);
void ply_terminal_session_attach_to_event_loop (ply_terminal_session_t *session,
ply_event_loop_t *loop);
bool ply_terminal_session_run (ply_terminal_session_t *session,
ply_terminal_session_flags_t flags,
ply_terminal_session_begin_handler_t begin_handler,
bool ply_terminal_session_run (ply_terminal_session_t *session,
ply_terminal_session_flags_t flags,
ply_terminal_session_begin_handler_t begin_handler,
ply_terminal_session_output_handler_t output_handler,
ply_terminal_session_hangup_handler_t done_handler,
void *user_data);
ply_terminal_session_hangup_handler_t done_handler,
void *user_data);
bool ply_terminal_session_attach (ply_terminal_session_t *session,
ply_terminal_session_flags_t flags,
bool ply_terminal_session_attach (ply_terminal_session_t *session,
ply_terminal_session_flags_t flags,
ply_terminal_session_output_handler_t output_handler,
ply_terminal_session_hangup_handler_t hangup_handler,
int ptmx,
void *user_data);
int ptmx,
void *user_data);
void ply_terminal_session_detach (ply_terminal_session_t *session);
void ply_terminal_session_detach (ply_terminal_session_t *session);
int ply_terminal_session_get_fd (ply_terminal_session_t *session);
bool ply_terminal_session_open_log (ply_terminal_session_t *session,

View file

@ -32,144 +32,139 @@
typedef struct
{
ply_trigger_handler_t handler;
void *user_data;
ply_trigger_handler_t handler;
void *user_data;
} ply_trigger_closure_t;
struct _ply_trigger
{
ply_list_t *closures;
ply_list_t *closures;
ply_trigger_t **free_address;
int ignore_count;
ply_trigger_t **free_address;
int ignore_count;
};
ply_trigger_t *
ply_trigger_new (ply_trigger_t **free_address)
{
ply_trigger_t *trigger;
ply_trigger_t *trigger;
trigger = calloc (1, sizeof (ply_trigger_t));
trigger->free_address = free_address;
trigger->closures = ply_list_new ();
trigger->ignore_count = 0;
trigger = calloc (1, sizeof(ply_trigger_t));
trigger->free_address = free_address;
trigger->closures = ply_list_new ();
trigger->ignore_count = 0;
return trigger;
return trigger;
}
void
ply_trigger_free (ply_trigger_t *trigger)
{
ply_list_node_t *node;
ply_list_node_t *node;
if (trigger == NULL)
return;
if (trigger == NULL)
return;
node = ply_list_get_first_node (trigger->closures);
while (node != NULL)
{
ply_list_node_t *next_node;
ply_trigger_closure_t *closure;
node = ply_list_get_first_node (trigger->closures);
while (node != NULL) {
ply_list_node_t *next_node;
ply_trigger_closure_t *closure;
closure = (ply_trigger_closure_t *) ply_list_node_get_data (node);
closure = (ply_trigger_closure_t *) ply_list_node_get_data (node);
next_node = ply_list_get_next_node (trigger->closures, node);
next_node = ply_list_get_next_node (trigger->closures, node);
free (closure);
ply_list_remove_node (trigger->closures, node);
free (closure);
ply_list_remove_node (trigger->closures, node);
node = next_node;
}
ply_list_free (trigger->closures);
if (trigger->free_address != NULL)
*trigger->free_address = NULL;
if (trigger->free_address != NULL)
*trigger->free_address = NULL;
free (trigger);
}
void
ply_trigger_add_handler (ply_trigger_t *trigger,
ply_trigger_handler_t handler,
void *user_data)
{
ply_trigger_closure_t *closure;
closure = calloc (1, sizeof (ply_trigger_closure_t));
closure->handler = handler;
closure->user_data = user_data;
ply_list_append_data (trigger->closures, closure);
}
void
ply_trigger_remove_handler (ply_trigger_t *trigger,
ply_trigger_handler_t handler,
void *user_data)
{
ply_list_node_t *node;
node = ply_list_get_first_node (trigger->closures);
while (node != NULL)
{
ply_list_node_t *next_node;
ply_trigger_closure_t *closure;
closure = (ply_trigger_closure_t *) ply_list_node_get_data (node);
next_node = ply_list_get_next_node (trigger->closures, node);
if (closure->handler == handler && closure->user_data == user_data)
{
free (closure);
ply_list_remove_node (trigger->closures, node);
break;
node = next_node;
}
ply_list_free (trigger->closures);
node = next_node;
}
if (trigger->free_address != NULL)
*trigger->free_address = NULL;
if (trigger->free_address != NULL)
*trigger->free_address = NULL;
free (trigger);
}
void
ply_trigger_add_handler (ply_trigger_t *trigger,
ply_trigger_handler_t handler,
void *user_data)
{
ply_trigger_closure_t *closure;
closure = calloc (1, sizeof(ply_trigger_closure_t));
closure->handler = handler;
closure->user_data = user_data;
ply_list_append_data (trigger->closures, closure);
}
void
ply_trigger_remove_handler (ply_trigger_t *trigger,
ply_trigger_handler_t handler,
void *user_data)
{
ply_list_node_t *node;
node = ply_list_get_first_node (trigger->closures);
while (node != NULL) {
ply_list_node_t *next_node;
ply_trigger_closure_t *closure;
closure = (ply_trigger_closure_t *) ply_list_node_get_data (node);
next_node = ply_list_get_next_node (trigger->closures, node);
if (closure->handler == handler && closure->user_data == user_data) {
free (closure);
ply_list_remove_node (trigger->closures, node);
break;
}
node = next_node;
}
}
void
ply_trigger_ignore_next_pull (ply_trigger_t *trigger)
{
trigger->ignore_count++;
trigger->ignore_count++;
}
void
ply_trigger_pull (ply_trigger_t *trigger,
const void *data)
{
ply_list_node_t *node;
ply_list_node_t *node;
assert (trigger != NULL);
assert (trigger->ignore_count >= 0);
assert (trigger != NULL);
assert (trigger->ignore_count >= 0);
if (trigger->ignore_count > 0)
{
trigger->ignore_count--;
return;
}
if (trigger->ignore_count > 0) {
trigger->ignore_count--;
return;
}
node = ply_list_get_first_node (trigger->closures);
while (node != NULL)
{
ply_list_node_t *next_node;
ply_trigger_closure_t *closure;
node = ply_list_get_first_node (trigger->closures);
while (node != NULL) {
ply_list_node_t *next_node;
ply_trigger_closure_t *closure;
closure = (ply_trigger_closure_t *) ply_list_node_get_data (node);
closure = (ply_trigger_closure_t *) ply_list_node_get_data (node);
next_node = ply_list_get_next_node (trigger->closures, node);
next_node = ply_list_get_next_node (trigger->closures, node);
closure->handler (closure->user_data, data, trigger);
closure->handler (closure->user_data, data, trigger);
node = next_node;
}
node = next_node;
}
if (trigger->free_address != NULL)
ply_trigger_free (trigger);
if (trigger->free_address != NULL)
ply_trigger_free (trigger);
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -30,18 +30,18 @@
typedef struct _ply_trigger ply_trigger_t;
typedef void (* ply_trigger_handler_t) (void *user_data,
const void *trigger_data,
ply_trigger_t *trigger);
typedef void (*ply_trigger_handler_t) (void *user_data,
const void *trigger_data,
ply_trigger_t *trigger);
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
ply_trigger_t *ply_trigger_new (ply_trigger_t **free_address);
void ply_trigger_add_handler (ply_trigger_t *trigger,
ply_trigger_handler_t handler,
void *user_data);
void ply_trigger_remove_handler (ply_trigger_t *trigger,
ply_trigger_handler_t handler,
void *user_data);
void ply_trigger_add_handler (ply_trigger_t *trigger,
ply_trigger_handler_t handler,
void *user_data);
void ply_trigger_remove_handler (ply_trigger_t *trigger,
ply_trigger_handler_t handler,
void *user_data);
void ply_trigger_free (ply_trigger_t *trigger);
void ply_trigger_ignore_next_pull (ply_trigger_t *trigger);

File diff suppressed because it is too large Load diff

View file

@ -28,29 +28,29 @@
#include <sys/types.h>
#ifndef MIN
#define MIN(a,b) ((a) <= (b)? (a) : (b))
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a,b) ((a) >= (b)? (a) : (b))
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
#endif
#ifndef CLAMP
#define CLAMP(a,b,c) (MIN (MAX ((a), (b)), (c)))
#define CLAMP(a, b, c) (MIN (MAX ((a), (b)), (c)))
#endif
#define PLY_UTF8_CHARACTER_SIZE_MAX 4
typedef intptr_t ply_module_handle_t;
typedef void (* ply_module_function_t) (void);
typedef void (*ply_module_function_t) (void);
typedef intptr_t ply_daemon_handle_t;
typedef enum
{
PLY_UNIX_SOCKET_TYPE_CONCRETE = 0,
PLY_UNIX_SOCKET_TYPE_ABSTRACT,
PLY_UNIX_SOCKET_TYPE_TRIMMED_ABSTRACT
PLY_UNIX_SOCKET_TYPE_CONCRETE = 0,
PLY_UNIX_SOCKET_TYPE_ABSTRACT,
PLY_UNIX_SOCKET_TYPE_TRIMMED_ABSTRACT
} ply_unix_socket_type_t;
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
@ -59,10 +59,10 @@ typedef enum
bool ply_open_unidirectional_pipe (int *sender_fd,
int *receiver_fd);
int ply_connect_to_unix_socket (const char *path,
ply_unix_socket_type_t type);
int ply_listen_to_unix_socket (const char *path,
ply_unix_socket_type_t type);
int ply_connect_to_unix_socket (const char *path,
ply_unix_socket_type_t type);
int ply_listen_to_unix_socket (const char *path,
ply_unix_socket_type_t type);
bool ply_get_credentials_from_fd (int fd,
pid_t *pid,
uid_t *uid,
@ -70,19 +70,19 @@ bool ply_get_credentials_from_fd (int fd,
bool ply_write (int fd,
const void *buffer,
size_t number_of_bytes);
size_t number_of_bytes);
bool ply_write_uint32 (int fd,
uint32_t value);
bool ply_read (int fd,
void *buffer,
size_t number_of_bytes);
bool ply_read (int fd,
void *buffer,
size_t number_of_bytes);
bool ply_read_uint32 (int fd,
uint32_t *value);
bool ply_fd_has_data (int fd);
bool ply_fd_can_take_data (int fd);
bool ply_fd_may_block (int fd);
char **ply_copy_string_array (const char * const *array);
char **ply_copy_string_array (const char *const *array);
void ply_free_string_array (char **array);
bool ply_string_has_prefix (const char *string,
const char *prefix);
@ -100,7 +100,7 @@ ply_module_handle_t *ply_open_module (const char *module_path);
ply_module_handle_t *ply_open_built_in_module (void);
ply_module_function_t ply_module_look_up_function (ply_module_handle_t *handle,
const char *function_name);
const char *function_name);
void ply_close_module (ply_module_handle_t *handle);
bool ply_create_directory (const char *directory);
@ -112,10 +112,10 @@ ply_daemon_handle_t *ply_create_daemon (void);
bool ply_detach_daemon (ply_daemon_handle_t *handle,
int exit_code);
int ply_utf8_character_get_size (const char *string,
size_t n);
int ply_utf8_string_get_length (const char *string,
size_t n);
int ply_utf8_character_get_size (const char *string,
size_t n);
int ply_utf8_string_get_length (const char *string,
size_t n);
char *ply_get_process_command_line (pid_t pid);
pid_t ply_get_process_parent_pid (pid_t pid);

3011
src/main.c

File diff suppressed because it is too large Load diff

View file

@ -51,147 +51,147 @@
struct _ply_label_plugin_control
{
ply_event_loop_t *loop;
ply_pixel_display_t *display;
ply_rectangle_t area;
ply_event_loop_t *loop;
ply_pixel_display_t *display;
ply_rectangle_t area;
char *text;
char *fontdesc;
char *text;
char *fontdesc;
PangoAlignment alignment;
long width;
float red;
float green;
float blue;
float alpha;
PangoAlignment alignment;
long width;
float red;
float green;
float blue;
float alpha;
uint32_t is_hidden : 1;
uint32_t is_hidden : 1;
};
ply_label_plugin_interface_t * ply_label_plugin_get_interface (void);
ply_label_plugin_interface_t *ply_label_plugin_get_interface (void);
static ply_label_plugin_control_t *
create_control (void)
{
ply_label_plugin_control_t *label;
ply_label_plugin_control_t *label;
label = calloc (1, sizeof (ply_label_plugin_control_t));
label = calloc (1, sizeof(ply_label_plugin_control_t));
label->is_hidden = true;
label->alignment = PANGO_ALIGN_LEFT;
label->width = -1;
label->is_hidden = true;
label->alignment = PANGO_ALIGN_LEFT;
label->width = -1;
return label;
return label;
}
static void
destroy_control (ply_label_plugin_control_t *label)
{
if (label == NULL)
return;
if (label == NULL)
return;
free (label);
free (label);
}
static long
get_width_of_control (ply_label_plugin_control_t *label)
{
return label->area.width;
return label->area.width;
}
static long
get_height_of_control (ply_label_plugin_control_t *label)
{
return label->area.height;
return label->area.height;
}
static cairo_t *
get_cairo_context_for_pixel_buffer (ply_label_plugin_control_t *label,
ply_pixel_buffer_t *pixel_buffer)
{
cairo_surface_t *cairo_surface;
cairo_t *cairo_context;
unsigned char *data;
ply_rectangle_t size;
cairo_surface_t *cairo_surface;
cairo_t *cairo_context;
unsigned char *data;
ply_rectangle_t size;
data = (unsigned char *) ply_pixel_buffer_get_argb32_data (pixel_buffer);
ply_pixel_buffer_get_size (pixel_buffer, &size);
data = (unsigned char *) ply_pixel_buffer_get_argb32_data (pixel_buffer);
ply_pixel_buffer_get_size (pixel_buffer, &size);
cairo_surface = cairo_image_surface_create_for_data (data,
CAIRO_FORMAT_ARGB32,
size.width,
size.height,
size.width * 4);
cairo_context = cairo_create (cairo_surface);
cairo_surface_destroy (cairo_surface);
cairo_surface = cairo_image_surface_create_for_data (data,
CAIRO_FORMAT_ARGB32,
size.width,
size.height,
size.width * 4);
cairo_context = cairo_create (cairo_surface);
cairo_surface_destroy (cairo_surface);
return cairo_context;
return cairo_context;
}
static cairo_t *
get_cairo_context_for_sizing (ply_label_plugin_control_t *label)
{
cairo_surface_t *cairo_surface;
cairo_t *cairo_context;
cairo_surface_t *cairo_surface;
cairo_t *cairo_context;
cairo_surface = cairo_image_surface_create_for_data (NULL, CAIRO_FORMAT_ARGB32, 0, 0, 0);
cairo_context = cairo_create (cairo_surface);
cairo_surface_destroy (cairo_surface);
cairo_surface = cairo_image_surface_create_for_data (NULL, CAIRO_FORMAT_ARGB32, 0, 0, 0);
cairo_context = cairo_create (cairo_surface);
cairo_surface_destroy (cairo_surface);
return cairo_context;
return cairo_context;
}
static PangoLayout*
init_pango_text_layout (cairo_t *cairo_context,
char *text,
char *font_description,
static PangoLayout *
init_pango_text_layout (cairo_t *cairo_context,
char *text,
char *font_description,
PangoAlignment alignment,
long width)
long width)
{
PangoLayout *pango_layout;
PangoFontDescription *description;
PangoLayout *pango_layout;
PangoFontDescription *description;
pango_layout = pango_cairo_create_layout (cairo_context);
pango_layout = pango_cairo_create_layout (cairo_context);
if (!font_description)
description = pango_font_description_from_string ("Sans 12");
else
description = pango_font_description_from_string (font_description);
if (!font_description)
description = pango_font_description_from_string ("Sans 12");
else
description = pango_font_description_from_string (font_description);
pango_layout_set_font_description (pango_layout, description);
pango_font_description_free (description);
pango_layout_set_font_description (pango_layout, description);
pango_font_description_free (description);
pango_layout_set_alignment(pango_layout, alignment);
if (width >= 0)
pango_layout_set_width(pango_layout, width * PANGO_SCALE);
pango_layout_set_alignment (pango_layout, alignment);
if (width >= 0)
pango_layout_set_width (pango_layout, width * PANGO_SCALE);
pango_layout_set_text (pango_layout, text, -1);
pango_cairo_update_layout (cairo_context, pango_layout);
pango_layout_set_text (pango_layout, text, -1);
pango_cairo_update_layout (cairo_context, pango_layout);
return pango_layout;
return pango_layout;
}
static void
size_control (ply_label_plugin_control_t *label)
{
cairo_t *cairo_context;
PangoLayout *pango_layout;
int text_width;
int text_height;
cairo_t *cairo_context;
PangoLayout *pango_layout;
int text_width;
int text_height;
if (label->is_hidden)
return;
if (label->is_hidden)
return;
cairo_context = get_cairo_context_for_sizing (label);
cairo_context = get_cairo_context_for_sizing (label);
pango_layout = init_pango_text_layout(cairo_context, label->text, label->fontdesc, label->alignment, label->width);
pango_layout = init_pango_text_layout (cairo_context, label->text, label->fontdesc, label->alignment, label->width);
pango_layout_get_size (pango_layout, &text_width, &text_height);
label->area.width = (long) ((double) text_width / PANGO_SCALE);
label->area.height = (long) ((double) text_height / PANGO_SCALE);
pango_layout_get_size (pango_layout, &text_width, &text_height);
label->area.width = (long) ((double) text_width / PANGO_SCALE);
label->area.height = (long) ((double) text_height / PANGO_SCALE);
g_object_unref (pango_layout);
cairo_destroy (cairo_context);
g_object_unref (pango_layout);
cairo_destroy (cairo_context);
}
static void
@ -202,133 +202,124 @@ draw_control (ply_label_plugin_control_t *label,
unsigned long width,
unsigned long height)
{
cairo_t *cairo_context;
PangoLayout *pango_layout;
int text_width;
int text_height;
cairo_t *cairo_context;
PangoLayout *pango_layout;
int text_width;
int text_height;
if (label->is_hidden)
return;
if (label->is_hidden)
return;
cairo_context = get_cairo_context_for_pixel_buffer (label, pixel_buffer);
cairo_context = get_cairo_context_for_pixel_buffer (label, pixel_buffer);
pango_layout = init_pango_text_layout(cairo_context, label->text, label->fontdesc, label->alignment, label->width);
pango_layout = init_pango_text_layout (cairo_context, label->text, label->fontdesc, label->alignment, label->width);
pango_layout_get_size (pango_layout, &text_width, &text_height);
label->area.width = (long) ((double) text_width / PANGO_SCALE);
label->area.height = (long) ((double) text_height / PANGO_SCALE);
pango_layout_get_size (pango_layout, &text_width, &text_height);
label->area.width = (long) ((double) text_width / PANGO_SCALE);
label->area.height = (long) ((double) text_height / PANGO_SCALE);
cairo_rectangle (cairo_context, x, y, width, height);
cairo_clip (cairo_context);
cairo_move_to (cairo_context,
label->area.x,
label->area.y);
cairo_set_source_rgba (cairo_context,
label->red,
label->green,
label->blue,
label->alpha);
pango_cairo_show_layout (cairo_context,
pango_layout);
cairo_rectangle (cairo_context, x, y, width, height);
cairo_clip (cairo_context);
cairo_move_to (cairo_context,
label->area.x,
label->area.y);
cairo_set_source_rgba (cairo_context,
label->red,
label->green,
label->blue,
label->alpha);
pango_cairo_show_layout (cairo_context,
pango_layout);
g_object_unref (pango_layout);
cairo_destroy (cairo_context);
g_object_unref (pango_layout);
cairo_destroy (cairo_context);
}
static void
set_alignment_for_control (ply_label_plugin_control_t *label,
ply_label_alignment_t alignment)
ply_label_alignment_t alignment)
{
ply_rectangle_t dirty_area;
PangoAlignment pango_alignment;
ply_rectangle_t dirty_area;
PangoAlignment pango_alignment;
switch(alignment)
{
case PLY_LABEL_ALIGN_CENTER:
pango_alignment = PANGO_ALIGN_CENTER;
break;
case PLY_LABEL_ALIGN_RIGHT:
pango_alignment = PANGO_ALIGN_RIGHT;
break;
case PLY_LABEL_ALIGN_LEFT:
default:
pango_alignment = PANGO_ALIGN_LEFT;
break;
}
switch (alignment) {
case PLY_LABEL_ALIGN_CENTER:
pango_alignment = PANGO_ALIGN_CENTER;
break;
case PLY_LABEL_ALIGN_RIGHT:
pango_alignment = PANGO_ALIGN_RIGHT;
break;
case PLY_LABEL_ALIGN_LEFT:
default:
pango_alignment = PANGO_ALIGN_LEFT;
break;
}
if (label->alignment != pango_alignment)
{
dirty_area = label->area;
label->alignment = pango_alignment;
size_control (label);
if (!label->is_hidden && label->display != NULL)
ply_pixel_display_draw_area (label->display,
dirty_area.x, dirty_area.y,
dirty_area.width, dirty_area.height);
}
if (label->alignment != pango_alignment) {
dirty_area = label->area;
label->alignment = pango_alignment;
size_control (label);
if (!label->is_hidden && label->display != NULL)
ply_pixel_display_draw_area (label->display,
dirty_area.x, dirty_area.y,
dirty_area.width, dirty_area.height);
}
}
static void
set_width_for_control (ply_label_plugin_control_t *label,
long width)
{
ply_rectangle_t dirty_area;
ply_rectangle_t dirty_area;
if (label->width != width)
{
dirty_area = label->area;
label->width = width;
size_control (label);
if (!label->is_hidden && label->display != NULL)
ply_pixel_display_draw_area (label->display,
dirty_area.x, dirty_area.y,
dirty_area.width, dirty_area.height);
}
if (label->width != width) {
dirty_area = label->area;
label->width = width;
size_control (label);
if (!label->is_hidden && label->display != NULL)
ply_pixel_display_draw_area (label->display,
dirty_area.x, dirty_area.y,
dirty_area.width, dirty_area.height);
}
}
static void
set_text_for_control (ply_label_plugin_control_t *label,
const char *text)
{
ply_rectangle_t dirty_area;
ply_rectangle_t dirty_area;
if (label->text != text)
{
dirty_area = label->area;
free (label->text);
label->text = strdup (text);
size_control (label);
if (!label->is_hidden && label->display != NULL)
ply_pixel_display_draw_area (label->display,
dirty_area.x, dirty_area.y,
dirty_area.width, dirty_area.height);
}
if (label->text != text) {
dirty_area = label->area;
free (label->text);
label->text = strdup (text);
size_control (label);
if (!label->is_hidden && label->display != NULL)
ply_pixel_display_draw_area (label->display,
dirty_area.x, dirty_area.y,
dirty_area.width, dirty_area.height);
}
}
static void
set_font_for_control (ply_label_plugin_control_t *label,
const char *fontdesc)
{
ply_rectangle_t dirty_area;
ply_rectangle_t dirty_area;
if (label->fontdesc != fontdesc)
{
dirty_area = label->area;
free (label->fontdesc);
if (fontdesc)
label->fontdesc = strdup (fontdesc);
else
label->fontdesc = NULL;
size_control (label);
if (!label->is_hidden && label->display != NULL)
ply_pixel_display_draw_area (label->display,
dirty_area.x, dirty_area.y,
dirty_area.width, dirty_area.height);
}
if (label->fontdesc != fontdesc) {
dirty_area = label->area;
free (label->fontdesc);
if (fontdesc)
label->fontdesc = strdup (fontdesc);
else
label->fontdesc = NULL;
size_control (label);
if (!label->is_hidden && label->display != NULL)
ply_pixel_display_draw_area (label->display,
dirty_area.x, dirty_area.y,
dirty_area.width, dirty_area.height);
}
}
static void
@ -338,15 +329,15 @@ set_color_for_control (ply_label_plugin_control_t *label,
float blue,
float alpha)
{
label->red = red;
label->green = green;
label->blue = blue;
label->alpha = alpha;
label->red = red;
label->green = green;
label->blue = blue;
label->alpha = alpha;
if (!label->is_hidden && label->display != NULL)
ply_pixel_display_draw_area (label->display,
label->area.x, label->area.y,
label->area.width, label->area.height);
if (!label->is_hidden && label->display != NULL)
ply_pixel_display_draw_area (label->display,
label->area.x, label->area.y,
label->area.width, label->area.height);
}
static bool
@ -355,67 +346,67 @@ show_control (ply_label_plugin_control_t *label,
long x,
long y)
{
ply_rectangle_t dirty_area;
ply_rectangle_t dirty_area;
dirty_area = label->area;
label->display = display;
label->area.x = x;
label->area.y = y;
dirty_area = label->area;
label->display = display;
label->area.x = x;
label->area.y = y;
label->is_hidden = false;
label->is_hidden = false;
size_control (label);
size_control (label);
if (!label->is_hidden && label->display != NULL)
ply_pixel_display_draw_area (label->display,
dirty_area.x, dirty_area.y,
dirty_area.width, dirty_area.height);
if (!label->is_hidden && label->display != NULL)
ply_pixel_display_draw_area (label->display,
dirty_area.x, dirty_area.y,
dirty_area.width, dirty_area.height);
label->is_hidden = false;
label->is_hidden = false;
return true;
return true;
}
static void
hide_control (ply_label_plugin_control_t *label)
{
label->is_hidden = true;
if (label->display != NULL)
ply_pixel_display_draw_area (label->display,
label->area.x, label->area.y,
label->area.width, label->area.height);
label->is_hidden = true;
if (label->display != NULL)
ply_pixel_display_draw_area (label->display,
label->area.x, label->area.y,
label->area.width, label->area.height);
label->display = NULL;
label->loop = NULL;
label->display = NULL;
label->loop = NULL;
}
static bool
is_control_hidden (ply_label_plugin_control_t *label)
{
return label->is_hidden;
return label->is_hidden;
}
ply_label_plugin_interface_t *
ply_label_plugin_get_interface (void)
{
static ply_label_plugin_interface_t plugin_interface =
{
.create_control = create_control,
.destroy_control = destroy_control,
.show_control = show_control,
.hide_control = hide_control,
.draw_control = draw_control,
.is_control_hidden = is_control_hidden,
.set_text_for_control = set_text_for_control,
.set_alignment_for_control = set_alignment_for_control,
.set_width_for_control = set_width_for_control,
.set_font_for_control = set_font_for_control,
.set_color_for_control = set_color_for_control,
.get_width_of_control = get_width_of_control,
.get_height_of_control = get_height_of_control
};
static ply_label_plugin_interface_t plugin_interface =
{
.create_control = create_control,
.destroy_control = destroy_control,
.show_control = show_control,
.hide_control = hide_control,
.draw_control = draw_control,
.is_control_hidden = is_control_hidden,
.set_text_for_control = set_text_for_control,
.set_alignment_for_control = set_alignment_for_control,
.set_width_for_control = set_width_for_control,
.set_font_for_control = set_font_for_control,
.set_color_for_control = set_color_for_control,
.get_width_of_control = get_width_of_control,
.get_height_of_control = get_height_of_control
};
return &plugin_interface;
return &plugin_interface;
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

File diff suppressed because it is too large Load diff

View file

@ -33,34 +33,33 @@ typedef struct _ply_renderer_driver ply_renderer_driver_t;
typedef struct
{
ply_renderer_driver_t * (* create_driver) (int device_fd);
ply_renderer_driver_t * (*create_driver)(int device_fd);
void (* destroy_driver) (ply_renderer_driver_t *driver);
void (*destroy_driver)(ply_renderer_driver_t *driver);
uint32_t (* create_buffer) (ply_renderer_driver_t *driver,
unsigned long width,
unsigned long height,
unsigned long *row_stride);
bool (* fetch_buffer) (ply_renderer_driver_t *driver,
uint32_t buffer_id,
unsigned long *width,
unsigned long *height,
unsigned long *row_stride);
uint32_t (*create_buffer)(ply_renderer_driver_t *driver,
unsigned long width,
unsigned long height,
unsigned long *row_stride);
bool (*fetch_buffer)(ply_renderer_driver_t *driver,
uint32_t buffer_id,
unsigned long *width,
unsigned long *height,
unsigned long *row_stride);
bool (* map_buffer) (ply_renderer_driver_t *driver,
uint32_t buffer_id);
void (* unmap_buffer) (ply_renderer_driver_t *driver,
bool (*map_buffer)(ply_renderer_driver_t *driver,
uint32_t buffer_id);
char * (* begin_flush) (ply_renderer_driver_t *driver,
uint32_t buffer_id);
void (* end_flush) (ply_renderer_driver_t *driver,
uint32_t buffer_id);
void (* destroy_buffer) (ply_renderer_driver_t *driver,
void (*unmap_buffer)(ply_renderer_driver_t *driver,
uint32_t buffer_id);
char * (*begin_flush)(ply_renderer_driver_t * driver,
uint32_t buffer_id);
void (*end_flush)(ply_renderer_driver_t *driver,
uint32_t buffer_id);
void (*destroy_buffer)(ply_renderer_driver_t *driver,
uint32_t buffer_id);
} ply_renderer_driver_interface_t;
#endif /* PLY_RENDERER_DRIVER_H */

View file

@ -53,91 +53,89 @@ typedef struct _ply_renderer_buffer ply_renderer_buffer_t;
struct _ply_renderer_buffer
{
uint32_t id;
uint32_t id;
uint32_t handle;
uint32_t width;
uint32_t height;
uint32_t row_stride;
uint32_t handle;
uint32_t width;
uint32_t height;
uint32_t row_stride;
void *map_address;
uint32_t map_size;
int map_count;
void *map_address;
uint32_t map_size;
int map_count;
uint32_t added_fb : 1;
uint32_t added_fb : 1;
};
struct _ply_renderer_driver
{
int device_fd;
ply_hashtable_t *buffers;
int device_fd;
ply_hashtable_t *buffers;
uint32_t requires_explicit_flushing : 1;
uint32_t requires_explicit_flushing : 1;
};
static bool
ply_renderer_buffer_map (ply_renderer_driver_t *driver,
ply_renderer_buffer_t *buffer)
{
struct drm_mode_map_dumb map_dumb_buffer_request;
void *map_address;
struct drm_mode_map_dumb map_dumb_buffer_request;
void *map_address;
if (buffer->map_address != MAP_FAILED)
{
buffer->map_count++;
return true;
}
if (buffer->map_address != MAP_FAILED) {
buffer->map_count++;
return true;
}
memset (&map_dumb_buffer_request, 0, sizeof (struct drm_mode_map_dumb));
map_dumb_buffer_request.handle = buffer->handle;
if (drmIoctl (driver->device_fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb_buffer_request) < 0)
{
ply_trace ("Could not map GEM object %u: %m", buffer->handle);
return false;
}
memset (&map_dumb_buffer_request, 0, sizeof(struct drm_mode_map_dumb));
map_dumb_buffer_request.handle = buffer->handle;
if (drmIoctl (driver->device_fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb_buffer_request) < 0) {
ply_trace ("Could not map GEM object %u: %m", buffer->handle);
return false;
}
map_address = mmap (0, buffer->map_size,
PROT_READ | PROT_WRITE, MAP_SHARED,
driver->device_fd, map_dumb_buffer_request.offset);
map_address = mmap (0, buffer->map_size,
PROT_READ | PROT_WRITE, MAP_SHARED,
driver->device_fd, map_dumb_buffer_request.offset);
if (map_address == MAP_FAILED)
return false;
if (map_address == MAP_FAILED)
return false;
buffer->map_address = map_address;
buffer->map_count++;
buffer->map_address = map_address;
buffer->map_count++;
return true;
return true;
}
static void
ply_renderer_buffer_unmap (ply_renderer_driver_t *driver,
ply_renderer_buffer_t *buffer)
{
buffer->map_count--;
buffer->map_count--;
assert (buffer->map_count >= 0);
assert (buffer->map_count >= 0);
}
static ply_renderer_driver_t *
create_driver (int device_fd)
{
ply_renderer_driver_t *driver;
ply_renderer_driver_t *driver;
driver = calloc (1, sizeof (ply_renderer_driver_t));
driver->device_fd = device_fd;
driver->requires_explicit_flushing = true;
driver->buffers = ply_hashtable_new (ply_hashtable_direct_hash,
ply_hashtable_direct_compare);
driver = calloc (1, sizeof(ply_renderer_driver_t));
driver->device_fd = device_fd;
driver->requires_explicit_flushing = true;
driver->buffers = ply_hashtable_new (ply_hashtable_direct_hash,
ply_hashtable_direct_compare);
return driver;
return driver;
}
static void
destroy_driver (ply_renderer_driver_t *driver)
{
ply_hashtable_free (driver->buffers);
ply_hashtable_free (driver->buffers);
free (driver);
free (driver);
}
static ply_renderer_buffer_t *
@ -145,77 +143,73 @@ ply_renderer_buffer_new (ply_renderer_driver_t *driver,
uint32_t width,
uint32_t height)
{
ply_renderer_buffer_t *buffer;
struct drm_mode_create_dumb create_dumb_buffer_request;
ply_renderer_buffer_t *buffer;
struct drm_mode_create_dumb create_dumb_buffer_request;
buffer = calloc (1, sizeof (ply_renderer_buffer_t));
buffer->width = width;
buffer->height = height;
buffer->map_address = MAP_FAILED;
buffer = calloc (1, sizeof(ply_renderer_buffer_t));
buffer->width = width;
buffer->height = height;
buffer->map_address = MAP_FAILED;
memset (&create_dumb_buffer_request, 0, sizeof (struct drm_mode_create_dumb));
memset (&create_dumb_buffer_request, 0, sizeof(struct drm_mode_create_dumb));
create_dumb_buffer_request.width = width;
create_dumb_buffer_request.height = height;
create_dumb_buffer_request.bpp = 32;
create_dumb_buffer_request.flags = 0;
create_dumb_buffer_request.width = width;
create_dumb_buffer_request.height = height;
create_dumb_buffer_request.bpp = 32;
create_dumb_buffer_request.flags = 0;
if (drmIoctl (driver->device_fd,
DRM_IOCTL_MODE_CREATE_DUMB,
&create_dumb_buffer_request) < 0)
{
free (buffer);
ply_trace ("Could not allocate GEM object for frame buffer: %m");
return NULL;
}
if (drmIoctl (driver->device_fd,
DRM_IOCTL_MODE_CREATE_DUMB,
&create_dumb_buffer_request) < 0) {
free (buffer);
ply_trace ("Could not allocate GEM object for frame buffer: %m");
return NULL;
}
buffer->handle = create_dumb_buffer_request.handle;
buffer->row_stride = create_dumb_buffer_request.pitch;
buffer->map_size = create_dumb_buffer_request.size;
buffer->handle = create_dumb_buffer_request.handle;
buffer->row_stride = create_dumb_buffer_request.pitch;
buffer->map_size = create_dumb_buffer_request.size;
ply_trace ("returning %ux%u buffer with stride %u",
width, height, buffer->row_stride);
ply_trace ("returning %ux%u buffer with stride %u",
width, height, buffer->row_stride);
return buffer;
return buffer;
}
static void
ply_renderer_buffer_free (ply_renderer_driver_t *driver,
ply_renderer_buffer_t *buffer)
{
struct drm_mode_destroy_dumb destroy_dumb_buffer_request;
struct drm_mode_destroy_dumb destroy_dumb_buffer_request;
if (buffer->added_fb)
drmModeRmFB (driver->device_fd, buffer->id);
if (buffer->added_fb)
drmModeRmFB (driver->device_fd, buffer->id);
if (buffer->map_address != MAP_FAILED)
{
munmap (buffer->map_address, buffer->map_size);
buffer->map_address = MAP_FAILED;
}
if (buffer->map_address != MAP_FAILED) {
munmap (buffer->map_address, buffer->map_size);
buffer->map_address = MAP_FAILED;
}
memset (&destroy_dumb_buffer_request, 0, sizeof (struct drm_mode_destroy_dumb));
destroy_dumb_buffer_request.handle = buffer->handle;
memset (&destroy_dumb_buffer_request, 0, sizeof(struct drm_mode_destroy_dumb));
destroy_dumb_buffer_request.handle = buffer->handle;
if (drmIoctl (driver->device_fd,
DRM_IOCTL_MODE_DESTROY_DUMB,
&destroy_dumb_buffer_request) < 0)
{
ply_trace ("Could not deallocate GEM object %u: %m", buffer->handle);
}
if (drmIoctl (driver->device_fd,
DRM_IOCTL_MODE_DESTROY_DUMB,
&destroy_dumb_buffer_request) < 0)
ply_trace ("Could not deallocate GEM object %u: %m", buffer->handle);
free (buffer);
free (buffer);
}
static ply_renderer_buffer_t *
get_buffer_from_id (ply_renderer_driver_t *driver,
uint32_t id)
{
static ply_renderer_buffer_t *buffer;
static ply_renderer_buffer_t *buffer;
buffer = ply_hashtable_lookup (driver->buffers, (void *) (uintptr_t) id);
buffer = ply_hashtable_lookup (driver->buffers, (void *) (uintptr_t) id);
return buffer;
return buffer;
}
static bool
@ -225,28 +219,27 @@ fetch_buffer (ply_renderer_driver_t *driver,
unsigned long *height,
unsigned long *row_stride)
{
ply_renderer_buffer_t *buffer;
ply_renderer_buffer_t *buffer;
buffer = get_buffer_from_id (driver, buffer_id);
buffer = get_buffer_from_id (driver, buffer_id);
if (buffer == NULL)
{
ply_trace ("could not fetch buffer %u", buffer_id);
return false;
}
if (buffer == NULL) {
ply_trace ("could not fetch buffer %u", buffer_id);
return false;
}
if (width != NULL)
*width = buffer->width;
if (width != NULL)
*width = buffer->width;
if (height != NULL)
*height = buffer->height;
if (height != NULL)
*height = buffer->height;
if (row_stride != NULL)
*row_stride = buffer->row_stride;
if (row_stride != NULL)
*row_stride = buffer->row_stride;
ply_trace ("fetched %ux%u buffer with stride %u",
buffer->width, buffer->height, buffer->row_stride);
return true;
ply_trace ("fetched %ux%u buffer with stride %u",
buffer->width, buffer->height, buffer->row_stride);
return true;
}
static uint32_t
@ -255,141 +248,138 @@ create_buffer (ply_renderer_driver_t *driver,
unsigned long height,
unsigned long *row_stride)
{
ply_renderer_buffer_t *buffer;
ply_renderer_buffer_t *buffer;
buffer = ply_renderer_buffer_new (driver, width, height);
buffer = ply_renderer_buffer_new (driver, width, height);
if (buffer == NULL)
{
ply_trace ("Could not allocate GEM object for frame buffer: %m");
return 0;
}
if (buffer == NULL) {
ply_trace ("Could not allocate GEM object for frame buffer: %m");
return 0;
}
if (drmModeAddFB (driver->device_fd, width, height,
24, 32, buffer->row_stride, buffer->handle,
&buffer->id) != 0)
{
ply_trace ("Could not set up GEM object as frame buffer: %m");
ply_renderer_buffer_free (driver, buffer);
return 0;
}
if (drmModeAddFB (driver->device_fd, width, height,
24, 32, buffer->row_stride, buffer->handle,
&buffer->id) != 0) {
ply_trace ("Could not set up GEM object as frame buffer: %m");
ply_renderer_buffer_free (driver, buffer);
return 0;
}
*row_stride = buffer->row_stride;
*row_stride = buffer->row_stride;
buffer->added_fb = true;
ply_hashtable_insert (driver->buffers,
(void *) (uintptr_t) buffer->id,
buffer);
buffer->added_fb = true;
ply_hashtable_insert (driver->buffers,
(void *) (uintptr_t) buffer->id,
buffer);
return buffer->id;
return buffer->id;
}
static bool
map_buffer (ply_renderer_driver_t *driver,
uint32_t buffer_id)
{
ply_renderer_buffer_t *buffer;
ply_renderer_buffer_t *buffer;
buffer = get_buffer_from_id (driver, buffer_id);
buffer = get_buffer_from_id (driver, buffer_id);
assert (buffer != NULL);
assert (buffer != NULL);
return ply_renderer_buffer_map (driver, buffer);
return ply_renderer_buffer_map (driver, buffer);
}
static void
unmap_buffer (ply_renderer_driver_t *driver,
uint32_t buffer_id)
{
ply_renderer_buffer_t *buffer;
ply_renderer_buffer_t *buffer;
buffer = get_buffer_from_id (driver, buffer_id);
buffer = get_buffer_from_id (driver, buffer_id);
assert (buffer != NULL);
assert (buffer != NULL);
ply_renderer_buffer_unmap (driver, buffer);
ply_renderer_buffer_unmap (driver, buffer);
}
static char *
begin_flush (ply_renderer_driver_t *driver,
uint32_t buffer_id)
{
ply_renderer_buffer_t *buffer;
ply_renderer_buffer_t *buffer;
buffer = get_buffer_from_id (driver, buffer_id);
buffer = get_buffer_from_id (driver, buffer_id);
assert (buffer != NULL);
assert (buffer != NULL);
return buffer->map_address;
return buffer->map_address;
}
static void
end_flush (ply_renderer_driver_t *driver,
uint32_t buffer_id)
{
ply_renderer_buffer_t *buffer;
ply_renderer_buffer_t *buffer;
buffer = get_buffer_from_id (driver, buffer_id);
buffer = get_buffer_from_id (driver, buffer_id);
assert (buffer != NULL);
assert (buffer != NULL);
if (driver->requires_explicit_flushing)
{
struct drm_clip_rect flush_area;
int ret;
if (driver->requires_explicit_flushing) {
struct drm_clip_rect flush_area;
int ret;
flush_area.x1 = 0;
flush_area.y1 = 0;
flush_area.x2 = buffer->width;
flush_area.y2 = buffer->height;
flush_area.x1 = 0;
flush_area.y1 = 0;
flush_area.x2 = buffer->width;
flush_area.y2 = buffer->height;
ret = drmModeDirtyFB (driver->device_fd, buffer->id, &flush_area, 1);
ret = drmModeDirtyFB (driver->device_fd, buffer->id, &flush_area, 1);
if (ret == -ENOSYS)
driver->requires_explicit_flushing = false;
}
if (ret == -ENOSYS)
driver->requires_explicit_flushing = false;
}
}
static void
destroy_buffer (ply_renderer_driver_t *driver,
uint32_t buffer_id)
{
ply_renderer_buffer_t *buffer;
ply_renderer_buffer_t *buffer;
buffer = ply_hashtable_remove (driver->buffers,
(void *) (uintptr_t) buffer_id);
buffer = ply_hashtable_remove (driver->buffers,
(void *) (uintptr_t) buffer_id);
assert (buffer != NULL);
assert (buffer != NULL);
ply_renderer_buffer_free (driver, buffer);
ply_renderer_buffer_free (driver, buffer);
}
ply_renderer_driver_interface_t *
ply_renderer_generic_driver_get_interface (int device_fd)
{
uint64_t supports_dumb_buffers;
uint64_t supports_dumb_buffers;
static ply_renderer_driver_interface_t driver_interface =
{
.create_driver = create_driver,
.destroy_driver = destroy_driver,
.create_buffer = create_buffer,
.fetch_buffer = fetch_buffer,
.map_buffer = map_buffer,
.unmap_buffer = unmap_buffer,
.begin_flush = begin_flush,
.end_flush = end_flush,
.destroy_buffer = destroy_buffer,
};
static ply_renderer_driver_interface_t driver_interface =
{
.create_driver = create_driver,
.destroy_driver = destroy_driver,
.create_buffer = create_buffer,
.fetch_buffer = fetch_buffer,
.map_buffer = map_buffer,
.unmap_buffer = unmap_buffer,
.begin_flush = begin_flush,
.end_flush = end_flush,
.destroy_buffer = destroy_buffer,
};
if (drmGetCap (device_fd, DRM_CAP_DUMB_BUFFER, &supports_dumb_buffers) < 0)
return NULL;
if (drmGetCap (device_fd, DRM_CAP_DUMB_BUFFER, &supports_dumb_buffers) < 0)
return NULL;
if (!supports_dumb_buffers)
return NULL;
if (!supports_dumb_buffers)
return NULL;
return &driver_interface;
return &driver_interface;
}
/* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s, (0,=.5s,:.5s */

File diff suppressed because it is too large Load diff

View file

@ -62,31 +62,31 @@
struct _ply_renderer_head
{
ply_renderer_backend_t *backend;
ply_pixel_buffer_t *pixel_buffer;
ply_rectangle_t area;
GtkWidget *window;
GdkPixmap *pixmap;
cairo_surface_t *image;
uint32_t is_fullscreen : 1;
ply_renderer_backend_t *backend;
ply_pixel_buffer_t *pixel_buffer;
ply_rectangle_t area;
GtkWidget *window;
GdkPixmap *pixmap;
cairo_surface_t *image;
uint32_t is_fullscreen : 1;
};
struct _ply_renderer_input_source
{
ply_buffer_t *key_buffer;
ply_renderer_input_source_handler_t handler;
void *user_data;
ply_buffer_t *key_buffer;
ply_renderer_input_source_handler_t handler;
void *user_data;
};
struct _ply_renderer_backend
{
ply_event_loop_t *loop;
ply_renderer_input_source_t input_source;
ply_list_t *heads;
ply_event_loop_t *loop;
ply_renderer_input_source_t input_source;
ply_list_t *heads;
ply_fd_watch_t *display_watch;
ply_fd_watch_t *display_watch;
uint32_t is_active : 1;
uint32_t is_active : 1;
};
ply_renderer_plugin_interface_t *ply_renderer_backend_get_interface (void);
@ -104,150 +104,150 @@ static ply_renderer_backend_t *
create_backend (const char *device_name,
ply_terminal_t *terminal)
{
ply_renderer_backend_t *backend;
ply_renderer_backend_t *backend;
backend = calloc (1, sizeof (ply_renderer_backend_t));
backend = calloc (1, sizeof(ply_renderer_backend_t));
backend->loop = ply_event_loop_get_default ();
backend->heads = ply_list_new ();
backend->input_source.key_buffer = ply_buffer_new ();
backend->loop = ply_event_loop_get_default ();
backend->heads = ply_list_new ();
backend->input_source.key_buffer = ply_buffer_new ();
return backend;
return backend;
}
static void
destroy_backend (ply_renderer_backend_t *backend)
{
ply_list_node_t *node;
node = ply_list_get_first_node (backend->heads);
while (node != NULL)
{
ply_list_node_t *next_node;
ply_renderer_head_t *head;
ply_list_node_t *node;
head = (ply_renderer_head_t *) ply_list_node_get_data (node);
next_node = ply_list_get_next_node (backend->heads, node);
node = ply_list_get_first_node (backend->heads);
while (node != NULL) {
ply_list_node_t *next_node;
ply_renderer_head_t *head;
free (head);
node = next_node;
}
head = (ply_renderer_head_t *) ply_list_node_get_data (node);
next_node = ply_list_get_next_node (backend->heads, node);
ply_list_free (backend->heads);
ply_buffer_free (backend->input_source.key_buffer);
free (backend);
free (head);
node = next_node;
}
ply_list_free (backend->heads);
ply_buffer_free (backend->input_source.key_buffer);
free (backend);
}
static void
on_display_event (ply_renderer_backend_t *backend)
{
while (gtk_events_pending ())
gtk_main_iteration ();
while (gtk_events_pending ()) {
gtk_main_iteration ();
}
}
static bool
open_device (ply_renderer_backend_t *backend)
{
Display *display;
int display_fd;
Display *display;
int display_fd;
if (!gtk_init_check (0, NULL))
return false;
if (!gtk_init_check (0, NULL))
return false;
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
display_fd = ConnectionNumber (display);
backend->display_watch = ply_event_loop_watch_fd (backend->loop,
display_fd,
PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
(ply_event_handler_t) on_display_event,
NULL,
backend);
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
display_fd = ConnectionNumber (display);
backend->display_watch = ply_event_loop_watch_fd (backend->loop,
display_fd,
PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
(ply_event_handler_t) on_display_event,
NULL,
backend);
return true;
return true;
}
static void
close_device (ply_renderer_backend_t *backend)
{
ply_event_loop_stop_watching_fd (backend->loop, backend->display_watch);
backend->display_watch = NULL;
return;
ply_event_loop_stop_watching_fd (backend->loop, backend->display_watch);
backend->display_watch = NULL;
return;
}
static void
create_fake_multi_head_setup (ply_renderer_backend_t *backend)
{
ply_renderer_head_t *head;
ply_renderer_head_t *head;
head = calloc (1, sizeof (ply_renderer_head_t));
head = calloc (1, sizeof(ply_renderer_head_t));
head->backend = backend;
head->area.x = 0;
head->area.y = 0;
head->area.width = 800; /* FIXME hardcoded */
head->area.height = 600;
head->pixmap = gdk_pixmap_new (NULL,
head->area.width,
head->area.height,
24);
head->pixel_buffer = ply_pixel_buffer_new (head->area.width, head->area.height);
head->backend = backend;
head->area.x = 0;
head->area.y = 0;
head->area.width = 800; /* FIXME hardcoded */
head->area.height = 600;
head->pixmap = gdk_pixmap_new (NULL,
head->area.width,
head->area.height,
24);
head->pixel_buffer = ply_pixel_buffer_new (head->area.width, head->area.height);
ply_list_append_data (backend->heads, head);
ply_list_append_data (backend->heads, head);
head = calloc (1, sizeof (ply_renderer_head_t));
head = calloc (1, sizeof(ply_renderer_head_t));
head->backend = backend;
head->area.x = 800;
head->area.y = 0;
head->area.width = 640; /* FIXME hardcoded */
head->area.height = 480;
head->pixmap = gdk_pixmap_new (NULL,
head->area.width,
head->area.height,
24);
head->pixel_buffer = ply_pixel_buffer_new (head->area.width, head->area.height);
head->backend = backend;
head->area.x = 800;
head->area.y = 0;
head->area.width = 640; /* FIXME hardcoded */
head->area.height = 480;
head->pixmap = gdk_pixmap_new (NULL,
head->area.width,
head->area.height,
24);
head->pixel_buffer = ply_pixel_buffer_new (head->area.width, head->area.height);
ply_list_append_data (backend->heads, head);
ply_list_append_data (backend->heads, head);
}
static void
create_fullscreen_single_head_setup (ply_renderer_backend_t *backend)
{
ply_renderer_head_t *head;
GdkRectangle monitor_geometry;
ply_renderer_head_t *head;
GdkRectangle monitor_geometry;
gdk_screen_get_monitor_geometry (gdk_screen_get_default (), 0, &monitor_geometry);
gdk_screen_get_monitor_geometry (gdk_screen_get_default (), 0, &monitor_geometry);
head = calloc (1, sizeof (ply_renderer_head_t));
head = calloc (1, sizeof(ply_renderer_head_t));
head->backend = backend;
head->area.x = monitor_geometry.x;
head->area.y = monitor_geometry.y;
head->area.width = monitor_geometry.width;
head->area.height = monitor_geometry.height;
head->is_fullscreen = true;
head->pixmap = gdk_pixmap_new (NULL,
head->area.width,
head->area.height,
24);
head->pixel_buffer = ply_pixel_buffer_new (head->area.width, head->area.height);
head->backend = backend;
head->area.x = monitor_geometry.x;
head->area.y = monitor_geometry.y;
head->area.width = monitor_geometry.width;
head->area.height = monitor_geometry.height;
head->is_fullscreen = true;
head->pixmap = gdk_pixmap_new (NULL,
head->area.width,
head->area.height,
24);
head->pixel_buffer = ply_pixel_buffer_new (head->area.width, head->area.height);
ply_list_append_data (backend->heads, head);
ply_list_append_data (backend->heads, head);
}
static bool
query_device (ply_renderer_backend_t *backend)
{
assert (backend != NULL);
assert (backend != NULL);
if (ply_list_get_first_node (backend->heads) == NULL)
{
if (getenv ("PLY_CREATE_FAKE_MULTI_HEAD_SETUP") != NULL)
create_fake_multi_head_setup (backend);
else
create_fullscreen_single_head_setup (backend);
}
if (ply_list_get_first_node (backend->heads) == NULL) {
if (getenv ("PLY_CREATE_FAKE_MULTI_HEAD_SETUP") != NULL)
create_fake_multi_head_setup (backend);
else
create_fullscreen_single_head_setup (backend);
}
return true;
return true;
}
static gboolean
@ -255,105 +255,104 @@ on_window_destroy (GtkWidget *widget,
GdkEvent *event,
gpointer user_data)
{
return TRUE;
return TRUE;
}
static bool
map_to_device (ply_renderer_backend_t *backend)
{
ply_list_node_t *node;
assert (backend != NULL);
ply_list_node_t *node;
node = ply_list_get_first_node (backend->heads);
while (node != NULL)
{
ply_list_node_t *next_node;
ply_renderer_head_t *head;
uint32_t *shadow_buffer;
assert (backend != NULL);
head = (ply_renderer_head_t *) ply_list_node_get_data (node);
next_node = ply_list_get_next_node (backend->heads, node);
node = ply_list_get_first_node (backend->heads);
while (node != NULL) {
ply_list_node_t *next_node;
ply_renderer_head_t *head;
uint32_t *shadow_buffer;
if (head->window == NULL)
{
head->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_resizable (GTK_WINDOW (head->window), FALSE);
gtk_widget_set_size_request (head->window,
head->area.width,
head->area.height);
shadow_buffer = ply_pixel_buffer_get_argb32_data (head->pixel_buffer);
head->image = cairo_image_surface_create_for_data ((unsigned char *) shadow_buffer,
CAIRO_FORMAT_ARGB32,
head->area.width, head->area.height,
head->area.width * 4);
gtk_widget_set_app_paintable (head->window, TRUE);
gtk_widget_show_all (head->window);
gdk_window_set_back_pixmap (head->window->window, head->pixmap, FALSE);
gdk_window_set_decorations (head->window->window, GDK_DECOR_BORDER);
gtk_window_move (GTK_WINDOW (head->window), head->area.x, head->area.y);
head = (ply_renderer_head_t *) ply_list_node_get_data (node);
next_node = ply_list_get_next_node (backend->heads, node);
gtk_window_set_type_hint (GTK_WINDOW (head->window), GDK_WINDOW_TYPE_HINT_DOCK);
if (head->window == NULL) {
head->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_resizable (GTK_WINDOW (head->window), FALSE);
gtk_widget_set_size_request (head->window,
head->area.width,
head->area.height);
shadow_buffer = ply_pixel_buffer_get_argb32_data (head->pixel_buffer);
head->image = cairo_image_surface_create_for_data ((unsigned char *) shadow_buffer,
CAIRO_FORMAT_ARGB32,
head->area.width, head->area.height,
head->area.width * 4);
gtk_widget_set_app_paintable (head->window, TRUE);
gtk_widget_show_all (head->window);
gdk_window_set_back_pixmap (head->window->window, head->pixmap, FALSE);
gdk_window_set_decorations (head->window->window, GDK_DECOR_BORDER);
gtk_window_move (GTK_WINDOW (head->window), head->area.x, head->area.y);
if (head->is_fullscreen)
gtk_window_fullscreen (GTK_WINDOW (head->window));
gtk_window_set_type_hint (GTK_WINDOW (head->window), GDK_WINDOW_TYPE_HINT_DOCK);
gtk_widget_add_events (head->window, GDK_BUTTON1_MOTION_MASK);
if (head->is_fullscreen)
gtk_window_fullscreen (GTK_WINDOW (head->window));
g_signal_connect (head->window, "motion-notify-event",
G_CALLBACK (on_motion_notify_event),
head);
g_signal_connect (head->window, "key-press-event",
G_CALLBACK (on_key_event),
&backend->input_source);
g_signal_connect (head->window, "delete-event",
G_CALLBACK (on_window_destroy),
NULL);
gtk_widget_add_events (head->window, GDK_BUTTON1_MOTION_MASK);
g_signal_connect (head->window, "motion-notify-event",
G_CALLBACK (on_motion_notify_event),
head);
g_signal_connect (head->window, "key-press-event",
G_CALLBACK (on_key_event),
&backend->input_source);
g_signal_connect (head->window, "delete-event",
G_CALLBACK (on_window_destroy),
NULL);
}
ply_renderer_head_redraw (backend, head);
node = next_node;
}
ply_renderer_head_redraw (backend, head);
node = next_node;
}
backend->is_active = true;
backend->is_active = true;
return true;
return true;
}
static void
unmap_from_device (ply_renderer_backend_t *backend)
{
ply_list_node_t *node;
assert (backend != NULL);
ply_list_node_t *node;
node = ply_list_get_first_node (backend->heads);
while (node != NULL)
{
ply_list_node_t *next_node;
ply_renderer_head_t *head;
assert (backend != NULL);
head = (ply_renderer_head_t *) ply_list_node_get_data (node);
next_node = ply_list_get_next_node (backend->heads, node);
node = ply_list_get_first_node (backend->heads);
while (node != NULL) {
ply_list_node_t *next_node;
ply_renderer_head_t *head;
gtk_widget_destroy (head->window);
head->window = NULL;
ply_pixel_buffer_free (head->pixel_buffer);
head->pixel_buffer = NULL;
cairo_surface_destroy (head->image);
head->image = NULL;
head = (ply_renderer_head_t *) ply_list_node_get_data (node);
next_node = ply_list_get_next_node (backend->heads, node);
node = next_node;
}
gtk_widget_destroy (head->window);
head->window = NULL;
ply_pixel_buffer_free (head->pixel_buffer);
head->pixel_buffer = NULL;
cairo_surface_destroy (head->image);
head->image = NULL;
node = next_node;
}
}
static void
activate (ply_renderer_backend_t *backend)
{
backend->is_active = true;
backend->is_active = true;
}
static void
deactivate (ply_renderer_backend_t *backend)
{
backend->is_active = false;
backend->is_active = false;
}
static void
@ -362,115 +361,114 @@ flush_area_to_device (ply_renderer_backend_t *backend,
ply_rectangle_t *area_to_flush,
cairo_t *cr)
{
cairo_save (cr);
cairo_rectangle (cr,
area_to_flush->x,
area_to_flush->y,
area_to_flush->width,
area_to_flush->height);
cairo_clip (cr);
cairo_save (cr);
cairo_rectangle (cr,
area_to_flush->x,
area_to_flush->y,
area_to_flush->width,
area_to_flush->height);
cairo_clip (cr);
cairo_set_source_surface (cr, head->image, 0, 0);
cairo_paint (cr);
cairo_restore (cr);
cairo_set_source_surface (cr, head->image, 0, 0);
cairo_paint (cr);
cairo_restore (cr);
}
static void
flush_head (ply_renderer_backend_t *backend,
ply_renderer_head_t *head)
{
ply_region_t *updated_region;
ply_list_t *areas_to_flush;
ply_list_node_t *node;
ply_pixel_buffer_t *pixel_buffer;
cairo_t *cr;
ply_region_t *updated_region;
ply_list_t *areas_to_flush;
ply_list_node_t *node;
ply_pixel_buffer_t *pixel_buffer;
cairo_t *cr;
assert (backend != NULL);
assert (backend != NULL);
if (!backend->is_active)
return;
if (!backend->is_active)
return;
pixel_buffer = head->pixel_buffer;
updated_region = ply_pixel_buffer_get_updated_areas (pixel_buffer);
areas_to_flush = ply_region_get_sorted_rectangle_list (updated_region);
pixel_buffer = head->pixel_buffer;
updated_region = ply_pixel_buffer_get_updated_areas (pixel_buffer);
areas_to_flush = ply_region_get_sorted_rectangle_list (updated_region);
cr = gdk_cairo_create (head->pixmap);
cr = gdk_cairo_create (head->pixmap);
node = ply_list_get_first_node (areas_to_flush);
while (node != NULL)
{
ply_list_node_t *next_node;
ply_rectangle_t *area_to_flush;
node = ply_list_get_first_node (areas_to_flush);
while (node != NULL) {
ply_list_node_t *next_node;
ply_rectangle_t *area_to_flush;
area_to_flush = (ply_rectangle_t *) ply_list_node_get_data (node);
area_to_flush = (ply_rectangle_t *) ply_list_node_get_data (node);
next_node = ply_list_get_next_node (areas_to_flush, node);
next_node = ply_list_get_next_node (areas_to_flush, node);
flush_area_to_device (backend, head, area_to_flush, cr);
gdk_window_clear_area (head->window->window,
area_to_flush->x,
area_to_flush->y,
area_to_flush->width,
area_to_flush->height);
node = next_node;
}
ply_region_clear (updated_region);
flush_area_to_device (backend, head, area_to_flush, cr);
gdk_window_clear_area (head->window->window,
area_to_flush->x,
area_to_flush->y,
area_to_flush->width,
area_to_flush->height);
node = next_node;
}
ply_region_clear (updated_region);
cairo_destroy (cr);
cairo_destroy (cr);
/* Force read-back to make sure plymouth isn't saturating the
* X server with requests
*/
g_object_unref (gdk_drawable_get_image (GDK_DRAWABLE (head->pixmap),
0, 0, 1, 1));
/* Force read-back to make sure plymouth isn't saturating the
* X server with requests
*/
g_object_unref (gdk_drawable_get_image (GDK_DRAWABLE (head->pixmap),
0, 0, 1, 1));
}
static void
ply_renderer_head_redraw (ply_renderer_backend_t *backend,
ply_renderer_head_t *head)
{
ply_region_t *region;
ply_rectangle_t area;
ply_region_t *region;
ply_rectangle_t area;
area.x = 0;
area.y = 0;
area.width = head->area.width;
area.height = head->area.height;
area.x = 0;
area.y = 0;
area.width = head->area.width;
area.height = head->area.height;
region = ply_pixel_buffer_get_updated_areas (head->pixel_buffer);
region = ply_pixel_buffer_get_updated_areas (head->pixel_buffer);
ply_region_add_rectangle (region, &area);
ply_region_add_rectangle (region, &area);
flush_head (backend, head);
flush_head (backend, head);
}
static ply_list_t *
get_heads (ply_renderer_backend_t *backend)
{
return backend->heads;
return backend->heads;
}
static ply_pixel_buffer_t *
get_buffer_for_head (ply_renderer_backend_t *backend,
ply_renderer_head_t *head)
{
if (head->backend != backend)
return NULL;
if (head->backend != backend)
return NULL;
return head->pixel_buffer;
return head->pixel_buffer;
}
static bool
has_input_source (ply_renderer_backend_t *backend,
ply_renderer_input_source_t *input_source)
{
return input_source == &backend->input_source;
return input_source == &backend->input_source;
}
static ply_renderer_input_source_t *
get_input_source (ply_renderer_backend_t *backend)
{
return &backend->input_source;
return &backend->input_source;
}
static gboolean
@ -478,11 +476,11 @@ on_motion_notify_event (GtkWidget *widget,
GdkEventMotion *event,
gpointer user_data)
{
ply_renderer_head_t *head = user_data;
ply_renderer_head_t *head = user_data;
gtk_window_begin_move_drag (GTK_WINDOW (head->window), 1,
event->x_root, event->y_root, event->time);
return FALSE;
gtk_window_begin_move_drag (GTK_WINDOW (head->window), 1,
event->x_root, event->y_root, event->time);
return FALSE;
}
static gboolean
@ -490,95 +488,88 @@ on_key_event (GtkWidget *widget,
GdkEventKey *event,
gpointer user_data)
{
ply_renderer_input_source_t *input_source = user_data;
ply_renderer_input_source_t *input_source = user_data;
if (event->keyval == GDK_Return) /* Enter */
{
ply_buffer_append_bytes (input_source->key_buffer, "\n", 1);
}
else if (event->keyval == GDK_Escape) /* Esc */
{
ply_buffer_append_bytes (input_source->key_buffer, "\033", 1);
}
else if (event->keyval == GDK_BackSpace) /* Backspace */
{
ply_buffer_append_bytes (input_source->key_buffer, "\177", 1);
}
else
{
gchar bytes[7];
int byte_count;
guint32 unichar;
unichar = gdk_keyval_to_unicode (event->keyval);
byte_count = g_unichar_to_utf8 (unichar, bytes);
if (bytes[0] != 0)
ply_buffer_append_bytes (input_source->key_buffer, bytes, byte_count);
else
ply_trace ("unknown GDK key: 0x%X \"%s\"",
event->keyval,
gdk_keyval_name (event->keyval));
}
if (event->keyval == GDK_Return) { /* Enter */
ply_buffer_append_bytes (input_source->key_buffer, "\n", 1);
} else if (event->keyval == GDK_Escape) { /* Esc */
ply_buffer_append_bytes (input_source->key_buffer, "\033", 1);
} else if (event->keyval == GDK_BackSpace) { /* Backspace */
ply_buffer_append_bytes (input_source->key_buffer, "\177", 1);
} else {
gchar bytes[7];
int byte_count;
guint32 unichar;
unichar = gdk_keyval_to_unicode (event->keyval);
byte_count = g_unichar_to_utf8 (unichar, bytes);
if (bytes[0] != 0)
ply_buffer_append_bytes (input_source->key_buffer, bytes, byte_count);
else
ply_trace ("unknown GDK key: 0x%X \"%s\"",
event->keyval,
gdk_keyval_name (event->keyval));
}
if (input_source->handler != NULL)
input_source->handler (input_source->user_data, input_source->key_buffer, input_source);
return FALSE;
if (input_source->handler != NULL)
input_source->handler (input_source->user_data, input_source->key_buffer, input_source);
return FALSE;
}
static bool
open_input_source (ply_renderer_backend_t *backend,
ply_renderer_input_source_t *input_source)
{
assert (backend != NULL);
assert (has_input_source (backend, input_source));
assert (backend != NULL);
assert (has_input_source (backend, input_source));
return true;
return true;
}
static void
set_handler_for_input_source (ply_renderer_backend_t *backend,
ply_renderer_input_source_t *input_source,
set_handler_for_input_source (ply_renderer_backend_t *backend,
ply_renderer_input_source_t *input_source,
ply_renderer_input_source_handler_t handler,
void *user_data)
void *user_data)
{
assert (backend != NULL);
assert (has_input_source (backend, input_source));
assert (backend != NULL);
assert (has_input_source (backend, input_source));
input_source->handler = handler;
input_source->user_data = user_data;
input_source->handler = handler;
input_source->user_data = user_data;
}
static void
close_input_source (ply_renderer_backend_t *backend,
ply_renderer_input_source_t *input_source)
{
assert (backend != NULL);
assert (has_input_source (backend, input_source));
assert (backend != NULL);
assert (has_input_source (backend, input_source));
}
ply_renderer_plugin_interface_t *
ply_renderer_backend_get_interface (void)
{
static ply_renderer_plugin_interface_t plugin_interface =
{
.create_backend = create_backend,
.destroy_backend = destroy_backend,
.open_device = open_device,
.close_device = close_device,
.query_device = query_device,
.map_to_device = map_to_device,
.unmap_from_device = unmap_from_device,
.activate = activate,
.deactivate = deactivate,
.flush_head = flush_head,
.get_heads = get_heads,
.get_buffer_for_head = get_buffer_for_head,
.get_input_source = get_input_source,
.open_input_source = open_input_source,
.set_handler_for_input_source = set_handler_for_input_source,
.close_input_source = close_input_source
};
return &plugin_interface;
static ply_renderer_plugin_interface_t plugin_interface =
{
.create_backend = create_backend,
.destroy_backend = destroy_backend,
.open_device = open_device,
.close_device = close_device,
.query_device = query_device,
.map_to_device = map_to_device,
.unmap_from_device = unmap_from_device,
.activate = activate,
.deactivate = deactivate,
.flush_head = flush_head,
.get_heads = get_heads,
.get_buffer_for_head = get_buffer_for_head,
.get_input_source = get_input_source,
.open_input_source = open_input_source,
.set_handler_for_input_source = set_handler_for_input_source,
.close_input_source = close_input_source
};
return &plugin_interface;
}
/* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */

View file

@ -54,16 +54,17 @@
#define CLEAR_LINE_SEQUENCE "\033[2K\r"
typedef enum {
PLY_BOOT_SPLASH_DISPLAY_NORMAL,
PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY,
PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY
typedef enum
{
PLY_BOOT_SPLASH_DISPLAY_NORMAL,
PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY,
PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY
} ply_boot_splash_display_type_t;
typedef struct
{
ply_boot_splash_plugin_t *plugin;
ply_text_display_t *display;
ply_boot_splash_plugin_t *plugin;
ply_text_display_t *display;
} view_t;
ply_boot_splash_plugin_interface_t *ply_boot_splash_plugin_get_interface (void);
@ -71,125 +72,121 @@ static void detach_from_event_loop (ply_boot_splash_plugin_t *plugin);
struct _ply_boot_splash_plugin
{
ply_event_loop_t *loop;
ply_boot_splash_mode_t mode;
ply_list_t *views;
ply_boot_splash_display_type_t state;
ply_list_t *messages;
ply_event_loop_t *loop;
ply_boot_splash_mode_t mode;
ply_list_t *views;
ply_boot_splash_display_type_t state;
ply_list_t *messages;
};
static view_t *
view_new (ply_boot_splash_plugin_t *plugin,
ply_text_display_t *display)
ply_text_display_t *display)
{
view_t *view;
view_t *view;
view = calloc (1, sizeof (view_t));
view->plugin = plugin;
view->display = display;
view = calloc (1, sizeof(view_t));
view->plugin = plugin;
view->display = display;
return view;
return view;
}
static void
view_free (view_t *view)
{
free (view);
free (view);
}
static void
free_views (ply_boot_splash_plugin_t *plugin)
{
ply_list_node_t *node;
ply_list_node_t *node;
node = ply_list_get_first_node (plugin->views);
node = ply_list_get_first_node (plugin->views);
while (node != NULL)
{
ply_list_node_t *next_node;
view_t *view;
while (node != NULL) {
ply_list_node_t *next_node;
view_t *view;
view = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->views, node);
view = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->views, node);
view_free (view);
ply_list_remove_node (plugin->views, node);
view_free (view);
ply_list_remove_node (plugin->views, node);
node = next_node;
}
node = next_node;
}
ply_list_free (plugin->views);
plugin->views = NULL;
ply_list_free (plugin->views);
plugin->views = NULL;
}
static void
free_messages (ply_boot_splash_plugin_t *plugin)
{
ply_list_node_t *node;
ply_list_node_t *node;
node = ply_list_get_first_node (plugin->messages);
node = ply_list_get_first_node (plugin->messages);
while (node != NULL)
{
ply_list_node_t *next_node;
char *message;
while (node != NULL) {
ply_list_node_t *next_node;
char *message;
message = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->messages, node);
message = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->messages, node);
free (message);
ply_list_remove_node (plugin->messages, node);
free (message);
ply_list_remove_node (plugin->messages, node);
node = next_node;
}
node = next_node;
}
ply_list_free (plugin->messages);
plugin->messages = NULL;
ply_list_free (plugin->messages);
plugin->messages = NULL;
}
static ply_boot_splash_plugin_t *
create_plugin (ply_key_file_t *key_file)
{
ply_boot_splash_plugin_t *plugin;
ply_boot_splash_plugin_t *plugin;
ply_trace ("creating plugin");
ply_trace ("creating plugin");
plugin = calloc (1, sizeof (ply_boot_splash_plugin_t));
plugin->views = ply_list_new ();
plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL;
plugin->messages = ply_list_new ();
return plugin;
plugin = calloc (1, sizeof(ply_boot_splash_plugin_t));
plugin->views = ply_list_new ();
plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL;
plugin->messages = ply_list_new ();
return plugin;
}
static void
destroy_plugin (ply_boot_splash_plugin_t *plugin)
{
ply_trace ("destroying plugin");
ply_trace ("destroying plugin");
if (plugin == NULL)
return;
if (plugin == NULL)
return;
if (plugin->loop != NULL)
{
ply_event_loop_stop_watching_for_exit (plugin->loop, (ply_event_loop_exit_handler_t)
detach_from_event_loop,
plugin);
detach_from_event_loop (plugin);
}
if (plugin->loop != NULL) {
ply_event_loop_stop_watching_for_exit (plugin->loop, (ply_event_loop_exit_handler_t)
detach_from_event_loop,
plugin);
detach_from_event_loop (plugin);
}
free_messages (plugin);
free_views (plugin);
free_messages (plugin);
free_views (plugin);
free (plugin);
free (plugin);
}
static void
detach_from_event_loop (ply_boot_splash_plugin_t *plugin)
{
plugin->loop = NULL;
plugin->loop = NULL;
ply_trace ("detaching from event loop");
ply_trace ("detaching from event loop");
}
static void
@ -197,10 +194,10 @@ view_write (view_t *view,
const char *text,
size_t number_of_bytes)
{
ply_terminal_t *terminal;
ply_terminal_t *terminal;
terminal = ply_text_display_get_terminal (view->display);
ply_terminal_write (terminal, "%.*s", (int) number_of_bytes, text);
terminal = ply_text_display_get_terminal (view->display);
ply_terminal_write (terminal, "%.*s", (int) number_of_bytes, text);
}
static void
@ -208,67 +205,63 @@ write_on_views (ply_boot_splash_plugin_t *plugin,
const char *text,
size_t number_of_bytes)
{
ply_list_node_t *node;
ply_list_node_t *node;
if (number_of_bytes == 0)
return;
if (number_of_bytes == 0)
return;
node = ply_list_get_first_node (plugin->views);
node = ply_list_get_first_node (plugin->views);
while (node != NULL)
{
ply_list_node_t *next_node;
view_t *view;
while (node != NULL) {
ply_list_node_t *next_node;
view_t *view;
view = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->views, node);
view = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->views, node);
view_write (view, text, number_of_bytes);
node = next_node;
}
view_write (view, text, number_of_bytes);
node = next_node;
}
}
static void
add_text_display (ply_boot_splash_plugin_t *plugin,
ply_text_display_t *display)
{
view_t *view;
ply_terminal_t *terminal;
view_t *view;
ply_terminal_t *terminal;
view = view_new (plugin, display);
view = view_new (plugin, display);
terminal = ply_text_display_get_terminal (view->display);
if (ply_terminal_open (terminal))
ply_terminal_activate_vt (terminal);
terminal = ply_text_display_get_terminal (view->display);
if (ply_terminal_open (terminal))
ply_terminal_activate_vt (terminal);
ply_list_append_data (plugin->views, view);
ply_list_append_data (plugin->views, view);
}
static void
remove_text_display (ply_boot_splash_plugin_t *plugin,
ply_text_display_t *display)
{
ply_list_node_t *node;
ply_list_node_t *node;
node = ply_list_get_first_node (plugin->views);
while (node != NULL)
{
view_t *view;
ply_list_node_t *next_node;
node = ply_list_get_first_node (plugin->views);
while (node != NULL) {
view_t *view;
ply_list_node_t *next_node;
view = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->views, node);
view = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->views, node);
if (view->display == display)
{
ply_list_remove_node (plugin->views, node);
return;
if (view->display == display) {
ply_list_remove_node (plugin->views, node);
return;
}
node = next_node;
}
node = next_node;
}
}
static bool
@ -277,34 +270,33 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin,
ply_buffer_t *boot_buffer,
ply_boot_splash_mode_t mode)
{
size_t size;
size_t size;
assert (plugin != NULL);
assert (plugin != NULL);
plugin->loop = loop;
plugin->mode = mode;
plugin->loop = loop;
plugin->mode = mode;
ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t)
detach_from_event_loop,
plugin);
ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t)
detach_from_event_loop,
plugin);
if (boot_buffer)
{
size = ply_buffer_get_size (boot_buffer);
if (boot_buffer) {
size = ply_buffer_get_size (boot_buffer);
write_on_views (plugin, ply_buffer_get_bytes (boot_buffer), size);
}
write_on_views (plugin, ply_buffer_get_bytes (boot_buffer), size);
}
return true;
return true;
}
static void
update_status (ply_boot_splash_plugin_t *plugin,
const char *status)
{
assert (plugin != NULL);
assert (plugin != NULL);
ply_trace ("status update");
ply_trace ("status update");
}
static void
@ -312,51 +304,50 @@ on_boot_output (ply_boot_splash_plugin_t *plugin,
const char *output,
size_t size)
{
ply_trace ("writing '%s' to all views (%d bytes)",
output, (int) size);
write_on_views (plugin, output, size);
ply_trace ("writing '%s' to all views (%d bytes)",
output, (int) size);
write_on_views (plugin, output, size);
}
static void
hide_splash_screen (ply_boot_splash_plugin_t *plugin,
ply_event_loop_t *loop)
{
assert (plugin != NULL);
assert (plugin != NULL);
ply_trace ("hiding splash screen");
ply_trace ("hiding splash screen");
ply_event_loop_stop_watching_for_exit (plugin->loop,
(ply_event_loop_exit_handler_t)
detach_from_event_loop,
plugin);
detach_from_event_loop (plugin);
ply_event_loop_stop_watching_for_exit (plugin->loop,
(ply_event_loop_exit_handler_t)
detach_from_event_loop,
plugin);
detach_from_event_loop (plugin);
}
static void
display_normal (ply_boot_splash_plugin_t *plugin)
{
ply_list_node_t *node;
ply_list_node_t *node;
if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_NORMAL)
write_on_views (plugin, "\r\n", strlen ("\r\n"));
if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_NORMAL)
write_on_views (plugin, "\r\n", strlen ("\r\n"));
plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL;
plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL;
node = ply_list_get_first_node (plugin->messages);
while (node != NULL)
{
const char *message;
ply_list_node_t *next_node;
node = ply_list_get_first_node (plugin->messages);
while (node != NULL) {
const char *message;
ply_list_node_t *next_node;
message = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->messages, node);
message = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->messages, node);
write_on_views (plugin, message, strlen (message));
write_on_views (plugin, "\r\n", strlen ("\r\n"));
write_on_views (plugin, message, strlen (message));
write_on_views (plugin, "\r\n", strlen ("\r\n"));
ply_list_remove_node (plugin->messages, node);
node = next_node;
}
ply_list_remove_node (plugin->messages, node);
node = next_node;
}
}
static void
@ -364,28 +355,30 @@ display_password (ply_boot_splash_plugin_t *plugin,
const char *prompt,
int bullets)
{
int i;
if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY)
write_on_views (plugin, "\r\n", strlen ("\r\n"));
else
write_on_views (plugin,
CLEAR_LINE_SEQUENCE,
strlen (CLEAR_LINE_SEQUENCE));
plugin->state = PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY;
int i;
if (prompt)
write_on_views (plugin,
prompt,
strlen (prompt));
else
write_on_views (plugin,
"Password",
strlen ("Password"));
if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY)
write_on_views (plugin, "\r\n", strlen ("\r\n"));
else
write_on_views (plugin,
CLEAR_LINE_SEQUENCE,
strlen (CLEAR_LINE_SEQUENCE));
plugin->state = PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY;
write_on_views (plugin, ":", strlen (":"));
if (prompt)
write_on_views (plugin,
prompt,
strlen (prompt));
else
write_on_views (plugin,
"Password",
strlen ("Password"));
for (i = 0; i < bullets; i++)
write_on_views (plugin, "*", strlen ("*"));
write_on_views (plugin, ":", strlen (":"));
for (i = 0; i < bullets; i++) {
write_on_views (plugin, "*", strlen ("*"));
}
}
static void
@ -393,54 +386,53 @@ display_question (ply_boot_splash_plugin_t *plugin,
const char *prompt,
const char *entry_text)
{
if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY)
write_on_views (plugin, "\r\n", strlen ("\r\n"));
else
write_on_views (plugin,
CLEAR_LINE_SEQUENCE,
strlen (CLEAR_LINE_SEQUENCE));
if (plugin->state != PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY)
write_on_views (plugin, "\r\n", strlen ("\r\n"));
else
write_on_views (plugin,
CLEAR_LINE_SEQUENCE,
strlen (CLEAR_LINE_SEQUENCE));
plugin->state = PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY;
if (prompt)
write_on_views (plugin, prompt, strlen (prompt));
plugin->state = PLY_BOOT_SPLASH_DISPLAY_QUESTION_ENTRY;
if (prompt)
write_on_views (plugin, prompt, strlen (prompt));
write_on_views (plugin, ":", strlen (":"));
write_on_views (plugin, entry_text, strlen (entry_text));
write_on_views (plugin, ":", strlen (":"));
write_on_views (plugin, entry_text, strlen (entry_text));
}
static void
display_message (ply_boot_splash_plugin_t *plugin,
const char *message)
{
if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_NORMAL)
{
write_on_views (plugin, message, strlen (message));
write_on_views (plugin, "\r\n", strlen ("\r\n"));
}
else
ply_list_append_data (plugin->messages, strdup (message));
if (plugin->state == PLY_BOOT_SPLASH_DISPLAY_NORMAL) {
write_on_views (plugin, message, strlen (message));
write_on_views (plugin, "\r\n", strlen ("\r\n"));
} else {
ply_list_append_data (plugin->messages, strdup (message));
}
}
ply_boot_splash_plugin_interface_t *
ply_boot_splash_plugin_get_interface (void)
{
static ply_boot_splash_plugin_interface_t plugin_interface =
{
.create_plugin = create_plugin,
.destroy_plugin = destroy_plugin,
.add_text_display = add_text_display,
.remove_text_display = remove_text_display,
.show_splash_screen = show_splash_screen,
.update_status = update_status,
.on_boot_output = on_boot_output,
.hide_splash_screen = hide_splash_screen,
.display_normal = display_normal,
.display_password = display_password,
.display_question = display_question,
.display_message = display_message,
};
static ply_boot_splash_plugin_interface_t plugin_interface =
{
.create_plugin = create_plugin,
.destroy_plugin = destroy_plugin,
.add_text_display = add_text_display,
.remove_text_display = remove_text_display,
.show_splash_screen = show_splash_screen,
.update_status = update_status,
.on_boot_output = on_boot_output,
.hide_splash_screen = hide_splash_screen,
.display_normal = display_normal,
.display_password = display_password,
.display_question = display_question,
.display_message = display_message,
};
return &plugin_interface;
return &plugin_interface;
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

File diff suppressed because it is too large Load diff

View file

@ -71,31 +71,31 @@
struct _ply_boot_splash_plugin
{
ply_event_loop_t *loop;
ply_boot_splash_mode_t mode;
ply_list_t *displays;
ply_keyboard_t *keyboard;
ply_event_loop_t *loop;
ply_boot_splash_mode_t mode;
ply_list_t *displays;
ply_keyboard_t *keyboard;
char *script_filename;
char *image_dir;
char *script_filename;
char *image_dir;
ply_list_t *script_env_vars;
script_op_t *script_main_op;
ply_list_t *script_env_vars;
script_op_t *script_main_op;
script_state_t *script_state;
script_lib_sprite_data_t *script_sprite_lib;
script_lib_image_data_t *script_image_lib;
script_lib_plymouth_data_t *script_plymouth_lib;
script_lib_math_data_t *script_math_lib;
script_lib_string_data_t *script_string_lib;
script_state_t *script_state;
script_lib_sprite_data_t *script_sprite_lib;
script_lib_image_data_t *script_image_lib;
script_lib_plymouth_data_t *script_plymouth_lib;
script_lib_math_data_t *script_math_lib;
script_lib_string_data_t *script_string_lib;
uint32_t is_animating : 1;
uint32_t is_animating : 1;
};
typedef struct
typedef struct
{
char *key;
char *value;
char *key;
char *value;
} script_env_var_t;
static void detach_from_event_loop (ply_boot_splash_plugin_t *plugin);
@ -108,134 +108,130 @@ static void on_keyboard_input (ply_boot_splash_plugin_t *plugin,
static void
pause_displays (ply_boot_splash_plugin_t *plugin)
{
ply_list_node_t *node;
ply_list_node_t *node;
node = ply_list_get_first_node (plugin->displays);
while (node != NULL)
{
ply_pixel_display_t *display;
ply_list_node_t *next_node;
node = ply_list_get_first_node (plugin->displays);
while (node != NULL) {
ply_pixel_display_t *display;
ply_list_node_t *next_node;
display = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->displays, node);
display = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->displays, node);
ply_pixel_display_pause_updates (display);
ply_pixel_display_pause_updates (display);
node = next_node;
}
node = next_node;
}
}
static void
unpause_displays (ply_boot_splash_plugin_t *plugin)
{
ply_list_node_t *node;
ply_list_node_t *node;
node = ply_list_get_first_node (plugin->displays);
while (node != NULL)
{
ply_pixel_display_t *display;
ply_list_node_t *next_node;
node = ply_list_get_first_node (plugin->displays);
while (node != NULL) {
ply_pixel_display_t *display;
ply_list_node_t *next_node;
display = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->displays, node);
display = ply_list_node_get_data (node);
next_node = ply_list_get_next_node (plugin->displays, node);
ply_pixel_display_unpause_updates (display);
ply_pixel_display_unpause_updates (display);
node = next_node;
}
node = next_node;
}
}
static void
static void
add_script_env_var (const char *group_name,
const char *key,
const char *value,
void *user_data)
{
ply_list_t *script_env_vars;
script_env_var_t *new_env_var;
ply_list_t *script_env_vars;
script_env_var_t *new_env_var;
if (strcmp (group_name, "script-env-vars") != 0)
return;
if (strcmp (group_name, "script-env-vars") != 0)
return;
script_env_vars = user_data;
new_env_var = malloc (sizeof (script_env_var_t));
new_env_var->key = strdup (key);
new_env_var->value = strdup (value);
script_env_vars = user_data;
new_env_var = malloc (sizeof(script_env_var_t));
new_env_var->key = strdup (key);
new_env_var->value = strdup (value);
ply_list_append_data (script_env_vars, new_env_var);
ply_list_append_data (script_env_vars, new_env_var);
}
static ply_boot_splash_plugin_t *
create_plugin (ply_key_file_t *key_file)
{
ply_boot_splash_plugin_t *plugin;
plugin = calloc (1, sizeof (ply_boot_splash_plugin_t));
plugin->image_dir = ply_key_file_get_value (key_file,
"script",
"ImageDir");
plugin->script_filename = ply_key_file_get_value (key_file,
ply_boot_splash_plugin_t *plugin;
plugin = calloc (1, sizeof(ply_boot_splash_plugin_t));
plugin->image_dir = ply_key_file_get_value (key_file,
"script",
"ScriptFile");
"ImageDir");
plugin->script_filename = ply_key_file_get_value (key_file,
"script",
"ScriptFile");
plugin->script_env_vars = ply_list_new ();
ply_key_file_foreach_entry (key_file, add_script_env_var, plugin->script_env_vars);
plugin->script_env_vars = ply_list_new ();
ply_key_file_foreach_entry (key_file, add_script_env_var, plugin->script_env_vars);
plugin->displays = ply_list_new ();
return plugin;
plugin->displays = ply_list_new ();
return plugin;
}
static void
destroy_plugin (ply_boot_splash_plugin_t *plugin)
{
ply_list_node_t *node;
script_env_var_t *env_var;
ply_list_node_t *node;
script_env_var_t *env_var;
if (plugin == NULL)
return;
if (plugin == NULL)
return;
if (plugin->loop != NULL)
{
stop_animation (plugin);
ply_event_loop_stop_watching_for_exit (plugin->loop,
(ply_event_loop_exit_handler_t)
detach_from_event_loop,
plugin);
detach_from_event_loop (plugin);
}
if (plugin->loop != NULL) {
stop_animation (plugin);
ply_event_loop_stop_watching_for_exit (plugin->loop,
(ply_event_loop_exit_handler_t)
detach_from_event_loop,
plugin);
detach_from_event_loop (plugin);
}
for (node = ply_list_get_first_node (plugin->script_env_vars);
node != NULL;
node = ply_list_get_next_node (plugin->script_env_vars, node))
{
env_var = ply_list_node_get_data (node);
free (env_var->key);
free (env_var->value);
free (env_var);
}
ply_list_free (plugin->script_env_vars);
free (plugin->script_filename);
free (plugin->image_dir);
free (plugin);
for (node = ply_list_get_first_node (plugin->script_env_vars);
node != NULL;
node = ply_list_get_next_node (plugin->script_env_vars, node)) {
env_var = ply_list_node_get_data (node);
free (env_var->key);
free (env_var->value);
free (env_var);
}
ply_list_free (plugin->script_env_vars);
free (plugin->script_filename);
free (plugin->image_dir);
free (plugin);
}
static void
on_timeout (ply_boot_splash_plugin_t *plugin)
{
double sleep_time;
double sleep_time;
sleep_time = 1.0 / FRAMES_PER_SECOND;
ply_event_loop_watch_for_timeout (plugin->loop,
sleep_time,
(ply_event_loop_timeout_handler_t)
on_timeout, plugin);
sleep_time = 1.0 / FRAMES_PER_SECOND;
ply_event_loop_watch_for_timeout (plugin->loop,
sleep_time,
(ply_event_loop_timeout_handler_t)
on_timeout, plugin);
script_lib_plymouth_on_refresh (plugin->script_state,
plugin->script_plymouth_lib);
pause_displays (plugin);
script_lib_sprite_refresh (plugin->script_sprite_lib);
unpause_displays (plugin);
script_lib_plymouth_on_refresh (plugin->script_state,
plugin->script_plymouth_lib);
pause_displays (plugin);
script_lib_sprite_refresh (plugin->script_sprite_lib);
unpause_displays (plugin);
}
static void
@ -243,122 +239,120 @@ on_boot_progress (ply_boot_splash_plugin_t *plugin,
double duration,
double percent_done)
{
script_lib_plymouth_on_boot_progress (plugin->script_state,
plugin->script_plymouth_lib,
duration,
percent_done);
script_lib_plymouth_on_boot_progress (plugin->script_state,
plugin->script_plymouth_lib,
duration,
percent_done);
}
static bool
start_script_animation (ply_boot_splash_plugin_t *plugin)
{
ply_list_node_t *node;
script_obj_t *target_obj;
script_obj_t *value_obj;
script_env_var_t *env_var;
assert (plugin != NULL);
ply_list_node_t *node;
script_obj_t *target_obj;
script_obj_t *value_obj;
script_env_var_t *env_var;
plugin->script_state = script_state_new (plugin);
for (node = ply_list_get_first_node (plugin->script_env_vars);
node != NULL;
node = ply_list_get_next_node (plugin->script_env_vars, node))
{
env_var = ply_list_node_get_data (node);
target_obj = script_obj_hash_get_element (plugin->script_state->global,
env_var->key);
value_obj = script_obj_new_string (env_var->value);
script_obj_assign (target_obj, value_obj);
}
plugin->script_image_lib = script_lib_image_setup (plugin->script_state,
plugin->image_dir);
plugin->script_sprite_lib = script_lib_sprite_setup (plugin->script_state,
plugin->displays);
plugin->script_plymouth_lib = script_lib_plymouth_setup (plugin->script_state,
plugin->mode);
plugin->script_math_lib = script_lib_math_setup (plugin->script_state);
plugin->script_string_lib = script_lib_string_setup (plugin->script_state);
assert (plugin != NULL);
ply_trace ("executing script file");
script_return_t ret = script_execute (plugin->script_state,
plugin->script_main_op);
script_obj_unref (ret.object);
if (plugin->keyboard != NULL)
ply_keyboard_add_input_handler (plugin->keyboard,
(ply_keyboard_input_handler_t)
on_keyboard_input, plugin);
on_timeout (plugin);
plugin->script_state = script_state_new (plugin);
return true;
for (node = ply_list_get_first_node (plugin->script_env_vars);
node != NULL;
node = ply_list_get_next_node (plugin->script_env_vars, node)) {
env_var = ply_list_node_get_data (node);
target_obj = script_obj_hash_get_element (plugin->script_state->global,
env_var->key);
value_obj = script_obj_new_string (env_var->value);
script_obj_assign (target_obj, value_obj);
}
plugin->script_image_lib = script_lib_image_setup (plugin->script_state,
plugin->image_dir);
plugin->script_sprite_lib = script_lib_sprite_setup (plugin->script_state,
plugin->displays);
plugin->script_plymouth_lib = script_lib_plymouth_setup (plugin->script_state,
plugin->mode);
plugin->script_math_lib = script_lib_math_setup (plugin->script_state);
plugin->script_string_lib = script_lib_string_setup (plugin->script_state);
ply_trace ("executing script file");
script_return_t ret = script_execute (plugin->script_state,
plugin->script_main_op);
script_obj_unref (ret.object);
if (plugin->keyboard != NULL)
ply_keyboard_add_input_handler (plugin->keyboard,
(ply_keyboard_input_handler_t)
on_keyboard_input, plugin);
on_timeout (plugin);
return true;
}
static bool
start_animation (ply_boot_splash_plugin_t *plugin)
{
assert (plugin != NULL);
assert (plugin->loop != NULL);
assert (plugin != NULL);
assert (plugin->loop != NULL);
if (plugin->is_animating)
return true;
if (plugin->is_animating)
return true;
ply_trace ("parsing script file");
plugin->script_main_op = script_parse_file (plugin->script_filename);
start_script_animation (plugin);
ply_trace ("parsing script file");
plugin->script_main_op = script_parse_file (plugin->script_filename);
plugin->is_animating = true;
return true;
start_script_animation (plugin);
plugin->is_animating = true;
return true;
}
static void
stop_script_animation (ply_boot_splash_plugin_t *plugin)
{
script_lib_plymouth_on_quit (plugin->script_state,
plugin->script_plymouth_lib);
script_lib_sprite_refresh (plugin->script_sprite_lib);
script_lib_plymouth_on_quit (plugin->script_state,
plugin->script_plymouth_lib);
script_lib_sprite_refresh (plugin->script_sprite_lib);
if (plugin->loop != NULL)
ply_event_loop_stop_watching_for_timeout (plugin->loop,
(ply_event_loop_timeout_handler_t)
on_timeout, plugin);
if (plugin->loop != NULL)
ply_event_loop_stop_watching_for_timeout (plugin->loop,
(ply_event_loop_timeout_handler_t)
on_timeout, plugin);
if (plugin->keyboard != NULL)
{
ply_keyboard_remove_input_handler (plugin->keyboard,
(ply_keyboard_input_handler_t)
on_keyboard_input);
plugin->keyboard = NULL;
}
if (plugin->keyboard != NULL) {
ply_keyboard_remove_input_handler (plugin->keyboard,
(ply_keyboard_input_handler_t)
on_keyboard_input);
plugin->keyboard = NULL;
}
script_state_destroy (plugin->script_state);
script_lib_sprite_destroy (plugin->script_sprite_lib);
script_lib_image_destroy (plugin->script_image_lib);
script_lib_plymouth_destroy (plugin->script_plymouth_lib);
script_lib_math_destroy (plugin->script_math_lib);
script_lib_string_destroy (plugin->script_string_lib);
script_state_destroy (plugin->script_state);
script_lib_sprite_destroy (plugin->script_sprite_lib);
script_lib_image_destroy (plugin->script_image_lib);
script_lib_plymouth_destroy (plugin->script_plymouth_lib);
script_lib_math_destroy (plugin->script_math_lib);
script_lib_string_destroy (plugin->script_string_lib);
}
static void
stop_animation (ply_boot_splash_plugin_t *plugin)
{
assert (plugin != NULL);
assert (plugin->loop != NULL);
assert (plugin != NULL);
assert (plugin->loop != NULL);
if (!plugin->is_animating)
return;
plugin->is_animating = false;
if (!plugin->is_animating)
return;
plugin->is_animating = false;
stop_script_animation (plugin);
stop_script_animation (plugin);
script_parse_op_free (plugin->script_main_op);
script_parse_op_free (plugin->script_main_op);
}
static void
detach_from_event_loop (ply_boot_splash_plugin_t *plugin)
{
plugin->loop = NULL;
plugin->loop = NULL;
}
static void
@ -366,42 +360,42 @@ on_keyboard_input (ply_boot_splash_plugin_t *plugin,
const char *keyboard_input,
size_t character_size)
{
char keyboard_string[character_size + 1];
char keyboard_string[character_size + 1];
memcpy (keyboard_string, keyboard_input, character_size);
keyboard_string[character_size] = '\0';
memcpy (keyboard_string, keyboard_input, character_size);
keyboard_string[character_size] = '\0';
script_lib_plymouth_on_keyboard_input (plugin->script_state,
plugin->script_plymouth_lib,
keyboard_string);
script_lib_plymouth_on_keyboard_input (plugin->script_state,
plugin->script_plymouth_lib,
keyboard_string);
}
static void
set_keyboard (ply_boot_splash_plugin_t *plugin,
ply_keyboard_t *keyboard)
{
plugin->keyboard = keyboard;
plugin->keyboard = keyboard;
}
static void
unset_keyboard (ply_boot_splash_plugin_t *plugin,
ply_keyboard_t *keyboard)
{
plugin->keyboard = NULL;
plugin->keyboard = NULL;
}
static void
add_pixel_display (ply_boot_splash_plugin_t *plugin,
ply_pixel_display_t *display)
{
ply_list_append_data (plugin->displays, display);
ply_list_append_data (plugin->displays, display);
}
static void
remove_pixel_display (ply_boot_splash_plugin_t *plugin,
ply_pixel_display_t *display)
{
ply_list_remove_data(plugin->displays, display);
ply_list_remove_data (plugin->displays, display);
}
static bool
@ -410,73 +404,71 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin,
ply_buffer_t *boot_buffer,
ply_boot_splash_mode_t mode)
{
assert (plugin != NULL);
assert (plugin != NULL);
if (ply_list_get_length (plugin->displays) == 0)
{
ply_trace ("no pixel displays");
return false;
}
if (ply_list_get_length (plugin->displays) == 0) {
ply_trace ("no pixel displays");
return false;
}
plugin->loop = loop;
plugin->mode = mode;
plugin->loop = loop;
plugin->mode = mode;
ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t)
detach_from_event_loop,
plugin);
ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t)
detach_from_event_loop,
plugin);
ply_trace ("starting boot animation");
return start_animation (plugin);
ply_trace ("starting boot animation");
return start_animation (plugin);
}
static void
update_status (ply_boot_splash_plugin_t *plugin,
const char *status)
{
script_lib_plymouth_on_update_status (plugin->script_state,
plugin->script_plymouth_lib,
status);
script_lib_plymouth_on_update_status (plugin->script_state,
plugin->script_plymouth_lib,
status);
}
static void
hide_splash_screen (ply_boot_splash_plugin_t *plugin,
ply_event_loop_t *loop)
{
assert (plugin != NULL);
assert (plugin != NULL);
if (plugin->loop != NULL)
{
stop_animation (plugin);
if (plugin->loop != NULL) {
stop_animation (plugin);
ply_event_loop_stop_watching_for_exit (plugin->loop,
(ply_event_loop_exit_handler_t)
detach_from_event_loop,
plugin);
detach_from_event_loop (plugin);
}
ply_event_loop_stop_watching_for_exit (plugin->loop,
(ply_event_loop_exit_handler_t)
detach_from_event_loop,
plugin);
detach_from_event_loop (plugin);
}
}
static void
on_root_mounted (ply_boot_splash_plugin_t *plugin)
{
script_lib_plymouth_on_root_mounted (plugin->script_state,
plugin->script_plymouth_lib);
script_lib_plymouth_on_root_mounted (plugin->script_state,
plugin->script_plymouth_lib);
}
static void
become_idle (ply_boot_splash_plugin_t *plugin,
ply_trigger_t *idle_trigger)
{
ply_trigger_pull (idle_trigger, NULL);
ply_trigger_pull (idle_trigger, NULL);
}
static void
display_normal (ply_boot_splash_plugin_t *plugin)
{
pause_displays (plugin);
script_lib_plymouth_on_display_normal (plugin->script_state,
plugin->script_plymouth_lib);
unpause_displays (plugin);
pause_displays (plugin);
script_lib_plymouth_on_display_normal (plugin->script_state,
plugin->script_plymouth_lib);
unpause_displays (plugin);
}
static void
@ -484,12 +476,12 @@ display_password (ply_boot_splash_plugin_t *plugin,
const char *prompt,
int bullets)
{
pause_displays (plugin);
script_lib_plymouth_on_display_password (plugin->script_state,
plugin->script_plymouth_lib,
prompt,
bullets);
unpause_displays (plugin);
pause_displays (plugin);
script_lib_plymouth_on_display_password (plugin->script_state,
plugin->script_plymouth_lib,
prompt,
bullets);
unpause_displays (plugin);
}
static void
@ -497,61 +489,61 @@ display_question (ply_boot_splash_plugin_t *plugin,
const char *prompt,
const char *entry_text)
{
pause_displays (plugin);
script_lib_plymouth_on_display_question (plugin->script_state,
plugin->script_plymouth_lib,
prompt,
entry_text);
unpause_displays (plugin);
pause_displays (plugin);
script_lib_plymouth_on_display_question (plugin->script_state,
plugin->script_plymouth_lib,
prompt,
entry_text);
unpause_displays (plugin);
}
static void
display_message (ply_boot_splash_plugin_t *plugin,
const char *message)
{
pause_displays (plugin);
script_lib_plymouth_on_display_message (plugin->script_state,
plugin->script_plymouth_lib,
message);
unpause_displays (plugin);
pause_displays (plugin);
script_lib_plymouth_on_display_message (plugin->script_state,
plugin->script_plymouth_lib,
message);
unpause_displays (plugin);
}
static void
hide_message (ply_boot_splash_plugin_t *plugin,
const char *message)
const char *message)
{
pause_displays (plugin);
script_lib_plymouth_on_hide_message (plugin->script_state,
plugin->script_plymouth_lib,
message);
unpause_displays (plugin);
pause_displays (plugin);
script_lib_plymouth_on_hide_message (plugin->script_state,
plugin->script_plymouth_lib,
message);
unpause_displays (plugin);
}
ply_boot_splash_plugin_interface_t *
ply_boot_splash_plugin_get_interface (void)
{
static ply_boot_splash_plugin_interface_t plugin_interface =
{
.create_plugin = create_plugin,
.destroy_plugin = destroy_plugin,
.set_keyboard = set_keyboard,
.unset_keyboard = unset_keyboard,
.add_pixel_display = add_pixel_display,
.remove_pixel_display = remove_pixel_display,
.show_splash_screen = show_splash_screen,
.update_status = update_status,
.on_boot_progress = on_boot_progress,
.hide_splash_screen = hide_splash_screen,
.on_root_mounted = on_root_mounted,
.become_idle = become_idle,
.display_normal = display_normal,
.display_password = display_password,
.display_question = display_question,
.display_message = display_message,
.hide_message = hide_message,
};
static ply_boot_splash_plugin_interface_t plugin_interface =
{
.create_plugin = create_plugin,
.destroy_plugin = destroy_plugin,
.set_keyboard = set_keyboard,
.unset_keyboard = unset_keyboard,
.add_pixel_display = add_pixel_display,
.remove_pixel_display = remove_pixel_display,
.show_splash_screen = show_splash_screen,
.update_status = update_status,
.on_boot_progress = on_boot_progress,
.hide_splash_screen = hide_splash_screen,
.on_root_mounted = on_root_mounted,
.become_idle = become_idle,
.display_normal = display_normal,
.display_password = display_password,
.display_question = display_question,
.display_message = display_message,
.hide_message = hide_message,
};
return &plugin_interface;
return &plugin_interface;
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -34,42 +34,40 @@ static ply_hashtable_t *script_debug_name_hash = NULL;
static void script_debug_setup (void)
{
if (!script_debug_location_hash)
{
script_debug_location_hash = ply_hashtable_new(NULL, NULL);
script_debug_name_hash = ply_hashtable_new(ply_hashtable_string_hash,
ply_hashtable_string_compare);
}
if (!script_debug_location_hash) {
script_debug_location_hash = ply_hashtable_new (NULL, NULL);
script_debug_name_hash = ply_hashtable_new (ply_hashtable_string_hash,
ply_hashtable_string_compare);
}
}
void script_debug_add_element (void *element,
script_debug_location_t *location)
{
script_debug_setup();
script_debug_location_t *new_location = malloc (sizeof(script_debug_location_t));
new_location->line_index = location->line_index;
new_location->column_index = location->column_index;
new_location->name = ply_hashtable_lookup (script_debug_name_hash, location->name);
if (!new_location->name)
{
new_location->name = strdup(location->name);
ply_hashtable_insert (script_debug_name_hash, new_location->name, new_location->name);
}
ply_hashtable_insert (script_debug_location_hash, element, new_location);
script_debug_setup ();
script_debug_location_t *new_location = malloc (sizeof(script_debug_location_t));
new_location->line_index = location->line_index;
new_location->column_index = location->column_index;
new_location->name = ply_hashtable_lookup (script_debug_name_hash, location->name);
if (!new_location->name) {
new_location->name = strdup (location->name);
ply_hashtable_insert (script_debug_name_hash, new_location->name, new_location->name);
}
ply_hashtable_insert (script_debug_location_hash, element, new_location);
}
void script_debug_remove_element (void *element)
{
script_debug_setup();
script_debug_location_t *old_location = ply_hashtable_remove (script_debug_location_hash,
element);
free(old_location);
script_debug_setup ();
script_debug_location_t *old_location = ply_hashtable_remove (script_debug_location_hash,
element);
free (old_location);
}
script_debug_location_t *script_debug_lookup_element (void *element)
{
script_debug_setup();
script_debug_location_t *location = ply_hashtable_lookup (script_debug_location_hash,
element);
return location;
script_debug_setup ();
script_debug_location_t *location = ply_hashtable_lookup (script_debug_location_hash,
element);
return location;
}

View file

@ -25,9 +25,9 @@
typedef struct
{
int line_index;
int column_index;
char* name;
int line_index;
int column_index;
char *name;
} script_debug_location_t;

File diff suppressed because it is too large Load diff

View file

@ -26,10 +26,10 @@
script_return_t script_execute (script_state_t *state,
script_op_t *op);
script_return_t script_execute_object (script_state_t *state,
script_obj_t *function,
script_obj_t *this,
script_obj_t *first_arg,
script_return_t script_execute_object (script_state_t * state,
script_obj_t * function,
script_obj_t * this,
script_obj_t * first_arg,
...);
#endif /* SCRIPT_EXECUTE_H */

View file

@ -42,260 +42,250 @@
static void image_free (script_obj_t *obj)
{
ply_pixel_buffer_t *image = obj->data.native.object_data;
ply_pixel_buffer_t *image = obj->data.native.object_data;
ply_pixel_buffer_free (image);
ply_pixel_buffer_free (image);
}
static script_return_t image_new (script_state_t *state,
void *user_data)
{
script_lib_image_data_t *data = user_data;
script_obj_t *reply;
char *path_filename;
char *filename = script_obj_hash_get_string (state->local, "filename");
char *test_string = filename;
const char *prefix_string = "special://";
script_lib_image_data_t *data = user_data;
script_obj_t *reply;
char *path_filename;
char *filename = script_obj_hash_get_string (state->local, "filename");
char *test_string = filename;
const char *prefix_string = "special://";
while (*test_string && *prefix_string && *test_string == *prefix_string)
{
test_string++;
prefix_string++;
}
if (!*prefix_string)
{
if (strcmp (test_string, "logo") == 0)
path_filename = strdup (PLYMOUTH_LOGO_FILE);
else
path_filename = strdup ("");
}
else
asprintf (&path_filename, "%s/%s", data->image_dir, filename);
ply_image_t *file_image = ply_image_new (path_filename);
if (ply_image_load (file_image))
{
ply_pixel_buffer_t *buffer = ply_image_convert_to_pixel_buffer (file_image);
reply = script_obj_new_native (buffer, data->class);
}
else
{
ply_image_free (file_image);
reply = script_obj_new_null ();
}
free (filename);
free (path_filename);
return script_return_obj (reply);
while (*test_string && *prefix_string && *test_string == *prefix_string) {
test_string++;
prefix_string++;
}
if (!*prefix_string) {
if (strcmp (test_string, "logo") == 0)
path_filename = strdup (PLYMOUTH_LOGO_FILE);
else
path_filename = strdup ("");
} else {
asprintf (&path_filename, "%s/%s", data->image_dir, filename);
}
ply_image_t *file_image = ply_image_new (path_filename);
if (ply_image_load (file_image)) {
ply_pixel_buffer_t *buffer = ply_image_convert_to_pixel_buffer (file_image);
reply = script_obj_new_native (buffer, data->class);
} else {
ply_image_free (file_image);
reply = script_obj_new_null ();
}
free (filename);
free (path_filename);
return script_return_obj (reply);
}
static script_return_t image_get_width (script_state_t *state,
void *user_data)
{
script_lib_image_data_t *data = user_data;
ply_rectangle_t size;
ply_pixel_buffer_t *image;
image = script_obj_as_native_of_class (state->this, data->class);
if (!image) return script_return_obj_null ();
ply_pixel_buffer_get_size (image, &size);
return script_return_obj (script_obj_new_number (size.width));
script_lib_image_data_t *data = user_data;
ply_rectangle_t size;
ply_pixel_buffer_t *image;
image = script_obj_as_native_of_class (state->this, data->class);
if (!image) return script_return_obj_null ();
ply_pixel_buffer_get_size (image, &size);
return script_return_obj (script_obj_new_number (size.width));
}
static script_return_t image_get_height (script_state_t *state,
void *user_data)
{
script_lib_image_data_t *data = user_data;
ply_rectangle_t size;
ply_pixel_buffer_t *image;
image = script_obj_as_native_of_class (state->this, data->class);
if (!image) return script_return_obj_null ();
ply_pixel_buffer_get_size (image, &size);
return script_return_obj (script_obj_new_number (size.height));
script_lib_image_data_t *data = user_data;
ply_rectangle_t size;
ply_pixel_buffer_t *image;
image = script_obj_as_native_of_class (state->this, data->class);
if (!image) return script_return_obj_null ();
ply_pixel_buffer_get_size (image, &size);
return script_return_obj (script_obj_new_number (size.height));
}
static script_return_t image_rotate (script_state_t *state,
void *user_data)
{
script_lib_image_data_t *data = user_data;
ply_pixel_buffer_t *image = script_obj_as_native_of_class (state->this, data->class);
float angle = script_obj_hash_get_number (state->local, "angle");
ply_rectangle_t size;
if (image)
{
ply_pixel_buffer_get_size (image, &size);
ply_pixel_buffer_t *new_image = ply_pixel_buffer_rotate (image,
size.width / 2,
size.height / 2,
angle);
return script_return_obj (script_obj_new_native (new_image, data->class));
}
return script_return_obj_null ();
script_lib_image_data_t *data = user_data;
ply_pixel_buffer_t *image = script_obj_as_native_of_class (state->this, data->class);
float angle = script_obj_hash_get_number (state->local, "angle");
ply_rectangle_t size;
if (image) {
ply_pixel_buffer_get_size (image, &size);
ply_pixel_buffer_t *new_image = ply_pixel_buffer_rotate (image,
size.width / 2,
size.height / 2,
angle);
return script_return_obj (script_obj_new_native (new_image, data->class));
}
return script_return_obj_null ();
}
static script_return_t image_scale (script_state_t *state,
void *user_data)
{
script_lib_image_data_t *data = user_data;
ply_pixel_buffer_t *image = script_obj_as_native_of_class (state->this, data->class);
int width = script_obj_hash_get_number (state->local, "width");
int height = script_obj_hash_get_number (state->local, "height");
script_lib_image_data_t *data = user_data;
ply_pixel_buffer_t *image = script_obj_as_native_of_class (state->this, data->class);
int width = script_obj_hash_get_number (state->local, "width");
int height = script_obj_hash_get_number (state->local, "height");
if (image)
{
ply_pixel_buffer_t *new_image = ply_pixel_buffer_resize (image, width, height);
return script_return_obj (script_obj_new_native (new_image, data->class));
}
return script_return_obj_null ();
if (image) {
ply_pixel_buffer_t *new_image = ply_pixel_buffer_resize (image, width, height);
return script_return_obj (script_obj_new_native (new_image, data->class));
}
return script_return_obj_null ();
}
static script_return_t image_text (script_state_t *state,
void *user_data)
{
script_lib_image_data_t *data = user_data;
ply_pixel_buffer_t *image;
ply_label_t *label;
script_obj_t *alpha_obj, *font_obj, *align_obj;
int width, height;
int align = PLY_LABEL_ALIGN_LEFT;
char *font;
char *text = script_obj_hash_get_string (state->local, "text");
float alpha;
float red = CLAMP(script_obj_hash_get_number (state->local, "red"), 0, 1);
float green = CLAMP(script_obj_hash_get_number (state->local, "green"), 0, 1);
float blue = CLAMP(script_obj_hash_get_number (state->local, "blue"), 0, 1);
script_lib_image_data_t *data = user_data;
ply_pixel_buffer_t *image;
ply_label_t *label;
script_obj_t *alpha_obj, *font_obj, *align_obj;
int width, height;
int align = PLY_LABEL_ALIGN_LEFT;
char *font;
alpha_obj = script_obj_hash_peek_element (state->local, "alpha");
char *text = script_obj_hash_get_string (state->local, "text");
if (script_obj_is_number (alpha_obj))
{
alpha = CLAMP(script_obj_as_number (alpha_obj), 0, 1);
}
else
alpha = 1;
script_obj_unref(alpha_obj);
float alpha;
float red = CLAMP (script_obj_hash_get_number (state->local, "red"), 0, 1);
float green = CLAMP (script_obj_hash_get_number (state->local, "green"), 0, 1);
float blue = CLAMP (script_obj_hash_get_number (state->local, "blue"), 0, 1);
font_obj = script_obj_hash_peek_element (state->local, "font");
alpha_obj = script_obj_hash_peek_element (state->local, "alpha");
if (script_obj_is_string (font_obj))
font = script_obj_as_string (font_obj);
else
font = NULL;
if (script_obj_is_number (alpha_obj))
alpha = CLAMP (script_obj_as_number (alpha_obj), 0, 1);
else
alpha = 1;
script_obj_unref (alpha_obj);
script_obj_unref(font_obj);
font_obj = script_obj_hash_peek_element (state->local, "font");
align_obj = script_obj_hash_peek_element(state->local, "align");
if (script_obj_is_string (font_obj))
font = script_obj_as_string (font_obj);
else
font = NULL;
if (script_obj_is_string(align_obj)) {
char *align_str = script_obj_as_string(align_obj);
script_obj_unref (font_obj);
if(!strcmp("left", align_str))
align = PLY_LABEL_ALIGN_LEFT;
else if(!strcmp("center", align_str))
align = PLY_LABEL_ALIGN_CENTER;
else if(!strcmp("right", align_str))
align = PLY_LABEL_ALIGN_RIGHT;
else
ply_error("Unrecognized Image.Text alignment string '%s'. "
"Expecting 'left', 'center', or 'right'\n",
align_str);
free(align_str);
}
script_obj_unref(align_obj);
align_obj = script_obj_hash_peek_element (state->local, "align");
if (!text) return script_return_obj_null ();
if (script_obj_is_string (align_obj)) {
char *align_str = script_obj_as_string (align_obj);
label = ply_label_new ();
ply_label_set_text (label, text);
if (font)
ply_label_set_font (label, font);
ply_label_set_alignment(label, align);
ply_label_set_color (label, red, green, blue, alpha);
ply_label_show (label, NULL, 0, 0);
width = ply_label_get_width (label);
height = ply_label_get_height (label);
image = ply_pixel_buffer_new (width, height);
ply_label_draw_area (label, image, 0, 0, width, height);
free (text);
free (font);
ply_label_free (label);
return script_return_obj (script_obj_new_native (image, data->class));
if (!strcmp ("left", align_str))
align = PLY_LABEL_ALIGN_LEFT;
else if (!strcmp ("center", align_str))
align = PLY_LABEL_ALIGN_CENTER;
else if (!strcmp ("right", align_str))
align = PLY_LABEL_ALIGN_RIGHT;
else
ply_error ("Unrecognized Image.Text alignment string '%s'. "
"Expecting 'left', 'center', or 'right'\n",
align_str);
free (align_str);
}
script_obj_unref (align_obj);
if (!text) return script_return_obj_null ();
label = ply_label_new ();
ply_label_set_text (label, text);
if (font)
ply_label_set_font (label, font);
ply_label_set_alignment (label, align);
ply_label_set_color (label, red, green, blue, alpha);
ply_label_show (label, NULL, 0, 0);
width = ply_label_get_width (label);
height = ply_label_get_height (label);
image = ply_pixel_buffer_new (width, height);
ply_label_draw_area (label, image, 0, 0, width, height);
free (text);
free (font);
ply_label_free (label);
return script_return_obj (script_obj_new_native (image, data->class));
}
script_lib_image_data_t *script_lib_image_setup (script_state_t *state,
char *image_dir)
char *image_dir)
{
script_lib_image_data_t *data = malloc (sizeof (script_lib_image_data_t));
script_lib_image_data_t *data = malloc (sizeof(script_lib_image_data_t));
data->class = script_obj_native_class_new (image_free, "image", data);
data->image_dir = strdup (image_dir);
data->class = script_obj_native_class_new (image_free, "image", data);
data->image_dir = strdup (image_dir);
script_obj_t *image_hash = script_obj_hash_get_element (state->global, "Image");
script_add_native_function (image_hash,
"_New",
image_new,
data,
"filename",
NULL);
script_add_native_function (image_hash,
"_Rotate",
image_rotate,
data,
"angle",
NULL);
script_add_native_function (image_hash,
"_Scale",
image_scale,
data,
"width",
"height",
NULL);
script_add_native_function (image_hash,
"GetWidth",
image_get_width,
data,
NULL);
script_add_native_function (image_hash,
"GetHeight",
image_get_height,
data,
NULL);
script_add_native_function (image_hash,
"_Text",
image_text,
data,
"text",
"red",
"green",
"blue",
"alpha",
"font",
"align",
NULL);
script_obj_t *image_hash = script_obj_hash_get_element (state->global, "Image");
script_obj_unref (image_hash);
data->script_main_op = script_parse_string (script_lib_image_string, "script-lib-image.script");
script_return_t ret = script_execute (state, data->script_main_op);
script_obj_unref (ret.object);
return data;
script_add_native_function (image_hash,
"_New",
image_new,
data,
"filename",
NULL);
script_add_native_function (image_hash,
"_Rotate",
image_rotate,
data,
"angle",
NULL);
script_add_native_function (image_hash,
"_Scale",
image_scale,
data,
"width",
"height",
NULL);
script_add_native_function (image_hash,
"GetWidth",
image_get_width,
data,
NULL);
script_add_native_function (image_hash,
"GetHeight",
image_get_height,
data,
NULL);
script_add_native_function (image_hash,
"_Text",
image_text,
data,
"text",
"red",
"green",
"blue",
"alpha",
"font",
"align",
NULL);
script_obj_unref (image_hash);
data->script_main_op = script_parse_string (script_lib_image_string, "script-lib-image.script");
script_return_t ret = script_execute (state, data->script_main_op);
script_obj_unref (ret.object);
return data;
}
void script_lib_image_destroy (script_lib_image_data_t *data)
{
script_obj_native_class_destroy (data->class);
free (data->image_dir);
script_parse_op_free (data->script_main_op);
free (data);
script_obj_native_class_destroy (data->class);
free (data->image_dir);
script_parse_op_free (data->script_main_op);
free (data);
}

View file

@ -26,9 +26,9 @@
typedef struct
{
script_obj_native_class_t *class;
script_op_t *script_main_op;
char *image_dir;
script_obj_native_class_t *class;
script_op_t *script_main_op;
char *image_dir;
} script_lib_image_data_t;
script_lib_image_data_t *script_lib_image_setup (script_state_t *state,

View file

@ -40,90 +40,91 @@
static script_return_t script_lib_math_double_from_double_function (script_state_t *state,
void *user_data)
{
double (*function)(double) = user_data;
double value = script_obj_hash_get_number (state->local, "value");
double reply_double = function (value);
return script_return_obj (script_obj_new_number (reply_double));
double (*function)(double) = user_data;
double value = script_obj_hash_get_number (state->local, "value");
double reply_double = function (value);
return script_return_obj (script_obj_new_number (reply_double));
}
static script_return_t script_lib_math_double_from_double_double_function (script_state_t *state,
void *user_data)
{
double (*function)(double, double) = user_data;
double value1 = script_obj_hash_get_number (state->local, "value_a");
double value2 = script_obj_hash_get_number (state->local, "value_b");
double reply_double = function (value1, value2);
return script_return_obj (script_obj_new_number (reply_double));
double (*function)(double,
double) = user_data;
double value1 = script_obj_hash_get_number (state->local, "value_a");
double value2 = script_obj_hash_get_number (state->local, "value_b");
double reply_double = function (value1, value2);
return script_return_obj (script_obj_new_number (reply_double));
}
static script_return_t script_lib_math_random (script_state_t *state,
void *user_data)
{
double reply_double = random() / ((double)RAND_MAX + 1);
return script_return_obj (script_obj_new_number (reply_double));
double reply_double = random () / ((double) RAND_MAX + 1);
return script_return_obj (script_obj_new_number (reply_double));
}
script_lib_math_data_t *script_lib_math_setup (script_state_t *state)
{
script_lib_math_data_t *data = malloc (sizeof (script_lib_math_data_t));
script_lib_math_data_t *data = malloc (sizeof(script_lib_math_data_t));
srand ((int) ply_get_timestamp ());
srand ((int) ply_get_timestamp ());
script_obj_t *math_hash = script_obj_hash_get_element (state->global, "Math");
script_add_native_function (math_hash,
"Cos",
script_lib_math_double_from_double_function,
cos,
"value",
NULL);
script_add_native_function (math_hash,
"Sin",
script_lib_math_double_from_double_function,
sin,
"value",
NULL);
script_add_native_function (math_hash,
"Tan",
script_lib_math_double_from_double_function,
tan,
"value",
NULL);
script_add_native_function (math_hash,
"ATan2",
script_lib_math_double_from_double_double_function,
atan2,
"value_a",
"value_b",
NULL);
script_add_native_function (math_hash,
"Sqrt",
script_lib_math_double_from_double_function,
sqrt,
"value",
NULL);
script_add_native_function (math_hash,
"Int",
script_lib_math_double_from_double_function,
floor,
"value",
NULL);
script_add_native_function (math_hash,
"Random",
script_lib_math_random,
NULL,
NULL);
script_obj_unref (math_hash);
script_obj_t *math_hash = script_obj_hash_get_element (state->global, "Math");
script_add_native_function (math_hash,
"Cos",
script_lib_math_double_from_double_function,
cos,
"value",
NULL);
script_add_native_function (math_hash,
"Sin",
script_lib_math_double_from_double_function,
sin,
"value",
NULL);
script_add_native_function (math_hash,
"Tan",
script_lib_math_double_from_double_function,
tan,
"value",
NULL);
script_add_native_function (math_hash,
"ATan2",
script_lib_math_double_from_double_double_function,
atan2,
"value_a",
"value_b",
NULL);
script_add_native_function (math_hash,
"Sqrt",
script_lib_math_double_from_double_function,
sqrt,
"value",
NULL);
script_add_native_function (math_hash,
"Int",
script_lib_math_double_from_double_function,
floor,
"value",
NULL);
script_add_native_function (math_hash,
"Random",
script_lib_math_random,
NULL,
NULL);
script_obj_unref (math_hash);
data->script_main_op = script_parse_string (script_lib_math_string, "script-lib-math.script");
script_return_t ret = script_execute (state, data->script_main_op);
script_obj_unref (ret.object);
data->script_main_op = script_parse_string (script_lib_math_string, "script-lib-math.script");
script_return_t ret = script_execute (state, data->script_main_op);
script_obj_unref (ret.object);
return data;
return data;
}
void script_lib_math_destroy (script_lib_math_data_t *data)
{
script_parse_op_free (data->script_main_op);
free (data);
script_parse_op_free (data->script_main_op);
free (data);
}

View file

@ -26,7 +26,7 @@
typedef struct
{
script_op_t *script_main_op;
script_op_t *script_main_op;
} script_lib_math_data_t;
script_lib_math_data_t *script_lib_math_setup (script_state_t *state);

View file

@ -39,229 +39,235 @@
static script_return_t plymouth_set_function (script_state_t *state,
void *user_data)
{
script_obj_t **script_func = user_data;
script_obj_t *obj = script_obj_hash_get_element (state->local, "function");
script_obj_t **script_func = user_data;
script_obj_t *obj = script_obj_hash_get_element (state->local, "function");
script_obj_deref (&obj);
script_obj_unref (*script_func);
*script_func = obj;
return script_return_obj_null ();
script_obj_deref (&obj);
script_obj_unref (*script_func);
*script_func = obj;
return script_return_obj_null ();
}
static script_return_t plymouth_get_mode (script_state_t *state,
void *user_data)
{
script_lib_plymouth_data_t *data = user_data;
script_obj_t *obj;
switch (data->mode)
{
case PLY_BOOT_SPLASH_MODE_BOOT_UP:
obj = script_obj_new_string ("boot");
break;
case PLY_BOOT_SPLASH_MODE_SHUTDOWN:
obj = script_obj_new_string ("shutdown");
break;
case PLY_BOOT_SPLASH_MODE_UPDATES:
obj = script_obj_new_string ("updates");
break;
case PLY_BOOT_SPLASH_MODE_INVALID:
default:
obj = script_obj_new_string ("unknown");
break;
}
return script_return_obj (obj);
script_lib_plymouth_data_t *data = user_data;
script_obj_t *obj;
switch (data->mode) {
case PLY_BOOT_SPLASH_MODE_BOOT_UP:
obj = script_obj_new_string ("boot");
break;
case PLY_BOOT_SPLASH_MODE_SHUTDOWN:
obj = script_obj_new_string ("shutdown");
break;
case PLY_BOOT_SPLASH_MODE_UPDATES:
obj = script_obj_new_string ("updates");
break;
case PLY_BOOT_SPLASH_MODE_INVALID:
default:
obj = script_obj_new_string ("unknown");
break;
}
return script_return_obj (obj);
}
script_lib_plymouth_data_t *script_lib_plymouth_setup (script_state_t *state,
ply_boot_splash_mode_t mode)
script_lib_plymouth_data_t *script_lib_plymouth_setup (script_state_t *state,
ply_boot_splash_mode_t mode)
{
script_lib_plymouth_data_t *data = malloc (sizeof (script_lib_plymouth_data_t));
script_lib_plymouth_data_t *data = malloc (sizeof(script_lib_plymouth_data_t));
data->script_refresh_func = script_obj_new_null ();
data->script_boot_progress_func = script_obj_new_null ();
data->script_root_mounted_func = script_obj_new_null ();
data->script_keyboard_input_func = script_obj_new_null ();
data->script_update_status_func = script_obj_new_null ();
data->script_display_normal_func = script_obj_new_null ();
data->script_display_password_func = script_obj_new_null ();
data->script_display_question_func = script_obj_new_null ();
data->script_display_message_func = script_obj_new_null ();
data->script_hide_message_func = script_obj_new_null ();
data->script_quit_func = script_obj_new_null ();
data->mode = mode;
script_obj_t *plymouth_hash = script_obj_hash_get_element (state->global, "Plymouth");
script_add_native_function (plymouth_hash,
"SetRefreshFunction",
plymouth_set_function,
&data->script_refresh_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"SetBootProgressFunction",
plymouth_set_function,
&data->script_boot_progress_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"SetRootMountedFunction",
plymouth_set_function,
&data->script_root_mounted_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"SetKeyboardInputFunction",
plymouth_set_function,
&data->script_keyboard_input_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"SetUpdateStatusFunction",
plymouth_set_function,
&data->script_update_status_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"SetDisplayNormalFunction",
plymouth_set_function,
&data->script_display_normal_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"SetDisplayPasswordFunction",
plymouth_set_function,
&data->script_display_password_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"SetDisplayQuestionFunction",
plymouth_set_function,
&data->script_display_question_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"SetDisplayMessageFunction",
plymouth_set_function,
&data->script_display_message_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"SetHideMessageFunction",
plymouth_set_function,
&data->script_hide_message_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"SetQuitFunction",
plymouth_set_function,
&data->script_quit_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"GetMode",
plymouth_get_mode,
data,
NULL);
script_obj_unref (plymouth_hash);
data->script_refresh_func = script_obj_new_null ();
data->script_boot_progress_func = script_obj_new_null ();
data->script_root_mounted_func = script_obj_new_null ();
data->script_keyboard_input_func = script_obj_new_null ();
data->script_update_status_func = script_obj_new_null ();
data->script_display_normal_func = script_obj_new_null ();
data->script_display_password_func = script_obj_new_null ();
data->script_display_question_func = script_obj_new_null ();
data->script_display_message_func = script_obj_new_null ();
data->script_hide_message_func = script_obj_new_null ();
data->script_quit_func = script_obj_new_null ();
data->mode = mode;
data->script_main_op = script_parse_string (script_lib_plymouth_string, "script-lib-plymouth.script");
script_return_t ret = script_execute (state, data->script_main_op);
script_obj_unref (ret.object); /* Throw anything sent back away */
script_obj_t *plymouth_hash = script_obj_hash_get_element (state->global, "Plymouth");
script_add_native_function (plymouth_hash,
"SetRefreshFunction",
plymouth_set_function,
&data->script_refresh_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"SetBootProgressFunction",
plymouth_set_function,
&data->script_boot_progress_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"SetRootMountedFunction",
plymouth_set_function,
&data->script_root_mounted_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"SetKeyboardInputFunction",
plymouth_set_function,
&data->script_keyboard_input_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"SetUpdateStatusFunction",
plymouth_set_function,
&data->script_update_status_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"SetDisplayNormalFunction",
plymouth_set_function,
&data->script_display_normal_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"SetDisplayPasswordFunction",
plymouth_set_function,
&data->script_display_password_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"SetDisplayQuestionFunction",
plymouth_set_function,
&data->script_display_question_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"SetDisplayMessageFunction",
plymouth_set_function,
&data->script_display_message_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"SetHideMessageFunction",
plymouth_set_function,
&data->script_hide_message_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"SetQuitFunction",
plymouth_set_function,
&data->script_quit_func,
"function",
NULL);
script_add_native_function (plymouth_hash,
"GetMode",
plymouth_get_mode,
data,
NULL);
script_obj_unref (plymouth_hash);
return data;
data->script_main_op = script_parse_string (script_lib_plymouth_string, "script-lib-plymouth.script");
script_return_t ret = script_execute (state, data->script_main_op);
script_obj_unref (ret.object); /* Throw anything sent back away */
return data;
}
void script_lib_plymouth_destroy (script_lib_plymouth_data_t *data)
{
script_parse_op_free (data->script_main_op);
script_obj_unref (data->script_refresh_func);
script_obj_unref (data->script_boot_progress_func);
script_obj_unref (data->script_root_mounted_func);
script_obj_unref (data->script_keyboard_input_func);
script_obj_unref (data->script_update_status_func);
script_obj_unref (data->script_display_normal_func);
script_obj_unref (data->script_display_password_func);
script_obj_unref (data->script_display_question_func);
script_obj_unref (data->script_display_message_func);
script_obj_unref (data->script_hide_message_func);
script_obj_unref (data->script_quit_func);
free (data);
script_parse_op_free (data->script_main_op);
script_obj_unref (data->script_refresh_func);
script_obj_unref (data->script_boot_progress_func);
script_obj_unref (data->script_root_mounted_func);
script_obj_unref (data->script_keyboard_input_func);
script_obj_unref (data->script_update_status_func);
script_obj_unref (data->script_display_normal_func);
script_obj_unref (data->script_display_password_func);
script_obj_unref (data->script_display_question_func);
script_obj_unref (data->script_display_message_func);
script_obj_unref (data->script_hide_message_func);
script_obj_unref (data->script_quit_func);
free (data);
}
void script_lib_plymouth_on_refresh (script_state_t *state,
script_lib_plymouth_data_t *data)
{
script_return_t ret = script_execute_object (state,
data->script_refresh_func,
NULL,
NULL);
script_obj_unref (ret.object);
script_return_t ret = script_execute_object (state,
data->script_refresh_func,
NULL,
NULL);
script_obj_unref (ret.object);
}
void script_lib_plymouth_on_boot_progress (script_state_t *state,
script_lib_plymouth_data_t *data,
double duration,
double progress)
double duration,
double progress)
{
script_obj_t *duration_obj = script_obj_new_number (duration);
script_obj_t *progress_obj = script_obj_new_number (progress);
script_return_t ret = script_execute_object (state,
data->script_boot_progress_func,
NULL,
duration_obj,
progress_obj,
NULL);
script_obj_unref (ret.object);
script_obj_unref (duration_obj);
script_obj_unref (progress_obj);
script_obj_t *duration_obj = script_obj_new_number (duration);
script_obj_t *progress_obj = script_obj_new_number (progress);
script_return_t ret = script_execute_object (state,
data->script_boot_progress_func,
NULL,
duration_obj,
progress_obj,
NULL);
script_obj_unref (ret.object);
script_obj_unref (duration_obj);
script_obj_unref (progress_obj);
}
void script_lib_plymouth_on_root_mounted (script_state_t *state,
script_lib_plymouth_data_t *data)
{
script_return_t ret = script_execute_object (state,
data->script_root_mounted_func,
NULL,
NULL);
script_obj_unref (ret.object);
script_return_t ret = script_execute_object (state,
data->script_root_mounted_func,
NULL,
NULL);
script_obj_unref (ret.object);
}
void script_lib_plymouth_on_keyboard_input (script_state_t *state,
script_lib_plymouth_data_t *data,
const char *keyboard_input)
{
script_obj_t *keyboard_input_obj = script_obj_new_string (keyboard_input);
script_return_t ret = script_execute_object (state,
data->script_keyboard_input_func,
NULL,
keyboard_input_obj,
NULL);
script_obj_unref (keyboard_input_obj);
script_obj_unref (ret.object);
script_obj_t *keyboard_input_obj = script_obj_new_string (keyboard_input);
script_return_t ret = script_execute_object (state,
data->script_keyboard_input_func,
NULL,
keyboard_input_obj,
NULL);
script_obj_unref (keyboard_input_obj);
script_obj_unref (ret.object);
}
void script_lib_plymouth_on_update_status (script_state_t *state,
script_lib_plymouth_data_t *data,
const char *new_status)
{
script_obj_t *new_status_obj = script_obj_new_string (new_status);
script_return_t ret = script_execute_object (state,
data->script_update_status_func,
NULL,
new_status_obj,
NULL);
script_obj_unref (new_status_obj);
script_obj_unref (ret.object);
script_obj_t *new_status_obj = script_obj_new_string (new_status);
script_return_t ret = script_execute_object (state,
data->script_update_status_func,
NULL,
new_status_obj,
NULL);
script_obj_unref (new_status_obj);
script_obj_unref (ret.object);
}
void script_lib_plymouth_on_display_normal (script_state_t *state,
script_lib_plymouth_data_t *data)
{
script_return_t ret = script_execute_object (state,
data->script_display_normal_func,
NULL,
NULL);
script_obj_unref (ret.object);
script_return_t ret = script_execute_object (state,
data->script_display_normal_func,
NULL,
NULL);
script_obj_unref (ret.object);
}
void script_lib_plymouth_on_display_password (script_state_t *state,
@ -269,17 +275,18 @@ void script_lib_plymouth_on_display_password (script_state_t *state,
const char *prompt,
int bullets)
{
script_obj_t *prompt_obj = script_obj_new_string (prompt);
script_obj_t *bullets_obj = script_obj_new_number (bullets);
script_return_t ret = script_execute_object (state,
data->script_display_password_func,
NULL,
prompt_obj,
bullets_obj,
NULL);
script_obj_unref (prompt_obj);
script_obj_unref (bullets_obj);
script_obj_unref (ret.object);
script_obj_t *prompt_obj = script_obj_new_string (prompt);
script_obj_t *bullets_obj = script_obj_new_number (bullets);
script_return_t ret = script_execute_object (state,
data->script_display_password_func,
NULL,
prompt_obj,
bullets_obj,
NULL);
script_obj_unref (prompt_obj);
script_obj_unref (bullets_obj);
script_obj_unref (ret.object);
}
void script_lib_plymouth_on_display_question (script_state_t *state,
@ -287,53 +294,57 @@ void script_lib_plymouth_on_display_question (script_state_t *state,
const char *prompt,
const char *entry_text)
{
script_obj_t *prompt_obj = script_obj_new_string (prompt);
script_obj_t *entry_text_obj = script_obj_new_string (entry_text);
script_return_t ret = script_execute_object (state,
data->script_display_question_func,
NULL,
prompt_obj,
entry_text_obj,
NULL);
script_obj_unref (prompt_obj);
script_obj_unref (entry_text_obj);
script_obj_unref (ret.object);
script_obj_t *prompt_obj = script_obj_new_string (prompt);
script_obj_t *entry_text_obj = script_obj_new_string (entry_text);
script_return_t ret = script_execute_object (state,
data->script_display_question_func,
NULL,
prompt_obj,
entry_text_obj,
NULL);
script_obj_unref (prompt_obj);
script_obj_unref (entry_text_obj);
script_obj_unref (ret.object);
}
void script_lib_plymouth_on_display_message (script_state_t *state,
script_lib_plymouth_data_t *data,
const char *message)
{
script_obj_t *new_message_obj = script_obj_new_string (message);
script_return_t ret = script_execute_object (state,
data->script_display_message_func,
NULL,
new_message_obj,
NULL);
script_obj_unref (new_message_obj);
script_obj_unref (ret.object);
script_obj_t *new_message_obj = script_obj_new_string (message);
script_return_t ret = script_execute_object (state,
data->script_display_message_func,
NULL,
new_message_obj,
NULL);
script_obj_unref (new_message_obj);
script_obj_unref (ret.object);
}
void script_lib_plymouth_on_hide_message (script_state_t *state,
script_lib_plymouth_data_t *data,
const char *message)
{
script_obj_t *new_message_obj = script_obj_new_string (message);
script_return_t ret = script_execute_object (state,
data->script_hide_message_func,
NULL,
new_message_obj,
NULL);
script_obj_unref (new_message_obj);
script_obj_unref (ret.object);
script_obj_t *new_message_obj = script_obj_new_string (message);
script_return_t ret = script_execute_object (state,
data->script_hide_message_func,
NULL,
new_message_obj,
NULL);
script_obj_unref (new_message_obj);
script_obj_unref (ret.object);
}
void script_lib_plymouth_on_quit (script_state_t *state,
script_lib_plymouth_data_t *data)
{
script_return_t ret = script_execute_object (state,
data->script_quit_func,
NULL,
NULL);
script_obj_unref (ret.object);
script_return_t ret = script_execute_object (state,
data->script_quit_func,
NULL,
NULL);
script_obj_unref (ret.object);
}

View file

@ -27,31 +27,31 @@
typedef struct
{
script_op_t *script_main_op;
script_obj_t *script_refresh_func;
script_obj_t *script_boot_progress_func;
script_obj_t *script_root_mounted_func;
script_obj_t *script_keyboard_input_func;
script_obj_t *script_update_status_func;
script_obj_t *script_display_normal_func;
script_obj_t *script_display_password_func;
script_obj_t *script_display_question_func;
script_obj_t *script_display_message_func;
script_obj_t *script_hide_message_func;
script_obj_t *script_quit_func;
ply_boot_splash_mode_t mode;
script_op_t *script_main_op;
script_obj_t *script_refresh_func;
script_obj_t *script_boot_progress_func;
script_obj_t *script_root_mounted_func;
script_obj_t *script_keyboard_input_func;
script_obj_t *script_update_status_func;
script_obj_t *script_display_normal_func;
script_obj_t *script_display_password_func;
script_obj_t *script_display_question_func;
script_obj_t *script_display_message_func;
script_obj_t *script_hide_message_func;
script_obj_t *script_quit_func;
ply_boot_splash_mode_t mode;
} script_lib_plymouth_data_t;
script_lib_plymouth_data_t *script_lib_plymouth_setup (script_state_t *state,
ply_boot_splash_mode_t mode);
script_lib_plymouth_data_t *script_lib_plymouth_setup (script_state_t *state,
ply_boot_splash_mode_t mode);
void script_lib_plymouth_destroy (script_lib_plymouth_data_t *data);
void script_lib_plymouth_on_refresh (script_state_t *state,
script_lib_plymouth_data_t *data);
void script_lib_plymouth_on_boot_progress (script_state_t *state,
script_lib_plymouth_data_t *data,
double duration,
double progress);
double duration,
double progress);
void script_lib_plymouth_on_root_mounted (script_state_t *state,
script_lib_plymouth_data_t *data);
void script_lib_plymouth_on_keyboard_input (script_state_t *state,

File diff suppressed because it is too large Load diff

View file

@ -28,39 +28,39 @@
typedef struct
{
ply_list_t *displays;
ply_list_t *sprite_list;
script_obj_native_class_t *class;
script_op_t *script_main_op;
uint32_t background_color_start;
uint32_t background_color_end;
bool full_refresh;
ply_list_t *displays;
ply_list_t *sprite_list;
script_obj_native_class_t *class;
script_op_t *script_main_op;
uint32_t background_color_start;
uint32_t background_color_end;
bool full_refresh;
} script_lib_sprite_data_t;
typedef struct
{
ply_pixel_display_t *pixel_display;
script_lib_sprite_data_t *data;
int x;
int y;
ply_pixel_display_t *pixel_display;
script_lib_sprite_data_t *data;
int x;
int y;
} script_lib_display_t;
typedef struct
{
int x;
int y;
int z;
double opacity;
int old_x;
int old_y;
int old_z;
int old_width;
int old_height;
double old_opacity;
bool refresh_me;
bool remove_me;
ply_pixel_buffer_t *image;
script_obj_t *image_obj;
int x;
int y;
int z;
double opacity;
int old_x;
int old_y;
int old_z;
int old_width;
int old_height;
double old_opacity;
bool refresh_me;
bool remove_me;
ply_pixel_buffer_t *image;
script_obj_t *image_obj;
} sprite_t;
script_lib_sprite_data_t *script_lib_sprite_setup (script_state_t *state,

View file

@ -39,91 +39,85 @@
static script_return_t script_lib_string_char_at (script_state_t *state,
void *user_data)
{
char *text = script_obj_as_string (state->this);
int index = script_obj_hash_get_number (state->local, "index");
int count;
char charstring [2];
if (!text || index < 0)
{
free (text);
return script_return_obj_null ();
}
for (count = 0; count < index; count++)
{
if (text[count] == '\0')
{
free (text);
return script_return_obj(script_obj_new_string (""));
char *text = script_obj_as_string (state->this);
int index = script_obj_hash_get_number (state->local, "index");
int count;
char charstring [2];
if (!text || index < 0) {
free (text);
return script_return_obj_null ();
}
}
charstring[0] = text[index];
charstring[1] = '\0';
free (text);
return script_return_obj(script_obj_new_string (charstring));
for (count = 0; count < index; count++) {
if (text[count] == '\0') {
free (text);
return script_return_obj (script_obj_new_string (""));
}
}
charstring[0] = text[index];
charstring[1] = '\0';
free (text);
return script_return_obj (script_obj_new_string (charstring));
}
static script_return_t script_lib_string_sub_string (script_state_t *state,
void *user_data)
{
char *text = script_obj_as_string (state->this);
int start = script_obj_hash_get_number (state->local, "start");
int end = script_obj_hash_get_number (state->local, "end");
int text_count;
char* substring;
script_obj_t *substring_obj;
char *text = script_obj_as_string (state->this);
int start = script_obj_hash_get_number (state->local, "start");
int end = script_obj_hash_get_number (state->local, "end");
int text_count;
char *substring;
script_obj_t *substring_obj;
if (!text || start < 0 || end < start)
{
free (text);
return script_return_obj_null ();
}
for (text_count = 0; text_count < start; text_count++)
{
if (text[text_count] == '\0')
{
free (text);
return script_return_obj(script_obj_new_string (""));
if (!text || start < 0 || end < start) {
free (text);
return script_return_obj_null ();
}
}
substring = strndup(&text[text_count], end - start);
substring_obj = script_obj_new_string (substring);
free (substring);
free (text);
return script_return_obj(substring_obj);
for (text_count = 0; text_count < start; text_count++) {
if (text[text_count] == '\0') {
free (text);
return script_return_obj (script_obj_new_string (""));
}
}
substring = strndup (&text[text_count], end - start);
substring_obj = script_obj_new_string (substring);
free (substring);
free (text);
return script_return_obj (substring_obj);
}
script_lib_string_data_t *script_lib_string_setup (script_state_t *state)
{
script_lib_string_data_t *data = malloc (sizeof (script_lib_string_data_t));
script_lib_string_data_t *data = malloc (sizeof(script_lib_string_data_t));
script_obj_t *string_hash = script_obj_hash_get_element (state->global, "String");
script_add_native_function (string_hash,
"CharAt",
script_lib_string_char_at,
NULL,
"index",
NULL);
script_add_native_function (string_hash,
"SubString",
script_lib_string_sub_string,
NULL,
"start",
"end",
NULL);
script_obj_unref (string_hash);
data->script_main_op = script_parse_string (script_lib_string_string, "script-lib-string.script");
script_return_t ret = script_execute (state, data->script_main_op);
script_obj_unref (ret.object);
script_obj_t *string_hash = script_obj_hash_get_element (state->global, "String");
return data;
script_add_native_function (string_hash,
"CharAt",
script_lib_string_char_at,
NULL,
"index",
NULL);
script_add_native_function (string_hash,
"SubString",
script_lib_string_sub_string,
NULL,
"start",
"end",
NULL);
script_obj_unref (string_hash);
data->script_main_op = script_parse_string (script_lib_string_string, "script-lib-string.script");
script_return_t ret = script_execute (state, data->script_main_op);
script_obj_unref (ret.object);
return data;
}
void script_lib_string_destroy (script_lib_string_data_t *data)
{
script_parse_op_free (data->script_main_op);
free (data);
script_parse_op_free (data->script_main_op);
free (data);
}

View file

@ -26,7 +26,7 @@
typedef struct
{
script_op_t *script_main_op;
script_op_t *script_main_op;
} script_lib_string_data_t;
script_lib_string_data_t *script_lib_string_setup (script_state_t *state);

View file

@ -44,583 +44,570 @@ void script_obj_reset (script_obj_t *obj);
void script_obj_free (script_obj_t *obj)
{
assert (!obj->refcount);
script_obj_reset (obj);
free (obj);
assert (!obj->refcount);
script_obj_reset (obj);
free (obj);
}
void script_obj_ref (script_obj_t *obj)
{
obj->refcount++;
obj->refcount++;
}
void script_obj_unref (script_obj_t *obj)
{
if (!obj) return;
assert (obj->refcount > 0);
obj->refcount--;
if (obj->refcount <= 0)
script_obj_free (obj);
if (!obj) return;
assert (obj->refcount > 0);
obj->refcount--;
if (obj->refcount <= 0)
script_obj_free (obj);
}
static void foreach_free_variable (void *key,
void *data,
void *user_data)
{
script_variable_t *variable = data;
script_variable_t *variable = data;
script_obj_unref (variable->object);
free (variable->name);
free (variable);
script_obj_unref (variable->object);
free (variable->name);
free (variable);
}
void script_obj_reset (script_obj_t *obj)
{
switch (obj->type)
{
case SCRIPT_OBJ_TYPE_REF:
script_obj_unref (obj->data.obj);
break;
switch (obj->type) {
case SCRIPT_OBJ_TYPE_REF:
script_obj_unref (obj->data.obj);
break;
case SCRIPT_OBJ_TYPE_EXTEND:
script_obj_unref (obj->data.dual_obj.obj_a);
script_obj_unref (obj->data.dual_obj.obj_b);
break;
case SCRIPT_OBJ_TYPE_EXTEND:
script_obj_unref (obj->data.dual_obj.obj_a);
script_obj_unref (obj->data.dual_obj.obj_b);
break;
case SCRIPT_OBJ_TYPE_NUMBER:
break;
case SCRIPT_OBJ_TYPE_NUMBER:
break;
case SCRIPT_OBJ_TYPE_STRING:
free (obj->data.string);
break;
case SCRIPT_OBJ_TYPE_STRING:
free (obj->data.string);
break;
case SCRIPT_OBJ_TYPE_HASH: /* FIXME nightmare */
ply_hashtable_foreach (obj->data.hash, foreach_free_variable, NULL);
ply_hashtable_free (obj->data.hash);
break;
case SCRIPT_OBJ_TYPE_HASH: /* FIXME nightmare */
ply_hashtable_foreach (obj->data.hash, foreach_free_variable, NULL);
ply_hashtable_free (obj->data.hash);
break;
case SCRIPT_OBJ_TYPE_FUNCTION:
case SCRIPT_OBJ_TYPE_FUNCTION:
{
if (obj->data.function->freeable)
{
ply_list_node_t *node;
for (node =
ply_list_get_first_node (obj->data.function->parameters);
node;
node =
ply_list_get_next_node (obj->data.function->parameters,
node))
{
char *operand = ply_list_node_get_data (node);
free (operand);
if (obj->data.function->freeable) {
ply_list_node_t *node;
for (node =
ply_list_get_first_node (obj->data.function->parameters);
node;
node =
ply_list_get_next_node (obj->data.function->parameters,
node)) {
char *operand = ply_list_node_get_data (node);
free (operand);
}
ply_list_free (obj->data.function->parameters);
free (obj->data.function);
}
ply_list_free (obj->data.function->parameters);
free (obj->data.function);
}
}
break;
case SCRIPT_OBJ_TYPE_NATIVE:
if (obj->data.native.class->free_func)
obj->data.native.class->free_func (obj);
break;
case SCRIPT_OBJ_TYPE_NATIVE:
if (obj->data.native.class->free_func)
obj->data.native.class->free_func (obj);
break;
case SCRIPT_OBJ_TYPE_NULL:
break;
}
obj->type = SCRIPT_OBJ_TYPE_NULL;
case SCRIPT_OBJ_TYPE_NULL:
break;
}
obj->type = SCRIPT_OBJ_TYPE_NULL;
}
script_obj_t *script_obj_deref_direct (script_obj_t *obj)
{
while (obj->type == SCRIPT_OBJ_TYPE_REF)
obj = obj->data.obj;
return obj;
while (obj->type == SCRIPT_OBJ_TYPE_REF) {
obj = obj->data.obj;
}
return obj;
}
void script_obj_deref (script_obj_t **obj_ptr)
{
script_obj_t *obj = *obj_ptr;
script_obj_t *obj = *obj_ptr;
obj = script_obj_deref_direct (obj);
script_obj_ref (obj);
script_obj_unref (*obj_ptr);
*obj_ptr = obj;
obj = script_obj_deref_direct (obj);
script_obj_ref (obj);
script_obj_unref (*obj_ptr);
*obj_ptr = obj;
}
script_obj_t *script_obj_new_null (void)
{
script_obj_t *obj = malloc (sizeof (script_obj_t));
script_obj_t *obj = malloc (sizeof(script_obj_t));
obj->type = SCRIPT_OBJ_TYPE_NULL;
obj->refcount = 1;
return obj;
obj->type = SCRIPT_OBJ_TYPE_NULL;
obj->refcount = 1;
return obj;
}
script_obj_t *script_obj_new_number (script_number_t number)
{
script_obj_t *obj = malloc (sizeof (script_obj_t));
obj->type = SCRIPT_OBJ_TYPE_NUMBER;
obj->refcount = 1;
obj->data.number = number;
return obj;
script_obj_t *obj = malloc (sizeof(script_obj_t));
obj->type = SCRIPT_OBJ_TYPE_NUMBER;
obj->refcount = 1;
obj->data.number = number;
return obj;
}
script_obj_t *script_obj_new_string (const char *string)
{
if (!string) return script_obj_new_null ();
script_obj_t *obj = malloc (sizeof (script_obj_t));
obj->type = SCRIPT_OBJ_TYPE_STRING;
obj->refcount = 1;
obj->data.string = strdup (string);
return obj;
if (!string) return script_obj_new_null ();
script_obj_t *obj = malloc (sizeof(script_obj_t));
obj->type = SCRIPT_OBJ_TYPE_STRING;
obj->refcount = 1;
obj->data.string = strdup (string);
return obj;
}
script_obj_t *script_obj_new_hash (void)
{
script_obj_t *obj = malloc (sizeof (script_obj_t));
script_obj_t *obj = malloc (sizeof(script_obj_t));
obj->type = SCRIPT_OBJ_TYPE_HASH;
obj->data.hash = ply_hashtable_new (ply_hashtable_string_hash,
ply_hashtable_string_compare);
obj->refcount = 1;
return obj;
obj->type = SCRIPT_OBJ_TYPE_HASH;
obj->data.hash = ply_hashtable_new (ply_hashtable_string_hash,
ply_hashtable_string_compare);
obj->refcount = 1;
return obj;
}
script_obj_t *script_obj_new_function (script_function_t *function)
{
script_obj_t *obj = malloc (sizeof (script_obj_t));
script_obj_t *obj = malloc (sizeof(script_obj_t));
obj->type = SCRIPT_OBJ_TYPE_FUNCTION;
obj->data.function = function;
obj->refcount = 1;
return obj;
obj->type = SCRIPT_OBJ_TYPE_FUNCTION;
obj->data.function = function;
obj->refcount = 1;
return obj;
}
script_obj_t *script_obj_new_ref (script_obj_t *sub_obj)
{
script_obj_t *obj = malloc (sizeof (script_obj_t));
sub_obj = script_obj_deref_direct (sub_obj);
script_obj_ref (sub_obj);
obj->type = SCRIPT_OBJ_TYPE_REF;
obj->data.obj = sub_obj;
obj->refcount = 1;
return obj;
script_obj_t *obj = malloc (sizeof(script_obj_t));
sub_obj = script_obj_deref_direct (sub_obj);
script_obj_ref (sub_obj);
obj->type = SCRIPT_OBJ_TYPE_REF;
obj->data.obj = sub_obj;
obj->refcount = 1;
return obj;
}
script_obj_t *script_obj_new_extend (script_obj_t *obj_a, script_obj_t *obj_b)
{
script_obj_t *obj = malloc (sizeof (script_obj_t));
obj_a = script_obj_deref_direct (obj_a);
obj_b = script_obj_deref_direct (obj_b);
script_obj_ref (obj_a);
script_obj_ref (obj_b);
obj->type = SCRIPT_OBJ_TYPE_EXTEND;
obj->data.dual_obj.obj_a = obj_a;
obj->data.dual_obj.obj_b = obj_b;
obj->refcount = 1;
return obj;
script_obj_t *obj = malloc (sizeof(script_obj_t));
obj_a = script_obj_deref_direct (obj_a);
obj_b = script_obj_deref_direct (obj_b);
script_obj_ref (obj_a);
script_obj_ref (obj_b);
obj->type = SCRIPT_OBJ_TYPE_EXTEND;
obj->data.dual_obj.obj_a = obj_a;
obj->data.dual_obj.obj_b = obj_b;
obj->refcount = 1;
return obj;
}
script_obj_t *script_obj_new_native (void *object_data,
script_obj_native_class_t *class)
{
if (!object_data) return script_obj_new_null ();
script_obj_t *obj = malloc (sizeof (script_obj_t));
obj->type = SCRIPT_OBJ_TYPE_NATIVE;
obj->data.native.class = class;
obj->data.native.object_data = object_data;
obj->refcount = 1;
return obj;
if (!object_data) return script_obj_new_null ();
script_obj_t *obj = malloc (sizeof(script_obj_t));
obj->type = SCRIPT_OBJ_TYPE_NATIVE;
obj->data.native.class = class;
obj->data.native.object_data = object_data;
obj->refcount = 1;
return obj;
}
void *script_obj_as_custom (script_obj_t *obj,
script_obj_direct_func_t user_func,
void *user_data)
void *script_obj_as_custom (script_obj_t *obj,
script_obj_direct_func_t user_func,
void *user_data)
{
obj = script_obj_deref_direct (obj);
void *reply = user_func(obj, user_data);
if (reply) return reply;
if (obj->type == SCRIPT_OBJ_TYPE_EXTEND)
{
reply = script_obj_as_custom(obj->data.dual_obj.obj_a, user_func, user_data);
if (reply) return reply;
reply = script_obj_as_custom(obj->data.dual_obj.obj_b, user_func, user_data);
if (reply) return reply;
}
return NULL;
obj = script_obj_deref_direct (obj);
void *reply = user_func (obj, user_data);
if (reply) return reply;
if (obj->type == SCRIPT_OBJ_TYPE_EXTEND) {
reply = script_obj_as_custom (obj->data.dual_obj.obj_a, user_func, user_data);
if (reply) return reply;
reply = script_obj_as_custom (obj->data.dual_obj.obj_b, user_func, user_data);
if (reply) return reply;
}
return NULL;
}
script_obj_t *script_obj_as_obj_type (script_obj_t *obj,
script_obj_type_t type)
script_obj_t *script_obj_as_obj_type (script_obj_t *obj,
script_obj_type_t type)
{
obj = script_obj_deref_direct (obj);
if (obj->type == type) return obj;
if (obj->type == SCRIPT_OBJ_TYPE_EXTEND)
{
script_obj_t *reply;
reply = script_obj_as_obj_type(obj->data.dual_obj.obj_a, type);
if (reply) return reply;
reply = script_obj_as_obj_type(obj->data.dual_obj.obj_b, type);
if (reply) return reply;
}
return NULL;
obj = script_obj_deref_direct (obj);
if (obj->type == type) return obj;
if (obj->type == SCRIPT_OBJ_TYPE_EXTEND) {
script_obj_t *reply;
reply = script_obj_as_obj_type (obj->data.dual_obj.obj_a, type);
if (reply) return reply;
reply = script_obj_as_obj_type (obj->data.dual_obj.obj_b, type);
if (reply) return reply;
}
return NULL;
}
script_number_t script_obj_as_number (script_obj_t *obj)
{ /* If in then reply contents, otherwise reply NAN */
obj = script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_NUMBER);
if (obj) return obj->data.number;
return NAN;
obj = script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_NUMBER);
if (obj) return obj->data.number;
return NAN;
}
static void *script_obj_direct_as_bool (script_obj_t *obj,
void *user_data)
{ /* False objects are NULL, 0, NAN, "" */
switch (obj->type)
{
case SCRIPT_OBJ_TYPE_NUMBER:
switch (obj->type) {
case SCRIPT_OBJ_TYPE_NUMBER:
{
int num_type = fpclassify(obj->data.number);
if (num_type == FP_ZERO || num_type == FP_NAN) return NULL;
return obj;
int num_type = fpclassify (obj->data.number);
if (num_type == FP_ZERO || num_type == FP_NAN) return NULL;
return obj;
}
case SCRIPT_OBJ_TYPE_NULL:
case SCRIPT_OBJ_TYPE_REF:
case SCRIPT_OBJ_TYPE_EXTEND:
return NULL;
case SCRIPT_OBJ_TYPE_HASH:
case SCRIPT_OBJ_TYPE_FUNCTION:
case SCRIPT_OBJ_TYPE_NATIVE:
return obj;
case SCRIPT_OBJ_TYPE_STRING:
if (*obj->data.string) return obj;
return NULL;
}
case SCRIPT_OBJ_TYPE_NULL:
case SCRIPT_OBJ_TYPE_REF:
case SCRIPT_OBJ_TYPE_EXTEND:
return NULL;
case SCRIPT_OBJ_TYPE_HASH:
case SCRIPT_OBJ_TYPE_FUNCTION:
case SCRIPT_OBJ_TYPE_NATIVE:
return obj;
case SCRIPT_OBJ_TYPE_STRING:
if (*obj->data.string) return obj;
return NULL;
}
return NULL;
}
bool script_obj_as_bool (script_obj_t *obj)
{
return script_obj_as_custom(obj, script_obj_direct_as_bool, NULL);
return script_obj_as_custom (obj, script_obj_direct_as_bool, NULL);
}
char *script_obj_as_string (script_obj_t *obj) /* reply is strdupped and may be NULL */
{
char *reply;
script_obj_t *string_obj = script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_STRING);
if (string_obj) return strdup (string_obj->data.string);
string_obj = script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_NUMBER);
if (string_obj)
{
asprintf (&reply, "%g", string_obj->data.number);
char *reply;
script_obj_t *string_obj = script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_STRING);
if (string_obj) return strdup (string_obj->data.string);
string_obj = script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_NUMBER);
if (string_obj) {
asprintf (&reply, "%g", string_obj->data.number);
return reply;
}
if (script_obj_is_null (obj))
return strdup ("#NULL");
asprintf (&reply, "#(0x%p)", obj);
return reply;
}
if (script_obj_is_null (obj))
return strdup("#NULL");
asprintf (&reply, "#(0x%p)", obj);
return reply;
}
static void *script_obj_direct_as_native_of_class (script_obj_t *obj,
void *user_data)
{
script_obj_native_class_t *class = user_data;
if (obj->type == SCRIPT_OBJ_TYPE_NATIVE && obj->data.native.class == class)
return obj->data.native.object_data;
return NULL;
script_obj_native_class_t *class = user_data;
if (obj->type == SCRIPT_OBJ_TYPE_NATIVE && obj->data.native.class == class)
return obj->data.native.object_data;
return NULL;
}
void *script_obj_as_native_of_class (script_obj_t *obj,
script_obj_native_class_t *class)
{
return script_obj_as_custom(obj, script_obj_direct_as_native_of_class, class);
return script_obj_as_custom (obj, script_obj_direct_as_native_of_class, class);
}
static void *script_obj_direct_as_native_of_class_name (script_obj_t *obj,
void *user_data)
{
const char *class_name = user_data;
if (obj->type == SCRIPT_OBJ_TYPE_NATIVE &&
!strcmp (obj->data.native.class->name, class_name))
return obj->data.native.object_data;
return NULL;
const char *class_name = user_data;
if (obj->type == SCRIPT_OBJ_TYPE_NATIVE &&
!strcmp (obj->data.native.class->name, class_name))
return obj->data.native.object_data;
return NULL;
}
void *script_obj_as_native_of_class_name (script_obj_t *obj,
const char *class_name)
{
return script_obj_as_custom(obj,
script_obj_direct_as_native_of_class_name,
(void*) class_name);
return script_obj_as_custom (obj,
script_obj_direct_as_native_of_class_name,
(void *) class_name);
}
bool script_obj_is_null (script_obj_t *obj)
{
return script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_NULL);
return script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_NULL);
}
bool script_obj_is_number (script_obj_t *obj)
{
return script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_NUMBER);
return script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_NUMBER);
}
bool script_obj_is_string (script_obj_t *obj)
{
return script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_STRING);
return script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_STRING);
}
bool script_obj_is_hash (script_obj_t *obj)
{
return script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_HASH);
return script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_HASH);
}
bool script_obj_is_native (script_obj_t *obj)
{
return script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_NATIVE);
return script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_NATIVE);
}
bool script_obj_is_native_of_class (script_obj_t *obj,
script_obj_native_class_t *class)
{
return script_obj_as_custom(obj,
script_obj_direct_as_native_of_class,
class);
return script_obj_as_custom (obj,
script_obj_direct_as_native_of_class,
class);
}
bool script_obj_is_native_of_class_name (script_obj_t *obj,
const char *class_name)
{
return script_obj_as_custom(obj,
script_obj_direct_as_native_of_class_name,
(void*)class_name);
return script_obj_as_custom (obj,
script_obj_direct_as_native_of_class_name,
(void *) class_name);
}
void script_obj_assign (script_obj_t *obj_a,
script_obj_t *obj_b)
{
obj_b = script_obj_deref_direct (obj_b);
script_obj_ref (obj_b);
script_obj_reset (obj_a);
obj_a->type = SCRIPT_OBJ_TYPE_REF;
obj_a->data.obj = obj_b;
obj_b = script_obj_deref_direct (obj_b);
script_obj_ref (obj_b);
script_obj_reset (obj_a);
obj_a->type = SCRIPT_OBJ_TYPE_REF;
obj_a->data.obj = obj_b;
}
static void *script_obj_direct_as_hash_element (script_obj_t *obj,
void *user_data)
{
const char *name = user_data;
if (obj->type == SCRIPT_OBJ_TYPE_HASH)
{
script_variable_t *variable = ply_hashtable_lookup (obj->data.hash, (void *) name);
if (variable)
return variable->object;
}
return NULL;
const char *name = user_data;
if (obj->type == SCRIPT_OBJ_TYPE_HASH) {
script_variable_t *variable = ply_hashtable_lookup (obj->data.hash, (void *) name);
if (variable)
return variable->object;
}
return NULL;
}
script_obj_t *script_obj_hash_peek_element (script_obj_t *hash,
const char *name)
{
script_obj_t *object;
if (!name) return script_obj_new_null ();
object = script_obj_as_custom(hash,
script_obj_direct_as_hash_element,
(void*) name);
if (object) script_obj_ref (object);
return object;
script_obj_t *object;
if (!name) return script_obj_new_null ();
object = script_obj_as_custom (hash,
script_obj_direct_as_hash_element,
(void *) name);
if (object) script_obj_ref (object);
return object;
}
script_obj_t *script_obj_hash_get_element (script_obj_t *hash,
const char *name)
{
script_obj_t *obj = script_obj_hash_peek_element (hash, name);
if (obj) return obj;
script_obj_t *realhash = script_obj_as_obj_type (hash, SCRIPT_OBJ_TYPE_HASH);
if (!realhash)
{
realhash = script_obj_new_hash(); /* If it wasn't a hash then make it into one */
script_obj_assign (hash, realhash);
}
script_variable_t *variable = malloc (sizeof (script_variable_t));
variable->name = strdup (name);
variable->object = script_obj_new_null ();
ply_hashtable_insert (realhash->data.hash, variable->name, variable);
script_obj_ref (variable->object);
return variable->object;
script_obj_t *obj = script_obj_hash_peek_element (hash, name);
if (obj) return obj;
script_obj_t *realhash = script_obj_as_obj_type (hash, SCRIPT_OBJ_TYPE_HASH);
if (!realhash) {
realhash = script_obj_new_hash (); /* If it wasn't a hash then make it into one */
script_obj_assign (hash, realhash);
}
script_variable_t *variable = malloc (sizeof(script_variable_t));
variable->name = strdup (name);
variable->object = script_obj_new_null ();
ply_hashtable_insert (realhash->data.hash, variable->name, variable);
script_obj_ref (variable->object);
return variable->object;
}
script_number_t script_obj_hash_get_number (script_obj_t *hash,
const char *name)
{
script_obj_t *obj = script_obj_hash_get_element (hash, name);
script_number_t reply = script_obj_as_number (obj);
script_obj_t *obj = script_obj_hash_get_element (hash, name);
script_number_t reply = script_obj_as_number (obj);
script_obj_unref (obj);
return reply;
script_obj_unref (obj);
return reply;
}
bool script_obj_hash_get_bool (script_obj_t *hash,
const char *name)
{
script_obj_t *obj = script_obj_hash_get_element (hash, name);
bool reply = script_obj_as_bool (obj);
script_obj_t *obj = script_obj_hash_get_element (hash, name);
bool reply = script_obj_as_bool (obj);
script_obj_unref (obj);
return reply;
script_obj_unref (obj);
return reply;
}
char *script_obj_hash_get_string (script_obj_t *hash,
const char *name)
{
script_obj_t *obj = script_obj_hash_get_element (hash, name);
char *reply = script_obj_as_string (obj);
script_obj_t *obj = script_obj_hash_get_element (hash, name);
char *reply = script_obj_as_string (obj);
script_obj_unref (obj);
return reply;
script_obj_unref (obj);
return reply;
}
void *script_obj_hash_get_native_of_class (script_obj_t *hash,
const char *name,
script_obj_native_class_t *class)
{
script_obj_t *obj = script_obj_hash_get_element (hash, name);
void *reply = script_obj_as_native_of_class (obj, class);
script_obj_t *obj = script_obj_hash_get_element (hash, name);
void *reply = script_obj_as_native_of_class (obj, class);
script_obj_unref (obj);
return reply;
script_obj_unref (obj);
return reply;
}
void *script_obj_hash_get_native_of_class_name (script_obj_t *hash,
const char *name,
const char *class_name)
{
script_obj_t *obj = script_obj_hash_get_element (hash, name);
void *reply = script_obj_as_native_of_class_name (obj, class_name);
script_obj_t *obj = script_obj_hash_get_element (hash, name);
void *reply = script_obj_as_native_of_class_name (obj, class_name);
script_obj_unref (obj);
return reply;
script_obj_unref (obj);
return reply;
}
void script_obj_hash_add_element (script_obj_t *hash,
script_obj_t *element,
const char *name)
{
script_obj_t *obj = script_obj_hash_get_element (hash, name);
script_obj_assign (obj, element);
script_obj_unref (obj);
script_obj_t *obj = script_obj_hash_get_element (hash, name);
script_obj_assign (obj, element);
script_obj_unref (obj);
}
script_obj_t *script_obj_plus (script_obj_t *script_obj_a,
script_obj_t *script_obj_b)
{
if (script_obj_is_number (script_obj_a) && script_obj_is_number (script_obj_b))
{
script_number_t value = script_obj_as_number (script_obj_a) + script_obj_as_number (script_obj_b);
return script_obj_new_number (value);
}
if (script_obj_is_string (script_obj_a) || script_obj_is_string (script_obj_b))
{
script_obj_t *obj;
char *string_a = script_obj_as_string (script_obj_a);
char *string_b = script_obj_as_string (script_obj_b);
if (string_a && string_b)
{
char *newstring;
asprintf (&newstring, "%s%s", string_a, string_b);
obj = script_obj_new_string (newstring);
free (newstring);
if (script_obj_is_number (script_obj_a) && script_obj_is_number (script_obj_b)) {
script_number_t value = script_obj_as_number (script_obj_a) + script_obj_as_number (script_obj_b);
return script_obj_new_number (value);
}
else
obj = script_obj_new_null ();
free (string_a);
free (string_b);
return obj;
}
return script_obj_new_null ();
if (script_obj_is_string (script_obj_a) || script_obj_is_string (script_obj_b)) {
script_obj_t *obj;
char *string_a = script_obj_as_string (script_obj_a);
char *string_b = script_obj_as_string (script_obj_b);
if (string_a && string_b) {
char *newstring;
asprintf (&newstring, "%s%s", string_a, string_b);
obj = script_obj_new_string (newstring);
free (newstring);
} else {
obj = script_obj_new_null ();
}
free (string_a);
free (string_b);
return obj;
}
return script_obj_new_null ();
}
script_obj_t *script_obj_minus (script_obj_t *script_obj_a,
script_obj_t *script_obj_b)
{
if (script_obj_is_number (script_obj_a) && script_obj_is_number (script_obj_b))
{
script_number_t value = script_obj_as_number (script_obj_a) - script_obj_as_number (script_obj_b);
return script_obj_new_number (value);
}
return script_obj_new_null ();
if (script_obj_is_number (script_obj_a) && script_obj_is_number (script_obj_b)) {
script_number_t value = script_obj_as_number (script_obj_a) - script_obj_as_number (script_obj_b);
return script_obj_new_number (value);
}
return script_obj_new_null ();
}
script_obj_t *script_obj_mul (script_obj_t *script_obj_a,
script_obj_t *script_obj_b)
{
if (script_obj_is_number (script_obj_a) && script_obj_is_number (script_obj_b))
{
script_number_t value = script_obj_as_number (script_obj_a) * script_obj_as_number (script_obj_b);
return script_obj_new_number (value);
}
return script_obj_new_null ();
if (script_obj_is_number (script_obj_a) && script_obj_is_number (script_obj_b)) {
script_number_t value = script_obj_as_number (script_obj_a) * script_obj_as_number (script_obj_b);
return script_obj_new_number (value);
}
return script_obj_new_null ();
}
script_obj_t *script_obj_div (script_obj_t *script_obj_a,
script_obj_t *script_obj_b)
{
if (script_obj_is_number (script_obj_a) && script_obj_is_number (script_obj_b))
{
script_number_t value = script_obj_as_number (script_obj_a) / script_obj_as_number (script_obj_b);
return script_obj_new_number (value);
}
return script_obj_new_null ();
if (script_obj_is_number (script_obj_a) && script_obj_is_number (script_obj_b)) {
script_number_t value = script_obj_as_number (script_obj_a) / script_obj_as_number (script_obj_b);
return script_obj_new_number (value);
}
return script_obj_new_null ();
}
script_obj_t *script_obj_mod (script_obj_t *script_obj_a,
script_obj_t *script_obj_b)
{
if (script_obj_is_number (script_obj_a) && script_obj_is_number (script_obj_b))
{
script_number_t value = fmodl (script_obj_as_number (script_obj_a), script_obj_as_number (script_obj_b));
return script_obj_new_number (value);
}
return script_obj_new_null ();
if (script_obj_is_number (script_obj_a) && script_obj_is_number (script_obj_b)) {
script_number_t value = fmodl (script_obj_as_number (script_obj_a), script_obj_as_number (script_obj_b));
return script_obj_new_number (value);
}
return script_obj_new_null ();
}
script_obj_cmp_result_t script_obj_cmp (script_obj_t *script_obj_a,
script_obj_t *script_obj_b)
{
if (script_obj_is_null (script_obj_a) && script_obj_is_null (script_obj_b))
{
return SCRIPT_OBJ_CMP_RESULT_EQ;
}
else if (script_obj_is_number (script_obj_a))
{
if (script_obj_is_number (script_obj_b))
{
script_number_t num_a = script_obj_as_number (script_obj_a);
script_number_t num_b = script_obj_as_number (script_obj_b);
if (script_obj_is_null (script_obj_a) && script_obj_is_null (script_obj_b)) {
return SCRIPT_OBJ_CMP_RESULT_EQ;
} else if (script_obj_is_number (script_obj_a)) {
if (script_obj_is_number (script_obj_b)) {
script_number_t num_a = script_obj_as_number (script_obj_a);
script_number_t num_b = script_obj_as_number (script_obj_b);
if (num_a < num_b) return SCRIPT_OBJ_CMP_RESULT_LT;
if (num_a > num_b) return SCRIPT_OBJ_CMP_RESULT_GT;
if (num_a == num_b) return SCRIPT_OBJ_CMP_RESULT_EQ;
return SCRIPT_OBJ_CMP_RESULT_NE;
if (num_a < num_b) return SCRIPT_OBJ_CMP_RESULT_LT;
if (num_a > num_b) return SCRIPT_OBJ_CMP_RESULT_GT;
if (num_a == num_b) return SCRIPT_OBJ_CMP_RESULT_EQ;
return SCRIPT_OBJ_CMP_RESULT_NE;
}
} else if (script_obj_is_string (script_obj_a)) {
if (script_obj_is_string (script_obj_b)) {
char *string_a = script_obj_as_string (script_obj_a);
char *string_b = script_obj_as_string (script_obj_b);
int diff = strcmp (string_a, string_b);
free (string_a);
free (string_b);
if (diff < 0) return SCRIPT_OBJ_CMP_RESULT_LT;
if (diff > 0) return SCRIPT_OBJ_CMP_RESULT_GT;
return SCRIPT_OBJ_CMP_RESULT_EQ;
}
} else if (script_obj_deref_direct (script_obj_a) == script_obj_deref_direct (script_obj_b)) {
return SCRIPT_OBJ_CMP_RESULT_EQ;
}
}
else if (script_obj_is_string (script_obj_a))
{
if (script_obj_is_string (script_obj_b))
{
char* string_a = script_obj_as_string (script_obj_a);
char* string_b = script_obj_as_string (script_obj_b);
int diff = strcmp (string_a, string_b);
free(string_a);
free(string_b);
if (diff < 0) return SCRIPT_OBJ_CMP_RESULT_LT;
if (diff > 0) return SCRIPT_OBJ_CMP_RESULT_GT;
return SCRIPT_OBJ_CMP_RESULT_EQ;
}
}
else if (script_obj_deref_direct (script_obj_a) == script_obj_deref_direct (script_obj_b))
return SCRIPT_OBJ_CMP_RESULT_EQ;
return SCRIPT_OBJ_CMP_RESULT_NE;
return SCRIPT_OBJ_CMP_RESULT_NE;
}

View file

@ -28,14 +28,15 @@
typedef enum
{
SCRIPT_OBJ_CMP_RESULT_EQ = 1<<1,
SCRIPT_OBJ_CMP_RESULT_GT = 1<<2,
SCRIPT_OBJ_CMP_RESULT_LT = 1<<3,
SCRIPT_OBJ_CMP_RESULT_NE = 1<<4,
SCRIPT_OBJ_CMP_RESULT_EQ = 1 << 1,
SCRIPT_OBJ_CMP_RESULT_GT = 1 << 2,
SCRIPT_OBJ_CMP_RESULT_LT = 1 << 3,
SCRIPT_OBJ_CMP_RESULT_NE = 1 << 4,
} script_obj_cmp_result_t;
typedef void *(*script_obj_direct_func_t)(script_obj_t *, void *);
typedef void *(*script_obj_direct_func_t)(script_obj_t *,
void *);
void script_obj_free (script_obj_t *obj);
@ -50,20 +51,21 @@ script_obj_t *script_obj_new_null (void);
script_obj_t *script_obj_new_hash (void);
script_obj_t *script_obj_new_function (script_function_t *function);
script_obj_t *script_obj_new_ref (script_obj_t *sub_obj);
script_obj_t *script_obj_new_extend (script_obj_t *obj_a, script_obj_t *obj_b);
script_obj_t *script_obj_new_extend (script_obj_t *obj_a,
script_obj_t *obj_b);
script_obj_t *script_obj_new_native (void *object_data,
script_obj_native_class_t *class );
void *script_obj_as_custom (script_obj_t *obj,
script_obj_direct_func_t user_func,
void *user_data);
script_obj_t *script_obj_as_obj_type (script_obj_t *obj,
script_obj_type_t type);
script_obj_t *script_obj_new_native (void *object_data,
script_obj_native_class_t *class);
void *script_obj_as_custom (script_obj_t *obj,
script_obj_direct_func_t user_func,
void *user_data);
script_obj_t *script_obj_as_obj_type (script_obj_t *obj,
script_obj_type_t type);
script_number_t script_obj_as_number (script_obj_t *obj);
bool script_obj_as_bool (script_obj_t *obj);
char *script_obj_as_string (script_obj_t *obj);
void *script_obj_as_native_of_class (script_obj_t *obj,
script_obj_native_class_t *class );
script_obj_native_class_t *class);
void *script_obj_as_native_of_class_name (script_obj_t *obj,
const char *class_name);
bool script_obj_is_null (script_obj_t *obj);
@ -72,8 +74,8 @@ bool script_obj_is_string (script_obj_t *obj);
bool script_obj_is_hash (script_obj_t *obj);
bool script_obj_is_native (script_obj_t *obj);
bool script_obj_is_native_of_class (script_obj_t * obj,
script_obj_native_class_t *class );
bool script_obj_is_native_of_class (script_obj_t *obj,
script_obj_native_class_t *class);
bool script_obj_is_native_of_class_name (script_obj_t *obj,
const char *class_name);
void script_obj_assign (script_obj_t *obj_a,
@ -88,9 +90,9 @@ bool script_obj_hash_get_bool (script_obj_t *hash,
const char *name);
char *script_obj_hash_get_string (script_obj_t *hash,
const char *name);
void *script_obj_hash_get_native_of_class (script_obj_t *hash,
const char *name,
script_obj_native_class_t *class );
void *script_obj_hash_get_native_of_class (script_obj_t *hash,
const char *name,
script_obj_native_class_t *class);
void *script_obj_hash_get_native_of_class_name (script_obj_t *hash,
const char *name,
const char *class_name);

File diff suppressed because it is too large Load diff

View file

@ -39,383 +39,352 @@
static script_scan_t *script_scan_new (void)
{
unsigned char *chars;
script_scan_t *scan = calloc (1, sizeof (script_scan_t));
unsigned char *chars;
script_scan_t *scan = calloc (1, sizeof(script_scan_t));
scan->tokens = NULL;
scan->tokencount = 0;
scan->cur_char = '\0';
scan->line_index = 1; /* According to Nedit the first line is 1 but first column is 0 */
scan->column_index = COLUMN_START_INDEX;
scan->tokens = NULL;
scan->tokencount = 0;
scan->cur_char = '\0';
scan->line_index = 1; /* According to Nedit the first line is 1 but first column is 0 */
scan->column_index = COLUMN_START_INDEX;
scan->identifier_1st_char = ply_bitarray_new (256);
scan->identifier_nth_char = ply_bitarray_new (256);
scan->identifier_1st_char = ply_bitarray_new (256);
scan->identifier_nth_char = ply_bitarray_new (256);
for (chars =
(unsigned char *) "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_";
*chars;
chars++)
ply_bitarray_set (scan->identifier_1st_char, *chars);
for (chars =
(unsigned char *) "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789";
*chars;
chars++)
ply_bitarray_set (scan->identifier_nth_char, *chars);
return scan;
for (chars =
(unsigned char *) "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_";
*chars;
chars++) {
ply_bitarray_set (scan->identifier_1st_char, *chars);
}
for (chars =
(unsigned char *) "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789";
*chars;
chars++) {
ply_bitarray_set (scan->identifier_nth_char, *chars);
}
return scan;
}
script_scan_t *script_scan_file (const char *filename)
{
int fd = open (filename, O_RDONLY|O_CLOEXEC);
if (fd < 0) return NULL;
script_scan_t *scan = script_scan_new ();
scan->name = strdup (filename);
scan->source.fd = fd;
scan->source_is_file = true;
script_scan_get_next_char (scan);
return scan;
int fd = open (filename, O_RDONLY | O_CLOEXEC);
if (fd < 0) return NULL;
script_scan_t *scan = script_scan_new ();
scan->name = strdup (filename);
scan->source.fd = fd;
scan->source_is_file = true;
script_scan_get_next_char (scan);
return scan;
}
script_scan_t *script_scan_string (const char *string,
const char *name)
{
script_scan_t *scan = script_scan_new ();
scan->name = strdup (name);
scan->source.string = string;
scan->source_is_file = false;
script_scan_get_next_char (scan);
return scan;
script_scan_t *scan = script_scan_new ();
scan->name = strdup (name);
scan->source.string = string;
scan->source_is_file = false;
script_scan_get_next_char (scan);
return scan;
}
void script_scan_token_clean (script_scan_token_t *token)
{
switch (token->type)
{
case SCRIPT_SCAN_TOKEN_TYPE_EMPTY:
case SCRIPT_SCAN_TOKEN_TYPE_EOF:
case SCRIPT_SCAN_TOKEN_TYPE_INTEGER:
case SCRIPT_SCAN_TOKEN_TYPE_FLOAT:
case SCRIPT_SCAN_TOKEN_TYPE_SYMBOL:
break;
case SCRIPT_SCAN_TOKEN_TYPE_IDENTIFIER:
case SCRIPT_SCAN_TOKEN_TYPE_STRING:
case SCRIPT_SCAN_TOKEN_TYPE_COMMENT:
case SCRIPT_SCAN_TOKEN_TYPE_ERROR:
free (token->data.string);
break;
}
token->type = SCRIPT_SCAN_TOKEN_TYPE_EMPTY;
token->whitespace = 0;
switch (token->type) {
case SCRIPT_SCAN_TOKEN_TYPE_EMPTY:
case SCRIPT_SCAN_TOKEN_TYPE_EOF:
case SCRIPT_SCAN_TOKEN_TYPE_INTEGER:
case SCRIPT_SCAN_TOKEN_TYPE_FLOAT:
case SCRIPT_SCAN_TOKEN_TYPE_SYMBOL:
break;
case SCRIPT_SCAN_TOKEN_TYPE_IDENTIFIER:
case SCRIPT_SCAN_TOKEN_TYPE_STRING:
case SCRIPT_SCAN_TOKEN_TYPE_COMMENT:
case SCRIPT_SCAN_TOKEN_TYPE_ERROR:
free (token->data.string);
break;
}
token->type = SCRIPT_SCAN_TOKEN_TYPE_EMPTY;
token->whitespace = 0;
}
void script_scan_free (script_scan_t *scan)
{
int i;
if (scan->source_is_file) close (scan->source.fd);
for (i = 0; i < scan->tokencount; i++)
{
script_scan_token_clean (scan->tokens[i]);
free (scan->tokens[i]);
}
ply_bitarray_free (scan->identifier_1st_char);
ply_bitarray_free (scan->identifier_nth_char);
free (scan->name);
free (scan->tokens);
free (scan);
int i;
if (scan->source_is_file) close (scan->source.fd);
for (i = 0; i < scan->tokencount; i++) {
script_scan_token_clean (scan->tokens[i]);
free (scan->tokens[i]);
}
ply_bitarray_free (scan->identifier_1st_char);
ply_bitarray_free (scan->identifier_nth_char);
free (scan->name);
free (scan->tokens);
free (scan);
}
unsigned char script_scan_get_current_char (script_scan_t *scan)
{
return scan->cur_char;
return scan->cur_char;
}
unsigned char script_scan_get_next_char (script_scan_t *scan)
{
if (scan->cur_char == '\n')
{
scan->line_index++;
scan->column_index = COLUMN_START_INDEX;
}
else if (scan->cur_char != '\0')
scan->column_index++;
if (scan->source_is_file)
{
int got = read (scan->source.fd, &scan->cur_char, 1);
if (!got) scan->cur_char = 0; /* FIXME a better way of doing EOF etc */
}
else
{
scan->cur_char = *scan->source.string;
if (scan->cur_char) scan->source.string++;
}
return scan->cur_char;
if (scan->cur_char == '\n') {
scan->line_index++;
scan->column_index = COLUMN_START_INDEX;
} else if (scan->cur_char != '\0') {
scan->column_index++;
}
if (scan->source_is_file) {
int got = read (scan->source.fd, &scan->cur_char, 1);
if (!got) scan->cur_char = 0; /* FIXME a better way of doing EOF etc */
} else {
scan->cur_char = *scan->source.string;
if (scan->cur_char) scan->source.string++;
}
return scan->cur_char;
}
void script_scan_read_next_token (script_scan_t *scan,
script_scan_token_t *token)
script_scan_token_t *token)
{
unsigned char curchar = script_scan_get_current_char (scan); /* FIXME Double check these unsigned chars are ok */
unsigned char nextchar;
unsigned char curchar = script_scan_get_current_char (scan); /* FIXME Double check these unsigned chars are ok */
unsigned char nextchar;
token->whitespace = 0;
while (true)
{
if (curchar == ' ')
{
curchar = script_scan_get_next_char (scan);
token->whitespace++;
continue;
} /* FIXME restrcuture */
if (curchar == '\n')
{
curchar = script_scan_get_next_char (scan);
token->whitespace++;
continue;
}
if (curchar == '\t')
{
curchar = script_scan_get_next_char (scan);
token->whitespace++;
continue;
}
break;
}
token->location.line_index = scan->line_index;
token->location.column_index = scan->column_index;
token->location.name = scan->name;
nextchar = script_scan_get_next_char (scan);
if (ply_bitarray_lookup (scan->identifier_1st_char, curchar))
{
int index = 1;
token->type = SCRIPT_SCAN_TOKEN_TYPE_IDENTIFIER;
token->data.string = malloc (2 * sizeof (char));
token->data.string[0] = curchar;
token->data.string[1] = '\0';
curchar = nextchar;
while (ply_bitarray_lookup (scan->identifier_nth_char, curchar))
{
token->data.string = realloc (token->data.string,
(index + 2) * sizeof (char));
token->data.string[index] = curchar;
token->data.string[index + 1] = '\0';
index++;
curchar = script_scan_get_next_char (scan);
}
return;
}
if ((curchar >= '0') && (curchar <= '9'))
{
long long int int_value = curchar - '0';
curchar = nextchar;
while (curchar >= '0' && curchar <= '9')
{
int_value *= 10;
int_value += curchar - '0';
curchar = script_scan_get_next_char (scan);
}
if (curchar == '.')
{
double floatpoint = int_value;
double scalar = 1;
curchar = script_scan_get_next_char (scan);
while (curchar >= '0' && curchar <= '9')
{
scalar /= 10;
floatpoint += scalar * (curchar - '0');
curchar = script_scan_get_next_char (scan);
}
token->type = SCRIPT_SCAN_TOKEN_TYPE_FLOAT;
token->data.floatpoint = floatpoint;
}
else
{
token->type = SCRIPT_SCAN_TOKEN_TYPE_INTEGER;
token->data.integer = int_value;
}
return;
}
if (!curchar)
{
token->type = SCRIPT_SCAN_TOKEN_TYPE_EOF;
return;
}
if (curchar == '\"')
{
token->type = SCRIPT_SCAN_TOKEN_TYPE_STRING;
int index = 0;
token->data.string = malloc (sizeof (char));
token->data.string[0] = '\0';
curchar = nextchar;
while (curchar != '\"')
{
if (curchar == '\0')
{
token->data.string = strdup("End of file before end of string");
token->type = SCRIPT_SCAN_TOKEN_TYPE_ERROR;
return;
}
if (curchar == '\n')
{
token->data.string = strdup("Line terminator before end of string");
token->type = SCRIPT_SCAN_TOKEN_TYPE_ERROR;
return;
}
if (curchar == '\\')
{
curchar = script_scan_get_next_char (scan);
switch (curchar)
{
case 'n':
curchar = '\n';
break;
case '0':
curchar = '\0';
break;
case '"':
curchar = '\"';
break;
default:
break;
token->whitespace = 0;
while (true) {
if (curchar == ' ') {
curchar = script_scan_get_next_char (scan);
token->whitespace++;
continue;
} /* FIXME restrcuture */
if (curchar == '\n') {
curchar = script_scan_get_next_char (scan);
token->whitespace++;
continue;
}
}
token->data.string = realloc (token->data.string,
(index + 2) * sizeof (char));
token->data.string[index] = curchar;
token->data.string[index + 1] = '\0';
index++;
curchar = script_scan_get_next_char (scan);
if (curchar == '\t') {
curchar = script_scan_get_next_char (scan);
token->whitespace++;
continue;
}
break;
}
script_scan_get_next_char (scan);
return;
}
{
bool linecomment = false;
if (curchar == '#') linecomment = true;
if ((curchar == '/') && (nextchar == '/'))
{
linecomment = true;
token->location.line_index = scan->line_index;
token->location.column_index = scan->column_index;
token->location.name = scan->name;
nextchar = script_scan_get_next_char (scan);
}
if (linecomment)
{
int index = 0;
token->data.string = malloc (sizeof (char));
token->data.string[0] = '\0';
curchar = nextchar;
for (curchar = nextchar;
curchar != '\n' && curchar != '\0';
curchar = script_scan_get_next_char (scan))
{
token->data.string = realloc (token->data.string,
(index + 2) * sizeof (char));
token->data.string[index] = curchar;
token->data.string[index + 1] = '\0';
index++;
}
token->type = SCRIPT_SCAN_TOKEN_TYPE_COMMENT;
return;
}
}
if ((curchar == '/') && (nextchar == '*'))
{
int index = 0;
int depth = 1;
token->data.string = malloc (sizeof (char));
token->data.string[0] = '\0';
curchar = script_scan_get_next_char (scan);
nextchar = script_scan_get_next_char (scan);
while (true)
{
if (nextchar == '\0')
{
free (token->data.string);
token->data.string = strdup("End of file before end of comment");
token->type = SCRIPT_SCAN_TOKEN_TYPE_ERROR;
return;
}
if ((curchar == '/') && (nextchar == '*'))
depth++;
if ((curchar == '*') && (nextchar == '/'))
{
depth--;
if (!depth) break;
}
token->data.string = realloc (token->data.string,
(index + 2) * sizeof (char));
token->data.string[index] = curchar;
token->data.string[index + 1] = '\0';
index++;
curchar = nextchar;
nextchar = script_scan_get_next_char (scan);
if (ply_bitarray_lookup (scan->identifier_1st_char, curchar)) {
int index = 1;
token->type = SCRIPT_SCAN_TOKEN_TYPE_IDENTIFIER;
token->data.string = malloc (2 * sizeof(char));
token->data.string[0] = curchar;
token->data.string[1] = '\0';
curchar = nextchar;
while (ply_bitarray_lookup (scan->identifier_nth_char, curchar)) {
token->data.string = realloc (token->data.string,
(index + 2) * sizeof(char));
token->data.string[index] = curchar;
token->data.string[index + 1] = '\0';
index++;
curchar = script_scan_get_next_char (scan);
}
return;
}
script_scan_get_next_char (scan);
token->type = SCRIPT_SCAN_TOKEN_TYPE_COMMENT;
return;
}
/* all other */
token->type = SCRIPT_SCAN_TOKEN_TYPE_SYMBOL;
token->data.symbol = curchar;
return;
if ((curchar >= '0') && (curchar <= '9')) {
long long int int_value = curchar - '0';
curchar = nextchar;
while (curchar >= '0' && curchar <= '9') {
int_value *= 10;
int_value += curchar - '0';
curchar = script_scan_get_next_char (scan);
}
if (curchar == '.') {
double floatpoint = int_value;
double scalar = 1;
curchar = script_scan_get_next_char (scan);
while (curchar >= '0' && curchar <= '9') {
scalar /= 10;
floatpoint += scalar * (curchar - '0');
curchar = script_scan_get_next_char (scan);
}
token->type = SCRIPT_SCAN_TOKEN_TYPE_FLOAT;
token->data.floatpoint = floatpoint;
} else {
token->type = SCRIPT_SCAN_TOKEN_TYPE_INTEGER;
token->data.integer = int_value;
}
return;
}
if (!curchar) {
token->type = SCRIPT_SCAN_TOKEN_TYPE_EOF;
return;
}
if (curchar == '\"') {
token->type = SCRIPT_SCAN_TOKEN_TYPE_STRING;
int index = 0;
token->data.string = malloc (sizeof(char));
token->data.string[0] = '\0';
curchar = nextchar;
while (curchar != '\"') {
if (curchar == '\0') {
token->data.string = strdup ("End of file before end of string");
token->type = SCRIPT_SCAN_TOKEN_TYPE_ERROR;
return;
}
if (curchar == '\n') {
token->data.string = strdup ("Line terminator before end of string");
token->type = SCRIPT_SCAN_TOKEN_TYPE_ERROR;
return;
}
if (curchar == '\\') {
curchar = script_scan_get_next_char (scan);
switch (curchar) {
case 'n':
curchar = '\n';
break;
case '0':
curchar = '\0';
break;
case '"':
curchar = '\"';
break;
default:
break;
}
}
token->data.string = realloc (token->data.string,
(index + 2) * sizeof(char));
token->data.string[index] = curchar;
token->data.string[index + 1] = '\0';
index++;
curchar = script_scan_get_next_char (scan);
}
script_scan_get_next_char (scan);
return;
}
{
bool linecomment = false;
if (curchar == '#') linecomment = true;
if ((curchar == '/') && (nextchar == '/')) {
linecomment = true;
nextchar = script_scan_get_next_char (scan);
}
if (linecomment) {
int index = 0;
token->data.string = malloc (sizeof(char));
token->data.string[0] = '\0';
curchar = nextchar;
for (curchar = nextchar;
curchar != '\n' && curchar != '\0';
curchar = script_scan_get_next_char (scan)) {
token->data.string = realloc (token->data.string,
(index + 2) * sizeof(char));
token->data.string[index] = curchar;
token->data.string[index + 1] = '\0';
index++;
}
token->type = SCRIPT_SCAN_TOKEN_TYPE_COMMENT;
return;
}
}
if ((curchar == '/') && (nextchar == '*')) {
int index = 0;
int depth = 1;
token->data.string = malloc (sizeof(char));
token->data.string[0] = '\0';
curchar = script_scan_get_next_char (scan);
nextchar = script_scan_get_next_char (scan);
while (true) {
if (nextchar == '\0') {
free (token->data.string);
token->data.string = strdup ("End of file before end of comment");
token->type = SCRIPT_SCAN_TOKEN_TYPE_ERROR;
return;
}
if ((curchar == '/') && (nextchar == '*'))
depth++;
if ((curchar == '*') && (nextchar == '/')) {
depth--;
if (!depth) break;
}
token->data.string = realloc (token->data.string,
(index + 2) * sizeof(char));
token->data.string[index] = curchar;
token->data.string[index + 1] = '\0';
index++;
curchar = nextchar;
nextchar = script_scan_get_next_char (scan);
}
script_scan_get_next_char (scan);
token->type = SCRIPT_SCAN_TOKEN_TYPE_COMMENT;
return;
}
/* all other */
token->type = SCRIPT_SCAN_TOKEN_TYPE_SYMBOL;
token->data.symbol = curchar;
return;
}
static script_scan_token_t *script_scan_peek_token (script_scan_t *scan,
int n)
int n)
{
int i;
int i;
/* we're screwed long before we ever actually hit INT_MAX; but at least
* we shouldn't get ourselves stuck in an infinite loop. */
if (scan->tokencount <= n && n < INT_MAX)
{
scan->tokens =
realloc (scan->tokens, (n + 1) * sizeof (script_scan_token_t *));
for (i = scan->tokencount; i <= n; i++)
{
scan->tokens[i] = malloc (sizeof (script_scan_token_t));
scan->tokens[i]->type = SCRIPT_SCAN_TOKEN_TYPE_EMPTY;
/* we're screwed long before we ever actually hit INT_MAX; but at least
* we shouldn't get ourselves stuck in an infinite loop. */
if (scan->tokencount <= n && n < INT_MAX) {
scan->tokens =
realloc (scan->tokens, (n + 1) * sizeof(script_scan_token_t *));
for (i = scan->tokencount; i <= n; i++) {
scan->tokens[i] = malloc (sizeof(script_scan_token_t));
scan->tokens[i]->type = SCRIPT_SCAN_TOKEN_TYPE_EMPTY;
}
scan->tokencount = n + 1;
}
scan->tokencount = n + 1;
}
if (scan->tokens[n]->type == SCRIPT_SCAN_TOKEN_TYPE_EMPTY)
{
if ((n > 0) && (scan->tokens[n - 1]->type == SCRIPT_SCAN_TOKEN_TYPE_EMPTY))
script_scan_peek_token (scan, n - 1);
do
{
script_scan_token_clean (scan->tokens[n]);
script_scan_read_next_token (scan, scan->tokens[n]); /* FIXME if skipping comments, add whitespace to next token */
if (scan->tokens[n]->type == SCRIPT_SCAN_TOKEN_TYPE_EMPTY) {
if ((n > 0) && (scan->tokens[n - 1]->type == SCRIPT_SCAN_TOKEN_TYPE_EMPTY))
script_scan_peek_token (scan, n - 1);
do {
script_scan_token_clean (scan->tokens[n]);
script_scan_read_next_token (scan, scan->tokens[n]); /* FIXME if skipping comments, add whitespace to next token */
} while (scan->tokens[n]->type == SCRIPT_SCAN_TOKEN_TYPE_COMMENT); /* FIXME optionally pass comments back */
}
while (scan->tokens[n]->type == SCRIPT_SCAN_TOKEN_TYPE_COMMENT); /* FIXME optionally pass comments back */
}
return scan->tokens[n];
return scan->tokens[n];
}
script_scan_token_t *script_scan_get_next_token (script_scan_t *scan)
{
int i;
script_scan_token_clean (scan->tokens[0]);
for (i = 0; i < (scan->tokencount - 1); i++)
*scan->tokens[i] = *scan->tokens[i + 1];
scan->tokens[(scan->tokencount - 1)]->type = SCRIPT_SCAN_TOKEN_TYPE_EMPTY;
return script_scan_peek_token (scan, 0);
int i;
script_scan_token_clean (scan->tokens[0]);
for (i = 0; i < (scan->tokencount - 1); i++) {
*scan->tokens[i] = *scan->tokens[i + 1];
}
scan->tokens[(scan->tokencount - 1)]->type = SCRIPT_SCAN_TOKEN_TYPE_EMPTY;
return script_scan_peek_token (scan, 0);
}
script_scan_token_t *script_scan_get_current_token (script_scan_t *scan)
{
return script_scan_peek_token (scan, 0);
return script_scan_peek_token (scan, 0);
}
script_scan_token_t *script_scan_peek_next_token (script_scan_t *scan)
{
return script_scan_peek_token (scan, 1);
return script_scan_peek_token (scan, 1);
}

View file

@ -28,66 +28,66 @@
typedef enum
{
SCRIPT_SCAN_TOKEN_TYPE_EMPTY,
SCRIPT_SCAN_TOKEN_TYPE_EOF,
SCRIPT_SCAN_TOKEN_TYPE_INTEGER,
SCRIPT_SCAN_TOKEN_TYPE_FLOAT,
SCRIPT_SCAN_TOKEN_TYPE_IDENTIFIER,
SCRIPT_SCAN_TOKEN_TYPE_STRING,
SCRIPT_SCAN_TOKEN_TYPE_SYMBOL,
SCRIPT_SCAN_TOKEN_TYPE_COMMENT,
SCRIPT_SCAN_TOKEN_TYPE_ERROR,
SCRIPT_SCAN_TOKEN_TYPE_EMPTY,
SCRIPT_SCAN_TOKEN_TYPE_EOF,
SCRIPT_SCAN_TOKEN_TYPE_INTEGER,
SCRIPT_SCAN_TOKEN_TYPE_FLOAT,
SCRIPT_SCAN_TOKEN_TYPE_IDENTIFIER,
SCRIPT_SCAN_TOKEN_TYPE_STRING,
SCRIPT_SCAN_TOKEN_TYPE_SYMBOL,
SCRIPT_SCAN_TOKEN_TYPE_COMMENT,
SCRIPT_SCAN_TOKEN_TYPE_ERROR,
} script_scan_token_type_t;
typedef struct
{
script_scan_token_type_t type;
union
{
char *string;
char symbol;
long long int integer;
double floatpoint;
} data;
int whitespace;
script_debug_location_t location;
script_scan_token_type_t type;
union
{
char *string;
char symbol;
long long int integer;
double floatpoint;
} data;
int whitespace;
script_debug_location_t location;
} script_scan_token_t;
typedef struct
{
union
{
int fd;
const char *string;
} source;
char* name;
unsigned char cur_char;
ply_bitarray_t *identifier_1st_char;
ply_bitarray_t *identifier_nth_char;
int tokencount;
script_scan_token_t **tokens;
int line_index;
int column_index;
bool source_is_file;
union
{
int fd;
const char *string;
} source;
char *name;
unsigned char cur_char;
ply_bitarray_t *identifier_1st_char;
ply_bitarray_t *identifier_nth_char;
int tokencount;
script_scan_token_t **tokens;
int line_index;
int column_index;
bool source_is_file;
} script_scan_t;
#define script_scan_token_is_symbol(__token) \
(__token->type == SCRIPT_SCAN_TOKEN_TYPE_SYMBOL)
#define script_scan_token_is_symbol_of_value(__token,__value) \
(__token->type == SCRIPT_SCAN_TOKEN_TYPE_SYMBOL \
&& __token->data.symbol == __value)
(__token->type == SCRIPT_SCAN_TOKEN_TYPE_SYMBOL)
#define script_scan_token_is_symbol_of_value(__token, __value) \
(__token->type == SCRIPT_SCAN_TOKEN_TYPE_SYMBOL \
&& __token->data.symbol == __value)
#define script_scan_token_is_identifier(__token) \
(__token->type == SCRIPT_SCAN_TOKEN_TYPE_IDENTIFIER)
#define script_scan_token_is_identifier_of_value(__token,__value) \
(__token->type == SCRIPT_SCAN_TOKEN_TYPE_IDENTIFIER \
&& !strcmp(__token->data.string, __value))
(__token->type == SCRIPT_SCAN_TOKEN_TYPE_IDENTIFIER)
#define script_scan_token_is_identifier_of_value(__token, __value) \
(__token->type == SCRIPT_SCAN_TOKEN_TYPE_IDENTIFIER \
&& !strcmp (__token->data.string, __value))
#define script_scan_token_is_integer(__token) \
(__token->type == SCRIPT_SCAN_TOKEN_TYPE_INTEGER)
(__token->type == SCRIPT_SCAN_TOKEN_TYPE_INTEGER)
#define script_scan_token_is_string(__token) \
(__token->type == SCRIPT_SCAN_TOKEN_TYPE_STRING)
(__token->type == SCRIPT_SCAN_TOKEN_TYPE_STRING)
#define script_scan_token_is_float(__token) \
(__token->type == SCRIPT_SCAN_TOKEN_TYPE_FLOAT)
(__token->type == SCRIPT_SCAN_TOKEN_TYPE_FLOAT)

View file

@ -44,28 +44,28 @@ script_function_t *script_function_script_new (script_op_t *script,
void *user_data,
ply_list_t *parameter_list)
{
script_function_t *function = malloc (sizeof (script_function_t));
script_function_t *function = malloc (sizeof(script_function_t));
function->type = SCRIPT_FUNCTION_TYPE_SCRIPT;
function->parameters = parameter_list;
function->data.script = script;
function->freeable = false;
function->user_data = user_data;
return function;
function->type = SCRIPT_FUNCTION_TYPE_SCRIPT;
function->parameters = parameter_list;
function->data.script = script;
function->freeable = false;
function->user_data = user_data;
return function;
}
script_function_t *script_function_native_new (script_native_function_t native_function,
void *user_data,
ply_list_t *parameter_list)
script_function_t *script_function_native_new (script_native_function_t native_function,
void *user_data,
ply_list_t *parameter_list)
{
script_function_t *function = malloc (sizeof (script_function_t));
script_function_t *function = malloc (sizeof(script_function_t));
function->type = SCRIPT_FUNCTION_TYPE_NATIVE;
function->parameters = parameter_list;
function->data.native = native_function;
function->freeable = true;
function->user_data = user_data;
return function;
function->type = SCRIPT_FUNCTION_TYPE_NATIVE;
function->parameters = parameter_list;
function->data.native = native_function;
function->freeable = true;
function->user_data = user_data;
return function;
}
void script_add_native_function (script_obj_t *hash,
@ -75,76 +75,76 @@ void script_add_native_function (script_obj_t *hash,
const char *first_arg,
...)
{
va_list args;
const char *arg;
ply_list_t *parameter_list = ply_list_new ();
va_list args;
const char *arg;
ply_list_t *parameter_list = ply_list_new ();
arg = first_arg;
va_start (args, first_arg);
while (arg)
{
ply_list_append_data (parameter_list, strdup (arg));
arg = va_arg (args, const char *);
}
va_end (args);
arg = first_arg;
va_start (args, first_arg);
while (arg) {
ply_list_append_data (parameter_list, strdup (arg));
arg = va_arg (args, const char *);
}
va_end (args);
script_function_t *function = script_function_native_new (native_function,
user_data,
parameter_list);
script_obj_t *obj = script_obj_new_function (function);
script_obj_hash_add_element (hash, obj, name);
script_obj_unref (obj);
script_function_t *function = script_function_native_new (native_function,
user_data,
parameter_list);
script_obj_t *obj = script_obj_new_function (function);
script_obj_hash_add_element (hash, obj, name);
script_obj_unref (obj);
}
script_obj_native_class_t *script_obj_native_class_new (script_obj_function_t free_func,
const char *name,
void *user_data)
{
script_obj_native_class_t *class = malloc (sizeof (script_obj_native_class_t));
script_obj_native_class_t *class = malloc (sizeof(script_obj_native_class_t));
class->free_func = free_func;
class->name = strdup (name);
class->user_data = user_data;
return class;
class->free_func = free_func;
class->name = strdup (name);
class->user_data = user_data;
return class;
}
void script_obj_native_class_destroy (script_obj_native_class_t *class)
{
free (class->name);
free (class);
return;
free (class->name);
free (class);
return;
}
script_state_t *script_state_new (void *user_data)
{
script_state_t *state = malloc (sizeof (script_state_t));
script_obj_t *global_hash = script_obj_new_hash ();
state->global = script_obj_new_ref (global_hash);
script_obj_unref(global_hash);
state->local = script_obj_new_ref (global_hash);
state->this = script_obj_new_null();
state->user_data = user_data;
return state;
script_state_t *state = malloc (sizeof(script_state_t));
script_obj_t *global_hash = script_obj_new_hash ();
state->global = script_obj_new_ref (global_hash);
script_obj_unref (global_hash);
state->local = script_obj_new_ref (global_hash);
state->this = script_obj_new_null ();
state->user_data = user_data;
return state;
}
script_state_t *script_state_init_sub (script_state_t *oldstate, script_obj_t *this)
{
script_state_t *newstate = malloc (sizeof (script_state_t));
script_obj_t *local_hash = script_obj_new_hash ();
newstate->local = script_obj_new_ref (local_hash);
script_obj_unref(local_hash);
newstate->global = script_obj_new_ref (oldstate->global);
if (this) newstate->this = script_obj_new_ref (this);
else newstate->this = script_obj_new_ref (oldstate->this);
newstate->user_data = oldstate->user_data;
return newstate;
script_state_t *newstate = malloc (sizeof(script_state_t));
script_obj_t *local_hash = script_obj_new_hash ();
newstate->local = script_obj_new_ref (local_hash);
script_obj_unref (local_hash);
newstate->global = script_obj_new_ref (oldstate->global);
if (this) newstate->this = script_obj_new_ref (this);
else newstate->this = script_obj_new_ref (oldstate->this);
newstate->user_data = oldstate->user_data;
return newstate;
}
void script_state_destroy (script_state_t *state)
{
script_obj_unref (state->global);
script_obj_unref (state->local);
script_obj_unref (state->this);
free (state);
script_obj_unref (state->global);
script_obj_unref (state->local);
script_obj_unref (state->this);
free (state);
}

Some files were not shown because too many files have changed in this diff Show more