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