#include <apricot.h>
#include "unix/guts.h"
Bool
apc_component_create( Handle self)
{
if
( !PComponent( self)-> sysData) {
if
( !( PComponent( self)-> sysData =
malloc
(
sizeof
( UnixSysData))))
return
false
;
bzero( PComponent( self)-> sysData,
sizeof
( UnixSysData));
((PUnixSysData)(PComponent(self)->sysData))->component. self = self;
}
return
true
;
}
Bool
apc_component_destroy( Handle self)
{
DEFXX;
if
( XX-> q_instance_name) {
free
( XX-> q_instance_name);
XX-> q_instance_name = NULL;
}
if
( XX-> q_class_name) {
free
( XX-> q_class_name);
XX-> q_class_name = NULL;
}
free
( PComponent( self)-> sysData);
PComponent( self)-> sysData = NULL;
X_WINDOW = NULL_HANDLE;
return
true
;
}
Bool
apc_component_fullname_changed_notify( Handle self)
{
Handle *list;
PComponent me = PComponent( self);
int
i, n;
if
( self == NULL_HANDLE)
return
false
;
if
(!prima_update_quarks_cache( self))
return
false
;
if
( me-> components && (n = me-> components-> count) > 0) {
if
( !( list = allocn( Handle, n)))
return
false
;
memcpy
( list, me-> components-> items,
sizeof
( Handle) * n);
for
( i = 0; i < n; i++) {
apc_component_fullname_changed_notify( list[i]);
}
free
( list);
}
return
true
;
}
int
apc_kbd_get_state( Handle self)
{
XWindow foo;
int
bar;
unsigned
int
mask;
XQueryPointer( DISP, guts.root, &foo, &foo, &bar, &bar, &bar, &bar, &mask);
return
(( mask & ShiftMask) ? kmShift : 0) |
(( mask & ControlMask) ? kmCtrl : 0) |
(( mask & Mod1Mask) ? kmAlt : 0);
}
static
void
close_msgdlg(
struct
MsgDlg * md)
{
md-> active =
false
;
md-> pressed =
false
;
if
( md-> grab)
XUngrabPointer( DISP, CurrentTime);
md-> grab =
false
;
XUnmapWindow( DISP, md-> w);
XFlush( DISP);
if
( md-> next == NULL) {
XSetInputFocus( DISP, md-> focus, md-> focus_revertTo, CurrentTime);
XCHECKPOINT;
}
}
void
prima_msgdlg_event( XEvent * ev,
struct
MsgDlg * md)
{
XWindow w = ev-> xany. window;
switch
( ev-> type) {
case
ConfigureNotify:
md-> winSz. x = ev-> xconfigure. width;
md-> winSz. y = ev-> xconfigure. height;
break
;
case
Expose:
{
int
i, y = md-> textPos. y;
int
d = md-> pressed ? 2 : 0;
XSetForeground( DISP, md-> gc, md-> bg. primary);
if
( md-> bg. balance > 0) {
Pixmap p = prima_get_hatch( &guts. ditherPatterns[ md-> bg. balance]);
if
( p) {
XSetStipple( DISP, md-> gc, p);
XSetFillStyle( DISP, md-> gc, FillOpaqueStippled);
XSetBackground( DISP, md-> gc, md-> bg. secondary);
}
}
XFillRectangle( DISP, w, md-> gc, 0, 0, md-> winSz.x, md-> winSz.y);
if
( md-> bg. balance > 0)
XSetFillStyle( DISP, md-> gc, FillSolid);
XSetForeground( DISP, md-> gc, md-> fg);
for
( i = 0; i < md-> wrappedCount; i++) {
if
( md-> wide)
XDrawString16( DISP, w, md-> gc,
( md-> winSz.x - md-> widths[i]) / 2, y,
( XChar2b*) md-> wrapped[i], md-> lengths[i]);
else
XDrawString( DISP, w, md-> gc,
( md-> winSz.x - md-> widths[i]) / 2, y,
md-> wrapped[i], md-> lengths[i]);
y += md-> font-> height + md-> font-> externalLeading;
}
XDrawRectangle( DISP, w, md-> gc,
md-> btnPos.x-1, md-> btnPos.y-1, md-> btnSz.x+2, md-> btnSz.y+2);
XDrawString( DISP, w, md-> gc,
md-> btnPos.x + ( md-> btnSz.x - md-> OKwidth) / 2 + d,
md-> btnPos.y + md-> font-> height + md-> font-> externalLeading +
( md-> btnSz.y - md-> font-> height - md-> font-> externalLeading) / 2 - 2 + d,
"OK"
, 2);
XSetForeground( DISP, md-> gc,
md-> pressed ? md-> d3d : md-> l3d);
XDrawLine( DISP, w, md-> gc,
md-> btnPos.x, md-> btnPos.y + md-> btnSz.y - 1,
md-> btnPos.x, md-> btnPos. y);
XDrawLine( DISP, w, md-> gc,
md-> btnPos.x + 1, md-> btnPos. y,
md-> btnPos.x + md-> btnSz.x - 1, md-> btnPos. y);
XSetForeground( DISP, md-> gc,
md-> pressed ? md-> l3d : md-> d3d);
XDrawLine( DISP, w, md-> gc,
md-> btnPos.x, md-> btnPos.y + md-> btnSz.y,
md-> btnPos.x + md-> btnSz.x, md-> btnPos.y + md-> btnSz.y);
XDrawLine( DISP, w, md-> gc,
md-> btnPos.x + md-> btnSz.x, md-> btnPos.y + md-> btnSz.y - 1,
md-> btnPos.x + md-> btnSz.x, md-> btnPos.y + 1);
}
break
;
case
ButtonPress:
if
( !md-> grab &&
( ev-> xbutton. button == Button1) &&
( ev-> xbutton. x >= md-> btnPos. x ) &&
( ev-> xbutton. x < md-> btnPos. x + md-> btnSz.x) &&
( ev-> xbutton. y >= md-> btnPos. y ) &&
( ev-> xbutton. y < md-> btnPos. y + md-> btnSz.y)) {
md-> pressed =
true
;
md-> grab =
true
;
XClearArea( DISP, w, md-> btnPos.x, md-> btnPos.y,
md-> btnSz.x, md-> btnSz.y,
true
);
XGrabPointer( DISP, w,
false
,
ButtonReleaseMask | PointerMotionMask | ButtonMotionMask,
GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
}
break
;
case
MotionNotify:
if
( md-> grab) {
Bool np =
(( ev-> xmotion. x >= md-> btnPos. x ) &&
( ev-> xmotion. x < md-> btnPos. x + md-> btnSz.x) &&
( ev-> xmotion. y >= md-> btnPos. y ) &&
( ev-> xmotion. y < md-> btnPos. y + md-> btnSz.y));
if
( np != md-> pressed) {
md-> pressed = np;
XClearArea( DISP, w, md-> btnPos.x, md-> btnPos.y,
md-> btnSz.x, md-> btnSz.y,
true
);
}
}
break
;
case
KeyPress:
{
char
str_buf[256];
KeySym keysym;
int
str_len = XLookupString( &ev-> xkey, str_buf, 256, &keysym, NULL);
if
(
( keysym == XK_Return) ||
( keysym == XK_Escape) ||
( keysym == XK_KP_Enter) ||
( keysym == XK_KP_Space) ||
(( str_len == 1) && ( str_buf[0] ==
' '
))
)
close_msgdlg( md);
}
break
;
case
ButtonRelease:
if
( md-> grab &&
( ev-> xbutton. button == Button1)) {
md-> grab =
false
;
XUngrabPointer( DISP, CurrentTime);
if
( md-> pressed) close_msgdlg( md);
}
break
;
case
ClientMessage:
if
(( ev-> xclient. message_type == WM_PROTOCOLS) &&
(( Atom) ev-> xclient. data. l[0] == WM_DELETE_WINDOW))
close_msgdlg( md);
break
;
}
}
Bool
apc_show_message(
const
char
* message, Bool utf8)
{
int
* wrapped;
Font f;
Point appSz, appPos;
Point textSz;
Point winSz;
TextWrapRec twr;
int
i, j;
struct
MsgDlg md, **storage;
Bool ret =
false
;
PList font_abc_unicode = NULL;
PFontABC font_abc_ascii = NULL;
XFontStruct *fs = NULL;
if
( !DISP) {
warn(
"%s"
, message);
return
true
;
}
if
( guts. grab_widget)
apc_widget_set_capture( guts. grab_widget, 0, 0);
appSz = apc_application_get_size( NULL_HANDLE);
appPos.x = 0;
appPos.y = 0;
{
int
i, nrects = 0;
Box *best = NULL, *rects = apc_application_get_monitor_rects( prima_guts.application, &nrects);
for
( i = 0; i < nrects; i++) {
Box * curr = rects + i;
if
( best == NULL || best-> x > curr->x || best->y > curr->y)
best = curr;
}
if
( best ) {
appPos.x = best->x;
appPos.y = best->y;
appSz.x = best->width;
appSz.y = best->height;
}
}
{
PCachedFont cf;
int
max;
apc_sys_get_msg_font( &f);
f. pitch = fpDefault;
#define DEBUG_FONT(font) font.height,font.width,font.size,font.name,font.encoding
if
( !( cf = prima_font_pick( &f, NULL, NULL, FONTKEY_CORE))) {
warn(
"%s"
, message);
return
false
;
}
fs = XQueryFont( DISP, cf-> id);
if
(!fs) {
warn(
"%s"
, message);
return
false
;
}
bzero(&twr,
sizeof
(twr));
twr. text = (
char
*) message;
twr. utf8_text = utf8;
twr. textLen =
strlen
( message);
twr. utf8_textLen = utf8 ? prima_utf8_length( message, -1) : twr. textLen;
twr. width = appSz. x * 2 / 3;
twr. tabIndent = 3;
twr. options = twNewLineBreak | twWordBreak | twReturnLines;
twr. ascii = &font_abc_ascii;
twr. unicode = &font_abc_unicode;
guts. font_abc_nil_hack = fs;
wrapped = CDrawable->do_text_wrap( NULL_HANDLE, &twr, NULL, NULL);
if
( font_abc_ascii)
free
( font_abc_ascii);
if
( font_abc_unicode) {
for
( i = 0; i < font_abc_unicode-> count; i += 2)
free
((
void
*) font_abc_unicode-> items[ i + 1]);
plist_destroy( font_abc_unicode);
}
md.wrappedCount = md.count = twr.count / 4;
if
( !( md.widths =
malloc
( md.count *
sizeof
(
int
))))
goto
EXIT;
if
( !( md.lengths =
malloc
( md.count *
sizeof
(
int
))))
goto
EXIT;
if
( !( md.wrapped =
malloc
( md.count *
sizeof
(
char
*))))
goto
EXIT;
bzero(md.wrapped, md.count *
sizeof
(
char
*));
max = 0;
for
( i = j = 0; i < md.count; i++, j += 4) {
md.lengths[i] = wrapped[j+3];
if
(utf8) {
if
(!(md.wrapped[i] = (
char
*)prima_alloc_utf8_to_wchar( message + wrapped[j], md.lengths[i])))
goto
EXIT;
md.widths[i] = XTextWidth16( fs, (XChar2b*) md.wrapped[i], md.lengths[i]);
}
else
{
if
(!(md.wrapped[i] =
malloc
( md.lengths[i] + 1)))
goto
EXIT;
memcpy
(md.wrapped[i], message + wrapped[j], md.lengths[i]);
md.wrapped[i][md.lengths[i]] = 0;
md. widths[i] = XTextWidth( fs, md.wrapped[i], md.lengths[i]);
}
if
( md. widths[i] > max) max = md. widths[i];
}
textSz. x = max;
textSz. y = md.count * ( f. height + f. externalLeading);
md. font = &f;
md. fontId = cf-> id;
md. OKwidth = XTextWidth( fs,
"OK"
, 2);
md. btnSz.x = md. OKwidth + 2 + 10;
if
( md. btnSz. x < 56) md. btnSz. x = 56;
md. btnSz.y = f. height + f. externalLeading + 2 + 12;
winSz. x = textSz. x + 4;
if
( winSz. x < md. btnSz. x + 2) winSz. x = md. btnSz.x + 2;
winSz. x += f. width * 4;
winSz. y = textSz. y + 2 + 12 + md. btnSz. y + f. height;
while
( winSz. y + 12 >= appSz.y) {
winSz. y -= f. height + f. externalLeading;
md. wrappedCount--;
}
md. btnPos. x = ( winSz. x - md. btnSz. x) / 2;
md. btnPos. y = winSz. y - 2 - md. btnSz. y - f. height / 2;
md. textPos. x = 2;
md. textPos. y = f. height * 3 / 2 + 2;
md. winSz = winSz;
}
md. wide = utf8;
md. active =
true
;
md. next = NULL;
md. pressed =
false
;
md. grab =
false
;
XGetInputFocus( DISP, &md. focus, &md. focus_revertTo);
XCHECKPOINT;
{
char
* prima =
"Prima"
;
XTextProperty p;
XSizeHints xs;
XSetWindowAttributes attrs;
Atom net_data[2];
attrs. event_mask = 0
| KeyPressMask
| ButtonPressMask
| ButtonReleaseMask
| ButtonMotionMask
| PointerMotionMask
| StructureNotifyMask
| ExposureMask;
attrs. override_redirect =
false
;
attrs. do_not_propagate_mask = attrs. event_mask;
md. w = XCreateWindow( DISP, guts. root,
appPos.x + ( appSz.x - winSz.x) / 2, appPos.y + ( appSz.y - winSz.y) / 2,
winSz.x, winSz.y, 0, CopyFromParent, InputOutput,
CopyFromParent, CWEventMask | CWOverrideRedirect, &attrs);
XCHECKPOINT;
if
( !md. w)
goto
EXIT;
XSetWMProtocols( DISP, md. w, &WM_DELETE_WINDOW, 1);
XCHECKPOINT;
xs. flags = PMinSize | PMaxSize | USPosition;
xs. min_width = xs. max_width = winSz.x;
xs. min_height = xs. max_height = winSz. y;
xs. x = appPos.x + ( appSz.x - winSz.x) / 2;
xs. y = appPos.y + ( appSz.y - winSz.y) / 2;
XSetWMNormalHints( DISP, md. w, &xs);
if
( XStringListToTextProperty( &prima, 1, &p) != 0) {
XSetWMIconName( DISP, md. w, &p);
XSetWMName( DISP, md. w, &p);
XFree( p. value);
}
net_data[0] = NET_WM_STATE_SKIP_TASKBAR;
net_data[1] = NET_WM_STATE_MODAL;
XChangeProperty( DISP, md. w, NET_WM_STATE, XA_ATOM, 32,
PropModeReplace, ( unsigned
char
*) net_data, 2);
}
storage = &guts. message_boxes;
while
( *storage) storage = &((*storage)-> next);
*storage = &md;
{
#define CLR(x) prima_allocate_color( NULL_HANDLE,prima_map_color(x,NULL),NULL)
XGCValues gcv;
gcv. font = md. fontId;
gcv. cap_style = CapProjecting;
md. gc = XCreateGC( DISP, md. w, GCFont | GCCapStyle, &gcv);
md. fg = CLR(clFore | wcDialog);
prima_allocate_color( NULL_HANDLE, prima_map_color(clBack | wcDialog,NULL), &md. bg);
md. l3d = CLR(clLight3DColor | wcDialog);
md. d3d = CLR(clDark3DColor | wcDialog);
#undef CLR
}
XMapWindow( DISP, md. w);
XMoveResizeWindow( DISP, md. w,
appPos.x + ( appSz.x - winSz.x) / 2, appPos.y + ( appSz.y - winSz.y) / 2, winSz.x, winSz.y);
XNoOp( DISP);
while
( md. active && !guts. applicationClose) {
XFlush( DISP);
prima_one_loop_round( WAIT_ALWAYS,
false
);
}
XFreeGC( DISP, md. gc);
XDestroyWindow( DISP, md. w);
*storage = md. next;
ret =
true
;
EXIT:
XFreeFontInfo( NULL, fs, 1);
if
( md.widths )
free
( md.widths);
if
( md.lengths)
free
( md.lengths);
if
( md.wrapped ) {
for
( i = 0; i < md.count; i++)
free
(md.wrapped[i]);
free
(md.wrapped);
}
md.wrappedCount = 0;
return
ret;
}
Bool
apc_sys_get_insert_mode(
void
)
{
return
guts. insert;
}
PFont
apc_sys_get_msg_font( PFont f)
{
memcpy
( f, &guts. default_msg_font,
sizeof
( Font));
return
f;
}
PFont
apc_sys_get_caption_font( PFont f)
{
memcpy
( f, &guts. default_caption_font,
sizeof
( Font));
return
f;
}
static
int
is_composite_display(
void
)
{
if
( guts. argb_visual. visual == NULL )
return
false
;
#ifndef HAVE_X11_EXTENSIONS_XCOMPOSITE_H
return
-1;
#else
XCHECKPOINT;
guts. composite_error_triggered =
false
;
XCompositeRedirectSubwindows( DISP, guts.root, CompositeRedirectManual);
XCHECKPOINT;
XSync(DISP,
false
);
if
( guts. composite_error_triggered )
return
true
;
XCompositeUnredirectSubwindows( DISP, guts.root, CompositeRedirectManual);
XCHECKPOINT;
XSync(DISP,
false
);
if
( guts. composite_error_triggered )
return
true
;
return
false
;
#endif
}
int
apc_sys_get_value(
int
v)
{
switch
( v) {
case
svYMenu: {
Font f;
apc_menu_default_font( &f);
return
f. height + MENU_ITEM_GAP * 2;
}
case
svYTitleBar:
return
20;
case
svMousePresent:
return
guts. mouse_buttons > 0;
case
svMouseButtons:
return
guts. mouse_buttons;
case
svSubmenuDelay:
return
guts. menu_timeout;
case
svFullDrag:
return
false
;
case
svWheelPresent:
return
guts.mouse_wheel_up || guts.mouse_wheel_down;
case
svXIcon:
case
svYIcon:
case
svXSmallIcon:
case
svYSmallIcon:
{
int
ret[4], n;
XIconSize * sz = NULL;
if
( XGetIconSizes( DISP, guts.root, &sz, &n) && ( n > 0) && (sz != NULL)) {
ret[0] = sz-> max_width;
ret[1] = sz-> max_height;
ret[2] = sz-> min_width;
ret[3] = sz-> min_height;
}
else
{
ret[0] = ret[1] = 64;
ret[2] = ret[3] = 20;
}
if
( sz) XFree( sz);
return
ret[v - svXIcon];
}
break
;
case
svXPointer:
return
guts. cursor_width;
case
svYPointer:
return
guts. cursor_height;
case
svXScrollbar:
return
19;
case
svYScrollbar:
return
19;
case
svXCursor:
return
1;
case
svAutoScrollFirst:
return
guts. scroll_first;
case
svAutoScrollNext:
return
guts. scroll_next;
case
svXbsNone:
return
0;
case
svYbsNone:
return
0;
case
svXbsSizeable:
return
3;
case
svYbsSizeable:
return
3;
case
svXbsSingle:
return
1;
case
svYbsSingle:
return
1;
case
svXbsDialog:
return
2;
case
svYbsDialog:
return
2;
case
svShapeExtension:
return
guts. shape_extension;
case
svDblClickDelay:
return
guts. double_click_time_frame;
case
svColorPointer:
return
#ifdef HAVE_X11_XCURSOR_XCURSOR_H
1
#else
0
#endif
;
case
svCanUTF8_Input:
return
1;
case
svCanUTF8_Output:
return
1;
case
svCompositeDisplay:
return
is_composite_display();
case
svLayeredWidgets:
return
guts. argb_visual. visual != NULL;
case
svFixedPointerSize:
return
#ifdef HAVE_X11_XCURSOR_XCURSOR_H
0
#else
1
#endif
;
case
svMenuCheckSize :
return
MENU_CHECK_XOFFSET;
case
svFriBidi :
return
prima_guts.use_fribidi;
case
svLibThai :
return
prima_guts.use_libthai;
case
svAntialias :
return
guts. argb_visual. visual != NULL;
default
:
return
-1;
}
}
Bool
apc_sys_set_insert_mode( Bool insMode)
{
guts. insert = !!insMode;
return
true
;
}
Bool
apc_beep(
int
style)
{
if
( DISP)
XBell( DISP, 0);
return
true
;
}
Bool
apc_beep_tone(
int
freq,
int
duration)
{
XKeyboardControl xkc;
XKeyboardState xks;
struct
timeval timeout;
if
( !DISP)
return
false
;
XGetKeyboardControl( DISP, &xks);
xkc. bell_pitch = freq;
xkc. bell_duration = duration;
XChangeKeyboardControl( DISP, KBBellPitch | KBBellDuration, &xkc);
XBell( DISP, 100);
XFlush( DISP);
xkc. bell_pitch = xks. bell_pitch;
xkc. bell_duration = xks. bell_duration;
XChangeKeyboardControl( DISP, KBBellPitch | KBBellDuration, &xkc);
timeout. tv_sec = duration / 1000;
timeout. tv_usec = 1000 * (duration % 1000);
select( 0, NULL, NULL, NULL, &timeout);
return
true
;
}
char
*
apc_system_action(
const
char
*s)
{
int
l =
strlen
( s);
switch
(*s) {
case
'b'
:
if
( l == 7 &&
strcmp
( s,
"browser"
) == 0)
return
duplicate_string(
"netscape"
);
break
;
case
'c'
:
if
( l == 19 &&
strcmp
( s,
"can.shape.extension"
) == 0 && guts.shape_extension)
return
duplicate_string(
"yes"
);
else
if
( l == 26 &&
strcmp
( s,
"can.shared.image.extension"
) == 0 && guts.shared_image_extension)
return
duplicate_string(
"yes"
);
break
;
case
'D'
:
if
( l == 7 && (
strcmp
( s,
"Display"
) == 0)) {
char
* c =
malloc
(19);
if
( c) snprintf( c, 18,
"0x%p"
, DISP);
return
c;
}
break
;
case
'g'
:
if
( l > 15 &&
strncmp
(
"get.frame.info "
, s, 15) == 0) {
char
*end;
XWindow w =
strtoul
( s + 15, &end, 0);
Handle self;
Rect r;
char
buf[ 80];
if
(*end ==
'\0'
&&
( self = prima_xw2h( w)) &&
prima_get_frame_info( self, &r) &&
snprintf( buf,
sizeof
(buf),
"%d %d %d %d"
, r.left, r.bottom, r.right, r.top) <
sizeof
(buf))
return
duplicate_string( buf);
return
duplicate_string(
""
);
}
else
if
(
strncmp
( s,
"gtk.OpenFile."
, 13) == 0) {
s += 13;
#ifdef WITH_GTK
if
( guts. use_gtk )
return
prima_gtk_openfile((
char
*) s);
#endif
return
NULL;
}
break
;
case
'l'
:
if
(
strncmp
( s,
"local_display"
,
strlen
(
"local_display"
)) == 0) {
return
guts.x11_local ? duplicate_string(
"1"
) : NULL;
}
break
;
case
'r'
:
if
(
strncmp
( s,
"resolution"
, 10) == 0) {
int
dx, dy;
int
i =
sscanf
( s + 10,
"%u %u"
, &dx, &dy);
if
( i != 2 || (dx < 1 || dy < 1)) {
warn(
"Bad resolution\n"
);
return
0;
}
guts. resolution. x = dx;
guts. resolution. y = dy;
return
NULL;
}
break
;
case
's'
:
if
(
strcmp
(
"synchronize"
, s) == 0) {
XSynchronize( DISP,
true
);
return
NULL;
}
if
(
strncmp
(
"setfont "
, s, 8) == 0) {
Handle self = NULL_HANDLE;
char
font[1024];
XWindow win;
int
i =
sscanf
( s + 8,
"%lu %s"
, &win, font);
if
( i != 2 || !(self = prima_xw2h( win))) {
warn(
"Bad parameters to sysaction setfont"
);
return
0;
}
if
( !opt_InPaint)
return
0;
XSetFont( DISP, X(self)-> gc, XLoadFont( DISP, font));
return
NULL;
}
if
(
strcmp
(
"shaper"
, s) == 0) {
char
shaper[64] =
""
;
#ifdef USE_XFT
if
( guts. use_xft )
strcat
(shaper,
"xft "
);
#endif
#ifdef WITH_HARFBUZZ
if
( guts. use_harfbuzz )
strcat
(shaper,
"harfbuzz "
);
#endif
#ifdef WITH_FREETYPE
if
( guts. use_freetype )
strcat
(shaper,
"freetype "
);
#endif
shaper[
strlen
(shaper)-1] = 0;
return
duplicate_string(shaper);
}
break
;
case
't'
:
if
(
strncmp
(
"textout16 "
, s, 10) == 0) {
Handle self = NULL_HANDLE;
unsigned
char
text[1024];
XWindow win;
int
x, y, len;
int
i =
sscanf
( s + 10,
"%lu %d %d %s"
, &win, &x, &y, text);
if
( i != 4 || !(self = prima_xw2h( win))) {
warn(
"Bad parameters to sysaction textout16"
);
return
0;
}
if
( !opt_InPaint)
return
0;
len =
strlen
((
char
*) text);
for
( i = 0; i < len; i++)
if
( text[i]==255) text[i] = 0;
XDrawString16( DISP, win, X(self)-> gc, x, y, ( XChar2b *) text, len / 2);
return
NULL;
}
break
;
case
'u'
:
if
(
strcmp
( s,
"unix_guts"
) == 0)
return
(
char
*) &guts;
break
;
case
'x'
:
if
(
strncmp
(s,
"xquartz."
, 8) == 0) {
s += 8;
#ifdef WITH_COCOA
if
( guts. use_quartz )
return
prima_cocoa_system_action((
char
*) s);
#endif
return
NULL;
}
break
;
case
'X'
:
if
(
strcmp
( s,
"XOpenDisplay"
) == 0) {
char
err_buf[512];
if
( DISP)
return
duplicate_string(
"X display already opened"
);
window_subsystem_set_option(
"yes-x11"
, NULL);
if
( !window_subsystem_init( err_buf))
return
duplicate_string( err_buf);
return
NULL;
}
break
;
}
warn(
"Unknown sysaction:%s"
, s);
return
NULL;
}
Bool
apc_query_drives_map(
const
char
* firstDrive,
char
*result,
int
len)
{
if
( !result || len <= 0)
return
true
;
*result = 0;
return
true
;
}
int
apc_query_drive_type(
const
char
*drive)
{
return
dtNone;
}
char
*
apc_get_user_name(
void
)
{
char
* c = getlogin();
return
c ? c :
""
;
}
Bool
apc_dl_export(
char
*path)
{
return
true
;
}
void
prima_rect_union( XRectangle *t,
const
XRectangle *s)
{
XRectangle r;
if
( t-> x < s-> x) r. x = t-> x;
else
r. x = s-> x;
if
( t-> y < s-> y) r. y = t-> y;
else
r. y = s-> y;
if
( t-> x + t-> width > s-> x + s-> width)
r. width = t-> x + t-> width - r. x;
else
r. width = s-> x + s-> width - r. x;
if
( t-> y + t-> height > s-> y + s-> height)
r. height = t-> y + t-> height - r. y;
else
r. height = s-> y + s-> height - r. y;
*t = r;
}
void
prima_rect_intersect( XRectangle *t,
const
XRectangle *s)
{
XRectangle r;
int
w, h;
if
( t-> x > s-> x) r. x = t-> x;
else
r. x = s-> x;
if
( t-> y > s-> y) r. y = t-> y;
else
r. y = s-> y;
if
( t-> x + t-> width < s-> x + s-> width)
w = t-> x + (
int
)t-> width - r. x;
else
w = s-> x + (
int
)s-> width - r. x;
if
( t-> y + t-> height < s-> y + s-> height)
h = t-> y + (
int
)t-> height - r. y;
else
h = s-> y + (
int
)s-> height - r. y;
if
( w < 0 || h < 0) {
r. x = 0; r. y = 0; r. width = 0; r. height = 0;
}
else
{
r. width = w; r. height = h;
}
*t = r;
}
void
prima_utf8_to_wchar(
const
char
* utf8, XChar2b * u16,
int
src_len_bytes,
int
target_len_xchars )
{
unsigned
int
charlen;
while
( target_len_xchars--) {
register
UV u = prima_utf8_uvchr(utf8, src_len_bytes, &charlen);
if
( u < 0x10000) {
u16-> byte1 = u >> 8;
u16-> byte2 = u & 0xff;
}
else
u16-> byte1 = u16-> byte2 = 0xff;
u16++;
utf8 += charlen;
src_len_bytes -= charlen;
if
( src_len_bytes <= 0 || charlen == 0)
break
;
}
}
XChar2b *
prima_alloc_utf8_to_wchar(
const
char
* utf8,
int
length_chars)
{
XChar2b * ret;
if
( length_chars < 0) length_chars = prima_utf8_length( utf8, -1) + 1;
if
( !( ret =
malloc
( length_chars *
sizeof
( XChar2b))))
return
NULL;
prima_utf8_to_wchar( utf8, ret,
strlen
(utf8), length_chars);
return
ret;
}
void
prima_wchar2char(
char
* dest, XChar2b * src,
int
lim)
{
if
( lim < 1)
return
;
while
( lim-- && src-> byte1 && src-> byte2) *(dest++) = (src++)-> byte2;
if
( lim < 0) dest--;
*dest = 0;
}
void
prima_char2wchar( XChar2b * dest,
char
* src,
int
lim)
{
int
l =
strlen
( src) + 1;
if
( lim < 1)
return
;
if
( lim > l) lim = l;
src += lim - 2;
dest += lim - 1;
dest-> byte1 = dest-> byte2 = 0;
dest--;
while
( lim--) {
dest-> byte2 = *(src--);
dest-> byte1 = 0;
dest--;
}
}
Bool apc_prn_create( Handle self) {
return
false
; }
Bool apc_prn_destroy( Handle self) {
return
true
; }
Bool apc_prn_select( Handle self,
const
char
* printer) {
return
false
; }
char
* apc_prn_get_selected( Handle self) {
return
NULL; }
Point apc_prn_get_size( Handle self) { Point r = {0,0};
return
r; }
Point apc_prn_get_resolution( Handle self) { Point r = {0,0};
return
r; }
char
* apc_prn_get_default( Handle self) {
return
NULL; }
Bool apc_prn_setup( Handle self) {
return
false
; }
Bool apc_prn_begin_doc( Handle self,
const
char
* docName) {
return
false
; }
Bool apc_prn_begin_paint_info( Handle self) {
return
false
; }
Bool apc_prn_end_doc( Handle self) {
return
true
; }
Bool apc_prn_end_paint_info( Handle self) {
return
true
; }
Bool apc_prn_new_page( Handle self) {
return
true
; }
Bool apc_prn_abort_doc( Handle self) {
return
true
; }
ApiHandle apc_prn_get_handle( Handle self) {
return
( ApiHandle) 0; }
Bool apc_prn_set_option( Handle self,
char
* option,
char
* value) {
return
false
; }
Bool apc_prn_get_option( Handle self,
char
* option,
char
** value)
{
*value = NULL;
return
false
;
}
Bool apc_prn_enum_options( Handle self,
int
* count,
char
*** options)
{
*count = 0;
return
false
;
}
PrinterInfo *
apc_prn_enumerate( Handle self,
int
* count)
{
*count = 0;
return
NULL;
}
char
*
apc_last_error(
void
)
{
return
NULL;
}