/*
 * GQmpeg
 * (C)1998, 1999 John Ellis
 *
 * Author: John Ellis
 *
 * This software is released under the GNU General Public License.
 * Please read the included file COPYING for more information.
 * This software comes with no warranty of any kind, use at you own risk!
 */

/*
 *-------------------------------------
 * Standard library includes
 *-------------------------------------
 */

#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <dirent.h>

/*
 *-------------------------------------
 * includes for glib / gtk / imlib
 *-------------------------------------
 */

#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include <gdk_imlib.h>

/*
 *----------------------------------------------------------------------------
 * defines
 *----------------------------------------------------------------------------
 */

#define		GQMPEG_VERSION_MAJOR 0
#define		GQMPEG_VERSION_MINOR 6
#define		GQMPEG_VERSION_REV 3

#define		GQMPEG_RC_DIR		".gqmpeg"
#define		GQMPEG_RC_DIR_SKIN	".gqmpeg/skins"
#define		GQMPEG_RC_DIR_PLAYLIST	".gqmpeg/playlists"
#define		GQMPEG_RC_FILE_SESSION	".gqmpeg/session-playlist.gqmpeg"

#define		list_width 180
#define		list_height 180
#define		playlist_window_width 500
#define		playlist_window_height 400
#define		foreground_color 0
#define		background_color 255

#define		STATUS_STOP 0
#define		STATUS_PAUSE 1
#define		STATUS_PLAY 2
#define		STATUS_NEXT 3

#define		PLAYLIST_MODE_EMPTY 0
#define		PLAYLIST_MODE_SESSION 1
#define		PLAYLIST_MODE_FILE 2

/*
 *----------------------------------------------------------------------------
 * skin widget structures
 *----------------------------------------------------------------------------
 */

typedef struct _ButtonData ButtonData;
struct _ButtonData
{
        GdkPixmap *pixmap;
	gint sections;
	gint has_light;
	gint has_prelight;
	gint pushed;
	gint lit;
	gint prelit;
	gint width;
	gint height;
	gint x;
	gint y;
	void (*press_func)();
	void (*release_func)();
	void (*click_func)();
};

typedef struct _ItemData ItemData;
struct _ItemData
{
        GdkPixmap *pixmap;
	gint sections;
	gint width;
	gint height;
	gint x;
	gint y;
};

typedef struct _FontData FontData;
struct _FontData
{
        GdkPixmap *pixmap;
	gint length;
	gint char_width;
	gint char_height;
	gint width;
	gint height;
	gint x;
	gint y;
	gchar *text;
	gint offset;
	gint scroll;
	gint extended;	/* to support chars above 128 */
};

typedef struct _DigitData DigitData;
struct _DigitData
{
        GdkPixmap *pixmap;
	gint width;
	gint height;
};

typedef struct _NumberData NumberData;
struct _NumberData
{
	DigitData *digits;
	gint x;
	gint y;
	gint length;
	gint zeros;
};

typedef struct _SliderData SliderData;
struct _SliderData
{
	GdkPixmap *pixmap;
	gint x;
	gint y;
	gint width;
	gint height;
	gint verticle;
	gint reversed;
	gint handle_width;
	gint handle_height;
	gint position;
	gint has_prelight;
	gint pushed;
	gint prelit;
	void (*press_func)(float);
	void (*release_func)(float);
	void (*move_func)(float);
	ItemData *item;
};

