Commit adecb5db3e52c32d602c744d54514b3d2ad8dbd3

Authored by perry.werneck@gmail.com
1 parent 0186bf84

Implementando interface DBUS

src/plugins/dbus/Makefile.in
... ... @@ -30,8 +30,8 @@
30 30  
31 31 MODULE_NAME=pw3270dbus
32 32 DEPENDS=Makefile dbus-glue.h
33   -PLUGIN_SRC=main.c
34   -DAEMON_SRC=daemon.c gobject.c
  33 +PLUGIN_SRC=main.c gobject.c
  34 +DAEMON_SRC=daemon.c gobject.c iocallback.c
35 35  
36 36 #---[ Paths ]------------------------------------------------------------------
37 37  
... ...
src/plugins/dbus/daemon.c
... ... @@ -38,13 +38,17 @@
38 38 #include <dbus/dbus-glib-lowlevel.h>
39 39 #include <dbus/dbus-glib.h>
40 40  
41   -#include "service.h"
  41 +#include "daemon.h"
42 42 #include "dbus-glue.h"
43 43  
44 44 /*---[ Globals ]---------------------------------------------------------------------------------*/
45 45  
46 46 static DBusGConnection * connection = NULL;
47 47 static DBusGProxy * proxy = NULL;
  48 + static H3270 * hSession = NULL;
  49 +
  50 + GMainLoop * main_loop = NULL;
  51 +
48 52  
49 53 /*---[ Implement ]-------------------------------------------------------------------------------*/
50 54  
... ... @@ -80,8 +84,6 @@ static int initialize(void)
80 84  
81 85 int main(int numpar, char *param[])
82 86 {
83   - GMainLoop *loop;
84   -
85 87 g_type_init ();
86 88  
87 89 if (!g_thread_supported ())
... ... @@ -89,16 +91,31 @@ int main(int numpar, char *param[])
89 91  
90 92 dbus_g_thread_init ();
91 93  
92   - loop = g_main_loop_new (NULL, FALSE);
  94 + pw3270_dbus_register_io_handlers();
  95 +
  96 + hSession = lib3270_session_new("");
  97 +
  98 + main_loop = g_main_loop_new (NULL, FALSE);
93 99  
94 100 if(initialize())
95 101 return -1;
96 102  
97 103  
98   - g_main_loop_run(loop);
  104 + g_main_loop_run(main_loop);
  105 +
  106 + lib3270_session_free(hSession);
99 107  
100 108 return 0;
101 109 }
102 110  
  111 +void pw3270_dbus_quit(PW3270Dbus *object, DBusGMethodInvocation *context)
  112 +{
  113 + g_main_loop_quit(main_loop);
  114 + dbus_g_method_return(context,0);
  115 +}
103 116  
  117 +H3270 * pw3270_dbus_get_session_handle(PW3270Dbus *object)
  118 +{
  119 + return hSession;
  120 +}
104 121  
... ...
src/plugins/dbus/daemon.h 0 → 100644
... ... @@ -0,0 +1,46 @@
  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 daemon.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 + * Referencias:
  31 + *
  32 + * https://live.gnome.org/DBusGlibBindings
  33 + *
  34 + */
  35 +
  36 + #include "service.h"
  37 +
  38 +/*---[ Globals ]---------------------------------------------------------------------------------*/
  39 +
  40 + G_GNUC_INTERNAL GMainLoop * main_loop;
  41 +
  42 +
  43 +/*---[ Prototipes ]------------------------------------------------------------------------------*/
  44 +
  45 + G_GNUC_INTERNAL void pw3270_dbus_register_io_handlers(void);
  46 +
