1Introduction
2============
3
4In the world of BeOS programming, a "resource" is data that is bundled with your application.
5Typical examples are the application's icons and its signature, but you can attach any data you
6want (bitmaps, text, cursors, etc). You stuff this data into a .rsrc file that will be linked to
7your application when it is compiled.
8
9Because .rsrc files have a binary file format, you need to use special tools to edit them, such as
10FileTypes, QuickRes, or Resourcer. Alternatively, you can use a "resource compiler". This is a
11command line tool that takes a text-based resource script and turns it into a .rsrc file.
12
13With a resource compiler, you express your resources as ASCII text using a special definition
14language, which makes the resource files much easier to edit and maintain. You no longer need
15separate GUI tools to build your .rsrc files, and you can even automate the whole process by
16calling the compiler from your Makefile or Jamfile. Resource scripts will also make your life
17easier if you use version control, because version control doesn't handle .rsrc files very well.
18
19BeOS R5 comes with an (experimental) resource compiler called "beres", and a corresponding
20decompiler called "deres". rc is an open source replacement (and enhancement) of these tools. It
21is (mostly) backwards compatible, so you should be able to compile your old .rdef files without any
22problems.
23
24How to install
25==============
26
27- Copy ``rc`` into ``/boot/home/config/non-packaged/bin``
28- Copy ``librdef.so`` into ``/boot/home/config/non-packaged/lib``
29- Let's party!
30
31Note: rc comes preinstalled in Haiku already.
32
33Writing resource scripts
34========================
35
36Writing resource scripts is not difficult, although the syntax may take some getting used to. A
37resource script is a plain text file with one or more resource definition statements. In addition,
38it may contain C or C++ style comments. By convention, resource script files have the extension ".rdef".
39
40Here is an example of a simple resource script:
41
42.. code-block:: c
43
44    resource(1) true;      /* this is a comment */
45    resource(2) 123;       // and so is this
46    resource(3) 3.14;
47    resource(4) "hello world";
48    resource(5) $"0123456789ABCDEF";
49
50When compiled, this script produces a resource file with five resources. The above example also
51illustrates the types of data that resources are allowed to have: boolean, integer, floating point,
52character string (UTF-8), and raw data buffer (hexadecimal).
53
54By default, integer data is stored as a 32-bit int, and floating point data is stored as a 4-byte
55float. If you want to change the way the data is stored, you have to cast it:
56
57.. code-block:: c
58
59    resource(6) (int8) 123;
60    resource(7) (double) 3.14;
61
62You can cast integer data to the following types: int8, uint8, int16, uint16, int32, uint32, int64,
63uint64, ssize_t, size_t, off_t, time_t, float, double, raw. You can cast floating point data to:
64float, double, raw. You are not allowed to cast boolean, string, or raw data to other types.
65
66In addition to casting, you can also change the resource's type code. This does not change the way
67the data is stored, only what it is called. To change the type code of a resource:
68
69.. code-block::
70
71    resource(8) #'dude' 123;
72
73This changes the type of resource 8 to the four-character-code 'dude'. If you did not change it, it
74would be 'LONG', which stands for 32-bit integer. By changing the type code, you assign a new
75meaning to the resource. You can also specify type codes as decimal or hexadecimal numbers:
76
77.. code-block::
78
79    resource(9) #200 123;
80    resource(10) #0xC8 123;
81
82For historical reasons, you may also enclose the type code in parens, but that is not the preferred
83notation. Type casts and type codes can be combined:
84
85.. code-block::
86
87    resource(11) #'dude' (int8) 123;
88    resource(11) (#'dude') (int8) 123;
89
90In the above examples, we have given the resources numeric IDs. The combination of ID and type code
91must be unique in the resource file; you cannot have two int32 resources with ID 1, for example.
92However, it is perfectly fine (but not necessarily a good idea) to do the following, because the
93data types are different:
94
95.. code-block:: c
96
97    resource(12) 123;
98    resource(12) "w00t!";
99
100For your own convenience, you can also name resources. Unlike the ID/type code combination, names
101do not have to be unique.
102
103.. code-block:: c
104
105    resource(13, "Friday") "Bad Luck";
106
107You can also do simple maths. The emphasis here is on simple because the number of operators is
108limited, they only work on integer data (or anything that can be cast to integer), and the result
109is always 32-bit integer as well. Still, the lazy amongst you may find it handy:
110
111.. code-block:: c
112
113    resource(14) 2 * (4 + 3);
114
115Since it is likely that you will be using these resources from a C/C++ program, it may be
116convenient to refer to them by symbolic names instead of hardcoded numeric ID's. The rdef format
117allows you to do this:
118
119.. code-block:: c
120
121    {
122        R_AppName = 1,
123        R_SomeOtherThing = 2
124    };
125
126    resource(R_AppName) "MyKillerApp";
127
128The compiler will automatically substitute the symbol R_AppName with the number 1. (You don't have
129to start these symbol names with the prefix ``R_``, but it is somewhat of a convention.)
130
131Now how do you tell your C/C++ app about these symbolic names? You simply put the enum into a
132header file that you include both from your application's source code and your rdef file. The
133header file, which we'll call "myresources.h", now looks like this:
134
135.. code-block:: c
136
137    {
138        R_AppName = 1,
139        R_SomeOtherThing = 2
140    }
141
142And the rdef file becomes this:
143
144.. code-block:: c
145
146    #include "myresources.h"
147
148    resource(R_AppName) "MyKillerApp";
149
150Don't let the .h suffix fool you: the header file is still considered to be an rdef file, and must
151contain valid rdef syntax. If you add any other C/C++ code, your resource script will fail to
152compile. Of course, you shouldn't add any other rdef syntax to the header either (unless you want
153your C++ compiler to start complaining). Besides comments, the only safe thing to put in that
154header file is the enum statement, because both rdef and C/C++ understand it.
155
156Just like IDs, symbolic identifiers can be combined with a name:
157
158.. code-block:: c
159
160    resource(R_AppName, "AppName") "MyKillerApp";
161
162If you don't specify a name, and invoke the compiler with the ``--auto-names`` option, it
163automatically uses the symbolic ID for the name as well. So the ID of the following resource is 1
164(because that is what R_AppName corresponds to) and its name becomes "R_AppName":
165
166.. code-block:: c
167
168    resource(R_AppName) "MyKillerApp";
169
170Big fat resources
171=================
172
173The resources we have made so far consisted of a single data item, but you can also supply a
174collection of data values. The simplest of these compound data structures is the array:
175
176.. code-block:: c
177
178    resource(20) array { 1234, 5678 };
179
180An array is nothing more than a raw buffer. The above statement takes the two 32-bit integers 1234
181and 5678 and stuffs them into a new 64-bit buffer. You can put any kind of data into an array, even
182other arrays:
183
184.. code-block:: c
185
186    resource(21) array
187    {
188        "hello",
189        3.14,
190        true,
191        array { "a", "nested", "array" },
192        $"AABB"
193    };
194
195It is up to you to remember the structure of this array, because array resources don't keep track
196of what kind of values you put into them and where you put these values. For that, we have messages.
197A message resource is a flattened BMessage:
198
199.. code-block::
200
201    resource(22) message('blah')
202    {
203        "Name" = "Santa Claus",
204        "Number" = 3.14,
205        "Array" = array { "a", "nested", "array" },
206        "Other Msg" = message { "field" = "value" }
207    };
208
209A message has an optional "what" code, in this case 'blah', and one or more fields. A field has a
210name (between double quotes), a value, and a data type. By default, the field assumes the type of
211its data, but you can also specify an explicit data type and type code in front of the field name:
212
213.. code-block::
214
215    resource(23) message('bla2')
216    {
217        "integer1" = (int8) 123,             // use cast to change data type
218        int16 "integer2" = 12345,            // specify data type
219        #'dude' "buffer1" = $"aabbccdd",     // specify a new type code
220        #'dude' raw "buffer2" = $"aabbccdd"  // you can also combine them
221    };
222
223A special type of message is the "archive". The BeOS API allows you to take a BArchivable class an
224flatten it into a BMessage. You can also add such archives to your resource scripts:
225
226.. code-block::
227
228    resource(24) #'BBMP' archive BBitmap
229    {
230        "_frame" = rect { 0.0, 0.0, 63.0, 31.0 },
231        "_cspace" = 8200,
232        "_bmflags" = 1,
233        "_rowbytes" = 256,
234        "_data" =  array
235        {
236            ... /* here goes the bitmap data */ ...
237        }
238    };
239
240So what's this "rect" thing in the "_frame" field? Besides arrays and messages, the compiler also
241supports a number of other data structures from the BeAPI:
242
243+-----------+-------------------------+--------------------------------+
244| Type      | Corresponds to          | Fields                         |
245+===========+=========================+================================+
246| point     | BPoint, B_POINT_TYPE    | float x, y                     |
247+-----------+-------------------------+--------------------------------+
248| rect      | BRect, B_RECT_TYPE      | float left, top, right, bottom |
249+-----------+-------------------------+--------------------------------+
250| rgb_color | rgb_color, B_COLOR_TYPE | uint8 red, greed, blue, alpha  |
251+-----------+-------------------------+--------------------------------+
252
253To add a color resource to your script, you can do:
254
255.. code-block:: c
256
257    resource(25) rgb_color { 255, 128, 0, 0 };
258
259Or you can use the field names, in which case the order of the fields does not matter:
260
261.. code-block:: c
262
263    resource(26) rgb_color
264    {
265        blue = 0, green = 128, alpha = 0, red = 255
266    };
267
268You can also make your own data structures, or as we refer to them, "user-defined types". Suppose
269that your application wants to store its GUI elements in the resources:
270
271.. code-block::
272
273    type #'menu' menu
274    {
275        string name,
276        int32 count,  // how many items
277        array items   // the menu items
278    };
279
280    type #'item' menuitem
281    {
282        string name,
283        message msg,
284        bool enabled = true  // default value is "true"
285    };
286
287A type has a name, an optional type code, and one or more fields. You are advised not to pick a
288type code that already belongs to one of the built-in types, to avoid any confusion. Each field has
289a data type, a name, and a default value. If you don't specify a default, it is typically 0 or
290empty. To create a new menu resource using the types from the above example, you might do:
291
292.. code-block::
293
294    resource(27) menu
295    {
296        name = "File",
297        count = 3,
298        items = array
299        {
300           menuitem { "New...",   message('fnew') },
301           menuitem { "Print...", message('fprt'), false },
302           menuitem { "Exit",     message('_QRQ') }
303        }
304    };
305
306Like an array, a type resource doesn't remember its internal structure. You can regard types as
307fancy arrays that are easier to fill in, a template if you will. User-defined types work under the
308same rules as the built-in types point, rect, and rgb_color, so you can specify the fields in order
309or by their names. If you don't specify a field, its default value will be used.
310
311Types can also have a default resource ID and/or name. If you omit to give the resource an ID or a
312name, it uses the defaults from its data type. For example, this:
313
314.. code-block:: c
315
316    type myint { int32 i };
317    resource(10, "MyName") myint { 123 };
318
319Is equivalent to this:
320
321.. code-block:: c
322
323    type(10, "MyName") myint { int32 i };
324    resource myint { 123 };
325
326And to save you even more typing, simple types that have only one field can also be specified as:
327
328.. code-block:: c
329
330    resource myint 123;
331
332Most data types have a fixed size; a uint16 is always 2 bytes long, a float always comprises 4
333bytes, and so on. But the sizes of string and raw data resources depend on what you put in them.
334Sometimes you may want to force these kinds of resources to have a fixed size as well. You can do
335this as follows:
336
337.. code-block:: c
338
339    type fixed { string s[64] };
340
341Any resources with type "fixed" will always contain a 64-byte string, no matter how many characters
342you actually specify. Too much data will be truncated; too little data will be padded with zeroes.
343Note that string resources are always terminated with a null character, so string "s" in the above
344type only allows for 63 real characters. The number between the square brackets always indicates
345bytes (unlike C/C++ arrays which use a similar notation).
346
347If you have (large) binary files that you want to include in the resources, such as pictures of
348Buffy, you don't need to convert the binary data to text form first. You can simply "import" the
349file:
350
351.. code-block::
352
353    resource(22) #'PNG ' import "buffy.png";
354
355Imported resources are always arrays (raw data), and you can specify the import statement
356everywhere that array data is valid.
357
358Application resources
359=====================
360
361All BeOS applications (except command line apps) have a basic set of resources, such as a MIME
362signature, launch flags, icons, and a few others. Adding these kinds of resources is easy, because
363rc also has a number of built-in types for that:
364
365+---------------+------------------------------+--------------------------------------------------+
366| Type          | Corresponds to               | Fields                                           |
367+===============+==============================+==================================================+
368| app_signature | the apps's MIME signature    | string signature                                 |
369+---------------+------------------------------+--------------------------------------------------+
370| app_flags     | the application launch flags | uint32 flags                                     |
371+---------------+------------------------------+--------------------------------------------------+
372| app_version   | version information          | uint32 major, middle, minor, variety, internal   |
373|               |                              | string short_info, long_info                     |
374+---------------+------------------------------+--------------------------------------------------+
375| large_icon    | 32x32 icon                   | array of 1024 bytes                              |
376+---------------+------------------------------+--------------------------------------------------+
377| mini_icon     | 16x16 icon                   | array of 256 bytes                               |
378+---------------+------------------------------+--------------------------------------------------+
379| vector_icon   | HVIF vector icon (type VICN) | array of bytes                                   |
380+---------------+------------------------------+--------------------------------------------------+
381| file_types    | supported file types         | message                                          |
382+---------------+------------------------------+--------------------------------------------------+
383
384Here are some examples on how to use these resources. These things are also documented in the
385Storage Kit section of the BeBook, so refer to that for more information.
386
387The signature:
388
389.. code-block:: c
390
391    resource app_signature "application/x-vnd.YourName.YourApp";
392
393The application flags determine how your application is launched. You must 'OR' together a combination of the following symbols:
394
395- ``B_SINGLE_LAUNCH``
396- ``B_MULTIPLE_LAUNCH``
397- ``B_EXCLUSIVE_LAUNCH``
398- ``B_BACKGROUND_APP``
399- ``B_ARGV_ONLY``
400
401For example:
402
403.. code-block:: c
404
405    resource app_flags B_SINGLE_LAUNCH | B_BACKGROUND_APP;
406
407The version information resource contains a number of fields for you to fill in. Most are pretty
408obvious, except maybe for the "variety" field. It can take one of the following values:
409
410``B_APPV_DEVELOPMENT``
411    development version
412
413``B_APPV_ALPHA``
414    alpha version
415
416``B_APPV_BETA``
417    beta version
418
419``B_APPV_GAMMA``
420    gamma version
421
422``B_APPV_GOLDEN_MASTER``
423    golden master
424
425``B_APPV_FINAL``
426    release version
427
428For example:
429
430.. code-block:: c
431
432    resource app_version
433    {
434        major      = 1,
435        middle     = 0,
436        minor      = 0,
437        variety    = B_APPV_BETA,
438        internal   = 0,
439        short_info = "My Cool Program",
440        long_info  = "My Cool Program - Copyright Me"
441    };
442
443The supported file types resource contains a list of MIME types, not unlike this:
444
445.. code-block:: c
446
447    resource file_types message
448    {
449        "types" = "text/plain",
450        "types" = "text"
451    };
452
453Compiling
454=========
455
456rc is a command line tool, which means you must run it from a Terminal window. Typical usage example:
457
458.. code-block:: sh
459
460    rc -o things.rsrc things.rdef
461
462This tells rc that you wish to compile the script "things.rdef" to the resource file "things.rsrc".
463The default name for the output file is "out.rsrc", but you can change that with the ``-o``
464or ``--output`` switch, just like we did here.
465
466You can specify multiple rdef files if you wish, and they will all be compiled into one big
467resource file. If your rdef files #include files that are not in the current working directory,
468you can add include paths with the ``-I`` or ``--include`` option. For a complete list of options,
469type ``rc --help``.
470
471If your project uses a Makefile, you can have rc automatically generate the resource file for you:
472
473.. code-block:: make
474
475    things.rsrc: things.rdef
476    	rc -o $@ $^</PRE></BLOCKQUOTE>
477
478.. TODO: also explain how to integrate rc in jamfiles
479
480Decompiling
481===========
482
483Of course you can write the resource scripts by hand, but if you already have a .rsrc file you can
484tell rc to decompile it. This will produce a ready-to-go rdef script, and save you some trouble.
485(Although in some cases it may be necessary to edit the script a little to suit your needs.) Note
486that rc isn't limited to just .rsrc files; you can decompile any file that has resources,
487including applications.
488
489For example, to decompile the file "things.rsrc" into "things.rdef", do:
490
491.. code-block:: sh
492
493    rc --decompile -o things.rdef things.rsrc
494
495The decompiler produces an rdef resource script with the name "out.rdef", but you can change that
496name with the ``-o`` or ``--output`` switches. If you specify the ``--auto-names`` option, rc will also
497write a C/C++ header file. Any resources whose name is a valid C/C++ identifier will be added to
498the header file. Now your program can access the resource using this symbolic name.
499
500Note: Even though rc can decompile multiple .rsrc files into one script, it does not detect
501conflicts in resource names or IDs. In such cases, the resulting .rdef and/or .h files may give
502errors when you try to compile them.
503
504Authors
505=======
506
507The rc resource compiler and its companion library librdef were written by `Matthijs Hollmans <mailto:mahlzeit@users.sourceforge.net>`_ for the `Haiku <http://www.haiku-os.org>`_ project. Thanks to Ingo Weinhold for the Jamfile and the Jam rules. Comments, bug reports, suggestions, and patches are welcome!
508