/* Copyright 2001-2003 by Norbert Freudemann, David Frese */

#include "xlib.h"

s48_ref_t scx_grab_mode_binding = NULL;
#define scx_extract_grab_mode(c, x) \
  S48_EXTRACT_ENUM(c, x, scx_grab_mode_binding)
s48_ref_t scx_grab_states_binding = NULL;
#define scx_enter_grab_status(c, x) \
  S48_ENTER_ENUM(c, x, scx_grab_states_binding)

s48_ref_t scx_Grab_Pointer(s48_call_t call, s48_ref_t dpy, s48_ref_t win, 
			   s48_ref_t ownerp, s48_ref_t events, 
			   s48_ref_t pmode, s48_ref_t kmode, 
			   s48_ref_t confine_to, s48_ref_t cursor, 
			   s48_ref_t time) {
  int res;

  res = XGrabPointer(scx_extract_display(call, dpy),
			 scx_extract_window(call, win),
			 s48_extract_boolean_2(call, ownerp),
			 scx_extract_event_mask(call, events),
			 scx_extract_grab_mode(call, pmode), 
			 scx_extract_grab_mode(call, kmode),
			 scx_extract_window(call, confine_to),
			 scx_extract_cursor(call, cursor),
			 scx_extract_time(call, time));
  return scx_enter_grab_status(call, res);
}

s48_ref_t scx_Ungrab_Pointer(s48_call_t call, s48_ref_t dpy, s48_ref_t time) 
{
  XUngrabPointer(scx_extract_display(call, dpy), scx_extract_time(call, time));
  return s48_unspecific_2(call);
}

s48_ref_t scx_Change_Active_Pointer_Grab(s48_call_t call, s48_ref_t dpy, 
            s48_ref_t events, s48_ref_t cursor, s48_ref_t time)
{
  XChangeActivePointerGrab(scx_extract_display(call, dpy),
			   scx_extract_event_mask(call, events),
			   scx_extract_cursor(call, cursor),
			   scx_extract_time(call, time));
  return s48_unspecific_2(call);
}

s48_ref_t scx_Grab_Button(s48_call_t call, s48_ref_t dpy, 
	    s48_ref_t button, s48_ref_t mods, s48_ref_t win, 
            s48_ref_t ownerp, s48_ref_t events, s48_ref_t pmode, 
	    s48_ref_t kmode, s48_ref_t confine_to, s48_ref_t cursor) {
  XGrabButton(scx_extract_display(call, dpy),
	      scx_extract_button(call, button),
	      scx_extract_state_set(call, mods),
	      scx_extract_window(call, win),
	      s48_extract_boolean_2(call, ownerp),
	      scx_extract_event_mask(call, events),
	      scx_extract_grab_mode(call, pmode),
	      scx_extract_grab_mode(call, kmode),
	      scx_extract_window(call, confine_to),
	      scx_extract_cursor(call, cursor));
  return s48_unspecific_2(call);
}

s48_ref_t scx_Ungrab_Button(s48_call_t call, s48_ref_t dpy, s48_ref_t button,
	     s48_ref_t mods, s48_ref_t win) {
  XUngrabButton(scx_extract_display(call, dpy),
		scx_extract_button(call, button),
		scx_extract_state_set(call, mods),
		scx_extract_window(call, win));
  return s48_unspecific_2(call);
}

s48_ref_t scx_Grab_Keyboard(s48_call_t call, s48_ref_t dpy, 
            s48_ref_t win, s48_ref_t ownerp, s48_ref_t pmode, 
            s48_ref_t kmode, s48_ref_t time) {
  int res;
  res = XGrabKeyboard( scx_extract_display(call, dpy),
			   scx_extract_window(call, win),
			   s48_extract_boolean_2(call, ownerp),
			   scx_extract_grab_mode(call, pmode),
			   scx_extract_grab_mode(call, kmode),
			   scx_extract_time(call, time));
  return scx_enter_grab_status(call, res);
}

s48_ref_t scx_Ungrab_Keyboard(s48_call_t call, s48_ref_t dpy, s48_ref_t time)
{
  XUngrabKeyboard(scx_extract_display(call, dpy),
		  scx_extract_time(call, time));
  return s48_unspecific_2(call);
}

s48_ref_t scx_Grab_Key(s48_call_t call, s48_ref_t dpy, s48_ref_t key, 
            s48_ref_t mods, s48_ref_t win, s48_ref_t ownerp, 
            s48_ref_t pmode, s48_ref_t kmode) {
  XGrabKey(scx_extract_display(call, dpy),
	   s48_extract_long_2(call, key), 
	   scx_extract_state_set(call, mods),
	   scx_extract_window(call, win),
	   s48_extract_boolean_2(call, ownerp),
	   scx_extract_grab_mode(call, pmode),
	   scx_extract_grab_mode(call, kmode));
  return s48_unspecific_2(call);
}

s48_ref_t scx_Ungrab_Key(s48_call_t call, s48_ref_t dpy, s48_ref_t key, 
	       s48_ref_t mods, s48_ref_t win) {
  XUngrabKey(scx_extract_display(call, dpy),
	     s48_extract_long_2(call, key), 
	     scx_extract_state_set(call, mods),
	     scx_extract_window(call, win));
  return s48_unspecific_2(call);
}

s48_ref_t scx_event_mode_binding = NULL;
#define scx_extract_event_mode(c, x) \
  S48_EXTRACT_ENUM(c, x, scx_event_mode_binding)

s48_ref_t scx_Allow_Events(s48_call_t call, s48_ref_t dpy,
	    s48_ref_t event_mode, s48_ref_t time) {
  XAllowEvents(scx_extract_display(call, dpy),
	       scx_extract_event_mode(call, event_mode),
	       scx_extract_time(call, time));
  return s48_unspecific_2(call);
}

s48_ref_t scx_Grab_Server(s48_call_t call, s48_ref_t dpy) {
  XGrabServer(scx_extract_display(call, dpy));
  return s48_unspecific_2(call);
}

s48_ref_t scx_Ungrab_Server(s48_call_t call, s48_ref_t dpy){
  XUngrabServer(scx_extract_display(call, dpy));
  return s48_unspecific_2(call);
}

void scx_init_grab(void) {
  scx_grab_mode_binding = s48_get_imported_binding_2("scx-grab-mode");
  scx_grab_states_binding = s48_get_imported_binding_2("scx-grab-states");
  scx_event_mode_binding = s48_get_imported_binding_2("scx-event-mode");

  S48_EXPORT_FUNCTION(scx_Grab_Pointer);
  S48_EXPORT_FUNCTION(scx_Ungrab_Pointer);
  S48_EXPORT_FUNCTION(scx_Grab_Button);
  S48_EXPORT_FUNCTION(scx_Ungrab_Button);
  S48_EXPORT_FUNCTION(scx_Change_Active_Pointer_Grab);
  S48_EXPORT_FUNCTION(scx_Grab_Keyboard);
  S48_EXPORT_FUNCTION(scx_Ungrab_Keyboard);
  S48_EXPORT_FUNCTION(scx_Grab_Key);
  S48_EXPORT_FUNCTION(scx_Ungrab_Key);
  S48_EXPORT_FUNCTION(scx_Allow_Events);
  S48_EXPORT_FUNCTION(scx_Grab_Server);
  S48_EXPORT_FUNCTION(scx_Ungrab_Server);
}
		      