typedef struct _SkinData SkinData;
struct _SkinData
{
	gint width;
	gint height;
	GdkPixmap *background;
	GdkBitmap *mask;
	FontData *title;
	FontData *artist;
	FontData *album;
	FontData *genre;
	ItemData *stereo;
	ItemData *item_shuffle;
	ItemData *item_repeat;
	ItemData *mpegver;
	ItemData *layer;
	ItemData *mode;
	ItemData *status;
	NumberData *hour;
	NumberData *min;
	NumberData *sec;
	NumberData *hour_total;
	NumberData *min_total;
	NumberData *sec_total;
	NumberData *song_current;
	NumberData *song_total;
	NumberData *input_bits;
	NumberData *input_hz;
	NumberData *output_bits;
	NumberData *output_hz;
	NumberData *frame;
	NumberData *frame_total;
	NumberData *cpu;
	NumberData *song_min;
	NumberData *song_sec;
	DigitData *dig_small;
	DigitData *dig_large;
	ButtonData *play;
	ButtonData *stop;
	ButtonData *pause;
	ButtonData *next;
	ButtonData *prev;
	ButtonData *ff;
	ButtonData *rw;
	ButtonData *shuffle;
	ButtonData *repeat;
	ButtonData *playlist;
	ButtonData *config;
	ButtonData *iconify;
	ButtonData *exit;
	ButtonData *mixer;
	ButtonData *skin_mode;
	SliderData *position;
	ItemData *position_item;
	SliderData *volume;
	ItemData *volume_item;
	ButtonData *volume_up;
	ButtonData *volume_dn;
	SliderData *balance;
	ItemData *balance_item;
	ButtonData *balance_left;
	ButtonData *balance_right;
	ButtonData *preset[10];
};

/*
 *----------------------------------------------------------------------------
 * song structure
 *----------------------------------------------------------------------------
 */

typedef struct _SongData SongData;
struct _SongData
{
	gchar *path;			/* path or location */

	gint type;			/* module type (location in io_list) */
	gchar *type_description;	/* file type description */

	gint custom;			/* if TRUE, not a standard file */
	gint custom_type;		/* location in typelist */

	gint generic_info_loaded;	/* if the title, artist, etc. was loaded */

	gchar *title;
	gchar *artist;
	gchar *album;
	gchar *genre;
	gchar *comment;
	gchar *year;

	gint format_info_loaded;	/* if the length, bit_rate, etc. was loaded */

	gint length;			/* seconds, -1 for unknown or live */
	gint live;			/* TRUE if live streaming */
	gint bit_rate;			/* for example mp3: 128 = 128Kbits */
	gint bit_depth;			/* usually 8 or 16 */
	gint khz_rate;			/* example: 44 = 44 Khz */
	gint channels;			/* usually 1 or 2, mono or stereo */

	gpointer data;			/* slot for misc internal use of io_modules */
	void (* free_data_func)(gpointer);	/* func to free data slot */
};

/*
 *----------------------------------------------------------------------------
 * globals
 *----------------------------------------------------------------------------
 */

	/* main window widgets */
extern GtkWidget *mainwindow;
extern GtkWidget *display_area;
extern GtkWidget *playlist_window;

extern GtkWidget *main_menu;
extern GtkWidget *dir_menu;
extern GtkWidget *file_menu;
extern GtkWidget *file_menu_list;
extern GtkWidget *playlist_menu;
extern GtkWidget *playlist_menu_custom;

	/* skins */

extern SkinData *skin;
extern SkinData *skin_normal;
extern SkinData *skin_small;

	/* file lists */
extern GList *filelist;
extern GList *dirlist;

	/* filtering */
extern GList *filter;
extern gint disable_filtering;
extern gint show_dot_files;

	/* playlist info */
extern gchar *playlist_pathname;
extern gchar *playlist_filename;

	/* song time info */
extern gint seconds;
extern gint seconds_remaining;
extern gint frames;
extern gint frames_remaining;

	/* input info */
extern gint input_channels;
extern gint input_hz;
extern gint input_bitrate;

	/* output info */
extern gint output_channels;
extern gint output_hz;
extern gint output_bits;

	/* soon to be removed, but not until necessary (more players added)
	 * because this will effect the skin format by deprecating
	 * MP3 specific widgets
	 * possible problem with backwards skin compatibility !!!
	 */
extern gint mpeg_version;
extern gint mpeg_layer;
extern gint mpeg_mode;

	/* options */
extern gint initial_playlist_mode;
extern gchar *initial_playlist_pathname;
extern gint initial_playlist_position;
extern gint initial_directory_enable;
extern gchar *initial_directory_path;
extern gint show_playlist_on_startup;
extern gint start_playing_on_startup;
extern gint smart_window_placement;
extern gint read_header_tags;
extern gint playlist_accounting;
extern gint remember_window_position;
extern gint window_pos_x;
extern gint window_pos_y;
extern gint window_list_x;
extern gint window_list_y;
extern gint window_list_w;
extern gint window_list_h;
extern gint alternate_skin;
extern gint wm_decorations;
extern gint prev_includes_current;

	/* miscellaneous */
