This file is indexed.

/usr/include/agg2/platform/agg_platform_support.h is in libagg-dev 2.5+dfsg1-9.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
//          mcseemagg@yahoo.com
//          http://antigrain.com
// 
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
// 
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
// MA 02110-1301, USA.
//----------------------------------------------------------------------------
//
// class platform_support
//
// It's not a part of the AGG library, it's just a helper class to create 
// interactive demo examples. Since the examples should not be too complex
// this class is provided to support some very basic interactive graphical
// funtionality, such as putting the rendered image to the window, simple 
// keyboard and mouse input, window resizing, setting the window title,
// and catching the "idle" events.
// 
// The idea is to have a single header file that does not depend on any 
// platform (I hate these endless #ifdef/#elif/#elif.../#endif) and a number
// of different implementations depending on the concrete platform. 
// The most popular platforms are:
//
// Windows-32 API
// X-Window API
// SDL library (see http://www.libsdl.org/)
// MacOS C/C++ API
// 
// This file does not include any system dependent .h files such as
// windows.h or X11.h, so, your demo applications do not depend on the
// platform. The only file that can #include system dependend headers
// is the implementation file agg_platform_support.cpp. Different
// implementations are placed in different directories, such as
// ~/agg/src/platform/win32
// ~/agg/src/platform/sdl
// ~/agg/src/platform/X11
// and so on.
//
// All the system dependent stuff sits in the platform_specific 
// class which is forward-declared here but not defined. 
// The platform_support class has just a pointer to it and it's 
// the responsibility of the implementation to create/delete it.
// This class being defined in the implementation file can have 
// any platform dependent stuff such as HWND, X11 Window and so on.
//
//----------------------------------------------------------------------------


#ifndef AGG_PLATFORM_SUPPORT_INCLUDED
#define AGG_PLATFORM_SUPPORT_INCLUDED


#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_trans_viewport.h"
#include "ctrl/agg_ctrl.h"

namespace agg
{

    //----------------------------------------------------------window_flag_e
    // These are flags used in method init(). Not all of them are
    // applicable on different platforms, for example the win32_api
    // cannot use a hardware buffer (window_hw_buffer).
    // The implementation should simply ignore unsupported flags.
    enum window_flag_e
    {
        window_resize            = 1,
        window_hw_buffer         = 2,
        window_keep_aspect_ratio = 4,
        window_process_all_keys  = 8
    };

    //-----------------------------------------------------------pix_format_e
    // Possible formats of the rendering buffer. Initially I thought that it's
    // reasonable to create the buffer and the rendering functions in 
    // accordance with the native pixel format of the system because it 
    // would have no overhead for pixel format conersion. 
    // But eventually I came to a conclusion that having a possibility to 
    // convert pixel formats on demand is a good idea. First, it was X11 where 
    // there lots of different formats and visuals and it would be great to 
    // render everything in, say, RGB-24 and display it automatically without
    // any additional efforts. The second reason is to have a possibility to 
    // debug renderers for different pixel formats and colorspaces having only 
    // one computer and one system.
    //
    // This stuff is not included into the basic AGG functionality because the 
    // number of supported pixel formats (and/or colorspaces) can be great and 
    // if one needs to add new format it would be good only to add new 
    // rendering files without having to modify any existing ones (a general 
    // principle of incapsulation and isolation).
    //
    // Using a particular pixel format doesn't obligatory mean the necessity
    // of software conversion. For example, win32 API can natively display 
    // gray8, 15-bit RGB, 24-bit BGR, and 32-bit BGRA formats. 
    // This list can be (and will be!) extended in future.
    enum pix_format_e
    {
        pix_format_undefined = 0,  // By default. No conversions are applied 
        pix_format_bw,             // 1 bit per color B/W
        pix_format_gray8,          // Simple 256 level grayscale
        pix_format_gray16,         // Simple 65535 level grayscale
        pix_format_rgb555,         // 15 bit rgb. Depends on the byte ordering!
        pix_format_rgb565,         // 16 bit rgb. Depends on the byte ordering!
        pix_format_rgbAAA,         // 30 bit rgb. Depends on the byte ordering!
        pix_format_rgbBBA,         // 32 bit rgb. Depends on the byte ordering!
        pix_format_bgrAAA,         // 30 bit bgr. Depends on the byte ordering!
        pix_format_bgrABB,         // 32 bit bgr. Depends on the byte ordering!
        pix_format_rgb24,          // R-G-B, one byte per color component
        pix_format_bgr24,          // B-G-R, native win32 BMP format.
        pix_format_rgba32,         // R-G-B-A, one byte per color component
        pix_format_argb32,         // A-R-G-B, native MAC format
        pix_format_abgr32,         // A-B-G-R, one byte per color component
        pix_format_bgra32,         // B-G-R-A, native win32 BMP format
        pix_format_rgb48,          // R-G-B, 16 bits per color component
        pix_format_bgr48,          // B-G-R, native win32 BMP format.
        pix_format_rgba64,         // R-G-B-A, 16 bits byte per color component
        pix_format_argb64,         // A-R-G-B, native MAC format
        pix_format_abgr64,         // A-B-G-R, one byte per color component
        pix_format_bgra64,         // B-G-R-A, native win32 BMP format
  
