/**
 *
 * ChoX11: XLib replacement for RISC OS
 *
 * Functions from Xutil.h
 *
 * Copyright 2003 by Peter Naulls
 * Written by Peter Naulls
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation. No representations are made about the suitability of this
 * software for any purpose.  It is provided "as is" without express or
 * implied warranty.
 *
 */

#define XLIB_ILLEGAL_ACCESS
#define NeedFunctionPrototypes 1
#define NeedNestedPrototypes   1


#include <X11/Xlib.h> 
#include <X11/XUtil.h>

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>


#include "chox11.h"

extern XIconSize *XAllocIconSize (

    void

);


extern const char *XDefaultString(

    void

);

extern int XDeleteContext(

    Display*		 display,
    XID			 rid,
    XContext		 context

) {
  printf("XDeleteContext: rid=%i, context=%i\n", rid, context);
  return Chox11DB_RemoveContext(rid, context);
}


extern int XFindContext(

    Display*		 display,
    XID			 rid,
    XContext		 context,
    XPointer*		 data_return

) {
  int status;
  XContextEntry *entry;

  printf("XFindContext: rid=%x context=%x\n", rid, context);
  status = Chox11DB_FindContext(rid, context, &entry);
  if (entry)
    *data_return = entry->data;
  else
    *data_return = NULL;  
  printf("XFindContext: data=%p, status=%i\n", entry ? entry->data : NULL, status);
  return status;
}


extern Status XGetStandardColormap(

    Display*		 display,
    Window		 w,
    XStandardColormap*	 colormap_return,
    Atom		 property			    

);


extern XVisualInfo *XGetVisualInfo(

    Display*		 display,
    long		 vinfo_mask,
    XVisualInfo*	 vinfo_template,
    int*		 nitems_return

) {
  XVisualInfo *visual = calloc(sizeof(XVisualInfo), 1);

  printf("XGetVisualInfo: %d %d\n",
    vinfo_template->screen,
    vinfo_template->depth);

  *nitems_return = 1;

  visual->visual         = display->screens->root_visual;
  visual->visualid       = display->screens->root_visual->visualid;
  visual->depth          = display->screens->root_visual->bits_per_rgb;
  visual->class          = display->screens->root_visual->class;
  visual->red_mask       = display->screens->root_visual->red_mask;
  visual->green_mask     = display->screens->root_visual->green_mask;
  visual->blue_mask      = display->screens->root_visual->blue_mask;
  visual->colormap_size  = display->screens->root_visual->map_entries;
  visual->bits_per_rgb   = display->screens->root_visual->bits_per_rgb;

  return visual;
}

extern Status XMatchVisualInfo(

    Display*		 display,
    int			 screen,
    int			 depth,
    int			 class,
    XVisualInfo*	 vinfo_return

) {
  Visual *rvisual = display->screens->root_visual;

  printf("XMatchVisualInfo: %d %d %d\n", depth, class, rvisual->class);

  memset(vinfo_return, 0, sizeof(XVisualInfo));

  if ((depth == 32 || depth == 24) && rvisual->class == class) {
    vinfo_return->visual        = rvisual;
    vinfo_return->visualid      = rvisual->visualid;

    vinfo_return->depth         = depth;
    vinfo_return->class         = class;

    vinfo_return->red_mask      = rvisual->red_mask;
    vinfo_return->green_mask    = rvisual->green_mask;
    vinfo_return->blue_mask     = rvisual->blue_mask;
    vinfo_return->colormap_size = rvisual->map_entries;
    vinfo_return->bits_per_rgb  = rvisual->bits_per_rgb;

    printf("matched\n");

    return 1;
  }

  return 0;
}


extern int XSaveContext(

    Display*		 display,
    XID			 rid,
    XContext		 context,
    _Xconst char*	 data

) {
  printf("XSaveContext: rid=%x context=%i data=%p\n", rid, context, data);
  return Chox11DB_StoreContext(rid, context, (char *)data);
}


extern void XSetRGBColormaps(

    Display*		 display,
    Window		 w,
    XStandardColormap*	 stdcmaps,
    int			 count,
    Atom		 property

);

