| 4 |   | A BOINC application may provide graphics (e.g. visualizations) to volunteers. | 
                      
                        | 5 |   | These graphics are shown in two contexts: | 
                      
                        | 6 |   |  | 
                      
                        | 7 |   |  * As a screensaver, if selected by the user. | 
                      
                        | 8 |   |  * In a window, opened using the Show Graphics button in the BOINC Manager. | 
                      
                        | 9 |   |  | 
                      
                        | 10 |   | == Graphics apps == | 
                      
                        | 11 |   |  | 
                      
                        | 12 |   | Graphics are generated by a 'graphics app' program (separate from the main application). | 
                      
                        | 13 |   | This graphics app must have the properties that: | 
                      
                        | 14 |   |  | 
                      
                        | 15 |   |  * If invoked with `--fullscreen`, it opens a full-screen borderless window. | 
                      
                        | 16 |   |   It must exit on mouse or keyboard input | 
                      
                        | 17 |   |   (if you use the [#api BOINC graphics API] library this is handled automatically). | 
                      
                        | 18 |   |  * Otherwise it opens a standard window, and may handle mouse/keyboard input. | 
                      
                        | 19 |   |  | 
                      
                        | 20 |   | The logical name of the program must be 'graphics_app'. | 
                      
                        | 21 |   | When you set up your [AppVersionNew application version directory], use an entry like | 
                      
                        | 22 |   | {{{ | 
                      
                        | 23 |   | <file> | 
                      
                        | 24 |   |    <physical_name>uppercase_graphics_6.14_windows_intelx86.exe</physical_name> | 
                      
                        | 25 |   |    <logical_name>graphics_app</logical_name> | 
                      
                        | 26 |   | </file> | 
                      
                        | 27 |   | }}} | 
                      
                        | 28 |   | in your version.xml file. | 
                      
                        | 29 |   |  | 
                      
                        | 30 |   | The graphics app is launched by the BOINC Manager and/or by the screensaver. | 
                      
                        | 31 |   | It may be killed at any time. | 
                      
                        | 32 |   | Multiple instances of the graphics app may run at the same time | 
                      
                        | 33 |   | (e.g. if the user opens a graphics window via the Manager, | 
                      
                        | 34 |   | and then the screensaver runs and launches another instance). | 
                      
                      
                        |   | 3 | = Using OpenGL = | 
                      
            
                      
                        | 94 |   | The graphics app may want to get information from the main app. | 
                      
                        | 95 |   | This can be done using either shared memory or a file. | 
                      
                        | 96 |   |  | 
                      
                        | 97 |   | ==== Shared memory ==== | 
                      
                        | 98 |   |  | 
                      
                        | 99 |   | Communicating large amounts of data | 
                      
                        | 100 |   | can be done efficiently using shared memory. | 
                      
                        | 101 |   | The BOINC library supplies the following functions to facilitate this: | 
                      
                        | 102 |   |  | 
                      
                        | 103 |   | {{{ | 
                      
                        | 104 |   | void* boinc_graphics_make_shmem(char* appname, int size); | 
                      
                        | 105 |   | }}} | 
                      
                        | 106 |   | Called from the main app. | 
                      
                        | 107 |   | Creates a shared memory segment of the given size. | 
                      
                        | 108 |   |  'appname' should be the name of this application (used to ensure uniqueness of the shared-memory segment name). | 
                      
                        | 109 |   |  | 
                      
                        | 110 |   | {{{ | 
                      
                        | 111 |   | void* boinc_graphics_get_shmem(char* appname); | 
                      
                        | 112 |   | }}} | 
                      
                        | 113 |   | Called from the graphics app. | 
                      
                        | 114 |   | Attaches to an existing segment. | 
                      
                        | 115 |   | It must be called AFTER boinc_parse_init_data_file(). | 
                      
                        | 116 |   |  | 
                      
                        | 117 |   | The contents of the shared memory segment are application-dependent; | 
                      
                        | 118 |   | typically it contains numeric information describing the state of the computation. | 
                      
                        | 119 |   |  | 
                      
                        | 120 |   | You may want to include the following items: | 
                      
                        | 121 |   | {{{ | 
                      
                        | 122 |   | struct UC_SHMEM { | 
                      
                        | 123 |   |     double update_time; | 
                      
                        | 124 |   |     double fraction_done; | 
                      
                        | 125 |   |     double cpu_time; | 
                      
                        | 126 |   |     BOINC_STATUS status; | 
                      
                        | 127 |   |     int countdown; | 
                      
                        | 128 |   | }; | 
                      
                        | 129 |   | }}} | 
                      
                        | 130 |   |  | 
                      
                        | 131 |   | These items should be updated by the main app once per second, | 
                      
                        | 132 |   | using [BasicApi#timer boinc_set_timer_handler()]. | 
                      
                        | 133 |   | The items are: | 
                      
                        | 134 |   |  update_time:: | 
                      
                        | 135 |   |    The current time (dtime()). | 
                      
                        | 136 |   |    The graphics app should exit if the current time exceeds this by 5 seconds or so, | 
                      
                        | 137 |   |    so that it exits if the main app exits. | 
                      
                        | 138 |   |  fraction_done:: | 
                      
                        | 139 |   |    The last fraction done reported by the main app. | 
                      
                        | 140 |   |  cpu_time:: | 
                      
                        | 141 |   |    The current CPU time, as returned by '''boinc_worker_thread_cpu_time()'''. | 
                      
                        | 142 |   |  status:: | 
                      
                        | 143 |   |    The BOINC status, as returned by '''boinc_get_status()'''. | 
                      
                        | 144 |   |    If the 'suspended' flag is set, | 
                      
                        | 145 |   |    the graphics app should stop changing its display, | 
                      
                        | 146 |   |    and instead show an "application suspended" message. | 
                      
                        | 147 |   |  countdown:: | 
                      
                        | 148 |   |    See below. | 
                      
                        | 149 |   |  | 
                      
                        | 150 |   | Keep in mind that multiple instances of the graphics app may run simultaneously; | 
                      
                        | 151 |   | avoid having the graphics app write to the shared memory. | 
                      
                        | 152 |   | If you use shared memory to store a data structure, | 
                      
                        | 153 |   | use a semaphore to synchronize access so that the graphics app | 
                      
                        | 154 |   | doesn't see an inconsistent state. | 
                      
                        | 155 |   |  | 
                      
                        | 156 |   | Updating the shared memory structure uses CPU time, | 
                      
                        | 157 |   | and it's desirable to avoid this overhead if no graphics app is running. | 
                      
                        | 158 |   |  | 
                      
                        | 159 |   | One way to do this is to include a '''countdown''' field in the shared memory structure, as above. | 
                      
                        | 160 |   |  * The graphics sets this to 5 (say) in its '''app_graphics_render()''' function. | 
                      
                        | 161 |   |  * The main app decrements this (if positive) once per second. | 
                      
                        | 162 |   |  * The main app updates the application-specific data in shared memory | 
                      
                        | 163 |   |    only when '''countdown''' is nonzero. | 
                      
                        | 164 |   |  | 
                      
                        | 165 |   | See [ExampleApps the example application] for an example. | 
                      
                        | 166 |   |  | 
                      
                        | 167 |   | ==== File ==== | 
                      
                        | 168 |   |  | 
                      
                        | 169 |   | Alternatively, you can communicate data from main app to graphics app via a file. | 
                      
                        | 170 |   | The BOINC library provides two functions for this purpose. | 
                      
                        | 171 |   | The main program can call | 
                      
                        | 172 |   | {{{ | 
                      
                        | 173 |   | int boinc_write_graphics_status( | 
                      
                        | 174 |   |     const char* filename, double cpu_time, double elapsed_time, | 
                      
                        | 175 |   |     double fraction_done | 
                      
                        | 176 |   | ); | 
                      
                        | 177 |   | }}} | 
                      
                        | 178 |   | to write a file containing its status in XML format. | 
                      
                        | 179 |   | The graphics app can call | 
                      
                        | 180 |   | {{{ | 
                      
                        | 181 |   | int boinc_parse_graphics_status( | 
                      
                        | 182 |   |     const char* filename, double* update_time, double* cpu_time, | 
                      
                        | 183 |   |     double* elapsed_time, double* fraction_done, BOINC_STATUS* status | 
                      
                        | 184 |   | ); | 
                      
                        | 185 |   | }}} | 
                      
                        | 186 |   | to read and parse this file. | 
                      
                        | 187 |   |  | 
                      
                        | 188 |   | === Creating an icon for your applications === | 
                      
                        | 189 |   |  | 
                      
                        | 190 |   | For Windows: | 
                      
                        | 191 |   |  | 
                      
                        | 192 |   |  *  make Icons (there's a tool for this in Visual Studio), | 
                      
                        | 193 |   |   say "boincAppIcon16x16.ico", "boincAppIcon32x32.ico" and "boincAppIcon48x48.ico". | 
                      
                        | 194 |   |  * create a simple resource description file "boincAppIcon.rc" in the same directory | 
                      
                        | 195 |   |   as the icon files pointing to the icon filenames, | 
                      
                        | 196 |   |   the first entry is the resource name that is later passed to setWinIcon(): | 
                      
                        | 197 |   | {{{ | 
                      
                        | 198 |   | boinca16 ICON boincAppIcon16x16.ico | 
                      
                        | 199 |   | boinca32 ICON boincAppIcon32x32.ico | 
                      
                        | 200 |   | boinca48 ICON boincAppIcon48x48.ico | 
                      
                        | 201 |   | }}} | 
                      
                        | 202 |   |  * compile the resource (I do this on a Visual Studio Command Prompt): | 
                      
                        | 203 |   | {{{ | 
                      
                        | 204 |   | rc.exe boincAppIcon.rc | 
                      
                        | 205 |   | }}} | 
                      
                        | 206 |   |  * when linking the App, add the resulting file boincAppIcon.RES to the objects | 
                      
                        | 207 |   |  | 
                      
                        | 208 |   |  * we call setWinIcon("boinca16","boinca48") in app_graphics_init() | 
                      
                        | 209 |   |  | 
                      
                        | 210 |   | === Support classes === | 
                      
                      
                        |   | 62 | == Support classes == |