        end_of_pix_formats
    };

    //-------------------------------------------------------------input_flag_e
    // Mouse and keyboard flags. They can be different on different platforms
    // and the ways they are obtained are also different. But in any case
    // the system dependent flags should be mapped into these ones. The meaning
    // of that is as follows. For example, if kbd_ctrl is set it means that the 
    // ctrl key is pressed and being held at the moment. They are also used in 
    // the overridden methods such as on_mouse_move(), on_mouse_button_down(),
    // on_mouse_button_dbl_click(), on_mouse_button_up(), on_key(). 
    // In the method on_mouse_button_up() the mouse flags have different
    // meaning. They mean that the respective button is being released, but
    // the meaning of the keyboard flags remains the same.
    // There's absolut minimal set of flags is used because they'll be most
    // probably supported on different platforms. Even the mouse_right flag
    // is restricted because Mac's mice have only one button, but AFAIK
    // it can be simulated with holding a special key on the keydoard.
    enum input_flag_e
    {
        mouse_left  = 1,
        mouse_right = 2,
        kbd_shift   = 4,
        kbd_ctrl    = 8
    };

    //--------------------------------------------------------------key_code_e
    // Keyboard codes. There's also a restricted set of codes that are most 
    // probably supported on different platforms. Any platform dependent codes
    // should be converted into these ones. There're only those codes are
    // defined that cannot be represented as printable ASCII-characters. 
    // All printable ASCII-set can be used in a regular C/C++ manner: 
    // ' ', 'A', '0' '+' and so on.
    // Since the class is used for creating very simple demo-applications
    // we don't need very rich possibilities here, just basic ones. 
    // Actually the numeric key codes are taken from the SDL library, so,
    // the implementation of the SDL support does not require any mapping.
    enum key_code_e
    {
        // ASCII set. Should be supported everywhere
        key_backspace      = 8,
        key_tab            = 9,
        key_clear          = 12,
        key_return         = 13,
        key_pause          = 19,
        key_escape         = 27,

        // Keypad 
        key_delete         = 127,
        key_kp0            = 256,
        key_kp1            = 257,
        key_kp2            = 258,
        key_kp3            = 259,
        key_kp4            = 260,
        key_kp5            = 261,
        key_kp6            = 262,
        key_kp7            = 263,
        key_kp8            = 264,
        key_kp9            = 265,
        key_kp_period      = 266,
        key_kp_divide      = 267,
        key_kp_multiply    = 268,
        key_kp_minus       = 269,
        key_kp_plus        = 270,
        key_kp_enter       = 271,
        key_kp_equals      = 272,

