1
//----------------------------------------------------------------------------
2
// Anti-Grain Geometry - Version 2.4 (Public License)
3
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5
// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
6
// Pascal Port By: Milan Marusinec alias Milano
8
// http://www.aggpas.org
9
// Copyright (c) 2005-2006
11
// Permission to copy, use, modify, sell and distribute this software
12
// is granted provided this copyright notice appears in all copies.
13
// This software is provided "as is" without express or implied
14
// warranty, and with no claim as to its suitability for any purpose.
16
//----------------------------------------------------------------------------
17
// Contact: mcseem@antigrain.com
18
// mcseemagg@yahoo.com
19
// http://www.antigrain.com
21
//----------------------------------------------------------------------------
23
// class platform_support
25
// It's not a part of the AGG library, it's just a helper class to create
26
// interactive demo examples. Since the examples should not be too complex
27
// this class is provided to support some very basic interactive graphical
28
// funtionality, such as putting the rendered image to the window, simple
29
// keyboard and mouse input, window resizing, setting the window title,
30
// and catching the "idle" events.
32
// The most popular platforms are:
36
// SDL library (see http://www.libsdl.org/)
39
// All the system dependent stuff sits in the platform_specific class.
40
// The platform_support class has just a pointer to it and it's
41
// the responsibility of the implementation to create/delete it.
42
// This class being defined in the implementation file can have
43
// any platform dependent stuff such as HWND, X11 Window and so on.
45
// [Pascal Port History] -----------------------------------------------------
47
// 23.06.2006-Milano: ptrcomp adjustments
48
// 29.03.2006-Milano: finished & tested OK
49
// 28.03.2006-Milano: platform_specific & platform_support
50
// 20.03.2006-Milano: Unit port establishment
52
{ agg_platform_support.pas }
54
agg_platform_support ;
61
X ,Xlib ,Xutil ,Xatom ,keysym ,CTypes ,SysUtils ,
65
agg_rendering_buffer ,
82
//----------------------------------------------------------window_flag_e
83
// These are flags used in method init(). Not all of them are
84
// applicable on different platforms, for example the win32_api
85
// cannot use a hardware buffer (window_hw_buffer).
86
// The implementation should simply ignore unsupported flags.
89
window_keep_aspect_ratio = 4;
90
window_process_all_keys = 8;
93
//-----------------------------------------------------------pix_format_e
94
// Possible formats of the rendering buffer. Initially I thought that it's
95
// reasonable to create the buffer and the rendering functions in
96
// accordance with the native pixel format of the system because it
97
// would have no overhead for pixel format conersion.
98
// But eventually I came to a conclusion that having a possibility to
99
// convert pixel formats on demand is a good idea. First, it was X11 where
100
// there lots of different formats and visuals and it would be great to
101
// render everything in, say, RGB-24 and display it automatically without
102
// any additional efforts. The second reason is to have a possibility to
103
// debug renderers for different pixel formats and colorspaces having only
104
// one computer and one system.
106
// This stuff is not included into the basic AGG functionality because the
107
// number of supported pixel formats (and/or colorspaces) can be great and
108
// if one needs to add new format it would be good only to add new
109
// rendering files without having to modify any existing ones (a general
110
// principle of incapsulation and isolation).
112
// Using a particular pixel format doesn't obligatory mean the necessity
113
// of software conversion. For example, win32 API can natively display
114
// gray8, 15-bit RGB, 24-bit BGR, and 32-bit BGRA formats.
115
// This list can be (and will be!) extended in future.
118
pix_format_undefined , // By default. No conversions are applied
119
pix_format_bw, // 1 bit per color B/W
120
pix_format_gray8, // Simple 256 level grayscale
121
pix_format_gray16, // Simple 65535 level grayscale
122
pix_format_rgb555, // 15 bit rgb. Depends on the byte ordering!
123
pix_format_rgb565, // 16 bit rgb. Depends on the byte ordering!
124
pix_format_rgbAAA, // 30 bit rgb. Depends on the byte ordering!
125
pix_format_rgbBBA, // 32 bit rgb. Depends on the byte ordering!
126
pix_format_bgrAAA, // 30 bit bgr. Depends on the byte ordering!
127
pix_format_bgrABB, // 32 bit bgr. Depends on the byte ordering!
128
pix_format_rgb24, // R-G-B, one byte per color component
129
pix_format_bgr24, // B-G-R, native win32 BMP format.
130
pix_format_rgba32, // R-G-B-A, one byte per color component
131
pix_format_argb32, // A-R-G-B, native MAC format
132
pix_format_abgr32, // A-B-G-R, one byte per color component
133
pix_format_bgra32, // B-G-R-A, native win32 BMP format
134
pix_format_rgb48, // R-G-B, 16 bits per color component
135
pix_format_bgr48, // B-G-R, native win32 BMP format.
136
pix_format_rgba64, // R-G-B-A, 16 bits byte per color component
137
pix_format_argb64, // A-R-G-B, native MAC format
138
pix_format_abgr64, // A-B-G-R, one byte per color component
139
pix_format_bgra64, // B-G-R-A, native win32 BMP format
141
end_of_pix_formats );
144
//-------------------------------------------------------------input_flag_e
145
// Mouse and keyboard flags. They can be different on different platforms
146
// and the ways they are obtained are also different. But in any case
147
// the system dependent flags should be mapped into these ones. The meaning
148
// of that is as follows. For example, if kbd_ctrl is set it means that the
149
// ctrl key is pressed and being held at the moment. They are also used in
150
// the overridden methods such as on_mouse_move(), on_mouse_button_down(),
151
// on_mouse_button_dbl_click(), on_mouse_button_up(), on_key().
152
// In the method on_mouse_button_up() the mouse flags have different
153
// meaning. They mean that the respective button is being released, but
154
// the meaning of the keyboard flags remains the same.
155
// There's absolut minimal set of flags is used because they'll be most
156
// probably supported on different platforms. Even the mouse_right flag
157
// is restricted because Mac's mice have only one button, but AFAIK
158
// it can be simulated with holding a special key on the keydoard.
164
//--------------------------------------------------------------key_code_e
165
// Keyboard codes. There's also a restricted set of codes that are most
166
// probably supported on different platforms. Any platform dependent codes
167
// should be converted into these ones. There're only those codes are
168
// defined that cannot be represented as printable ASCII-characters.
169
// All printable ASCII-set can be used in a regilar C/C++ manner:
170
// ' ', 'A', '0' '+' and so on.
171
// Since the clasas is used for creating very simple demo-applications
172
// we don't need very rich possibilities here, just basic ones.
173
// Actually the numeric key codes are taken from the SDL library, so,
174
// the implementation of the SDL support does not require any mapping.
175
// ASCII set. Should be supported everywhere
197
key_kp_multiply = 268;
203
// Arrow-keys and stuff
214
// Functional keys. You'd better avoid using
215
// f11...f15 in your applications if you want
216
// the applications to be portable
233
// The possibility of using these keys is
234
// very restricted. Actually it's guaranteed
235
// only in win32_api and win32_sdl implementations
243
//----------------------------------------------------------ctrl_container
244
// A helper class that contains pointers to a number of controls.
245
// This class is used to ease the event handling with controls.
246
// The implementation should simply call the appropriate methods
247
// of this class when appropriate events occure.
248
crtl_container_ptr = ^ctrl_container;
249
ctrl_container = object
250
m_ctrl : array[0..max_ctrl - 1 ] of ctrl_ptr;
252
m_num_ctrl : unsigned;
255
constructor Construct;
258
procedure add(c : ctrl_ptr );
260
function in_rect(x ,y : double ) : boolean;
262
function on_mouse_button_down(x ,y : double ) : boolean;
263
function on_mouse_button_up (x ,y : double ) : boolean;
265
function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean;
266
function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean;
268
function set_cur(x ,y : double ) : boolean;
272
//---------------------------------------------------------platform_support
273
// This class is a base one to the apllication classes. It can be used
276
// the_application = object(platform_support )
278
// constructor Construct(bpp : unsigned; flip_y : boolean );
281
// //override stuff . . .
282
// procedure on_init; virtual;
283
// procedure on_draw; virtual;
284
// procedure on_resize(sx ,sy : int ); virtual;
285
// // . . . and so on, see virtual functions
287
// //any your own stuff . . .
291
// app : the_application;
294
// app.Construct(pix_format_rgb24 ,true );
295
// app.caption ("AGG Example. Lion" );
297
// if app.init(500 ,400 ,window_resize ) then
308
platform_specific_ptr = ^platform_specific;
309
platform_specific = object
311
m_sys_format : pix_format_e;
316
m_sys_bpp : unsigned;
317
m_display : PDisplay;
324
m_window_attributes : TXSetWindowAttributes;
326
m_ximg_window : PXImage;
327
m_close_atom : TAtom;
328
m_buf_window : pointer;
329
m_buf_alloc : unsigned;
330
m_buf_img : array[0..max_images - 1 ] of pointer;
331
m_img_alloc : array[0..max_images - 1 ] of unsigned;
333
m_keymap : array[0..255 ] of unsigned;
337
m_initialized : boolean;
339
//m_wait_mode : boolean;
340
m_sw_start : clock_t;
342
constructor Construct(format : pix_format_e; flip_y : boolean );
345
procedure caption_ (capt : PChar );
346
procedure put_image(src : rendering_buffer_ptr );
350
platform_support_ptr = ^platform_support;
351
platform_support = object
352
m_specific : platform_specific_ptr;
353
m_ctrls : ctrl_container;
355
m_format : pix_format_e;
359
m_rbuf_window : rendering_buffer;
360
m_rbuf_img : array[0..max_images - 1 ] of rendering_buffer;
362
m_window_flags : unsigned;
364
m_flip_y : boolean; // flip_y - true if you want to have the Y-axis flipped vertically
365
m_caption : shortstring;
366
m_resize_mtx : trans_affine;
369
m_initial_height : int;
373
constructor Construct(format_ : pix_format_e; flip_y_ : boolean );
376
// Setting the windows caption (title). Should be able
377
// to be called at least before calling init().
378
// It's perfect if they can be called anytime.
379
procedure caption_(cap : shortstring );
381
// These 3 menthods handle working with images. The image
382
// formats are the simplest ones, such as .BMP in Windows or
383
// .ppm in Linux. In the applications the names of the files
384
// should not have any file extensions. Method load_img() can
385
// be called before init(), so, the application could be able
386
// to determine the initial size of the window depending on
387
// the size of the loaded image.
388
// The argument "idx" is the number of the image 0...max_images-1
389
function load_img (idx : unsigned; file_ : shortstring ) : boolean;
390
function save_img (idx : unsigned; file_ : shortstring ) : boolean;
391
function create_img(idx : unsigned; width_ : unsigned = 0; height_ : unsigned = 0 ) : boolean;
393
// init() and run(). See description before the class for details.
394
// The necessity of calling init() after creation is that it's
395
// impossible to call the overridden virtual function (on_init())
396
// from the constructor. On the other hand it's very useful to have
397
// some on_init() event handler when the window is created but
398
// not yet displayed. The rbuf_window() method (see below) is
399
// accessible from on_init().
400
function init(width_ ,height_ ,flags : unsigned ) : boolean;
404
// The very same parameters that were used in the constructor
405
function _format : pix_format_e;
406
function _flip_y : boolean;
407
function _bpp : unsigned;
409
// The following provides a very simple mechanism of doing someting
410
// in background. It's not multitheading. When whait_mode is true
411
// the class waits for the events and it does not ever call on_idle().
412
// When it's false it calls on_idle() when the event queue is empty.
413
// The mode can be changed anytime. This mechanism is satisfactory
414
// for creation very simple animations.
415
function _wait_mode : boolean;
416
procedure wait_mode_(wait_mode : boolean );
418
// These two functions control updating of the window.
419
// force_redraw() is an analog of the Win32 InvalidateRect() function.
420
// Being called it sets a flag (or sends a message) which results
421
// in calling on_draw() and updating the content of the window
422
// when the next event cycle comes.
423
// update_window() results in just putting immediately the content
424
// of the currently rendered buffer to the window without calling
426
procedure force_redraw;
427
procedure update_window;
429
// So, finally, how to draw anythig with AGG? Very simple.
430
// rbuf_window() returns a reference to the main rendering
431
// buffer which can be attached to any rendering class.
432
// rbuf_img() returns a reference to the previously created
433
// or loaded image buffer (see load_img()). The image buffers
434
// are not displayed directly, they should be copied to or
435
// combined somehow with the rbuf_window(). rbuf_window() is
436
// the only buffer that can be actually displayed.
437
function rbuf_window : rendering_buffer_ptr;
438
function rbuf_img(idx : unsigned ) : rendering_buffer_ptr;
440
// Returns file extension used in the implemenation for the particular
442
function _img_ext : shortstring;
445
procedure copy_img_to_window(idx : unsigned );
446
procedure copy_window_to_img(idx : unsigned );
447
procedure copy_img_to_img (idx_to ,idx_from : unsigned );
449
// Event handlers. They are not pure functions, so you don't have
450
// to override them all.
451
// In my demo applications these functions are defined inside
452
// the the_application class
453
procedure on_init; virtual;
454
procedure on_resize(sx ,sy : int ); virtual;
455
procedure on_idle; virtual;
457
procedure on_mouse_move(x ,y : int; flags : unsigned ); virtual;
459
procedure on_mouse_button_down(x ,y : int; flags : unsigned ); virtual;
460
procedure on_mouse_button_up (x ,y : int; flags : unsigned ); virtual;
462
procedure on_key(x ,y : int; key ,flags : unsigned ); virtual;
463
procedure on_ctrl_change; virtual;
464
procedure on_draw; virtual;
465
procedure on_post_draw(raw_handler : pointer ); virtual;
467
// Adding control elements. A control element once added will be
468
// working and reacting to the mouse and keyboard events. Still, you
469
// will have to render them in the on_draw() using function
470
// render_ctrl() because platform_support doesn't know anything about
471
// renderers you use. The controls will be also scaled automatically
472
// if they provide a proper scaling mechanism (all the controls
473
// included into the basic AGG package do).
474
// If you don't need a particular control to be scaled automatically
475
// call ctrl::no_transform() after adding.
476
procedure add_ctrl(c : ctrl_ptr );
478
// Auxiliary functions. trans_affine_resizing() modifier sets up the resizing
479
// matrix on the basis of the given width and height and the initial
480
// width and height of the window. The implementation should simply
481
// call this function every time when it catches the resizing event
482
// passing in the new values of width and height of the window.
483
// Nothing prevents you from "cheating" the scaling matrix if you
484
// call this function from somewhere with wrong arguments.
485
// trans_affine_resizing() accessor simply returns current resizing matrix
486
// which can be used to apply additional scaling of any of your
487
// stuff when the window is being resized.
488
// width(), height(), initial_width(), and initial_height() must be
489
// clear to understand with no comments :-)
490
procedure trans_affine_resizing_(width_ ,height_ : int );
491
function _trans_affine_resizing : trans_affine_ptr;
493
function _width : double;
494
function _height : double;
495
function _initial_width : double;
496
function _initial_height : double;
497
function _window_flags : unsigned;
499
// Get raw display handler depending on the system.
500
// For win32 its an HDC, for other systems it can be a pointer to some
501
// structure. See the implementation files for detals.
502
// It's provided "as is", so, first you should check if it's not null.
503
// If it's null the raw_display_handler is not supported. Also, there's
504
// no guarantee that this function is implemented, so, in some
505
// implementations you may have simply an unresolved symbol when linking.
506
function _raw_display_handler : pointer;
508
// display message box or print the message to the console
509
// (depending on implementation)
510
procedure message_(msg : PChar );
512
// Stopwatch functions. Function elapsed_time() returns time elapsed
513
// since the latest start_timer() invocation in millisecods.
514
// The resolutoin depends on the implementation.
515
// In Win32 it uses QueryPerformanceFrequency() / QueryPerformanceCounter().
516
procedure start_timer;
517
function elapsed_time : double;
519
// Get the full file name. In most cases it simply returns
520
// file_name. As it's appropriate in many systems if you open
521
// a file by its name without specifying the path, it tries to
522
// open it in the current directory. The demos usually expect
523
// all the supplementary files to be placed in the current
524
// directory, that is usually coincides with the directory where
525
// the the executable is. However, in some systems (BeOS) it's not so.
526
// For those kinds of systems full_file_name() can help access files
527
// preserving commonly used policy.
528
// So, it's a good idea to use in the demos the following:
529
// FILE* fd = fopen(full_file_name("some.file"), "r");
531
// FILE* fd = fopen("some.file", "r");
532
function full_file_name(file_name : shortstring ) : shortstring;
533
function file_source (path ,fname : shortstring ) : shortstring;
537
{ GLOBAL PROCEDURES }
541
{ LOCAL VARIABLES & CONSTANTS }
542
{ UNIT IMPLEMENTATION }
544
constructor ctrl_container.Construct;
552
destructor ctrl_container.Destruct;
557
procedure ctrl_container.add;
559
if m_num_ctrl < max_ctrl then
561
m_ctrl[m_num_ctrl ]:=c;
570
function ctrl_container.in_rect;
577
if m_num_ctrl > 0 then
578
for i:=0 to m_num_ctrl - 1 do
579
if m_ctrl[i ].in_rect(x ,y ) then
589
{ ON_MOUSE_BUTTON_DOWN }
590
function ctrl_container.on_mouse_button_down;
597
if m_num_ctrl > 0 then
598
for i:=0 to m_num_ctrl - 1 do
599
if m_ctrl[i ].on_mouse_button_down(x ,y ) then
609
{ ON_MOUSE_BUTTON_UP }
610
function ctrl_container.on_mouse_button_up;
617
if m_num_ctrl > 0 then
618
for i:=0 to m_num_ctrl - 1 do
619
if m_ctrl[i ].on_mouse_button_up(x ,y ) then
630
function ctrl_container.on_mouse_move;
637
if m_num_ctrl > 0 then
638
for i:=0 to m_num_ctrl - 1 do
639
if m_ctrl[i ].on_mouse_move(x ,y ,button_flag ) then
650
function ctrl_container.on_arrow_keys;
654
if m_cur_ctrl >= 0 then
655
result:=m_ctrl[m_cur_ctrl ].on_arrow_keys(left ,right ,down ,up );
660
function ctrl_container.set_cur;
667
if m_num_ctrl > 0 then
668
for i:=0 to m_num_ctrl - 1 do
669
if m_ctrl[i ].in_rect(x ,y ) then
671
if m_cur_ctrl <> i then
683
if m_cur_ctrl <> -1 then
694
constructor platform_specific.Construct;
700
m_sys_format:=pix_format_undefined;
701
m_byte_order:=LSBFirst;
720
m_initialized:=false;
723
fillchar(m_buf_img[0 ] ,sizeof(m_buf_img ) ,0 );
728
m_keymap[XK_Pause and $FF ]:=key_pause;
729
m_keymap[XK_Clear and $FF ]:=key_clear;
731
m_keymap[XK_KP_0 and $FF ]:=key_kp0;
732
m_keymap[XK_KP_1 and $FF ]:=key_kp1;
733
m_keymap[XK_KP_2 and $FF ]:=key_kp2;
734
m_keymap[XK_KP_3 and $FF ]:=key_kp3;
735
m_keymap[XK_KP_4 and $FF ]:=key_kp4;
736
m_keymap[XK_KP_5 and $FF ]:=key_kp5;
737
m_keymap[XK_KP_6 and $FF ]:=key_kp6;
738
m_keymap[XK_KP_7 and $FF ]:=key_kp7;
739
m_keymap[XK_KP_8 and $FF ]:=key_kp8;
740
m_keymap[XK_KP_9 and $FF ]:=key_kp9;
742
m_keymap[XK_KP_Insert and $FF ] :=key_kp0;
743
m_keymap[XK_KP_End and $FF ] :=key_kp1;
744
m_keymap[XK_KP_Down and $FF ] :=key_kp2;
745
m_keymap[XK_KP_Page_Down and $FF ]:=key_kp3;
746
m_keymap[XK_KP_Left and $FF ] :=key_kp4;
747
m_keymap[XK_KP_Begin and $FF ] :=key_kp5;
748
m_keymap[XK_KP_Right and $FF ] :=key_kp6;
749
m_keymap[XK_KP_Home and $FF ] :=key_kp7;
750
m_keymap[XK_KP_Up and $FF ] :=key_kp8;
751
m_keymap[XK_KP_Page_Up and $FF ] :=key_kp9;
752
m_keymap[XK_KP_Delete and $FF ] :=key_kp_period;
753
m_keymap[XK_KP_Decimal and $FF ] :=key_kp_period;
754
m_keymap[XK_KP_Divide and $FF ] :=key_kp_divide;
755
m_keymap[XK_KP_Multiply and $FF ] :=key_kp_multiply;
756
m_keymap[XK_KP_Subtract and $FF ] :=key_kp_minus;
757
m_keymap[XK_KP_Add and $FF ] :=key_kp_plus;
758
m_keymap[XK_KP_Enter and $FF ] :=key_kp_enter;
759
m_keymap[XK_KP_Equal and $FF ] :=key_kp_equals;
761
m_keymap[XK_Up and $FF ] :=key_up;
762
m_keymap[XK_Down and $FF ] :=key_down;
763
m_keymap[XK_Right and $FF ] :=key_right;
764
m_keymap[XK_Left and $FF ] :=key_left;
765
m_keymap[XK_Insert and $FF ] :=key_insert;
766
m_keymap[XK_Home and $FF ] :=key_delete;
767
m_keymap[XK_End and $FF ] :=key_end;
768
m_keymap[XK_Page_Up and $FF ] :=key_page_up;
769
m_keymap[XK_Page_Down and $FF ]:=key_page_down;
771
m_keymap[XK_F1 and $FF ] :=key_f1;
772
m_keymap[XK_F2 and $FF ] :=key_f2;
773
m_keymap[XK_F3 and $FF ] :=key_f3;
774
m_keymap[XK_F4 and $FF ] :=key_f4;
775
m_keymap[XK_F5 and $FF ] :=key_f5;
776
m_keymap[XK_F6 and $FF ] :=key_f6;
777
m_keymap[XK_F7 and $FF ] :=key_f7;
778
m_keymap[XK_F8 and $FF ] :=key_f8;
779
m_keymap[XK_F9 and $FF ] :=key_f9;
780
m_keymap[XK_F10 and $FF ]:=key_f10;
781
m_keymap[XK_F11 and $FF ]:=key_f11;
782
m_keymap[XK_F12 and $FF ]:=key_f12;
783
m_keymap[XK_F13 and $FF ]:=key_f13;
784
m_keymap[XK_F14 and $FF ]:=key_f14;
785
m_keymap[XK_F15 and $FF ]:=key_f15;
787
m_keymap[XK_Num_Lock and $FF ] :=key_numlock;
788
m_keymap[XK_Caps_Lock and $FF ] :=key_capslock;
789
m_keymap[XK_Scroll_Lock and $FF ]:=key_scrollock;
816
destructor platform_specific.Destruct;
821
procedure platform_specific.caption_;
826
tp.value :=PCUChar(@capt[1 ] );
827
tp.encoding:=XA_WM_NAME;
829
tp.nitems :=strlen(capt );
831
XSetWMName (m_display ,m_window ,@tp );
832
XStoreName (m_display ,m_window ,capt );
833
XSetIconName (m_display ,m_window ,capt );
834
XSetWMIconName(m_display ,m_window ,@tp );
839
procedure platform_specific.put_image;
844
rbuf_tmp : rendering_buffer;
847
if m_ximg_window = NIL then
850
m_ximg_window.data:=m_buf_window;
852
if m_format = m_sys_format then
864
row_len:=src._width * m_sys_bpp div 8;
866
agg_getmem(buf_tmp ,row_len * src._height );
886
pix_format_rgb555 : color_conv(@rbuf_tmp ,src ,color_conv_rgb555_to_rgb555 );
887
pix_format_rgb565 : color_conv(@rbuf_tmp ,src ,color_conv_rgb565_to_rgb555 );
888
//pix_format_rgb24 : color_conv(@rbuf_tmp ,src ,color_conv_rgb24_to_rgb555 );
889
pix_format_bgr24 : color_conv(@rbuf_tmp ,src ,color_conv_bgr24_to_rgb555 );
890
//pix_format_rgba32 : color_conv(@rbuf_tmp ,src ,color_conv_rgba32_to_rgb555 );
891
//pix_format_argb32 : color_conv(@rbuf_tmp ,src ,color_conv_argb32_to_rgb555 );
892
pix_format_bgra32 : color_conv(@rbuf_tmp ,src ,color_conv_bgra32_to_rgb555 );
893
//pix_format_abgr32 : color_conv(@rbuf_tmp ,src ,color_conv_abgr32_to_rgb555 );
899
pix_format_rgb555 : color_conv(@rbuf_tmp ,src ,color_conv_rgb555_to_rgb565 );
900
//pix_format_rgb565 : color_conv(@rbuf_tmp ,src ,color_conv_rgb565_to_rgb565 );
901
//pix_format_rgb24 : color_conv(@rbuf_tmp ,src ,color_conv_rgb24_to_rgb565 );
902
pix_format_bgr24 : color_conv(@rbuf_tmp ,src ,color_conv_bgr24_to_rgb565 );
903
//pix_format_rgba32 : color_conv(@rbuf_tmp ,src ,color_conv_rgba32_to_rgb565 );
904
//pix_format_argb32 : color_conv(@rbuf_tmp ,src ,color_conv_argb32_to_rgb565 );
905
pix_format_bgra32 : color_conv(@rbuf_tmp ,src ,color_conv_bgra32_to_rgb565 );
906
//pix_format_abgr32 : color_conv(@rbuf_tmp ,src ,color_conv_abgr32_to_rgb565 );
912
pix_format_rgb555 : color_conv(@rbuf_tmp ,src ,color_conv_rgb555_to_rgba32 );
913
//pix_format_rgb565 : color_conv(@rbuf_tmp ,src ,color_conv_rgb565_to_rgba32 );
914
//pix_format_rgb24 : color_conv(@rbuf_tmp ,src ,color_conv_rgb24_to_rgba32 );
915
pix_format_bgr24 : color_conv(@rbuf_tmp ,src ,color_conv_bgr24_to_rgba32 );
916
//pix_format_rgba32 : color_conv(@rbuf_tmp ,src ,color_conv_rgba32_to_rgba32 );
917
//pix_format_argb32 : color_conv(@rbuf_tmp ,src ,color_conv_argb32_to_rgba32 );
918
pix_format_bgra32 : color_conv(@rbuf_tmp ,src ,color_conv_bgra32_to_rgba32 );
919
//pix_format_abgr32 : color_conv(@rbuf_tmp ,src ,color_conv_abgr32_to_rgba32 );
925
pix_format_rgb555 : color_conv(@rbuf_tmp ,src ,color_conv_rgb555_to_abgr32 );
926
//pix_format_rgb565 : color_conv(@rbuf_tmp ,src ,color_conv_rgb565_to_abgr32 );
927
//pix_format_rgb24 : color_conv(@rbuf_tmp ,src ,color_conv_rgb24_to_abgr32 );
928
pix_format_bgr24 : color_conv(@rbuf_tmp ,src ,color_conv_bgr24_to_abgr32 );
929
//pix_format_abgr32 : color_conv(@rbuf_tmp ,src ,color_conv_abgr32_to_abgr32 );
930
//pix_format_rgba32 : color_conv(@rbuf_tmp ,src ,color_conv_rgba32_to_abgr32 );
931
//pix_format_argb32 : color_conv(@rbuf_tmp ,src ,color_conv_argb32_to_abgr32 );
932
pix_format_bgra32 : color_conv(@rbuf_tmp ,src ,color_conv_bgra32_to_abgr32 );
938
pix_format_rgb555 : color_conv(@rbuf_tmp ,src ,color_conv_rgb555_to_argb32 );
939
//pix_format_rgb565 : color_conv(@rbuf_tmp ,src ,color_conv_rgb565_to_argb32 );
940
//pix_format_rgb24 : color_conv(@rbuf_tmp ,src ,color_conv_rgb24_to_argb32 );
941
pix_format_bgr24 : color_conv(@rbuf_tmp ,src ,color_conv_bgr24_to_argb32 );
942
pix_format_rgba32 : color_conv(@rbuf_tmp ,src ,color_conv_rgba32_to_argb32 );
943
//pix_format_argb32 : color_conv(@rbuf_tmp ,src ,color_conv_argb32_to_argb32 );
944
pix_format_abgr32 : color_conv(@rbuf_tmp ,src ,color_conv_abgr32_to_argb32 );
945
pix_format_bgra32 : color_conv(@rbuf_tmp ,src ,color_conv_bgra32_to_argb32 );
951
pix_format_rgb555 : color_conv(@rbuf_tmp ,src ,color_conv_rgb555_to_bgra32 );
952
//pix_format_rgb565 : color_conv(@rbuf_tmp ,src ,color_conv_rgb565_to_bgra32 );
953
//pix_format_rgb24 : color_conv(@rbuf_tmp ,src ,color_conv_rgb24_to_bgra32 );
954
pix_format_bgr24 : color_conv(@rbuf_tmp ,src ,color_conv_bgr24_to_bgra32 );
955
pix_format_rgba32 : color_conv(@rbuf_tmp ,src ,color_conv_rgba32_to_bgra32 );
956
pix_format_argb32 : color_conv(@rbuf_tmp ,src ,color_conv_argb32_to_bgra32 );
957
pix_format_abgr32 : color_conv(@rbuf_tmp ,src ,color_conv_abgr32_to_bgra32 );
958
pix_format_bgra32 : color_conv(@rbuf_tmp ,src ,color_conv_bgra32_to_bgra32 );
964
m_ximg_window.data:=buf_tmp;
975
agg_freemem(buf_tmp ,row_len * src._height );
984
constructor platform_support.Construct;
988
p ,n ,x : shortstring;
991
new(m_specific ,Construct(format_ ,flip_y_ ) );
994
m_rbuf_window.Construct;
996
for i:=0 to max_images - 1 do
997
m_rbuf_img[i ].Construct;
999
m_resize_mtx.Construct;
1003
m_bpp:=m_specific.m_bpp;
1009
m_initial_width :=10;
1010
m_initial_height:=10;
1012
m_caption:='Anti-Grain Geometry Application'#0;
1014
// Change working dir to the application one
1015
spread_name(ParamStr(0 ) ,p ,n ,x );
1020
// libc.__chdir(PChar(@p[1 ] ) );
1025
destructor platform_support.Destruct;
1030
dispose(m_specific ,Destruct );
1033
m_rbuf_window.Destruct;
1035
for i:=0 to max_images - 1 do
1036
m_rbuf_img[i ].Destruct;
1041
procedure platform_support.caption_;
1043
m_caption:=cap + #0;
1045
dec(byte(m_caption[0 ] ) );
1047
if m_specific.m_initialized then
1048
m_specific.caption_(PChar(@m_caption[1 ] ) );
1053
function isdigit(c : char ) : boolean;
1067
function atoi(c : char_ptr ) : int;
1094
function platform_support.load_img;
1097
buf : array[0..1023 ] of char;
1102
width ,height : unsigned;
1105
rbuf_img_ : rendering_buffer;
1110
if idx < max_images then
1112
file_:=file_ + _img_ext;
1114
if not file_exists(file_ ) then
1115
file_:='ppm/' + file_;
1117
AssignFile(fd ,file_ );
1120
if IOResult <> 0 then
1123
blockread(fd ,buf ,1022 ,len );
1134
if (buf[0 ] <> 'P' ) and
1135
(buf[1 ] <> '6' ) then
1144
while (ptr^ <> #0 ) and
1145
not isdigit(ptr^ ) do
1146
inc(ptrcomp(ptr ) );
1158
(width > 4096 ) then
1165
while (ptr^ <> #0 ) and
1167
inc(ptrcomp(ptr ) );
1169
while (ptr^ <> #0 ) and
1170
not isdigit(ptr^ ) do
1171
inc(ptrcomp(ptr ) );
1183
(height > 4096 ) then
1190
while (ptr^ <> #0 ) and
1192
inc(ptrcomp(ptr ) );
1194
while (ptr^ <> #0 ) and
1195
not isdigit(ptr^ ) do
1196
inc(ptrcomp(ptr ) );
1198
if atoi(ptr ) <> 255 then
1205
while (ptr^ <> #0 ) and
1207
inc(ptrcomp(ptr ) );
1216
inc (ptrcomp(ptr ) );
1217
seek (fd ,ptrcomp(ptr ) - ptrcomp(@buf ) );
1218
create_img(idx ,width ,height );
1222
if m_format = pix_format_rgb24 then
1223
blockread(fd ,m_specific.m_buf_img[idx ]^ ,width * height * 3 )
1226
agg_getmem(buf_img ,width * height * 3 );
1228
rbuf_img_.Construct;
1231
rbuf_img_.attach(buf_img ,width ,height ,-width * 3 )
1233
rbuf_img_.attach(buf_img ,width ,height ,width * 3 );
1235
blockread(fd ,buf_img^ ,width * height * 3 );
1238
//pix_format_rgb555 : color_conv(@m_rbuf_img[idx ] ,@rbuf_img_ ,color_conv_rgb24_to_rgb555 );
1239
//pix_format_rgb565 : color_conv(@m_rbuf_img[idx ] ,@rbuf_img_ ,color_conv_rgb24_to_rgb565 );
1240
pix_format_bgr24 : color_conv(@m_rbuf_img[idx ] ,@rbuf_img_ ,color_conv_rgb24_to_bgr24 );
1241
//pix_format_rgba32 : color_conv(@m_rbuf_img[idx ] ,@rbuf_img_ ,color_conv_rgb24_to_rgba32 );
1242
//pix_format_argb32 : color_conv(@m_rbuf_img[idx ] ,@rbuf_img_ ,color_conv_rgb24_to_argb32 );
1243
pix_format_bgra32 : color_conv(@m_rbuf_img[idx ] ,@rbuf_img_ ,color_conv_rgb24_to_bgra32 );
1244
//pix_format_abgr32 : color_conv(@m_rbuf_img[idx ] ,@rbuf_img_ ,color_conv_rgb24_to_abgr32 );
1250
agg_freemem(buf_img ,width * height * 3 );
1265
function platform_support.save_img;
1273
tmp_buf ,src : pointer;
1278
if (idx < max_images ) and
1279
(rbuf_img(idx )._buf <> NIL ) then
1281
AssignFile(fd ,file_ );
1284
if IOResult <> 0 then
1287
w:=rbuf_img(idx )._width;
1288
h:=rbuf_img(idx )._height;
1292
s:='P6'#13 + c + ' ';
1296
s:=s + c + #13'255'#13;
1298
blockwrite(fd ,s[1 ] ,length(s ) );
1300
agg_getmem(tmp_buf ,w * 3 );
1304
while y < rbuf_img(idx )._height do
1307
src:=rbuf_img(idx ).row(h - 1 - y )
1309
src:=rbuf_img(idx ).row(y );
1312
pix_format_rgb555 : color_conv_rgb555_to_rgb24(tmp_buf ,src ,w );
1313
//pix_format_rgb565 : color_conv_rgb565_to_rgb24(tmp_buf ,src ,w );
1314
pix_format_bgr24 : color_conv_bgr24_to_rgb24 (tmp_buf ,src ,w );
1315
//pix_format_rgb24 : color_conv_rgb24_to_rgb24 (tmp_buf ,src ,w );
1316
//pix_format_rgba32 : color_conv_rgba32_to_rgb24(tmp_buf ,src ,w );
1317
//pix_format_argb32 : color_conv_argb32_to_rgb24(tmp_buf ,src ,w );
1318
pix_format_bgra32 : color_conv_bgra32_to_rgb24(tmp_buf ,src ,w );
1319
//pix_format_abgr32 : color_conv_abgr32_to_rgb24(tmp_buf ,src ,w );
1323
blockwrite(fd ,tmp_buf^ ,w * 3 );
1328
agg_getmem(tmp_buf ,w * 3 );
1338
function platform_support.create_img;
1342
if idx < max_images then
1345
width_:=trunc(rbuf_window._width );
1348
height_:=trunc(rbuf_window._height );
1350
agg_freemem(m_specific.m_buf_img[idx ] ,m_specific.m_img_alloc[idx ] );
1352
m_specific.m_img_alloc[idx ]:=width_ * height_ * (m_bpp div 8 );
1354
agg_getmem(m_specific.m_buf_img[idx ] ,m_specific.m_img_alloc[idx ] );
1357
m_rbuf_img[idx ].attach(
1358
m_specific.m_buf_img[idx ] ,
1360
-width_ * (m_bpp div 8 ) )
1362
m_rbuf_img[idx ].attach(
1363
m_specific.m_buf_img[idx ] ,
1365
width_ * (m_bpp div 8 ) );
1374
function platform_support.init;
1377
PointerMotionMask or
1379
ButtonReleaseMask or
1382
StructureNotifyMask;
1385
r_mask ,g_mask ,b_mask ,window_mask : unsigned;
1387
t ,hw_byte_order : int;
1389
hints : PXSizeHints;
1392
m_window_flags:=flags;
1394
m_specific.m_display:=XOpenDisplay(NIL );
1396
if m_specific.m_display = NIL then
1398
writeln(stderr ,'Unable to open DISPLAY!' );
1406
m_specific.m_screen:=XDefaultScreen(m_specific.m_display );
1407
m_specific.m_depth :=XDefaultDepth (m_specific.m_display ,m_specific.m_screen );
1408
m_specific.m_visual:=XDefaultVisual(m_specific.m_display ,m_specific.m_screen );
1410
r_mask:=m_specific.m_visual.red_mask;
1411
g_mask:=m_specific.m_visual.green_mask;
1412
b_mask:=m_specific.m_visual.blue_mask;
1414
if (m_specific.m_depth < 15 ) or
1419
writeln(stderr ,'There''s no Visual compatible with minimal AGG requirements:' );
1420
writeln(stderr ,'At least 15-bit color depth and True- or DirectColor class.' );
1423
XCloseDisplay(m_specific.m_display );
1433
hw_byte_order:=LSBFirst;
1435
if byte(pointer(@t )^ ) = 0 then
1436
hw_byte_order:=MSBFirst;
1438
// Perceive SYS-format by mask
1439
case m_specific.m_depth of
1442
m_specific.m_sys_bpp:=16;
1444
if (r_mask = $7C00 ) and
1445
(g_mask = $3E0 ) and
1446
(b_mask = $1F ) then
1448
m_specific.m_sys_format:=pix_format_rgb555;
1449
m_specific.m_byte_order:=hw_byte_order;
1457
m_specific.m_sys_bpp:=16;
1459
if (r_mask = $F800 ) and
1460
(g_mask = $7E0 ) and
1461
(b_mask = $1F ) then
1463
m_specific.m_sys_format:=pix_format_rgb565;
1464
m_specific.m_byte_order:=hw_byte_order;
1472
m_specific.m_sys_bpp:=32;
1474
if g_mask = $FF00 then
1476
if (r_mask = $FF ) and
1477
(b_mask = $FF0000 ) then
1478
case m_specific.m_format of
1481
m_specific.m_sys_format:=pix_format_rgba32;
1482
m_specific.m_byte_order:=LSBFirst;
1488
m_specific.m_sys_format:=pix_format_abgr32;
1489
m_specific.m_byte_order:=MSBFirst;
1495
m_specific.m_byte_order:=hw_byte_order;
1497
if hw_byte_order = LSBFirst then
1498
m_specific.m_sys_format:=pix_format_rgba32
1500
m_specific.m_sys_format:=pix_format_abgr32;
1506
if (r_mask = $FF0000 ) and
1507
(b_mask = $FF ) then
1508
case m_specific.m_format of
1511
m_specific.m_sys_format:=pix_format_argb32;
1512
m_specific.m_byte_order:=MSBFirst;
1518
m_specific.m_sys_format:=pix_format_bgra32;
1519
m_specific.m_byte_order:=LSBFirst;
1525
m_specific.m_byte_order:=hw_byte_order;
1527
if hw_byte_order = MSBFirst then
1528
m_specific.m_sys_format:=pix_format_argb32
1530
m_specific.m_sys_format:=pix_format_bgra32;
1542
if m_specific.m_sys_format = pix_format_undefined then
1544
writeln(stderr ,'RGB masks are not compatible with AGG pixel formats:' );
1545
write (stderr ,'R=' ,r_mask ,'G=' ,g_mask ,'B=' ,b_mask );
1547
XCloseDisplay(m_specific.m_display );
1556
m_specific.m_window_attributes ,
1557
sizeof(m_specific.m_window_attributes ) ,0 );
1559
m_specific.m_window_attributes.border_pixel:=
1560
XBlackPixel(m_specific.m_display ,m_specific.m_screen );
1562
m_specific.m_window_attributes.background_pixel:=
1563
XWhitePixel(m_specific.m_display ,m_specific.m_screen );
1565
m_specific.m_window_attributes.override_redirect:=xfalse;
1567
window_mask:=CWBackPixel or CWBorderPixel;
1569
m_specific.m_window:=
1571
m_specific.m_display ,
1572
XDefaultRootWindow(m_specific.m_display ) ,
1576
m_specific.m_depth ,
1580
@m_specific.m_window_attributes );
1582
m_specific.m_gc:=XCreateGC(m_specific.m_display ,m_specific.m_window ,0 ,0 );
1584
m_specific.m_buf_alloc:=width_ * height_ * (m_bpp div 8 );
1586
agg_getmem(m_specific.m_buf_window ,m_specific.m_buf_alloc );
1587
fillchar (m_specific.m_buf_window^ ,m_specific.m_buf_alloc ,255 );
1590
m_rbuf_window.attach(
1591
m_specific.m_buf_window ,
1593
-width_ * (m_bpp div 8 ) )
1595
m_rbuf_window.attach(
1596
m_specific.m_buf_window ,
1598
width_ * (m_bpp div 8 ) );
1600
m_specific.m_ximg_window:=
1602
m_specific.m_display ,
1603
m_specific.m_visual , //CopyFromParent,
1604
m_specific.m_depth ,
1607
m_specific.m_buf_window ,
1609
m_specific.m_sys_bpp ,
1610
width_ * (m_specific.m_sys_bpp div 8 ) );
1612
m_specific.m_ximg_window.byte_order:=m_specific.m_byte_order;
1614
m_specific.caption_(PChar(@m_caption[1 ] ) );
1616
m_initial_width :=width_;
1617
m_initial_height:=height_;
1619
if not m_specific.m_initialized then
1623
m_specific.m_initialized:=true;
1627
trans_affine_resizing_(width_ ,height_ );
1629
on_resize(width_ ,height_ );
1631
m_specific.m_update_flag:=true;
1633
hints:=XAllocSizeHints;
1635
if hints <> NIL then
1637
if flags and window_resize <> 0 then
1639
hints.min_width :=32;
1640
hints.min_height:=32;
1641
hints.max_width :=4096;
1642
hints.max_height:=4096;
1647
hints.min_width :=width_;
1648
hints.min_height:=height_;
1649
hints.max_width :=width_;
1650
hints.max_height:=height_;
1654
hints.flags:=PMaxSize or PMinSize;
1656
XSetWMNormalHints(m_specific.m_display ,m_specific.m_window ,hints );
1661
XMapWindow (m_specific.m_display ,m_specific.m_window );
1662
XSelectInput(m_specific.m_display ,m_specific.m_window ,xevent_mask );
1664
m_specific.m_close_atom:=
1665
XInternAtom(m_specific.m_display ,'WM_DELETE_WINDOW' ,false );
1668
m_specific.m_display ,
1669
m_specific.m_window ,
1670
@m_specific.m_close_atom ,1 );
1677
function platform_support.run;
1679
flags ,i : unsigned;
1681
cur_x ,cur_y ,width ,height : int;
1683
x_event ,te : TXEvent;
1687
left ,up ,right ,down : boolean;
1690
XFlush(m_specific.m_display );
1696
if m_specific.m_update_flag then
1701
m_specific.m_update_flag:=false;
1705
if not m_wait_mode then
1706
if XPending(m_specific.m_display ) = 0 then
1713
XNextEvent(m_specific.m_display ,@x_event );
1715
// In the Idle mode discard all intermediate MotionNotify events
1716
if not m_wait_mode and
1717
(x_event._type = MotionNotify ) then
1722
if XPending(m_specific.m_display ) = 0 then
1725
XNextEvent(m_specific.m_display ,@te );
1727
if te._type <> MotionNotify then
1736
case x_event._type of
1738
if (x_event.xconfigure.width <> trunc(m_rbuf_window._width ) ) or
1739
(x_event.xconfigure.height <> trunc(m_rbuf_window._height ) ) then
1741
width :=x_event.xconfigure.width;
1742
height:=x_event.xconfigure.height;
1744
agg_freemem(m_specific.m_buf_window ,m_specific.m_buf_alloc );
1746
m_specific.m_ximg_window.data:=0;
1748
XDestroyImage(m_specific.m_ximg_window );
1750
m_specific.m_buf_alloc:=width * height * (m_bpp div 8 );
1752
agg_getmem(m_specific.m_buf_window ,m_specific.m_buf_alloc );
1755
m_rbuf_window.attach(
1756
m_specific.m_buf_window ,
1758
-width * (m_bpp div 8 ) )
1760
m_rbuf_window.attach(
1761
m_specific.m_buf_window ,
1763
width * (m_bpp div 8 ) );
1765
m_specific.m_ximg_window:=
1766
XCreateImage(m_specific.m_display ,
1767
m_specific.m_visual , //CopyFromParent,
1768
m_specific.m_depth ,
1771
m_specific.m_buf_window ,
1773
m_specific.m_sys_bpp ,
1774
width * (m_specific.m_sys_bpp div 8 ) );
1776
m_specific.m_ximg_window.byte_order:=m_specific.m_byte_order;
1778
trans_affine_resizing_(width ,height );
1780
on_resize(width ,height );
1788
m_specific.put_image(@m_rbuf_window );
1790
XFlush(m_specific.m_display );
1791
XSync (m_specific.m_display ,false );
1797
key :=XLookupKeysym(@x_event.xkey ,0 );
1800
if x_event.xkey.state and Button1Mask <> 0 then
1801
flags:=flags or mouse_left;
1803
if x_event.xkey.state and Button3Mask <> 0 then
1804
flags:=flags or mouse_right;
1806
if x_event.xkey.state and ShiftMask <> 0 then
1807
flags:=flags or kbd_shift;
1809
if x_event.xkey.state and ControlMask <> 0 then
1810
flags:=flags or kbd_ctrl;
1817
case m_specific.m_keymap[key and $FF ] of
1818
key_left : left :=true;
1820
key_right : right:=true;
1821
key_down : down :=true;
1825
copy_window_to_img(max_images - 1 );
1826
save_img (max_images - 1 ,'screenshot.ppm' );
1832
if m_ctrls.on_arrow_keys(left ,right ,down ,up ) then
1842
trunc(m_rbuf_window._height ) - x_event.xkey.y ,
1843
m_specific.m_keymap[key and $FF ] ,flags )
1848
m_specific.m_keymap[key and $FF ] ,flags )
1856
if x_event.xbutton.state and ShiftMask <> 0 then
1857
flags:=flags or kbd_shift;
1859
if x_event.xbutton.state and ControlMask <> 0 then
1860
flags:=flags or kbd_ctrl;
1862
if x_event.xbutton.button = Button1 then
1863
flags:=flags or mouse_left;
1865
if x_event.xbutton.button = Button3 then
1866
flags:=flags or mouse_right;
1868
cur_x:=x_event.xbutton.x;
1871
cur_y:=trunc(m_rbuf_window._height ) - x_event.xbutton.y
1873
cur_y:=x_event.xbutton.y;
1875
if flags and mouse_left <> 0 then
1876
if m_ctrls.on_mouse_button_down(cur_x ,cur_y ) then
1878
m_ctrls.set_cur(cur_x ,cur_y );
1884
if m_ctrls.in_rect(cur_x ,cur_y ) then
1885
if m_ctrls.set_cur(cur_x ,cur_y ) then
1893
on_mouse_button_down(cur_x ,cur_y ,flags );
1895
if flags and mouse_right <> 0 then
1896
on_mouse_button_down(cur_x ,cur_y ,flags );
1898
//m_specific.m_wait_mode:=m_wait_mode;
1899
//m_wait_mode :=true;
1907
if x_event.xmotion.state and Button1Mask <> 0 then
1908
flags:=flags or mouse_left;
1910
if x_event.xmotion.state and Button3Mask <> 0 then
1911
flags:=flags or mouse_right;
1913
if x_event.xmotion.state and ShiftMask <> 0 then
1914
flags:=flags or kbd_shift;
1916
if x_event.xmotion.state and ControlMask <> 0 then
1917
flags:=flags or kbd_ctrl;
1919
cur_x:=x_event.xbutton.x;
1922
cur_y:=trunc(m_rbuf_window._height ) - x_event.xbutton.y
1924
cur_y:=x_event.xbutton.y;
1926
if m_ctrls.on_mouse_move(cur_x ,cur_y ,flags and mouse_left <> 0 ) then
1933
if not m_ctrls.in_rect(cur_x ,cur_y ) then
1934
on_mouse_move(cur_x ,cur_y ,flags );
1942
if x_event.xbutton.state and ShiftMask <> 0 then
1943
flags:=flags or kbd_shift;
1945
if x_event.xbutton.state and ControlMask <> 0 then
1946
flags:=flags or kbd_ctrl;
1948
if x_event.xbutton.button = Button1 then
1949
flags:=flags or mouse_left;
1951
if x_event.xbutton.button = Button3 then
1952
flags:=flags or mouse_right;
1954
cur_x:=x_event.xbutton.x;
1957
cur_y:=trunc(m_rbuf_window._height ) - x_event.xbutton.y
1959
cur_y:=x_event.xbutton.y;
1961
if flags and mouse_left <> 0 then
1962
if m_ctrls.on_mouse_button_up(cur_x ,cur_y ) then
1969
if flags and (mouse_left or mouse_right ) <> 0 then
1970
on_mouse_button_up(cur_x ,cur_y ,flags );
1972
//m_wait_mode:=m_specific.m_wait_mode;
1977
if (x_event.xclient.format = 32 ) and
1978
(x_event.xclient.data.l[0 ] = int(m_specific.m_close_atom ) ) then
1991
if m_specific.m_buf_img[i ] <> NIL then
1992
agg_freemem(m_specific.m_buf_img[i ] ,m_specific.m_img_alloc[i ] );
1996
agg_freemem(m_specific.m_buf_window ,m_specific.m_buf_alloc );
1998
m_specific.m_ximg_window.data:=NIL;
2000
XDestroyImage (m_specific.m_ximg_window );
2001
XFreeGC (m_specific.m_display ,m_specific.m_gc );
2002
XDestroyWindow(m_specific.m_display ,m_specific.m_window );
2003
XCloseDisplay (m_specific.m_display );
2010
procedure platform_support.quit;
2017
function platform_support._format;
2024
function platform_support._flip_y;
2031
function platform_support._bpp;
2038
function platform_support._wait_mode;
2040
result:=m_wait_mode;
2045
procedure platform_support.wait_mode_;
2047
m_wait_mode:=wait_mode;
2052
procedure platform_support.force_redraw;
2054
m_specific.m_update_flag:=true;
2059
procedure platform_support.update_window;
2061
m_specific.put_image(@m_rbuf_window );
2063
// When m_wait_mode is true we can discard all the events
2064
// came while the image is being drawn. In this case
2065
// the X server does not accumulate mouse motion events.
2066
// When m_wait_mode is false, i.e. we have some idle drawing
2067
// we cannot afford to miss any events
2068
XSync(m_specific.m_display ,m_wait_mode );
2073
function platform_support.rbuf_window;
2075
result:=@m_rbuf_window;
2080
function platform_support.rbuf_img;
2082
result:=@m_rbuf_img[idx ];
2087
function platform_support._img_ext;
2093
{ COPY_IMG_TO_WINDOW }
2094
procedure platform_support.copy_img_to_window;
2096
if (idx < max_images ) and
2097
(rbuf_img(idx )._buf <> NIL ) then
2098
rbuf_window.copy_from(rbuf_img(idx ) );
2102
{ COPY_WINDOW_TO_IMG }
2103
procedure platform_support.copy_window_to_img;
2105
if idx < max_images then
2107
create_img(idx ,rbuf_window._width ,rbuf_window._height );
2108
rbuf_img (idx ).copy_from(rbuf_window );
2115
procedure platform_support.copy_img_to_img;
2117
if (idx_from < max_images ) and
2118
(idx_to < max_images ) and
2119
(rbuf_img(idx_from )._buf <> NIL ) then
2123
rbuf_img(idx_from )._width ,
2124
rbuf_img(idx_from )._height );
2126
rbuf_img(idx_to ).copy_from(rbuf_img(idx_from ) );
2133
procedure platform_support.on_init;
2138
procedure platform_support.on_resize;
2143
procedure platform_support.on_idle;
2148
procedure platform_support.on_mouse_move;
2152
{ ON_MOUSE_BUTTON_DOWN }
2153
procedure platform_support.on_mouse_button_down;
2157
{ ON_MOUSE_BUTTON_UP }
2158
procedure platform_support.on_mouse_button_up;
2163
procedure platform_support.on_key;
2168
procedure platform_support.on_ctrl_change;
2173
procedure platform_support.on_draw;
2178
procedure platform_support.on_post_draw;
2183
procedure platform_support.add_ctrl;
2187
c.transform(@m_resize_mtx );
2191
{ TRANS_AFFINE_RESIZING_ }
2192
procedure platform_support.trans_affine_resizing_;
2194
vp : trans_viewport;
2195
ts : trans_affine_scaling;
2198
if m_window_flags and window_keep_aspect_ratio <> 0 then
2201
vp.preserve_aspect_ratio(0.5 ,0.5 ,aspect_ratio_meet );
2203
vp.device_viewport(0 ,0 ,width_ ,height_ );
2204
vp.world_viewport (0 ,0 ,m_initial_width ,m_initial_height );
2206
vp.to_affine(@m_resize_mtx );
2212
width_ / m_initial_width ,
2213
height_ / m_initial_height );
2215
m_resize_mtx.assign(@ts );
2221
{ _TRANS_AFFINE_RESIZING }
2222
function platform_support._trans_affine_resizing;
2224
result:=@m_resize_mtx;
2229
function platform_support._width;
2231
result:=m_rbuf_window._width;
2236
function platform_support._height;
2238
result:=m_rbuf_window._height;
2243
function platform_support._initial_width;
2245
result:=m_initial_width;
2250
function platform_support._initial_height;
2252
result:=m_initial_height;
2257
function platform_support._window_flags;
2259
result:=m_window_flags;
2263
{ _RAW_DISPLAY_HANDLER }
2264
function platform_support._raw_display_handler;
2269
procedure platform_support.message_;
2275
capt = ' PRESS ANY KEY TO CONTINUE THE AGGPAS DEMO ...';
2279
x_display : PDisplay;
2283
x_changes : TXWindowChanges;
2284
x_hints : PXSizeHints;
2287
x_tp : TXTextProperty;
2290
str ,cur : char_ptr;
2292
y ,len ,cnt ,max ,x_dx ,x_dy : unsigned;
2294
font_dir ,font_ascent ,font_descent : int;
2296
font_str : TXCharStruct;
2298
procedure draw_text;
2304
cur:=PChar(@msg[0 ] );
2317
XDrawString (x_display ,x_window ,x_gc ,10 ,y ,str ,len );
2319
x_display ,XGContextFromGC(x_gc) ,
2326
inc(y ,font_str.ascent + font_str.descent + plus );
2327
inc(x_dy ,font_str.ascent + font_str.descent + plus );
2329
if font_str.width > x_dx then
2330
x_dx:=font_str.width;
2341
inc(ptrcomp(cur ) );
2348
XDrawString (x_display ,x_window ,x_gc ,10 ,y ,str ,len );
2350
x_display ,XGContextFromGC(x_gc) ,
2357
inc(x_dy ,font_str.ascent + font_str.descent + plus );
2359
if font_str.width > x_dx then
2360
x_dx:=font_str.width;
2367
x_display:=XOpenDisplay(NIL );
2369
if x_display <> NIL then
2372
XCreateSimpleWindow(
2374
XDefaultRootWindow(x_display ) ,
2378
255 + (255 shl 8 ) + (255 shl 16 ) );
2380
x_gc:=XCreateGC(x_display ,x_window ,0 ,0 );
2383
XResizeWindow(x_display ,x_window ,x_dx + 20 ,x_dy + 40 );
2385
x_hints:=XAllocSizeHints;
2387
if x_hints <> NIL then
2389
x_hints.min_width :=x_dx + 20;
2390
x_hints.min_height:=x_dy + 40;
2391
x_hints.max_width :=x_dx + 20;
2392
x_hints.max_height:=x_dy + 40;
2394
x_hints.flags:=PMaxSize or PMinSize;
2396
XSetWMNormalHints(x_display ,x_window ,x_hints );
2401
x_tp.value :=PCUChar(@capt[1 ] );
2402
x_tp.encoding:=XA_WM_NAME;
2404
x_tp.nitems :=strlen(capt );
2406
XSetWMName (x_display ,x_window ,@x_tp );
2407
XStoreName (x_display ,x_window ,capt );
2408
XSetIconName (x_display ,x_window ,capt );
2409
XSetWMIconName(x_display ,x_window ,@x_tp );
2411
XMapWindow (x_display ,x_window );
2412
XSelectInput(x_display ,x_window ,x_event_mask );
2415
XInternAtom(x_display ,'WM_DELETE_WINDOW' ,false );
2425
XNextEvent(x_display ,@x_event );
2428
XSync (x_display ,true );
2430
case x_event._type of
2438
if (x_event.xclient.format = 32 ) and
2439
(x_event.xclient.data.l[0 ] = int(x_close ) ) then
2447
while XPending(x_display ) > 0 do
2449
XNextEvent(x_display ,@x_event );
2452
XSync (x_display ,true );
2456
XFreeGC (x_display ,x_gc );
2457
XDestroyWindow(x_display ,x_window );
2458
XCloseDisplay (x_display );
2462
writeln(stderr ,msg );
2467
procedure platform_support.start_timer;
2469
m_specific.m_sw_start:=clock;
2474
function platform_support.elapsed_time;
2481
result:=(stop - m_specific.m_sw_start ) * 1000.0 / CLOCKS_PER_SEC;
2486
function platform_support.full_file_name;
2493
function platform_support.file_source;
2503
AssignFile(f ,result );
2506
if ioresult <> 0 then
2507
result:=path + '/' + fname;