Commit aa4225777de5428a49f30ceb019761e39a996148

Authored by Perry Werneck
1 parent d15da6e1
Exists in v5.2

Adding support for session file set.

configure.ac
... ... @@ -483,7 +483,6 @@ dnl ---------------------------------------------------------------------------
483 483  
484 484 AC_CONFIG_FILES(src/pw3270/Makefile)
485 485 AC_CONFIG_FILES(src/pw3270/uiparser/Makefile)
486   -AC_CONFIG_FILES(src/pw3270/common/Makefile)
487 486  
488 487 AC_CONFIG_FILES(src/libpw3270cpp/Makefile)
489 488  
... ...
pw3270.cbp
... ... @@ -134,6 +134,7 @@
134 134 <Unit filename="src/pw3270/colors.c">
135 135 <Option compilerVar="CC" />
136 136 </Unit>
  137 + <Unit filename="src/pw3270/common.h" />
137 138 <Unit filename="src/pw3270/common/common.h" />
138 139 <Unit filename="src/pw3270/common/config.c">
139 140 <Option compilerVar="CC" />
... ... @@ -153,6 +154,9 @@
153 154 </Unit>
154 155 <Unit filename="src/pw3270/include/v3270.h" />
155 156 <Unit filename="src/pw3270/include/v3270ft.h" />
  157 + <Unit filename="src/pw3270/linux/config.c">
  158 + <Option compilerVar="CC" />
  159 + </Unit>
156 160 <Unit filename="src/pw3270/linux/print.c">
157 161 <Option compilerVar="CC" />
158 162 </Unit>
... ... @@ -235,6 +239,9 @@
235 239 <Unit filename="src/pw3270/window.c">
236 240 <Option compilerVar="CC" />
237 241 </Unit>
  242 + <Unit filename="src/pw3270/windows/config.c">
  243 + <Option compilerVar="CC" />
  244 + </Unit>
