# module TclTkLib

—- initialization —-

wrap methods on TclTkLib : not permit calling TclTkLib module methods

### Constants

COMPILE_INFO

FINALIZE_PROC_NAME
RELEASE_DATE
WINDOWING_SYSTEM

### Public Class Methods

_conv_listelement(p1) click to toggle source

    static VALUE
    lib_conv_listelement(self, src)
        VALUE self;
        VALUE src;
    {
        int   len, scan_flag;
        volatile VALUE dst;
        int   taint_flag = OBJ_TAINTED(src);
        int thr_crit_bup;

        tcl_stubs_check();

        thr_crit_bup = rb_thread_critical;
        rb_thread_critical = Qtrue;

        StringValue(src);

    #if TCL_MAJOR_VERSION >= 8
        len = Tcl_ScanCountedElement(RSTRING_PTR(src), RSTRING_LENINT(src),
                                     &scan_flag);
        dst = rb_str_new(0, len + 1);
        len = Tcl_ConvertCountedElement(RSTRING_PTR(src), RSTRING_LENINT(src),
                                        RSTRING_PTR(dst), scan_flag);
    #else /* TCL_MAJOR_VERSION < 8 */
        len = Tcl_ScanElement(RSTRING_PTR(src), &scan_flag);
        dst = rb_str_new(0, len + 1);
        len = Tcl_ConvertElement(RSTRING_PTR(src), RSTRING_PTR(dst), scan_flag);
    #endif

        rb_str_resize(dst, len);
        if (taint_flag) RbTk_OBJ_UNTRUST(dst);

        rb_thread_critical = thr_crit_bup;

        return dst;
    }

_fromUTF8(p1, p2 = v2) click to toggle source

    static VALUE
    lib_fromUTF8(argc, argv, self)
        int   argc;
        VALUE *argv;
        VALUE self;
    {
        VALUE str, encodename;

        if (rb_scan_args(argc, argv, "11", &str, &encodename) == 1) {
            encodename = Qnil;
        }
        return lib_fromUTF8_core(Qnil, str, encodename);
    }

_merge_tklist(*args) click to toggle source

    static VALUE
    lib_merge_tklist(argc, argv, obj)
        int argc;
        VALUE *argv;
        VALUE obj;
    {
        int  num, len;
        int  *flagPtr;
        char *dst, *result;
        volatile VALUE str;
        int taint_flag = 0;
        int thr_crit_bup;
        VALUE old_gc;

        if (argc == 0) return rb_str_new2("");

        tcl_stubs_check();

        thr_crit_bup = rb_thread_critical;
        rb_thread_critical = Qtrue;
        old_gc = rb_gc_disable();

        /* based on Tcl/Tk's Tcl_Merge() */
        /* flagPtr = ALLOC_N(int, argc); */
        flagPtr = RbTk_ALLOC_N(int, argc);
    #if 0 /* use Tcl_Preserve/Release */
        Tcl_Preserve((ClientData)flagPtr); /* XXXXXXXXXX */
    #endif

        /* pass 1 */
        len = 1;
        for(num = 0; num < argc; num++) {
            if (OBJ_TAINTED(argv[num])) taint_flag = 1;
            dst = StringValueCStr(argv[num]);
    #if TCL_MAJOR_VERSION >= 8
            len += Tcl_ScanCountedElement(dst, RSTRING_LENINT(argv[num]),
                                          &flagPtr[num]) + 1;
    #else /* TCL_MAJOR_VERSION < 8 */
            len += Tcl_ScanElement(dst, &flagPtr[num]) + 1;
    #endif
        }

        /* pass 2 */
        /* result = (char *)Tcl_Alloc(len); */
        result = (char *)ckalloc(len);
    #if 0 /* use Tcl_Preserve/Release */
        Tcl_Preserve((ClientData)result);
    #endif
        dst = result;
        for(num = 0; num < argc; num++) {
    #if TCL_MAJOR_VERSION >= 8
            len = Tcl_ConvertCountedElement(RSTRING_PTR(argv[num]),
                                            RSTRING_LENINT(argv[num]),
                                            dst, flagPtr[num]);
    #else /* TCL_MAJOR_VERSION < 8 */
            len = Tcl_ConvertElement(RSTRING_PTR(argv[num]), dst, flagPtr[num]);
    #endif
            dst += len;
            *dst = ' ';
            dst++;
        }
        if (dst == result) {
            *dst = 0;
        } else {
            dst[-1] = 0;
        }

    #if 0 /* use Tcl_EventuallyFree */
        Tcl_EventuallyFree((ClientData)flagPtr, TCL_DYNAMIC); /* XXXXXXXX */
    #else
    #if 0 /* use Tcl_Preserve/Release */
        Tcl_Release((ClientData)flagPtr);
    #else
        /* free(flagPtr); */
        ckfree((char*)flagPtr);
    #endif
    #endif

        /* create object */
        str = rb_str_new(result, dst - result - 1);
        if (taint_flag) RbTk_OBJ_UNTRUST(str);
    #if 0 /* use Tcl_EventuallyFree */
        Tcl_EventuallyFree((ClientData)result, TCL_DYNAMIC); /* XXXXXXXX */
    #else
    #if 0 /* use Tcl_Preserve/Release */
        Tcl_Release((ClientData)result); /* XXXXXXXXXXX */
    #else
        /* Tcl_Free(result); */
        ckfree(result);
    #endif
    #endif

        if (old_gc == Qfalse) rb_gc_enable();
        rb_thread_critical = thr_crit_bup;

        return str;
    }

