Logo Search packages:      
Sourcecode: rgtk version File versions  Download package

gtkUtils.c

#include "gtkUtils.h"

#include "R_ext/Memory.h"


void
R_gtkDebug()
{
      GLogLevelFlags fatal_mask;
            
      fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
      fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
      g_log_set_always_fatal (fatal_mask);
}

void
gdkFlush()
{
  gdk_flush();
}


char **
asCStringArray(USER_OBJECT_ svec)
{
    char **els = NULL;
 
    int i, n;
 
    n = GET_LENGTH(svec);
    if(n > 0) {
      els = (char **) R_alloc(n+1, sizeof(char*));
      for(i = 0; i < n; i++) {
          els[i] = CHAR_DEREF(STRING_ELT(svec, i));
      }
        els[n] = NULL;
    }

    return(els); 
}

USER_OBJECT_
asRLogical(Rboolean val)
{
  USER_OBJECT_ ans;
  ans = NEW_LOGICAL(1);
  LOGICAL_DATA(ans)[0] = val;

  return(ans);
}


USER_OBJECT_
asRInt(int val)
{
  USER_OBJECT_ ans;
  ans = NEW_INTEGER(1);
  INTEGER_DATA(ans)[0] = val;

  return(ans);
}

USER_OBJECT_
asRNumeric(double val)
{
  USER_OBJECT_ ans;
  ans = NEW_NUMERIC(1);
  NUMERIC_DATA(ans)[0] = val;

  return(ans);
}

USER_OBJECT_
asRCharacter(const char *val)
{
  USER_OBJECT_ ans;
  PROTECT(ans = NEW_CHARACTER(1));
  if(val)
      SET_STRING_ELT(ans, 0, COPY_TO_USER_STRING(val));
  UNPROTECT(1);

  return(ans);
}

/**
  Returns a numeric vector of length 1 containing the value
  of the GdkAtom. This is an opaque value and should not be used
  directly. The name of the atom is given in the names() attribute of
  the object and it is of class "GdkAtom"
 */

USER_OBJECT_
asRGdkAtom(GdkAtom val)
{
  USER_OBJECT_ ans;
  char *tmp;
  PROTECT(ans = NEW_NUMERIC(1));
  NUMERIC_DATA(ans)[0] = val;
  tmp = gdk_atom_name(val);
  if(tmp)
      SET_NAMES(ans, asRCharacter(tmp));
  SET_CLASS(ans,   asRCharacter("GdkAtom"));
  UNPROTECT(1);

  return(ans);
}


/**

 The idea is that the `val' argument is either an integer
 or a string. If it is an integer, we check that it is a
 value in the array cValues[] array.
 If it is a string, we look through the two arrays of names
 (the real names from the header files and the local names/aliases
  from the .defs files from which the enumerations are built.)

  If the value is matched, the associated integer is returned.

  We should probably put the real name on the result
  and also a class. In that case, we will need the name of the
  enum type.

  Otherwise, 
 */
USER_OBJECT_ 
S_checkEnum(USER_OBJECT_ val, const char *const localNames[], const char *const realNames[], 
                          const int cValues[], int len, const char *const enumName)
{
    int i;
    USER_OBJECT_ names, ans = NULL_USER_OBJECT;
    if(IS_INTEGER(val) || IS_NUMERIC(val)) {
        int cval;
        if(IS_INTEGER(val))
          cval = INTEGER_DATA(val)[0];
        else 
          cval = NUMERIC_DATA(val)[0];
      for(i = 0; i < len ; i++) {
          if(cValues[i] == cval) {
            ans = val;
            break;
          }
      }
        if(i == len) {
          PROBLEM "Invalid enum value: %d", INTEGER_DATA(val)[0]
        ERROR;
      }
    } else if(IS_CHARACTER(val)) {
      char *tmp = CHAR_DEREF(STRING_ELT(val, 0));
      for(i = 0; i < len; i++) {
          if(strcmp(tmp, localNames[i]) == 0 || strcmp(tmp, realNames[i]) == 0) {
                PROTECT(ans = NEW_INTEGER(1));
            INTEGER_DATA(ans)[0] = cValues[i];
            break;
          }
      }
      if(i == len) {
          PROBLEM "Invalid enum name: %s", tmp
        ERROR;
      }
    } else {
         PROBLEM "Invalid argument type (%d) passed to S_checkEnum.",
                TYPEOF(val)
       ERROR;
    }

    PROTECT(names = NEW_CHARACTER(1));
    SET_STRING_ELT(names, 0, COPY_TO_USER_STRING(realNames[i]));
    SET_NAMES(ans, names);

    PROTECT(names = NEW_CHARACTER(2));   
    SET_STRING_ELT(names, 0, COPY_TO_USER_STRING(enumName));
    SET_STRING_ELT(names, 1, COPY_TO_USER_STRING("enum"));
    SET_CLASS(ans, names);

    UNPROTECT(ans == val ? 2 : 3);

    return(ans);
}


