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