Skip to content

Commit 95606c5

Browse files
committed
hidecursor/showcursor
1 parent 7acbff6 commit 95606c5

File tree

4 files changed

+109
-18
lines changed

4 files changed

+109
-18
lines changed

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ See also original documentation at https://github.com/LionyxML/nocurses.
7575
* [nocurses.settitle()](#nocurses_settitle)
7676
* [nocurses.setunderline()](#nocurses_setunderline)
7777
* [nocurses.wait()](#nocurses_wait)
78+
* [nocurses.hidecursor()](#nocurses_hidecursor)
79+
* [nocurses.showcursor()](#nocurses_showcursor)
7880
* [Color Names](#color-names)
7981
* [Shape Names](#shape-names)
8082

@@ -269,6 +271,23 @@ See also original documentation at https://github.com/LionyxML/nocurses.
269271
Waits for the user to hit [ENTER].
270272

271273

274+
<!-- ---------------------------------------------------------------------------------------- -->
275+
276+
* <a id="nocurses_hidecursor">**`nocurses.hidecursor()
277+
`**</a>
278+
279+
Hides the cursor. If the program exits, a hidden cursor is automatically made visible again.
280+
281+
See also: [`example05.lua`](./examples/example05.lua)
282+
283+
<!-- ---------------------------------------------------------------------------------------- -->
284+
285+
* <a id="nocurses_showcursor">**`nocurses.showcursor()
286+
`**</a>
287+
288+
Makes the cursor visible. To be called after [nocurses.hidecursor()](#nocurses_hidecursor).
289+
290+
272291
<!-- ---------------------------------------------------------------------------------------- -->
273292
## Color Names
274293
<!-- ---------------------------------------------------------------------------------------- -->

examples/example05.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ local function printCentered(y, ...)
1717
printf(message)
1818
end
1919

20+
nocurses.hidecursor()
21+
2022
while true do
2123
if redisplay then
2224
nocurses.clrscr();
@@ -58,6 +60,7 @@ while true do
5860
end
5961
end
6062

63+
nocurses.showcursor()
6164
nocurses.gotoxy(1, screenHeight - 2)
6265
nocurses.clrline()
6366
printf("Finished.\n")

src/main.c

Lines changed: 80 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ static int nc_awake_fds[2];
4141
static unsigned char nc_readbuffer[NC_READBUFLEN];
4242
static size_t nc_readlen = 0;
4343
static size_t nc_readpos = 0;
44-
static size_t nc_peekpos = 0;
44+
static bool nc_hidecur = 0;
4545

4646
#endif /* __unix__ */
4747

@@ -51,15 +51,20 @@ static size_t nc_peekpos = 0;
5151

5252
static int handleClosingLuaState(lua_State* L)
5353
{
54-
bool unrestricted = false;
54+
bool restricted = true;
5555
if (lua_rawgetp(L, LUA_REGISTRYINDEX, NOCURSES_MODULE_NAME) == LUA_TUSERDATA) {
5656
if (lua_touserdata(L, -1) == udata) {
57-
unrestricted = true;
57+
restricted = false;
5858
}
5959
}
6060
lua_pop(L, 1);
61-
if (unrestricted) {
61+
if (!restricted) {
6262
if (atomic_set_if_equal(&initStage, 1, 0)) {
63+
if (nc_hidecur) {
64+
nc_hidecur = false;
65+
showcursor();
66+
fflush(stdout);
67+
}
6368
}
6469
}
6570
return 0;
@@ -123,6 +128,12 @@ static bool hasInputAt(int i)
123128
return (nc_readpos + i < nc_readlen);
124129
}
125130

131+
static void clearInput()
132+
{
133+
nc_readpos = 0;
134+
nc_readlen = 0;
135+
}
136+
126137
static bool hasInput()
127138
{
128139
return (nc_readpos < nc_readlen);
@@ -177,23 +188,21 @@ static bool waitForInput(const double timeout)
177188

178189
static int Nocurses_wait(lua_State* L)
179190
{
191+
clearInput();
180192
#if defined(__unix__)
181-
bool wasEnter = false;
182193
while (true) {
183-
if (hasInput() || waitForInput(-1)) {
194+
if (waitForInput(-1)) {
184195
if (fgetc(stdin) == '\n') {
185196
break;
186197
}
187198
} else {
188199
break;
189200
}
190201
}
191-
lua_pushboolean(L, wasEnter);
192202
#else
193203
while (fgetc(stdin) != '\n');
194-
lua_pushboolean(L, true);
195204
#endif
196-
return 1;
205+
return 0;
197206
}
198207

199208
/* ============================================================================================ */
@@ -351,8 +360,7 @@ static int nc_getch()
351360
return nc_readbuffer[0];
352361
}
353362
else {
354-
nc_readpos = 0;
355-
nc_readlen = 0;
363+
clearInput();
356364
return -1;
357365
}
358366
}
@@ -417,8 +425,31 @@ static int nc_skipch(int skip)
417425
}
418426
#endif
419427

428+
/* ============================================================================================ */
429+
430+
static int assureUnrestricted(lua_State* L)
431+
{
432+
bool restricted = true;
433+
if (lua_rawgetp(L, LUA_REGISTRYINDEX, NOCURSES_MODULE_NAME) == LUA_TUSERDATA) { // -> nocurses
434+
if (lua_touserdata(L, -1) == udata) { // -> nocurses
435+
restricted = false;
436+
}
437+
}
438+
lua_pop(L, 1); // ->
439+
if (restricted) {
440+
return luaL_error(L, "function must be called from main thread");
441+
}
442+
else {
443+
return 0;
444+
}
445+
}
446+
447+
/* ============================================================================================ */
448+
420449
static int Nocurses_getch(lua_State* L)
421450
{
451+
assureUnrestricted(L);
452+
422453
double timeout = -1;
423454
if (!lua_isnoneornil(L, 1)) {
424455
timeout = luaL_checknumber(L, 1);
@@ -448,6 +479,8 @@ static int Nocurses_getch(lua_State* L)
448479

449480
static int Nocurses_peekch(lua_State* L)
450481
{
482+
assureUnrestricted(L);
483+
451484
int offs = 0;
452485
if (!lua_isnoneornil(L, 1)) {
453486
offs = luaL_checkinteger(L, 1) - 1;
@@ -478,6 +511,8 @@ static int Nocurses_peekch(lua_State* L)
478511

479512
static int Nocurses_skipch(lua_State* L)
480513
{
514+
assureUnrestricted(L);
515+
481516
int skip = 1;
482517
if (!lua_isnoneornil(L, 1)) {
483518
skip = luaL_checkinteger(L, 1) ;
@@ -520,6 +555,31 @@ static int Nocurses_resetcolors(lua_State* L)
520555

521556
/* ============================================================================================ */
522557

558+
static int Nocurses_showcursor(lua_State* L)
559+
{
560+
assureUnrestricted(L);
561+
562+
nc_hidecur = false;
563+
showcursor();
564+
fflush(stdout);
565+
566+
return 0;
567+
}
568+
569+
/* ============================================================================================ */
570+
571+
static int Nocurses_hidecursor(lua_State* L)
572+
{
573+
assureUnrestricted(L);
574+
575+
nc_hidecur = true;
576+
hidecursor();
577+
fflush(stdout);
578+
return 0;
579+
}
580+
581+
/* ============================================================================================ */
582+
523583
#if defined(__unix__)
524584

525585
static int Nocurses_awake(lua_State* L)
@@ -602,6 +662,8 @@ static const luaL_Reg ModuleFunctions[] =
602662
{ "skipch", Nocurses_skipch },
603663
{ "clrline", Nocurses_clrline },
604664
{ "resetcolors", Nocurses_resetcolors },
665+
{ "showcursor", Nocurses_showcursor },
666+
{ "hidecursor", Nocurses_hidecursor },
605667
#if defined(__unix__)
606668
{ "awake", Nocurses_awake },
607669
#endif
@@ -655,9 +717,9 @@ DLL_PUBLIC int luaopen_nocurses(lua_State* L)
655717

656718
/* ---------------------------------------- */
657719

658-
bool unrestricted = false;
720+
bool restricted = true;
659721
if (atomic_set_if_equal(&initStage, 0, 1)) {
660-
unrestricted = true;
722+
restricted = false;
661723
#if defined(__unix__)
662724
initAwake();
663725
#endif
@@ -672,7 +734,7 @@ DLL_PUBLIC int luaopen_nocurses(lua_State* L)
672734
else {
673735
if (lua_rawgetp(L, LUA_REGISTRYINDEX, NOCURSES_MODULE_NAME) == LUA_TUSERDATA) {
674736
if (lua_touserdata(L, -1) == udata) {
675-
unrestricted = true;
737+
restricted = false;
676738
}
677739
}
678740
lua_pop(L, 1);
@@ -685,10 +747,10 @@ DLL_PUBLIC int luaopen_nocurses(lua_State* L)
685747
int module = ++n; lua_newtable(L);
686748

687749
lua_pushvalue(L, module); /* --> module */
688-
if (unrestricted) {
689-
luaL_setfuncs(L, ModuleFunctions, 0);
690-
} else {
750+
if (restricted) {
691751
luaL_setfuncs(L, RestrictedModuleFunctions, 0);
752+
} else {
753+
luaL_setfuncs(L, ModuleFunctions, 0);
692754
}
693755
lua_newtable(L); /* --> module, key */
694756
for (const InputSequence* seq = inputSequences; seq->name; ++seq) {
@@ -709,7 +771,7 @@ DLL_PUBLIC int luaopen_nocurses(lua_State* L)
709771
#endif
710772
lua_pushstring(L, NOCURSES_MODULE_NAME); /* -> meta, "nocurses" */
711773
lua_setfield(L, -2, "__metatable"); /* -> meta */
712-
if (unrestricted) {
774+
if (!restricted) {
713775
int rc = luaL_loadstring(L,
714776
"local t, k = ...\n"
715777
"if type(k) == 'string' then\n"

src/nocurses.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,3 +243,10 @@ static void resetcolors(){
243243
font_invert = 0;
244244
}
245245

246+
static void showcursor(){
247+
printf(ESC"[?25h");
248+
}
249+
250+
static void hidecursor(){
251+
printf(ESC"[?25l");
252+
}

0 commit comments

Comments
 (0)