#include <stdlib.h>
#include <stdio.h>


#include <kapplication.h>
#include <kdebug.h>
#include <kprocess.h>
#include <kglobal.h>
#include <kstandarddirs.h>


#include "extension.h"
#include <qwindowdefs.h>
#include <qglobal.h>
#include <locale.h>

#include <X11/Xatom.h>
#include <X11/Xos.h>
#include <X11/XKBlib.h>
#include <X11/X.h>

XKBExtension::XKBExtension(Display *d)
{
  // determine display to use
  if (!d)
    d = qt_xdisplay();
  dpy = d;

  qt_input_encoding = XInternAtom( d, "_QT_INPUT_ENCODING", false);

    // Verify the Xlib has matching XKB extension.

    int major = XkbMajorVersion;
    int minor = XkbMinorVersion;
    if (!XkbLibraryVersion(&major, &minor))
    {
        kdError() << "Xlib XKB extension " << major << '.' << minor <<
            " != " << XkbMajorVersion << '.' << XkbMinorVersion << endl;
        return;
    }

    // Verify the X server has matching XKB extension.

    int opcode_rtrn;
    int error_rtrn;
    if (!XkbQueryExtension(qt_xdisplay(), &opcode_rtrn, &xkb_opcode, &error_rtrn,
                         &major, &minor))
    {
        kdError() << "X server XKB extension " << major << '.' << minor <<
            " != " << XkbMajorVersion << '.' << XkbMinorVersion << endl;
        return;
    }
}

XKBExtension::~XKBExtension()
{
    // clear the property. Makes Qt use the locale again for input mapping
    Atom type;
    int format;
    unsigned long  nitems, after = 1;
    unsigned char * data;
    XGetWindowProperty( dpy, qt_xrootwin(), qt_input_encoding, 0, 1024,
				true, XA_STRING, &type, &format, &nitems,
				&after,  &data );
    if( data )
	delete data;
}

void XKBExtension::setLayout(const QString& rule, const QString& model, 
		const QString& layout, const char* variant, const QString& options, 
		bool resetOld, const QString &encoding, unsigned int group)
{
  if (rule.isEmpty() || model.isEmpty() || layout.isEmpty())
    return;

  QString exe = KGlobal::dirs()->findExe("setxkbmap");
  if (exe.isEmpty())
    return;

  KProcess *p = new KProcess;
  *p << exe;
  *p << "-rules" << rule;
  *p << "-model" << model;
  *p << "-layout" << layout;
  if( variant && *variant )
    *p << "-variant" << variant;
  if( resetOld )
    *p << "-option";
  if( !options.isEmpty() )
    *p << "-option" << options;

  p->start(KProcess::Block);

  XkbLockGroup( dpy, XkbUseCoreKbd, group );
//   XkbStateRec rec;
//   XkbGetState( dpy, XkbUseCoreKbd, &rec );
//   qDebug( "keyboard state is: group: %d, lock %d", (int)rec.group, (int)rec.locked_group);

#if QT_VERSION < 230
  const char * enc = encoding.latin1();
  XChangeProperty( dpy, qt_xrootwin(), qt_input_encoding, XA_STRING, 8,
		   PropModeReplace, (unsigned char *)enc, strlen(enc) );
#endif
}


void XKBExtension::setGroup(int group)
{
  XkbLockGroup( dpy, XkbUseCoreKbd, group );
}

int XKBExtension::getGroup()
{
    XkbStateRec xkbState;
    XkbGetState( dpy, XkbUseCoreKbd, &xkbState);
    
    return xkbState.group;
}
