Exemple #1
0
/*
 * External entry to manage registering callbacks
 * 'xtra1' and 'xtra2' are ignored by most callbacks; only the two callbacks
 * use them:
 *   glutTimerFunc: xtra1 for millliseconds, xtra2 for value
 *   glutJoystickFunc: xtra1 for interval
 */
void Scm_GlutRegisterCallback(int type, ScmObj closure, int xtra1, int xtra2)
{
    SCM_ASSERT(type >= 0 && type < SCM_GLUT_NUM_CBS);
    if (type < SCM_GLUT_NUM_WINDOW_CBS) {
        int win = glutGetWindow();
        ScmObj entry = Scm_HashTableRef(SCM_HASH_TABLE(ScmGlutCallbackTable),
                                        SCM_MAKE_INT(win), SCM_FALSE);
        
        if (SCM_EQ(entry, SCM_FALSE)) {
            entry = Scm_MakeVector(SCM_GLUT_NUM_WINDOW_CBS, SCM_FALSE);
            Scm_HashTableSet(SCM_HASH_TABLE(ScmGlutCallbackTable),
                             SCM_MAKE_INT(win), entry, 0);
        }
        SCM_VECTOR_ELEMENT(entry, type) = closure;
        registrars[type](!SCM_FALSEP(closure), xtra1);
    } else if (type == SCM_GLUT_CB_IDLE) {
        idle_closure = closure;
        if (SCM_FALSEP(closure)) {
            glutIdleFunc(NULL);
        } else {
            glutIdleFunc(idle_cb);
        }
    } else {
        timer_closure = closure;
        if (!SCM_FALSEP(closure)) {
            glutTimerFunc(xtra1, timer_cb, xtra2);
        }
    }
}
Exemple #2
0
/*------------------------------------------------------------
 * Vport Getb
 */
static int vport_getb(ScmPort *p)
{
    vport *data = (vport*)p->src.vt.data;
    SCM_ASSERT(data != NULL);

    if (SCM_FALSEP(data->getb_proc)) {
        /* If the port doesn't have get-byte method, use get-char
           if possible. */
        ScmObj ch;
        ScmChar c;
        char buf[SCM_CHAR_MAX_BYTES];
        int nb, i;

        if (SCM_FALSEP(data->getc_proc)) return EOF;
        ch = Scm_ApplyRec(data->getc_proc, SCM_NIL);
        if (!SCM_CHARP(ch)) return EOF;

        c = SCM_CHAR_VALUE(ch);
        nb = SCM_CHAR_NBYTES(c);
        SCM_CHAR_PUT(buf, c);

        for (i=1; i<nb; i++) {
            /* pushback for later use.  this isn't very efficient;
               if efficiency becomes a problem, we need another API
               to pushback multiple bytes. */
            Scm_UngetbUnsafe(buf[i], p);
        }
        return buf[0];
    } else {
        ScmObj b = Scm_ApplyRec(data->getb_proc, SCM_NIL);
        if (!SCM_INTP(b)) return EOF;
        return (SCM_INT_VALUE(b) & 0xff);
    }
}
Exemple #3
0
/*------------------------------------------------------------
 * Vport Getc
 */
static int vport_getc(ScmPort *p)
{
    vport *data = (vport*)p->src.vt.data;
    SCM_ASSERT(data != NULL);

    if (SCM_FALSEP(data->getc_proc)) {
        /* If the port doesn't have get-char method, try get-byte */
        ScmObj b;
        int n, i;
        ScmChar ch;
        char buf[SCM_CHAR_MAX_BYTES];

        if (SCM_FALSEP(data->getb_proc)) return EOF;
        b = Scm_ApplyRec(data->getb_proc, SCM_NIL);
        if (!SCM_INTP(b)) return EOF;
        buf[0] = (char)SCM_INT_VALUE(b);
        n = SCM_CHAR_NFOLLOWS(p->scratch[0]);
        for (i=0; i<n; i++) {
            b = Scm_ApplyRec(data->getb_proc, SCM_NIL);
            if (!SCM_INTP(b)) {
                /* TODO: should raise an exception? */
                return EOF;
            }
            buf[i+1] = (char)SCM_INT_VALUE(b);
        }
        SCM_CHAR_GET(buf, ch);
        return ch;
    } else {
        ScmObj ch = Scm_ApplyRec(data->getc_proc, SCM_NIL);
        if (!SCM_CHARP(ch)) return EOF;
        return SCM_CHAR_VALUE(ch);
    }
}
Exemple #4
0
static void porterror_port_set(ScmPortError *obj, ScmObj val)
{
    if (!SCM_PORTP(val) && !SCM_FALSEP(val)) {
        Scm_Error("port or #f required, but got %S", val);
    }
    obj->port = SCM_FALSEP(val)? NULL : SCM_PORT(val);
}
Exemple #5
0
/*------------------------------------------------------------
 * Vport puts
 */
