1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry (AGG) - Version 2.5
3 // A high quality rendering engine for C++
4 // Copyright (C) 2002-2006 Maxim Shemanarev
5 // Copyright (C) 2004 Steven Solie
6 // Contact: mcseem@antigrain.com
7 // mcseemagg@yahoo.com
8 // http://antigrain.com
9 //
10 // AGG is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU General Public License
12 // as published by the Free Software Foundation; either version 2
13 // of the License, or (at your option) any later version.
14 //
15 // AGG is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with AGG; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23 // MA 02110-1301, USA.
24 //----------------------------------------------------------------------------
25
26 #include "platform/agg_platform_support.h"
27 #include "util/agg_color_conv_rgb8.h"
28
29 #include <sys/time.h>
30 #include <cstring>
31
32 #include <classes/requester.h>
33 #include <classes/window.h>
34 #include <datatypes/pictureclass.h>
35 #include <proto/exec.h>
36 #include <proto/datatypes.h>
37 #include <proto/dos.h>
38 #include <proto/graphics.h>
39 #include <proto/intuition.h>
40 #include <proto/keymap.h>
41 #include <proto/Picasso96API.h>
42 #include <proto/utility.h>
43
44 Library* DataTypesBase = 0;
45 Library* GraphicsBase = 0;
46 Library* IntuitionBase = 0;
47 Library* KeymapBase = 0;
48 Library* P96Base = 0;
49
50 DataTypesIFace* IDataTypes = 0;
51 GraphicsIFace* IGraphics = 0;
52 IntuitionIFace* IIntuition = 0;
53 KeymapIFace* IKeymap = 0;
54 P96IFace* IP96 = 0;
55
56 Class* RequesterClass = 0;
57 Class* WindowClass = 0;
58
59
60 namespace agg
61 {
62 void handle_idcmp(Hook* hook, APTR win, IntuiMessage* msg);
63
64 //------------------------------------------------------------------------
65 class platform_specific
66 {
67 public:
68 platform_specific(platform_support& support, pix_format_e format,
69 bool flip_y);
70 ~platform_specific();
71 bool handle_input();
72 bool load_img(const char* file, unsigned idx, rendering_buffer* rbuf);
73 bool create_img(unsigned idx, rendering_buffer* rbuf, unsigned width,
74 unsigned height);
75 bool make_bitmap();
76 public:
77 platform_support& m_support;
78 RGBFTYPE m_ftype;
79 pix_format_e m_format;
80 unsigned m_bpp;
81 BitMap* m_bitmap;
82 bool m_flip_y;
83 uint16 m_width;
84 uint16 m_height;
85 APTR m_window_obj;
86 Window* m_window;
87 Hook* m_idcmp_hook;
88 unsigned m_input_flags;
89 bool m_dragging;
90 double m_start_time;
91 uint16 m_last_key;
92 BitMap* m_img_bitmaps[platform_support::max_images];
93 };
94
95 //------------------------------------------------------------------------
platform_specific(platform_support & support,pix_format_e format,bool flip_y)96 platform_specific::platform_specific(platform_support& support,
97 pix_format_e format, bool flip_y) :
98 m_support(support),
99 m_ftype(RGBFB_NONE),
100 m_format(format),
101 m_bpp(0),
102 m_bitmap(0),
103 m_flip_y(flip_y),
104 m_width(0),
105 m_height(0),
106 m_window_obj(0),
107 m_window(0),
108 m_idcmp_hook(0),
109 m_input_flags(0),
110 m_dragging(false),
111 m_start_time(0.0),
112 m_last_key(0)
113 {
114 switch ( format )
115 {
116 case pix_format_gray8:
117 // Not supported.
118 break;
119 case pix_format_rgb555:
120 m_ftype = RGBFB_R5G5B5;
121 m_bpp = 15;
122 break;
123 case pix_format_rgb565:
124 m_ftype = RGBFB_R5G6B5;
125 m_bpp = 16;
126 break;
127 case pix_format_rgb24:
128 m_ftype = RGBFB_R8G8B8;
129 m_bpp = 24;
130 break;
131 case pix_format_bgr24:
132 m_ftype = RGBFB_B8G8R8;
133 m_bpp = 24;
134 break;
135 case pix_format_bgra32:
136 m_ftype = RGBFB_B8G8R8A8;
137 m_bpp = 32;
138 break;
139 case pix_format_abgr32:
140 m_ftype = RGBFB_A8B8G8R8;
141 m_bpp = 32;
142 break;
143 case pix_format_argb32:
144 m_ftype = RGBFB_A8R8G8B8;
145 m_bpp = 32;
146 break;
147 case pix_format_rgba32:
148 m_ftype = RGBFB_R8G8B8A8;
149 m_bpp = 32;
150 break;
151 }
152
153 for ( unsigned i = 0; i < platform_support::max_images; ++i )
154 {
155 m_img_bitmaps[i] = 0;
156 }
157 }
158
159 //------------------------------------------------------------------------
~platform_specific()160 platform_specific::~platform_specific()
161 {
162 IIntuition->DisposeObject(m_window_obj);
163
164 IP96->p96FreeBitMap(m_bitmap);
165
166 for ( unsigned i = 0; i < platform_support::max_images; ++i )
167 {
168 IP96->p96FreeBitMap(m_img_bitmaps[i]);
169 }
170
171 if ( m_idcmp_hook != 0 )
172 {
173 IExec->FreeSysObject(ASOT_HOOK, m_idcmp_hook);
174 }
175 }
176
177 //------------------------------------------------------------------------
handle_input()178 bool platform_specific::handle_input()
179 {
180 int16 code = 0;
181 uint32 result = 0;
182 Object* obj = reinterpret_cast<Object*>(m_window_obj);
183
184 while ( (result = IIntuition->IDoMethod(obj, WM_HANDLEINPUT,
185 &code)) != WMHI_LASTMSG )
186 {
187 switch ( result & WMHI_CLASSMASK )
188 {
189 case WMHI_CLOSEWINDOW:
190 return true;
191 break;
192 case WMHI_INTUITICK:
193 if ( !m_support.wait_mode() )
194 {
195 m_support.on_idle();
196 }
197 break;
198 case WMHI_NEWSIZE:
199 if ( make_bitmap() )
200 {
201 m_support.trans_affine_resizing(m_width, m_height);
202 m_support.on_resize(m_width, m_height);
203 m_support.force_redraw();
204 }
205 break;
206 }
207 }
208
209 return false;
210 }
211
212 //------------------------------------------------------------------------
load_img(const char * file,unsigned idx,rendering_buffer * rbuf)213 bool platform_specific::load_img(const char* file, unsigned idx,
214 rendering_buffer* rbuf)
215 {
216 if ( m_img_bitmaps[idx] != 0 )
217 {
218 IP96->p96FreeBitMap(m_img_bitmaps[idx]);
219 m_img_bitmaps[idx] = 0;
220 }
221
222 bool result = false;
223
224 Object* picture = IDataTypes->NewDTObject(const_cast<STRPTR>(file),
225 DTA_GroupID, GID_PICTURE,
226 PDTA_DestMode, PMODE_V43,
227 PDTA_Remap, FALSE,
228 TAG_END);
229 if ( picture != 0 )
230 {
231 gpLayout layout;
232 layout.MethodID = DTM_PROCLAYOUT;
233 layout.gpl_GInfo = 0;
234 layout.gpl_Initial = 1;
235 ULONG loaded = IDataTypes->DoDTMethodA(picture, 0, 0,
236 reinterpret_cast<Msg>(&layout));
237 if ( loaded != 0 )
238 {
239 BitMap* src_bitmap = 0;
240 IDataTypes->GetDTAttrs(picture,
241 PDTA_ClassBitMap, &src_bitmap,
242 TAG_END);
243
244 bool supported = false;
245
246 RGBFTYPE ftype = static_cast<RGBFTYPE>(IP96->p96GetBitMapAttr(
247 src_bitmap, P96BMA_RGBFORMAT));
248
249 switch ( ftype )
250 {
251 case RGBFB_R8G8B8:
252 supported = true;
253 break;
254 default:
255 m_support.message("File uses unsupported graphics mode.");
256 break;
257 }
258
259 if ( supported ) {
260 uint16 width = IP96->p96GetBitMapAttr(src_bitmap,
261 P96BMA_WIDTH);
262 uint16 height = IP96->p96GetBitMapAttr(src_bitmap,
263 P96BMA_HEIGHT);
264
265 m_img_bitmaps[idx] = IP96->p96AllocBitMap(width, height,
266 m_bpp, BMF_USERPRIVATE, 0, m_ftype);
267 if ( m_img_bitmaps[idx] != 0 )
268 {
269 int8u* buf = reinterpret_cast<int8u*>(
270 IP96->p96GetBitMapAttr(m_img_bitmaps[idx],
271 P96BMA_MEMORY));
272 int bpr = IP96->p96GetBitMapAttr(m_img_bitmaps[idx],
273 P96BMA_BYTESPERROW);
274 int stride = (m_flip_y) ? -bpr : bpr;
275 rbuf->attach(buf, width, height, stride);
276
277 // P96 sets the alpha to zero so it can't be used to
278 // color convert true color modes.
279 if ( m_bpp == 32 )
280 {
281 RenderInfo ri;
282 int32 lock = IP96->p96LockBitMap(src_bitmap,
283 reinterpret_cast<uint8*>(&ri),
284 sizeof(RenderInfo));
285
286 rendering_buffer rbuf_src;
287 rbuf_src.attach(
288 reinterpret_cast<int8u*>(ri.Memory),
289 width, height, (m_flip_y) ?
290 -ri.BytesPerRow : ri.BytesPerRow);
291
292 switch ( m_format )
293 {
294 case pix_format_bgra32:
295 color_conv(rbuf, &rbuf_src,
296 color_conv_rgb24_to_bgra32());
297 break;
298 case pix_format_abgr32:
299 color_conv(rbuf, &rbuf_src,
300 color_conv_rgb24_to_abgr32());
301 break;
302 case pix_format_argb32:
303 color_conv(rbuf, &rbuf_src,
304 color_conv_rgb24_to_argb32());
305 break;
306 case pix_format_rgba32:
307 color_conv(rbuf, &rbuf_src,
308 color_conv_rgb24_to_rgba32());
309 break;
310 }
311
312 IP96->p96UnlockBitMap(src_bitmap, lock);
313 }
314 else
315 {
316 IGraphics->BltBitMap(src_bitmap, 0, 0,
317 m_img_bitmaps[idx], 0, 0, width, height,
318 ABC|ABNC, 0xFF, 0);
319 }
320
321 result = true;
322 }
323 }
324 }
325 }
326
327 IGraphics->WaitBlit();
328 IDataTypes->DisposeDTObject(picture);
329
330 return result;
331 }
332
333 //------------------------------------------------------------------------
create_img(unsigned idx,rendering_buffer * rbuf,unsigned width,unsigned height)334 bool platform_specific::create_img(unsigned idx, rendering_buffer* rbuf,
335 unsigned width, unsigned height)
336 {
337 if ( m_img_bitmaps[idx] != 0 )
338 {
339 IP96->p96FreeBitMap(m_img_bitmaps[idx]);
340 m_img_bitmaps[idx] = 0;
341 }
342
343 m_img_bitmaps[idx] = IP96->p96AllocBitMap(width, height,
344 m_bpp, BMF_USERPRIVATE, m_bitmap, m_ftype);
345 if ( m_img_bitmaps[idx] != 0 )
346 {
347 int8u* buf = reinterpret_cast<int8u*>(
348 IP96->p96GetBitMapAttr(m_img_bitmaps[idx],
349 P96BMA_MEMORY));
350 int bpr = IP96->p96GetBitMapAttr(m_img_bitmaps[idx],
351 P96BMA_BYTESPERROW);
352 int stride = (m_flip_y) ? -bpr : bpr;
353
354 rbuf->attach(buf, width, height, stride);
355
356 return true;
357 }
358
359 return false;
360 }
361
362 //------------------------------------------------------------------------
make_bitmap()363 bool platform_specific::make_bitmap()
364 {
365 uint32 width = 0;
366 uint32 height = 0;
367 IIntuition->GetWindowAttrs(m_window,
368 WA_InnerWidth, &width,
369 WA_InnerHeight, &height,
370 TAG_END);
371
372 BitMap* bm = IP96->p96AllocBitMap(width, height, m_bpp,
373 BMF_USERPRIVATE|BMF_CLEAR, 0, m_ftype);
374 if ( bm == 0 )
375 {
376 return false;
377 }
378
379 int8u* buf = reinterpret_cast<int8u*>(
380 IP96->p96GetBitMapAttr(bm, P96BMA_MEMORY));
381 int bpr = IP96->p96GetBitMapAttr(bm, P96BMA_BYTESPERROW);
382 int stride = (m_flip_y) ? -bpr : bpr;
383
384 m_support.rbuf_window().attach(buf, width, height, stride);
385
386 if ( m_bitmap != 0 )
387 {
388 IP96->p96FreeBitMap(m_bitmap);
389 m_bitmap = 0;
390 }
391
392 m_bitmap = bm;
393 m_width = width;
394 m_height = height;
395
396 return true;
397 }
398
399 //------------------------------------------------------------------------
platform_support(pix_format_e format,bool flip_y)400 platform_support::platform_support(pix_format_e format, bool flip_y) :
401 m_specific(new platform_specific(*this, format, flip_y)),
402 m_format(format),
403 m_bpp(m_specific->m_bpp),
404 m_window_flags(0),
405 m_wait_mode(true),
406 m_flip_y(flip_y),
407 m_initial_width(10),
408 m_initial_height(10)
409 {
410 std::strncpy(m_caption, "Anti-Grain Geometry", 256);
411 }
412
413 //------------------------------------------------------------------------
~platform_support()414 platform_support::~platform_support()
415 {
416 delete m_specific;
417 }
418
419 //------------------------------------------------------------------------
caption(const char * cap)420 void platform_support::caption(const char* cap)
421 {
422 std::strncpy(m_caption, cap, 256);
423 if ( m_specific->m_window != 0 )
424 {
425 const char* ignore = reinterpret_cast<const char*>(-1);
426 IIntuition->SetWindowAttr(m_specific->m_window,
427 WA_Title, m_caption, sizeof(char*));
428 }
429 }
430
431 //------------------------------------------------------------------------
start_timer()432 void platform_support::start_timer()
433 {
434 timeval tv;
435 gettimeofday(&tv, 0);
436 m_specific->m_start_time = tv.tv_secs + tv.tv_micro/1e6;
437 }
438
439 //------------------------------------------------------------------------
elapsed_time() const440 double platform_support::elapsed_time() const
441 {
442 timeval tv;
443 gettimeofday(&tv, 0);
444 double end_time = tv.tv_secs + tv.tv_micro/1e6;
445
446 double elasped_seconds = end_time - m_specific->m_start_time;
447 double elasped_millis = elasped_seconds*1e3;
448
449 return elasped_millis;
450 }
451
452 //------------------------------------------------------------------------
raw_display_handler()453 void* platform_support::raw_display_handler()
454 {
455 return 0; // Not available.
456 }
457
458 //------------------------------------------------------------------------
message(const char * msg)459 void platform_support::message(const char* msg)
460 {
461 APTR req = IIntuition->NewObject(RequesterClass, 0,
462 REQ_TitleText, "Anti-Grain Geometry",
463 REQ_Image, REQIMAGE_INFO,
464 REQ_BodyText, msg,
465 REQ_GadgetText, "_Ok",
466 TAG_END);
467 if ( req == 0 )
468 {
469 IDOS->Printf("Message: %s\n", msg);
470 return;
471 }
472
473 orRequest reqmsg;
474 reqmsg.MethodID = RM_OPENREQ;
475 reqmsg.or_Attrs = 0;
476 reqmsg.or_Window = m_specific->m_window;
477 reqmsg.or_Screen = 0;
478
479 IIntuition->IDoMethodA(reinterpret_cast<Object*>(req),
480 reinterpret_cast<Msg>(&reqmsg));
481 IIntuition->DisposeObject(req);
482 }
483
484 //------------------------------------------------------------------------
init(unsigned width,unsigned height,unsigned flags)485 bool platform_support::init(unsigned width, unsigned height,
486 unsigned flags)
487 {
488 if( m_specific->m_ftype == RGBFB_NONE )
489 {
490 message("Unsupported mode requested.");
491 return false;
492 }
493
494 m_window_flags = flags;
495
496 m_specific->m_idcmp_hook = reinterpret_cast<Hook*>(
497 IExec->AllocSysObjectTags(ASOT_HOOK,
498 ASOHOOK_Entry, handle_idcmp,
499 ASOHOOK_Data, this,
500 TAG_END));
501 if ( m_specific->m_idcmp_hook == 0 )
502 {
503 return false;
504 }
505
506 m_specific->m_window_obj = IIntuition->NewObject(WindowClass, 0,
507 WA_Title, m_caption,
508 WA_AutoAdjustDClip, TRUE,
509 WA_InnerWidth, width,
510 WA_InnerHeight, height,
511 WA_Activate, TRUE,
512 WA_SmartRefresh, TRUE,
513 WA_NoCareRefresh, TRUE,
514 WA_CloseGadget, TRUE,
515 WA_DepthGadget, TRUE,
516 WA_SizeGadget, (flags & agg::window_resize) ? TRUE : FALSE,
517 WA_DragBar, TRUE,
518 WA_AutoAdjust, TRUE,
519 WA_ReportMouse, TRUE,
520 WA_RMBTrap, TRUE,
521 WA_MouseQueue, 1,
522 WA_IDCMP,
523 IDCMP_NEWSIZE |
524 IDCMP_MOUSEBUTTONS |
525 IDCMP_MOUSEMOVE |
526 IDCMP_RAWKEY |
527 IDCMP_INTUITICKS,
528 WINDOW_IDCMPHook, m_specific->m_idcmp_hook,
529 WINDOW_IDCMPHookBits,
530 IDCMP_MOUSEBUTTONS |
531 IDCMP_MOUSEMOVE |
532 IDCMP_RAWKEY,
533 TAG_END);
534 if ( m_specific->m_window_obj == 0 )
535 {
536 return false;
537 }
538
539 Object* obj = reinterpret_cast<Object*>(m_specific->m_window_obj);
540 m_specific->m_window =
541 reinterpret_cast<Window*>(IIntuition->IDoMethod(obj, WM_OPEN));
542 if ( m_specific->m_window == 0 )
543 {
544 return false;
545 }
546
547 RGBFTYPE ftype = static_cast<RGBFTYPE>(IP96->p96GetBitMapAttr(
548 m_specific->m_window->RPort->BitMap, P96BMA_RGBFORMAT));
549
550 switch ( ftype )
551 {
552 case RGBFB_A8R8G8B8:
553 case RGBFB_B8G8R8A8:
554 case RGBFB_R5G6B5PC:
555 break;
556 default:
557 message("Unsupported screen mode.\n");
558 return false;
559 }
560
561 if ( !m_specific->make_bitmap() )
562 {
563 return false;
564 }
565
566 m_initial_width = width;
567 m_initial_height = height;
568
569 on_init();
570 on_resize(width, height);
571 force_redraw();
572
573 return true;
574 }
575
576 //------------------------------------------------------------------------
run()577 int platform_support::run()
578 {
579 uint32 window_mask = 0;
580 IIntuition->GetAttr(WINDOW_SigMask, m_specific->m_window_obj,
581 &window_mask);
582 uint32 wait_mask = window_mask | SIGBREAKF_CTRL_C;
583
584 bool done = false;
585
586 while ( !done )
587 {
588 uint32 sig_mask = IExec->Wait(wait_mask);
589 if ( sig_mask & SIGBREAKF_CTRL_C )
590 {
591 done = true;
592 }
593 else
594 {
595 done = m_specific->handle_input();
596 }
597 }
598
599 return 0;
600 }
601
602 //------------------------------------------------------------------------
img_ext() const603 const char* platform_support::img_ext() const
604 {
605 return ".bmp";
606 }
607
608 //------------------------------------------------------------------------
full_file_name(const char * file_name)609 const char* platform_support::full_file_name(const char* file_name)
610 {
611 return file_name;
612 }
613
614 //------------------------------------------------------------------------
load_img(unsigned idx,const char * file)615 bool platform_support::load_img(unsigned idx, const char* file)
616 {
617 if ( idx < max_images )
618 {
619 static char fn[1024];
620 std::strncpy(fn, file, 1024);
621 int len = std::strlen(fn);
622 if ( len < 4 || std::strcmp(fn + len - 4, ".bmp") != 0 )
623 {
624 std::strncat(fn, ".bmp", 1024);
625 }
626
627 return m_specific->load_img(fn, idx, &m_rbuf_img[idx]);
628 }
629
630 return false;
631 }
632
633 //------------------------------------------------------------------------
save_img(unsigned idx,const char * file)634 bool platform_support::save_img(unsigned idx, const char* file)
635 {
636 message("Not supported");
637 return false;
638 }
639
640 //------------------------------------------------------------------------
create_img(unsigned idx,unsigned width,unsigned height)641 bool platform_support::create_img(unsigned idx, unsigned width,
642 unsigned height)
643 {
644 if ( idx < max_images )
645 {
646 if ( width == 0 )
647 {
648 width = m_specific->m_width;
649 }
650
651 if ( height == 0 )
652 {
653 height = m_specific->m_height;
654 }
655
656 return m_specific->create_img(idx, &m_rbuf_img[idx], width,
657 height);
658 }
659
660 return false;
661 }
662
663 //------------------------------------------------------------------------
force_redraw()664 void platform_support::force_redraw()
665 {
666 on_draw();
667 update_window();
668 }
669
670 //------------------------------------------------------------------------
update_window()671 void platform_support::update_window()
672 {
673 // Note this function does automatic color conversion.
674 IGraphics->BltBitMapRastPort(m_specific->m_bitmap, 0, 0,
675 m_specific->m_window->RPort, m_specific->m_window->BorderLeft,
676 m_specific->m_window->BorderTop, m_specific->m_width,
677 m_specific->m_height, ABC|ABNC);
678 }
679
680 //------------------------------------------------------------------------
on_init()681 void platform_support::on_init() {}
on_resize(int sx,int sy)682 void platform_support::on_resize(int sx, int sy) {}
on_idle()683 void platform_support::on_idle() {}
on_mouse_move(int x,int y,unsigned flags)684 void platform_support::on_mouse_move(int x, int y, unsigned flags) {}
on_mouse_button_down(int x,int y,unsigned flags)685 void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {}
on_mouse_button_up(int x,int y,unsigned flags)686 void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {}
on_key(int x,int y,unsigned key,unsigned flags)687 void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {}
on_ctrl_change()688 void platform_support::on_ctrl_change() {}
on_draw()689 void platform_support::on_draw() {}
on_post_draw(void * raw_handler)690 void platform_support::on_post_draw(void* raw_handler) {}
691
692 //------------------------------------------------------------------------
handle_idcmp(Hook * hook,APTR obj,IntuiMessage * msg)693 void handle_idcmp(Hook* hook, APTR obj, IntuiMessage* msg)
694 {
695 platform_support* app =
696 reinterpret_cast<platform_support*>(hook->h_Data);
697 Window* window = app->m_specific->m_window;
698
699 int16 x = msg->MouseX - window->BorderLeft;
700
701 int16 y = 0;
702 if ( app->flip_y() )
703 {
704 y = window->Height - window->BorderBottom - msg->MouseY;
705 }
706 else
707 {
708 y = msg->MouseY - window->BorderTop;
709 }
710
711 switch ( msg->Class )
712 {
713 case IDCMP_MOUSEBUTTONS:
714 if ( msg->Code & IECODE_UP_PREFIX )
715 {
716 if ( msg->Code == SELECTUP )
717 {
718 app->m_specific->m_input_flags = mouse_left;
719 app->m_specific->m_dragging = false;
720 }
721 else if ( msg->Code == MENUUP )
722 {
723 app->m_specific->m_input_flags = mouse_right;
724 app->m_specific->m_dragging = false;
725 }
726 else
727 {
728 return;
729 }
730
731
732 if ( app->m_ctrls.on_mouse_button_up(x, y) )
733 {
734 app->on_ctrl_change();
735 app->force_redraw();
736 }
737
738 app->on_mouse_button_up(x, y, app->m_specific->m_input_flags);
739 }
740 else
741 {
742 if ( msg->Code == SELECTDOWN )
743 {
744 app->m_specific->m_input_flags = mouse_left;
745 app->m_specific->m_dragging = true;
746 }
747 else if ( msg->Code == MENUDOWN )
748 {
749 app->m_specific->m_input_flags = mouse_right;
750 app->m_specific->m_dragging = true;
751 }
752 else
753 {
754 return;
755 }
756
757 app->m_ctrls.set_cur(x, y);
758 if ( app->m_ctrls.on_mouse_button_down(x, y) )
759 {
760 app->on_ctrl_change();
761 app->force_redraw();
762 }
763 else
764 {
765 if ( app->m_ctrls.in_rect(x, y) )
766 {
767 if ( app->m_ctrls.set_cur(x, y) )
768 {
769 app->on_ctrl_change();
770 app->force_redraw();
771 }
772 }
773 else
774 {
775 app->on_mouse_button_down(x, y,
776 app->m_specific->m_input_flags);
777 }
778 }
779 }
780 break;
781 case IDCMP_MOUSEMOVE:
782 if ( app->m_specific->m_dragging ) {
783 if ( app->m_ctrls.on_mouse_move(x, y,
784 app->m_specific->m_input_flags & mouse_left) != 0 )
785 {
786 app->on_ctrl_change();
787 app->force_redraw();
788 }
789 else
790 {
791 if ( !app->m_ctrls.in_rect(x, y) )
792 {
793 app->on_mouse_move(x, y,
794 app->m_specific->m_input_flags);
795 }
796 }
797 }
798 break;
799 case IDCMP_RAWKEY:
800 {
801 static InputEvent ie = { 0 };
802 ie.ie_Class = IECLASS_RAWKEY;
803 ie.ie_Code = msg->Code;
804 ie.ie_Qualifier = msg->Qualifier;
805
806 static const unsigned BUF_SIZE = 16;
807 static char key_buf[BUF_SIZE];
808 int16 num_chars = IKeymap->MapRawKey(&ie, key_buf, BUF_SIZE, 0);
809
810 uint32 code = 0x00000000;
811 switch ( num_chars )
812 {
813 case 1:
814 code = key_buf[0];
815 break;
816 case 2:
817 code = key_buf[0]<<8 | key_buf[1];
818 break;
819 case 3:
820 code = key_buf[0]<<16 | key_buf[1]<<8 | key_buf[2];
821 break;
822 }
823
824 uint16 key_code = 0;
825
826 if ( num_chars == 1 )
827 {
828 if ( code >= IECODE_ASCII_FIRST && code <= IECODE_ASCII_LAST )
829 {
830 key_code = code;
831 }
832 }
833
834 if ( key_code == 0 )
835 {
836 switch ( code )
837 {
838 case 0x00000008: key_code = key_backspace; break;
839 case 0x00000009: key_code = key_tab; break;
840 case 0x0000000D: key_code = key_return; break;
841 case 0x0000001B: key_code = key_escape; break;
842 case 0x0000007F: key_code = key_delete; break;
843 case 0x00009B41:
844 case 0x00009B54: key_code = key_up; break;
845 case 0x00009B42:
846 case 0x00009B53: key_code = key_down; break;
847 case 0x00009B43:
848 case 0x009B2040: key_code = key_right; break;
849 case 0x00009B44:
850 case 0x009B2041: key_code = key_left; break;
851 case 0x009B307E: key_code = key_f1; break;
852 case 0x009B317E: key_code = key_f2; break;
853 case 0x009B327E: key_code = key_f3; break;
854 case 0x009B337E: key_code = key_f4; break;
855 case 0x009B347E: key_code = key_f5; break;
856 case 0x009B357E: key_code = key_f6; break;
857 case 0x009B367E: key_code = key_f7; break;
858 case 0x009B377E: key_code = key_f8; break;
859 case 0x009B387E: key_code = key_f9; break;
860 case 0x009B397E: key_code = key_f10; break;
861 case 0x009B3F7E: key_code = key_scrollock; break;
862 }
863 }
864
865 if ( ie.ie_Code & IECODE_UP_PREFIX )
866 {
867 if ( app->m_specific->m_last_key != 0 )
868 {
869 bool left = (key_code == key_left) ? true : false;
870 bool right = (key_code == key_right) ? true : false;
871 bool down = (key_code == key_down) ? true : false;
872 bool up = (key_code == key_up) ? true : false;
873
874 if ( app->m_ctrls.on_arrow_keys(left, right, down, up) )
875 {
876 app->on_ctrl_change();
877 app->force_redraw();
878 }
879 else
880 {
881 app->on_key(x, y, app->m_specific->m_last_key, 0);
882 }
883
884 app->m_specific->m_last_key = 0;
885 }
886 }
887 else
888 {
889 app->m_specific->m_last_key = key_code;
890 }
891 break;
892 }
893 default:
894 break;
895 }
896 }
897 }
898
899 //----------------------------------------------------------------------------
900 int agg_main(int argc, char* argv[]);
901 bool open_libs();
902 void close_libs();
903
904 //----------------------------------------------------------------------------
open_libs()905 bool open_libs()
906 {
907 DataTypesBase = IExec->OpenLibrary("datatypes.library", 51);
908 GraphicsBase = IExec->OpenLibrary("graphics.library", 51);
909 IntuitionBase = IExec->OpenLibrary("intuition.library", 51);
910 KeymapBase = IExec->OpenLibrary("keymap.library", 51);
911 P96Base = IExec->OpenLibrary("Picasso96API.library", 2);
912
913 IDataTypes = reinterpret_cast<DataTypesIFace*>(
914 IExec->GetInterface(DataTypesBase, "main", 1, 0));
915 IGraphics = reinterpret_cast<GraphicsIFace*>(
916 IExec->GetInterface(GraphicsBase, "main", 1, 0));
917 IIntuition = reinterpret_cast<IntuitionIFace*>(
918 IExec->GetInterface(IntuitionBase, "main", 1, 0));
919 IKeymap = reinterpret_cast<KeymapIFace*>(
920 IExec->GetInterface(KeymapBase, "main", 1, 0));
921 IP96 = reinterpret_cast<P96IFace*>(
922 IExec->GetInterface(P96Base, "main", 1, 0));
923
924 if ( IDataTypes == 0 ||
925 IGraphics == 0 ||
926 IIntuition == 0 ||
927 IKeymap == 0 ||
928 IP96 == 0 )
929 {
930 close_libs();
931 return false;
932 }
933 else
934 {
935 return true;
936 }
937 }
938
939 //----------------------------------------------------------------------------
close_libs()940 void close_libs()
941 {
942 IExec->DropInterface(reinterpret_cast<Interface*>(IP96));
943 IExec->DropInterface(reinterpret_cast<Interface*>(IKeymap));
944 IExec->DropInterface(reinterpret_cast<Interface*>(IIntuition));
945 IExec->DropInterface(reinterpret_cast<Interface*>(IGraphics));
946 IExec->DropInterface(reinterpret_cast<Interface*>(IDataTypes));
947
948 IExec->CloseLibrary(P96Base);
949 IExec->CloseLibrary(KeymapBase);
950 IExec->CloseLibrary(IntuitionBase);
951 IExec->CloseLibrary(GraphicsBase);
952 IExec->CloseLibrary(DataTypesBase);
953 }
954
955 //----------------------------------------------------------------------------
main(int argc,char * argv[])956 int main(int argc, char* argv[])
957 {
958 if ( !open_libs() ) {
959 IDOS->Printf("Can't open libraries.\n");
960 return -1;
961 }
962
963 ClassLibrary* requester =
964 IIntuition->OpenClass("requester.class", 51, &RequesterClass);
965 ClassLibrary* window =
966 IIntuition->OpenClass("window.class", 51, &WindowClass);
967 if ( requester == 0 || window == 0 )
968 {
969 IDOS->Printf("Can't open classes.\n");
970 IIntuition->CloseClass(requester);
971 IIntuition->CloseClass(window);
972 close_libs();
973 return -1;
974 }
975
976 int rc = agg_main(argc, argv);
977
978 IIntuition->CloseClass(window);
979 IIntuition->CloseClass(requester);
980 close_libs();
981
982 return rc;
983 }
984