_split_tklist(p1) click to toggle source

    static VALUE
    lib_split_tklist(self, list_str)
        VALUE self;
        VALUE list_str;
    {
        return lib_split_tklist_core(Qnil, list_str);
    }

_subst_Tcl_backslash(p1) click to toggle source

    static VALUE
    lib_Tcl_backslash(self, str)
        VALUE self;
        VALUE str;
    {
        return lib_UTF_backslash_core(self, str, 1);
    }

_subst_UTF_backslash(p1) click to toggle source

    static VALUE
    lib_UTF_backslash(self, str)
        VALUE self;
        VALUE str;
    {
        return lib_UTF_backslash_core(self, str, 0);
    }

_toUTF8(p1, p2 = v2) click to toggle source

    static VALUE
    lib_toUTF8(argc, argv, self)
        int   argc;
        VALUE *argv;
        VALUE self;
    {
        VALUE str, encodename;

        if (rb_scan_args(argc, argv, "11", &str, &encodename) == 1) {
            encodename = Qnil;
        }
        return lib_toUTF8_core(Qnil, str, encodename);
    }

do_one_event(*args) click to toggle source

    static VALUE
    lib_do_one_event(argc, argv, self)
        int   argc;
        VALUE *argv;
        VALUE self;
    {
        return lib_do_one_event_core(argc, argv, self, 0);
    }

do_thread_callback(p1 = v1) click to toggle source

    static VALUE
    lib_thread_callback(argc, argv, self)
        int argc;
        VALUE *argv;
        VALUE self;
    {
        struct thread_call_proc_arg *q;
        VALUE proc, th, ret;
        int status;

        if (rb_scan_args(argc, argv, "01", &proc) == 0) {
            proc = rb_block_proc();
        }

        q = (struct thread_call_proc_arg *)ALLOC(struct thread_call_proc_arg);
        /* q = RbTk_ALLOC_N(struct thread_call_proc_arg, 1); */
        q->proc = proc;
        q->done = (int*)ALLOC(int);
        /* q->done = RbTk_ALLOC_N(int, 1); */
        *(q->done) = 0;

        /* create call-proc thread */
        th = rb_thread_create(_thread_call_proc, (void*)q);

        rb_thread_schedule();

        /* start sub-eventloop */
        lib_eventloop_launcher(/* not check root-widget */0, 0,
                               q->done, (Tcl_Interp*)NULL);

        if (RTEST(rb_thread_alive_p(th))) {
            rb_funcall(th, ID_kill, 0);
            ret = Qnil;
        } else {
            ret = rb_protect(_thread_call_proc_value, th, &status);
        }

        xfree(q->done);
        xfree(q);
        /* ckfree((char*)q->done); */
        /* ckfree((char*)q); */

        if (NIL_P(rbtk_pending_exception)) {
            /* return rb_errinfo(); */
            if (status) {
                rb_exc_raise(rb_errinfo());
            }
        } else {
            VALUE exc = rbtk_pending_exception;
            rbtk_pending_exception = Qnil;
            /* return exc; */
            rb_exc_raise(exc);
        }

        return ret;
    }

