Merge branch '4647_indicator_click_sort_reverse'
[midnight-commander.git] / doc / HACKING
blobdfd4ad9f1423b98cf7afc976e96c3a4b5e4b6214
1 This document
2 =============
4 This document is a guide how to develop GNU Midnight Commander.  It's
5 quite incomplete, but may be worth reading anyway.
7 The document was written by Miguel de Icaza and reworked by Pavel
8 Roskin and later from Patrick Winnertz.
9  Some parts were taken from the messages posted in the mailing
10 lists.
13 Compiling from GIT
14 ==================
16 The full list of requirements is listed in the INSTALL file.
18 It is recommended that all those tools are installed with the same
19 prefix.  Make sure that the tools with the right version are first in
20 PATH.
22 Once you have the right tools, run `autogen.sh' - it will generate
23 everything necessary for the build `configure'. Then run 'configure'
24 and `make' as usually.
26 The distribution tarball is created by the command `make distcheck'. 
27 This command can take a while.
29 Note that the version of gettext doesn't affect the snapshot because the
30 distributed files are installed by gettext from archives for the version
31 used in the AM_GNU_GETTEXT_VERSION macro, which is 0.18.2.
35 Working with GNU Midnight Commander
36 ===================================
38 Please use the GIT version.  It may be quite different from the released
39 versions.  A lot of cleanup is going on.  The GIT version may be easier
40 to understand, in addition to the obvious fact that the merging is
41 easier with the GIT version.
43 In order to compile GNU Midnight Commander from a clean GIT checkout you
44 should use 'autogen.sh && ./configure' instead of 'configure'.
46 GNU Midnight Commander uses Autoconf and Automake, with make it fairly
47 portable.  However, GNU Make is strongly recommended for development
48 because other versions of make may not track dependencies properly. 
49 This is very important for correct compilation, especially if you change
50 any header files.
52 If you add or remove any files, please change Makefile.am in the same
53 directory accordingly.  When doing significant changes in the tree
54 structure, "make distcheck" is strongly recommended.
56 GNU Autoconf allows you to test several different configurations are
57 once.  To do so, use the so called out-of-tree (or VPATH) compilation. 
58 Create separate empty directories and run configure with full path from
59 those directories, like this:
61 cd /usr/local/src
62 mkdir mc-slang
63 mkdir mc-ncurses
64 cd mc-slang
65 /usr/local/src/mc/configure && make all
66 cd ../mc-ncurses
67 /usr/local/src/mc/configure --with-screen=ncurses && make all
69 Please use the same indentation as other developers.  To indent a block,
70 select in the internal editor and use Shift-F9 to call the external
71 indent.  For historic reasons, GNU Midnight Commander used formatting
72 that is not default for GNU Indent.  Please put following text to your
73 ~/.indent.pro file to make GNU Indent follow the style used in GNU
74 Midnight Commander:
76 --gnu-style
77 --format-first-column-comments
78 --indent-level4
79 --brace-indent0
80 --line-length100
81 --no-tabs
82 --blank-lines-after-procedures
84 or in short notation:
86 indent -gnu -fc1 -i4 -bli0 -nut -bap -l100
88 It's OK to indent the whole function if you edit it.  However, please
89 refrain from it if you are posting your patch for review.  In this case
90 you would save time of other developers if you only include significant
91 changes.  The developer applying your patch can format the code for you.
93 Please keep in mind that the VFS subsystem is licensed under LGPL, while
94 the rest of the code uses GPL.
97 Code structure - outline
98 ========================
100 The code is located in following directories.
102 vfs - Virtual File System.
104 This library provides filesystem-like access to various data, such are
105 archives and remote filesystems.  To use VFS, you should use wrappers
106 around POSIX calls.  The wrappers have names composed from "mc_" and the
107 standard name of the function.  For example, to open a file on VFS, use
108 mc_open() instead.
110 edit - the internal editor.
112 This code has been contributed by Paul Sheer, the author of Cooledit.
113 The internal editor shares some code with Cooledit, but now it's
114 developed as part of GNU Midnight Commander.
116 src - the main part of the code.
118 This code includes the dialog manager written by Radek Doulik and source
119 code of the main application.
121 Code structure - details
122 ========================
124 GNU Midnight Commander uses extensively the dialog manager written by
125 Radek Doulik.  To understand how the dialog manager works, please read
126 the dialog.c.  You will find the basic widgets in the files widget.c.
127 Some more high-level functions, e.g. to display a message box, are
128 located in wtools.c.  This file also contains the Quick Dialog code,
129 which makes it easier to create complex dialogs.
131 The files util.c and utilunix.c have a lot of utility functions.  Get
132 familiar with them, they are very simple.
134 glib is used for memory allocation and for some utility functions, such
135 as manipulation with lists and trees.  gmodule (part of the glib
136 distribution) is used to load some libraries dynamically at the run
137 time.
139 Thanks to glib, the code has almost no hardcoded limits, since there are
140 many ways to avoid them.  For example, when you want to concatenate
141 strings, use the g_strconcat() function:
143         new_text = g_strconcat (username, " ", password, (char *)0);
145 This allocates new memory for the string, so you should use g_free() on
146 the result.
148 The parent of all dialogs is called midnight_dlg.  Both panels are
149 widgets in that dialog.  Other widgets include the menu, the command
150 line and the button bar.
153 Input handling
154 ==============
156 The routines for input handling on the Midnight Commander are:
157 getch, get_key_code, mi_getch and get_event.
159 getch is an interface to the low level system input mechanism.  It
160 does not deal with the mouse.  
162     In the case of ncurses, this is a function implemented in the
163     ncurses library that translates key sequences to key codes (\E[A to
164     something like KEY_UP and so on).
166     In the case of S-Lang there is no such conversion, that's why we
167     load a set of extra definitions.
169 The get_key_code routine converts the data from getch to the
170 constants the Midnight Commander uses.
172     In the case of S-Lang, it will actually do all the jobs that getch
173     does for curses.  In the case of curses it patches a couple of
174     sequences that are not available on some terminal databases.  This
175     routine is the one you want to use if you want a character without
176     the mouse support.
178 get_event is the routine you want to use if you want to handle mouse
179 events, it will return 0 on a mouse event, -1 if no input is available
180 or a key code if there is some input available.  This routine in turn
181 uses get_key_code to decode the input stream and convert it to useful
182 constants.
184 mi_getch is just a wrapper around get_event that ignores all the mouse
185 events.  It's used only in a couple of places, this routine may return
186 -1 if no input is available (if you have set the nodelay option of
187 ncurses or S-Lang with nodelay) or a character code if no such option is
188 available. 
191 Mouse support
192 =============
194 The mouse support in the Midnight Commander is based on the get_event
195 routine.  The core of the mouse event dispatching is in the
196 dlg.c:run_dlg routine.
199 ncurses
200 =======
202 Although S-Lang is now used by default, we still support ncurses.  We
203 basically are using a small subset of ncurses because we want to be
204 compatible with Slang.
207 The Dialog manager and the Widgets
208 ==================================
210 The Dialog manager and the Widget structure are implemented in
211 src/dialog.c.  Everything shown on screen is a dialog.  Dialogs contain
212 widgets, but not everything on screen is a widget.  Dialogs can draw
213 themselves.
215 Dialogs are connected into a singly linked list using "parent" field. 
216 Currently active dialog is saved in current_dlg variable.  The toplevel
217 dialog has parent NULL.  Usually it's midnight_dlg.
219             parent                  parent
220 current_dlg ------->another dialog-- ... -->midnight_dlg
222 When the screen needs to be refreshed, every dialog asks its parent to
223 refresh first, and then refreshes itself.
225 A dialog is created by create_dlg().  Then it's populated by widgets
226 using add_widget().  Then the dialog is run by calling run_dlg(), which
227 returns the id of the button selected by the user.  Finally, the dialog
228 is destroyed by calling destroy_dlg().
230 Widgets are placed to a doubly linked circular list.  Each widget has
231 previous and next widget.
233         prev   next         prev   next
234 widget1 <---------> widget2 <---------> widget3
235    ^                                       ^
236    -----------------------------------------
237    next                                 prev
239 Pressing Tab moves focus to the "next" widget, pressing Shift-Tab moves
240 focus to "prev".  The tab order is equal to the add order except some
241 old code that use the reverse order by setting DLG_REVERSE flag in
242 create_dlg() call.  Please don't use reverse order in the new code.
244 The initial widget to get focus can be selected by calling
245 dlg_select_widget().
247 When creating a dialog, you may want to use a callback that would
248 intercept some dialog events.  However, many widgets will do the right
249 thing by default, so some dialogs can work just fine without callbacks.
251 There are also widget events, which are sent by the dialog to individual
252 widgets.  Some widgets also have user callbacks.
254 To create your own widget, use init_widget().  In this case, you must
255 provide a callback function.  Please note that it's not the same as the
256 user callback in some widgets.
259 Where to Find Bug Reports and Patches
260 =====================================
262 The official place for bug reports is:
264     https://www.midnight-commander.org
267 There are various unofficial sources where bug reports and patches can
268 be found (NOT maintained by the MC team).
271 https://tracker.debian.org/pkg/mc
272 https://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg=mc
273         The bug tracking system for Debian, a package collection mainly
274         for GNU/Linux and the Hurd.
276 https://bugzilla.redhat.com/bugzilla/buglist.cgi?component=mc
277 https://src.fedoraproject.org/rpms/mc
278         Bugs reported in Redhat Linux.
280 https://gitweb.gentoo.org/repo/gentoo.git/tree/app-misc/mc/files
281         The patches that are applied for the Gentoo Linux version of MC.
283 https://cgit.freebsd.org/ports/tree/misc/mc/files
284         The patches that are applied for the FreeBSD version of MC.
286 https://cvsweb.openbsd.org/ports/misc/mc/patches/
287         The patches that are applied for the OpenBSD version of MC.
289 http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/sysutils/mc/patches/
290         The patches that are applied for the NetBSD version of MC.
294 Programming Tips
295 ================
297 (This list should be sorted alphabetically.)
299 ?: This operator has a precedence that is easy to use the wrong way. You
300         might think that
302                 int right = 25 + have_frame() ? 1 : 0; /* WRONG */
304         results in either 25 or 26. This is not the case. The C compiler
305         sees this as:
307                 int right = (25 + have_frame()) ? 1 : 0; /* WRONG */
309         To avoid this, put the ?: in parentheses, like this
311                 int right = 25 + (have_frame() ? 1 : 0); /* RIGHT */
313         If the condition is more complicated, put it in additional
314         parentheses:
316                 int right = 25 + ((have_frame()) ? 1 : 0); /* RIGHT */
318 const: For every function taking a string argument, decide whether you
319         (as a user of the function) would expect that the string is modi-
320         fied by the function. If not, declare the string argument as
321         "const char *". If your implementation needs to modify the string,
322         use g_strdup to create a local copy.
324 const_cast: Has been replaced by str_unconst.
326 g_free: g_free handles NULL argument too, no need for the comparison.
327         Bad way:
328             if (old_dir) g_free (old_dir);
329         Right way:
330             g_free (old_dir);
332 g_strdup: When you use g_strdup to create a local copy of a string, use
333         the following pattern to keep the reference.
335         char * const pathref = g_strdup(argument);
336         /* ... */
337         g_free (pathref);
339         The "const" will make the pointer unmodifiable (pathref++
340         is not possible), but you can still modify the string contents.
342 NULL: When you pass NULL as an argument of a varargs function, cast the
343         0 to the appropriate data type. If a system #defines NULL to
344         be 0 (at least NetBSD and OpenBSD do), and the sizes of int and
345         a pointer are different, the argument will be passed as int 0,
346         not as a pointer.
348         This tip applies at least to catstrs (edit/edit.h), execl(3),
349         execle(3), execlp(3), g_strconcat (glib), parent_call
350         (src/background.h), parent_call_string (src/background.h).
352         example:
353         char *path = g_strconcat("dir", "/", "file", (char *)0);
355 size_t: This data type is suitable for expressing sizes of memory or the
356         length of strings. This type is unsigned, so you need not check
357         if the value is >= 0.
359 strncpy: Don't use this function in newly created code. It is slow, insecure
360         and hard to use. A much better alternative is g_strlcpy (see there).
362 str_unconst: We use many libraries that do not know about "const char *"
363         and thus declare their functions to require "char *". If you
364         know for sure that an external function does not modify the
365         string, you can "unconst" a string using the function
366         str_unconst(). If you are not sure whether the function modifies
367         the string, you should use g_strdup() to pass a copy of a string
368         to the function. Don't forget to call g_free() after work is done.
370 unused: Unused arguments of a function can be marked like this:
372         void do_nothing(int data)
373         {
374             (void) &data;
375         }
377         This tells the GNU C Compiler not to emit a warning, and has no
378         side effects for other compilers.