        // Arrow-keys and stuff
        key_up             = 273,
        key_down           = 274,
        key_right          = 275,
        key_left           = 276,
        key_insert         = 277,
        key_home           = 278,
        key_end            = 279,
        key_page_up        = 280,
        key_page_down      = 281,

        // Functional keys. You'd better avoid using
        // f11...f15 in your applications if you want 
        // the applications to be portable
        key_f1             = 282,
        key_f2             = 283,
        key_f3             = 284,
        key_f4             = 285,
        key_f5             = 286,
        key_f6             = 287,
        key_f7             = 288,
        key_f8             = 289,
        key_f9             = 290,
        key_f10            = 291,
        key_f11            = 292,
        key_f12            = 293,
        key_f13            = 294,
        key_f14            = 295,
        key_f15            = 296,

        // The possibility of using these keys is 
        // very restricted. Actually it's guaranteed 
        // only in win32_api and win32_sdl implementations
        key_numlock        = 300,
        key_capslock       = 301,
        key_scrollock      = 302,

        // Phew!
        end_of_key_codes
    };


    //------------------------------------------------------------------------
    // A predeclaration of the platform dependent class. Since we do not
    // know anything here the only we can have is just a pointer to this
    // class as a data member. It should be created and destroyed explicitly
    // in the constructor/destructor of the platform_support class. 
    // Although the pointer to platform_specific is public the application 
    // cannot have access to its members or methods since it does not know
    // anything about them and it's a perfect incapsulation :-)
    class platform_specific;

    
    //----------------------------------------------------------ctrl_container
    // A helper class that contains pointers to a number of controls.
    // This class is used to ease the event handling with controls.
    // The implementation should simply call the appropriate methods
    // of this class when appropriate events occur.
    class ctrl_container
    {
        enum max_ctrl_e { max_ctrl = 64 };

    public:
        //--------------------------------------------------------------------
        ctrl_container() : m_num_ctrl(0), m_cur_ctrl(-1) {}

        //--------------------------------------------------------------------
        void add(ctrl& c)
        {
            if(m_num_ctrl < max_ctrl)
            {
                m_ctrl[m_num_ctrl++] = &c;
            }
        }

        //--------------------------------------------------------------------
        bool in_rect(double x, double y)
        {
            unsigned i;
            for(i = 0; i < m_num_ctrl; i++)
            {
                if(m_ctrl[i]->in_rect(x, y)) return true;
            }
            return false;
        }

        //--------------------------------------------------------------------
        bool on_mouse_button_down(double x, double y)
        {
            unsigned i;
            for(i = 0; i < m_num_ctrl; i++)
            {
                if(m_ctrl[i]->on_mouse_button_down(x, y)) return true;
            }
            return false;
        }

        //--------------------------------------------------------------------
        bool on_mouse_button_up(double x, double y)
        {
            unsigned i;
            bool flag = false;
            for(i = 0; i < m_num_ctrl; i++)
            {
                if(m_ctrl[i]->on_mouse_button_up(x, y)) flag = true;
            }
            return flag;
        }

        //--------------------------------------------------------------------
        bool on_mouse_move(double x, double y, bool button_flag)
        {
            unsigned i;
            for(i = 0; i < m_num_ctrl; i++)
            {
                if(m_ctrl[i]->on_mouse_move(x, y, button_flag)) return true;
            }
            return false;
        }

        //--------------------------------------------------------------------
        bool on_arrow_keys(bool left, bool right, bool down, bool up)
        {
            if(m_cur_ctrl >= 0)
            {
                return m_ctrl[m_cur_ctrl]->on_arrow_keys(left, right, down, up);
            }
            return false;
        }

        //--------------------------------------------------------------------
        bool set_cur(double x, double y)
        {
            unsigned i;
            for(i = 0; i < m_num_ctrl; i++)
            {
                if(m_ctrl[i]->in_rect(x, y)) 
                {
                    if(m_cur_ctrl != int(i))
                    {
                        m_cur_ctrl = i;
                        return true;
                    }
                    return false;
                }
            }
            if(m_cur_ctrl != -1)
            {
                m_cur_ctrl = -1;
                return true;
            }
            return false;
        }