static void vport_puts(ScmString *s, ScmPort *p)
{
    vport *data = (vport*)p->src.vt.data;
    const ScmStringBody *b = SCM_STRING_BODY(s);
    SCM_ASSERT(data != NULL);

    if (!SCM_FALSEP(data->puts_proc)) {
        Scm_ApplyRec(data->puts_proc, SCM_LIST1(SCM_OBJ(s)));
    } else if (SCM_STRING_BODY_INCOMPLETE_P(b)
               || (SCM_FALSEP(data->putc_proc)
                   && !SCM_FALSEP(data->putb_proc))) {
        /* we perform binary output */
        vport_putz(SCM_STRING_BODY_START(b), SCM_STRING_BODY_SIZE(b), p);
    } else if (!SCM_FALSEP(data->putc_proc)) {
        ScmChar c;
        int i;
        const char *cp = SCM_STRING_BODY_START(b);
        for (i=0; i < (int)SCM_STRING_BODY_LENGTH(b); i++) {
            SCM_CHAR_GET(cp, c);
            cp += SCM_CHAR_NFOLLOWS(*cp)+1;
            Scm_ApplyRec(data->putc_proc, SCM_LIST1(SCM_MAKE_CHAR(c)));
        }
    } else {
        Scm_PortError(p, SCM_PORT_ERROR_OTHER,
                      "cannot perform output to the port %S", p);
    }
}
Exemple #6
0
/*------------------------------------------------------------
 * Bport Ready
 */
static int bport_ready(ScmPort *p)
{
    bport *data = (bport*)p->src.buf.data;
    SCM_ASSERT(data != NULL);

    if (!SCM_FALSEP(data->ready_proc)) {
        ScmObj s = Scm_ApplyRec(data->ready_proc, SCM_NIL);
        return SCM_FALSEP(s)? SCM_FD_WOULDBLOCK:SCM_FD_READY;
    } else {
        /* if no method is given, always return #t */
        return SCM_FD_READY;
    }
}
Exemple #7
0
/*------------------------------------------------------------
 * Vport Ready
 */
static int vport_ready(ScmPort *p, int charp)
{
    vport *data = (vport*)p->src.vt.data;
    SCM_ASSERT(data != NULL);

    if (!SCM_FALSEP(data->ready_proc)) {
        ScmObj s = Scm_ApplyRec(data->ready_proc,
                                SCM_LIST1(SCM_MAKE_BOOL(charp)));
        return !SCM_FALSEP(s);
    } else {
        /* if no method is given, always return #t */
        return TRUE;
    }
}
Exemple #8
0
/*------------------------------------------------------------
 * Vport Gets
 */
