mirror of
https://gitlab.freedesktop.org/plymouth/plymouth.git
synced 2026-05-08 04:18:01 +02:00
Reindent
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:
parent
5e55bdb33e
commit
85704145ee
112 changed files with 22421 additions and 23820 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
3011
src/main.c
File diff suppressed because it is too large
Load diff
|
|
@ -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
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Reference in a new issue