extern gchar *current_path;
extern gchar *mixer_command;
extern gint mixer_device_id;

extern gint status;
extern gint repeat_mode;
extern gint shuffle_mode;
extern gint save_mode_in_playlist;
extern gint obey_mode_in_playlist;

extern gchar *preset_name[];
extern gchar *preset_file[];
extern gint play_presets;
extern gint show_remaining_time;

extern int pid;

extern gchar *default_skin;

extern gint pos_slider_in_drag;
extern gint new_song;

extern gint show_extra_winamp_info;
extern gint double_size_mode;

extern gint debug_mode;
extern gint debug_skin;

extern gchar **gqmpeg_icon_xpm;

extern gint allow_ipc;

extern gint dock_mode;

extern gint drop_single_to_playlist;

/*
 *----------------------------------------------------------------------------
 * global functions
 *----------------------------------------------------------------------------
 */

/*
 * =========================== btn_funcs.c
 */
gint main_window_widgets_update();
void btn_play_pressed();
void btn_stop_pressed();
void btn_pause_pressed();

void btn_next_pressed();
void btn_prev_pressed();
void btn_next_down();
void btn_next_up();
void btn_prev_down();
void btn_prev_up();

void position_slider_moved(float pos);
void position_slider_released(float pos);
void btn_rw_pressed();
void btn_ff_pressed();
void btn_rw_down();
void btn_rw_up();
void btn_ff_down();
void btn_ff_up();

void volume_slider_moved(float pos);
void btn_volume_up_pressed();
void btn_volume_down_pressed();
void btn_volume_released();

void balance_slider_moved(float pos);
void btn_balance_left_pressed();
void btn_balance_right_pressed();
void btn_balance_released();

void btn_shuffle_pressed();
void btn_repeat_pressed();
void time_toggle_pressed();
void btn_iconify_pressed();
void btn_mixer_pressed();
void current_song_info_pressed();

void btn_load_playlist_pressed();
void btn_load_file_pressed();
void btn_load_custom_pressed();

void preset_1_pressed();
void preset_2_pressed();
void preset_3_pressed();
void preset_4_pressed();
void preset_5_pressed();
void preset_6_pressed();
void preset_7_pressed();
void preset_8_pressed();
void preset_9_pressed();
void preset_10_pressed();

/*
 * =========================== config.c
 */
void show_about_info();
void show_configuration_window();

/*
 * =========================== cpu_perc.c
 */
gfloat check_child_cpu_usage(int childs_pid);

/*
 * =========================== display.c
 */
void display_freeze();
void display_thaw();
void display_draw_song_count(gint n, gint redraw);
void display_draw_song_number(gint n, gint redraw);
void display_draw_shuffle(gint redraw);
void display_draw_repeat(gint redraw);
void display_draw_position(gint redraw);
void display_draw_volume(gint redraw);
void display_draw_balance(gint redraw);
void display_draw_status(gint redraw);
void display_draw_frame_count(gint n, gint redraw);
void display_draw_cpu(gfloat percentf, gint redraw);
void display_draw_time(gint count, gint remain, gint redraw);
void display_draw_io_information(gint zero, gint redraw);
void display_draw_song_text_info(gint n, gint current, gint redraw);
void display_draw_title(gchar *text, gint redraw);
void display_flush();
void display_draw_song_info(gint redraw);
void display_draw_all(gint redraw);

/*
 * =========================== dndutil.c
 */
GList *uri_get_list(gchar *data);
gchar *uri_create_text(GList *list, gint *t, gint plain_text);
void dnd_init();

/*
 * =========================== dock.c
 */
void winmaker_setup_dock(char *argv[]);

/*
 * =========================== filelist.c
 */
gint filelist_count();
void filelist_add_item(gchar *path);
void filelist_insert_item(gchar *path, gint n);
void filelist_remove_item(gint n);
void filelist_swap_items(gint n1, gint n2);
gchar *filelist_get_item(gint n);
gchar *filelist_get_path(gint n);
gint dirlist_count();
void dirlist_add_item(gchar *path);
void dirlist_insert_item(gchar *path, gint n);
void dirlist_remove_item(gint n);
void dirlist_swap_items(gint n1, gint n2);
gchar *dirlist_get_item(gint n);
gchar *dirlist_get_path(gint n);
void filelist_refresh();
void change_to_path(gchar *path);