static int vport_getz(char *buf, int buflen, ScmPort *p)
{
    vport *data = (vport*)p->src.vt.data;
    SCM_ASSERT(data != NULL);

    if (!SCM_FALSEP(data->gets_proc)) {
        u_int size;
        const char *start;
        ScmObj s = Scm_ApplyRec(data->gets_proc,
                                SCM_LIST1(SCM_MAKE_INT(buflen)));
        if (!SCM_STRINGP(s)) return EOF;
        start = Scm_GetStringContent(SCM_STRING(s), &size, NULL, NULL);
        if ((int)size > buflen) {
            /* NB: should raise an exception? */
            memcpy(buf, start, buflen);
            return buflen;
        } else {
            memcpy(buf, start, size);
            return size;
        }
    } else {
        int byte, i;
        for (i=0; i<buflen; i++) {
            byte = vport_getb(p);
            if (byte == EOF) break;
            buf[i] = byte;
        }
        if (i==0) return EOF;
        else return i;
    }
}
Exemple #9
0
static void mutex_print(ScmObj obj, ScmPort *port, ScmWriteContext *ctx)
{
    ScmMutex *mutex = SCM_MUTEX(obj);

    (void)SCM_INTERNAL_MUTEX_LOCK(mutex->mutex);
    int locked = mutex->locked;
    ScmVM *vm = mutex->owner;
    ScmObj name = mutex->name;
    (void)SCM_INTERNAL_MUTEX_UNLOCK(mutex->mutex);

    if (SCM_FALSEP(name)) Scm_Printf(port, "#<mutex %p ", mutex);
    else                  Scm_Printf(port, "#<mutex %S ", name);
    if (locked) {
        if (vm) {
            if (vm->state == SCM_VM_TERMINATED) {
                Scm_Printf(port, "unlocked/abandoned>");
            } else {
                Scm_Printf(port, "locked/owned by %S>", vm);
            }
        } else {
            Scm_Printf(port, "locked/not-owned>");
        }
    } else {
        Scm_Printf(port, "unlocked/not-abandoned>");
    }
}
Exemple #10
0
static void cv_print(ScmObj obj, ScmPort *port, ScmWriteContext *ctx)
{
    ScmConditionVariable *cv = SCM_CONDITION_VARIABLE(obj);
    ScmObj name = cv->name;
    if (SCM_FALSEP(name)) Scm_Printf(port, "#<condition-variable %p>", cv);
    else                  Scm_Printf(port, "#<condition-variable %S>", name);
}
Exemple #11
0
/* internal constructor.  NAME must be an immutable string. */
static ScmSymbol *make_sym(ScmClass *klass, ScmString *name, int interned)
{
    if (interned) {
        /* fast path */
        SCM_INTERNAL_MUTEX_LOCK(obtable_mutex);
        ScmObj e = Scm_HashTableRef(obtable, SCM_OBJ(name), SCM_FALSE);
        SCM_INTERNAL_MUTEX_UNLOCK(obtable_mutex);
        if (!SCM_FALSEP(e)) return SCM_SYMBOL(e);
    }

    ScmSymbol *sym = SCM_NEW(ScmSymbol);
    SCM_SET_CLASS(sym, klass);
    sym->name = name;
    sym->flags = interned? SCM_SYMBOL_FLAG_INTERNED : 0;

    if (!interned) {
        return sym;
    } else {
        /* Using SCM_DICT_NO_OVERWRITE ensures that if another thread interns
           the same name symbol between above HashTableRef and here, we'll
           get the already interned symbol. */
        SCM_INTERNAL_MUTEX_LOCK(obtable_mutex);
        ScmObj e = Scm_HashTableSet(obtable, SCM_OBJ(name), SCM_OBJ(sym),
                                    SCM_DICT_NO_OVERWRITE);
        SCM_INTERNAL_MUTEX_UNLOCK(obtable_mutex);
        return SCM_SYMBOL(e);
    }
}
Exemple #12
0
int
graphicsGdImageDestroyedP(ScmObj obj)
{
  SCM_ASSERT(SCM_FOREIGN_POINTER_P(obj));
  return !SCM_FALSEP(Scm_ForeignPointerAttrGet(SCM_FOREIGN_POINTER(obj),
											   sym_destroyed, SCM_FALSE));
}
Exemple #13
0
/*------------------------------------------------------------
 * Vport flush
 */
static void vport_flush(ScmPort *p)
{
    vport *data = (vport*)p->src.vt.data;
    SCM_ASSERT(data != NULL);
    if (!SCM_FALSEP(data->flush_proc)) {
        Scm_ApplyRec(data->flush_proc, SCM_NIL);
    }
}
Exemple #14
0
/*------------------------------------------------------------
 * Bport close
 */
static void bport_close(ScmPort *p)
{
    bport *data = (bport*)p->src.buf.data;
    SCM_ASSERT(data != NULL);
    if (!SCM_FALSEP(data->close_proc)) {
        Scm_ApplyRec(data->close_proc, SCM_NIL);
    }
}
Exemple #15
0
static void promise_print(ScmObj obj, ScmPort *port, ScmWriteContext *ctx)
{
    ScmPromise *p = (ScmPromise*)obj;
    const char *forced = p->content->forced? " (forced)" : "";
    if (SCM_FALSEP(p->kind)) {
        Scm_Printf(port, "#<promise %p%s>", p, forced);
    } else {
        Scm_Printf(port, "#<promise(%S) %p%s>", p->kind, p, forced);
    }
}
Exemple #16
0
ScmObj Scm_MutexUnlocker(ScmMutex *mutex)
{
    ScmObj p = mutex->unlocker_proc;
    if (SCM_FALSEP(p)) {
        /* safe; race is ok here */
        p = Scm_MakeSubr(mutex_unlocker, (void*)mutex, 0, 0, SCM_FALSE);
        mutex->unlocker_proc = p;
    }
    return p;
}
Exemple #17
0
/* Error handling */
void error_exit(ScmObj c)
{
    ScmObj m = Scm_ConditionMessage(c);
    if (SCM_FALSEP(m)) {
        Scm_Printf(SCM_CURERR, "gosh: Thrown unknown condition: %S\n", c);
    } else {
        Scm_Printf(SCM_CURERR, "gosh: %S: %A\n", Scm_ConditionTypeName(c), m);
    }
    Scm_Exit(1);
}
Exemple #18
0
/*------------------------------------------------------------
 * Vport putz
 */
