3
3
* Author: Brent Hendricks
4
4
* Project: GGZ Core Client Lib
6
* $Id: module.c,v 1.24 2002/11/05 10:18:41 jdorje Exp $
6
* $Id: module.c 7889 2006-03-07 09:57:32Z josef $
8
8
* This fils contains functions for handling client-side game modules
10
10
* Copyright (C) 2000 Brent Hendricks.
12
* This program is free software; you can redistribute it and/or modify
13
* it under the terms of the GNU General Public License as published by
14
* the Free Software Foundation; either version 2 of the License, or
15
* (at your option) any later version.
17
* This program is distributed in the hope that it will be useful,
12
* This library is free software; you can redistribute it and/or
13
* modify it under the terms of the GNU Lesser General Public
14
* License as published by the Free Software Foundation; either
15
* version 2.1 of the License, or (at your option) any later version.
17
* This library is distributed in the hope that it will be useful,
18
18
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
* GNU General Public License for more details.
22
* You should have received a copy of the GNU General Public License
23
* along with this program; if not, write to the Free Software
24
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20
* Lesser General Public License for more details.
22
* You should have received a copy of the GNU Lesser General Public
23
* License along with this library; if not, write to the Free Software
24
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27
27
#ifdef HAVE_CONFIG_H
28
# include <config.h> /* Site-specific config */
28
# include <config.h> /* Site-specific config */
31
31
#include <stdlib.h>
39
39
#define GGZ_MOD_RC "ggz.modules"
42
/* Structure describing particular client-side game module */
48
/* Game module version */
51
/* Protocol engine implemented */
52
const char *prot_engine;
54
/* Protocol version implemented */
55
const char *prot_version;
66
/* Hopepage for this module */
69
/* Commandline for executing module */
72
/* Path to icon for this game module */
75
/* Path to help file */
78
/* Preferred runtime environment */
79
GGZModuleEnvironment environment;
42
82
/* List of modules */
43
83
static GGZList *module_list;
44
84
static unsigned int num_modules;
45
85
static int mod_handle = -1;
86
static int embedded_module = 0;
47
88
/* static internal functions */
48
static struct _GGZModule* _ggzcore_module_new(void);
89
static GGZModule *_ggzcore_module_new(void);
50
static void _ggzcore_module_init(struct _GGZModule *module,
91
static void _ggzcore_module_init(GGZModule * module,
52
93
const char *version,
53
94
const char *prot_engine,
59
100
const char *icon_path,
60
101
const char *help_path);
61
102
#endif /* #if 0 */
62
static void _ggzcore_module_free(struct _GGZModule *module);
63
static void _ggzcore_module_read(struct _GGZModule *mod, char *id);
64
static int _ggzcore_module_add(struct _GGZModule *module);
103
static void _ggzcore_module_free(GGZModule * module);
104
static void _ggzcore_module_read(GGZModule * mod, char *id);
105
static int _ggzcore_module_add(GGZModule * module);
66
static char* _ggzcore_module_conf_filename(void);
67
static void _ggzcore_module_print(struct _GGZModule*);
107
static char *_ggzcore_module_conf_filename(void);
108
static void _ggzcore_module_print(const GGZModule *);
68
109
static void _ggzcore_module_list_print(void);
69
110
/* Utility functions used by ggz_list */
70
111
static void _ggz_free_chars(char **argv);
71
static int _ggzcore_module_compare(void *p, void *q);
112
static int _ggzcore_module_compare(const void *p, const void *q);
73
static void* _ggzcore_module_create(void* p);
114
static void *_ggzcore_module_create(void *p);
74
115
#endif /* #if 0 */
75
static void _ggzcore_module_destroy(void* p);
116
static void _ggzcore_module_destroy(void *p);
78
119
/* Publicly exported functions */
115
155
/* This adds a local module to the list. It returns 0 if successful or
116
156
-1 on failure. */
117
157
int ggzcore_module_add(const char *name,
119
const char *prot_engine,
120
const char *prot_version,
159
const char *prot_engine,
160
const char *prot_version,
122
162
const char *frontend,
124
164
const char *exe_path,
125
165
const char *icon_path,
126
const char *help_path)
166
const char *help_path,
167
GGZModuleEnvironment environment)
132
/* This attempts to launch the specified module and returns 0 is
133
successful or -1 on error. */
134
int ggzcore_module_launch(GGZModule *module)
139
return _ggzcore_module_launch(module);
143
173
/* These functions lookup a particular property of a module. I've added
144
174
icon to the list we discussed at the meeting. This is an optional xpm
145
175
file that the module can provide to use for representing the game
147
const char * ggzcore_module_get_name(GGZModule *module)
177
const char *ggzcore_module_get_name(GGZModule * module)
267
306
mod_handle = ggz_conf_parse(file, GGZ_CONF_RDONLY);
268
307
/* Free up space taken by name */
271
310
if (mod_handle == -1) {
272
311
ggz_debug(GGZCORE_DBG_MODULE,
273
312
"Unable to load module conffile");
277
316
/* Read in list of supported gametypes */
278
status = ggz_conf_read_list(mod_handle, "Games", "*Engines*",
317
status = ggz_conf_read_list(mod_handle, "Games", "*Engines*",
279
318
&count_types, &games);
280
319
if (status < 0) {
281
320
ggz_debug(GGZCORE_DBG_MODULE, "Couldn't read engine list");
284
323
ggz_debug(GGZCORE_DBG_MODULE,
285
324
"%d game engines supported", count_types);
287
326
for (i = 0; i < count_types; i++) {
288
status = ggz_conf_read_list(mod_handle, "Games", games[i],
327
status = ggz_conf_read_list(mod_handle, "Games", games[i],
289
328
&count_modules, &ids);
292
331
ggz_debug(GGZCORE_DBG_MODULE,
293
332
"%d modules for %s", count_modules, games[i]);
360
void _ggzcore_module_set_embedded(void)
366
int _ggzcore_module_is_embedded(void)
368
return embedded_module;
321
372
/* FIXME: do this right. We should parse through module_list not
322
373
re-read the config file */
323
int _ggzcore_module_get_num_by_type(const char *game,
374
int _ggzcore_module_get_num_by_type(const char *game,
324
375
const char *engine,
325
376
const char *version)
327
378
int count, status, i, numcount;
329
struct _GGZModule module;
331
382
/* Get total count for this engine (regardless of version) */
332
status = ggz_conf_read_list(mod_handle, "Games", engine, &count, &ids);
384
ggz_conf_read_list(mod_handle, "Games", engine, &count, &ids);
337
389
numcount = count;
338
390
for (i = 0; i < count; i++) {
339
391
_ggzcore_module_read(&module, ids[i]);
340
392
/* Subtract out modules that aren't the same protocol */
341
if (strcmp(engine, module.prot_engine) != 0
342
|| (version && strcmp(version, module.prot_version) != 0)
343
/* || game not included in game list */)
393
if (ggz_strcmp(engine, module.prot_engine) != 0
395
&& ggz_strcmp(version, module.prot_version) != 0)
396
/* || game not included in game list */
354
408
/* FIXME: do this right. We should parse through module_list not
355
409
re-read the config file */
356
struct _GGZModule* _ggzcore_module_get_nth_by_type(const char *game,
359
const unsigned int num)
410
GGZModule *_ggzcore_module_get_nth_by_type(const char *game,
413
const unsigned int num)
361
415
int i, total, status, count;
363
struct _GGZModule *module, *found = NULL;
417
GGZModule *module, *found = NULL;
364
418
GGZListEntry *entry;
366
status = ggz_conf_read_list(mod_handle, "Games", engine, &total, &ids);
368
ggz_debug(GGZCORE_DBG_MODULE, "Found %d modules matching %s", total,
421
ggz_conf_read_list(mod_handle, "Games", engine, &total, &ids);
423
ggz_debug(GGZCORE_DBG_MODULE, "Found %d modules matching %s",
380
435
for (i = 0; i < total; i++) {
381
436
module = _ggzcore_module_new();
382
437
_ggzcore_module_read(module, ids[i]);
383
if (strcmp(version, module->prot_version) == 0) {
438
if (ggz_strcmp(version, module->prot_version) == 0) {
384
439
/* FIXME: also check to see if 'game' is in supported list */
385
440
if (count++ == num) {
386
441
/* Now find same module in list */
387
entry = ggz_list_search(module_list, module);
443
ggz_list_search(module_list, module);
388
444
found = ggz_list_get_data(entry);
389
445
_ggzcore_module_free(module);
396
452
/* Free the rest of the ggz_conf memory */
397
453
_ggz_free_chars(ids);
400
456
/* Return found module (if any) */
405
const char* _ggzcore_module_get_name(struct _GGZModule *module)
461
const char *_ggzcore_module_get_name(const GGZModule * module)
407
463
return module->name;
411
const char* _ggzcore_module_get_version(struct _GGZModule *module)
467
const char *_ggzcore_module_get_version(const GGZModule * module)
413
469
return module->version;
417
const char* _ggzcore_module_get_prot_engine(struct _GGZModule *module)
473
const char *_ggzcore_module_get_prot_engine(const GGZModule * module)
419
475
return module->prot_engine;
423
const char* _ggzcore_module_get_prot_version(struct _GGZModule *module)
479
const char *_ggzcore_module_get_prot_version(const GGZModule * module)
425
481
return module->prot_version;
429
const char* _ggzcore_module_get_author(struct _GGZModule *module)
485
const char *_ggzcore_module_get_author(const GGZModule * module)
431
487
return module->author;
435
const char* _ggzcore_module_get_frontend(struct _GGZModule *module)
491
const char *_ggzcore_module_get_frontend(const GGZModule * module)
437
493
return module->frontend;
441
const char* _ggzcore_module_get_url(struct _GGZModule *module)
497
const char *_ggzcore_module_get_url(const GGZModule * module)
443
499
return module->url;
447
const char* _ggzcore_module_get_icon_path(struct _GGZModule *module)
503
const char *_ggzcore_module_get_icon_path(const GGZModule * module)
449
505
return module->icon;
453
const char* _ggzcore_module_get_help_path(struct _GGZModule *module)
509
const char *_ggzcore_module_get_help_path(const GGZModule * module)
455
511
return module->help;
459
char** _ggzcore_module_get_argv(struct _GGZModule *module)
515
char **_ggzcore_module_get_argv(const GGZModule * module)
461
517
return module->argv;
465
int _ggzcore_module_launch(struct _GGZModule *module)
521
GGZModuleEnvironment _ggzcore_module_get_environment(const GGZModule *
467
ggz_debug(GGZCORE_DBG_MODULE, "Launching module: ");
468
_ggzcore_module_print(module);
524
return module->environment;
579
static void _ggzcore_module_read(struct _GGZModule *mod, char *id)
635
static void _ggzcore_module_read(GGZModule * mod, char *id)
582
639
/* FIXME: check for errors on all of these */
584
641
/* Note: the memory allocated here is freed in _ggzcore_module_free */
585
642
mod->name = ggz_conf_read_string(mod_handle, id, "Name", NULL);
586
mod->version = ggz_conf_read_string(mod_handle, id, "Version", NULL);
587
mod->prot_engine = ggz_conf_read_string(mod_handle, id,
588
"ProtocolEngine", NULL);
589
mod->prot_version = ggz_conf_read_string(mod_handle, id,
590
"ProtocolVersion", NULL);
591
ggz_conf_read_list(mod_handle, id, "SupportedGames", &argc,
644
ggz_conf_read_string(mod_handle, id, "Version", NULL);
646
ggz_conf_read_string(mod_handle, id, "ProtocolEngine", NULL);
648
ggz_conf_read_string(mod_handle, id, "ProtocolVersion", NULL);
649
ggz_conf_read_list(mod_handle, id, "SupportedGames", &argc,
593
651
mod->author = ggz_conf_read_string(mod_handle, id, "Author", NULL);
594
mod->frontend = ggz_conf_read_string(mod_handle, id, "Frontend", NULL);
653
ggz_conf_read_string(mod_handle, id, "Frontend", NULL);
595
654
mod->url = ggz_conf_read_string(mod_handle, id, "Homepage", NULL);
596
ggz_conf_read_list(mod_handle, id, "CommandLine", &argc, &mod->argv);
655
ggz_conf_read_list(mod_handle, id, "CommandLine", &argc,
597
657
mod->icon = ggz_conf_read_string(mod_handle, id, "IconPath", NULL);
598
mod->help = ggz_conf_read_string(mod_handle, id, "HelpPath", NULL);
658
mod->help = ggz_conf_read_string(mod_handle, id, "HelpPath", NULL);
661
ggz_conf_read_string(mod_handle, id, "Environment", NULL);
663
mod->environment = GGZ_ENVIRONMENT_XWINDOW;
664
else if (!ggz_strcmp(environment, "xwindow"))
665
mod->environment = GGZ_ENVIRONMENT_XWINDOW;
666
else if (!ggz_strcmp(environment, "xfullscreen"))
667
mod->environment = GGZ_ENVIRONMENT_XFULLSCREEN;
668
else if (!ggz_strcmp(environment, "passive"))
669
mod->environment = GGZ_ENVIRONMENT_PASSIVE;
670
else if (!ggz_strcmp(environment, "console"))
671
mod->environment = GGZ_ENVIRONMENT_CONSOLE;
673
mod->environment = GGZ_ENVIRONMENT_XWINDOW;
675
ggz_free(environment);
602
static void _ggzcore_module_print(struct _GGZModule *module)
679
static void _ggzcore_module_print(const GGZModule * module)
606
683
ggz_debug(GGZCORE_DBG_MODULE, "Name: %s", module->name);
607
684
ggz_debug(GGZCORE_DBG_MODULE, "Version: %s", module->version);
608
ggz_debug(GGZCORE_DBG_MODULE, "ProtocolEngine: %s", module->prot_engine);
685
ggz_debug(GGZCORE_DBG_MODULE, "ProtocolEngine: %s",
686
module->prot_engine);
609
687
ggz_debug(GGZCORE_DBG_MODULE, "ProtocolVersion: %s",
610
688
module->prot_version);
611
689
if (module->games)
612
690
while (module->games[i]) {
613
ggz_debug(GGZCORE_DBG_MODULE, "Game[%d]: %s", i,
691
ggz_debug(GGZCORE_DBG_MODULE, "Game[%d]: %s", i,
614
692
module->games[i]);
642
721
static void _ggz_free_chars(char **argv)
646
725
for (i = 0; argv[i]; i++)
647
726
ggz_free(argv[i]);
653
732
/* Match game module by 'name', 'prot_engine', 'prot_version' */
654
static int _ggzcore_module_compare(void *p, void *q)
733
static int _ggzcore_module_compare(const void *p, const void *q)
658
struct _GGZModule *pmod = (struct _GGZModule*)p;
659
struct _GGZModule *qmod = (struct _GGZModule*)q;
661
compare = strcmp(pmod->name, qmod->name);
662
if (compare != 0) return compare;
664
compare = strcmp(pmod->prot_engine, qmod->prot_engine);
665
if (compare != 0) return compare;
667
compare = strcmp(pmod->prot_version, qmod->prot_version);
668
if (compare != 0) return compare;
670
compare = strcmp(pmod->frontend, qmod->frontend);
736
const GGZModule *pmod = p, *qmod = q;
738
compare = ggz_strcmp(pmod->name, qmod->name);
742
compare = ggz_strcmp(pmod->prot_engine, qmod->prot_engine);
746
compare = ggz_strcmp(pmod->prot_version, qmod->prot_version);
750
compare = ggz_strcmp(pmod->frontend, qmod->frontend);
676
static void* _ggzcore_module_create(void* p)
756
static void *_ggzcore_module_create(void *p)
678
struct _GGZModule *new, *src = p;
758
GGZModule *new, *src = p;
680
760
new = _ggzcore_module_new();
682
_ggzcore_module_init(new, src->name, src->version,
762
_ggzcore_module_init(new, src->name, src->version,
683
763
src->prot_engine, src->prot_version,
684
src->author, src->frontend, src->url,
764
src->author, src->frontend, src->url,
685
765
src->argv[0], src->icon, src->help);
690
770
#endif /* #if 0 */
692
static void _ggzcore_module_destroy(void* p)
772
static void _ggzcore_module_destroy(void *p)
694
774
/* Quick sanity check */