/*
 * =========================== fileops.c
 */
gchar *homedir();
int isfile(char *s);
int isdir(char *s);
int filesize(char *s);
gchar *get_current_dir();
int copy_file(char *s, char *t);
int move_file(char *s, char *t);

/*
 * =========================== globals.c
 */
void init_vars();

/*
 * =========================== ipc.c
 */
void ipc_send(gchar *command);
void ipc_on();
void ipc_off();
gint ipc_another_process_active();

/*
 * =========================== main.c
 */
gchar *filename_from_path(char *t);
gchar *remove_level_from_path(gchar *path);
void parse_out_relatives(gchar *path);
gint file_in_path(gchar *file);

SongData *current_song_get_data();
gint current_song_get_number();
void current_song_set(gint n, gchar *path);
gint current_song_is_in_playlist();
void current_song_set_to_next();
void current_song_set_to_prev();
void current_song_set_and_play(gint n, gchar *path);
gchar *current_song_get_path();
gchar *current_song_get_title();
gchar *current_song_get_artist();
gchar *current_song_get_album();
gchar *current_song_get_genre();

void gqmpeg_exit();

/*
 * =========================== menus.c
 */
void create_preset_menu();
GtkWidget *create_main_menu();
GtkWidget *create_dir_menu();
GtkWidget *create_file_menu();
GtkWidget *create_file_menu_list();
GtkWidget *create_playlist_menu();
GtkWidget *create_playlist_menu_custom();

/*
 * =========================== mixer.c
 */
void mixer_init(gint init_device_id);
void set_volume(gint vol);
gint get_volume();
void set_balance(gint bal);
gint get_balance();

GList *get_mixer_device_list();
gint get_mixer_device_id(gchar *device_name);
void set_mixer_device(gint device_id);

/*
 * =========================== pathsel.c
 */
GtkWidget *destination_widget_new_with_files(gchar *path, gchar *filter, GtkWidget *entry);
GtkWidget *destination_widget_new(gchar *path, GtkWidget *entry);
void destination_widget_sync_to_entry(GtkWidget *entry);

/*
 * =========================== players.c
 */
void player_modules_init();
void player_modules_config_load(FILE *f, gchar *option, gchar *value, gchar *value_all);
void player_modules_config_save(FILE *f);
GList *player_modules_config_init();
void player_modules_config_apply();
void player_modules_config_close();

SongData *player_module_songdata_init(gchar *path);
gint player_module_songdata_update(SongData *sd, gint generic_info, gint format_info);
GtkWidget *player_module_songdata_detail_info(gchar *path);

gint playback_start(SongData *sd, gint seconds);
gint playback_stop(SongData *sd);
gint playback_pause(SongData *sd);
gint playback_continue(SongData *sd);
gint playback_seek(SongData *sd, gint seconds);

/*
 * =========================== playlist-dlg.c
 */
void playlist_dialog_save_as(gchar *path);
void playlist_dialog_load(gchar *path);
void playlist_dialog_append(gchar *path);
void playlist_dialog_import(gchar *path);

void playlist_dialog_add_custom_type(gint to_playlist);
void playlist_dialog_edit_custom_type(SongData *sd);

void playlist_dialog_load_file(gchar *path, gint to_playlist);

/*
 * =========================== playlist-window.c
 */
void playlist_window_clist_append(gint n);
void playlist_window_clist_insert(gint n);
void playlist_window_clist_move(gint s, gint t);
void playlist_window_clist_remove(gint n);
void playlist_window_clist_update_item(gint n);
void playlist_window_clist_clear();
void playlist_window_clist_populate();

GList *clist_get_selection_list(GtkCList *clist);
void free_selection_list(GList *list);

void plw_add_dir_pressed();
void plw_add_dir_recursive_pressed();

void plw_filelist_songinfo_pressed();
void plw_filelist_move_pressed();
void plw_filelist_copy_pressed();
void plw_filelist_rename_pressed();
void plw_filelist_delete_pressed();
void plw_filelist_add_play_pressed();
void plw_filelist_play_pressed();
void plw_filelist_add_pressed();
void plw_filelist_insert_pressed();
void plw_load_pressed();
void plw_append_pressed();

