//================================================================
// Xe UI toolkit
//
// X11-specific header file
//
// AUTHOR:  Gabor Nagy
// DATE:    2026-Jan-01 23:46:08
//
// Copyright (C) 1996-2026 by Gabor Nagy. All rights reserved.
//================================================================
#ifndef _XeX_h
#define _XeX_h

#include <Xe/Xe.h>

#include <X11/Xatom.h>

#if defined (__cplusplus) && (!(defined (__CPLUSLIBS)))
extern "C" {
#endif


#define XeM_AddXPoint(pPoints, pCounter,  pX, pY) do\
{\
	pPoints[pCounter].x = pX, pPoints[pCounter].y = pY, pCounter++;\
} while(0)


#define XeXWindowToWidgetHash(pTab, pXWindow)           ((pXWindow) & pTab->Mask)


typedef struct XeWidgetX11Data_S  XeWidgetX11Data;

struct XeWidgetX11Data_S
{
	Screen*         X_Screen;
	Window          X_Window;
	Colormap        X_Colormap;
	GC              X_GC;                 // Plain graphics context

	uint32_t        X_ColormapAllocated : 1,
	                ClearXWindow : 1,     // Let X11 etc. clear the background on expose (we usually don't want this, as it causes flickering and wastes GPU time, but some Widget implementors may want a quick and dirty first prototype...)
	                ClearCacheDrawable : 1;

	Pixmap          WindowMaskXPixmap;    // For non-rectangular Widgets
	Pixmap          CacheXPixmap;
	int             CacheXPixmapSizeX, CacheXPixmapSizeY;
	XImage*         CacheXImage;
};


struct XeStringDrawContextX11Data_S
{
	Drawable  X_TargetDrawable;
	Pixmap    X_AACachePixmap;           // Lazily-grown Pixmap for down-scaling based anti-aliasing
	XImage*   X_AACacheImage;            // Persistent XImage to avoid creating / destroying one in EpImage_PasteToXDrawable() etc.
	int       X_AACachePixmapSizeX, X_AACachePixmapSizeY;
	GC        X_BackgroundGC, X_GC;
	Pixel     X_BackgroundColor, X_CurrentColor;
};



typedef unsigned long  XeXGCMask;      // Mask of values that are used by a Widget
typedef unsigned long  XeXWValueMask;

extern void          _XeX_Redraw(XeWidget PW, const EpImage* (*PRedrawFunc)(XeWidget PW, EpImage* PImage));

extern Pixel         XeX_Black, XeX_White;

extern XeDisplay*    _XeX_OpenDisplay(XeApp PApp, const char* PDisplayName, const char* PAppName, const char* PAppClassName,  int* PArgC, const char* const* PArgV);
extern XeApp         XeX_DisplayToApp(Display* PXDisplay);

extern char*         XeX_KeyToAccel(const unsigned short PKey, const unsigned int PModifiers, char* PStr);
extern char*         XeX_KeyToAccelText(const unsigned short PKey, const unsigned int PModifiers, char* PStr);
extern void          XeX_ConvertCase(XeDisplay* PDisplay, XeKeySym PKeysym, XeKeySym* PLowerRet, XeKeySym* PUpperRet);
extern unsigned int  XeX_ModifiersFromEvent(const XeEvent* PEvent);

#ifdef _XeP_h

extern XeDisplay*  XeX_XDisplayToDisplay(Display* PXDisplay);
extern void        XeX_CreateWindow(XeWidget PW, XeXWValueMask PValueMask, XSetWindowAttributes* PAttributes);

extern void        _XeX_CoreRedraw(XeWidget PW, XeRedrawEvent* PEvent, void (*PRedrawProc)(XeWidget, Drawable));
extern void        _XeX_WidgetDrawFromImage(XeWidget PW, const EpImage* PImage);

#else

extern Pixmap      XeX_GetCachePixmap(XeWidget PW);

#endif

extern Screen*     XeX_Screen(XeWidget PW);
extern Display*    XeX_Display(XeWidget PW);
extern Window      XeX_Window(XeWidget PW);
extern Colormap    XeX_Colormap(XeWidget PW);
extern GC          XeX_GetGC(XeWidget PW);


extern EBool     _XeX_HandleTruecolorIcons(XeDisplay* PDisplay, XEvent* PXEvent);


extern void      XeX_Redraw(XeWidget PW);

extern Window    XeX_ClosestDrawableAncestorWindow(XeWidget PW);
extern Window    XeX_DrawableWindowAndPosition(XeWidget PW,  int* PXP, int* PYP);

extern Pixel     XeColor_GetXColor(const XeVisual* PVisual, const XeColor* PXeColor);

extern Pixel     XeX_GetNamedColor(const XeVisual* PVisual, const char* PColorName);
extern Pixel     XeX_GetRGBColor(const XeVisual* PVisual,  const unsigned int PR, const unsigned int PG, const unsigned int PB);


// X11 Drawable <-> EpImage
//
extern Pixmap    EpImage_ToXPixmapVa(const XeVisual* PVisual, const EpImage* PImage, ...);
extern int       EpImage_PasteToXDrawable(const EpImage* PImage, const XeVisual* PVisual, GC PGC,  Drawable PDrawable, XImage* PXImage,
                  const int PSrcX, const int PSrcY,  const int PDstX, const int PDstY,  const int PSizeX, const int PSizeY);
extern int       EpImage_CompositeToXDrawable(const EpImage* PImage,  const XeLayer* PBackgroundLayers, const int PNBackgroundLayers,  const XeVisual* PVisual,
                  const int PSrcX, const int PSrcY,  const int PDstX, const int PDstY,  const int PSizeX, const int PSizeY, const uint16_t PBlendFunction,  GC PXGC, Drawable PXDrawable);

extern int       XeX_DrawableToImage(const XeVisual* PVisual, const Drawable PDrawable, Pixel PBackgroundXColor, EpImage* PImage);

extern int       XeX_DrawablePasteToImage(const XeVisual* PVisual, Drawable PXDrawable, const Pixel PBackgroundXPixel, EpImage* PImage,
                  const int PSrcX, const int PSrcY,  const int PDstX, const int PDstY,  const int PSizeX, const int PSizeY);

// Drawing
//
extern void      XeX_FillGradientRectangle(const XeVisual* PVisual, Drawable PPixmap, GC PGC, const int POrientation, const int PX, const int PY, const int PSizeX, const int PSizeY, const EcRGBAf32Color* PColor0, const EcRGBAf32Color* PColor1);

extern void      XeX_DrawShadows(const XeVisual* PVisual, Drawable PXDrawable, GC PXGC,  const int PX, const int PY,  const int PSizeX, const int PSizeY,  const int PGapWidth, const int PGapCornerRadius, const EcRGBAf32Color* PGapColor,
 const int PShadowThickness, const uint16_t PType, const uint8_t PGradient, const EcRGBAiColor* PBackgroundColor, const EcRGBAiColor* PParentBackgroundColor);

extern XeFontSize*  _XeX_FontSizeCreate(XeDisplay* PDisplay, const char* PXName,  const float PSizeInPixels, const float PAntiAliasing);
extern EIndex       _XeX_SysFontsCollect(XeDisplay* PDisplay, const EBool PDetails, const EBool PForceReload, const int PMinSizeInPixels, const uint8_t PSpacing, const char* PCharset, const char* PEncoding);

extern int          XeFontX_Load(XeFont* PFont, XeFontSize* PFontSize);

extern void         XeX_WTextExtents(const XeFontSize* PFontSize, const wchar_t* PString, const int PLength, int* PDir, int* PAsc, int* PDesc, XeCharStruct* POverall);


extern int          XeXDrawable_SaveToFile(XeVisual* PVisual, Drawable PXDrawable, const char* PFileName);


// Conversion operations with XeNConversion (for EpCImage_ToPixmapVa)
//
#define XeX_ALPHA_TO_1BIT_PIXMAP  0x0001

extern Pixmap      XeX_XPMToPixmapVa(const XeVisual* PVisual, char** PXPM, ...);
extern Pixmap      EpCImage_ToPixmapVa(const XeVisual* PVisual, EpCImage* PImage, ...);


#define _XeX_DrawFocusShadows(mEW, mDrawable, mOffset) do\
{\
	XeX_DrawShadows(LXDisplay, mDrawable, LGC, (mOffset), (mOffset), Xe_SizeX(mEW) - (mOffset) * 2, Xe_SizeY(mEW) - (mOffset) * 2, 0, 0, LBottomShadowXColor, mEW->Primitive.HighlightThickness, XeShadowIN|LShadowSpecFlags, 0,  LBackgroundXColor, LTopShadowXColor, LBottomShadowXColor);\
} while(0)


extern XeEventMask  _XeX_EventTypeToMask(const int PEventType);

extern XeWidget     XeX_WindowToWidget(XeDisplay* PDisplay, Window PXWindow);
extern XeWidget     XeX_WindowToWidgetXD(Display* PXDisplay, Window PXWindow);

extern void       XeX_DrawableRegister(Display* PXDisplay, Drawable PXDrawable, XeWidget PW);
extern void       XeX_DrawableUnregister(Display* PXDisplay, Drawable PXDrawable);


//
// Selection
//
typedef EPointer  XeRequestId;

typedef EBool  (*XeXConvertSelectionFunc)(XeWidget PW, Atom* PSelection, Atom* PTarget, Atom* PTypeReturn, EPointer* PValueRet, unsigned long* PLengthRet, int* PFormatRet);
typedef void   (*XeXLoseSelectionFunc)(XeWidget PW, Atom* PSelection);
typedef void   (*XeXSelectionDoneFunc)(XeWidget PW, Atom* PSelection, Atom* PTarget);
typedef void   (*XeXSelectionCallbackFunc)(XeWidget PW, EPointer PClientData, Atom* PSelection, Atom* PType, EPointer PValue, unsigned long* PLength, int* PFormat);
typedef void   (*XeXLoseIncrementalSelectionProc)(XeWidget PW, Atom* PSelection, EPointer PClientData);
typedef void   (*XeXIncrementalSelectionDoneProc)(XeWidget PW, Atom* PSelection, Atom* PTarget, XeRequestId* PReceiverID, EPointer PClientData);
typedef EBool  (*XeXConvertIncrementalSelectionProc)(XeWidget PW, Atom* PSelection, Atom* PTarget, Atom* PType, EPointer* PValue, unsigned long* PLength, int* PFormat, unsigned long* PMaxLength, EPointer PClientData, XeRequestId* PReceiverID);

typedef void   (*XeXCancelConvertSelectionFunc)(XeWidget PW, Atom* PSelection, Atom* PTarget, XeRequestId* PReceiverID, EPointer PClientData);


extern EBool   XeX_OwnSelection(XeWidget PW, const Atom PSelection, const Time PTime, XeXConvertSelectionFunc PConvert, XeXLoseSelectionFunc PLose, XeXSelectionDoneFunc PDone);
extern void    XeX_DisownSelection(XeWidget PW, Atom PSelection, const Time PTime);
extern void    XeX_GetSelectionValue(XeWidget PW, Atom PSelection, Atom PTarget, XeXSelectionCallbackFunc PCallback, EPointer PClientData, const Time PTime);
extern void    XeX_GetSelectionValues(XeWidget PW, Atom PSelection,  Atom* PTargets, const int PCount,  XeXSelectionCallbackFunc PCallback, EPointer* PClientData,  const Time PTime, const EBool PStopAfterFirstTypeMatch);

extern void    Xe_GetSelectionValue(XeWidget PW, const int PSelection, const int PTarget, XeXSelectionCallbackFunc PCallback, EPointer PClientData, const ETime PTime);
extern void    Xe_GetSelectionValues(XeWidget PW, const int PSelection,  const int* PTargets, const int PNTargets,  XeXSelectionCallbackFunc PCallback, EPointer PClientData,  const ETime PTime);

extern XeEventMask  _XeX_BuildEventMask(XeWidget PW);

extern XEvent*    XeX_NextEvent(Display* PXDisplay, XEvent* PXEvent);
extern EBool      XeX_DispatchEvent(XEvent* PXEvent);
extern int        XeX_UnbufferButtonEvents(Display* PDisplay, Window PWindow, const int PButton);

extern void      XeStringBinary_LinesDraw(XeStringDrawContext* PContext, const XeVisual* PVisual, EpImage* PTargetImage,
  const EIndex PDrawableSizeX, const EIndex PDrawableSizeY,  const EcRGBAiColor* PBackgroundColor, const EcRGBAiColor* PForegroundColor, EBool PUseColorsInString,
  const EIndex PX, const EIndex PY,  EIndex PFullSizeX,  XeStringLine* PLines, const EIndex PNLines,
  const XeStringBinarySegmentListA* PSegments,  const XeStringRenderingSettings* PRenderSettings, const int PAlignment);

extern GC        XeX_GCNew(XeWidget PW, const int PDepth, XeXGCMask PXValueMask, XGCValues* PXValues, XeXGCMask PXDynamicMask, XeXGCMask PUnusedMask);
extern void      XeX_GCFree(XeWidget PW, GC PXGC);

extern XeKeySym   XeX_GetActionKeySym(XEvent* PXEvent, XeModifiers* PModifiersR);


extern void          XeX_GrabButton(XeWidget PW, const int PButton, const XeModifiers PModifiers, const EBool  POwnerEvents, const unsigned int PEventMask, const int PPointerMode, const int PKeyboardMode, Window PConfineToXWindow, Cursor PXCursor);
extern int           XeX_GrabPointer(XeWidget PW, const EBool POwnerEvents, const unsigned int PEventMask, const int PPointerMode, const int PKeyboardMode, Window PConfineToXWindow, Cursor PXCursor, const ETime PTime);


extern XrmDatabase   XeX_GetDatabase(Display* PXDisplay);

extern void          _XeXEvents_Free(void);


#if defined (__cplusplus) && (!(defined (__CPLUSLIBS)))
}  // Close scope of 'extern "C"' declaration
#endif

#endif // _XeX_h