encoding() click to toggle source

    static VALUE
    lib_get_system_encoding(self)
        VALUE self;
    {
    #if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 0)
        tcl_stubs_check();
        return rb_str_new2(Tcl_GetEncodingName((Tcl_Encoding)NULL));
    #else
        return Qnil;
    #endif
    }

encoding=(p1) click to toggle source

    static VALUE
    lib_set_system_encoding(self, enc_name)
        VALUE self;
        VALUE enc_name;
    {
    #if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 0)
        tcl_stubs_check();

        if (NIL_P(enc_name)) {
            Tcl_SetSystemEncoding((Tcl_Interp *)NULL, (CONST char *)NULL);
            return lib_get_system_encoding(self);
        }

        enc_name = rb_funcallv(enc_name, ID_to_s, 0, 0);
        if (Tcl_SetSystemEncoding((Tcl_Interp *)NULL,
                                  StringValueCStr(enc_name)) != TCL_OK) {
            rb_raise(rb_eArgError, "unknown encoding name '%s'",
                     RSTRING_PTR(enc_name));
        }

        return enc_name;
    #else
        return Qnil;
    #endif
    }

encoding_system() click to toggle source

    static VALUE
    lib_get_system_encoding(self)
        VALUE self;
    {
    #if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 0)
        tcl_stubs_check();
        return rb_str_new2(Tcl_GetEncodingName((Tcl_Encoding)NULL));
    #else
        return Qnil;
    #endif
    }

encoding_system=(p1) click to toggle source

    static VALUE
    lib_set_system_encoding(self, enc_name)
        VALUE self;
        VALUE enc_name;
    {
    #if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 0)
        tcl_stubs_check();

        if (NIL_P(enc_name)) {
            Tcl_SetSystemEncoding((Tcl_Interp *)NULL, (CONST char *)NULL);
            return lib_get_system_encoding(self);
        }

        enc_name = rb_funcallv(enc_name, ID_to_s, 0, 0);
        if (Tcl_SetSystemEncoding((Tcl_Interp *)NULL,
                                  StringValueCStr(enc_name)) != TCL_OK) {
            rb_raise(rb_eArgError, "unknown encoding name '%s'",
                     RSTRING_PTR(enc_name));
        }

        return enc_name;
    #else
        return Qnil;
    #endif
    }

get_eventloop_tick() click to toggle source

    static VALUE
    get_eventloop_tick(self)
        VALUE self;
    {
        return INT2NUM(timer_tick);
    }

get_eventloop_weight() click to toggle source

    static VALUE
    get_eventloop_weight(self)
        VALUE self;
    {
        return rb_ary_new3(2, INT2NUM(event_loop_max), INT2NUM(no_event_tick));
    }

get_eventloop_window_mode() click to toggle source

    static VALUE
    get_eventloop_window_mode(self)
        VALUE self;
    {
        if ( ~window_event_mode ) {
          return Qfalse;
        } else {
          return Qtrue;
        }
    }

get_no_event_wait() click to toggle source

    static VALUE
    get_no_event_wait(self)
        VALUE self;
    {
        return INT2NUM(no_event_wait);
    }

