1 #include "apricot.h"
2 #include "Timer.h"
3 #include "Window.h"
4 #include "Image.h"
5 #include "Application.h"
6 #include <Application.inc>
7 
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
11 
12 
13 #undef  my
14 #define inherited CWidget->
15 #define my  ((( PApplication) self)-> self)
16 #define var (( PApplication) self)
17 
18 static void Application_HintTimer_handle_event( Handle, PEvent);
19 
20 void
Application_init(Handle self,HV * profile)21 Application_init( Handle self, HV * profile)
22 {
23 	dPROFILE;
24 	int hintPause = pget_i( hintPause);
25 	Color hintColor = pget_i( hintColor), hintBackColor = pget_i( hintBackColor);
26 	SV * hintFont = pget_sv( hintFont);
27 	SV * sv;
28 	char * hintClass      = pget_c( hintClass);
29 	if ( application != NULL_HANDLE)
30 		croak( "Attempt to create more than one application instance");
31 
32 	opt_set(optSystemDrawable);
33 	CDrawable-> init( self, profile);
34 	list_create( &var->  widgets, 16, 16);
35 	list_create( &var->  modalHorizons, 0, 8);
36 	application = self;
37 	if ( !apc_application_create( self))
38 		croak( "Error creating application");
39 /* Widget init */
40 	SvHV_Font( pget_sv( font), &Font_buffer, "Application::init");
41 	my-> set_font( self, Font_buffer);
42 	SvHV_Font( pget_sv( popupFont), &Font_buffer, "Application::init");
43 	my-> set_popup_font( self, Font_buffer);
44 	{
45 		AV * av = ( AV *) SvRV( pget_sv( designScale));
46 		SV ** holder = av_fetch( av, 0, 0);
47 		if ( holder)
48 			var->  designScale. x = SvNV( *holder);
49 		else
50 			warn("Array panic on 'designScale'");
51 		holder = av_fetch( av, 1, 0);
52 		if ( holder)
53 			var->  designScale. y = SvNV( *holder);
54 		else
55 			warn("Array panic on 'designScale'");
56 		pdelete( designScale);
57 	}
58 	var->  text = newSVpv("", 0);
59 	var->  hint = newSVpv("", 0);
60 	opt_set( optModalHorizon);
61 
62 	/* store extra info */
63 	{
64 		HV * hv = ( HV *) SvRV( var-> mate);
65 		(void) hv_store( hv, "PrinterClass",  12, newSVpv( pget_c( printerClass),  0), 0);
66 		(void) hv_store( hv, "PrinterModule", 13, newSVpv( pget_c( printerModule), 0), 0);
67 		(void) hv_store( hv, "HelpClass",     9,  newSVpv( pget_c( helpClass),     0), 0);
68 		(void) hv_store( hv, "HelpModule",    10, newSVpv( pget_c( helpModule),    0), 0);
69 	}
70 
71 	{
72 		HV * profile = newHV();
73 		static Timer_vmt HintTimerVmt;
74 
75 		pset_H( owner, self);
76 		pset_i( timeout, hintPause);
77 		pset_c( name, "HintTimer");
78 		var->  hintTimer = create_instance( "Prima::Timer");
79 		protect_object( var-> hintTimer);
80 		hv_clear( profile);
81 		memcpy( &HintTimerVmt, CTimer, sizeof( HintTimerVmt));
82 		HintTimerVmt. handle_event = Application_HintTimer_handle_event;
83 		(( PTimer) var->  hintTimer)-> self = &HintTimerVmt;
84 
85 		pset_H( owner, self);
86 		pset_i( color, hintColor);
87 		pset_i( backColor, hintBackColor);
88 		pset_i( visible, 0);
89 		pset_i( selectable, 0);
90 		pset_i( showHint, 0);
91 		pset_c( name, "HintWidget");
92 		pset_sv( font, hintFont);
93 		var->  hintWidget = create_instance( hintClass);
94 		protect_object( var->  hintWidget);
95 		sv_free(( SV *) profile);
96 	}
97 
98 	if ( SvTYPE( sv = pget_sv( accelItems)) != SVt_NULL)
99 		my-> set_accelItems( self, sv);
100 	if ( SvTYPE( sv = pget_sv( popupItems)) != SVt_NULL)
101 		my-> set_popupItems( self, sv);
102 	pdelete( accelTable);
103 	pdelete( accelItems);
104 	pdelete( popupItems);
105 
106 	my-> set( self, profile);
107 	CORE_INIT_TRANSIENT(Application);
108 }
109 
110 void
Application_done(Handle self)111 Application_done( Handle self)
112 {
113 	if ( self != application) return;
114 	unprotect_object( var-> hintTimer);
115 	unprotect_object( var-> hintWidget);
116 	list_destroy( &var->  modalHorizons);
117 	list_destroy( &var->  widgets);
118 	if ( var-> text ) SvREFCNT_dec( var-> text);
119 	if ( var-> hint ) SvREFCNT_dec( var-> hint);
120 	free( var-> helpContext);
121 	var-> accelTable = var-> hintWidget = var-> hintTimer = NULL_HANDLE;
122 	var-> helpContext = NULL;
123 	var-> hint = var-> text = NULL;
124 	apc_application_destroy( self);
125 	CDrawable-> done( self);
126 	application = NULL_HANDLE;
127 }
128 
129 void
Application_cleanup(Handle self)130 Application_cleanup( Handle self)
131 {
132 	int i;
133 
134 	for ( i = 0; i < var-> widgets. count; i++)
135 		Object_destroy( var-> widgets. items[i]);
136 
137 	if ( var-> icon)
138 		my-> detach( self, var-> icon, true);
139 	var-> icon = NULL_HANDLE;
140 
141 	my-> first_that_component( self, (void*)prima_kill_all_objects, NULL);
142 
143 	CDrawable-> cleanup( self);
144 }
145 
146 
147 void
Application_set(Handle self,HV * profile)148 Application_set( Handle self, HV * profile)
149 {
150 	pdelete( bottom);
151 	pdelete( buffered);
152 	pdelete( capture);
153 	pdelete( centered);
154 	pdelete( clipOwner);
155 	pdelete( enabled);
156 	pdelete( focused);
157 	pdelete( geometry);
158 	pdelete( geomHeight);
159 	pdelete( geomSize);
160 	pdelete( geomWidth);
161 	pdelete( growMode);
162 	pdelete( height);
163 	pdelete( hintClass);
164 	pdelete( hintVisible);
165 	pdelete( layered);
166 	pdelete( left);
167 	pdelete( modalHorizon);
168 	pdelete( origin);
169 	pdelete( owner);
170 	pdelete( ownerBackColor);
171 	pdelete( ownerColor);
172 	pdelete( ownerFont);
173 	pdelete( ownerPalette);
174 	pdelete( ownerShowHint);
175 	pdelete( palette);
176 	pdelete( pack);
177 	pdelete( place);
178 	pdelete( printerClass);
179 	pdelete( printerModule);
180 	pdelete( helpClass);
181 	pdelete( helpModule);
182 	pdelete( rect);
183 	pdelete( rigth);
184 	pdelete( selectable);
185 	pdelete( shape);
186 	pdelete( size);
187 	pdelete( syncPaint);
188 	pdelete( tabOrder);
189 	pdelete( tabStop);
190 	pdelete( transparent);
191 	pdelete( text);
192 	pdelete( top);
193 	pdelete( visible);
194 	pdelete( width);
195 	inherited set( self, profile);
196 }
197 
Application_handle_event(Handle self,PEvent event)198 void Application_handle_event( Handle self, PEvent event)
199 {
200 	switch ( event-> cmd)
201 	{
202 		case cmPost:
203 			if ( event-> gen. H != self)
204 			{
205 				((( PComponent) event-> gen. H)-> self)-> message( event-> gen. H, event);
206 				event-> cmd = 0;
207 				if ( var->  stage > csNormal) return;
208 			}
209 			break;
210 		case cmIdle:
211 			my-> notify( self, "<s", "Idle");
212 			return;
213 	}
214 	inherited handle_event ( self, event);
215 }
216 
217 void
Application_sync(char * dummy)218 Application_sync( char * dummy)
219 {
220 	apc_application_sync();
221 }
222 
223 Bool
Application_yield(char * dummy,Bool wait_for_event)224 Application_yield( char * dummy, Bool wait_for_event)
225 {
226 	return apc_application_yield(wait_for_event);
227 }
228 
229 Bool
Application_begin_paint(Handle self)230 Application_begin_paint( Handle self)
231 {
232 	Bool ok;
233 	if ( !CDrawable-> begin_paint( self))
234 		return false;
235 	if ( !( ok = apc_application_begin_paint( self))) {
236 		CDrawable-> end_paint( self);
237 		perl_error();
238 	}
239 	return ok;
240 }
241 
242 Bool
Application_begin_paint_info(Handle self)243 Application_begin_paint_info( Handle self)
244 {
245 	Bool ok;
246 	if ( is_opt( optInDraw))     return true;
247 	if ( !CDrawable-> begin_paint_info( self))
248 		return false;
249 	if ( !( ok = apc_application_begin_paint_info( self))) {
250 		CDrawable-> end_paint_info( self);
251 		perl_error();
252 	}
253 	return ok;
254 }
255 
256 void
Application_detach(Handle self,Handle objectHandle,Bool kill)257 Application_detach( Handle self, Handle objectHandle, Bool kill)
258 {
259 	inherited detach( self, objectHandle, kill);
260 	if ( var->  autoClose &&
261 		( var->  widgets. count == 1) &&
262 		kind_of( objectHandle, CWidget) &&
263 		( objectHandle != var->  hintWidget)
264 		) my-> close( self);
265 }
266 
267 void
Application_end_paint(Handle self)268 Application_end_paint( Handle self)
269 {
270 	if ( !is_opt( optInDraw)) return;
271 	apc_application_end_paint( self);
272 	CDrawable-> end_paint( self);
273 }
274 
275 void
Application_end_paint_info(Handle self)276 Application_end_paint_info( Handle self)
277 {
278 	if ( !is_opt( optInDrawInfo)) return;
279 	apc_application_end_paint_info( self);
280 	CDrawable-> end_paint_info( self);
281 }
282 
283 Bool
Application_focused(Handle self,Bool set,Bool focused)284 Application_focused( Handle self, Bool set, Bool focused)
285 {
286 	if ( set) return false;
287 	return inherited focused( self, set, focused);
288 }
289 
Application_bring_to_front(Handle self)290 void Application_bring_to_front( Handle self) {}
Application_show(Handle self)291 void Application_show( Handle self) {}
Application_hide(Handle self)292 void Application_hide( Handle self) {}
Application_insert_behind(Handle self,Handle view)293 void Application_insert_behind( Handle self, Handle view) {}
Application_send_to_back(Handle self)294 void Application_send_to_back( Handle self) {}
295 
296 SV*
Application_fonts(Handle self,char * name,char * encoding)297 Application_fonts( Handle self, char * name, char * encoding)
298 {
299 	int count, i;
300 	AV * glo = newAV();
301 	PFont fmtx = apc_fonts( self,
302 		(name && name[0])         ? name : NULL,
303 		(encoding && encoding[0]) ? encoding : NULL,
304 		&count);
305 	for ( i = 0; i < count; i++) {
306 		SV * sv      = sv_Font2HV( &fmtx[ i]);
307 		HV * profile = ( HV*) SvRV( sv);
308 		if ( fmtx[i].is_utf8.name ) {
309 			SV ** entry = hv_fetch(( HV*) SvRV( sv), "name", 4, 0);
310 			if ( entry && SvOK( *entry))
311 				SvUTF8_on( *entry);
312 		}
313 		if ( fmtx[i].is_utf8.family ) {
314 			SV ** entry = hv_fetch(( HV*) SvRV( sv), "family", 6, 0);
315 			if ( name && SvOK( *entry))
316 				SvUTF8_on( *entry);
317 		}
318 		if ( fmtx[i].is_utf8.encoding ) {
319 			SV ** entry = hv_fetch(( HV*) SvRV( sv), "encoding", 8, 0);
320 			if ( name && SvOK( *entry))
321 				SvUTF8_on( *entry);
322 		}
323 		if ( name[0] == 0 && encoding[0] == 0) {
324 			/* Read specially-coded (const char*) encodings[] vector,
325 			stored in fmtx[i].encoding. First pointer is filled with 0s,
326 			except the last byte which is a counter. Such scheme
327 			allows max 31 encodings per entry to be coded with sizeof(char*)==8.
328 			The interface must be re-implemented, but this requires
329 			either change in gencls syntax so arrays can be members of hashes,
330 			or passing of a dynamic-allocated pointer vector here.
331 			*/
332 			char ** enc = (char**) fmtx[i].encoding;
333 			unsigned char * shift = (unsigned char*) enc + sizeof(char *) - 1, j = *shift;
334 			AV * loc = newAV();
335 			pset_sv_noinc( encoding, newSVpv(( j > 0) ? *(++enc) : "", 0));
336 			while ( j--) av_push( loc, newSVpv(*(enc++),0));
337 			pset_sv_noinc( encodings, newRV_noinc(( SV*) loc));
338 		}
339 		pdelete( resolution);
340 		pdelete( codepage);
341 		av_push( glo, sv);
342 	}
343 	free( fmtx);
344 	return newRV_noinc(( SV *) glo);
345 }
346 
347 SV*
Application_font_encodings(Handle self,char * encoding)348 Application_font_encodings( Handle self, char * encoding)
349 {
350 	AV * glo = newAV();
351 	HE *he;
352 	PHash h = apc_font_encodings( self);
353 
354 	if ( !h) return newRV_noinc(( SV *) glo);
355 	hv_iterinit(( HV*) h);
356 	for (;;)
357 	{
358 		void *key;
359 		STRLEN  keyLen;
360 		if (( he = hv_iternext( h)) == NULL)
361 			break;
362 		key    = HeKEY( he);
363 		keyLen = HeKLEN( he);
364 		av_push( glo, newSVpvn(( char*) key, keyLen));
365 	}
366 	return newRV_noinc(( SV *) glo);
367 }
368 
369 Font
Application_get_default_font(char * dummy)370 Application_get_default_font( char * dummy)
371 {
372 	Font font;
373 	apc_font_default( &font);
374 	return font;
375 }
376 
377 Font
Application_get_message_font(char * dummy)378 Application_get_message_font( char * dummy)
379 {
380 	Font font;
381 	apc_sys_get_msg_font( &font);
382 	return font;
383 }
384 
385 Font
Application_get_caption_font(char * dummy)386 Application_get_caption_font( char * dummy)
387 {
388 	Font font;
389 	apc_sys_get_caption_font( &font);
390 	return font;
391 }
392 
393 
394 int
Application_get_default_cursor_width(char * dummy)395 Application_get_default_cursor_width( char * dummy)
396 {
397 	return apc_sys_get_value( svXCursor);
398 }
399 
400 Point
Application_get_default_scrollbar_metrics(char * dummy)401 Application_get_default_scrollbar_metrics( char * dummy)
402 {
403 	Point ret;
404 	ret. x = apc_sys_get_value( svXScrollbar);
405 	ret. y = apc_sys_get_value( svYScrollbar);
406 	return ret;
407 }
408 
409 Point
Application_get_default_window_borders(char * dummy,int borderStyle)410 Application_get_default_window_borders( char * dummy, int borderStyle)
411 {
412 	Point ret = { 0,0};
413 	switch ( borderStyle) {
414 	case bsNone:
415 		ret.x = svXbsNone;
416 		ret.y = svYbsNone;
417 		break;
418 	case bsSizeable:
419 		ret.x = svXbsSizeable;
420 		ret.y = svYbsSizeable;
421 		break;
422 	case bsSingle:
423 		ret.x = svXbsSingle;
424 		ret.y = svYbsSingle;
425 		break;
426 	case bsDialog:
427 		ret.x = svXbsDialog;
428 		ret.y = svYbsDialog;
429 		break;
430 	default:
431 		return ret;
432 	}
433 	ret. x = apc_sys_get_value( ret. x);
434 	ret. y = apc_sys_get_value( ret. y);
435 	return ret;
436 }
437 
438 int
Application_get_system_value(char * dummy,int sysValue)439 Application_get_system_value( char * dummy, int sysValue)
440 {
441 	return apc_sys_get_value( sysValue);
442 }
443 
444 SV *
Application_get_system_info(char * dummy)445 Application_get_system_info( char * dummy)
446 {
447 	HV * profile = newHV();
448 	char system   [ 1024];
449 	char release  [ 1024];
450 	char vendor   [ 1024];
451 	char arch     [ 1024];
452 	char gui_desc [ 1024];
453 	char gui_lang [ 1024];
454 	int  os, gui;
455 
456 	os  = apc_application_get_os_info( system, sizeof( system),
457 					release, sizeof( release),
458 					vendor, sizeof( vendor),
459 					arch, sizeof( arch));
460 	gui = apc_application_get_gui_info( gui_desc, sizeof( gui_desc), gui_lang, sizeof(gui_lang));
461 
462 	pset_i( apc,            os);
463 	pset_i( gui,            gui);
464 	pset_c( system,         system);
465 	pset_c( release,        release);
466 	pset_c( vendor,         vendor);
467 	pset_c( architecture,   arch);
468 	pset_c( guiDescription, gui_desc);
469 	pset_c( guiLanguage,    gui_lang);
470 
471 	return newRV_noinc(( SV *) profile);
472 }
473 
474 Handle
Application_get_widget_from_handle(Handle self,SV * handle)475 Application_get_widget_from_handle( Handle self, SV * handle)
476 {
477 	ApiHandle apiHandle;
478 	if ( SvIOK( handle))
479 		apiHandle = SvUVX( handle);
480 	else
481 		apiHandle = sv_2uv( handle);
482 	return apc_application_get_handle( self, apiHandle);
483 }
484 
485 Handle
Application_get_hint_widget(Handle self)486 Application_get_hint_widget( Handle self)
487 {
488 	return var->  hintWidget;
489 }
490 
491 static Bool
icon_notify(Handle self,Handle child,Handle icon)492 icon_notify ( Handle self, Handle child, Handle icon)
493 {
494 	if ( kind_of( child, CWindow) && (( PWidget) child)-> options. optOwnerIcon) {
495 		CWindow( child)-> set_icon( child, icon);
496 		PWindow( child)-> options. optOwnerIcon = 1;
497 	}
498 	return false;
499 }
500 
501 Handle
Application_icon(Handle self,Bool set,Handle icon)502 Application_icon( Handle self, Bool set, Handle icon)
503 {
504 	if ( var-> stage > csFrozen) return NULL_HANDLE;
505 
506 	if ( !set)
507 		return var-> icon;
508 
509 	if ( icon && !kind_of( icon, CImage)) {
510 		warn("Illegal object reference passed to Application::icon");
511 		return NULL_HANDLE;
512 	}
513 	if ( icon) {
514 		icon = ((( PImage) icon)-> self)-> dup( icon);
515 		++SvREFCNT( SvRV((( PAnyObject) icon)-> mate));
516 	}
517 	my-> first_that( self, (void*)icon_notify, (void*)icon);
518 	if ( var-> icon)
519 		my-> detach( self, var-> icon, true);
520 	var-> icon = icon;
521 	if ( icon && ( list_index_of( var-> components, icon) < 0))
522 		my-> attach( self, icon);
523 	return NULL_HANDLE;
524 }
525 
526 Handle
Application_get_focused_widget(Handle self)527 Application_get_focused_widget( Handle self)
528 {
529 	return apc_widget_get_focused();
530 }
531 
532 Handle
Application_get_active_window(Handle self)533 Application_get_active_window( Handle self)
534 {
535 	return apc_window_get_active();
536 }
537 
538 Bool
Application_autoClose(Handle self,Bool set,Bool autoClose)539 Application_autoClose( Handle self, Bool set, Bool autoClose)
540 {
541 	if ( !set)
542 		return var->  autoClose;
543 	return var-> autoClose = autoClose;
544 }
545 
546 SV *
Application_sys_action(char * dummy,char * params)547 Application_sys_action( char * dummy, char * params)
548 {
549 	char * i = apc_system_action( params);
550 	SV * ret = i ? newSVpv( i, 0) : NULL_SV;
551 	free( i);
552 	return ret;
553 }
554 
555 typedef struct _SingleColor
556 {
557 	Color color;
558 	int   index;
559 } SingleColor, *PSingleColor;
560 
561 
562 Color
Application_colorIndex(Handle self,Bool set,int index,Color color)563 Application_colorIndex( Handle self, Bool set, int index, Color color)
564 {
565 	if ( var->  stage > csFrozen) return clInvalid;
566 	if (( index < 0) || ( index > ciMaxId)) return clInvalid;
567 	if ( !set) {
568 		switch ( index) {
569 		case ciFore:
570 			return opt_InPaint ?
571 				CDrawable-> get_color ( self) : var-> colors[ index];
572 		case ciBack:
573 			return opt_InPaint ?
574 				CDrawable-> get_backColor ( self) : var-> colors[ index];
575 		default:
576 			return  var->  colors[ index];
577 		}
578 	} else {
579 		SingleColor s;
580 		s. color = color;
581 		s. index = index;
582 		if ( !opt_InPaint) my-> first_that( self, (void*)prima_single_color_notify, &s);
583 		if ( opt_InPaint) switch ( index) {
584 			case ciFore:
585 				CDrawable-> set_color ( self, color);
586 				break;
587 			case ciBack:
588 				CDrawable-> set_backColor ( self, color);
589 				break;
590 		}
591 		var-> colors[ index] = color;
592 	}
593 	return clInvalid;
594 }
595 
596 void
Application_set_font(Handle self,Font font)597 Application_set_font( Handle self, Font font)
598 {
599 	if ( !opt_InPaint) my-> first_that( self, (void*)prima_font_notify, &font);
600 	apc_font_pick( self, &font, & var-> font);
601 	if ( opt_InPaint) apc_gp_set_font ( self, &var-> font);
602 }
603 
604 Bool
Application_close(Handle self)605 Application_close( Handle self)
606 {
607 	if ( var->  stage > csNormal) return true;
608 	return my-> can_close( self) ? ( apc_application_close( self), true) : false;
609 }
610 
611 Bool
Application_insertMode(Handle self,Bool set,Bool insMode)612 Application_insertMode( Handle self, Bool set, Bool insMode)
613 {
614 	if ( !set)
615 		return apc_sys_get_insert_mode();
616 	return apc_sys_set_insert_mode( insMode);
617 }
618 
619 
620 Handle
Application_get_modal_window(Handle self,int modalFlag,Bool topMost)621 Application_get_modal_window( Handle self, int modalFlag, Bool topMost)
622 {
623 	if ( modalFlag == mtExclusive) {
624 		return topMost ? var-> topExclModal   : var-> exclModal;
625 	} else if ( modalFlag == mtShared) {
626 		return topMost ? var-> topSharedModal : var-> sharedModal;
627 	}
628 	return NULL_HANDLE;
629 }
630 
631 SV *
Application_get_monitor_rects(Handle self)632 Application_get_monitor_rects( Handle self)
633 {
634 	int i, nrects;
635 	Box * rects = apc_application_get_monitor_rects(self, &nrects);
636 	AV * ret = newAV();
637 	for ( i = 0; i < nrects; i++) {
638 		AV * rect = newAV();
639 		av_push( rect, newSViv( rects[i].x));
640 		av_push( rect, newSViv( rects[i].y));
641 		av_push( rect, newSViv( rects[i].width));
642 		av_push( rect, newSViv( rects[i].height));
643 		av_push( ret, newRV_noinc(( SV *) rect));
644 	}
645 	free(rects);
646 
647 	/* .. or return at least the current size */
648 	if ( nrects == 0) {
649 		AV * rect = newAV();
650 		Point sz = apc_application_get_size(self);
651 		av_push( rect, newSViv( 0));
652 		av_push( rect, newSViv( 0));
653 		av_push( rect, newSViv( sz.x));
654 		av_push( rect, newSViv( sz.y));
655 		av_push( ret, newRV_noinc(( SV *) rect));
656 	}
657 
658 	return newRV_noinc(( SV *) ret);
659 }
660 
661 
662 Handle
Application_get_parent(Handle self)663 Application_get_parent( Handle self)
664 {
665 	return NULL_HANDLE;
666 }
667 
668 Point
Application_get_scroll_rate(Handle self)669 Application_get_scroll_rate( Handle self)
670 {
671 	Point ret;
672 	ret. x = apc_sys_get_value( svAutoScrollFirst);
673 	ret. y = apc_sys_get_value( svAutoScrollNext);
674 	return ret;
675 }
676 
hshow(Handle self)677 static void hshow( Handle self)
678 {
679 	PWidget_vmt hintUnder = CWidget( var->  hintUnder);
680 	SV * text = hintUnder-> get_hint( var->  hintUnder);
681 	Point size  = hintUnder-> get_size( var->  hintUnder);
682 	Point s = my-> get_size( self);
683 	Point fin = {0,0};
684 	Point pos = fin;
685 	Point mouse = my-> get_pointerPos( self);
686 	Point hintSize;
687 	PWidget_vmt hintWidget = CWidget( var->  hintWidget);
688 
689 	apc_widget_map_points( var-> hintUnder, true, 1, &pos);
690 
691 	hintWidget-> set_text( var->  hintWidget, text);
692 	hintSize = hintWidget-> get_size( var->  hintWidget);
693 
694 	fin. x = mouse. x - 16;
695 	fin. y = pos. y - hintSize. y - 1;
696 	if ( fin. y > mouse. y - hintSize. y - 32) fin. y = mouse. y - hintSize. y - 32;
697 
698 	if ( fin. x + hintSize. x >= s. x) fin. x = pos. x - hintSize. x;
699 	if ( fin. x < 0) fin. x = 0;
700 	if ( fin. y + hintSize. y >= s. y) fin. y = pos. y - hintSize. y;
701 	if ( fin. y < 0) fin. y = pos. y + size. y + 1;
702 	if ( fin. y < 0) fin. y = 0;
703 
704 	hintWidget-> set_origin( var->  hintWidget, fin);
705 	hintWidget-> show( var->  hintWidget);
706 	hintWidget-> bring_to_front( var->  hintWidget);
707 }
708 
709 void
Application_HintTimer_handle_event(Handle timer,PEvent event)710 Application_HintTimer_handle_event( Handle timer, PEvent event)
711 {
712 	CComponent-> handle_event( timer, event);
713 	if ( event-> cmd == cmTimer) {
714 		Handle self = application;
715 		CTimer(timer)-> stop( timer);
716 		if ( var->  hintActive == 1) {
717 			Event ev = {cmHint};
718 			if (   !var->hintUnder
719 				|| apc_application_get_widget_from_point( self, my-> get_pointerPos(self)) != var->hintUnder
720 				|| PObject( var-> hintUnder)-> stage != csNormal)
721 				return;
722 			ev. gen. B = true;
723 			ev. gen. H = var->  hintUnder;
724 			var->  hintVisible = 1;
725 			if (( PWidget( var->  hintUnder)-> stage == csNormal) &&
726 				( CWidget( var->  hintUnder)-> message( var->  hintUnder, &ev)))
727 				hshow( self);
728 		} else if ( var->  hintActive == -1)
729 			var->  hintActive = 0;
730 	}
731 }
732 
733 void
Application_set_hint_action(Handle self,Handle view,Bool show,Bool byMouse)734 Application_set_hint_action( Handle self, Handle view, Bool show, Bool byMouse)
735 {
736 	if ( var-> stage >= csFrozen) return;
737 	if ( show && !is_opt( optShowHint)) return;
738 	if ( show)
739 	{
740 		var->  hintUnder = view;
741 		if ( var->  hintActive == -1)
742 		{
743 			Event ev = {cmHint};
744 			ev. gen. B = true;
745 			ev. gen. H = view;
746 			((( PTimer) var->  hintTimer)-> self)-> stop( var-> hintTimer);
747 			var->  hintVisible = 1;
748 			if (( PWidget( view)-> stage == csNormal) &&
749 				( CWidget( view)-> message( view, &ev)))
750 				hshow( self);
751 		} else {
752 			if ( !byMouse && var->  hintActive == 1) return;
753 			CTimer( var->  hintTimer)-> start( var-> hintTimer);
754 		}
755 		var->  hintActive = 1;
756 	} else {
757 		int oldHA = var->  hintActive;
758 		int oldHV = var->  hintVisible;
759 		if ( oldHA != -1)
760 			((( PTimer) var-> hintTimer)-> self)-> stop( var-> hintTimer);
761 		if ( var->  hintVisible)
762 		{
763 			Event ev = {cmHint};
764 			ev. gen. B = false;
765 			ev. gen. H = view;
766 			var->  hintVisible = 0;
767 			if (( PWidget( view)-> stage != csNormal) ||
768 				( CWidget( view)-> message( view, &ev)))
769 				CWidget( var->  hintWidget)-> hide( var->  hintWidget);
770 		}
771 		if ( oldHA != -1) var->  hintActive = 0;
772 		if ( byMouse && oldHV) {
773 			var->  hintActive = -1;
774 			CTimer( var->  hintTimer)-> start( var->  hintTimer);
775 		}
776 	}
777 }
778 
779 Color
Application_hintColor(Handle self,Bool set,Color hintColor)780 Application_hintColor( Handle self, Bool set, Color hintColor)
781 {
782 	if ( !set)
783 		return CWidget( var-> hintWidget)-> get_color( var->  hintWidget);
784 	return CWidget( var->  hintWidget)-> set_color( var->  hintWidget, hintColor);
785 }
786 
787 Color
Application_hintBackColor(Handle self,Bool set,Color hintBackColor)788 Application_hintBackColor( Handle self, Bool set, Color hintBackColor)
789 {
790 	if ( !set)
791 		return CWidget( var->  hintWidget)-> get_backColor( var-> hintWidget);
792 	return CWidget( var->  hintWidget)-> set_backColor( var->  hintWidget, hintBackColor);
793 }
794 
795 int
Application_hintPause(Handle self,Bool set,int hintPause)796 Application_hintPause( Handle self, Bool set, int hintPause)
797 {
798 	if ( !set)
799 		return CTimer( var->  hintTimer)-> get_timeout( var->  hintTimer);
800 	return CTimer( var->  hintTimer)-> set_timeout( var->  hintTimer, hintPause);
801 }
802 
803 void
Application_set_hint_font(Handle self,Font hintFont)804 Application_set_hint_font( Handle self, Font hintFont)
805 {
806 	CWidget( var-> hintWidget)-> set_font( var->  hintWidget, hintFont);
807 }
808 
809 
810 Font
Application_get_hint_font(Handle self)811 Application_get_hint_font( Handle self)
812 {
813 	return CWidget( var->  hintWidget)-> get_font( var->  hintWidget);
814 }
815 
816 Bool
Application_showHint(Handle self,Bool set,Bool showHint)817 Application_showHint( Handle self, Bool set, Bool showHint)
818 {
819 	if ( !set)
820 		return inherited showHint( self, set, showHint);
821 	opt_assign( optShowHint, showHint);
822 	return false;
823 }
824 
Application_next(Handle self)825 Handle Application_next( Handle self) { return self;}
Application_prev(Handle self)826 Handle Application_prev( Handle self) { return self;}
827 
828 Bool
Application_layered(Handle self,Bool set,Bool layered)829 Application_layered( Handle self, Bool set, Bool layered)
830 {
831 	return false;
832 }
833 
834 SV *
Application_palette(Handle self,Bool set,SV * palette)835 Application_palette( Handle self, Bool set, SV * palette)
836 {
837 	return CDrawable-> palette( self, set, palette);
838 }
839 
840 Handle
Application_top_frame(Handle self,Handle from)841 Application_top_frame( Handle self, Handle from)
842 {
843 	while ( from) {
844 		if (
845 			kind_of( from, CWindow) && (
846 			( PWidget( from)-> owner == application) ||
847 			!CWidget( from)-> get_clipOwner(from)
848 		))
849 			return from;
850 		from = PWidget( from)-> owner;
851 	}
852 	return application;
853 }
854 
855 Handle
Application_get_image(Handle self,int x,int y,int xLen,int yLen)856 Application_get_image( Handle self, int x, int y, int xLen, int yLen)
857 {
858 	HV * profile;
859 	Handle i;
860 	Bool ret;
861 	Point sz;
862 	if ( var->  stage > csFrozen) return NULL_HANDLE;
863 	if ( x < 0 || y < 0 || xLen <= 0 || yLen <= 0) return NULL_HANDLE;
864 	sz = apc_application_get_size( self);
865 	if ( x + xLen > sz. x) xLen = sz. x - x;
866 	if ( y + yLen > sz. y) yLen = sz. y - y;
867 	if ( x >= sz. x || y >= sz. y || xLen <= 0 || yLen <= 0) return NULL_HANDLE;
868 
869 	profile = newHV();
870 	i = Object_create( "Prima::Image", profile);
871 	sv_free(( SV *) profile);
872 	ret = apc_application_get_bitmap( self, i, x, y, xLen, yLen);
873 	--SvREFCNT( SvRV((( PAnyObject) i)-> mate));
874 	return ret ? i : NULL_HANDLE;
875 }
876 
877 /*
878 * Cannot return NULL_HANDLE.
879 */
880 Handle
Application_map_focus(Handle self,Handle from)881 Application_map_focus( Handle self, Handle from)
882 {
883 	Handle topFrame = my-> top_frame( self, from);
884 	Handle topShared;
885 
886 	if ( var->  topExclModal)
887 		return ( topFrame == var->  topExclModal) ? from : var->  topExclModal;
888 
889 	if ( !var->  topSharedModal && var->  modalHorizons. count == 0)
890 		return from; /* return from if no shared modals active */
891 
892 	if ( topFrame == self) {
893 		if ( !var->  topSharedModal) return from;
894 		topShared = var->  topSharedModal;
895 	} else {
896 		Handle horizon =
897 			( !CWindow( topFrame)-> get_modalHorizon( topFrame)) ?
898 			CWindow( topFrame)-> get_horizon( topFrame) : topFrame;
899 		if ( horizon == self)
900 			topShared = var->  topSharedModal;
901 		else
902 			topShared = PWindow( horizon)-> topSharedModal;
903 	}
904 
905 	return ( !topShared || ( topShared == topFrame)) ? from : topShared;
906 }
907 
908 static Handle
popup_win(Handle xTop)909 popup_win( Handle xTop)
910 {
911 	PWindow_vmt top = CWindow( xTop);
912 	if ( !top-> get_visible( xTop))
913 		top-> set_visible( xTop, 1);
914 	if ( top-> get_windowState( xTop) == wsMinimized)
915 		top-> set_windowState( xTop, wsNormal);
916 	top-> set_selected( xTop, 1);
917 	return xTop;
918 }
919 
920 Handle
Application_popup_modal(Handle self)921 Application_popup_modal( Handle self)
922 {
923 	Handle ha = apc_window_get_active();
924 	Handle xTop;
925 
926 	if ( var->  topExclModal) {
927 	/* checking exclusive modal chain */
928 		xTop = ( !ha || ( PWindow(ha)->modal == 0)) ? var->  exclModal : ha;
929 		while ( xTop) {
930 			if ( PWindow(xTop)-> nextExclModal) {
931 				CWindow(xTop)-> bring_to_front( xTop);
932 				xTop = PWindow(xTop)-> nextExclModal;
933 			} else {
934 				return popup_win( xTop);
935 			}
936 		}
937 	} else {
938 		if ( !var->  topSharedModal && var->  modalHorizons. count == 0)
939 			return NULL_HANDLE; /* return from if no shared modals active */
940 		/* checking shared modal chains */
941 		if ( ha) {
942 			xTop = ( PWindow(ha)->modal == 0) ? CWindow(ha)->get_horizon(ha) : ha;
943 			if ( xTop == application) xTop = var->  sharedModal;
944 		} else
945 			xTop = var->  sharedModal ? var->  sharedModal : var->  modalHorizons. items[ 0];
946 
947 		while ( xTop) {
948 			if ( PWindow(xTop)-> nextSharedModal) {
949 				CWindow(xTop)-> bring_to_front( xTop);
950 				xTop = PWindow(xTop)-> nextSharedModal;
951 			} else {
952 				return popup_win( xTop);
953 			}
954 		}
955 	}
956 
957 	return NULL_HANDLE;
958 }
959 
960 Bool
Application_pointerVisible(Handle self,Bool set,Bool pointerVisible)961 Application_pointerVisible( Handle self, Bool set, Bool pointerVisible)
962 {
963 	if ( !set)
964 		return apc_pointer_get_visible( self);
965 	return apc_pointer_set_visible( self, pointerVisible);
966 }
967 
968 Point
Application_size(Handle self,Bool set,Point size)969 Application_size( Handle self, Bool set, Point size)
970 {
971 	if ( set) return size;
972 	return apc_application_get_size( self);
973 }
974 
975 Point
Application_origin(Handle self,Bool set,Point origin)976 Application_origin( Handle self, Bool set, Point origin)
977 {
978 	Point p = { 0, 0};
979 	return p;
980 }
981 
982 Bool
Application_modalHorizon(Handle self,Bool set,Bool modalHorizon)983 Application_modalHorizon( Handle self, Bool set, Bool modalHorizon)
984 {
985 	return true;
986 }
987 
988 Bool
Application_textDirection(Handle self,Bool set,Bool textDirection)989 Application_textDirection( Handle self, Bool set, Bool textDirection)
990 {
991 	if ( !set ) return var->textDirection;
992 	return var-> textDirection = textDirection;
993 }
994 
995 #define UISCALING_STEP 4
996 double
Application_uiScaling(Handle self,Bool set,double uiScaling)997 Application_uiScaling( Handle self, Bool set, double uiScaling)
998 {
999 	if ( !set ) return var->uiScaling;
1000 	if ( uiScaling < 0.00001 ) {
1001 		Point res = my-> get_resolution(self);
1002 		uiScaling  = (double)((int)((double) res.x/ (96.0/UISCALING_STEP) + 0.5)) / UISCALING_STEP; /* 96-143 = 1.5, 144-191 = 1.5 etc */
1003 		if ( uiScaling < 0.25 ) uiScaling = 0.25;
1004 	}
1005 	return var-> uiScaling = uiScaling;
1006 }
1007 
1008 Bool
Application_wantUnicodeInput(Handle self,Bool set,Bool want_ui)1009 Application_wantUnicodeInput( Handle self, Bool set, Bool want_ui)
1010 {
1011 	if ( !set) return var-> wantUnicodeInput;
1012 	if ( apc_sys_get_value( svCanUTF8_Input))
1013 		var-> wantUnicodeInput = want_ui;
1014 	return 0;
1015 }
1016 
1017 
Application_update_sys_handle(Handle self,HV * profile)1018 void   Application_update_sys_handle( Handle self, HV * profile) {}
Application_get_capture(Handle self)1019 Bool   Application_get_capture( Handle self) { return false; }
Application_set_capture(Handle self,Bool capture,Handle confineTo)1020 Bool   Application_set_capture( Handle self, Bool capture, Handle confineTo) { return false; }
Application_set_centered(Handle self,Bool x,Bool y)1021 void   Application_set_centered( Handle self, Bool x, Bool y) {}
1022 
Application_tabStop(Handle self,Bool set,Bool tabStop)1023 Bool   Application_tabStop( Handle self, Bool set, Bool tabStop)       { return false; }
Application_selectable(Handle self,Bool set,Bool selectable)1024 Bool   Application_selectable( Handle self, Bool set, Bool selectable) { return false; }
Application_shape(Handle self,Bool set,Handle mask)1025 Handle Application_shape( Handle self, Bool set, Handle mask)          { return NULL_HANDLE; }
Application_syncPaint(Handle self,Bool set,Bool syncPaint)1026 Bool   Application_syncPaint( Handle self, Bool set, Bool syncPaint)   { return false; }
Application_visible(Handle self,Bool set,Bool visible)1027 Bool   Application_visible( Handle self, Bool set, Bool visible)       { return true; }
Application_buffered(Handle self,Bool set,Bool buffered)1028 Bool   Application_buffered( Handle self, Bool set, Bool buffered)     { return false; }
Application_enabled(Handle self,Bool set,Bool enable)1029 Bool   Application_enabled( Handle self, Bool set, Bool enable)        { return true;}
Application_growMode(Handle self,Bool set,int flags)1030 int    Application_growMode( Handle self, Bool set, int flags)         { return 0; }
Application_hintVisible(Handle self,Bool set,Bool visible)1031 Bool   Application_hintVisible( Handle self, Bool set, Bool visible)   { return false; }
Application_owner(Handle self,Bool set,Handle owner)1032 Handle Application_owner( Handle self, Bool set, Handle owner)         { return NULL_HANDLE; }
Application_ownerColor(Handle self,Bool set,Bool ownerColor)1033 Bool   Application_ownerColor( Handle self, Bool set, Bool ownerColor) { return false; }
Application_ownerBackColor(Handle self,Bool set,Bool ownerBackColor)1034 Bool   Application_ownerBackColor( Handle self, Bool set, Bool ownerBackColor) { return false; }
Application_ownerFont(Handle self,Bool set,Bool ownerFont)1035 Bool   Application_ownerFont( Handle self, Bool set, Bool ownerFont)   { return false; }
Application_ownerShowHint(Handle self,Bool set,Bool ownerShowHint)1036 Bool   Application_ownerShowHint( Handle self, Bool set, Bool ownerShowHint) { return false; }
Application_ownerPalette(Handle self,Bool set,Bool ownerPalette)1037 Bool   Application_ownerPalette( Handle self, Bool set, Bool ownerPalette) { return false; }
Application_clipChildren(Handle self,Bool set,Bool clip)1038 Bool   Application_clipChildren( Handle self, Bool set, Bool clip)   { return true; }
Application_clipOwner(Handle self,Bool set,Bool clip_by_children)1039 Bool   Application_clipOwner( Handle self, Bool set, Bool clip_by_children)   { return false; }
Application_tabOrder(Handle self,Bool set,int tabOrder)1040 int    Application_tabOrder( Handle self, Bool set, int tabOrder)      { return 0; }
Application_get_text(Handle self)1041 SV   * Application_get_text    ( Handle self)                          { return NULL_SV; }
Application_set_text(Handle self,SV * text)1042 void   Application_set_text    ( Handle self, SV * text)               { }
Application_transparent(Handle self,Bool set,Bool transparent)1043 Bool   Application_transparent( Handle self, Bool set, Bool transparent) { return false; }
Application_validate_owner(Handle self,Handle * owner,HV * profile)1044 Bool   Application_validate_owner( Handle self, Handle * owner, HV * profile) { *owner = NULL_HANDLE; return true; }
1045 
1046 #ifdef __cplusplus
1047 }
1048 #endif
1049