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. Some parts were taken from the messages posted in the mailing
15 To compile GNU Midnight commander from CVS, the following software is
18 Autoconf 2.52 and above (latest is recommended)
19 Automake 1.5 and above (latest is recommended)
20 Gettext 0.11.5 and above
21 Glib 1.2.6 and above (2.x is recommended)
23 It is recommended that all those tools are installed with the same
24 prefix. Make sure that the tools with the right version are first in
27 Once you have the right tools, run `autogen.sh' - it will generate
28 everything necessary for the build and run `configure'. Arguments given
29 to `autogen.sh' are passed to `configure'. Then run `make' as usually.
31 The distribution tarball is created by the command `make distcheck'.
32 This command can take a while.
34 Currently snapshots are made on Debian unstable and use the versions of
35 the tools from the unstable repository. Yes, the rpm packages are made
38 Note that the version of gettext doesn't affect the snapshot because the
39 distributed files are installed by gettext from archives for the version
40 used in the AM_GNU_GETTEXT_VERSION macro, which is 0.11.5.
44 Working with GNU Midnight Commander
45 ===================================
47 Please use the CVS version. It may be quite different from the released
48 versions. A lot of cleanup is going on. The CVS version may be easier
49 to understand, in addition to the obvious fact that the merging is
50 easier with the CVS version.
52 There are some tools in the maint directory on CVS. They are not
53 included with releases or snapshots. You may be interested to look at
54 them if you are going to work on the project for an extended period of
55 time. In particular, the release procedure is described there.
57 In order to compile GNU Midnight Commander from a clean CVS checkout you
58 should use autogen.sh instead of configure. Arguments passed to
59 autogen.sh are passed to configure after it's generated. See README.CVS
60 for details and required software.
62 GNU Midnight Commander uses Autoconf and Automake, with make it fairly
63 portable. However, GNU Make is strongly recommended for development
64 because other versions of make may not track dependencies properly.
65 This is very important for correct compilation, especially if you change
68 If you add or remove any files, please change Makefile.am in the same
69 directory accordingly. When doing significant changes in the tree
70 structure, "make distcheck" is strongly recommended.
72 If you have etags installed, you can run "make tags" and use tags in
73 emacs to find functions or variables. But you can also use the internal
74 editor and the "Find File" command to find any text in the source tree.
76 GNU Autoconf allows you to test several different configurations are
77 once. To do so, use the so called out-of-tree (or VPATH) compilation.
78 Create separate empty directories and run configure with full path from
79 those directories, like this:
85 /usr/local/src/mc/configure && make all
87 /usr/local/src/mc/configure --with-screen=ncurses && make all
89 Please use the same indentation as other developers. To indent a block,
90 select in the internal editor and use Shift-F9 to call the external
91 indent. For historic reasons, GNU Midnight Commander used formatting
92 that is not default for GNU Indent. Please put following text to your
93 ~/.indent.pro file to make GNU Indent follow the style used in GNU
96 -kr -i4 -pcs -psl --ignore-newlines
98 It's OK to indent the whole function if you edit it. However, please
99 refrain from it if you are posting your patch for review. In this case
100 you would save time of other developers if you only include significant
101 changes. The developer applying your patch can format the code for you.
103 Please keep in mind that the VFS subsystem is licensed under LGPL, while
104 the rest of the code uses GPL.
107 Code structure - outline
108 ========================
110 The code is located in following directories.
112 vfs - Virtual File System.
114 This library provides filesystem-like access to various data, such are
115 archives and remote filesystems. To use VFS, you should use wrappers
116 around POSIX calls. The wrappers have names composed from "mc_" and the
117 standard name of the function. For example, to open a file on VFS, use
120 edit - the internal editor.
122 This code has been contributed by Paul Sheer, the author of Cooledit.
123 The internal editor shares some code with Cooledit, but now it's
124 developed as part of GNU Midnight Commander.
126 src - the main part of the code.
128 This code includes the dialog manager written by Radek Doulik and source
129 code of the main application.
131 slang - stripped down S-Lang library.
133 It's provided to allow compilation that don't have the S-Lang library
134 with complete headers or the library is broken. Please avoid changing
135 this code. If you do change it, please consider contributing your
136 changes to the maintainers of S-Lang.
139 Code structure - details
140 ========================
142 GNU Midnight Commander uses extensively the dialog manager written by
143 Radek Doulik. To understand how the dialog manager works, please read
144 the dialog.c. You will find the basic widgets in the files widget.c.
145 Some more high-level functions, e.g. to display a message box, are
146 located in wtools.c. This file also contains the Quick Dialog code,
147 which makes it easier to create complex dialogs.
149 Files findme.c, popt.c, poptconfig.c, popthelp.c and poptparse.c come
150 from the popt library used to parse the command line. They should not
151 be modified unless absolutely necessary.
153 The files util.c and utilunix.c have a lot of utility functions. Get
154 familiar with them, they are very simple.
156 glib is used for memory allocation and for some utility functions, such
157 as manipulation with lists and trees. gmodule (part of the glib
158 distribution) is used to load some libraries dynamically at the run
161 Thanks to glib, the code has almost no hardcoded limits, since there are
162 many ways to avoid them. For example, when you want to concatenate
163 strings, use the g_strconcat() function:
165 new_text = g_strconcat (username, " ", password, NULL);
167 This allocates new memory for the string, so you should use g_free() on
170 The parent of all dialogs is called midnight_dlg. Both panels are
171 widgets in that dialog. Other widgets include the menu, the command
172 line and the button bar.
178 The routines for input handling on the Midnight Commander are:
179 getch, get_key_code, mi_getch and get_event.
181 getch is an interface to the low level system input mechanism. It
182 does not deal with the mouse.
184 In the case of ncurses, this is a function implemented in the
185 ncurses library that translates key sequences to key codes (\E[A to
186 something like KEY_UP and so on).
188 In the case of S-Lang there is no such conversion, that's why we
189 load a set of extra definitions.
191 The get_key_code routine converts the data from getch to the
192 constants the Midnight Commander uses.
194 In the case of S-Lang, it will actually do all the jobs that getch
195 does for curses. In the case of curses it patches a couple of
196 sequences that are not available on some terminal databases. This
197 routine is the one you want to use if you want a character without
200 get_event is the routine you want to use if you want to handle mouse
201 events, it will return 0 on a mouse event, -1 if no input is available
202 or a key code if there is some input available. This routine in turn
203 uses get_key_code to decode the input stream and convert it to useful
206 mi_getch is just a wrapper around get_event that ignores all the mouse
207 events. It's used only in a couple of places, this routine may return
208 -1 if no input is available (if you have set the nodelay option of
209 ncurses or S-Lang with nodelay) or a character code if no such option is
216 The mouse support in the Midnight Commander is based on the get_event
217 routine. The core of the mouse event dispatching is in the
218 dlg.c:run_dlg routine.
224 Although S-Lang is now used by default, we still support it ncurses. We
225 basically are using a small subset of ncurses because we want to be
226 compatible with Slang.
229 The Dialog manager and the Widgets
230 ==================================
232 The Dialog manager and the Widget structure are implemented in
233 src/dialog.c. Everything shown on screen is a dialog. Dialogs contain
234 widgets, but not everything on screen is a widget. Dialogs can draw
237 Dialogs are connected into a singly linked list using "parent" field.
238 Currently active dialog is saved in current_dlg variable. The toplevel
239 dialog has parent NULL. Usually it's midnight_dlg.
242 current_dlg ------->another dialog-- ... -->midnight_dlg
244 When the screen needs to be refreshed, every dialog asks its parent to
245 refresh first, and then refreshes itself.
247 A dialog is created by create_dlg(). Then it's populated by widgets
248 using add_widget(). Then the dialog is run by calling run_dlg(), which
249 returns the id of the button selected by the user. Finally, the dialog
250 is destroyed by calling destroy_dlg().
252 Widgets are placed to a doubly linked circular list. Each widget has
253 previous and next widget.
256 widget1 <---------> widget2 <---------> widget3
258 -----------------------------------------
261 Pressing Tab moves focus to the "next" widget, pressing Shift-Tab moves
262 focus to "prev". The tab order is equal to the add order except some
263 old code that use the reverse order by setting DLG_REVERSE flag in
264 create_dlg() call. Please don't use reverse order in the new code.
266 The initial widget to get focus can be selected by calling
269 When creating a dialog, you may want to use a callback that would
270 intercept some dialog events. However, many widgets will do the right
271 thing by default, so some dialogs can work just fine without callbacks.
273 There are also widget events, which are sent by the dialog to individual
274 widgets. Some widgets also have user callbacks.
276 To create your own widget, use init_widget(). In this case, you must
277 provide a callback function. Please note that it's not the same as the
278 user callback in some widgets.