static void vport_putz(const char *buf, int size, ScmPort *p)
{
    vport *data = (vport*)p->src.vt.data;
    SCM_ASSERT(data != NULL);

    if (!SCM_FALSEP(data->puts_proc)) {
        Scm_ApplyRec(data->puts_proc,
                     SCM_LIST1(Scm_MakeString(buf, size, -1,
                                              SCM_STRING_COPYING)));
    } else if (!SCM_FALSEP(data->putb_proc)) {
        for (int i=0; i<size; i++) {
            unsigned char b = buf[i];
            Scm_ApplyRec(data->putb_proc, SCM_LIST1(SCM_MAKE_INT(b)));
        }
    } else {
        Scm_PortError(p, SCM_PORT_ERROR_UNIT,
                      "cannot perform binary output to the port %S", p);
   }
}
Exemple #19
0
ScmObj Scm_ComparatorOrderingPredicate(ScmComparator *cmpr)
{
    if (SCM_FALSEP(cmpr->orderFn)) {
        static ScmObj p = SCM_UNDEFINED;
        SCM_BIND_PROC(p, "comparator-ordering-predicate",
                      Scm_GaucheModule());
        return Scm_ApplyRec1(p, SCM_OBJ(cmpr)); /* this fills orderFn */
    } else {
        return cmpr->orderFn;
    }
}
Exemple #20
0
/* C-level accessors, that take care of on-demand filling of slots. */
ScmObj Scm_ComparatorComparisonProcedure(ScmComparator *cmpr)
{
    if (SCM_FALSEP(cmpr->compareFn)) {
        static ScmObj p = SCM_UNDEFINED;
        SCM_BIND_PROC(p, "comparator-comparison-procedure",
                      Scm_GaucheModule());
        return Scm_ApplyRec1(p, SCM_OBJ(cmpr)); /* this fills compareFn */
    } else {
        return cmpr->compareFn;
    }
}
Exemple #21
0
ScmObj Scm_ComparatorHashFunction(ScmComparator *cmpr)
{
    if (SCM_FALSEP(cmpr->hashFn)) {
        static ScmObj p = SCM_UNDEFINED;
        SCM_BIND_PROC(p, "comparator-hash-function",
                      Scm_GaucheModule());
        return Scm_ApplyRec1(p, SCM_OBJ(cmpr)); /* this fills hashFn */
    } else {
        return cmpr->hashFn;
    }
}
Exemple #22
0
/*------------------------------------------------------------
 * Vport putb
 */
static void vport_putb(ScmByte b, ScmPort *p)
{
    vport *data = (vport*)p->src.vt.data;
    SCM_ASSERT(data != NULL);

    if (SCM_FALSEP(data->putb_proc)) {
        if (!SCM_FALSEP(data->putc_proc)
            && SCM_CHAR_NFOLLOWS(b) == 0) {
            /* This byte is a single-byte character, so we can use putc. */
            Scm_ApplyRec(data->putc_proc, SCM_LIST1(SCM_MAKE_CHAR(b)));
        } else {
            /* Given byte is a part of multibyte sequence.  We don't
               handle it for the time being. */
            Scm_PortError(p, SCM_PORT_ERROR_UNIT,
                          "cannot perform binary output to the port %S", p);
        }
    } else {
        Scm_ApplyRec(data->putb_proc, SCM_LIST1(SCM_MAKE_INT(b)));
    }
}
Exemple #23
0
/*------------------------------------------------------------
 * Vport putc
 */