//extern XSetStandardProperties(
//
//    Display*		 display,
//    Window		 w,
//    _Xconst char*	 window_name,
//    _Xconst char*	 icon_name,
//    Pixmap		 icon_pixmap,
//    char**		 argv,
//    int			 argc,
//    XSizeHints*		 hints
//
//) {
//  XDrawable *window = (XDrawable *)w; 
//
//  printf("XSetStandardProperties: %s (not implemented fully)\n", window_name);
//
//  /* TODO: create atoms, and create PropertyNewValue events */
//  Window_SetTitle(window->data.window.handle, window_name);
//}


//extern void XSetWMName(
//
//    Display*		 display,
//    Window		 w,
//    XTextProperty*	 text_prop
//
//) {
//  puts("XSetWMName (not implemented)");
//
//  if (text_prop && text_prop->value)
//    Window_SetTitle(window->data.window.handle, text_prop->value);
//  else
//    Window_SetTitle(window->data.window.handle, "");
//}


/* From Xlibint.c */

/*
 * _XGetHostname - similar to gethostname but allows special processing.
 */
int _XGetHostname (
    char *buf,
    int maxlen)
{
    int len;

#ifdef NEED_UTSNAME
    struct utsname name;

    if (maxlen <= 0 || buf == NULL)
	return 0;

    uname (&name);
    len = strlen (name.nodename);
    if (len >= maxlen) len = maxlen - 1;
    strncpy (buf, name.nodename, len);
    buf[len] = '\0';
#else
    if (maxlen <= 0 || buf == NULL)
	return 0;

    buf[0] = '\0';
    (void) gethostname (buf, maxlen);
    buf [maxlen - 1] = '\0';
    len = strlen(buf);
#endif /* NEED_UTSNAME */
    return len;
}



//extern void XSetWMProperties(
//
//    Display*		 display,
//    Window		 w,
//    XTextProperty*	 window_name,
//    XTextProperty*	 icon_name,
//    char**		 argv,
//    int			 argc,
//    XSizeHints*		 normal_hints,
//    XWMHints*		 wm_hints,
//    XClassHint*		 class_hints
//
//) {
//  XDrawable *window = (XDrawable *)w; 
//
//  printf("XSetWMProperties: w=%x, name=%s, icon=%s\n", w,
//         window_name ? (const char *)window_name->value : "(not set)",
//         icon_name ? (const char *)icon_name->value : "(not set)");
//
//
//  if (normal_hints) {
//    printf("hints: %x\n", normal_hints->flags);
//    printf("%d %d %d %d %d %d\n",
//           normal_hints->min_width,
//           normal_hints->max_width,
//           normal_hints->min_height,
//           normal_hints->max_height,
//           normal_hints->base_width,
//           normal_hints->base_height);
//  }
//}

extern void XSetWMSizeHints(

    Display*		 display,
    Window		 w,
    XSizeHints*		 hints,
    Atom		 property

);


extern void XSetStandardColormap(

    Display*		 display,
    Window		 w,
    XStandardColormap*	 colormap,
    Atom		 property

);


extern Status XStringListToTextProperty(

    char**		 list,
    int			 count,
    XTextProperty*	 text_prop_return

) {
  printf("XStringListToTextProperty: list=%x (not implemented)\n", list);
  memset(text_prop_return, 0, sizeof(XTextProperty));
  return 1;
}


extern int XWMGeometry(

    Display*		 display,
    int			 screen_number,
    _Xconst char*	 user_geometry,
    _Xconst char*	 default_geometry,
    unsigned int	 border_width,
    XSizeHints*		 hints,
    int*		 x_return,
    int*		 y_return,
    int*		 width_return,
    int*		 height_return,
    int*		 gravity_return

) {
  puts("XWMGeometry (not implemented)");

  *x_return = 0;
  *y_return = 0;
  *width_return = 0;
  *height_return = 0;
  *gravity_return = 0;

  return 0;
}


int
XRebindKeysym (
    Display *dpy,
    KeySym keysym,
    KeySym *mlist,
    int nm,		/* number of modifiers in mlist */
    _Xconst unsigned char *str,
    int nbytes) {

  puts("XRebindKeysym: not implemented"); 

  return 0;
}