get_release_type_name(*args) click to toggle source

    static VALUE
    lib_get_reltype_name(self)
        VALUE self;
    {
        set_tcltk_version();

        switch(tcltk_version.type) {
        case TCL_ALPHA_RELEASE:
          return rb_str_new2("alpha");
        case TCL_BETA_RELEASE:
          return rb_str_new2("beta");
        case TCL_FINAL_RELEASE:
          return rb_str_new2("final");
        default:
          rb_raise(rb_eRuntimeError, "tcltklib has invalid release type number");
        }

        UNREACHABLE;
    }

get_version(*args) click to toggle source

    static VALUE
    lib_getversion(self)
        VALUE self;
    {
        set_tcltk_version();

        return rb_ary_new3(4, INT2NUM(tcltk_version.major),
                              INT2NUM(tcltk_version.minor),
                              INT2NUM(tcltk_version.type),
                              INT2NUM(tcltk_version.patchlevel));
    }

mainloop(p1 = v1) click to toggle source

execute Tk_MainLoop

    static VALUE
    lib_mainloop(argc, argv, self)
        int   argc;
        VALUE *argv;
        VALUE self;
    {
        VALUE check_rootwidget;

        if (rb_scan_args(argc, argv, "01", &check_rootwidget) == 0) {
            check_rootwidget = Qtrue;
        } else if (RTEST(check_rootwidget)) {
            check_rootwidget = Qtrue;
        } else {
            check_rootwidget = Qfalse;
        }

        return lib_eventloop_launcher(RTEST(check_rootwidget), 0,
                                      (int*)NULL, (Tcl_Interp*)NULL);
    }

mainloop_abort_on_exception() click to toggle source

    static VALUE
    lib_evloop_abort_on_exc(self)
        VALUE self;
    {
        if (event_loop_abort_on_exc > 0) {
            return Qtrue;
        } else if (event_loop_abort_on_exc == 0) {
            return Qfalse;
        } else {
            return Qnil;
        }
    }

mainloop_abort_on_exception=(p1) click to toggle source

    static VALUE
    lib_evloop_abort_on_exc_set(self, val)
        VALUE self, val;
    {
        if (RTEST(val)) {
            event_loop_abort_on_exc =  1;
        } else if (NIL_P(val)) {
            event_loop_abort_on_exc = -1;
        } else {
            event_loop_abort_on_exc =  0;
        }
        return lib_evloop_abort_on_exc(self);
    }

mainloop_thread?() click to toggle source

    static VALUE
    lib_evloop_thread_p(self)
        VALUE self;
    {
        if (NIL_P(eventloop_thread)) {
            return Qnil;    /* no eventloop */
        } else if (rb_thread_current() == eventloop_thread) {
            return Qtrue;   /* is eventloop */
        } else {
            return Qfalse;  /* not eventloop */
        }
    }

mainloop_watchdog(p1 = v1) click to toggle source

    static VALUE
    lib_mainloop_watchdog(argc, argv, self)
        int   argc;
        VALUE *argv;
        VALUE self;
    {
        VALUE check_rootwidget;

    #ifdef RUBY_VM
        rb_raise(rb_eNotImpError,
                 "eventloop_watchdog is not implemented on Ruby VM.");
    #endif

        if (rb_scan_args(argc, argv, "01", &check_rootwidget) == 0) {
            check_rootwidget = Qtrue;
        } else if (RTEST(check_rootwidget)) {
            check_rootwidget = Qtrue;
        } else {
            check_rootwidget = Qfalse;
        }

        return rb_ensure(lib_watchdog_core, check_rootwidget,
                         lib_watchdog_ensure, Qnil);
    }