static void vport_putc(ScmChar c, ScmPort *p)
{
    vport *data = (vport*)p->src.vt.data;
    SCM_ASSERT(data != NULL);

    if (SCM_FALSEP(data->putc_proc)) {
        if (SCM_FALSEP(data->putb_proc)) {
            Scm_PortError(p, SCM_PORT_ERROR_OTHER,
                          "cannot perform output to the port %S", p);
        } else {
            unsigned char buf[SCM_CHAR_MAX_BYTES];
            int i, n=SCM_CHAR_NBYTES(c);
            SCM_CHAR_PUT(buf, c);
            for (i=0; i<n; i++) {
                Scm_ApplyRec(data->putb_proc, SCM_LIST1(SCM_MAKE_INT(buf[i])));
            }
        }
    } else {
        Scm_ApplyRec(data->putc_proc, SCM_LIST1(SCM_MAKE_CHAR(c)));
    }
}
Exemple #24
0
static void readerror_port_set(ScmReadError *obj, ScmObj val)
{
    if (SCM_IPORTP(val)) {
        obj->port = SCM_PORT(val);
    }
    else if (SCM_FALSEP(val)) {
        obj->port = NULL;
    }
    else {
        Scm_Error("input port or #f required, but got %S", val);
    }
}
Exemple #25
0
/* Default method for write-object */
static ScmObj write_object_fallback(ScmObj *args, int nargs, ScmGeneric *gf)
{
    if (nargs != 2 || (nargs == 2 && !SCM_OPORTP(args[1]))) {
        Scm_Error("No applicable method for write-object with %S",
                  Scm_ArrayToList(args, nargs));
    }
    ScmClass *klass = Scm_ClassOf(args[0]);
    Scm_Printf(SCM_PORT(args[1]), "#<%A%s%p>",
               klass->name,
               (SCM_FALSEP(klass->redefined)? " " : ":redefined "),
               args[0]);
    return SCM_TRUE;
}
Exemple #26
0
/*------------------------------------------------------------
 * Bport filenum
 */
static int bport_filenum(ScmPort *p)
{
    bport *data = (bport*)p->src.buf.data;
    SCM_ASSERT(data != NULL);

    if (SCM_FALSEP(data->filenum_proc)) {
        return -1;
    } else {
        ScmObj s = Scm_ApplyRec(data->filenum_proc, SCM_NIL);
        if (SCM_INTP(s)) return SCM_INT_VALUE(s);
        else return -1;
    }
}
Exemple #27
0
/*------------------------------------------------------------
 * Bport seek
 */
static off_t bport_seek(ScmPort *p, off_t off, int whence)
{
    bport *data = (bport*)p->src.buf.data;
    SCM_ASSERT(data != NULL);
    if (!SCM_FALSEP(data->seek_proc)) {
        ScmObj r = Scm_ApplyRec(data->seek_proc,
                                SCM_LIST2(Scm_OffsetToInteger(off),
                                          Scm_MakeInteger(whence)));
        if (SCM_INTEGERP(r)) {
            return Scm_IntegerToOffset(r);
        }
    }
    return (off_t)-1;
}
Exemple #28
0
/*------------------------------------------------------------
 * Bport fill
 */
static int bport_fill(ScmPort *p, int cnt)
{
    bport *data = (bport*)p->src.buf.data;
    SCM_ASSERT(data != NULL);
    if (SCM_FALSEP(data->fill_proc)) {
        return 0;               /* indicates EOF */
    }
    ScmObj vec = Scm_MakeU8VectorFromArrayShared(
        cnt, (unsigned char*)p->src.buf.buffer);
    ScmObj r = Scm_ApplyRec(data->fill_proc, SCM_LIST1(vec));
    if (SCM_INTP(r)) return SCM_INT_VALUE(r);
    else if (SCM_EOFP(r)) return 0;
    else return -1;
}
Exemple #29
0
/*------------------------------------------------------------
 * Bport flush
 */
static int bport_flush(ScmPort *p, int cnt, int forcep)
{
    bport *data = (bport*)p->src.buf.data;
    ScmObj vec, r;
    SCM_ASSERT(data != NULL);
    if (SCM_FALSEP(data->flush_proc)) {
        return cnt;             /* blackhole */
    }
    vec = Scm_MakeU8VectorFromArrayShared(cnt,
                                          (unsigned char*)p->src.buf.buffer);
    r = Scm_ApplyRec(data->flush_proc, SCM_LIST2(vec, SCM_MAKE_BOOL(forcep)));
    if (SCM_INTP(r)) return SCM_INT_VALUE(r);
    else if (SCM_EOFP(r)) return 0;
    else return -1;
}
Exemple #30
0
/* Auxiliary function */
const char* Scm_GetCESName(ScmObj code, const char *argname)
{
    const char *c = NULL;
    if (SCM_UNBOUNDP(code) || SCM_FALSEP(code)) {
        c = Scm_SupportedCharacterEncodings()[0];
    } else if (SCM_STRINGP(code)) {
        c = Scm_GetStringConst(SCM_STRING(code));
    } else if (SCM_SYMBOLP(code)) {
        c = Scm_GetStringConst(SCM_SYMBOL_NAME(code));
    } else {
        Scm_Error("string, symbol or #f is required for %s, but got %S",
                  argname, code);
    }
    return c;
}