/* $Id: xkbsel.h,v 1.4 1999/07/24 15:13:16 stano Exp $

   Library functions to be used by the callers

   This is the only file to be included by the clients not using X

   (C) 1999 Stanislav Meduna <stano@eunet.sk>
*/

#ifndef _XKBSEL_H_
#define _XKBSEL_H_

#include <stdio.h>

#ifdef __cplusplus
  extern "C" {
#endif

/* === Database record and associated data === */

/* Max length of the shortcut */
#define MAX_SHORTCUT_LEN     16

/* Max length of the relative path to the data */
#define MAX_DATA_PATH_LEN    64

/* Max length of the description */
#define MAX_DESCRIPTION_LEN  80

/* Source of the data. Caution: ordering matters */
typedef enum
{
	DEFAULT,   /* not explicitly defined - use default */
	X11_DISTR, /* X distribution */
	SYS_DISTR, /* package directory */
	SYS_REDEF, /* package redefinition files */
	USER,      /* user definition */
	USER_REDEF /* user redefinition file */
} data_source_t;

/* Database record */

typedef struct
{
	char map_name[MAX_DATA_PATH_LEN+1];

	char descr[MAX_DESCRIPTION_LEN+1];
	data_source_t descr_src;

	char keymap[MAX_DATA_PATH_LEN+1];
	data_source_t keymap_src;
	
	char pixmap[MAX_DATA_PATH_LEN+1];
	data_source_t pixmap_src;
} db_record_t;

/* Open the system database and the user one (if present) for reading */
int open_db(void);

/* Read the data for a specified map
   Expects valid map_name, the rest will be filled in
*/
int read_db(db_record_t *rec, int *found);

/* Read the data for a specified map
*/
int read_db_name(const char *name, db_record_t *rec, int *found);

/* Traverse the data (from the system or user view) */
int traverse_db(int userview, int first, db_record_t *rec, int *found);

/* Close the database(s) */
int close_db(void);

/* Output the content of the record in readable form */
void print_record(FILE *fp, const db_record_t *rec);


/* === Configuration === */

/* Library name and version */
extern const char *xkbsel_package;
extern const char *xkbsel_version;

/* For GUI menus etc. */
typedef struct
{
	char shortcut[MAX_SHORTCUT_LEN+1];

	char map_name[MAX_DATA_PATH_LEN+1];
} sel_info_t;

/* Caution: the user directories need not exist */
extern char *x11_xkb_dir;
extern char *x11_keymap_dir;
extern char *sys_dir;
extern char *sys_keymap_dir;
extern char *sys_redef_dir;
extern char *sys_pixmap_dir;
extern char *user_dir;
extern char *user_keymap_dir;
extern char *user_redef_dir;
extern char *user_pixmap_dir;
extern char *sys_db;
extern char *user_db;
extern char *sys_xkm_dir;
extern char *user_xkm_dir;
extern char *sys_config;
extern char *user_config;

/* Will be set to $DISPLAY or :0.0, if not set explicitly
   before calling read_config
*/
extern char *display_name;

/* Will be set to locale language and region, if not
   set explicitely before calling read_config. Assume
   portable locale if empty.

   Don't forget to call setlocale(LC_ALL, "") or equivalent
   at the beginning of the program, otherwise you won't get
   anything useful.

   You can force a locale by setting XKBSEL_LOCALE.
*/
extern char *locale_lang;
extern char *locale_territ;

extern int flag_verbose;
extern int flag_debug;

extern int xkbcomp_has_bug; /* -1 if unknown, 0 if no, 1 if yes */

/* A list of all configured maps */
extern sel_info_t *cfg_maps;
extern int        n_cfg_maps;

/* A list of maps valid for the specified locale (for GUI selectors) */
extern sel_info_t *locale_maps;
extern int        n_locale_maps;

/* Fill in the configuration */
int read_config(void);

/* Create user directories */
int create_user_dirs();

/* Take a shortcut and fill a map name */
int get_locale_map(const char *shortcut, sel_info_t *info, int *idx, int *found);

/* Take a shortcut and fill a map name */
int get_cfg_map(const char *shortcut, sel_info_t *info, int *idx, int *found);

/* === Keymap handling === */

/* Unconditionally compile a map according to the map name.
   The databases must be open (calls read_db internally)
*/
int compile_map(const char *name);

/* Conditionally compile map, if not present
*/
int compile_map_if_needed(const char *name, char **file_name);

/* Install a map (eventually compile first)
   The databases must be open (calls read_db internally).
   Can parse shortcuts.
*/
int install_map(const char *name);

/* === Utilities === */

/* A dynamic list of names
   strings    ... pointer to the list
   nstrings   ... current number of items
   nalloc     ... keeps track of allocated space
*/

/* Start a new list */
void list_start(char ***strings, int *nstrings, int *nalloc);

/* Append a string to the list */
int list_append(char ***strings, int *nstrings, int *nalloc, const char *str);

/* Append a dynamically allocated string to the list (will be freed by list_free)*/
int list_append_ptr(char ***strings, int *nstrings, int *nalloc, char *str);

/* Free the list and all items */
void list_free(char ***strings, int *nstrings, int *nalloc);

/* Sort the list */
void list_sort(char ***strings, int *nstrings, int *nalloc);

/* Print a formatted help line */
void help_line(const char *short_opt, const char *long_opt, const char *descr);

#ifdef __cplusplus
  }
#endif

#endif /* _XKBSEL_H_ */
