@@ -577,6 +577,115 @@ console_echo_p(VALUE io)
577577 return echo_p (& t ) ? Qtrue : Qfalse ;
578578}
579579
580+ static const rb_data_type_t conmode_type = {
581+ "console-mode" ,
582+ {0 , RUBY_TYPED_DEFAULT_FREE ,},
583+ 0 , 0 ,
584+ RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED ,
585+ };
586+ static VALUE cConmode ;
587+
588+ static VALUE
589+ conmode_alloc (VALUE klass )
590+ {
591+ return rb_data_typed_object_zalloc (klass , sizeof (conmode ), & conmode_type );
592+ }
593+
594+ static VALUE
595+ conmode_new (VALUE klass , const conmode * t )
596+ {
597+ VALUE obj = conmode_alloc (klass );
598+ * (conmode * )DATA_PTR (obj ) = * t ;
599+ return obj ;
600+ }
601+
602+ static VALUE
603+ conmode_init_copy (VALUE obj , VALUE obj2 )
604+ {
605+ conmode * t = rb_check_typeddata (obj , & conmode_type );
606+ conmode * t2 = rb_check_typeddata (obj2 , & conmode_type );
607+ * t = * t2 ;
608+ return obj ;
609+ }
610+
611+ static VALUE
612+ conmode_set_echo (VALUE obj , VALUE f )
613+ {
614+ conmode * t = rb_check_typeddata (obj , & conmode_type );
615+ if (RTEST (f ))
616+ set_echo (t , NULL );
617+ else
618+ set_noecho (t , NULL );
619+ return obj ;
620+ }
621+
622+ static VALUE
623+ conmode_set_raw (int argc , VALUE * argv , VALUE obj )
624+ {
625+ conmode * t = rb_check_typeddata (obj , & conmode_type );
626+ rawmode_arg_t opts , * optp = rawmode_opt (& argc , argv , 0 , 0 , & opts );
627+
628+ set_rawmode (t , optp );
629+ return obj ;
630+ }
631+
632+ static VALUE
633+ conmode_raw_new (int argc , VALUE * argv , VALUE obj )
634+ {
635+ conmode * r = rb_check_typeddata (obj , & conmode_type );
636+ conmode t = * r ;
637+ rawmode_arg_t opts , * optp = rawmode_opt (& argc , argv , 0 , 0 , & opts );
638+
639+ set_rawmode (& t , optp );
640+ return conmode_new (rb_obj_class (obj ), & t );
641+ }
642+
643+ /*
644+ * call-seq:
645+ * io.console_mode -> mode
646+ *
647+ * Returns a data represents the current console mode.
648+ *
649+ * You must require 'io/console' to use this method.
650+ */
651+ static VALUE
652+ console_conmode_get (VALUE io )
653+ {
654+ conmode t ;
655+ rb_io_t * fptr ;
656+ int fd ;
657+
658+ GetOpenFile (io , fptr );
659+ fd = GetReadFD (fptr );
660+ if (!getattr (fd , & t )) rb_sys_fail (0 );
661+
662+ return conmode_new (cConmode , & t );
663+ }
664+
665+ /*
666+ * call-seq:
667+ * io.console_mode = mode
668+ *
669+ * Sets the console mode to +mode+.
670+ *
671+ * You must require 'io/console' to use this method.
672+ */
673+ static VALUE
674+ console_conmode_set (VALUE io , VALUE mode )
675+ {
676+ conmode * t , r ;
677+ rb_io_t * fptr ;
678+ int fd ;
679+
680+ TypedData_Get_Struct (mode , conmode , & conmode_type , t );
681+ r = * t ;
682+ GetOpenFile (io , fptr );
683+ fd = GetReadFD (fptr );
684+ if (!setattr (fd , & r )) rb_sys_fail (0 );
685+
686+ return mode ;
687+ }
688+
580689#if defined TIOCGWINSZ
581690typedef struct winsize rb_console_size_t ;
582691#define getwinsize (fd , buf ) (ioctl((fd), TIOCGWINSZ, (buf)) == 0)
@@ -1447,6 +1556,8 @@ InitVM_console(void)
14471556 rb_define_method (rb_cIO , "getch" , console_getch , -1 );
14481557 rb_define_method (rb_cIO , "echo=" , console_set_echo , 1 );
14491558 rb_define_method (rb_cIO , "echo?" , console_echo_p , 0 );
1559+ rb_define_method (rb_cIO , "console_mode" , console_conmode_get , 0 );
1560+ rb_define_method (rb_cIO , "console_mode=" , console_conmode_set , 1 );
14501561 rb_define_method (rb_cIO , "noecho" , console_noecho , 0 );
14511562 rb_define_method (rb_cIO , "winsize" , console_winsize , 0 );
14521563 rb_define_method (rb_cIO , "winsize=" , console_set_winsize , 1 );
@@ -1480,4 +1591,15 @@ InitVM_console(void)
14801591 rb_define_method (mReadable , "getpass" , io_getpass , -1 );
14811592#endif
14821593 }
1594+ {
1595+ /* :stopdoc: */
1596+ cConmode = rb_define_class_under (rb_cIO , "ConsoleMode" , rb_cObject );
1597+ rb_define_alloc_func (cConmode , conmode_alloc );
1598+ rb_undef_method (cConmode , "initialize" );
1599+ rb_define_method (cConmode , "initialize_copy" , conmode_init_copy , 1 );
1600+ rb_define_method (cConmode , "echo=" , conmode_set_echo , 1 );
1601+ rb_define_method (cConmode , "raw!" , conmode_set_raw , -1 );
1602+ rb_define_method (cConmode , "raw" , conmode_raw_new , -1 );
1603+ /* :startdoc: */
1604+ }
14831605}
0 commit comments