/**
  val can be an integer or a character vector.
  If it is a character vector, we build up the actual value by 
  OR'ing the values in cValues[] by matching the elements in the vector
  with the elements in localNames or realNames.
 */

USER_OBJECT_ 
S_checkFlag(USER_OBJECT_ val, const char *const localNames[], const char *const realNames[], 
                          const int cValues[], int len, const char *const flagName)
{
    int i, j, n;
    USER_OBJECT_ ans, names;
    int numProtects = 0;
    n = GET_LENGTH(val);

    if(IS_INTEGER(val)) {
      for(i = 0; i < n ; i++) {
          for(j = 0; j < len; j++) {
            if(!(cValues[j] | INTEGER_DATA(val)[i]))
               PROBLEM "incorrect flag value: %d", INTEGER_DATA(val)[0]
               ERROR;
          }
      }
        ans = val;
    } else {
      int value = 0;
      for(i = 0; i < n; i++) {
          char *tmp = CHAR_DEREF(STRING_ELT(val, i));
            for(j = 0; j < len; j++)
          if(strcmp(tmp, localNames[j]) == 0 || strcmp(tmp, realNames[j]) == 0) {
            value = value | cValues[j];
                break;
          }
            if(j == len) {
               PROBLEM "Invalid flag name: %s", tmp
                   ERROR;
          }
      }
        PROTECT(ans = NEW_INTEGER(1));
        numProtects = 1;
        INTEGER_DATA(ans)[0] = value;
   }

    PROTECT(names = NEW_CHARACTER(2));   
    SET_STRING_ELT(names, 0, COPY_TO_USER_STRING(flagName));
    SET_STRING_ELT(names, 1, COPY_TO_USER_STRING("flag"));
    SET_CLASS(ans, names);

    UNPROTECT(numProtects + 1);

    return(ans);
}

USER_OBJECT_
R_toRFlag(int value, const char *flagName)
{
    USER_OBJECT_ ans, names;
    PROTECT(ans = NEW_INTEGER(1));
    INTEGER_DATA(ans)[0] = value;

    PROTECT(names = NEW_CHARACTER(2));   
    SET_STRING_ELT(names, 0, COPY_TO_USER_STRING(flagName));
    SET_STRING_ELT(names, 1, COPY_TO_USER_STRING("flag"));
    SET_CLASS(ans, names);

    UNPROTECT(2);
    return(ans);
}


USER_OBJECT_
toRPointer(void *val, const char *type)
{
    USER_OBJECT_ ans;

    if(val == NULL)
       return(NULL_USER_OBJECT);

    PROTECT(ans = R_MakeExternalPtr(val, Rf_install(type), NULL_USER_OBJECT));
    if(type) {
      SET_CLASS(ans, asRCharacter(type));
    }
    UNPROTECT(1);
  
    return(ans);
}

void *
getPtrValue(USER_OBJECT_ sval)
{
  if(sval == NULL_USER_OBJECT)
      return(NULL);

  return(R_ExternalPtrAddr(sval));
}

