grim/guifications3
Clone
Summary
Browse
Changes
Graph
removed GfHash since nothing is using it right now and we can just use the hashing stuff in glib
2011-05-17, Gary Kramlich
3d11600033ad
removed GfHash since nothing is using it right now and we can just use the hashing stuff in glib
/*
* Guifications - The end-all, be-all notification framework
* Copyright (C) 2003-2009 Gary Kramlich <grim@reaperworld.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#
include
<config.h>
#endif
/* HAVE_CONFIG_H */
#include
"guifications-daemon-connections.h"
/******************************************************************************
* Globals
*****************************************************************************/
static
GHashTable
*
connections
=
NULL
;
static
GfFeedManager
*
feed_manager
=
NULL
;
static
GfPreferenceEngine
*
engine
=
NULL
;
/******************************************************************************
* Local Server Connection Object
*****************************************************************************/
static
GfConnection
*
local_server
=
NULL
;
typedef
struct
{
GfServerConnection
gparent
;
}
GfdLocalServerConnection
;
typedef
struct
{
GfServerConnectionClass
gparent
;
}
GfdLocalServerConnectionClass
;
static
gboolean
gfd_local_server_connection_disconnect
(
GfConnection
*
connection
,
GError
**
e
)
{
return
TRUE
;
}
static
gboolean
gfd_local_server_connection_listen
(
GfServerConnection
*
connection
,
GError
**
e
)
{
return
TRUE
;
}
static
void
gfd_local_server_connection_class_init
(
GfConnectionClass
*
klass
)
{
GfServerConnectionClass
*
server_class
=
GF_SERVER_CONNECTION_CLASS
(
klass
);
klass
->
disconnect
=
gfd_local_server_connection_disconnect
;
server_class
->
listen
=
gfd_local_server_connection_listen
;
}
static
GType
gfd_local_server_connection_get_gtype
(
void
)
{
static
GType
type
=
0
;
if
(
G_UNLIKELY
(
type
==
0
))
{
static
const
GTypeInfo
info
=
{
.
class_size
=
sizeof
(
GfdLocalServerConnectionClass
),
.
class_init
=
(
GClassInitFunc
)
gfd_local_server_connection_class_init
,
.
instance_size
=
sizeof
(
GfdLocalServerConnection
),
};
type
=
g_type_register_static
(
GF_TYPE_SERVER_CONNECTION
,
"GfdLocalServerConnection"
,
&
info
,
0
);
}
return
type
;
}
/******************************************************************************
* Local Client Connection Object
*****************************************************************************/
static
GObjectClass
*
local_client_parent_class
=
NULL
;
typedef
struct
{
GfClientConnection
gparent
;
}
GfdLocalClientConnection
;
typedef
struct
{
GfClientConnectionClass
gparent
;
}
GfdLocalClientConnectionClass
;
static
gboolean
gfd_local_client_connection_disconnect
(
GfConnection
*
connection
,
GError
**
e
)
{
/* we set both disconnecting and disconnected so that anyone listening to
* the signals will be notified.
*/
gf_connection_set_state
(
connection
,
GF_CONNECTION_STATE_DISCONNECTING
);
gf_connection_set_state
(
connection
,
GF_CONNECTION_STATE_DISCONNECTED
);
return
TRUE
;
}
static
gboolean
gfd_local_client_connection_connect
(
GfClientConnection
*
connection
,
GError
**
e
)
{
gboolean
ret
=
FALSE
;
gf_connection_set_state
(
GF_CONNECTION
(
connection
),
GF_CONNECTION_STATE_CONNECTING
);
if
(
GF_IS_CONNECTION
(
local_server
))
{
gf_connection_set_feed_manager
(
GF_CONNECTION
(
connection
),
gf_connection_get_feed_manager
(
local_server
));
gf_connection_set_preference_engine
(
GF_CONNECTION
(
connection
),
gf_connection_get_preference_engine
(
local_server
));
ret
=
TRUE
;
}
else
{
ret
=
FALSE
;
}
gf_connection_set_state
(
GF_CONNECTION
(
connection
),
(
ret
)
?
GF_CONNECTION_STATE_CONNECTED
:
GF_CONNECTION_STATE_DISCONNECTED
);
return
ret
;
}
static
void
gfd_local_client_connection_finalize
(
GObject
*
obj
)
{
GfConnectionState
state
=
gf_connection_get_state
(
GF_CONNECTION
(
obj
));
if
(
state
!=
GF_CONNECTION_STATE_DISCONNECTING
||
state
!=
GF_CONNECTION_STATE_DISCONNECTED
)
{
gf_connection_disconnect
(
GF_CONNECTION
(
obj
),
NULL
);
}
G_OBJECT_CLASS
(
local_client_parent_class
)
->
finalize
(
obj
);
}
static
void
gfd_local_client_connection_class_init
(
GfConnectionClass
*
klass
)
{
GfClientConnectionClass
*
client_class
=
GF_CLIENT_CONNECTION_CLASS
(
klass
);
GfNamedObjectClass
*
no_class
=
GF_NAMED_OBJECT_CLASS
(
klass
);
GObjectClass
*
obj_class
=
G_OBJECT_CLASS
(
klass
);
local_client_parent_class
=
g_type_class_peek_parent
(
klass
);
klass
->
disconnect
=
gfd_local_client_connection_disconnect
;
client_class
->
connect
=
gfd_local_client_connection_connect
;
no_class
->
name
=
"Local Connection"
;
obj_class
->
finalize
=
gfd_local_client_connection_finalize
;
}
static
GType
gfd_local_client_connection_get_gtype
(
void
)
{
static
GType
type
=
0
;
if
(
G_UNLIKELY
(
type
==
0
))
{
static
const
GTypeInfo
info
=
{
.
class_size
=
sizeof
(
GfdLocalClientConnectionClass
),
.
class_init
=
(
GClassInitFunc
)
gfd_local_client_connection_class_init
,
.
instance_size
=
sizeof
(
GfdLocalClientConnection
),
};
type
=
g_type_register_static
(
GF_TYPE_CLIENT_CONNECTION
,
"GfdLocalClientConnection"
,
&
info
,
0
);
}
return
type
;
}
/******************************************************************************
* Helpers
*****************************************************************************/
static
void
gfd_connections_debug_helper
(
gpointer
k
,
gpointer
v
,
gpointer
d
)
{
GfConnection
*
c
=
NULL
;
GfFeedManager
*
fp
=
NULL
;
GfFeed
**
feeds
=
NULL
;
guint
nf
=
0
,
i
=
0
;
c
=
GF_CONNECTION
(
v
);
fp
=
gf_connection_get_feed_manager
(
c
);
gf_log_info
(
"Guifications-Daemon"
,
"Found connection %s.
\n
"
,
gf_named_object_get_name
(
GF_NAMED_OBJECT
(
c
)));
if
(
fp
)
{
gf_log_info
(
"Guifications-Daemon"
,
"
\t
Found a feed manager. Iterating children, if any.
\n
"
);
feeds
=
gf_feed_manager_list_feeds
(
fp
,
&
nf
);
if
(
feeds
&&
nf
>=
1
)
{
for
(;
i
<
nf
;
i
++
)
{
gf_log_info
(
"Guifications-Daemon"
,
"
\t\t
Found feed %s.
\n
"
,
gf_named_object_get_name
(
GF_NAMED_OBJECT
(
feeds
[
i
])));
}
}
else
{
gf_log_info
(
"Guifications-Daemon"
,
"
\t\t
No feeds in feed manager.
\n
"
);
}
}
else
{
gf_log_info
(
"Guifications-Daemon"
,
"
\t
No feed manager found in connection.
\n
"
);
}
}
static
void
gfd_connections_listen_helper
(
gpointer
k
,
gpointer
v
,
gpointer
d
)
{
GfServerConnection
*
c
=
GF_SERVER_CONNECTION
(
v
);
GError
*
error
=
NULL
;
const
gchar
*
name
=
G_OBJECT_TYPE_NAME
(
c
);
gf_server_connection_listen
(
c
,
&
error
);
if
(
error
)
{
gf_log_warning
(
"Guifications-Daemon"
,
"Failed to listen on connection %s: %s
\n
"
,
name
,
(
error
->
message
)
?
error
->
message
:
"Uknown error"
);
g_error_free
(
error
);
}
else
{
gf_log_info
(
"Guifications-Daemon"
,
"Listening on connection %s
\n
"
,
name
);
}
}
static
void
gfd_connections_disconnect_helper
(
gpointer
k
,
gpointer
v
,
gpointer
d
)
{
GfConnection
*
c
=
GF_CONNECTION
(
v
);
GError
*
error
=
NULL
;
const
gchar
*
name
=
G_OBJECT_TYPE_NAME
(
c
);
gf_connection_disconnect
(
c
,
&
error
);
if
(
error
)
{
gf_log_warning
(
"Guifications-Daemon"
,
"Failed to disconnection connection %s: %s
\n
"
,
name
,
(
error
->
message
)
?
error
->
message
:
"Unknown error"
);
g_error_free
(
error
);
}
else
{
gf_log_info
(
"Guifications-Daemon"
,
"Disconnected connection %s
\n
"
,
name
);
}
}
/******************************************************************************
* API
*****************************************************************************/
void
gfd_connections_init
(
GfFeedManager
*
fp
,
GfPreferenceEngine
*
e
)
{
const
gchar
*
name
=
NULL
;
g_return_if_fail
(
!
connections
);
/* register the local client connection since we don't instantiate it */
gfd_local_client_connection_get_gtype
();
connections
=
g_hash_table_new_full
(
g_str_hash
,
g_str_equal
,
g_free
,
g_object_unref
);
feed_manager
=
g_object_ref
(
G_OBJECT
(
fp
));
engine
=
g_object_ref
(
G_OBJECT
(
e
));
/* create and manual insert our local server connection */
local_server
=
g_object_new
(
gfd_local_server_connection_get_gtype
(),
"feed-manager"
,
feed_manager
,
"pref-engine"
,
engine
,
NULL
);
name
=
gf_named_object_get_name
(
local_server
);
g_hash_table_insert
(
connections
,
g_strdup
(
name
),
local_server
);
/* now look for any other connections which are plugins */
gfd_connections_refresh
();
/* set the default client connection */
gf_connection_manager_set_default
(
gfd_local_client_connection_get_gtype
());
}
void
gfd_connections_uninit
(
void
)
{
g_hash_table_destroy
(
connections
);
g_object_unref
(
G_OBJECT
(
feed_manager
));
g_object_unref
(
G_OBJECT
(
engine
));
}
void
gfd_connections_refresh
(
void
)
{
GType
*
cons
=
NULL
;
guint
n
=
0
,
i
=
0
;
g_return_if_fail
(
connections
!=
NULL
);
cons
=
gf_type_concrete_children
(
GF_TYPE_SERVER_CONNECTION
,
&
n
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
GfConnection
*
server
=
NULL
;
GfNamedObjectClass
*
named_class
=
NULL
;
const
gchar
*
name
=
NULL
;
named_class
=
g_type_class_ref
(
cons
[
i
]);
name
=
gf_named_object_class_get_name
(
named_class
);
/* we can't unref the class yet since it could invalidate the name */
server
=
g_hash_table_lookup
(
connections
,
name
);
if
(
server
)
{
g_type_class_unref
(
named_class
);
continue
;
}
server
=
g_object_new
(
cons
[
i
],
"feed-manager"
,
feed_manager
,
"pref-engine"
,
engine
,
NULL
);
g_hash_table_insert
(
connections
,
g_strdup
(
name
),
server
);
gf_log_info
(
"Guifications-Daemon"
,
"adding connection %s to our connections.
\n
"
,
name
);
g_type_class_unref
(
named_class
);
}
g_free
(
cons
);
}
void
gfd_connections_listen
(
void
)
{
g_hash_table_foreach
(
connections
,
gfd_connections_listen_helper
,
NULL
);
}
void
gfd_connections_close
(
void
)
{
g_hash_table_foreach
(
connections
,
gfd_connections_disconnect_helper
,
NULL
);
}
void
gfd_connections_debug
(
void
)
{
g_hash_table_foreach
(
connections
,
gfd_connections_debug_helper
,
NULL
);
}