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