void plw_playlist_songinfo_pressed();
void plw_playlist_edit_pressed();
void plw_playlist_move_pressed();
void plw_playlist_copy_pressed();
void plw_playlist_rename_pressed();
void plw_playlist_delete_pressed();
void plw_playlist_remove_pressed();
void plw_playlist_play_pressed();

void playlist_window_length_update();
void playlist_window_update_titles();

void playlist_window_filelist_update();

void playlist_window_show();
void playlist_window_hide();

/*
 * =========================== playlist.c
 */
void shuffle_list_create(gint start_with_current);
void shuffle_list_destroy();

gint playlist_load(gchar *fn, gint append, gint strict);
gint playlist_load_from_file(gchar *path, gint append, gint strict);
gint playlist_save(gchar *fn);

void playlist_append_from_dir(gchar *path, gint recursive);

SongData *playlist_new_data(gchar *path);
void playlist_free_data(SongData *sd);

SongData *playlist_get_data(gint n);
gchar *playlist_get_item(gint n);
gchar *playlist_get_title(gint n);
gchar *playlist_get_artist(gint n);
gchar *playlist_get_album(gint n);
gchar *playlist_get_genre(gint n);
gint playlist_item_is_live(gint n);
gint playlist_item_is_custom(gint n);
gint playlist_get_index(gchar *path);
gint playlist_get_index_by_data(SongData *sd);
gint playlist_get_count();
gint playlist_get_length();
gint playlist_get_next(gint n);
gint playlist_get_prev(gint n);
gint playlist_get_first();

void playlist_update_all_info(gint generic_info, gint format_info);
void playlist_update_generic_info();
void playlist_update_format_info();
void playlist_sort_by_func(GCompareFunc sort_func);

void playlist_add(gchar *path);
void playlist_insert(gchar *path, gint n);
void playlist_move(gint s, gint t);
gint playlist_remove(gchar *path, gint n, gint all);
void playlist_update(gint n, gchar *path);
void playlist_update_by_path(gchar *path);
void playlist_replace(gchar *old_path, gchar *new_path);
void playlist_clear();

gint is_playlist(gchar *path);

/*
 * =========================== rcfile.c
 */
gchar *quoted_value(gchar *text);
void write_char_option(FILE *f, gchar *label, gchar *text);
gchar *read_char_option(FILE *f, gchar *option, gchar *label, gchar *value, gchar *text);
void write_int_option(FILE *f, gchar *label, gint n);
gint read_int_option(FILE *f, gchar *option, gchar *label, gchar *value, gint n);
void write_bool_option(FILE *f, gchar *label, gint n);
gint read_bool_option(FILE *f, gchar *option, gchar *label, gchar *value, gint n);
void save_options();
void load_options();

/*
 * =========================== skindef.c
 */
SkinData *load_default_normal_skin();
SkinData *load_default_small_skin();

/*
 * =========================== skinui.c
 */
GdkPixmap *get_pixmap_from_data(gchar **data);
GdkPixmap *get_pixmap_from_file(gchar *path);
GdkBitmap *get_bitmap_from_file(gchar *path);

void redraw_skin();
ButtonData *new_button(GdkPixmap *pixmap, gint prelight, gint light, gint x, gint y,
                void (*click_func)(void *), void (*press_func)(void *), void (*release_func)(void *));
ButtonData *new_button_from_data(gchar **data, gint prelight, gint light, gint x, gint y,
                void (*click_func)(void *), void (*press_func)(void *), void (*release_func)(void *));
ButtonData *new_button_from_file(gchar *file, gint prelight, gint light, gint x, gint y,
                void (*click_func)(void *), void (*press_func)(void *), void (*release_func)(void *));