238 245 <Unit filename="src/pw3270/windows/print.c">
239 246 <Option compilerVar="CC" />
240 247 </Unit>
... ...
src/pw3270/Makefile.in
... ... @@ -45,8 +45,7 @@ APP_SOURCES=\
45 45 $(wildcard @OSNAME@/*.rc)
46 46  
47 47 MODULES=\
48   - uiparser \
49   - common
  48 + uiparser
50 49  
51 50 #---[ Configuration values ]-------------------------------------------------------------
52 51  
... ...
src/pw3270/common.h 0 → 100644
... ... @@ -0,0 +1,89 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como common.h e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + *
  28 + */
  29 +
  30 +#ifndef COMMON_H_INCLUDED
  31 +
  32 + #include <config.h>
  33 +
  34 +#ifdef _WIN32
  35 + #include <windows.h>
  36 +#endif // _WIN32
  37 +
  38 +
  39 + #define COMMON_H_INCLUDED 1
  40 +
  41 + #include <gtk/gtk.h>
  42 + #include <errno.h>
  43 +
  44 + #ifndef GETTEXT_PACKAGE
  45 + #define GETTEXT_PACKAGE PACKAGE_NAME
  46 + #endif
  47 +
  48 + #include <libintl.h>
  49 + #include <lib3270.h>
  50 + #include <glib/gi18n.h>
  51 + #include <gtk/gtk.h>
  52 +
  53 + #if defined( DEBUG )
  54 + #define trace(x, ...) fprintf(stderr,"%s(%d):\t" x "\n",__FILE__,__LINE__, __VA_ARGS__); fflush(stderr);
  55 + #else
  56 + #define trace(x, ...) /* */
  57 + #endif
  58 +
  59 + // Configuration
  60 + LIB3270_EXPORT void pw3270_session_config_load(const gchar *filename);
  61 + LIB3270_EXPORT void pw3270_session_config_free(void);
  62 + LIB3270_EXPORT GKeyFile * pw3270_session_config_get(void);
  63 +
  64 + gchar * get_string_from_config(const gchar *group, const gchar *key, const gchar *def);
  65 + gboolean get_boolean_from_config(const gchar *group, const gchar *key, gboolean def);
  66 + gint get_integer_from_config(const gchar *group, const gchar *key, gint def);
  67 +
  68 + void set_string_to_config(const gchar *group, const gchar *key, const gchar *fmt, ...);
  69 + void set_boolean_to_config(const gchar *group, const gchar *key, gboolean val);
  70 + void set_integer_to_config(const gchar *group, const gchar *key, gint val);
  71 +
  72 + gchar * build_data_filename(const gchar *first_element, ...);
  73 + gchar * filename_from_va(const gchar *first_element, va_list args);
  74 +
  75 + void save_window_state_to_config(const gchar *group, const gchar *key, GdkWindowState CurrentState);
  76 + void save_window_size_to_config(const gchar *group, const gchar *key, GtkWidget *hwnd);
  77 +
  78 + void restore_window_from_config(const gchar *group, const gchar *key, GtkWidget *hwnd);
  79 +
  80 + #ifdef ENABLE_WINDOWS_REGISTRY
  81 + gboolean get_registry_handle(const gchar *group, HKEY *hKey, REGSAM samDesired);
  82 + HKEY get_application_registry(REGSAM samDesired);
  83 + void registry_foreach(HKEY parent, const gchar *name,void (*cbk)(const gchar *key, const gchar *val, gpointer *user_data), gpointer *user_data);
  84 + void registry_set_double(HKEY hKey, const gchar *key, gdouble value);
  85 + gboolean registry_get_double(HKEY hKey, const gchar *key, gdouble *value);
  86 + #endif // ENABLE_WINDOWS_REGISTRY
  87 +
  88 +
  89 +#endif
... ...
src/pw3270/common/Makefile.in
... ... @@ -1,174 +0,0 @@
1   -#
2   -# "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
3   -# (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
4   -# aplicativos mainframe. Registro no INPI sob o nome G3270.
5   -#
6   -# Copyright (C) <2008> <Banco do Brasil S.A.>
7   -#
8   -# Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
9   -# os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
10   -# Free Software Foundation.
11   -#
12   -# Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
13   -# GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
14   -# A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
15   -# obter mais detalhes.
16   -#
17   -# Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
18   -# programa; se não, escreva para a Free Software Foundation, Inc., 59 Temple
19   -# Place, Suite 330, Boston, MA, 02111-1307, USA
20   -#
21   -# Contatos:
22   -#
23   -# perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
24   -# erico.mendonca@gmail.com (Erico Mascarenhas de Mendonça)
25   -#
26   -
27   -MODULE_NAME=common
28   -
29   -SOURCES=config.c
30   -
31   -#---[ Configuration values ]-------------------------------------------------------------
32   -
33   -PACKAGE_NAME=@PACKAGE_NAME@
34   -PACKAGE_VERSION=@PACKAGE_VERSION@
35   -PACKAGE_TARNAME=@PACKAGE_TARNAME@
36   -
37   -prefix=@prefix@
38   -exec_prefix=@exec_prefix@
39   -bindir=@bindir@
40   -sbindir=@sbindir@
41   -libdir=@libdir@
42   -datarootdir=@datarootdir@
43   -
44   -BASEDIR=@BASEDIR@
45   -SRCDIR=$(BASEDIR)/.src/$(PACKAGE_TARNAME)-$(PACKAGE_VERSION)/src/pw3270/$(MODULE_NAME)
46   -POTDIR=$(BASEDIR)/.pot/$(PACKAGE_TARNAME)/$(MODULE_NAME)
47   -
48   -OBJDIR=$(BASEDIR)/.obj/application/common
49   -OBJDBG=$(OBJDIR)/Debug
50   -OBJRLS=$(OBJDIR)/Release
51   -
52   -MKDIR=@MKDIR_P@
53   -CC=@CC@
54   -LD=@CC@
55   -AR=@AR@
56   -XGETTEXT=@XGETTEXT@
57   -MSGCAT=@MSGCAT@
58   -INSTALL=@INSTALL@
59   -INSTALL_DATA=@INSTALL_DATA@
60   -
61   -CFLAGS= \
62   - @CFLAGS@ \
63   - @LIB3270_CFLAGS@ \
64   - @LIBV3270_CFLAGS@ \
65   - @PW3270_CFLAGS@ \
66   - -Wno-deprecated-declarations \
67   - -DDATAROOTDIR=\"$(datarootdir)\" \
68   - @GTK_CFLAGS@
69   -
70   -LIBS= \
71   - @LIBS@ \
72   - @GTK_LIBS@ \
73   - @LIB3270_LIBS@ \
74   - @LIBV3270_LIBS@
75   -
76   -#---[ Rules ]----------------------------------------------------------------------------
77   -
78   -DEPENDS= \
79   - ../../include/*.h
80   -
81   -$(OBJDBG)/%.o: \
82   - %.c \
83   - $(DEPENDS)
84   -
85   - @echo $< ...
86   - @$(MKDIR) `dirname $@`
87   - @$(CC) $(CFLAGS) \
88   - @DBG_CFLAGS@ \
89   - -DBUILD_DATE=`date +"0x%Y%m%d"`\
90   - -o $@ -c $<
91   -
92   -$(OBJRLS)/%.o: \
93   - %.c \
94   - $(DEPENDS)
95   -
96   - @echo $< ...
97   - @$(MKDIR) `dirname $@`
98   - @$(CC) $(CFLAGS) \
99   - @RLS_CFLAGS@ \
100   - -DBUILD_DATE=`date +"0x%Y%m%d"` \
101   - -o $@ -c $<
102   -
103   -$(POTDIR)/%.pot: %.c
104   -
105   - @echo $(notdir $@) ...
106   - @$(MKDIR) `dirname $@`
107   - @$(XGETTEXT) \
108   - --default-domain=$(PACKAGE) \
109   - --language=C \
110   - --keyword=_ \
111   - --keyword=N_ \
112   - --keyword=MSG_:2 \
113   - --output=$@ \
114   - $<
115   -
116   - @touch $@
117   -
118   -#---[ Release Targets ]------------------------------------------------------------------
119   -
120   -Release: \
121   - $(BASEDIR)/.obj/Release/$(MODULE_NAME).a
122   -
123   -$(BASEDIR)/.obj/Release/$(MODULE_NAME).a: \
124   - $(foreach SRC, $(basename $(SOURCES)), $(OBJRLS)/$(SRC).o)
125   -
126   - @echo $@ ...
127   - @$(MKDIR) `dirname $@`
128   - @$(AR) rcs $@ $^
129   -
130   -pot: \
131   - $(BASEDIR)/.pot/$(PACKAGE_TARNAME)/$(MODULE_NAME).pot
132   -
133   -$(BASEDIR)/.pot/$(PACKAGE_TARNAME)/$(MODULE_NAME).pot: \
134   - $(foreach SRC, $(basename $(SOURCES)), $(POTDIR)/$(SRC).pot)
135   -
136   - @rm -f $@
137   - @mkdir -p `dirname $@`
138   - @$(MSGCAT) --sort-output $^ > $@
139   -
140   -$(SRCDIR): \
141   - clean
142   -
143   - @$(MKDIR) $@
144   - @$(INSTALL_DATA) *.c *.h *.in $@
145   -
146   -#---[ Debug Targets ]--------------------------------------------------------------------
147   -
148   -Debug: \
149   - $(BASEDIR)/.obj/Debug/$(MODULE_NAME).a
150   -
151   -$(BASEDIR)/.obj/Debug/$(MODULE_NAME).a: \
152   - $(foreach SRC, $(basename $(SOURCES)), $(OBJDBG)/$(SRC).o)
153   -
154   - @echo $@ ...
155   - @$(MKDIR) `dirname $@`
156   - @$(AR) rcs $@ $^
157   -
158   -#---[ Clean Targets]---------------------------------------------------------------------
159   -
160   -cleanDebug:
161   -
162   - @rm -fr $(BASEDIR)/.obj/Debug/$(MODULE_NAME).a \
163   - $(OBJDBG)
164   -
165   -cleanRelease:
166   -
167   - @rm -fr $(BASEDIR)/.obj/Release/$(MODULE_NAME).a \
168   - $(OBJRLS)
169   -
170   -clean: \
171   - cleanDebug \
172   - cleanRelease
173   -
174   -
src/pw3270/common/common.h
... ... @@ -1,89 +0,0 @@
1   -/*
2   - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
3   - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
4   - * aplicativos mainframe. Registro no INPI sob o nome G3270.
5   - *
6   - * Copyright (C) <2008> <Banco do Brasil S.A.>
7   - *
8   - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
9   - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
10   - * Free Software Foundation.
11   - *
12   - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
13   - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
14   - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
15   - * obter mais detalhes.
16   - *
17   - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
18   - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
19   - * St, Fifth Floor, Boston, MA 02110-1301 USA
20   - *
21   - * Este programa está nomeado como common.h e possui - linhas de código.
22   - *
23   - * Contatos:
24   - *
25   - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
26   - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
27   - *
28   - */
29   -
30   -#ifndef COMMON_H_INCLUDED
31   -
32   - #include <config.h>
33   -
34   -#ifdef _WIN32
35   - #include <windows.h>
36   -#endif // _WIN32
37   -
38   -
39   - #define COMMON_H_INCLUDED 1
40   -
41   - #include <gtk/gtk.h>
42   - #include <errno.h>
43   -
44   - #ifndef GETTEXT_PACKAGE
45   - #define GETTEXT_PACKAGE PACKAGE_NAME
46   - #endif
47   -
48   - #include <libintl.h>
49   - #include <glib/gi18n.h>
50   - #include <gtk/gtk.h>
51   -
52   - #if defined( DEBUG )
53   - #define trace(x, ...) fprintf(stderr,"%s(%d):\t" x "\n",__FILE__,__LINE__, __VA_ARGS__); fflush(stderr);
54   - #else
55   - #define trace(x, ...) /* */
56   - #endif
57   -
58   - // Configuration
59   - void configuration_init(void);
60   - void configuration_deinit(void);
61   -
62   - gchar * get_string_from_config(const gchar *group, const gchar *key, const gchar *def);
63   - gboolean get_boolean_from_config(const gchar *group, const gchar *key, gboolean def);
64   - gint get_integer_from_config(const gchar *group, const gchar *key, gint def);
65   -
66   - void set_string_to_config(const gchar *group, const gchar *key, const gchar *fmt, ...);
67   - void set_boolean_to_config(const gchar *group, const gchar *key, gboolean val);
68   - void set_integer_to_config(const gchar *group, const gchar *key, gint val);
69   -
70   - gchar * build_data_filename(const gchar *first_element, ...);
71   - gchar * filename_from_va(const gchar *first_element, va_list args);
72   -
73   - void save_window_state_to_config(const gchar *group, const gchar *key, GdkWindowState CurrentState);
74   - void save_window_size_to_config(const gchar *group, const gchar *key, GtkWidget *hwnd);
75   -
76   - void restore_window_from_config(const gchar *group, const gchar *key, GtkWidget *hwnd);
77   -
78   - #ifdef ENABLE_WINDOWS_REGISTRY
79   - gboolean get_registry_handle(const gchar *group, HKEY *hKey, REGSAM samDesired);
80   - HKEY get_application_registry(REGSAM samDesired);
81   - void registry_foreach(HKEY parent, const gchar *name,void (*cbk)(const gchar *key, const gchar *val, gpointer *user_data), gpointer *user_data);
82   - void registry_set_double(HKEY hKey, const gchar *key, gdouble value);
83   - gboolean registry_get_double(HKEY hKey, const gchar *key, gdouble *value);
84   - #else
85   - GKeyFile * get_application_keyfile(void);
86   - #endif // ENABLE_WINDOWS_REGISTRY
87   -
88   -
89   -#endif
src/pw3270/common/config.c
... ... @@ -1,938 +0,0 @@
1   -/*
2   - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
3   - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
4   - * aplicativos mainframe. Registro no INPI sob o nome G3270.
5   - *
6   - * Copyright (C) <2008> <Banco do Brasil S.A.>
7   - *
8   - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
9   - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
10   - * Free Software Foundation.
11   - *
12   - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
13   - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
14   - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
15   - * obter mais detalhes.
16   - *
17   - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
18   - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
19   - * St, Fifth Floor, Boston, MA 02110-1301 USA
20   - *
21   - * Este programa está nomeado como config.c e possui - linhas de código.
22   - *
23   - * Contatos:
24   - *
25   - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
26   - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
27   - * licinio@bb.com.br (Licínio Luis Branco)
28   - * kraucer@bb.com.br (Kraucer Fernandes Mazuco)
29   - *
30   - */
31   -
32   -#ifdef _WIN32
33   - #include <windows.h>
34   -#endif // _WIN32
35   -
36   - #include "../pw3270/private.h"
37   -
38   - #include "common.h"
39   - #include <stdarg.h>
40   - #include <glib/gstdio.h>
41   -
42   -#ifdef _WIN32
43   -
44   - #include <windows.h>
45   -
46   - #ifndef KEY_WOW64_64KEY
47   - #define KEY_WOW64_64KEY 0x0100
48   - #endif // KEY_WOW64_64KEY
49   -
50   - #ifndef KEY_WOW64_32KEY
51   - #define KEY_WOW64_32KEY 0x0200
52   - #endif // KEY_WOW64_64KEY
53   -
54   -#endif // _WIN32
55   -
56   -/*--[ Globals ]--------------------------------------------------------------------------------------*/
57   -
58   -#ifdef ENABLE_WINDOWS_REGISTRY
59   -
60   - static const gchar * registry_path = "SOFTWARE";
61   -
62   -#else
63   -
64   - static GKeyFile * program_config = NULL;
65   -
66   -#endif // ENABLE_WINDOWS_REGISTRY
67   -
68   -/*--[ Implement ]------------------------------------------------------------------------------------*/
69   -
70   -#ifdef ENABLE_WINDOWS_REGISTRY
71   -
72   - enum REG_KEY
73   - {
74   - REG_KEY_USER,
75   - REG_KEY_SYSTEM,
76   - REG_KEY_INEXISTENT
77   - };
78   -
79   - static enum REG_KEY registry_query(const gchar *group, const gchar *key, HKEY *hKey)
80   - {
81   - static HKEY predefined[] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE };
82   - gchar * path = g_strdup_printf("%s\\%s\\%s",registry_path,g_get_application_name(),group);
83   - int f;
84   -
85   - for(f=0;f<G_N_ELEMENTS(predefined);f++)
86   - {
87   - if(RegOpenKeyEx(predefined[f],path,0,KEY_READ,hKey) == ERROR_SUCCESS)
88   - {
89   - if(RegQueryValueExA(*hKey,key,NULL,NULL,NULL,NULL) == ERROR_SUCCESS)
90   - {
91   - trace("Key\"%s\\%s\" found at id %d",path,key,f);
92   - g_free(path);
93   - return f;
94   - }
95   - RegCloseKey(*hKey);
96   - }
97   - }
98   -
99   - trace("Key \"%s\\%s\""" not found",path,key,f);
100   - g_free(path);
101   -
102   - return -1;
103   - }
104   -
105   - static BOOL registry_open_key(const gchar *group, const gchar *key, REGSAM samDesired, HKEY *hKey)
106   - {
107   - static HKEY predefined[] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE };
108   - int f;
109   - gchar * path = g_strdup_printf("%s\\%s\\%s",registry_path,g_get_application_name(),group);
110   -
111   - for(f=0;f<G_N_ELEMENTS(predefined);f++)
112   - {
113   - if(RegOpenKeyEx(predefined[f],path,0,samDesired,hKey) == ERROR_SUCCESS)
114   - {
115   - g_free(path);
116   - return TRUE;
117   - }
118   - }
119   -
120   - g_free(path);
121   -
122   - return FALSE;
123   - }
124   -
125   - void registry_foreach(HKEY parent, const gchar *name,void (*cbk)(const gchar *key, const gchar *val, gpointer *user_data), gpointer *user_data)
126   - {
127   - HKEY hKey = 0;
128   -
129   - if(RegOpenKeyEx(parent,name,0,KEY_READ,&hKey) == ERROR_SUCCESS)
130   - {
131   - #define MAX_KEY_LENGTH 255
132   - #define MAX_VALUE_NAME 16383
133   -
134   - TCHAR pName[MAX_KEY_LENGTH];
135   - DWORD cName = MAX_KEY_LENGTH;
136   - int ix = 0;
137   -
138   - while(RegEnumValue(hKey,ix++,pName,&cName,NULL,NULL,NULL,NULL) == ERROR_SUCCESS)
139   - {
140   - BYTE data[4097];
141   - unsigned long datatype;
142   - unsigned long datalen = 4096;
143   -
144   - if(RegQueryValueExA(hKey,pName,NULL,&datatype,data,&datalen) == ERROR_SUCCESS)
145   - {
146   - data[datalen+1] = 0;
147   - cbk(pName,(const gchar *) data, user_data);
148   - }
149   - cName = MAX_KEY_LENGTH;
150   - }
151   - RegCloseKey(hKey);
152   - }
153   - }
154   -
155   - void registry_set_double(HKEY hKey, const gchar *key, gdouble value)
156   - {
157   - // Reference: http://git.gnome.org/browse/glib/tree/glib/gkeyfile.c
158   - gchar result[G_ASCII_DTOSTR_BUF_SIZE];
159   - g_ascii_dtostr (result, sizeof (result), value);
160   -
161   - RegSetValueEx(hKey,key,0,REG_SZ,(const BYTE *) result,strlen(result)+1);
162   - }
163   -
164   - gboolean registry_get_double(HKEY hKey, const gchar *key, gdouble *value)
165   - {
166   -// GError * error = NULL;
167   - BYTE data[4096];
168   - unsigned long datatype;
169   - unsigned long datalen = sizeof(data);
170   - gchar * end_of_valid_d;
171   -
172   - if(RegQueryValueExA(hKey,key,NULL,&datatype,data,&datalen) != ERROR_SUCCESS)
173   - return FALSE;
174   -
175   - data[datalen] = 0;
176   -
177   - * value = g_ascii_strtod((const gchar *) data, &end_of_valid_d);
178   -
179   - if(*end_of_valid_d != '\0' || end_of_valid_d == ((gchar *) data))
180   - {
181   - g_warning("Key %s on registry isnt a valid double value",key);
182   - return FALSE;
183   - }
184   -
185   - return TRUE;
186   - }
187   -
188   -
189   -
190   -#else
191   -
192   - static gchar * search_for_ini(void)
193   - {
194   - static const gchar * (*dir[])(void) =
195   - {
196   - g_get_user_config_dir,
197   - g_get_user_data_dir,
198   - g_get_home_dir,
199   - };
200   -
201   - size_t f;
202   - g_autofree gchar * name = g_strconcat(g_get_application_name(),".conf",NULL);
203   -
204   - //
205   - // First search the user data
206   - //
207   -
208   - for(f=0;f<G_N_ELEMENTS(dir);f++)
209   - {
210   - gchar *filename = g_build_filename(dir[f](),name,NULL);
211   -
212   - trace("Checking for %s",filename);
213   -
214   - if(g_file_test(filename,G_FILE_TEST_IS_REGULAR))
215   - return filename;
216   - g_free(filename);
217   -
218   - }
219   -
220   -#ifdef DATADIR
221   - //
222   - // Search the application DATADIR
223   - //
224   - {
225   - gchar *filename = g_build_filename(DATAROOTDIR,G_STRINGIFY(PRODUCT_NAME),name,NULL);
226   -
227   - trace("Checking for default config \"%s\"",filename);
228   -
229   - if(g_file_test(filename,G_FILE_TEST_IS_REGULAR))
230   - return filename;
231   -
232   - g_message("Can't find default config (%s)",filename);
233   -
234   - g_free(filename);
235   -
236   - }
237   -#endif // DATADIR
238   -
239   - //
240   - // Search the system config folders
241   - //
242   - const gchar * const * sysconfig = g_get_system_config_dirs();
243   - for(f=0;sysconfig[f];f++)
244   - {
245   - gchar *filename = g_build_filename(sysconfig[f],name,NULL);
246   - trace("Checking for %s",filename);
247   - if(g_file_test(filename,G_FILE_TEST_IS_REGULAR))
248   - return filename;
249   - g_free(filename);
250   - }
251   -
252   - //
253   - // Search the system data folders
254   - //
255   - const gchar * const * sysdata = g_get_system_data_dirs();
256   - for(f=0;sysdata[f];f++)
257   - {
258   - gchar *filename;
259   -
260   - // Check for product dir
261   - filename = g_build_filename(sysdata[f],G_STRINGIFY(PRODUCT_NAME),name,NULL);
262   - trace("Checking for system data \"%s\"",filename);
263   - if(g_file_test(filename,G_FILE_TEST_IS_REGULAR))
264   - return filename;
265   - g_free(filename);
266   -
267   - // Check for file
268   - filename = g_build_filename(sysdata[f],name,NULL);
269   - trace("Checking for system data \"%s\"",filename);
270   - if(g_file_test(filename,G_FILE_TEST_IS_REGULAR))
271   - return filename;
272   - g_free(filename);
273   -
274   -
275   -
276   - }
277   -
278   - //
279   - // Can't find, use user config dir
280   - //
281   - g_message("No config, defaulting to %s/%s",g_get_user_config_dir(),name);
282   - return g_build_filename(g_get_user_config_dir(),name,NULL);
283   -
284   - }
285   -#endif // #ifdef ENABLE_WINDOWS_REGISTRY
286   -
287   - gboolean get_boolean_from_config(const gchar *group, const gchar *key, gboolean def)
288   - {
289   -#ifdef ENABLE_WINDOWS_REGISTRY
290   - gboolean ret = def;
291   - HKEY hKey;
292   -
293   - if(registry_query(group,key,&hKey) != REG_KEY_INEXISTENT)
294   - {
295   - DWORD data;
296   - unsigned long datalen = sizeof(data);
297   - unsigned long datatype;
298   -
299   - if(RegQueryValueExA(hKey,key,NULL,&datatype,(BYTE *) &data,&datalen) == ERROR_SUCCESS)
300   - {
301   - if(datatype == REG_DWORD)
302   - ret = data ? TRUE : FALSE;
303   - else
304   - g_warning("Unexpected registry data type in %s\\%s\\%s\\%s",registry_path,g_get_application_name(),group,key);
305   - }
306   -
307   - RegCloseKey(hKey);
308   - }
309   -
310   - return ret;
311   -
312   -#else
313   -
314   - if(program_config)
315   - {
316   - GError * err = NULL;
317   - gboolean val = g_key_file_get_boolean(program_config,group,key,&err);
318   - if(err)
319   - g_error_free(err);
320   - else
321   - return val;
322   - }
323   -#endif // ENABLE_WINDOWS_REGISTRY
324   -
325   - return def;
326   - }
327   -
328   - gint get_integer_from_config(const gchar *group, const gchar *key, gint def)
329   - {
330   -#ifdef ENABLE_WINDOWS_REGISTRY
331   -
332   - HKEY key_handle;
333   -
334   - if(registry_open_key(group,key,KEY_READ,&key_handle))
335   - {
336   - DWORD data;
337   - gint ret = def;
338   - unsigned long datalen = sizeof(data);
339   - unsigned long datatype;
340   -
341   - if(RegQueryValueExA(key_handle,key,NULL,&datatype,(BYTE *) &data,&datalen) == ERROR_SUCCESS)
342   - {
343   - if(datatype == REG_DWORD)
344   - ret = (gint) data;
345   - else
346   - g_warning("Unexpected registry data type in %s\\%s\\%s\\%s",registry_path,g_get_application_name(),group,key);
347   - }
348   -
349   - RegCloseKey(key_handle);
350   -
351   - return ret;
352   -
353   - }
354   -
355   -#else
356   -
357   - if(program_config)
358   - {
359   - GError * err = NULL;
360   - gint val = g_key_file_get_integer(program_config,group,key,&err);
361   - if(err)
362   - g_error_free(err);
363   - else
364   - return val;
365   - }
366   -#endif // ENABLE_WINDOWS_REGISTRY
367   -
368   - return def;
369   - }
370   -
371   -
372   - gchar * get_string_from_config(const gchar *group, const gchar *key, const gchar *def)
373   - {
374   -#ifdef ENABLE_WINDOWS_REGISTRY
375   -
376   - HKEY key_handle;
377   - unsigned long datalen = 4096;
378   - unsigned long datatype;
379   - gchar * ret = NULL;
380   - BYTE * data;
381   -
382   - if(!registry_open_key(group,key,KEY_READ,&key_handle))
383   - {
384   - if(def)
385   - return g_strdup(def);
386   - return NULL;
387   - }
388   -
389   - data = (BYTE *) g_malloc0(datalen+2);
390   -
391   - if(RegQueryValueExA(key_handle,key,NULL,&datatype,data,&datalen) == ERROR_SUCCESS)
392   - {
393   - data[datalen+1] = 0;
394   - ret = g_strdup((const gchar *) data);
395   - }
396   - else if(def)
397   - {
398   - ret = g_strdup(def);
399   - }
400   -
401   - g_free(data);
402   -
403   - RegCloseKey(key_handle);
404   -
405   - return ret;
406   -
407   -#else
408   -
409   - if(program_config)
410   - {
411   - gchar *ret = g_key_file_get_string(program_config,group,key,NULL);
412   - if(ret)
413   - return ret;
414   - }
415   -
416   - if(def)
417   - return g_strdup(def);
418   -
419   - return NULL;
420   -
421   -#endif // ENABLE_WINDOWS_REGISTRY
422   - }
423   -
424   -void configuration_init(void)
425   -{
426   -#ifndef ENABLE_WINDOWS_REGISTRY
427   - gchar *filename = search_for_ini();
428   -
429   - if(program_config)
430   - g_key_file_free(program_config);
431   -
432   - program_config = g_key_file_new();
433   -
434   - if(filename)
435   - {
436   - g_message(_("Loading %s"),filename);
437   - g_key_file_load_from_file(program_config,filename,G_KEY_FILE_NONE,NULL);
438   - g_free(filename);
439   - }
440   -
441   -#endif // ENABLE_WINDOWS_REGISTRY
442   -}
443   -
444   -static void set_string(const gchar *group, const gchar *key, const gchar *fmt, va_list args)
445   -{
446   - gchar * value = g_strdup_vprintf(fmt,args);
447   -
448   -#ifdef ENABLE_WINDOWS_REGISTRY
449   -
450   - gchar * path = g_strdup_printf("%s\\%s\\%s",registry_path,g_get_application_name(),group);
451   - HKEY hKey;
452   - DWORD disp;
453   -
454   - if(RegCreateKeyEx(HKEY_CURRENT_USER,path,0,NULL,REG_OPTION_NON_VOLATILE,KEY_SET_VALUE,NULL,&hKey,&disp) == ERROR_SUCCESS)
455   - {
456   - RegSetValueEx(hKey,key,0,REG_SZ,(const BYTE *) value,strlen(value)+1);
457   - RegCloseKey(hKey);
458   - }
459   -
460   - g_free(path);
461   -
462   -#else
463   -
464   - g_key_file_set_string(program_config,group,key,value);
465   -
466   -#endif
467   -
468   - g_free(value);
469   -}
470   -
471   -void set_string_to_config(const gchar *group, const gchar *key, const gchar *fmt, ...)
472   -{
473   - if(fmt)
474   - {
475   - va_list args;
476   - va_start(args, fmt);
477   - set_string(group,key,fmt,args);
478   - va_end(args);
479   - }
480   -#ifdef ENABLE_WINDOWS_REGISTRY
481   - else
482   - {
483   -
484   - gchar * path = g_strdup_printf("%s\\%s\\%s",registry_path,g_get_application_name(),group);
485   - HKEY hKey;
486   - DWORD disp;
487   -
488   - if(RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
489   - {
490   - RegDeleteKey(hKey,key);
491   - RegCloseKey(hKey);
492   - }
493   -
494   - g_free(path);
495   -
496   - }
497   -#else
498   - else if(g_key_file_has_key(program_config,group,key,NULL))
499   - {
500   - g_key_file_remove_key(program_config,group,key,NULL);
501   - }
502   -#endif
503   -}
504   -
505   -void set_boolean_to_config(const gchar *group, const gchar *key, gboolean val)
506   -{
507   -#ifdef ENABLE_WINDOWS_REGISTRY
508   -
509   - HKEY hKey;
510   - DWORD disp;
511   - gchar * path = g_strdup_printf("%s\\%s\\%s",registry_path,g_get_application_name(),group);
512   -
513   -// trace("Creating key %s",path);
514   - if(RegCreateKeyEx(HKEY_CURRENT_USER,path,0,NULL,REG_OPTION_NON_VOLATILE,KEY_SET_VALUE,NULL,&hKey,&disp) == ERROR_SUCCESS)
515   - {
516   - DWORD value = val ? 1 : 0;
517   - LONG rc = RegSetValueEx(hKey, key, 0, REG_DWORD,(const BYTE *) &value,sizeof(value));
518   -
519   - SetLastError(rc);
520   -
521   - if(rc != ERROR_SUCCESS)
522   - {
523   - gchar *msg = g_win32_error_message(GetLastError());
524   - g_warning("Error \"%s\" when setting key HKCU\\%s\\%s",msg,path,key);
525   - g_free(msg);
526   - }
527   - RegCloseKey(hKey);
528   - }
529   - else
530   - {
531   - gchar *msg = g_win32_error_message(GetLastError());
532   - g_warning("Error \"%s\" when creating key HKCU\\%s",msg,path);
533   - g_free(msg);
534   - }
535   -
536   - g_free(path);
537   -
538   -#else
539   -
540   - if(program_config)
541   - g_key_file_set_boolean(program_config,group,key,val);
542   -
543   -#endif // ENABLE_WINDOWS_REGISTRY
544   -
545   -}
546   -
547   -void set_integer_to_config(const gchar *group, const gchar *key, gint val)
548   -{
549   -#ifdef ENABLE_WINDOWS_REGISTRY
550   -
551   - HKEY hKey;
552   - DWORD disp;
553   - gchar * path = g_strdup_printf("%s\\%s\\%s",registry_path,g_get_application_name(),group);
554   -
555   - trace("Creating key %s",path);
556   - if(RegCreateKeyEx(HKEY_CURRENT_USER,path,0,NULL,REG_OPTION_NON_VOLATILE,KEY_SET_VALUE,NULL,&hKey,&disp) == ERROR_SUCCESS)
557   - {
558   - DWORD value = (DWORD) val;
559   - LONG rc = RegSetValueEx(hKey, key, 0, REG_DWORD,(const BYTE *) &value,sizeof(value));
560   -
561   - SetLastError(rc);
562   -
563   - if(rc != ERROR_SUCCESS)
564   - {
565   - gchar *msg = g_win32_error_message(GetLastError());
566   - g_warning("Error \"%s\" when setting key HKCU\\%s\\%s",msg,path,key);
567   - g_free(msg);
568   - }
569   - RegCloseKey(hKey);
570   - }
571   - else
572   - {
573   - gchar *msg = g_win32_error_message(GetLastError());
574   - g_warning("Error \"%s\" when creating key HKCU\\%s",msg,path);
575   - g_free(msg);
576   - }
577   -
578   - g_free(path);
579   -
580   -#else
581   -
582   - if(program_config)
583   - g_key_file_set_integer(program_config,group,key,val);
584   -
585   -#endif // ENABLE_WINDOWS_REGISTRY
586   -
587   -}
588   -
589   -void configuration_deinit(void)
590   -{
591   -#if !defined(ENABLE_WINDOWS_REGISTRY)
592   -
593   - if(!program_config)
594   - return;
595   -
596   - g_autofree gchar * text = g_key_file_to_data(program_config,NULL,NULL);
597   -
598   - if(text)
599   - {
600   - GError * error = NULL;
601   -
602   - g_autofree gchar * name = g_strconcat(g_get_application_name(),".conf",NULL);
603   - g_autofree gchar * filename = g_build_filename(g_get_user_config_dir(),name,NULL);
604   -
605   - g_mkdir_with_parents(g_get_user_config_dir(),S_IRUSR|S_IWUSR);
606   -
607   - g_message( _("Saving %s"), filename);
608   -
609   - g_file_set_contents(filename,text,-1,&error);
610   -
611   - if(error) {
612   - g_message( _( "Can't save \"%s\": %s" ), filename, error->message);
613   - g_error_free(error);
614   - }
615   -
616   - }
617   -
618   - g_key_file_free(program_config);
619   - program_config = NULL;
620   -
621   -#endif // ENABLE_WINDOWS_REGISTRY
622   -}
623   -
624   -gchar * build_data_filename(const gchar *first_element, ...)
625   -{
626   - va_list args;
627   - gchar *path;
628   -
629   - va_start(args, first_element);
630   - path = filename_from_va(first_element,args);
631   - va_end(args);
632   - return path;
633   -}
634   -
635   -gchar * filename_from_va(const gchar *first_element, va_list args)
636   -{
637   - const gchar * appname[] = { g_get_application_name(), PACKAGE_NAME };
638   - size_t p,f;
639   -
640   - // Make base path
641   - const gchar *element;
642   - GString * result = g_string_new("");
643   - for(element = first_element;element;element = va_arg(args, gchar *))
644   - {
645   - g_string_append_c(result,G_DIR_SEPARATOR);
646   - g_string_append(result,element);
647   - }
648   -
649   - g_autofree gchar * suffix = g_string_free(result, FALSE);
650   -
651   -#if defined( ENABLE_WINDOWS_REGISTRY )
652   - for(p=0;p<G_N_ELEMENTS(appname) && !result;p++)
653   - {
654   - g_autofree gchar * path = g_strconcat("Software\\",appname[p],NULL);
655   -
656   - HKEY hKey = 0;
657   - LONG rc = 0;
658   -
659   - // Note: This could be needed: http://support.microsoft.com/kb/556009
660   - // http://msdn.microsoft.com/en-us/library/windows/desktop/aa384129(v=vs.85).aspx
661   -
662   - rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,path,0,KEY_QUERY_VALUE,&hKey);
663   - SetLastError(rc);
664   -
665   - if(rc == ERROR_SUCCESS)
666   - {
667   - char data[4096];
668   - unsigned long datalen = sizeof(data); // data field length(in), data returned length(out)
669   - unsigned long datatype; // #defined in winnt.h (predefined types 0-11)
670   -
671   - rc = RegQueryValueExA(hKey,"datadir",NULL,&datatype,(LPBYTE) data,&datalen);
672   - if(rc == ERROR_SUCCESS)
673   - {
674   - gchar * path = g_build_filename(data,appname[p],suffix,NULL);
675   - trace("searching \"%s\"",path);
676   - if(g_file_test(path,G_FILE_TEST_EXISTS))
677   - return path;
678   - g_free(path);
679   - }
680   - RegCloseKey(hKey);
681   - }
682   -
683   - }
684   -#endif // ENABLE_WINDOWS_REGISTRY
685   -
686   -#ifdef _WIN32
687   - for(p=0;p<G_N_ELEMENTS(appname) && !result;p++)
688   - {
689   - gchar * path = g_build_filename(g_win32_get_package_installation_directory_of_module(NULL),appname[p],suffix,NULL);
690   - trace("searching \"%s\"",path);
691   - if(g_file_test(path,G_FILE_TEST_EXISTS))
692   - return path;
693   - g_free(path);
694   - }
695   -#endif // _WIN32
696   -
697   - // Check system data dirs
698   - const gchar * const * system_data_dirs = g_get_system_data_dirs();
699   - for(p=0;p<G_N_ELEMENTS(appname);p++)
700   - {
701   - for(f=0;system_data_dirs[f];f++)
702   - {
703   - gchar * path = g_build_filename(system_data_dirs[f],appname[p],suffix,NULL);
704   - trace("searching \"%s\"",path);
705   - if(g_file_test(path,G_FILE_TEST_EXISTS))
706   - return path;
707   - g_free(path);
708   - }
709   -
710   - }
711   -
712   - // Check current dir
713   - g_autofree gchar *dir = g_get_current_dir();
714   - gchar * path = g_build_filename(dir,suffix,NULL);
715   - trace("searching \"%s\"",path);
716   - if(g_file_test(path,G_FILE_TEST_EXISTS))
717   - return path;
718   - g_free(path);
719   -
720   - trace("Can't find \"%s\"",suffix);
721   -
722   - return g_build_filename(".",suffix,NULL);
723   -}
724   -
725   -#ifdef ENABLE_WINDOWS_REGISTRY
726   -gboolean get_registry_handle(const gchar *group, HKEY *hKey, REGSAM samDesired)
727   -{
728   - gboolean ret;
729   - gchar * path;
730   - DWORD disp;
731   -
732   - if(group)
733   - path = g_strdup_printf("%s\\%s\\%s",registry_path,g_get_application_name(),group);
734   - else
735   - path = g_strdup_printf("%s\\%s",registry_path,g_get_application_name());
736   -
737   - if(RegCreateKeyEx(HKEY_CURRENT_USER,path,0,NULL,REG_OPTION_NON_VOLATILE,samDesired,NULL,hKey,&disp) == ERROR_SUCCESS)
738   - ret = TRUE;
739   - else
740   - ret = FALSE;
741   -
742   - g_free(path);
743   -
744   - return ret;
745   -}
746   -#else
747   -GKeyFile * get_application_keyfile(void)
748   -{
749   - if(!program_config)
750   - configuration_init();
751   - return program_config;
752   -}
753   -#endif // ENABLE_WINDOWS_REGISTRY
754   -
755   - static const struct _WindowState
756   - {
757   - const char *name;
758   - GdkWindowState flag;
759   - void (*activate)(GtkWindow *);
760   - } WindowState[] =
761   - {
762   - { "Maximized", GDK_WINDOW_STATE_MAXIMIZED, gtk_window_maximize },
763   - { "Iconified", GDK_WINDOW_STATE_ICONIFIED, gtk_window_iconify },
764   - { "Sticky", GDK_WINDOW_STATE_STICKY, gtk_window_stick }
765   - };
766   -
767   -void save_window_state_to_config(const gchar *group, const gchar *key, GdkWindowState CurrentState)
768   -{
769   -#if defined( ENABLE_WINDOWS_REGISTRY )
770   -
771   - gchar * path = g_strdup_printf("%s\\%s\\%s\\%s",registry_path,g_get_application_name(),group,key);
772   -
773   - HKEY hKey;
774   - DWORD disp;
775   -
776   - if(RegCreateKeyEx(HKEY_CURRENT_USER,path,0,NULL,REG_OPTION_NON_VOLATILE,KEY_SET_VALUE,NULL,&hKey,&disp) == ERROR_SUCCESS)
777   - {
778   - int f;
779   - for(f=0;f<G_N_ELEMENTS(WindowState);f++)
780   - {
781   - DWORD value = (CurrentState & WindowState[f].flag) ? 1 : 0;
782   -// trace("%s=%s",WindowState[f].name,value ? "Yes" : "No");
783   - RegSetValueEx(hKey, WindowState[f].name, 0, REG_DWORD,(const BYTE *) &value,sizeof(value));
784   - }
785   -
786   - RegCloseKey(hKey);
787   - }
788   -
789   - g_free(path);
790   -
791   -#else
792   - int f;
793   - GKeyFile * conf = get_application_keyfile();
794   - gchar * id = g_strconcat(group,".",key,NULL);
795   -
796   - for(f=0;f<G_N_ELEMENTS(WindowState);f++)
797   - g_key_file_set_boolean(conf,id,WindowState[f].name,CurrentState & WindowState[f].flag);
798   -
799   - g_free(id);
800   -
801   -#endif // ENABLE_WINDOWS_REGISTRY
802   -}
803   -
804   -void save_window_size_to_config(const gchar *group, const gchar *key, GtkWidget *hwnd)
805   -{
806   -#if defined( ENABLE_WINDOWS_REGISTRY )
807   -
808   - gchar * path = g_strdup_printf("%s\\%s\\%s\\%s",registry_path,g_get_application_name(),group,key);
809   -
810   - HKEY hKey;
811   - DWORD disp;
812   -
813   - if(RegCreateKeyEx(HKEY_CURRENT_USER,path,0,NULL,REG_OPTION_NON_VOLATILE,KEY_SET_VALUE,NULL,&hKey,&disp) == ERROR_SUCCESS)
814   - {
815   - int pos[2];
816   -
817   - gtk_window_get_size(GTK_WINDOW(hwnd),&pos[0],&pos[1]);
818   -
819   - RegSetValueEx(hKey, "Size", 0, REG_BINARY,(const BYTE *) pos,sizeof(pos));
820   -
821   - RegCloseKey(hKey);
822   - }
823   -
824   - g_free(path);
825   -
826   -#else
827   - int pos[2];
828   - GKeyFile * conf = get_application_keyfile();
829   - gchar * id = g_strconcat(group,".",key,NULL);
830   -
831   - gtk_window_get_size(GTK_WINDOW(hwnd),&pos[0],&pos[1]);
832   - g_key_file_set_integer_list(conf,id,"size",pos,2);
833   -
834   - g_free(id);
835   -
836   -#endif // ENABLE_WINDOWS_REGISTRY
837   -}
838   -
839   -#if defined( ENABLE_WINDOWS_REGISTRY )
840   -static void restore_window_from_regkey(GtkWidget *hwnd, HKEY hKey, const gchar *path)
841   -{
842   - int f;
843   - int pos[2];
844   - unsigned long datalen;
845   - unsigned long datatype;
846   -
847   -
848   - datalen = sizeof(pos);
849   - if(RegQueryValueExA(hKey,"Size",NULL,&datatype,(BYTE *) pos,&datalen) == ERROR_SUCCESS)
850   - {
851   - if(datatype == REG_BINARY && datalen == sizeof(pos))
852   - {
853   - gtk_window_resize(GTK_WINDOW(hwnd),pos[0],pos[1]);
854   - }
855   - else
856   - {
857   - g_warning("Unexpected registry data in %s\\Size",path);
858   - }
859   - }
860   -
861   -
862   - for(f=0;f<G_N_ELEMENTS(WindowState);f++)
863   - {
864   - DWORD data;
865   -
866   - datalen = sizeof(data);
867   -
868   - if(RegQueryValueExA(hKey,WindowState[f].name,NULL,&datatype,(BYTE *) &data,&datalen) == ERROR_SUCCESS)
869   - {
870   - if(datatype == REG_DWORD)
871   - {
872   - if(data)
873   - WindowState[f].activate(GTK_WINDOW(hwnd));
874   -
875   - }
876   - else
877   - {
878   - g_warning("Unexpected registry data type in %s\\%s",path,WindowState[f].name);
879   - }
880   - }
881   - }
882   -
883   -
884   -}
885   -#endif // ENABLE_WINDOWS_REGISTRY
886   -
887   -void restore_window_from_config(const gchar *group, const gchar *key, GtkWidget *hwnd)
888   -{
889   -#if defined( ENABLE_WINDOWS_REGISTRY )
890   -
891   - gchar * path = g_strdup_printf("%s\\%s\\%s\\%s",registry_path,g_get_application_name(),group,key);
892   - HKEY hKey;
893   -
894   - if(RegOpenKeyEx(HKEY_CURRENT_USER,path,0,KEY_READ,&hKey) == ERROR_SUCCESS)
895   - {
896   - // Load user settings
897   - restore_window_from_regkey(hwnd,hKey,path);
898   - RegCloseKey(hKey);
899   - }
900   - else if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,path,0,KEY_READ,&hKey) == ERROR_SUCCESS)
901   - {
902   - // Load system defaults
903   - restore_window_from_regkey(hwnd,hKey,path);
904   - RegCloseKey(hKey);
905   - }
906   -
907   - g_free(path);
908   -
909   -#else
910   - gchar * id = g_strconcat(group,".",key,NULL);
911   - GKeyFile * conf = get_application_keyfile();
912   -
913   - if(g_key_file_has_key(conf,id,"size",NULL))
914   - {
915   - gsize sz = 2;
916   - gint * vlr = g_key_file_get_integer_list(conf,id,"size",&sz,NULL);
917   - int f;
918   -
919   - if(vlr)
920   - {
921   - gtk_window_resize(GTK_WINDOW(hwnd),vlr[0],vlr[1]);
922   - g_free(vlr);
923   - }
924   -
925   - for(f=0;f<G_N_ELEMENTS(WindowState);f++)
926   - {
927   - if(g_key_file_get_boolean(conf,id,WindowState[f].name,NULL))
928   - WindowState[f].activate(GTK_WINDOW(hwnd));
929   - }
930   -
931   - }
932   -
933   - g_free(id);
934   -
935   -#endif // ENABLE_WINDOWS_REGISTRY
936   -
937   -}
938   -
src/pw3270/linux/config.c 0 → 100644
... ... @@ -0,0 +1,437 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como config.c e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + * licinio@bb.com.br (Licínio Luis Branco)
  28 + * kraucer@bb.com.br (Kraucer Fernandes Mazuco)
  29 + *
  30 + */
  31 +
  32 +#ifdef _WIN32
  33 + #include <windows.h>
  34 +#endif // _WIN32
  35 +
  36 + #include "../pw3270/private.h"
  37 +
  38 + #include "../common.h"
  39 + #include <stdarg.h>
  40 + #include <glib/gstdio.h>
  41 +
  42 +/*--[ Globals ]--------------------------------------------------------------------------------------*/
  43 +
  44 + static GKeyFile * keyfile = NULL;
  45 + static gchar * keyfilename = NULL;
  46 +
  47 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  48 +
  49 + static gchar * search_for_ini(void)
  50 + {
  51 + static const gchar * (*dir[])(void) =
  52 + {
  53 + g_get_user_config_dir,
  54 + g_get_user_data_dir,
  55 + g_get_home_dir,
  56 + };
  57 +
  58 + size_t f;
  59 + g_autofree gchar * name = g_strconcat(g_get_application_name(),".conf",NULL);
  60 +
  61 + //
  62 + // First search the user data
  63 + //
  64 +
  65 + for(f=0;f<G_N_ELEMENTS(dir);f++)
  66 + {
  67 + gchar *filename = g_build_filename(dir[f](),name,NULL);
  68 +
  69 + trace("Checking for %s",filename);
  70 +
  71 + if(g_file_test(filename,G_FILE_TEST_IS_REGULAR))
  72 + return filename;
  73 + g_free(filename);
  74 +
  75 + }
  76 +
  77 +#ifdef DATADIR
  78 + //
  79 + // Search the application DATADIR
  80 + //
  81 + {
  82 + gchar *filename = g_build_filename(DATAROOTDIR,G_STRINGIFY(PRODUCT_NAME),name,NULL);
  83 +
  84 + trace("Checking for default config \"%s\"",filename);
  85 +
  86 + if(g_file_test(filename,G_FILE_TEST_IS_REGULAR))
  87 + return filename;
  88 +
  89 + g_message("Can't find default config (%s)",filename);
  90 +
  91 + g_free(filename);
  92 +
  93 + }
  94 +#endif // DATADIR
  95 +
  96 + //
  97 + // Search the system config folders
  98 + //
  99 + const gchar * const * sysconfig = g_get_system_config_dirs();
  100 + for(f=0;sysconfig[f];f++)
  101 + {
  102 + gchar *filename = g_build_filename(sysconfig[f],name,NULL);
  103 + trace("Checking for %s",filename);
  104 + if(g_file_test(filename,G_FILE_TEST_IS_REGULAR))
  105 + return filename;
  106 + g_free(filename);
  107 + }
  108 +
  109 + //
  110 + // Search the system data folders
  111 + //
  112 + const gchar * const * sysdata = g_get_system_data_dirs();
  113 + for(f=0;sysdata[f];f++)
  114 + {
  115 + gchar *filename;
  116 +
  117 + // Check for product dir
  118 + filename = g_build_filename(sysdata[f],G_STRINGIFY(PRODUCT_NAME),name,NULL);
  119 + trace("Checking for system data \"%s\"",filename);
  120 + if(g_file_test(filename,G_FILE_TEST_IS_REGULAR))
  121 + return filename;
  122 + g_free(filename);
  123 +
  124 + // Check for file
  125 + filename = g_build_filename(sysdata[f],name,NULL);
  126 + trace("Checking for system data \"%s\"",filename);
  127 + if(g_file_test(filename,G_FILE_TEST_IS_REGULAR))
  128 + return filename;
  129 + g_free(filename);
  130 +
  131 +
  132 +
  133 + }
  134 +
  135 + //
  136 + // Can't find, use user config dir
  137 + //
  138 + g_message("No config, defaulting to %s/%s",g_get_user_config_dir(),name);
  139 + return g_build_filename(g_get_user_config_dir(),name,NULL);
  140 +
  141 + }
  142 +
  143 + gboolean get_boolean_from_config(const gchar *group, const gchar *key, gboolean def)
  144 + {
  145 +
  146 + if(keyfile)
  147 + {
  148 + GError * err = NULL;
  149 + gboolean val = g_key_file_get_boolean(keyfile,group,key,&err);
  150 + if(err)
  151 + g_error_free(err);
  152 + else
  153 + return val;
  154 + }
  155 +
  156 + return def;
  157 + }
  158 +
  159 + gint get_integer_from_config(const gchar *group, const gchar *key, gint def)
  160 + {
  161 +
  162 + if(keyfile)
  163 + {
  164 + GError * err = NULL;
  165 + gint val = g_key_file_get_integer(keyfile,group,key,&err);
  166 + if(err)
  167 + g_error_free(err);
  168 + else
  169 + return val;
  170 + }
  171 +
  172 + return def;
  173 + }
  174 +
  175 +
  176 + gchar * get_string_from_config(const gchar *group, const gchar *key, const gchar *def)
  177 + {
  178 +
  179 + if(keyfile)
  180 + {
  181 + gchar *ret = g_key_file_get_string(keyfile,group,key,NULL);
  182 + if(ret)
  183 + return ret;
  184 + }
  185 +
  186 + if(def)
  187 + return g_strdup(def);
  188 +
  189 + return NULL;
  190 +
  191 + }
  192 +
  193 +void pw3270_session_config_load(const gchar *filename)
  194 +{
  195 + if(keyfilename)
  196 + {
  197 + g_free(keyfilename);
  198 + keyfilename = NULL;
  199 + }
  200 +
  201 + if(keyfile)
  202 + {
  203 + g_key_file_free(keyfile);
  204 + keyfile = NULL;
  205 + }
  206 +
  207 + keyfile = g_key_file_new();
  208 +
  209 + if(filename)
  210 + {
  211 + g_message(_("Loading %s"),filename);
  212 + g_key_file_load_from_file(keyfile,filename,G_KEY_FILE_NONE,NULL);
  213 + keyfilename = g_strdup(filename);
  214 + }
  215 + else
  216 + {
  217 + // Using default file.
  218 + g_autofree gchar *name = search_for_ini();
  219 + if(name)
  220 + {
  221 + g_message(_("Loading %s"),name);
  222 + g_key_file_load_from_file(keyfile,name,G_KEY_FILE_NONE,NULL);
  223 + }
  224 + }
  225 +
  226 +}
  227 +
  228 +static void set_string(const gchar *group, const gchar *key, const gchar *fmt, va_list args)
  229 +{
  230 + gchar * value = g_strdup_vprintf(fmt,args);
  231 +
  232 + g_key_file_set_string(keyfile,group,key,value);
  233 +
  234 + g_free(value);
  235 +}
  236 +
  237 +void set_string_to_config(const gchar *group, const gchar *key, const gchar *fmt, ...)
  238 +{
  239 + if(fmt)
  240 + {
  241 + va_list args;
  242 + va_start(args, fmt);
  243 + set_string(group,key,fmt,args);
  244 + va_end(args);
  245 + }
  246 + else if(g_key_file_has_key(keyfile,group,key,NULL))
  247 + {
  248 + g_key_file_remove_key(keyfile,group,key,NULL);
  249 + }
  250 +
  251 +}
  252 +
  253 +void set_boolean_to_config(const gchar *group, const gchar *key, gboolean val)
  254 +{
  255 + if(keyfile)
  256 + g_key_file_set_boolean(keyfile,group,key,val);
  257 +
  258 +}
  259 +
  260 +void set_integer_to_config(const gchar *group, const gchar *key, gint val)
  261 +{
  262 +
  263 + if(keyfile)
  264 + g_key_file_set_integer(keyfile,group,key,val);
  265 +
  266 +}
  267 +
  268 +void pw3270_session_config_free(void)
  269 +{
  270 +
  271 + if(!keyfile)
  272 + return;
  273 +
  274 + g_autofree gchar * text = g_key_file_to_data(keyfile,NULL,NULL);
  275 +
  276 + if(text)
  277 + {
  278 + GError * error = NULL;
  279 +
  280 + if(keyfilename)
  281 + {
  282 + g_message( _("Saving %s"), keyfilename);
  283 +
  284 + g_file_set_contents(keyfilename,text,-1,&error);
  285 + g_free(keyfilename);
  286 + keyfilename = 0;
  287 + }
  288 + else
  289 + {
  290 + g_autofree gchar * name = g_strconcat(g_get_application_name(),".conf",NULL);
  291 + g_autofree gchar * filename = g_build_filename(g_get_user_config_dir(),name,NULL);
  292 + g_mkdir_with_parents(g_get_user_config_dir(),S_IRUSR|S_IWUSR);
  293 + g_file_set_contents(filename,text,-1,&error);
  294 + }
  295 +
  296 +
  297 + if(error) {
  298 + g_message( _( "Can't save session settings: %s" ), error->message);
  299 + g_error_free(error);
  300 + }
  301 +
  302 + }
  303 +
  304 + g_key_file_free(keyfile);
  305 + keyfile = NULL;
  306 +
  307 +}
  308 +
  309 +gchar * build_data_filename(const gchar *first_element, ...)
  310 +{
  311 + va_list args;
  312 + gchar *path;
  313 +
  314 + va_start(args, first_element);
  315 + path = filename_from_va(first_element,args);
  316 + va_end(args);
  317 + return path;
  318 +}
  319 +
  320 +gchar * filename_from_va(const gchar *first_element, va_list args)
  321 +{
  322 + const gchar * appname[] = { g_get_application_name(), PACKAGE_NAME };
  323 + size_t p,f;
  324 +
  325 + // Make base path
  326 + const gchar *element;
  327 + GString * result = g_string_new("");
  328 + for(element = first_element;element;element = va_arg(args, gchar *))
  329 + {
  330 + g_string_append_c(result,G_DIR_SEPARATOR);
  331 + g_string_append(result,element);
  332 + }
  333 +
  334 + g_autofree gchar * suffix = g_string_free(result, FALSE);
  335 +
  336 + // Check system data dirs
  337 + const gchar * const * system_data_dirs = g_get_system_data_dirs();
  338 + for(p=0;p<G_N_ELEMENTS(appname);p++)
  339 + {
  340 + for(f=0;system_data_dirs[f];f++)
  341 + {
  342 + gchar * path = g_build_filename(system_data_dirs[f],appname[p],suffix,NULL);
  343 + trace("searching \"%s\"",path);
  344 + if(g_file_test(path,G_FILE_TEST_EXISTS))
  345 + return path;
  346 + g_free(path);
  347 + }
  348 +
  349 + }
  350 +
  351 + // Check current dir
  352 + g_autofree gchar *dir = g_get_current_dir();
  353 + gchar * path = g_build_filename(dir,suffix,NULL);
  354 + trace("searching \"%s\"",path);
  355 + if(g_file_test(path,G_FILE_TEST_EXISTS))
  356 + return path;
  357 + g_free(path);
  358 +
  359 + trace("Can't find \"%s\"",suffix);
  360 +
  361 + return g_build_filename(".",suffix,NULL);
  362 +}
  363 +
  364 +GKeyFile * pw3270_session_config_get(void)
  365 +{
  366 + if(!keyfile)
  367 + pw3270_session_config_load(NULL);
  368 + return keyfile;
  369 +}
  370 +
  371 + static const struct _WindowState
  372 + {
  373 + const char *name;
  374 + GdkWindowState flag;
  375 + void (*activate)(GtkWindow *);
  376 + } WindowState[] =
  377 + {
  378 + { "Maximized", GDK_WINDOW_STATE_MAXIMIZED, gtk_window_maximize },
  379 + { "Iconified", GDK_WINDOW_STATE_ICONIFIED, gtk_window_iconify },
  380 + { "Sticky", GDK_WINDOW_STATE_STICKY, gtk_window_stick }
  381 + };
  382 +
  383 +void save_window_state_to_config(const gchar *group, const gchar *key, GdkWindowState CurrentState)
  384 +{
  385 + int f;
  386 + GKeyFile * conf = pw3270_session_config_get();
  387 + gchar * id = g_strconcat(group,".",key,NULL);
  388 +
  389 + for(f=0;f<G_N_ELEMENTS(WindowState);f++)
  390 + g_key_file_set_boolean(conf,id,WindowState[f].name,CurrentState & WindowState[f].flag);
  391 +
  392 + g_free(id);
  393 +
  394 +}
  395 +
  396 +void save_window_size_to_config(const gchar *group, const gchar *key, GtkWidget *hwnd)
  397 +{
  398 + int pos[2];
  399 + GKeyFile * conf = pw3270_session_config_get();
  400 + gchar * id = g_strconcat(group,".",key,NULL);
  401 +
  402 + gtk_window_get_size(GTK_WINDOW(hwnd),&pos[0],&pos[1]);
  403 + g_key_file_set_integer_list(conf,id,"size",pos,2);
  404 +
  405 + g_free(id);
  406 +
  407 +}
  408 +
  409 +void restore_window_from_config(const gchar *group, const gchar *key, GtkWidget *hwnd)
  410 +{
  411 + gchar * id = g_strconcat(group,".",key,NULL);
  412 + GKeyFile * conf = pw3270_session_config_get();
  413 +
  414 + if(g_key_file_has_key(conf,id,"size",NULL))
  415 + {
  416 + gsize sz = 2;
  417 + gint * vlr = g_key_file_get_integer_list(conf,id,"size",&sz,NULL);
  418 + int f;
  419 +
  420 + if(vlr)
  421 + {
  422 + gtk_window_resize(GTK_WINDOW(hwnd),vlr[0],vlr[1]);
  423 + g_free(vlr);
  424 + }
  425 +
  426 + for(f=0;f<G_N_ELEMENTS(WindowState);f++)
  427 + {
  428 + if(g_key_file_get_boolean(conf,id,WindowState[f].name,NULL))
  429 + WindowState[f].activate(GTK_WINDOW(hwnd));
  430 + }
  431 +
  432 + }
  433 +
  434 + g_free(id);
  435 +
  436 +}
  437 +