USER_OBJECT_
S_newTargetEntry(USER_OBJECT_ target, USER_OBJECT_ flags, USER_OBJECT_ info)
{
    GtkTargetEntry *entry;

    entry = (GtkTargetEntry*) g_malloc(sizeof(GtkTargetEntry));
    entry->target = g_strdup(CHAR_DEREF(STRING_ELT(target, 0)));
    entry->flags = INTEGER_DATA(flags)[0];
    entry->info = INTEGER_DATA(info)[0] < 0 ? 0 : INTEGER_DATA(info)[0];
/*XXX Need to put a finalizer here. */

    return(toRPointer(entry, "GtkTargetEntry"));
}

void
R_setArgFromSValue(USER_OBJECT_ sval, GtkArg *arg)
{
    switch(TYPEOF(sval)) {
      case LGLSXP: 
        arg->type = GTK_TYPE_BOOL;
        GTK_VALUE_BOOL(*arg) = LOGICAL_DATA(sval)[0];
      break;
      case INTSXP: 
        arg->type = GTK_TYPE_INT;
        GTK_VALUE_INT(*arg) = INTEGER_DATA(sval)[0];
      break;
      case REALSXP: 
        arg->type = GTK_TYPE_DOUBLE;
        GTK_VALUE_DOUBLE(*arg) = NUMERIC_DATA(sval)[0];
      break;
      case EXTPTRSXP: 
        arg->type = GTK_TYPE_POINTER;
        GTK_VALUE_POINTER(*arg) = getPtrValue(sval);
      break;
      case STRSXP: 
        arg->type = GTK_TYPE_STRING;
        GTK_VALUE_STRING(*arg) = g_strdup(CHAR_DEREF(STRING_ELT(sval, 0)));
      break;
     default:
       fprintf(stderr, "Unhandled R type %d\n", TYPEOF(sval));fflush(stderr);
    }
}