DigitData *new_digit(GdkPixmap *pixmap);
DigitData *new_digit_from_data(gchar **data);
DigitData *new_digit_from_file(gchar *file);
FontData * new_font(GdkPixmap *pixmap, gint length, gint extended, gint x, gint y);
FontData * new_font_from_data(gchar **data, gint length, gint extended, gint x, gint y);
FontData * new_font_from_file(gchar *file, gint length, gint extended, gint x, gint y);
NumberData *new_number(DigitData *digits, gint length, gint zeros, gint x, gint y);
NumberData *new_number_from_data(gchar **data, gint length, gint zeros, gint x, gint y);
NumberData *new_number_from_file(gchar *file, gint length, gint zeros, gint x, gint y);
ItemData *new_item(GdkPixmap *pixmap, gint sections, gint x, gint y);
ItemData *new_item_from_data(gchar **data, gint sections, gint x, gint y);
ItemData *new_item_from_file(gchar *file, gint sections, gint x, gint y);
SliderData *new_slider(GdkPixmap *pixmap, gint prelight, gint verticle, gint reversed,
                        gint length, gint x, gint y, ItemData *item,
                        void (*press_func)(float), void (*release_func)(float),
                        void (*move_func)(float));
SliderData *new_slider_from_data(gchar **data, gint prelight, gint verticle, gint reversed,
                        gint length, gint x, gint y, ItemData *item,
                        void (*press_func)(float), void (*release_func)(float),
                        void (*move_func)(float));
SliderData *new_slider_from_file(gchar *file, gint prelight, gint verticle, gint reversed,
                        gint length, gint x, gint y, ItemData *item,
                        void (*press_func)(float), void (*release_func)(float),
                        void (*move_func)(float));
SkinData *new_skin();
void sync_window_to_skin();
void free_skin(SkinData *s);

void draw_number(NumberData *number, gint n);
void draw_font(FontData *font);
void set_font_text(FontData *font, gchar *text);
void update_font(FontData *font);
void draw_item(ItemData *item, gint section);
void change_button_light(ButtonData *button, gint lit);
void draw_button(ButtonData *button, gint prelight, gint pressed, gint force);
void draw_slider(SliderData *slider, float position, gint absolute, gint move,
                        gint prelight, gint pushed, gint force);

void setup_display();
void mode_button_pressed();

/*
 * =========================== skinutil.c
 */
gint change_to_skin(gchar *file);

/*
 * =========================== skinwamp.c
 */
SkinData *load_wamp_normal_skin(gchar *path);
SkinData *load_wamp_small_skin(gchar *path);

/*
 * =========================== songinfo.c
 */
void view_song_info(gchar *path);

/*
 * =========================== tabcomp.c
 */
GtkWidget *tab_completion_new(GtkWidget **entry, GtkWidget *window, gchar *text,
			      void (*enter_func)(gchar *, gpointer), gpointer data);
void tab_completion_add_to_entry(GtkWidget *entry, void (*enter_func)(gchar *, gpointer), gpointer data);
void tab_completion_add_tab_func(GtkWidget *entry, void (*tab_func)(gchar *, gpointer), gpointer data);
gchar *remove_trailing_slash(gchar *path);

/*
 * =========================== types.c
 */
gint file_is_hidden(gchar *name);
gint file_is_in_filter(gchar *name);
void add_to_filter(gchar *text, gchar *description, gint module_id);
void remove_from_filter(gchar *text);
gint filter_determine_module_id(gchar *path);
gchar *filter_get_text_list();

void add_to_typelist(gchar *format, gchar *description, gint module_id, gint live,
		     gint (*is_type_func)(gchar *),
		     GtkWidget *(*entry_setup_func)(gchar *),
		     GtkWidget *(*edit_func)(SongData *),
		     gchar *(*get_path_func)(GtkWidget *));
gint typelist_determine_module_id(gchar *path);
gint typelist_determine_type_id(gchar *path);
void typelist_determine_ids(gchar *path, gint *module_id, gint *custom, gint *custom_type, gint *live);
GtkWidget *typelist_get_entry_widget_by_id(gint id, gchar *path);
GtkWidget *typelist_get_edit_widget_by_id(gint id, SongData *sd);
gchar *typelist_get_path_from_widget(gint id, GtkWidget *widget);
GList *typelist_get_description_list();

/*
 * =========================== utilops.c
 */
void file_util_move(gchar *source_path, GList *source_list, gchar *dest_path);
void file_util_copy(gchar *source_path, GList *source_list, gchar *dest_path);
void file_util_delete(gchar *source_path, GList *source_list);
void file_util_rename(gchar *source_path, GList *source_list);
void file_util_create_dir(gchar *path);

/*
 * =========================== window.c
 */
void create_main_window(gchar *skin_path);