... ...
src/plugins/dbus/gobject.c
... ... @@ -57,9 +57,9 @@ static void pw3270_dbus_finalize(GObject *object)
57 57  
58 58 static void pw3270_dbus_class_init(PW3270DbusClass *klass)
59 59 {
60   - GObjectClass *object_class;
61   - object_class = G_OBJECT_CLASS (klass);
62   - object_class->finalize = pw3270_dbus_finalize;
  60 + GObjectClass *object_class;
  61 + object_class = G_OBJECT_CLASS (klass);
  62 + object_class->finalize = pw3270_dbus_finalize;
63 63 }
64 64  
65 65 static void pw3270_dbus_init(PW3270Dbus *object)
... ... @@ -76,3 +76,17 @@ void pw3270_dbus_get_revision(PW3270Dbus *object, DBusGMethodInvocation *context
76 76 {
77 77 dbus_g_method_return(context,PACKAGE_REVISION);
78 78 }
  79 +
  80 +void pw3270_dbus_connect(PW3270Dbus *object, const gchar *uri, DBusGMethodInvocation *context)
  81 +{
  82 + g_message("Connecting to \"%s\" by remote request",uri);
  83 + dbus_g_method_return(context,lib3270_connect(pw3270_dbus_get_session_handle(PW3270_DBUS(object)),uri,0));
  84 +}
  85 +
  86 +void pw3270_dbus_disconnect(PW3270Dbus *object, DBusGMethodInvocation *context)
  87 +{
  88 + g_message("Disconnecting by remote request");
  89 + lib3270_disconnect(pw3270_dbus_get_session_handle(PW3270_DBUS(object)));
  90 + dbus_g_method_return(context,0);
  91 +}
  92 +
... ...
src/plugins/dbus/iocallback.c 0 → 100644
... ... @@ -0,0 +1,349 @@
  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 iocallback.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 +#if defined(_WIN32) /*[*/
  33 + #include <windows.h>
  34 +#elif defined(__APPLE__)
  35 + #include <poll.h>
  36 + #include <string.h>
  37 +#else
  38 + #include <poll.h>
  39 + #include <string.h>
  40 +#endif /*]*/
  41 +
  42 +#include <stdio.h>
  43 +#include <glib.h>
  44 +#include "daemon.h"
  45 +
  46 +static int static_CallAndWait(int(*callback)(H3270 *session, void *), H3270 *session, void *parm);
  47 +static void static_RemoveSource(void *id);
  48 +
  49 +#ifdef WIN32
  50 +static void * static_AddInput(HANDLE source, H3270 *session, void (*fn)(H3270 *session));
  51 +static void * static_AddExcept(HANDLE source, H3270 *session, void (*fn)(H3270 *session));
  52 +#else
  53 +static void * static_AddInput(int source, H3270 *session, void (*fn)(H3270 *session));
  54 +static void * static_AddExcept(int source, H3270 *session, void (*fn)(H3270 *session));
  55 +#endif // WIN32
  56 +
  57 +static void * static_AddTimeOut(unsigned long interval_ms, H3270 *session, void (*proc)(H3270 *session));
  58 +static void static_RemoveTimeOut(void * timer);
  59 +static int static_Sleep(H3270 *hSession, int seconds);
  60 +static int static_RunPendingEvents(H3270 *hSession, int wait);
  61 +
  62 +static gboolean IO_prepare(GSource *source, gint *timeout);
  63 +static gboolean IO_check(GSource *source);
  64 +static gboolean IO_dispatch(GSource *source, GSourceFunc callback, gpointer user_data);
  65 +static void IO_finalize(GSource *source); /* Can be NULL */
  66 +static gboolean IO_closure(gpointer data);
  67 +
  68 +/*---[ Structs ]-------------------------------------------------------------------------------------------*/
  69 +
  70 + typedef struct _IO_Source
  71 + {
  72 + GSource gsrc;
  73 + GPollFD poll;
  74 +#if defined(_WIN32)
  75 + HANDLE source;
  76 +#else
  77 + int source;
  78 +#endif // WIN32
  79 + void (*fn)(H3270 *session);
  80 + H3270 *session;
  81 + } IO_Source;
  82 +
  83 + typedef struct _timer
  84 + {
  85 + unsigned char remove;
  86 + void (*fn)(H3270 *session);
  87 + H3270 *session;
  88 + } TIMER;
  89 +
  90 + static GSourceFuncs IOSources =
  91 + {
  92 + IO_prepare,
  93 + IO_check,
  94 + IO_dispatch,
  95 + IO_finalize,
  96 + IO_closure,
  97 + NULL
  98 + };
  99 +
  100 +/*---[ Implement ]-----------------------------------------------------------------------------------------*/
  101 +
  102 +#ifdef WIN32
  103 +static void * AddSource(HANDLE source, H3270 *session, gushort events, void (*fn)(H3270 *session))
  104 +#else
  105 +static void * AddSource(int source, H3270 *session, gushort events, void (*fn)(H3270 *session))
  106 +#endif // WIN32
  107 +{
  108 + IO_Source *src = (IO_Source *) g_source_new(&IOSources,sizeof(IO_Source));
  109 +
  110 + src->source = source;
  111 + src->fn = fn;
  112 + src->poll.fd = (int) source;
  113 + src->poll.events = events;
  114 + src->session = session;
  115 +
  116 + g_source_attach((GSource *) src,NULL);
  117 + g_source_add_poll((GSource *) src,&src->poll);
  118 +
  119 + return src;
  120 +}
  121 +
  122 +#ifdef WIN32
  123 +static void * static_AddInput(HANDLE source, H3270 *session, void (*fn)(H3270 *session))
  124 +#else
  125 +static void * static_AddInput(int source, H3270 *session, void (*fn)(H3270 *session))
  126 +#endif // WIN32
  127 +{
  128 + return AddSource(source,session,G_IO_IN|G_IO_HUP|G_IO_ERR,fn);
  129 +}
  130 +
  131 +static void static_RemoveSource(void *id)
  132 +{
  133 + if(id)
  134 + g_source_destroy((GSource *) id);
  135 +}
  136 +
  137 +#if defined(WIN32)
  138 +static void * static_AddExcept(HANDLE source, H3270 *session, void (*fn)(H3270 *session))
  139 +{
  140 + return 0;
  141 +}
  142 +#else
  143 +static void * static_AddExcept(int source, H3270 *session, void (*fn)(H3270 *session))
  144 +{
  145 + return AddSource(source,session,G_IO_HUP|G_IO_ERR,fn);
  146 +}
  147 +#endif // WIN32
  148 +
  149 +static gboolean do_timer(TIMER *t)
  150 +{
  151 + if(!t->remove)
  152 + t->fn(t->session);
  153 + return FALSE;
  154 +}
  155 +
  156 +static void * static_AddTimeOut(unsigned long interval, H3270 *session, void (*proc)(H3270 *session))
  157 +{
  158 + TIMER *t = g_malloc0(sizeof(TIMER));
  159 +
  160 + t->fn = proc;
  161 + t->session = session;
  162 +
  163 + g_timeout_add_full(G_PRIORITY_DEFAULT, (guint) interval, (GSourceFunc) do_timer, t, g_free);
  164 +
  165 + return t;
  166 +}
  167 +
  168 +static void static_RemoveTimeOut(void * timer)
  169 +{
  170 + ((TIMER *) timer)->remove++;
  171 +}
  172 +
  173 +static gboolean IO_prepare(GSource *source, gint *timeout)
  174 +{
  175 + /*
  176 + * Called before all the file descriptors are polled.
  177 + * If the source can determine that it is ready here
  178 + * (without waiting for the results of the poll() call)
  179 + * it should return TRUE.
  180 + *
  181 + * It can also return a timeout_ value which should be the maximum
  182 + * timeout (in milliseconds) which should be passed to the poll() call.
  183 + * The actual timeout used will be -1 if all sources returned -1,
  184 + * or it will be the minimum of all the timeout_ values
  185 + * returned which were >= 0.
  186 + *
  187 + */
  188 + return 0;
  189 +}
  190 +
  191 +static gboolean IO_check(GSource *source)
  192 +{
  193 + /*
  194 + * Called after all the file descriptors are polled.
  195 + * The source should return TRUE if it is ready to be dispatched.
  196 + * Note that some time may have passed since the previous prepare
  197 + * function was called, so the source should be checked again here.
  198 + *
  199 + */
  200 +#if defined(_WIN32) /*[*/
  201 +
  202 + if(WaitForSingleObject(((IO_Source *) source)->source,0) == WAIT_OBJECT_0)
  203 + return TRUE;
  204 +
  205 +#else /*][*/
  206 +
  207 + struct pollfd fds;
  208 +
  209 + memset(&fds,0,sizeof(fds));
  210 +
  211 + fds.fd = ((IO_Source *) source)->poll.fd;
  212 + fds.events = ((IO_Source *) source)->poll.events;
  213 +
  214 + if(poll(&fds,1,0) > 0)
  215 + return TRUE;
  216 +
  217 +#endif /*]*/
  218 +
  219 + return FALSE;
  220 +}
  221 +
  222 +static gboolean IO_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
  223 +{
  224 + /*
  225 + * Called to dispatch the event source,
  226 + * after it has returned TRUE in either its prepare or its check function.
  227 + * The dispatch function is passed in a callback function and data.
  228 + * The callback function may be NULL if the source was never connected
  229 + * to a callback using g_source_set_callback(). The dispatch function
  230 + * should call the callback function with user_data and whatever additional
  231 + * parameters are needed for this type of event source.
  232 + */
  233 + ((IO_Source *) source)->fn(((IO_Source *) source)->session);
  234 + return TRUE;
  235 +}
  236 +
  237 +static void IO_finalize(GSource *source)
  238 +{
  239 +
  240 +}
  241 +
  242 +static gboolean IO_closure(gpointer data)
  243 +{
  244 + return 0;
  245 +}
  246 +
  247 +struct bgParameter
  248 +{
  249 + gboolean running;
  250 + H3270 *session;
  251 + int rc;
  252 + int(*callback)(H3270 *session, void *);
  253 + void *parm;
  254 +
  255 +};
  256 +
  257 +gpointer BgCall(struct bgParameter *p)
  258 +{
  259 +// trace("%s starts",__FUNCTION__);
  260 + p->rc = p->callback(p->session, p->parm);
  261 + p->running = FALSE;
  262 +// trace("%s ends",__FUNCTION__);
  263 + return 0;
  264 +}
  265 +
  266 +static int static_CallAndWait(int(*callback)(H3270 *session, void *), H3270 *session, void *parm)
  267 +{
  268 + struct bgParameter p = { TRUE, session, -1, callback, parm };
  269 + GThread *thread;
  270 +
  271 +// trace("Starting auxiliary thread for callback %p",callback);
  272 +
  273 + p.running = TRUE;
  274 + thread = g_thread_create( (GThreadFunc) BgCall, &p, 0, NULL);
  275 +
  276 + if(!thread)
  277 + {
  278 + g_error("Can't start background thread");
  279 + return -1;
  280 + }
  281 +
  282 + while(p.running)
  283 + g_main_context_iteration(g_main_loop_get_context(main_loop),TRUE);
  284 +
  285 + return p.rc;
  286 +}
  287 +
  288 +static int static_Sleep(H3270 *hSession, int seconds)
  289 +{
  290 + time_t end = time(0) + seconds;
  291 +
  292 + while(time(0) < end)
  293 + g_main_iteration(TRUE);
  294 +
  295 + return 0;
  296 +}
  297 +
  298 +static int static_RunPendingEvents(H3270 *hSession, int wait)
  299 +{
  300 + GMainContext *context = g_main_loop_get_context(main_loop);
  301 + int rc = 0;
  302 + while(g_main_context_pending(context))
  303 + {
  304 + rc = 1;
  305 + g_main_context_iteration(context,FALSE);
  306 + }
  307 +
  308 + if(wait)
  309 + g_main_context_iteration(context,TRUE);
  310 +
  311 + return rc;
  312 +}
  313 +
  314 +static void beep(H3270 *session)
  315 +{
  316 +}
  317 +
  318 +void pw3270_dbus_register_io_handlers(void)
  319 +{
  320 + static const struct lib3270_callbacks hdl =
  321 + {
  322 + sizeof(struct lib3270_callbacks),
  323 +
  324 + static_AddTimeOut,
  325 + static_RemoveTimeOut,
  326 +
  327 + static_AddInput,
  328 + static_RemoveSource,
  329 +
  330 + static_AddExcept,
  331 +
  332 +#ifdef G_THREADS_ENABLED
  333 + static_CallAndWait,
  334 +#else
  335 + NULL,
  336 +#endif
  337 +
  338 + static_Sleep,
  339 + static_RunPendingEvents,
  340 + beep
  341 +
  342 + };
  343 +
  344 + if(lib3270_register_handlers(&hdl))
  345 + {
  346 + g_error("%s","Can't set lib3270 I/O handlers");
  347 + }
  348 +
  349 +}
... ...
src/plugins/dbus/pw3270dbus.cbp
... ... @@ -42,6 +42,9 @@
42 42 <Add option="-Wall" />
43 43 </Compiler>
44 44 <Unit filename="Makefile.in" />
  45 + <Unit filename="daemon.c">
  46 + <Option compilerVar="CC" />
  47 + </Unit>
45 48 <Unit filename="dbus-glue.h" />
46 49 <Unit filename="gobject.c">
47 50 <Option compilerVar="CC" />
... ... @@ -51,9 +54,7 @@
51 54 </Unit>
52 55 <Unit filename="pw3270dbus.xml" />
53 56 <Unit filename="service.h" />
54   - <Unit filename="testprogram.c">
55   - <Option compilerVar="CC" />
56   - </Unit>
  57 + <Unit filename="test.sh" />
57 58 <Extensions>
58 59 <code_completion />
59 60 <debugger />
... ...
src/plugins/dbus/pw3270dbus.xml
... ... @@ -5,5 +5,18 @@
5 5 <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
6 6 <arg type="s" name="revision" direction="out" />
7 7 </method>
  8 + <method name="quit">
  9 + <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
  10 + <arg type="i" name="result" direction="out" />
  11 + </method>
  12 + <method name="connect">
  13 + <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
  14 + <arg type="s" name="uri" direction="in" />
  15 + <arg type="i" name="result" direction="out" />
  16 + </method>
  17 + <method name="disconnect">
  18 + <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
  19 + <arg type="i" name="result" direction="out" />
  20 + </method>
8 21 </interface>
9 22 </node>
... ...
src/plugins/dbus/service.h
1 1 #ifndef _PW3270_DBUS_SERVICE_H
2 2  
3   - #define _PW3270_DBUS_SERVICE_H
  3 + #define _PW3270_DBUS_SERVICE_H 1
4 4  
  5 + #include <lib3270.h>
5 6 #include <glib.h>
6 7 #include <dbus/dbus-glib.h>
7 8 #include <dbus/dbus-glib-bindings.h>
... ... @@ -36,6 +37,10 @@
36 37 GType pw3270_dbus_get_type (void);
37 38  
38 39 void pw3270_dbus_get_revision(PW3270Dbus *object, DBusGMethodInvocation *context);
  40 + void pw3270_dbus_quit(PW3270Dbus *object, DBusGMethodInvocation *context);
  41 + void pw3270_dbus_connect(PW3270Dbus *object, const gchar *uri, DBusGMethodInvocation *context);
  42 + void pw3270_dbus_disconnect(PW3270Dbus *object, DBusGMethodInvocation *context);
  43 + H3270 * pw3270_dbus_get_session_handle(PW3270Dbus *object);
39 44  
40 45 G_END_DECLS
41 46  
... ...
src/plugins/dbus/test.sh
1 1 #!/bin/bash
2   -dbus-send --session --print-reply --dest=br.com.bb.pw3270 /br/com/bb/pw3270 br.com.bb.pw3270.getRevision
  2 +
  3 +case $1 in
  4 +
  5 + revision)
  6 + dbus-send --session --print-reply --dest=br.com.bb.pw3270 /br/com/bb/pw3270 br.com.bb.pw3270.getRevision
  7 + ;;
  8 +
  9 + connect)
  10 + dbus-send --session --print-reply --dest=br.com.bb.pw3270 /br/com/bb/pw3270 br.com.bb.pw3270.connect string:$2
  11 + ;;
  12 +
  13 + disconnect)
  14 + dbus-send --session --print-reply --dest=br.com.bb.pw3270 /br/com/bb/pw3270 br.com.bb.pw3270.disconnect
  15 + ;;
  16 +
  17 + quit)
  18 + dbus-send --session --print-reply --dest=br.com.bb.pw3270 /br/com/bb/pw3270 br.com.bb.pw3270.quit
  19 + ;;
  20 +
  21 + *)
  22 + dbus-send --session --print-reply --dest=br.com.bb.pw3270 /br/com/bb/pw3270 br.com.bb.pw3270.getRevision
  23 + ;;
  24 +
  25 +esac
3 26  
... ...