... ...
src/pw3270/linux/print.c
... ... @@ -48,7 +48,7 @@
48 48 g_message("Loading print settings");
49 49  
50 50 // Load page and print settings
51   - GKeyFile * conf = get_application_keyfile();
  51 + GKeyFile * conf = pw3270_session_config_get();
52 52 GError * err = NULL;
53 53  
54 54 debug("print_settings=%s",g_key_file_has_group(conf,"print_settings") ? "TRUE" : "FALSE");
... ... @@ -128,7 +128,7 @@
128 128 trace("%s(%p)",__FUNCTION__,operation);
129 129 g_message("Saving print settings");
130 130  
131   - GKeyFile * conf = get_application_keyfile();
  131 + GKeyFile * conf = pw3270_session_config_get();
132 132 gtk_print_settings_to_key_file(settings,conf,"print_settings");
133 133 gtk_page_setup_to_key_file(pgsetup,conf,"page_setup");
134 134 gtk_paper_size_to_key_file(papersize,conf,"paper_size");
... ...
src/pw3270/main.c
... ... @@ -50,6 +50,7 @@
50 50 #include "v3270/accessible.h"
51 51 #include <stdlib.h>
52 52 #include <lib3270/log.h>
  53 +#include "common.h"
53 54  
54 55 #define ERROR_DOMAIN g_quark_from_static_string(PACKAGE_NAME)
55 56  
... ... @@ -475,6 +476,21 @@ int main(int argc, char *argv[])
475 476 if(!session_name)
476 477 session_name = PACKAGE_NAME;
477 478  
  479 + // Load session settings.
  480 + {
  481 + const gchar * session_settings_file_name = NULL;
  482 + size_t ix;
  483 +
  484 + for(ix = 1; ix < argc; ix++)
  485 + {
  486 + if(argv[ix][0] != '-' && g_file_test(argv[ix],G_FILE_TEST_IS_REGULAR))
  487 + pw3270_session_config_load(argv[ix]);
  488 + }
  489 +
  490 + pw3270_session_config_get();
  491 +
  492 + }
  493 +
