File: DEVELOPER

package info (click to toggle)
irmp3 0.4.3pre6-2
  • links: PTS
  • area: main
  • in suites: woody
  • size: 584 kB
  • ctags: 374
  • sloc: ansic: 3,955; makefile: 212; pascal: 39
file content (187 lines) | stat: -rw-r--r-- 6,249 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187

This file describes the coding style and gives some useful informations
for developer who want to add their own module.

 --------------------------------------------------------
 - please send code submissions to dp-irmp3@dpotter.com -
 --------------------------------------------------------


CODING STYLE
------------

	The main IRMP3 program can use functions of several modules.
	Modules may be included or excluded at build time to have
	or haven't support for different hardware. Every modules
	is named mod_xxx.c / mod_xxx.h. Modules that are excluded
	during build time (Makefile configuration), will not be
	compiled.
	All functions and global variables within a module should
	be called mod_xxx_*, to prevent conflicts with oder modules
	or the main program.
	Every module must have an init function, which is of type:
	char *mod_xxx_init(void);
	The init function is called right after starting irmp3,
	after reading the configuration and setting up some other
	basic things. It should return NULL if it succeeded, and
	return an error string on failure.
	To get a clue on how a module works, have a look at
	mod_debug.c, which is good to learn the basic things.


INCLUDING A NEW MODULE
----------------------

	To describe how to write and include a new module, I'll
	give an examples on a module called mod_mymod:

	1) Set up the Makefile to include the new module. You
	   should add a section to the configuration part of
	   the Makefile. Include something like:
		MOD_MYMOD = 1
		MOD_MYMOD_BLAH = youneedtoconfigurethis

	2) Include your changes to the target configuration
	   section of the Makefile:
		ifdef MOD_MYMOD
			OBJS += mod_mymod.o
			MODS += -DMOD_MYMOD
		endif

	3) Include your changes to the target section of the
	   Makefile:
		mod_mymod.o:	mod_mymod.c
				$(CC) $(CFLAGS) -DMOD_MYMOD_BLAH=\"$(MOD_MYMOD_BLAH)\" -c mod_mymod.c -o mod_mymod.o

	4) Setup modules.inc to include your module init function.
	   You need to specify the module init function prototype:
		char *mod_mymod_init(void);
	   and include it in the list of module init functions in
	   mod_list_init[] like this:
		#ifdef MOD_MYMOD
			mod_mymod_init,
		#endif

	5) Now your mod_mymod_init() function is called every time
	   IRMP3 starts. Your init function should now fill up a
	   mod_t structure and pass it to mod_register, so that
	   your module is registered within IRMP3 and the main
	   program knows what data your module wants to handle.
	   You should take care that the structure is still valid
	   if your init function is left, so don't use a local
	   variable!
	   The structure contains the following fields:

		mod_deinitfunc_t deinit;
			Set this to a function (usually
			void mod_mymod_deinit (void)) that will
			be called before IRMP3 shuts down. This
			function typically cleans up all used data
			structures, closes connections etc.

		mod_reloadfunc_t reload;
			This function will be called whenever
			IRMP3 needs to reload all configs (usually
			when receiving a SIGHUP). You should
			do whatever is neccessary here to make
			the changes take effect.

		fd_set watchfd;
			A set of file descriptors that your module
			will want to read/write from/to.  Your module
			may dynamically add or remove fd's from
			this set.

		mod_pollfunc_t poll(int fd);
			This function will be called if incoming
			data was detected on any of the file descriptors
			in watchfd. The descriptor with input is passed as
			fd.  This function should read the data, otherwise 
			it will be called again and again and again,
			and probably lock up the whole program.

		mod_updatefunc_t update;
			This function will be called periodically about
			twice a second. If you need to do any periodically
			work, this is the right place to do it.

		mod_messagefunc_t message;
			Every module can send a message through the
			message passing system. If you want to react
			to messages of other modules, you need to
			set a function here and you'll receive all
			messages.

		mod_sigchldfunc_t chld(pid_t pid, int status);
			If your module spawns child processes, you
			may want to be notified when they die.  If
			so, register a function here:  Please 
			*don't* use signal(SIGCHLD,func), or you 
			will be stealing SIGCHLDs from other
			modules.

	Again, if you don't understand everything, look at mod_debug.c,
	which is a basic custom module and may be also used as a
	template for new ones.


CALLING FUNCTIONS
-----------------

	Of course your module may use some of the main programs functions:

	* Modules
		#include "mod.h"
		void mod_register (mod_t *newmod);
		void mod_sendmsg (int msgtype, char *message);

		mod_register is used to register your module (see above).
		With mod_sendmsg() you can send a message to other modules.
		The msgtype should reflect the type of the message. See
		mod.h for different message types.

	* Tools
		#include "tools.h"

		Some useful functions may be found here. Check tools.h.

	* Logging
		#include "log.h"
		log_printf(log-level, "text like printf: %s %d", str, num);

		Writes a line to the logfile. See log.h about log-levels.

	* Configuration
		#include "config.h"
		char *value = config_getstr(key, defaultvalue);
		int value = config_getnum(key, defaultvalue);

		Reads a value of a configuration key which is defined in the
		IRMP3 config file. You should name all your keys "mymod_xxx",
		so that it's clear where they belong to.


PUBLISHING
----------

	If you have developed a new module and it works fine, you probably
	want to publish it so that others can use it, too.

	First of all you should make sure, that your code meets all the above
	requirements. It should be programmed cleanly and easy to read (you
	didn't forget comments, did you?). You should also take care that
	the whole program also still works without your module. Also don't
	forget to make things customizable, a program that does use hardcoded
	paths (like /mnt/cdrom) won't be useful for others.

	So if your code does meet all these things, you simply have to contact
	me via mail or via the mailinglist (see README) and tell me about it.


STANDARD MODULES
----------------

	TODO: describe what the standard modules do and how they interact via
	      the message system.