USER_OBJECT_
convertGtkArgToSValue(GtkArg arg)
{
    USER_OBJECT_ ans = NULL_USER_OBJECT;

    switch(arg.type) {
      case GTK_TYPE_CHAR:
      {
        char tmp[2] = "a";
        tmp[0] = GTK_VALUE_CHAR(arg);
        ans = asRCharacter(tmp);
        break;
      }
      case GTK_TYPE_UCHAR:
      {
        char tmp[2] = "a";
        tmp[0] = GTK_VALUE_UCHAR(arg);
        ans = asRCharacter(tmp);
        break;
      }
      case GTK_TYPE_INT:
        ans = asRInt(GTK_VALUE_INT(arg));
        break;
      case GTK_TYPE_UINT:
        ans = asRInt(GTK_VALUE_UINT(arg));
        break;
      case GTK_TYPE_LONG:
        ans = asRInt(GTK_VALUE_LONG(arg));
        break;
      case GTK_TYPE_ULONG:
        ans = asRNumeric(GTK_VALUE_ULONG(arg));
        break;

      case GTK_TYPE_BOOL:
        ans = asRLogical(GTK_VALUE_BOOL(arg));
        break;

      case GTK_TYPE_FLOAT:
        ans = asRNumeric(GTK_VALUE_FLOAT(arg));
        break;

      case GTK_TYPE_DOUBLE:
        ans = asRNumeric(GTK_VALUE_DOUBLE(arg));
        break;

      case GTK_TYPE_STRING:
        ans = asRCharacter(GTK_VALUE_STRING(arg));
        break;


      case GTK_TYPE_ENUM:
        ans = asRInt(GTK_VALUE_ENUM(arg));
        break;
      case GTK_TYPE_FLAGS:
        ans = asRInt(GTK_VALUE_FLAGS(arg));
        break;

      case GTK_TYPE_BOXED:
        ans = toRPointer(GTK_VALUE_BOXED(arg), "GtkBoxed");
        break;

      case GTK_TYPE_POINTER:
        ans = toRPointer(GTK_VALUE_POINTER(arg), "<?>");
        break;

      case GTK_TYPE_SIGNAL:
        fprintf(stderr, "Signal type\n");fflush(stderr);
        break;
      case GTK_TYPE_ARGS:
        fprintf(stderr, "Args type\n");fflush(stderr);
        break;
      case GTK_TYPE_CALLBACK:
        fprintf(stderr, "Callback type\n");fflush(stderr);
        break;
      case GTK_TYPE_C_CALLBACK:
        fprintf(stderr, "C Callback type\n");fflush(stderr);
        break;
      case GTK_TYPE_FOREIGN:
        fprintf(stderr, "Foreign type\n");fflush(stderr);
        break;

      case GTK_TYPE_INVALID:
        fprintf(stderr, "Invalid type\n");fflush(stderr);
        break;

      case GTK_TYPE_NONE:
        fprintf(stderr, "None type\n");fflush(stderr);
        break;

      case GTK_TYPE_OBJECT:
      {
        ans = toRPointer(GTK_VALUE_OBJECT(arg), "GtkObject");
          PROTECT(ans);
          SET_CLASS(ans, R_internal_getTypeHierarchy(GTK_OBJECT_TYPE(GTK_VALUE_OBJECT(arg))));
          UNPROTECT(1);
        break;
      }

      default:
        if(strcmp(gtk_type_name(arg.type), "GdkEvent") == 0) {
            GdkEvent *ev = GTK_VALUE_POINTER(arg);
            char *evType;
            USER_OBJECT_ klass;
            if(!ev)
                return(NULL_USER_OBJECT);
              switch(ev->type) {
              case GDK_BUTTON_RELEASE:
              case GDK_BUTTON_PRESS:
              case GDK_2BUTTON_PRESS:
              case GDK_3BUTTON_PRESS:
                    evType = "GdkEventButton";
                break;
              case GDK_MOTION_NOTIFY:
                    evType = "GdkEventMotion";
                break;
              case GDK_KEY_RELEASE:
              case GDK_KEY_PRESS:
                    evType = "GdkEventKey";
                break;
                case GDK_ENTER_NOTIFY:
                case GDK_LEAVE_NOTIFY:
                    evType = "GdkEventKey";
                break;
                case GDK_DRAG_ENTER:
                case GDK_DRAG_LEAVE:
                case GDK_DRAG_MOTION:
                case GDK_DRAG_STATUS:
                case GDK_DROP_START:
                case GDK_DROP_FINISHED:
                  evType = "GdkEventDND";
                  break;
                case GDK_PROPERTY_NOTIFY:
                  evType = "GdkEventProperty";
                  break;
                case GDK_CONFIGURE:
                      evType = "GdkEventConfigure";
                  break;
                  default:
                  evType = "To be filled in later";
                  break;
            }
            ans = toRPointer(GTK_VALUE_POINTER(arg), gtk_type_name(arg.type));
              PROTECT(ans);
              PROTECT(klass = NEW_CHARACTER(2));
              SET_STRING_ELT(klass, 0, COPY_TO_USER_STRING(evType));
              SET_STRING_ELT(klass, 1, COPY_TO_USER_STRING("GdkEvent"));
              SET_CLASS(ans, klass);
            UNPROTECT(2);
/*
              fprintf(stderr, "event type %d\n", ev->type);fflush(stderr);
*/
        } else {
              GtkType type = arg.type;
              if(type == GTK_TYPE_WIDGET)
              type = GTK_OBJECT_TYPE(GTK_OBJECT(GTK_VALUE_POINTER(arg)));
            PROTECT(ans = toRPointer(GTK_VALUE_POINTER(arg), gtk_type_name(type)));
            SET_CLASS(ans, R_internal_getTypeHierarchy(type));
              UNPROTECT(1);
        }
/*
        fprintf(stderr, "handling generic type: GtkArg type %s (%d)\n", gtk_type_name(arg.type), arg.type);fflush(stderr);
*/
        break;
    }

    return(ans);
}

Generated by  Doxygen 1.6.0   Back to index