478 494 rc = initialize();
479 495  
480 496 if(!rc)
... ... @@ -556,6 +572,7 @@ int main(int argc, char *argv[])
556 572  
557 573 pw3270_stop_plugins(toplevel);
558 574 pw3270_unload_plugins();
  575 + pw3270_session_config_free();
559 576  
560 577 }
561 578  
... ...
src/pw3270/private.h
... ... @@ -68,7 +68,7 @@
68 68  
69 69 /*--[ Global prototipes ]----------------------------------------------------------------------------*/
70 70  
71   - #include "common/common.h"
  71 + #include "common.h"
72 72  
73 73 G_GNUC_INTERNAL GtkWidget * create_main_window(const gchar *uri);
74 74 G_GNUC_INTERNAL void setup_font_list(GtkWidget *widget, GtkWidget *obj);
... ...
src/pw3270/tools.c
... ... @@ -75,23 +75,9 @@ int libpw3270_loaded(void)
75 75 int libpw3270_unloaded(void)
76 76 {
77 77 trace("%s",__FUNCTION__);
78   - configuration_deinit();
79 78 return 0;
80 79 }
81 80  
82   -/*
83   -LIB3270_EXPORT gchar * pw3270_build_filename(GtkWidget *widget, const gchar *first_element, ...)
84   -{
85   - va_list args;
86   - gchar *path;
87   -
88   - va_start(args, first_element);
89   - path = filename_from_va(first_element,args);
90   - va_end(args);
91   - return path;
92   -}
93   -*/
94   -
95 81 LIB3270_EXPORT void pw3270_save_window_size(GtkWidget *widget, const gchar *name)
96 82 {
97 83 trace("%s",__FUNCTION__);
... ...
src/pw3270/uiparser/private.h
... ... @@ -31,7 +31,7 @@
31 31  
32 32 #include <gtk/gtk.h>
33 33 #include <config.h>
34   - #include "../common/common.h"
  34 + #include "../common.h"
35 35 #include "parser.h"
36 36  
37 37 #define ERROR_DOMAIN g_quark_from_static_string("uiparser")
... ...
src/pw3270/uiparser/testprogram.c
1 1  
2 2 #include <gtk/gtk.h>
3   -#include "../common/common.h"
  3 +#include "../common.h"
4 4 #include "parser.h"
5 5  
6 6 /*--[ Globals ]--------------------------------------------------------------------------------------*/
... ... @@ -90,7 +90,6 @@ int main (int argc, char *argv[])
90 90 GtkWidget * hbox;
91 91  
92 92 gtk_init(&argc, &argv);
93   - configuration_init();
94 93  
95 94 hbox = gtk_hbox_new(FALSE,5);
96 95 vbox = gtk_vbox_new(FALSE,5);
... ...
src/pw3270/window.c
... ... @@ -40,7 +40,7 @@
40 40 #include <v3270/trace.h>
41 41 #include <v3270/toggle.h>
42 42 #include <v3270/settings.h>
43   -#include "common/common.h"
  43 +#include "common.h"
44 44  
45 45 /*--[ Widget definition ]----------------------------------------------------------------------------*/
46 46  
... ... @@ -163,8 +163,6 @@ static GtkWidget * trace_window = NULL;
163 163 }
164 164 #endif // GTK3
165 165  
166   - configuration_init();
167   -
168 166 }
169 167  
170 168 static void trace_on_file(G_GNUC_UNUSED H3270 *hSession, void * userdata, const char *fmt, va_list args)
... ... @@ -420,7 +418,7 @@ static GtkWidget * trace_window = NULL;
420 418  
421 419 #else
422 420  
423   - v3270_to_key_file(widget, get_application_keyfile(), "terminal");
  421 + v3270_to_key_file(widget, pw3270_session_config_get(), "terminal");