    private:
        ctrl*         m_ctrl[max_ctrl];
        unsigned      m_num_ctrl;
        int           m_cur_ctrl;
    };



    //---------------------------------------------------------platform_support
    // This class is a base one to the apllication classes. It can be used 
    // as follows:
    //
    //  class the_application : public agg::platform_support
    //  {
    //  public:
    //      the_application(unsigned bpp, bool flip_y) :
    //          platform_support(bpp, flip_y) 
    //      . . .
    //
    //      //override stuff . . .
    //      virtual void on_init()
    //      {
    //         . . .
    //      }
    //
    //      virtual void on_draw()
    //      {
    //          . . .
    //      }
    //
    //      virtual void on_resize(int sx, int sy)
    //      {
    //          . . .
    //      }
    //      // . . . and so on, see virtual functions
    //
    //
    //      //any your own stuff . . .
    //  };
    //
    //
    //  int agg_main(int argc, char* argv[])
    //  {
    //      the_application app(pix_format_rgb24, true);
    //      app.caption("AGG Example. Lion");
    //
    //      if(app.init(500, 400, agg::window_resize))
    //      {
    //          return app.run();
    //      }
    //      return 1;
    //  }
    //
    // The reason to have agg_main() instead of just main() is that SDL
    // for Windows requires including SDL.h if you define main(). Since
    // the demo applications cannot rely on any platform/library specific
    // stuff it's impossible to include SDL.h into the application files.
    // The demo applications are simple and their use is restricted, so, 
    // this approach is quite reasonable.
    // 
    class platform_support
    {
    public:
        enum max_images_e { max_images = 16 };

        // format - see enum pix_format_e {};
        // flip_y - true if you want to have the Y-axis flipped vertically.
        platform_support(pix_format_e format, bool flip_y);
        virtual ~platform_support();

        // Setting the windows caption (title). Should be able
        // to be called at least before calling init(). 
        // It's perfect if they can be called anytime.
        void        caption(const char* cap);
        const char* caption() const { return m_caption; }

        //--------------------------------------------------------------------
        // These 3 methods handle working with images. The image
        // formats are the simplest ones, such as .BMP in Windows or 
        // .ppm in Linux. In the applications the names of the files
        // should not have any file extensions. Method load_img() can
        // be called before init(), so, the application could be able 
        // to determine the initial size of the window depending on 
        // the size of the loaded image. 
        // The argument "idx" is the number of the image 0...max_images-1
        bool load_img(unsigned idx, const char* file);
        bool save_img(unsigned idx, const char* file);
        bool create_img(unsigned idx, unsigned width=0, unsigned height=0);

        //--------------------------------------------------------------------
        // init() and run(). See description before the class for details.
        // The necessity of calling init() after creation is that it's 
        // impossible to call the overridden virtual function (on_init()) 
        // from the constructor. On the other hand it's very useful to have
        // some on_init() event handler when the window is created but 
        // not yet displayed. The rbuf_window() method (see below) is 
        // accessible from on_init().
        bool init(unsigned width, unsigned height, unsigned flags);
        int  run();

        //--------------------------------------------------------------------
        // The very same parameters that were used in the constructor
        pix_format_e format() const { return m_format; }
        bool flip_y() const { return m_flip_y; }
        unsigned bpp() const { return m_bpp; }

        //--------------------------------------------------------------------
        // The following provides a very simple mechanism of doing someting
        // in background. It's not multithreading. When wait_mode is true
        // the class waits for the events and it does not ever call on_idle().
        // When it's false it calls on_idle() when the event queue is empty.
        // The mode can be changed anytime. This mechanism is satisfactory
        // to create very simple animations.
        bool wait_mode() const { return m_wait_mode; }
        void wait_mode(bool wait_mode) { m_wait_mode = wait_mode; }