num_of_mainwindows() click to toggle source

    static VALUE
    lib_num_of_mainwindows(self)
        VALUE self;
    {
    #ifdef RUBY_USE_NATIVE_THREAD  /* Ruby 1.9+ !!! */
        return tk_funcall(lib_num_of_mainwindows_core, 0, (VALUE*)NULL, self);
    #else
        return lib_num_of_mainwindows_core(self, 0, (VALUE*)NULL);
    #endif
    }

restart(*args) click to toggle source

    # File lib/multi-tk.rb, line 2721
    def restart(*args)
      MultiTkIp.restart(*args)
    end

set_eventloop_tick(p1) click to toggle source

    static VALUE
    set_eventloop_tick(self, tick)
        VALUE self;
        VALUE tick;
    {
        int ttick = NUM2INT(tick);
        int thr_crit_bup;

        if (ttick < 0) {
            rb_raise(rb_eArgError,
                     "timer-tick parameter must be 0 or positive number");
        }

        thr_crit_bup = rb_thread_critical;
        rb_thread_critical = Qtrue;

        /* delete old timer callback */
        Tcl_DeleteTimerHandler(timer_token);

        timer_tick = req_timer_tick = ttick;
        if (timer_tick > 0) {
            /* start timer callback */
            timer_token = Tcl_CreateTimerHandler(timer_tick, _timer_for_tcl,
                                                 (ClientData)0);
        } else {
            timer_token = (Tcl_TimerToken)NULL;
        }

        rb_thread_critical = thr_crit_bup;

        return tick;
    }

set_eventloop_weight(p1, p2) click to toggle source

    static VALUE
    set_eventloop_weight(self, loop_max, no_event)
        VALUE self;
        VALUE loop_max;
        VALUE no_event;
    {
        int lpmax = NUM2INT(loop_max);
        int no_ev = NUM2INT(no_event);

        if (lpmax <= 0 || no_ev <= 0) {
            rb_raise(rb_eArgError, "weight parameters must be positive numbers");
        }

        event_loop_max = lpmax;
        no_event_tick  = no_ev;

        return rb_ary_new3(2, loop_max, no_event);
    }

set_eventloop_window_mode(p1) click to toggle source

    static VALUE
    set_eventloop_window_mode(self, mode)
        VALUE self;
        VALUE mode;
    {

        if (RTEST(mode)) {
          window_event_mode = ~0;
        } else {
          window_event_mode = ~TCL_WINDOW_EVENTS;
        }

        return mode;
    }

set_max_block_time(p1) click to toggle source

    static VALUE
    set_max_block_time(self, time)
        VALUE self;
        VALUE time;
    {
        struct Tcl_Time tcl_time;
        VALUE divmod;

        switch(TYPE(time)) {
        case T_FIXNUM:
        case T_BIGNUM:
            /* time is micro-second value */
            divmod = rb_funcall(time, rb_intern("divmod"), 1, LONG2NUM(1000000));
            tcl_time.sec  = NUM2LONG(RARRAY_AREF(divmod, 0));
            tcl_time.usec = NUM2LONG(RARRAY_AREF(divmod, 1));
            break;

        case T_FLOAT:
            /* time is second value */
            divmod = rb_funcall(time, rb_intern("divmod"), 1, INT2FIX(1));
            tcl_time.sec  = NUM2LONG(RARRAY_AREF(divmod, 0));
            tcl_time.usec = (long)(NUM2DBL(RARRAY_AREF(divmod, 1)) * 1000000);
            break;

        default:
            rb_raise(rb_eArgError, "invalid value for time: '%+"PRIsVALUE"'", time);
        }

        Tcl_SetMaxBlockTime(&tcl_time);

        return Qnil;
    }

set_no_event_wait(p1) click to toggle source

    static VALUE
    set_no_event_wait(self, wait)
        VALUE self;
        VALUE wait;
    {
        int t_wait = NUM2INT(wait);

        if (t_wait <= 0) {
            rb_raise(rb_eArgError,
                     "no_event_wait parameter must be positive number");
        }

        no_event_wait = t_wait;

        return wait;
    }