424 422  
425 423 #endif // _WIN32
426 424  
... ...
src/pw3270/windows/config.c 0 → 100644
... ... @@ -0,0 +1,939 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como config.c e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + * licinio@bb.com.br (Licínio Luis Branco)
  28 + * kraucer@bb.com.br (Kraucer Fernandes Mazuco)
  29 + *
  30 + */
  31 +
  32 +#ifdef _WIN32
  33 + #include <windows.h>
  34 +#endif // _WIN32
  35 +
  36 + #include "../pw3270/private.h"
  37 +
  38 + #include "common.h"
  39 + #include <stdarg.h>
  40 + #include <glib/gstdio.h>
  41 +
  42 +#ifdef _WIN32
  43 +
  44 + #include <windows.h>
  45 +
  46 + #ifndef KEY_WOW64_64KEY
  47 + #define KEY_WOW64_64KEY 0x0100
  48 + #endif // KEY_WOW64_64KEY
  49 +
  50 + #ifndef KEY_WOW64_32KEY
  51 + #define KEY_WOW64_32KEY 0x0200
  52 + #endif // KEY_WOW64_64KEY
  53 +
  54 +#endif // _WIN32
  55 +
  56 +/*--[ Globals ]--------------------------------------------------------------------------------------*/
  57 +
  58 +#ifdef ENABLE_WINDOWS_REGISTRY
  59 +
  60 + static const gchar * registry_path = "SOFTWARE";
  61 +
  62 +#else
  63 +
  64 + static GKeyFile * program_config = NULL;
  65 +
  66 +#endif // ENABLE_WINDOWS_REGISTRY
  67 +
  68 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  69 +
  70 +#ifdef ENABLE_WINDOWS_REGISTRY
  71 +
  72 + enum REG_KEY
  73 + {
  74 + REG_KEY_USER,
  75 + REG_KEY_SYSTEM,
  76 + REG_KEY_INEXISTENT
  77 + };
  78 +
  79 + static enum REG_KEY registry_query(const gchar *group, const gchar *key, HKEY *hKey)
  80 + {
  81 + static HKEY predefined[] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE };
  82 + gchar * path = g_strdup_printf("%s\\%s\\%s",registry_path,g_get_application_name(),group);
  83 + int f;
  84 +
  85 + for(f=0;f<G_N_ELEMENTS(predefined);f++)
  86 + {
  87 + if(RegOpenKeyEx(predefined[f],path,0,KEY_READ,hKey) == ERROR_SUCCESS)
  88 + {
  89 + if(RegQueryValueExA(*hKey,key,NULL,NULL,NULL,NULL) == ERROR_SUCCESS)
  90 + {
  91 + trace("Key\"%s\\%s\" found at id %d",path,key,f);
  92 + g_free(path);
  93 + return f;
  94 + }
  95 + RegCloseKey(*hKey);
  96 + }
  97 + }
  98 +
  99 + trace("Key \"%s\\%s\""" not found",path,key,f);
  100 + g_free(path);
  101 +
  102 + return -1;
  103 + }
  104 +
  105 + static BOOL registry_open_key(const gchar *group, const gchar *key, REGSAM samDesired, HKEY *hKey)
  106 + {
  107 + static HKEY predefined[] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE };
  108 + int f;
  109 + gchar * path = g_strdup_printf("%s\\%s\\%s",registry_path,g_get_application_name(),group);
  110 +
  111 + for(f=0;f<G_N_ELEMENTS(predefined);f++)
  112 + {
  113 + if(RegOpenKeyEx(predefined[f],path,0,samDesired,hKey) == ERROR_SUCCESS)
  114 + {
  115 + g_free(path);
  116 + return TRUE;
  117 + }
  118 + }
  119 +
  120 + g_free(path);
  121 +
  122 + return FALSE;
  123 + }
  124 +
  125 + void registry_foreach(HKEY parent, const gchar *name,void (*cbk)(const gchar *key, const gchar *val, gpointer *user_data), gpointer *user_data)
  126 + {
  127 + HKEY hKey = 0;
  128 +
  129 + if(RegOpenKeyEx(parent,name,0,KEY_READ,&hKey) == ERROR_SUCCESS)
  130 + {
  131 + #define MAX_KEY_LENGTH 255
  132 + #define MAX_VALUE_NAME 16383
  133 +
  134 + TCHAR pName[MAX_KEY_LENGTH];
  135 + DWORD cName = MAX_KEY_LENGTH;
  136 + int ix = 0;
  137 +
  138 + while(RegEnumValue(hKey,ix++,pName,&cName,NULL,NULL,NULL,NULL) == ERROR_SUCCESS)
  139 + {
  140 + BYTE data[4097];
  141 + unsigned long datatype;
  142 + unsigned long datalen = 4096;
  143 +
  144 + if(RegQueryValueExA(hKey,pName,NULL,&datatype,data,&datalen) == ERROR_SUCCESS)
  145 + {
  146 + data[datalen+1] = 0;
  147 + cbk(pName,(const gchar *) data, user_data);
  148 + }
  149 + cName = MAX_KEY_LENGTH;
  150 + }
  151 + RegCloseKey(hKey);
  152 + }
  153 + }
  154 +
  155 + void registry_set_double(HKEY hKey, const gchar *key, gdouble value)
  156 + {
  157 + // Reference: http://git.gnome.org/browse/glib/tree/glib/gkeyfile.c
  158 + gchar result[G_ASCII_DTOSTR_BUF_SIZE];
  159 + g_ascii_dtostr (result, sizeof (result), value);
  160 +
  161 + RegSetValueEx(hKey,key,0,REG_SZ,(const BYTE *) result,strlen(result)+1);
  162 + }
  163 +
  164 + gboolean registry_get_double(HKEY hKey, const gchar *key, gdouble *value)
  165 + {
  166 +// GError * error = NULL;
  167 + BYTE data[4096];
  168 + unsigned long datatype;
  169 + unsigned long datalen = sizeof(data);
  170 + gchar * end_of_valid_d;
  171 +
  172 + if(RegQueryValueExA(hKey,key,NULL,&datatype,data,&datalen) != ERROR_SUCCESS)
  173 + return FALSE;
  174 +
  175 + data[datalen] = 0;
  176 +
  177 + * value = g_ascii_strtod((const gchar *) data, &end_of_valid_d);
  178 +
  179 + if(*end_of_valid_d != '\0' || end_of_valid_d == ((gchar *) data))
  180 + {
  181 + g_warning("Key %s on registry isnt a valid double value",key);
  182 + return FALSE;
  183 + }
  184 +
  185 + return TRUE;
  186 + }
  187 +
  188 +
  189 +
  190 +#else
  191 +
  192 + static gchar * search_for_ini(void)
  193 + {
  194 + static const gchar * (*dir[])(void) =
  195 + {
  196 + g_get_user_config_dir,
  197 + g_get_user_data_dir,
  198 + g_get_home_dir,
  199 + };
  200 +
  201 + size_t f;
  202 + g_autofree gchar * name = g_strconcat(g_get_application_name(),".conf",NULL);
  203 +
  204 + //
  205 + // First search the user data
  206 + //
  207 +
  208 + for(f=0;f<G_N_ELEMENTS(dir);f++)
  209 + {
  210 + gchar *filename = g_build_filename(dir[f](),name,NULL);
  211 +
  212 + trace("Checking for %s",filename);
  213 +
  214 + if(g_file_test(filename,G_FILE_TEST_IS_REGULAR))
  215 + return filename;
  216 + g_free(filename);
  217 +
  218 + }
  219 +
  220 +#ifdef DATADIR
  221 + //
  222 + // Search the application DATADIR
  223 + //
  224 + {
  225 + gchar *filename = g_build_filename(DATAROOTDIR,G_STRINGIFY(PRODUCT_NAME),name,NULL);
  226 +
  227 + trace("Checking for default config \"%s\"",filename);
  228 +
  229 + if(g_file_test(filename,G_FILE_TEST_IS_REGULAR))
  230 + return filename;
  231 +
  232 + g_message("Can't find default config (%s)",filename);
  233 +
  234 + g_free(filename);
  235 +
  236 + }
  237 +#endif // DATADIR
  238 +
  239 + //
  240 + // Search the system config folders
  241 + //
  242 + const gchar * const * sysconfig = g_get_system_config_dirs();
  243 + for(f=0;sysconfig[f];f++)
  244 + {
  245 + gchar *filename = g_build_filename(sysconfig[f],name,NULL);
  246 + trace("Checking for %s",filename);
  247 + if(g_file_test(filename,G_FILE_TEST_IS_REGULAR))
  248 + return filename;
  249 + g_free(filename);
  250 + }
  251 +
  252 + //
  253 + // Search the system data folders
  254 + //
  255 + const gchar * const * sysdata = g_get_system_data_dirs();
  256 + for(f=0;sysdata[f];f++)
  257 + {
  258 + gchar *filename;
  259 +
  260 + // Check for product dir
  261 + filename = g_build_filename(sysdata[f],G_STRINGIFY(PRODUCT_NAME),name,NULL);
  262 + trace("Checking for system data \"%s\"",filename);
  263 + if(g_file_test(filename,G_FILE_TEST_IS_REGULAR))
  264 + return filename;
  265 + g_free(filename);
  266 +
  267 + // Check for file
  268 + filename = g_build_filename(sysdata[f],name,NULL);
  269 + trace("Checking for system data \"%s\"",filename);
  270 + if(g_file_test(filename,G_FILE_TEST_IS_REGULAR))
  271 + return filename;
  272 + g_free(filename);
  273 +
  274 +
  275 +
  276 + }
  277 +
  278 + //
  279 + // Can't find, use user config dir
  280 + //
  281 + g_message("No config, defaulting to %s/%s",g_get_user_config_dir(),name);
  282 + return g_build_filename(g_get_user_config_dir(),name,NULL);
  283 +
  284 + }
  285 +#endif // #ifdef ENABLE_WINDOWS_REGISTRY
  286 +
  287 + gboolean get_boolean_from_config(const gchar *group, const gchar *key, gboolean def)
  288 + {
  289 +#ifdef ENABLE_WINDOWS_REGISTRY
  290 + gboolean ret = def;
  291 + HKEY hKey;
  292 +
  293 + if(registry_query(group,key,&hKey) != REG_KEY_INEXISTENT)
  294 + {
  295 + DWORD data;
  296 + unsigned long datalen = sizeof(data);
  297 + unsigned long datatype;
  298 +
  299 + if(RegQueryValueExA(hKey,key,NULL,&datatype,(BYTE *) &data,&datalen) == ERROR_SUCCESS)
  300 + {
  301 + if(datatype == REG_DWORD)
  302 + ret = data ? TRUE : FALSE;
  303 + else
  304 + g_warning("Unexpected registry data type in %s\\%s\\%s\\%s",registry_path,g_get_application_name(),group,key);
  305 + }
  306 +
  307 + RegCloseKey(hKey);
  308 + }
  309 +
  310 + return ret;
  311 +
  312 +#else
  313 +
  314 + if(program_config)
  315 + {
  316 + GError * err = NULL;
  317 + gboolean val = g_key_file_get_boolean(program_config,group,key,&err);
  318 + if(err)
  319 + g_error_free(err);
  320 + else
  321 + return val;
  322 + }
  323 +#endif // ENABLE_WINDOWS_REGISTRY
  324 +
  325 + return def;
  326 + }
  327 +
  328 + gint get_integer_from_config(const gchar *group, const gchar *key, gint def)
  329 + {
  330 +#ifdef ENABLE_WINDOWS_REGISTRY
  331 +
  332 + HKEY key_handle;
  333 +
  334 + if(registry_open_key(group,key,KEY_READ,&key_handle))
  335 + {
  336 + DWORD data;
  337 + gint ret = def;
  338 + unsigned long datalen = sizeof(data);
  339 + unsigned long datatype;
  340 +
  341 + if(RegQueryValueExA(key_handle,key,NULL,&datatype,(BYTE *) &data,&datalen) == ERROR_SUCCESS)
  342 + {
  343 + if(datatype == REG_DWORD)
  344 + ret = (gint) data;
  345 + else
  346 + g_warning("Unexpected registry data type in %s\\%s\\%s\\%s",registry_path,g_get_application_name(),group,key);
  347 + }
  348 +
  349 + RegCloseKey(key_handle);
  350 +
  351 + return ret;
  352 +
  353 + }
  354 +
  355 +#else
  356 +
  357 + if(program_config)
  358 + {
  359 + GError * err = NULL;
  360 + gint val = g_key_file_get_integer(program_config,group,key,&err);
  361 + if(err)
  362 + g_error_free(err);
  363 + else
  364 + return val;
  365 + }
  366 +#endif // ENABLE_WINDOWS_REGISTRY
  367 +
  368 + return def;
  369 + }
  370 +
  371 +
  372 + gchar * get_string_from_config(const gchar *group, const gchar *key, const gchar *def)
  373 + {
  374 +#ifdef ENABLE_WINDOWS_REGISTRY
  375 +
  376 + HKEY key_handle;
  377 + unsigned long datalen = 4096;
  378 + unsigned long datatype;
  379 + gchar * ret = NULL;
  380 + BYTE * data;
  381 +
  382 + if(!registry_open_key(group,key,KEY_READ,&key_handle))
  383 + {
  384 + if(def)
  385 + return g_strdup(def);
  386 + return NULL;
  387 + }
  388 +
  389 + data = (BYTE *) g_malloc0(datalen+2);
  390 +
  391 + if(RegQueryValueExA(key_handle,key,NULL,&datatype,data,&datalen) == ERROR_SUCCESS)
  392 + {
  393 + data[datalen+1] = 0;
  394 + ret = g_strdup((const gchar *) data);
  395 + }
  396 + else if(def)
  397 + {
  398 + ret = g_strdup(def);
  399 + }
  400 +
  401 + g_free(data);
  402 +
  403 + RegCloseKey(key_handle);
  404 +
  405 + return ret;
  406 +
  407 +#else
  408 +
  409 + if(program_config)
  410 + {
  411 + gchar *ret = g_key_file_get_string(program_config,group,key,NULL);
  412 + if(ret)
  413 + return ret;
  414 + }
  415 +
  416 + if(def)
  417 + return g_strdup(def);
  418 +
  419 + return NULL;
  420 +
  421 +#endif // ENABLE_WINDOWS_REGISTRY
  422 + }
  423 +
  424 +void configuration_init(void)
  425 +{
  426 +#ifndef ENABLE_WINDOWS_REGISTRY
  427 + gchar *filename = search_for_ini();
  428 +
  429 + if(program_config)
  430 + g_key_file_free(program_config);
  431 +
  432 + program_config = g_key_file_new();
  433 +
  434 + if(filename)
  435 + {
  436 + g_message(_("Loading %s"),filename);
  437 + g_key_file_load_from_file(program_config,filename,G_KEY_FILE_NONE,NULL);
  438 + g_free(filename);
  439 + }
  440 +
  441 +#endif // ENABLE_WINDOWS_REGISTRY
  442 +}
  443 +
  444 +static void set_string(const gchar *group, const gchar *key, const gchar *fmt, va_list args)
  445 +{
  446 + gchar * value = g_strdup_vprintf(fmt,args);
  447 +
  448 +#ifdef ENABLE_WINDOWS_REGISTRY
  449 +
  450 + gchar * path = g_strdup_printf("%s\\%s\\%s",registry_path,g_get_application_name(),group);
  451 + HKEY hKey;
  452 + DWORD disp;
  453 +
  454 + if(RegCreateKeyEx(HKEY_CURRENT_USER,path,0,NULL,REG_OPTION_NON_VOLATILE,KEY_SET_VALUE,NULL,&hKey,&disp) == ERROR_SUCCESS)
  455 + {
  456 + RegSetValueEx(hKey,key,0,REG_SZ,(const BYTE *) value,strlen(value)+1);
  457 + RegCloseKey(hKey);
  458 + }
  459 +
  460 + g_free(path);
  461 +
  462 +#else
  463 +
  464 + g_key_file_set_string(program_config,group,key,value);
  465 +
  466 +#endif
  467 +
  468 + g_free(value);
  469 +}
  470 +
  471 +void set_string_to_config(const gchar *group, const gchar *key, const gchar *fmt, ...)
  472 +{
  473 + if(fmt)
  474 + {
  475 + va_list args;
  476 + va_start(args, fmt);
  477 + set_string(group,key,fmt,args);
  478 + va_end(args);
  479 + }
  480 +#ifdef ENABLE_WINDOWS_REGISTRY
  481 + else
  482 + {
  483 +
  484 + gchar * path = g_strdup_printf("%s\\%s\\%s",registry_path,g_get_application_name(),group);
  485 + HKEY hKey;
  486 + DWORD disp;
  487 +
  488 + if(RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
  489 + {
  490 + RegDeleteKey(hKey,key);
  491 + RegCloseKey(hKey);
  492 + }
  493 +
  494 + g_free(path);
  495 +
  496 + }
  497 +#else
  498 + else if(g_key_file_has_key(program_config,group,key,NULL))
  499 + {
  500 + g_key_file_remove_key(program_config,group,key,NULL);
  501 + }
  502 +#endif
  503 +}
  504 +
  505 +void set_boolean_to_config(const gchar *group, const gchar *key, gboolean val)
  506 +{
  507 +#ifdef ENABLE_WINDOWS_REGISTRY
  508 +
  509 + HKEY hKey;
  510 + DWORD disp;
  511 + gchar * path = g_strdup_printf("%s\\%s\\%s",registry_path,g_get_application_name(),group);
  512 +
  513 +// trace("Creating key %s",path);
  514 + if(RegCreateKeyEx(HKEY_CURRENT_USER,path,0,NULL,REG_OPTION_NON_VOLATILE,KEY_SET_VALUE,NULL,&hKey,&disp) == ERROR_SUCCESS)
  515 + {
  516 + DWORD value = val ? 1 : 0;
  517 + LONG rc = RegSetValueEx(hKey, key, 0, REG_DWORD,(const BYTE *) &value,sizeof(value));
  518 +
  519 + SetLastError(rc);
  520 +
  521 + if(rc != ERROR_SUCCESS)
  522 + {
  523 + gchar *msg = g_win32_error_message(GetLastError());
  524 + g_warning("Error \"%s\" when setting key HKCU\\%s\\%s",msg,path,key);
  525 + g_free(msg);
  526 + }
  527 + RegCloseKey(hKey);
  528 + }
  529 + else
  530 + {
  531 + gchar *msg = g_win32_error_message(GetLastError());
  532 + g_warning("Error \"%s\" when creating key HKCU\\%s",msg,path);
  533 + g_free(msg);
  534 + }
  535 +
  536 + g_free(path);
  537 +
  538 +#else
  539 +
  540 + if(program_config)
  541 + g_key_file_set_boolean(program_config,group,key,val);
  542 +
  543 +#endif // ENABLE_WINDOWS_REGISTRY
  544 +
  545 +}
  546 +
  547 +void set_integer_to_config(const gchar *group, const gchar *key, gint val)
  548 +{
  549 +#ifdef ENABLE_WINDOWS_REGISTRY
  550 +
  551 + HKEY hKey;
  552 + DWORD disp;
  553 + gchar * path = g_strdup_printf("%s\\%s\\%s",registry_path,g_get_application_name(),group);
  554 +
  555 + trace("Creating key %s",path);
  556 + if(RegCreateKeyEx(HKEY_CURRENT_USER,path,0,NULL,REG_OPTION_NON_VOLATILE,KEY_SET_VALUE,NULL,&hKey,&disp) == ERROR_SUCCESS)
  557 + {
  558 + DWORD value = (DWORD) val;
  559 + LONG rc = RegSetValueEx(hKey, key, 0, REG_DWORD,(const BYTE *) &value,sizeof(value));
  560 +
  561 + SetLastError(rc);
  562 +
  563 + if(rc != ERROR_SUCCESS)
  564 + {
  565 + gchar *msg = g_win32_error_message(GetLastError());
  566 + g_warning("Error \"%s\" when setting key HKCU\\%s\\%s",msg,path,key);
  567 + g_free(msg);
  568 + }
  569 + RegCloseKey(hKey);
  570 + }
  571 + else
  572 + {
  573 + gchar *msg = g_win32_error_message(GetLastError());
  574 + g_warning("Error \"%s\" when creating key HKCU\\%s",msg,path);
  575 + g_free(msg);
  576 + }
  577 +
  578 + g_free(path);
  579 +
  580 +#else
  581 +
  582 + if(program_config)
  583 + g_key_file_set_integer(program_config,group,key,val);
  584 +
  585 +#endif // ENABLE_WINDOWS_REGISTRY
  586 +
  587 +}
  588 +
  589 +void configuration_deinit(void)
  590 +{
  591 +#if !defined(ENABLE_WINDOWS_REGISTRY)
  592 +
  593 + if(!program_config)
  594 + return;
  595 +
  596 + g_autofree gchar * text = g_key_file_to_data(program_config,NULL,NULL);
  597 +
  598 + if(text)
  599 + {
  600 + GError * error = NULL;
  601 +
  602 + g_autofree gchar * name = g_strconcat(g_get_application_name(),".conf",NULL);
  603 + g_autofree gchar * filename = g_build_filename(g_get_user_config_dir(),name,NULL);
  604 +
  605 + g_mkdir_with_parents(g_get_user_config_dir(),S_IRUSR|S_IWUSR);
  606 +
  607 + g_message( _("Saving %s"), filename);
  608 +
  609 + g_file_set_contents(filename,text,-1,&error);
  610 +
  611 + if(error) {
  612 + g_message( _( "Can't save \"%s\": %s" ), filename, error->message);
  613 + g_error_free(error);
  614 + }
  615 +
  616 + }
  617 +
  618 + g_key_file_free(program_config);
  619 + program_config = NULL;
  620 +
  621 +#endif // ENABLE_WINDOWS_REGISTRY
  622 +}
  623 +
  624 +gchar * build_data_filename(const gchar *first_element, ...)
  625 +{
  626 + va_list args;
  627 + gchar *path;
  628 +
  629 + va_start(args, first_element);
  630 + path = filename_from_va(first_element,args);
  631 + va_end(args);
  632 + return path;
  633 +}
  634 +
  635 +gchar * filename_from_va(const gchar *first_element, va_list args)
  636 +{
  637 + const gchar * appname[] = { g_get_application_name(), PACKAGE_NAME };
  638 + size_t p,f;
  639 +
  640 + // Make base path
  641 + const gchar *element;
  642 + GString * result = g_string_new("");
  643 + for(element = first_element;element;element = va_arg(args, gchar *))
  644 + {
  645 + g_string_append_c(result,G_DIR_SEPARATOR);
  646 + g_string_append(result,element);
  647 + }
  648 +
  649 + g_autofree gchar * suffix = g_string_free(result, FALSE);
  650 +
  651 +#if defined( ENABLE_WINDOWS_REGISTRY )
  652 + for(p=0;p<G_N_ELEMENTS(appname) && !result;p++)
  653 + {
  654 + g_autofree gchar * path = g_strconcat("Software\\",appname[p],NULL);
  655 +
  656 + HKEY hKey = 0;
  657 + LONG rc = 0;
  658 +
  659 + // Note: This could be needed: http://support.microsoft.com/kb/556009
  660 + // http://msdn.microsoft.com/en-us/library/windows/desktop/aa384129(v=vs.85).aspx
  661 +
  662 + rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,path,0,KEY_QUERY_VALUE,&hKey);
  663 + SetLastError(rc);
  664 +
  665 + if(rc == ERROR_SUCCESS)
  666 + {
  667 + char data[4096];
  668 + unsigned long datalen = sizeof(data); // data field length(in), data returned length(out)
  669 + unsigned long datatype; // #defined in winnt.h (predefined types 0-11)
  670 +
  671 + rc = RegQueryValueExA(hKey,"datadir",NULL,&datatype,(LPBYTE) data,&datalen);
  672 + if(rc == ERROR_SUCCESS)
  673 + {
  674 + gchar * path = g_build_filename(data,appname[p],suffix,NULL);
  675 + trace("searching \"%s\"",path);
  676 + if(g_file_test(path,G_FILE_TEST_EXISTS))
  677 + return path;
  678 + g_free(path);
  679 + }
  680 + RegCloseKey(hKey);
  681 + }
  682 +
  683 + }
  684 +#endif // ENABLE_WINDOWS_REGISTRY
  685 +
  686 +#ifdef _WIN32
  687 + for(p=0;p<G_N_ELEMENTS(appname) && !result;p++)
  688 + {
  689 + gchar * path = g_build_filename(g_win32_get_package_installation_directory_of_module(NULL),appname[p],suffix,NULL);
  690 + trace("searching \"%s\"",path);
  691 + if(g_file_test(path,G_FILE_TEST_EXISTS))
  692 + return path;
  693 + g_free(path);
  694 + }
  695 +#endif // _WIN32
  696 +
  697 + // Check system data dirs
  698 + const gchar * const * system_data_dirs = g_get_system_data_dirs();
  699 + for(p=0;p<G_N_ELEMENTS(appname);p++)
  700 + {
  701 + for(f=0;system_data_dirs[f];f++)
  702 + {
  703 + gchar * path = g_build_filename(system_data_dirs[f],appname[p],suffix,NULL);
  704 + trace("searching \"%s\"",path);
  705 + if(g_file_test(path,G_FILE_TEST_EXISTS))
  706 + return path;
  707 + g_free(path);
  708 + }
  709 +
  710 + }
  711 +
  712 + // Check current dir
  713 + g_autofree gchar *dir = g_get_current_dir();
  714 + gchar * path = g_build_filename(dir,suffix,NULL);
  715 + trace("searching \"%s\"",path);
  716 + if(g_file_test(path,G_FILE_TEST_EXISTS))
  717 + return path;
  718 + g_free(path);
  719 +
  720 + trace("Can't find \"%s\"",suffix);
  721 +
  722 + return g_build_filename(".",suffix,NULL);
  723 +}
  724 +
  725 +#ifdef ENABLE_WINDOWS_REGISTRY
  726 +gboolean get_registry_handle(const gchar *group, HKEY *hKey, REGSAM samDesired)
  727 +{
  728 + gboolean ret;
  729 + gchar * path;
  730 + DWORD disp;
  731 +
  732 + if(group)
  733 + path = g_strdup_printf("%s\\%s\\%s",registry_path,g_get_application_name(),group);
  734 + else
  735 + path = g_strdup_printf("%s\\%s",registry_path,g_get_application_name());
  736 +
  737 + if(RegCreateKeyEx(HKEY_CURRENT_USER,path,0,NULL,REG_OPTION_NON_VOLATILE,samDesired,NULL,hKey,&disp) == ERROR_SUCCESS)
  738 + ret = TRUE;
  739 + else
  740 + ret = FALSE;
  741 +
  742 + g_free(path);
  743 +
  744 + return ret;
  745 +}
  746 +#else
  747 +#error Replace it!
  748 +GKeyFile * get_application_keyfile(void)
  749 +{
  750 + if(!program_config)
  751 + configuration_init();
  752 + return program_config;
  753 +}
  754 +#endif // ENABLE_WINDOWS_REGISTRY
  755 +
  756 + static const struct _WindowState
  757 + {
  758 + const char *name;
  759 + GdkWindowState flag;
  760 + void (*activate)(GtkWindow *);
  761 + } WindowState[] =
  762 + {
  763 + { "Maximized", GDK_WINDOW_STATE_MAXIMIZED, gtk_window_maximize },
  764 + { "Iconified", GDK_WINDOW_STATE_ICONIFIED, gtk_window_iconify },
  765 + { "Sticky", GDK_WINDOW_STATE_STICKY, gtk_window_stick }
  766 + };
  767 +
  768 +void save_window_state_to_config(const gchar *group, const gchar *key, GdkWindowState CurrentState)
  769 +{
  770 +#if defined( ENABLE_WINDOWS_REGISTRY )
  771 +
  772 + gchar * path = g_strdup_printf("%s\\%s\\%s\\%s",registry_path,g_get_application_name(),group,key);
  773 +
  774 + HKEY hKey;
  775 + DWORD disp;
  776 +
  777 + if(RegCreateKeyEx(HKEY_CURRENT_USER,path,0,NULL,REG_OPTION_NON_VOLATILE,KEY_SET_VALUE,NULL,&hKey,&disp) == ERROR_SUCCESS)
  778 + {
  779 + int f;
  780 + for(f=0;f<G_N_ELEMENTS(WindowState);f++)
  781 + {
  782 + DWORD value = (CurrentState & WindowState[f].flag) ? 1 : 0;
  783 +// trace("%s=%s",WindowState[f].name,value ? "Yes" : "No");
  784 + RegSetValueEx(hKey, WindowState[f].name, 0, REG_DWORD,(const BYTE *) &value,sizeof(value));
  785 + }
  786 +
  787 + RegCloseKey(hKey);
  788 + }
  789 +
  790 + g_free(path);
  791 +
  792 +#else
  793 + int f;
  794 + GKeyFile * conf = get_application_keyfile();
  795 + gchar * id = g_strconcat(group,".",key,NULL);
  796 +
  797 + for(f=0;f<G_N_ELEMENTS(WindowState);f++)
  798 + g_key_file_set_boolean(conf,id,WindowState[f].name,CurrentState & WindowState[f].flag);
  799 +
  800 + g_free(id);
  801 +
  802 +#endif // ENABLE_WINDOWS_REGISTRY
  803 +}
  804 +
  805 +void save_window_size_to_config(const gchar *group, const gchar *key, GtkWidget *hwnd)
  806 +{
  807 +#if defined( ENABLE_WINDOWS_REGISTRY )
  808 +
  809 + gchar * path = g_strdup_printf("%s\\%s\\%s\\%s",registry_path,g_get_application_name(),group,key);
  810 +
  811 + HKEY hKey;
  812 + DWORD disp;
  813 +
  814 + if(RegCreateKeyEx(HKEY_CURRENT_USER,path,0,NULL,REG_OPTION_NON_VOLATILE,KEY_SET_VALUE,NULL,&hKey,&disp) == ERROR_SUCCESS)
  815 + {
  816 + int pos[2];
  817 +
  818 + gtk_window_get_size(GTK_WINDOW(hwnd),&pos[0],&pos[1]);
  819 +
  820 + RegSetValueEx(hKey, "Size", 0, REG_BINARY,(const BYTE *) pos,sizeof(pos));
  821 +
  822 + RegCloseKey(hKey);
  823 + }
  824 +
  825 + g_free(path);
  826 +
  827 +#else
  828 + int pos[2];
  829 + GKeyFile * conf = get_application_keyfile();
  830 + gchar * id = g_strconcat(group,".",key,NULL);
  831 +
  832 + gtk_window_get_size(GTK_WINDOW(hwnd),&pos[0],&pos[1]);
  833 + g_key_file_set_integer_list(conf,id,"size",pos,2);
  834 +
  835 + g_free(id);
  836 +
  837 +#endif // ENABLE_WINDOWS_REGISTRY
  838 +}
  839 +
  840 +#if defined( ENABLE_WINDOWS_REGISTRY )
  841 +static void restore_window_from_regkey(GtkWidget *hwnd, HKEY hKey, const gchar *path)
  842 +{
  843 + int f;
  844 + int pos[2];
  845 + unsigned long datalen;
  846 + unsigned long datatype;
  847 +
  848 +
  849 + datalen = sizeof(pos);
  850 + if(RegQueryValueExA(hKey,"Size",NULL,&datatype,(BYTE *) pos,&datalen) == ERROR_SUCCESS)
  851 + {
  852 + if(datatype == REG_BINARY && datalen == sizeof(pos))
  853 + {
  854 + gtk_window_resize(GTK_WINDOW(hwnd),pos[0],pos[1]);
  855 + }
  856 + else
  857 + {
  858 + g_warning("Unexpected registry data in %s\\Size",path);
  859 + }
  860 + }
  861 +
  862 +
  863 + for(f=0;f<G_N_ELEMENTS(WindowState);f++)
  864 + {
  865 + DWORD data;
  866 +
  867 + datalen = sizeof(data);
  868 +
  869 + if(RegQueryValueExA(hKey,WindowState[f].name,NULL,&datatype,(BYTE *) &data,&datalen) == ERROR_SUCCESS)
  870 + {
  871 + if(datatype == REG_DWORD)
  872 + {
  873 + if(data)
  874 + WindowState[f].activate(GTK_WINDOW(hwnd));
  875 +
  876 + }
  877 + else
  878 + {
  879 + g_warning("Unexpected registry data type in %s\\%s",path,WindowState[f].name);
  880 + }
  881 + }
  882 + }
  883 +
  884 +
  885 +}
  886 +#endif // ENABLE_WINDOWS_REGISTRY
  887 +
  888 +void restore_window_from_config(const gchar *group, const gchar *key, GtkWidget *hwnd)
  889 +{
  890 +#if defined( ENABLE_WINDOWS_REGISTRY )
  891 +
  892 + gchar * path = g_strdup_printf("%s\\%s\\%s\\%s",registry_path,g_get_application_name(),group,key);
  893 + HKEY hKey;
  894 +
  895 + if(RegOpenKeyEx(HKEY_CURRENT_USER,path,0,KEY_READ,&hKey) == ERROR_SUCCESS)
  896 + {
  897 + // Load user settings
  898 + restore_window_from_regkey(hwnd,hKey,path);
  899 + RegCloseKey(hKey);
  900 + }
  901 + else if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,path,0,KEY_READ,&hKey) == ERROR_SUCCESS)
  902 + {
  903 + // Load system defaults
  904 + restore_window_from_regkey(hwnd,hKey,path);
  905 + RegCloseKey(hKey);
  906 + }
  907 +
  908 + g_free(path);
  909 +
  910 +#else
  911 + gchar * id = g_strconcat(group,".",key,NULL);
  912 + GKeyFile * conf = get_application_keyfile();
  913 +
  914 + if(g_key_file_has_key(conf,id,"size",NULL))
  915 + {
  916 + gsize sz = 2;
  917 + gint * vlr = g_key_file_get_integer_list(conf,id,"size",&sz,NULL);
  918 + int f;
  919 +
  920 + if(vlr)
  921 + {
  922 + gtk_window_resize(GTK_WINDOW(hwnd),vlr[0],vlr[1]);
  923 + g_free(vlr);
  924 + }
  925 +
  926 + for(f=0;f<G_N_ELEMENTS(WindowState);f++)
  927 + {
  928 + if(g_key_file_get_boolean(conf,id,WindowState[f].name,NULL))
  929 + WindowState[f].activate(GTK_WINDOW(hwnd));
  930 + }
  931 +
  932 + }
  933 +
  934 + g_free(id);
  935 +
  936 +#endif // ENABLE_WINDOWS_REGISTRY
  937 +
  938 +}
  939 +
... ...