        //--------------------------------------------------------------------
        // These two functions control updating of the window. 
        // force_redraw() is an analog of the Win32 InvalidateRect() function.
        // Being called it sets a flag (or sends a message) which results
        // in calling on_draw() and updating the content of the window 
        // when the next event cycle comes.
        // update_window() results in just putting immediately the content 
        // of the currently rendered buffer to the window without calling
        // on_draw().
        void force_redraw();
        void update_window();

        //--------------------------------------------------------------------
        // So, finally, how to draw anythig with AGG? Very simple.
        // rbuf_window() returns a reference to the main rendering 
        // buffer which can be attached to any rendering class.
        // rbuf_img() returns a reference to the previously created
        // or loaded image buffer (see load_img()). The image buffers 
        // are not displayed directly, they should be copied to or 
        // combined somehow with the rbuf_window(). rbuf_window() is
        // the only buffer that can be actually displayed.
        rendering_buffer& rbuf_window()          { return m_rbuf_window; } 
        rendering_buffer& rbuf_img(unsigned idx) { return m_rbuf_img[idx]; } 
        

        //--------------------------------------------------------------------
        // Returns file extension used in the implementation for the particular
        // system.
        const char* img_ext() const;

        //--------------------------------------------------------------------
        void copy_img_to_window(unsigned idx)
        {
            if(idx < max_images && rbuf_img(idx).buf())
            {
                rbuf_window().copy_from(rbuf_img(idx));
            }
        }
        
        //--------------------------------------------------------------------
        void copy_window_to_img(unsigned idx)
        {
            if(idx < max_images)
            {
                create_img(idx, rbuf_window().width(), rbuf_window().height());
                rbuf_img(idx).copy_from(rbuf_window());
            }
        }
       
        //--------------------------------------------------------------------
        void copy_img_to_img(unsigned idx_to, unsigned idx_from)
        {
            if(idx_from < max_images && 
               idx_to < max_images && 
               rbuf_img(idx_from).buf())
            {
                create_img(idx_to, 
                           rbuf_img(idx_from).width(), 
                           rbuf_img(idx_from).height());
                rbuf_img(idx_to).copy_from(rbuf_img(idx_from));
            }
        }

        //--------------------------------------------------------------------
        // Event handlers. They are not pure functions, so you don't have
        // to override them all.
        // In my demo applications these functions are defined inside
        // the the_application class (implicit inlining) which is in general 
        // very bad practice, I mean vitual inline methods. At least it does
        // not make sense. 
        // But in this case it's quite appropriate bacause we have the only
        // instance of the the_application class and it is in the same file 
        // where this class is defined.
        virtual void on_init();
        virtual void on_resize(int sx, int sy);
        virtual void on_idle();
        virtual void on_mouse_move(int x, int y, unsigned flags);
        virtual void on_mouse_button_down(int x, int y, unsigned flags);
        virtual void on_mouse_button_up(int x, int y, unsigned flags);
        virtual void on_key(int x, int y, unsigned key, unsigned flags);
        virtual void on_ctrl_change();
        virtual void on_draw();
        virtual void on_post_draw(void* raw_handler);

        //--------------------------------------------------------------------
        // Adding control elements. A control element once added will be 
        // working and reacting to the mouse and keyboard events. Still, you
        // will have to render them in the on_draw() using function 
        // render_ctrl() because platform_support doesn't know anything about 
        // renderers you use. The controls will be also scaled automatically 
        // if they provide a proper scaling mechanism (all the controls 
        // included into the basic AGG package do).
        // If you don't need a particular control to be scaled automatically 
        // call ctrl::no_transform() after adding.
        void add_ctrl(ctrl& c) { m_ctrls.add(c); c.transform(m_resize_mtx); }

        //--------------------------------------------------------------------
        // Auxiliary functions. trans_affine_resizing() modifier sets up the resizing 
        // matrix on the basis of the given width and height and the initial
        // width and height of the window. The implementation should simply 
        // call this function every time when it catches the resizing event
        // passing in the new values of width and height of the window.
        // Nothing prevents you from "cheating" the scaling matrix if you
        // call this function from somewhere with wrong arguments. 
        // trans_affine_resizing() accessor simply returns current resizing matrix 
        // which can be used to apply additional scaling of any of your 
        // stuff when the window is being resized.
        // width(), height(), initial_width(), and initial_height() must be
        // clear to understand with no comments :-)
        void trans_affine_resizing(int width, int height)
        {
            if(m_window_flags & window_keep_aspect_ratio)
            {
                //double sx = double(width) / double(m_initial_width);
                //double sy = double(height) / double(m_initial_height);
                //if(sy < sx) sx = sy;
                //m_resize_mtx = trans_affine_scaling(sx, sx);
                trans_viewport vp;
                vp.preserve_aspect_ratio(0.5, 0.5, aspect_ratio_meet);
                vp.device_viewport(0, 0, width, height);
                vp.world_viewport(0, 0, m_initial_width, m_initial_height);
                m_resize_mtx = vp.to_affine();
            }
            else
            {
                m_resize_mtx = trans_affine_scaling(
                    double(width) / double(m_initial_width),
                    double(height) / double(m_initial_height));
            }
        }
        const    trans_affine& trans_affine_resizing() const { return m_resize_mtx; }
        double   width()  const { return m_rbuf_window.width(); }
        double   height() const { return m_rbuf_window.height(); }
        double   initial_width()  const { return m_initial_width; }
        double   initial_height() const { return m_initial_height; }
        unsigned window_flags() const { return m_window_flags; }

        //--------------------------------------------------------------------
        // Get raw display handler depending on the system. 
        // For win32 its an HDC, for other systems it can be a pointer to some
        // structure. See the implementation files for detals.
        // It's provided "as is", so, first you should check if it's not null.
        // If it's null the raw_display_handler is not supported. Also, there's 
        // no guarantee that this function is implemented, so, in some 
        // implementations you may have simply an unresolved symbol when linking.
        void* raw_display_handler();

        //--------------------------------------------------------------------
        // display message box or print the message to the console 
        // (depending on implementation)
        void message(const char* msg);

        //--------------------------------------------------------------------
        // Stopwatch functions. Function elapsed_time() returns time elapsed 
        // since the latest start_timer() invocation in millisecods. 
        // The resolutoin depends on the implementation. 
        // In Win32 it uses QueryPerformanceFrequency() / QueryPerformanceCounter().
        void   start_timer();
        double elapsed_time() const;

        //--------------------------------------------------------------------
        // Get the full file name. In most cases it simply returns
        // file_name. As it's appropriate in many systems if you open
        // a file by its name without specifying the path, it tries to 
        // open it in the current directory. The demos usually expect 
        // all the supplementary files to be placed in the current 
        // directory, that is usually coincides with the directory where
        // the the executable is. However, in some systems (BeOS) it's not so. 
        // For those kinds of systems full_file_name() can help access files 
        // preserving commonly used policy.
        // So, it's a good idea to use in the demos the following:
        // FILE* fd = fopen(full_file_name("some.file"), "r"); 
        // instead of
        // FILE* fd = fopen("some.file", "r"); 
        const char* full_file_name(const char* file_name);

    public:
        platform_specific* m_specific;
        ctrl_container m_ctrls;

        // Sorry, I'm too tired to describe the private 
        // data membders. See the implementations for different
        // platforms for details.
    private:
        platform_support(const platform_support&);
        const platform_support& operator = (const platform_support&);

        pix_format_e     m_format;
        unsigned         m_bpp;
        rendering_buffer m_rbuf_window;
        rendering_buffer m_rbuf_img[max_images];
        unsigned         m_window_flags;
        bool             m_wait_mode;
        bool             m_flip_y;
        char             m_caption[256];
        int              m_initial_width;
        int              m_initial_height;
        trans_affine     m_resize_mtx;
    };


}



#endif