Selaa lähdekoodia

neercs: import files from the (unfinished) old neercs code.

master
Sam Hocevar 12 vuotta sitten
vanhempi
commit
b4772eed53
37 muutettua tiedostoa jossa 8811 lisäystä ja 4 poistoa
  1. +32
    -1
      neercs/Makefile.am
  2. +7
    -2
      neercs/neercs.cpp
  3. +1
    -1
      neercs/neercs.h
  4. +63
    -0
      neercs/old/actions.c
  5. +1149
    -0
      neercs/old/ansi.c
  6. +424
    -0
      neercs/old/attach.c
  7. +298
    -0
      neercs/old/client.c
  8. +568
    -0
      neercs/old/configuration.c
  9. +278
    -0
      neercs/old/effects.c
  10. +393
    -0
      neercs/old/grab.c
  11. +76
    -0
      neercs/old/help.c
  12. +192
    -0
      neercs/old/input.c
  13. +221
    -0
      neercs/old/lock.c
  14. +324
    -0
      neercs/old/main.c
  15. +94
    -0
      neercs/old/mini-client.c
  16. +52
    -0
      neercs/old/mini-neercs.c
  17. +22
    -0
      neercs/old/mini-neercs.h
  18. +80
    -0
      neercs/old/mini-server.c
  19. +297
    -0
      neercs/old/mini-socket.c
  20. +24
    -0
      neercs/old/mini-socket.h
  21. +125
    -0
      neercs/old/mygetopt.c
  22. +30
    -0
      neercs/old/mygetopt.h
  23. +785
    -0
      neercs/old/mytrace.c
  24. +33
    -0
      neercs/old/mytrace.h
  25. +430
    -0
      neercs/old/neercs.h
  26. +197
    -0
      neercs/old/python/interpreter.c
  27. +193
    -0
      neercs/old/python/py_module.c
  28. +25
    -0
      neercs/old/python/py_module.h
  29. +112
    -0
      neercs/old/recurrent.c
  30. +216
    -0
      neercs/old/screen_list.c
  31. +334
    -0
      neercs/old/screens.c
  32. +187
    -0
      neercs/old/screensaver.c
  33. +680
    -0
      neercs/old/server.c
  34. +133
    -0
      neercs/old/term.c
  35. +176
    -0
      neercs/old/widgets.c
  36. +47
    -0
      neercs/old/widgets.h
  37. +513
    -0
      neercs/old/wm.c

+ 32
- 1
neercs/Makefile.am Näytä tiedosto

@@ -6,13 +6,15 @@ endif
neercs_SOURCES = \
neercs.cpp neercs.h \
\
$(old_sources) \
\
video/render.cpp video/render.h \
video/text-render.cpp video/text-render.h \
video/simple.lolfx \
video/blurh.lolfx video/blurv.lolfx \
video/remanency.lolfx video/glow.lolfx video/postfx.lolfx video/radial.lolfx \
video/text.lolfx
neercs_CPPFLAGS = @LOL_CFLAGS@ @PIPI_CFLAGS@ @CACA_CFLAGS@
neercs_CPPFLAGS = @LOL_CFLAGS@ @PIPI_CFLAGS@ @CACA_CFLAGS@ -Iold
neercs_LDADD =
neercs_LDFLAGS = $(top_builddir)/src/liblol.a \
@LOL_LIBS@ @PIPI_LIBS@ @CACA_LIBS@ @UTIL_LIBS@ @PAM_LIBS@
@@ -31,3 +33,32 @@ SUFFIXES = .lolfx
.lolfx.o:
$(LOLFX_BUILD)

old_sources = \
old/actions.c \
old/ansi.c \
old/attach.c \
old/client.c \
old/configuration.c \
old/effects.c \
old/grab.c \
old/help.c \
old/input.c \
old/lock.c \
old/main.c \
old/mygetopt.c \
old/mygetopt.h \
old/mytrace.c \
old/mytrace.h \
old/neercs.h \
old/python/interpreter.c \
old/python/py_module.c \
old/python/py_module.h \
old/recurrent.c \
old/screen_list.c \
old/screensaver.c \
old/screens.c \
old/server.c \
old/term.c \
old/widgets.c \
old/widgets.h \
old/wm.c

+ 7
- 2
neercs/neercs.cpp Näytä tiedosto

@@ -43,7 +43,12 @@ using namespace lol;
#include "neercs.h"
#include "video/render.h"

Neercs::Neercs()
extern "C"
{
#include "old/neercs.h"
}

Neercs::Neercs(int argc, char **argv)
: m_ready(false),
m_caca(caca_create_canvas(10, 10)),
m_render(new Render(m_caca)),
@@ -140,7 +145,7 @@ int main(int argc, char **argv)
_chdir("../..");
#endif

new Neercs();
new Neercs(argc, argv);
new DebugFps(2, 2);
app.ShowPointer(false);



+ 1
- 1
neercs/neercs.h Näytä tiedosto

@@ -14,7 +14,7 @@
class Neercs : public WorldEntity
{
public:
Neercs();
Neercs(int argc, char **argv);
virtual ~Neercs();

char const *GetName() { return "<neercs>"; }


+ 63
- 0
neercs/old/actions.c Näytä tiedosto

@@ -0,0 +1,63 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* 2008-2010 Pascal Terjan <pterjan@linuxfr.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"
#include <caca.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include "neercs.h"

void dump_to_file(struct screen_list *screen_list)
{
char filename[14] = "hardcopy.0";
int n = 0;
struct stat bufstat;
void * export;
size_t len, wrote;
FILE * out;

/* FIXME maybe use glob and get next one directly */
while (n<9999 && !stat(filename, &bufstat))
{
n++;
sprintf(&filename[9], "%d", n);
}
if (n>=9999)
{
debug("Too many hardcopy files in current directory\n");
return;
}

export = caca_export_canvas_to_memory(screen_list->cv, "ansi", &len);
if (!export)
{
debug("Failed to export to ansi\n");
return;
}

out = fopen(filename, "w");
if (!out)
{
debug("Failed to open output file %s: %s\n", filename, strerror(errno));
return;
}
wrote = fwrite(export, len, 1, out);
if (!wrote)
{
debug("Failed to write to output file: %s\n", strerror(errno));
return;
}
free(export);
}

+ 1149
- 0
neercs/old/ansi.c
File diff suppressed because it is too large
Näytä tiedosto


+ 424
- 0
neercs/old/attach.c Näytä tiedosto

@@ -0,0 +1,424 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* 2008-2010 Pascal Terjan <pterjan@linuxfr.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include <errno.h>
#include <fcntl.h>
#include <glob.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <sys/socket.h>
#include <sys/un.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <caca.h>

#include "config.h"
#include "neercs.h"

char *build_socket_path(char *socket_dir, char *session_name,
enum socket_type socktype)
{
char *path, *dir;
path = (char *)malloc(PATH_MAX + 1);
dir = socket_dir;
if (!dir)
dir = getenv("NEERCSDIR");
if (!dir)
dir = getenv("TMPDIR");
if (!dir)
dir = "/tmp";
if (path)
snprintf(path, PATH_MAX + 1, "%s/neercs.%s%s.sock", dir, session_name,
socktype ? "" : ".srv");
return path;
}

static char *socket_to_session(char const *sockpath)
{
char *p, *s;
p = strrchr(sockpath, '/');
if (!p)
{
debug("Invalid socket path %s", sockpath);
return NULL;
}
p += 8; /* skip neercs. */
s = strdup(p);
p = strrchr(s, '.');
*p = '\0'; /* drop .sock */
p = strrchr(s, '.');
*p = '\0'; /* drop .srv */
p = strdup(s);
free(s);
return p;
}

int create_socket(struct screen_list *screen_list, enum socket_type socktype)
{
int sock;
struct sockaddr_un myaddr;

sock = socket(AF_UNIX, SOCK_DGRAM, 0);

if (sock < 0)
{
perror("create_socket:socket");
return errno;
}

memset(&myaddr, 0, sizeof(struct sockaddr_un));

myaddr.sun_family = AF_UNIX;
strncpy(myaddr.sun_path, screen_list->comm.socket_path[socktype],
sizeof(myaddr.sun_path) - 1);

unlink(screen_list->comm.socket_path[socktype]);

if (bind(sock, (struct sockaddr *)&myaddr, sizeof(struct sockaddr_un)) < 0)
{
free(screen_list->comm.socket_path[socktype]);
screen_list->comm.socket_path[socktype] = NULL;
close(sock);
perror("create_socket:bind");
return errno;
}
fcntl(sock, F_SETFL, O_NONBLOCK);

debug("Listening on %s (%d)", screen_list->comm.socket_path[socktype], sock);

screen_list->comm.socket[socktype] = sock;

return 0;
}

char **list_sockets(char *socket_dir, char *session_name)
{
char *pattern, *dir;
glob_t globbuf;

globbuf.gl_pathv = NULL;

pattern = (char *)malloc(PATH_MAX + 1);

dir = socket_dir;
if (!dir)
dir = getenv("NEERCSDIR");
if (!dir)
dir = getenv("TMPDIR");
if (!dir)
dir = "/tmp";

if (!pattern)
return globbuf.gl_pathv;

if (session_name && strlen(session_name) + strlen(dir) + 13 < PATH_MAX)
sprintf(pattern, "%s/neercs.%s.srv.sock", dir, session_name);
else
snprintf(pattern, PATH_MAX, "%s/neercs.*.srv.sock", dir);
pattern[PATH_MAX] = '\0';

debug("Looking for sockets in the form %s", pattern);

glob(pattern, 0, NULL, &globbuf);

free(pattern);

return globbuf.gl_pathv;
}

char *connect_socket(struct screen_list *screen_list,
enum socket_type socktype)
{
int sock;
struct sockaddr_un addr;

debug("Connecting to %s", screen_list->comm.socket_path[socktype]);

/* Open the socket */
if ((sock = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
{
debug("Failed to create socket\n");
perror("connect_server:socket");
return NULL;
}

memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, screen_list->comm.socket_path[socktype]);
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
debug("Failed to connect to %s: %s",
screen_list->comm.socket_path[socktype], strerror(errno));
close(sock);
return NULL;
}
fcntl(sock, F_SETFL, O_NONBLOCK);

screen_list->comm.socket[socktype] = sock;

if (socktype == SOCK_SERVER)
{
return socket_to_session(screen_list->comm.socket_path[socktype]);
}
else
return NULL;
}

int request_attach(struct screen_list *screen_list)
{
char buf[41];
int bytes;

bytes = snprintf(buf, sizeof(buf) - 1, "ATTACH %10d %10d %10d",
caca_get_canvas_width(screen_list->cv),
caca_get_canvas_height(screen_list->cv),
screen_list->delay);
buf[bytes] = '\0';
debug("Requesting attach: %s", buf);
return write(screen_list->comm.socket[SOCK_SERVER], buf, strlen(buf)) <= 0;
}

static char *select_socket(struct screen_list *screen_list)
{
char **sockets = NULL, **usable_sockets = NULL;
int i, sock, nb_usable_sockets = 0;
char *ret = NULL;

sockets = list_sockets(screen_list->comm.socket_dir, screen_list->comm.session_name);
if (sockets)
{
for (i = 0; sockets[i]; i++);

/* Return the socket or NULL if there is not more than one match */
if (i <= 1)
{
if (sockets[0])
ret = strdup(sockets[0]);
goto end;
}

/* Else ask the user to chose one */
usable_sockets = malloc(i * sizeof(char *));
for (i = 0; sockets[i]; i++)
{
struct sockaddr_un addr;
if ((sock = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
{
perror("select_socket:socket");
goto end;
}
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, sockets[i]);
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
switch (errno)
{
case EACCES:
debug("Connection refused on %s", sockets[i]);
break;
case ECONNREFUSED:
fprintf(stderr, "%s is dead\n", sockets[i]);
break;
default:
fprintf(stderr, "Unknown error on %s:%s\n", sockets[i],
strerror(errno));
}
}
else
{
usable_sockets[nb_usable_sockets] = strdup(sockets[i]);
debug("%s is usable", usable_sockets[nb_usable_sockets]);
nb_usable_sockets++;
close(sock);
}
}
if (!nb_usable_sockets)
goto end;
if (nb_usable_sockets == 1)
{
ret = strdup(usable_sockets[0]);
goto end;
}
else
{
caca_event_t ev;
enum caca_event_type t;
int current_line = 1;
int refresh = 1;
screen_list->cv = caca_create_canvas(0, 0);
screen_list->dp = caca_create_display(screen_list->cv);
if (!screen_list->dp)
goto end;
caca_set_cursor(screen_list->dp, 0);
caca_set_display_title(screen_list->dp, PACKAGE_STRING);
while (1)
{
if (refresh)
{
caca_set_color_ansi(screen_list->cv, CACA_BLUE, CACA_BLUE);
caca_fill_box(screen_list->cv,
0, 0,
caca_get_canvas_width(screen_list->cv),
caca_get_canvas_height(screen_list->cv),
'#');
caca_set_color_ansi(screen_list->cv, CACA_DEFAULT,
CACA_BLUE);
caca_draw_cp437_box(screen_list->cv, 0, 0,
caca_get_canvas_width(screen_list->cv),
caca_get_canvas_height(screen_list->
cv));
caca_printf(screen_list->cv, 2, 2,
"Please select a session to reconnect:");
for (i = 0; i < nb_usable_sockets; i++)
{
if (i == current_line - 1)
{
caca_set_attr(screen_list->cv, CACA_BOLD);
caca_set_color_ansi(screen_list->cv, CACA_GREEN,
CACA_BLUE);
caca_put_char(screen_list->cv, 1, i + 3, '>');
}
else
{
caca_set_attr(screen_list->cv, 0);
caca_set_color_ansi(screen_list->cv,
CACA_LIGHTGRAY, CACA_BLUE);
caca_put_char(screen_list->cv, 1, i + 3, ' ');
}
caca_printf(screen_list->cv,
3, i + 3,
"%s",
socket_to_session(usable_sockets[i]));
}
caca_refresh_display(screen_list->dp);
refresh = 0;
}

if (!caca_get_event(screen_list->dp,
CACA_EVENT_KEY_PRESS
| CACA_EVENT_RESIZE
| CACA_EVENT_QUIT, &ev, 10000))
continue;

t = caca_get_event_type(&ev);

if (t & CACA_EVENT_KEY_PRESS)
{
unsigned int c = caca_get_event_key_ch(&ev);
switch (c)
{
case CACA_KEY_UP:
if (current_line > 1)
current_line--;
break;
case CACA_KEY_DOWN:
if (current_line < nb_usable_sockets)
current_line++;
break;
case CACA_KEY_RETURN:
ret = strdup(usable_sockets[current_line - 1]);
goto end;
break;
case CACA_KEY_ESCAPE:
goto end;
break;
default:
break;
}
refresh = 1;
}
else if (t & CACA_EVENT_RESIZE)
{
refresh = 1;
}
else if (t & CACA_EVENT_QUIT)
goto end;
}
}
}

end:
if (sockets)
{
for (i = 0; sockets[i]; i++)
free(sockets[i]);
free(sockets);
}
if (usable_sockets)
{
for (i = 0; i < nb_usable_sockets; i++)
free(usable_sockets[i]);
free(usable_sockets);
}
if (screen_list->dp)
{
caca_free_display(screen_list->dp);
screen_list->dp = NULL;
}
if (screen_list->cv)
{
caca_free_canvas(screen_list->cv);
screen_list->cv = NULL;
}
return ret;
}

void attach(struct screen_list *screen_list)
{
screen_list->comm.socket_path[SOCK_SERVER] = select_socket(screen_list);

if (screen_list->comm.socket_path[SOCK_SERVER])
{
char *session;
session = connect_socket(screen_list, SOCK_SERVER);
if (session)
{
debug("Connected to session %s", session);
/* Create main canvas and associated caca window */
screen_list->cv = caca_create_canvas(0, 0);
screen_list->dp = caca_create_display(screen_list->cv);
if (!screen_list->dp)
return;
caca_set_display_time(screen_list->dp, screen_list->delay * 1000);
caca_set_cursor(screen_list->dp, 1);

screen_list->comm.socket_path[SOCK_CLIENT] =
build_socket_path(screen_list->comm.socket_dir, session,
SOCK_CLIENT);
create_socket(screen_list, SOCK_CLIENT);
request_attach(screen_list);
if (screen_list->comm.session_name)
free(screen_list->comm.session_name);
screen_list->comm.session_name = session;
}
else
{
fprintf(stderr, "Failed to attach!\n");
free(screen_list->comm.socket_path[SOCK_SERVER]);
screen_list->comm.socket_path[SOCK_SERVER] = NULL;
screen_list->sys.attach = 0;
}
}
else
{
fprintf(stderr, "No socket found!\n");
screen_list->sys.attach = 0;
}
}


+ 298
- 0
neercs/old/client.c Näytä tiedosto

@@ -0,0 +1,298 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* 2008-2011 Pascal Terjan <pterjan@linuxfr.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <time.h>
#include <pwd.h>

#include <errno.h>
#include <caca.h>

#include "neercs.h"

#define NEERCS_RECV_BUFSIZE 128*1024


int start_client(struct screen_list *screen_list)
{
char *sess = NULL;
create_socket(screen_list, SOCK_CLIENT);
while ((sess = connect_socket(screen_list, SOCK_SERVER)) == NULL)
usleep(100);
free(sess);

/* Create main canvas and associated caca window */
screen_list->cv = caca_create_canvas(0, 0);
screen_list->dp = caca_create_display(screen_list->cv);
screen_list->mouse_button = 0;

if (!screen_list->dp)
return -3;

caca_set_display_time(screen_list->dp, screen_list->delay * 1000);
caca_set_cursor(screen_list->dp, 1);

request_attach(screen_list);

return 0;
}

int send_event(caca_event_t ev, struct screen_list *screen_list)
{
enum caca_event_type t;
char buf[64];
int bytes = 0;

t = caca_get_event_type(&ev);

if (t & CACA_EVENT_KEY_PRESS)
{
bytes = snprintf(buf, sizeof(buf) - 1, "KEY %d",
caca_get_event_key_ch(&ev));
debug("Sending key press to server: %s", buf);
}
else if (t & CACA_EVENT_RESIZE)
{
bytes = snprintf(buf, sizeof(buf) - 1, "RESIZE %10d %10d",
caca_get_event_resize_width(&ev),
caca_get_event_resize_height(&ev));
}
else if (t & CACA_EVENT_MOUSE_PRESS)
{
screen_list->mouse_button = caca_get_event_mouse_button(&ev);
bytes = snprintf(buf, sizeof(buf) - 1, "MOUSEP %10d %10d %10d",
caca_get_mouse_x(screen_list->dp),
caca_get_mouse_y(screen_list->dp),
screen_list->mouse_button);
}
else if (t & CACA_EVENT_MOUSE_RELEASE)
{
bytes = snprintf(buf, sizeof(buf) - 1, "MOUSER %10d %10d %10d",
caca_get_mouse_x(screen_list->dp),
caca_get_mouse_y(screen_list->dp),
screen_list->mouse_button);
screen_list->mouse_button = 0;
}
else if (t & CACA_EVENT_MOUSE_MOTION)
{
int x = caca_get_mouse_x(screen_list->dp);
int y = caca_get_mouse_y(screen_list->dp);
int b = screen_list->mouse_button;
debug("Mouse motion, button %d", b);
if (x != screen_list->old_x || y != screen_list->old_y)
{
screen_list->old_x = caca_get_mouse_x(screen_list->dp);
screen_list->old_y = caca_get_mouse_y(screen_list->dp);

bytes = snprintf(buf, sizeof(buf) - 1, "MOUSEM %10d %10d %10d",
caca_get_mouse_x(screen_list->dp),
caca_get_mouse_y(screen_list->dp),
b>=0?b:0);
}
}
else if (t & CACA_EVENT_QUIT)
{
bytes = snprintf(buf, sizeof(buf) - 1, "QUIT");
}
if (bytes)
{
ssize_t r;
buf[bytes] = '\0';
debug("Sending '%s', %d bytes", buf, bytes);
r = write(screen_list->comm.socket[SOCK_SERVER], buf, bytes+1);
while (r < 0 && errno == EAGAIN)
{
usleep(20);
r = write(screen_list->comm.socket[SOCK_SERVER], buf, bytes+1);
}
return r < 0;
}
return 0;
}

int send_delay(struct screen_list *screen_list)
{
debug("Sending DELAY\n");
char buf[18];
int bytes;
bytes = snprintf(buf, sizeof(buf) - 1, "DELAY %10d", screen_list->delay);
buf[bytes] = '\0';
return write(screen_list->comm.socket[SOCK_SERVER], buf, strlen(buf)) <= 0;
}

/** \brief Main client loop.
*
* This is the main client loop.
*
* Repeat forever:
* - if data is available on the client socket, read it and interpret it:
* - "DETACH": exit the loop
* - "UPDATE": update screen with the given canvas data
* - "REFRESH": refresh the whole display
* - "CURSOR": set cursor position
* - "TITLE": set window or display title
* - wait for an input event with a 10ms timeout
*/
void mainloop(struct screen_list *screen_list)
{
char *buf = NULL;
screen_list->last_key_time = get_us();

while (mainloop_tick(&buf, screen_list))
;

free(buf);
}

int mainloop_tick(char **pbuf, struct screen_list *screen_list)
{
caca_event_t ev;
int ret = 0;
ssize_t n;
if (!screen_list)
return 0;
if (!*pbuf)
*pbuf = malloc(NEERCS_RECV_BUFSIZE);
if (!*pbuf)
{
debug("Failed to allocate memory");
return 0;
}
if (screen_list->comm.socket[SOCK_CLIENT]
&& (n =
read(screen_list->comm.socket[SOCK_CLIENT], *pbuf,
NEERCS_RECV_BUFSIZE - 1)) > 0)
{
*pbuf[n] = 0;
debug("Received from server: '%s' (%d bytes)", *pbuf, n);
if (!strncmp("DETACH", *pbuf, 6))
{
/* ret = 1; Not used */
return 1;
}
else if (!strncmp("UPDATE ", *pbuf, 7))
{
int x, y;
ssize_t l2 = 0, lb = 0;
char *buf2;
size_t l = 0;
/* FIXME check the length before calling atoi */
x = atoi(*pbuf + 8);
y = atoi(*pbuf + 19);

/* 0 means we have valid data but incomplete, so read the rest
*/
while (l == 0)
{
buf2 = realloc(*pbuf, l2 + NEERCS_RECV_BUFSIZE);
if (!buf2)
{
debug("Failed to allocate memory");
return 0;
}
*pbuf = buf2;
fcntl(screen_list->comm.socket[SOCK_CLIENT], F_SETFL, 0);
lb = read(screen_list->comm.socket[SOCK_CLIENT], *pbuf + l2,
NEERCS_RECV_BUFSIZE - 1);
if (lb < 0)
{
debug
("Failed to read the end of the refresh message (%s)",
strerror(errno));
l = -1;
}
else
{
l2 += lb;
l = caca_import_area_from_memory(screen_list->cv, x, y,
*pbuf, l2, "caca");
}
}
fcntl(screen_list->comm.socket[SOCK_CLIENT], F_SETFL,
O_NONBLOCK);
}
else if (!strncmp("REFRESH ", *pbuf, 8))
{
int dt, x, y;
/* FIXME check the length before calling atoi */
x = atoi(*pbuf + 8);
y = atoi(*pbuf + 19);
caca_gotoxy(screen_list->cv, x, y);
caca_refresh_display(screen_list->dp);
dt = caca_get_display_time(screen_list->dp);

/* Adjust refresh delay so that the server do not compute
useless things */
if (dt > 2 * 1000 * screen_list->delay
&& screen_list->delay <= 100)
{
screen_list->delay *= 2;
send_delay(screen_list);
}
else if (dt < screen_list->delay * 1000 * 1.2 &&
screen_list->delay >=
3 * screen_list->requested_delay / 2)
{
screen_list->delay = 2 * screen_list->delay / 3;
send_delay(screen_list);
}
screen_list->comm.attached = 1;
}
else if (!strncmp("CURSOR ", *pbuf, 7))
{
caca_set_cursor(screen_list->dp, atoi(*pbuf + 7));
}
else if (!strncmp("TITLE ", *pbuf, 6))
{
caca_set_display_title(screen_list->dp, *pbuf + 6);
caca_refresh_display(screen_list->dp);
}
else
{
debug("Unknown message received from server: %s", *pbuf);
}
}

/* Wait to have finished attaching before handling events */
if (screen_list->comm.attached)
{
ret = caca_get_event(screen_list->dp,
CACA_EVENT_KEY_PRESS
| CACA_EVENT_MOUSE_PRESS
| CACA_EVENT_MOUSE_RELEASE
| CACA_EVENT_MOUSE_MOTION
| CACA_EVENT_RESIZE
| CACA_EVENT_QUIT, &ev, 10000);
if (ret)
ret = send_event(ev, screen_list);
if (ret)
{
debug("Failed send event, quitting: %s\n", strerror(errno));
return 1;
}
}

return 1;
}

+ 568
- 0
neercs/old/configuration.c Näytä tiedosto

@@ -0,0 +1,568 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#include "neercs.h"


struct config_line *get_config(const char *name);
int set_window_manager(const char *argv, struct screen_list *screen_list);
int set_cube_duration(const char *argv, struct screen_list *screen_list);
int set_thumbnails(const char *argv, struct screen_list *screen_list);
int set_status_bar(const char *argv, struct screen_list *screen_list);
int set_screensaver_timeout(const char *argv, struct screen_list *screen_list);
int set_autolock_timeout(const char *argv, struct screen_list *screen_list);
int set_lock_on_detach(const char *argv, struct screen_list *screen_list);
int set_socket_dir(const char *argv, struct screen_list *screen_list);
int set_delay(const char *argv, struct screen_list *screen_list);
int set_eyecandy(const char *argv, struct screen_list *screen_list);
int set_border(const char *argv, struct screen_list *screen_list);
char *get_window_manager(struct screen_list *screen_list);
char *get_cube_duration(struct screen_list *screen_list);
char *get_thumbnails(struct screen_list *screen_list);
char *get_status_bar(struct screen_list *screen_list);
char *get_screensaver_timeout(struct screen_list *screen_list);
char *get_autolock_timeout(struct screen_list *screen_list);
char *get_lock_on_detach(struct screen_list *screen_list);
char *get_socket_dir(struct screen_list *screen_list);
char *get_delay(struct screen_list *screen_list);
char *get_eyecandy(struct screen_list *screen_list);
char *get_border(struct screen_list *screen_list);

/* Options definition and associated function pointer */
struct config_line config_option[] = {
{.name = "window_manager",.set = set_window_manager,.get =
get_window_manager},
{.name = "eyecandy",.set = set_eyecandy,.get = get_eyecandy},
{.name = "borders",.set = set_border,.get = get_border},
{.name = "cube_duration",.set = set_cube_duration,.get =
get_cube_duration},
{.name = "thumbnails",.set = set_thumbnails,.get = get_thumbnails},
{.name = "status_bar",.set = set_status_bar,.get = get_status_bar},
{.name = "screensaver_timeout",.set = set_screensaver_timeout,.get =
get_screensaver_timeout},
{.name = "autolock_timeout",.set = set_autolock_timeout,.get =
get_autolock_timeout},
{.name = "lock_on_detach",.set = set_lock_on_detach,.get =
get_lock_on_detach},
{.name = "socket_dir",.set = set_socket_dir,.get = get_socket_dir},
{.name = "delay",.set = set_delay,.get = get_delay},

{.name = "last",.set = NULL},
};



int read_configuration_file(char *filename, struct screen_list *screen_list)
{
FILE *fp;
struct stat st;
int size = 0, i = 0, total = 0, offset = 0, l = 1;
char *buffer = NULL;

screen_list->config = NULL;

/* Check if file exist */
if (stat(filename, &st) < 0)
{
return -1;
}
/* Get its size */
size = st.st_size;
if (!size)
{
fprintf(stderr, "File too short\n");
return -1;
}

/* Open it */
fp = fopen(filename, "r");
if (!fp)
{
return -1;
}

buffer = malloc(size + 1);
if (!buffer)
{
fclose(fp);
fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__,
__LINE__);
return -1;
}
/* Read it */
while ((i = fread(buffer + total, 1, size, fp)) > 0)
{
total += i;
}
buffer[total] = '\n';

fclose(fp);

/* Parse it */
while ((i =
parse_conf_line(buffer + offset, total - offset, screen_list)) > 0)
{
offset += i;
l++;
}

free(buffer);

/* Fill neercs configuration with it */
fill_config(screen_list);

return 1;
}

struct config_line *get_config_option(void)
{
return config_option;
}

int parse_conf_line(char *buf, int size, struct screen_list *screen_list)
{
int i, s = 0, c = 0;
char *line = NULL;
int l = 0;
int in_quote = 0, end_spaces = 0;
static struct option *prev = NULL;

if (size <= 0)
return -1;

/* Find EOL */
for (i = 0; i < size; i++)
{
if (buf[i] == '\n')
{
s = i + 1;
break;
}
}

/* Strip comments and trailing spaces */
for (i = 0; i < s; i++)
{
if (buf[i] == ';' && !in_quote)
{
break;
}
else if (buf[i] == '\n')
{
break;
}
else if (buf[i] == ' ' && !c)
{
}
else
{
if (line == NULL)
{
line = malloc(2);
if (!line)
{
fprintf(stderr, "Can't allocate memory at %s:%d\n",
__FUNCTION__, __LINE__);
return -1;
}
}
else
{
line = realloc(line, l + 2);
if (!line)
{
fprintf(stderr, "Can't allocate memory at %s:%d\n",
__FUNCTION__, __LINE__);
return -1;
}
}
if (buf[i] == '"')
in_quote = !in_quote;
if (buf[i] == ' ')
end_spaces++;
else
end_spaces = 0;

line[l] = buf[i];
line[l + 1] = 0;
l++;
c = 1;
}
}

if (c == 0)
{
/* This line is empty, do nothing */
}
else
{
struct option *option = malloc(sizeof(struct option));
if (!option)
{
fprintf(stderr, "Can't allocate memory at %s:%d\n",
__FUNCTION__, __LINE__);
return -1;
}
option->next = NULL;
l -= end_spaces;
line = realloc(line, l + 1);
line[l] = 0;

get_key_value(line, option);

if (!screen_list->config)
screen_list->config = option;

if (prev)
prev->next = option;

prev = option;
}
free(line);
return s;
}

int get_key_value(char *line, struct option *option)
{
unsigned int i, o = 0, b = 0, end_spaces = 0;
char *cur = NULL;
option->value = NULL;
option->key = NULL;

/* Line is a section delimiter */
if (line[0] == '[')
{
option->value = malloc(strlen(line) - 1);
if (!option->value)
{
fprintf(stderr, "Can't allocate memory at %s:%d\n",
__FUNCTION__, __LINE__);
return -1;
}
memcpy(option->value, line + 1, strlen(line) - 1);
option->value[strlen(line) - 2] = 0;
return 0;
}

cur = malloc(1);
if (!cur)
{
fprintf(stderr, "Can't allocate memory at %s:%d\n",
__FUNCTION__, __LINE__);
return -1;
}
cur[0] = 0;

for (i = 0; i < strlen(line); i++)
{
if (line[i] == ' ' && !b)
continue;


if (line[i] == '=')
{
b = 0;
cur[o - end_spaces] = 0;
cur = realloc(cur, (o - end_spaces) + 1);
if (!cur)
{
fprintf(stderr, "Can't allocate memory at %s:%d\n",
__FUNCTION__, __LINE__);
return -1;
}
o = 0;
option->key = cur;
cur = malloc(1);
}
else
{
if (line[i] == ' ')
end_spaces++;
else
end_spaces = 0;

cur = realloc(cur, o + 2);
if (!cur)
{
fprintf(stderr, "Can't allocate memory at %s:%d\n",
__FUNCTION__, __LINE__);
return -1;
}
cur[o] = line[i];
o++;
b = 1;

}
}
cur[o] = 0;
option->value = cur;
return 0;
}



struct config_line *get_config(const char *name)
{
int i = 0;

debug("Looking for '%s'\n", name);

while (strncmp(config_option[i].name, "last", strlen("last")))
{
debug("%d Testing against '%s'\n", i, config_option[i].name);
if (!strncmp(name, config_option[i].name, strlen(name)))
{
debug("Found\n");
return &config_option[i];
}
i++;
}
return NULL;
}



int fill_config(struct screen_list *screen_list)
{
int i = 0;
struct option *option = screen_list->config;

while (option)
{
if (option->key == NULL)
{
option = option->next;
continue;
}

struct config_line *c = get_config(option->key);
if (c)
{
c->set((const char *)option->value, screen_list);
}
option = option->next;
}

return i;
}



/*
* Options setters
*/

#define IS_OPTION(t) (!strncmp(argv, t, strlen(argv)))
#define IS_OPTION_TRUE (IS_OPTION("true") || IS_OPTION("True") || IS_OPTION("1"))

int set_window_manager(const char *argv, struct screen_list *screen_list)
{
if (IS_OPTION("full"))
screen_list->wm_type = WM_FULL;
else if (IS_OPTION("hsplit"))
screen_list->wm_type = WM_HSPLIT;
else if (IS_OPTION("vsplit"))
screen_list->wm_type = WM_VSPLIT;
else if (IS_OPTION("card"))
screen_list->wm_type = WM_CARD;
else
{
fprintf(stderr, "Unknown window manager '%s'\n", argv);
return -1;
}
return 0;
}

int set_cube_duration(const char *argv, struct screen_list *screen_list)
{
screen_list->cube.duration = atoi(argv) * 1000000;
return 0;
}

int set_thumbnails(const char *argv, struct screen_list *screen_list)
{
if (IS_OPTION_TRUE)
screen_list->modals.mini = 1;
else
screen_list->modals.mini = 0;
return 0;

}

int set_status_bar(const char *argv, struct screen_list *screen_list)
{
if (IS_OPTION_TRUE)
screen_list->modals.status = 1;
else
screen_list->modals.status = 0;
return 0;
}

int set_screensaver_timeout(const char *argv, struct screen_list *screen_list)
{
screen_list->screensaver.timeout = atoi(argv) * 1000000;
/* if timeout is 0, set it to 0xFFFFFFFFFFFFFFFF */
if (!screen_list->screensaver.timeout)
screen_list->screensaver.timeout -= 1;
return 0;
}

int set_autolock_timeout(const char *argv, struct screen_list *screen_list)
{
if (screen_list->lock.autolock_timeout == 0 ||
screen_list->lock.autolock_timeout == ((long long unsigned int)0) - 1)
{
screen_list->lock.autolock_timeout = atoi(argv) * 1000000;
/* if timeout is 0, set it to 0xFFFFFFFFFFFFFFFF */
if (!screen_list->lock.autolock_timeout)
screen_list->lock.autolock_timeout -= 1;
}
return 0;
}

int set_lock_on_detach(const char *argv, struct screen_list *screen_list)
{
if (IS_OPTION_TRUE)
screen_list->lock.lock_on_detach = 1;
else
screen_list->lock.lock_on_detach = 0;
return 0;
}

int set_eyecandy(const char *argv, struct screen_list *screen_list)
{
if (IS_OPTION_TRUE)
screen_list->eyecandy = 1;
else
screen_list->eyecandy = 0;
return 0;
}

int set_border(const char *argv, struct screen_list *screen_list)
{
if (IS_OPTION_TRUE)
screen_list->border_size = 1;
else
screen_list->border_size = 0;
return 0;
}

int set_socket_dir(const char *argv, struct screen_list *screen_list)
{
screen_list->comm.socket_dir = strdup(argv);
return 0;
}

int set_delay(const char *argv, struct screen_list *screen_list)
{
screen_list->requested_delay = atoi(argv);
screen_list->delay = atoi(argv);
return 0;
}

char *get_window_manager(struct screen_list *screen_list)
{
debug("Window manager is %d", screen_list->wm_type);
switch (screen_list->wm_type)
{
case WM_FULL:
return "full";
case WM_CARD:
return "card";
case WM_VSPLIT:
return "vsplit";
case WM_HSPLIT:
return "hsplit";
default:
return "invalid window manager";
}
return NULL; /* Not reached */
}

char *get_cube_duration(struct screen_list *screen_list)
{
char *r = malloc(100);
sprintf(r, "%f", (float)screen_list->cube.duration / 1000000.0f);
return r;
}

char *get_thumbnails(struct screen_list *screen_list)
{
if (screen_list->modals.mini)
return "true";
return "false";
}

char *get_status_bar(struct screen_list *screen_list)
{
if (screen_list->modals.status)
return "true";
return "false";
}

char *get_eyecandy(struct screen_list *screen_list)
{
if (screen_list->eyecandy)
return "true";
return "false";
}

char *get_border(struct screen_list *screen_list)
{
if (screen_list->border_size)
return "true";
return "false";
}

char *get_screensaver_timeout(struct screen_list *screen_list)
{
char *r = malloc(100);
sprintf(r, "%f", (float)screen_list->screensaver.timeout / 1000000.0f);
return r;
}

char *get_autolock_timeout(struct screen_list *screen_list)
{
char *r = malloc(100);
sprintf(r, "%f", (float)screen_list->lock.autolock_timeout / 1000000.0f);
return r;
}

char *get_lock_on_detach(struct screen_list *screen_list)
{
if (screen_list->lock.lock_on_detach)
return "true";
else
return "false";
}

char *get_socket_dir(struct screen_list *screen_list)
{
return screen_list->comm.socket_dir;
}

char *get_delay(struct screen_list *screen_list)
{
char *r = malloc(100);
sprintf(r, "%d", screen_list->requested_delay);
return r;
}

+ 278
- 0
neercs/old/effects.c Näytä tiedosto

@@ -0,0 +1,278 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <caca.h>

#include "neercs.h"

void draw_thumbnails(struct screen_list *screen_list)
{
char const *const *fonts;
caca_dither_t *d;
caca_font_t *f;
uint8_t *buf;
int i, y =
caca_get_canvas_height(screen_list->cv) - 6 - screen_list->modals.status;
int miniw, minih;

if (screen_list->count)
{
fonts = caca_get_font_list();
f = caca_load_font(fonts[0], 0);

miniw = caca_get_canvas_width(screen_list->screen[0]->cv)
* caca_get_font_width(f);
minih = caca_get_canvas_height(screen_list->screen[0]->cv)
* caca_get_font_height(f);
buf = malloc(4 * miniw * minih);

#if defined(HAVE_ENDIAN_H)
if (__BYTE_ORDER == __BIG_ENDIAN)
#else
/* This is compile-time optimised with at least -O1 or -Os */
uint32_t const tmp = 0x12345678;
if (*(uint8_t const *)&tmp == 0x12)
#endif
d = caca_create_dither(32, miniw, minih, 4 * miniw,
0xff0000, 0xff00, 0xff, 0x0);
else
d = caca_create_dither(32, miniw, minih, 4 * miniw,
0xff00, 0xff0000, 0xff000000, 0x0);

for (i = 0; i < screen_list->count; i++)
{
if (!screen_list->screen[i]->changed && !screen_list->changed)
continue;
caca_render_canvas(screen_list->screen[i]->cv, f, buf,
miniw, minih, miniw * 4);
caca_dither_bitmap(screen_list->cv, 20 * i, y, 19, 6, d, buf);
caca_set_color_ansi(screen_list->cv, CACA_WHITE, CACA_BLUE);

if (screen_list->pty == i)
caca_draw_cp437_box(screen_list->cv, 20 * i, y, 19, 6);
caca_printf(screen_list->cv, 20 * i, y, "(%i)", i + 1);
}

caca_free_dither(d);
caca_free_font(f);

free(buf);
}

}

/* FIXME, make this stuff more configurable */
void draw_status(struct screen_list *screen_list)
{
int x = 0, y = caca_get_canvas_height(screen_list->cv) - 1;


/* caca_fill_box(screen_list->cv, x, y,
caca_get_canvas_width(screen_list->cv), 1, '#'); */

/* Hour */
{
time_t now = time((time_t *) 0);
struct tm *t = localtime(&now);
char hour[256];
sprintf(hour, "%02d:%02d", t->tm_hour, t->tm_min);

caca_set_color_ansi(screen_list->cv, CACA_LIGHTBLUE, CACA_BLUE);
caca_printf(screen_list->cv, x, y, "[");

caca_set_color_ansi(screen_list->cv, CACA_DEFAULT, CACA_BLUE);
caca_printf(screen_list->cv, x + 1, y, hour);
caca_set_color_ansi(screen_list->cv, CACA_LIGHTBLUE, CACA_BLUE);
caca_printf(screen_list->cv, x + strlen(hour) + 1, y, "]");
x += 7;

}

/* Window */
{
char text[256];
sprintf(text, "%d/%d", screen_list->pty + 1, screen_list->count);
caca_set_color_ansi(screen_list->cv, CACA_BLUE, CACA_BLUE);
caca_put_char(screen_list->cv, x, y, '#');
x++;
caca_set_color_ansi(screen_list->cv, CACA_LIGHTBLUE, CACA_BLUE);
caca_printf(screen_list->cv, x, y, "Window:");
caca_set_color_ansi(screen_list->cv, CACA_BLUE, CACA_BLUE);
caca_put_char(screen_list->cv, x + 7, y, '#');
caca_set_color_ansi(screen_list->cv, CACA_DEFAULT, CACA_BLUE);
caca_printf(screen_list->cv, x + 8, y, text);
x += 8 + strlen(text);
}

/* Window Manager */
{
char text[256];

switch (screen_list->wm_type)
{
case WM_CARD:
strcpy(text, "card");
break;
case WM_HSPLIT:
strcpy(text, "hsplit");
break;
case WM_VSPLIT:
strcpy(text, "vsplit");
break;
case WM_FULL:
default:
strcpy(text, "full");
break;

}

caca_set_color_ansi(screen_list->cv, CACA_BLUE, CACA_BLUE);
caca_put_char(screen_list->cv, x, y, '#');
x++;
caca_set_color_ansi(screen_list->cv, CACA_LIGHTBLUE, CACA_BLUE);
caca_printf(screen_list->cv, x, y, "WM:");
caca_set_color_ansi(screen_list->cv, CACA_BLUE, CACA_BLUE);
caca_put_char(screen_list->cv, x + 3, y, '#');
caca_set_color_ansi(screen_list->cv, CACA_DEFAULT, CACA_BLUE);
caca_printf(screen_list->cv, x + 4, y, text);
x += 4 + strlen(text);
}

/* Help (must be the last one ) */
{
char text[256];
sprintf(text, "Help: ctrl-a-?");
caca_set_color_ansi(screen_list->cv, CACA_BLUE, CACA_BLUE);
while (x <
(int)(caca_get_canvas_width(screen_list->cv) - strlen(text)))
{
caca_put_char(screen_list->cv, x, y, '#');
x++;
}
caca_set_color_ansi(screen_list->cv, CACA_DEFAULT, CACA_BLUE);
caca_printf(screen_list->cv, x, y, text);
}


}



int update_window_list(int c, struct screen_list *screen_list)
{
debug("Got %x\n", c);

switch (c)
{
case 0x111:
if (screen_list->modals.cur_in_list > 0)
screen_list->modals.cur_in_list--;
break;
case 0x112:
if (screen_list->modals.cur_in_list < screen_list->count - 1)
screen_list->modals.cur_in_list++;
break;
case 0xd:
screen_list->modals.window_list = 0;
screen_list->prevpty = screen_list->pty;
screen_list->pty = screen_list->modals.cur_in_list;
break;
case 0x22:
screen_list->modals.window_list = 0;
break;
default:
break;
}

return 1;
}

void draw_list(struct screen_list *screen_list)
{
int i;
int w = (caca_get_canvas_width(screen_list->cv));
int h = (caca_get_canvas_height(screen_list->cv));

debug("Drawing list\n");
caca_set_color_ansi(screen_list->cv, CACA_BLACK, CACA_BLACK);
caca_fill_box(screen_list->cv, 0, 0, w, h, '#');
caca_set_color_ansi(screen_list->cv, CACA_DEFAULT, CACA_DEFAULT);
caca_draw_cp437_box(screen_list->cv, 0, 0, w, h);

caca_printf(screen_list->cv, 2, 1, "Num Name");
for (i = 0; i < screen_list->count; i++)
{
char line[1024];
if (screen_list->modals.cur_in_list == i)
caca_set_color_ansi(screen_list->cv, CACA_BLACK, CACA_WHITE);
else
caca_set_color_ansi(screen_list->cv, CACA_DEFAULT, CACA_DEFAULT);
sprintf(line, "%d %s", i + 1, screen_list->screen[i]->title);

caca_printf(screen_list->cv, 2, i + 3, line);
}
}

/* Close a window by animating it collapsing */
/* Total close time */
#define DELAY 500000.0f
int close_screen_recurrent(struct screen_list *screen_list,
struct recurrent *rec, void *user,
long long unsigned int t)
{
long long unsigned int delta = t - rec->start_time;

screen_list->dont_update_coords = 1;
screen_list->delay = 0;
rec->kill_me = 0;
if (delta >= DELAY || (!screen_list->eyecandy))
{
rec->kill_me = 1;
remove_screen(screen_list, screen_list->pty, 1);
screen_list->pty = screen_list->prevpty>screen_list->count?screen_list->count:screen_list->prevpty;
screen_list->prevpty = 0;
screen_list->dont_update_coords = 0;
}
else
{
float r = 1 - ((DELAY - (DELAY - delta)) / DELAY);
caca_canvas_t *old, *new;
struct screen *s = screen_list->screen[screen_list->pty];
int w = s->orig_w * r;
int h = s->orig_h * r;

/* libcaca canvas resize function is bugged, do it by hand */
old = s->cv;
new = caca_create_canvas(w, h);
caca_blit(new, 0, 0, old, NULL);
s->cv = new;
caca_free_canvas(old);
set_tty_size(s->fd, w, h);

s->w = w;
s->h = h;

s->x = (s->orig_x * r) + ((s->orig_w / 2) - s->w / 2);
s->y = (s->orig_y * r) + ((s->orig_h / 2) - s->h / 2);
}
screen_list->changed = 1;
return 1;
}

+ 393
- 0
neercs/old/grab.c Näytä tiedosto

@@ -0,0 +1,393 @@
/*
* neercs console-based window manager
* Copyright (c) 2008-2010 Pascal Terjan <pterjan@linuxfr.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"

#define _XOPEN_SOURCE 500 /* getsid() */

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <glob.h>
#include <libgen.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>

#if defined HAVE_LINUX_KDEV_T_H
# include <linux/kdev_t.h>
# include <linux/major.h>
#endif

#include "neercs.h"
#include "mytrace.h"

int grab_process(long pid, char *ptyname, int ptyfd, int *newpid)
{
#if defined HAVE_LINUX_KDEV_T_H
char fdstr[1024];
struct mytrace *parent, *child;
int i = 0, fd = 0, ret;
char to_open[128];
int mode[128];
int fds[128];
struct stat stat_buf;
struct termios tos;
int validtos = 0;
DIR *fddir;
struct dirent *fddirent;

debug("pty is %s", ptyname);

parent = mytrace_attach(pid);
if (!parent)
{
fprintf(stderr, "Cannot access process %ld\n", pid);
return -1;
}

child = mytrace_fork(parent);

snprintf(fdstr, sizeof(fdstr), "/proc/%ld/fd", pid);
fddir = opendir(fdstr);

/* Look for file descriptors that are PTYs */
while ((fddirent = readdir(fddir)) && i < (int)sizeof(to_open) - 1)
{
fd = atoi(fddirent->d_name);
fds[i] = fd;
to_open[i] = 0;
lstat(fdstr, &stat_buf);
if ((stat_buf.st_mode & S_IRUSR) && (stat_buf.st_mode & S_IWUSR))
mode[i] = O_RDWR;
else if (stat_buf.st_mode & S_IWUSR)
mode[i] = O_WRONLY;
else
mode[i] = O_RDONLY;

snprintf(fdstr, sizeof(fdstr), "/proc/%ld/fd/%s", pid,
fddirent->d_name);

if (stat(fdstr, &stat_buf) < 0)
continue;

if (!S_ISCHR(stat_buf.st_mode)
|| MAJOR(stat_buf.st_rdev) != UNIX98_PTY_SLAVE_MAJOR)
continue;

debug("found pty %d for pid %d", fd, pid);

if (!validtos)
{
ret = mytrace_tcgets(child, fd, &tos);
if (ret < 0)
{
perror("mytrace_tcgets");
}
else
{
validtos = 1;
}
}
to_open[i] = 1;
i++;
}
closedir(fddir);

if (i >= (int)sizeof(to_open) - 1)
{
fprintf(stderr, "too many open pty\n");
mytrace_detach(child);
return -1;
}

ret = mytrace_exec(parent, "/usr/bin/reset");
if (ret < 0)
mytrace_exit(parent, 0);
mytrace_detach(parent);
waitpid(pid, NULL, 0); /* Wait for reset to finish before displaying */
mytrace_write(child, 2, "\033[H\033[2J", 7);
mytrace_write(child, 2, "\n[Process stolen by neercs]\r\n\n", 30);

pid = mytrace_getpid(child);
*newpid = pid;

/* Set the process's session ID */
debug("Running setsid on process %ld (sid=%d)", pid, getsid(pid));

ret = mytrace_setpgid(child, 0, getsid(pid));
if (ret < 0)
{
fprintf(stderr, "syscall setpgid failed\n");
mytrace_detach(child);
return -1;
}

if (ret != 0)
{
fprintf(stderr, "setpgid returned %d\n", ret);
mytrace_detach(child);
return -1;
}

ret = mytrace_setsid(child);
if (ret < 0)
{
fprintf(stderr, "syscall setsid failed\n");
mytrace_detach(child);
return -1;
}

debug("pid %ld has now sid %d", pid, getsid(pid));

/* Reopen PTY file descriptors */
for (; i >= 0; i--)
{
if (!to_open[i])
continue;
ret = mytrace_close(child, fds[i]);
if (ret < 0)
{
perror("mytrace_close");
continue;
}
fd = mytrace_open(child, ptyname, mode[i]);
if (fd < 0)
{
perror("mytrace_open");
continue;
}

/* FIXME Only needed once */
mytrace_sctty(child, fd);

if (validtos)
{
ret = mytrace_tcsets(child, fd, &tos);
if (ret < 0)
{
perror("mytrace_tcsets");
}
validtos = 0;
}
ret = mytrace_dup2(child, fd, fds[i]);
if (ret < 0)
{
perror("mytrace_dup2");
}
}

kill(pid, SIGWINCH);
mytrace_detach(child);

close(ptyfd);
return 0;
#else
errno = ENOSYS;
return -1;
#endif
}

struct process
{
long pid;
char *cmdline;
};

static int list_process(struct process **process_list)
{
glob_t pglob;
unsigned int i, n = 0;
glob("/proc/[0-9]*", GLOB_NOSORT, NULL, &pglob);
*process_list = malloc(pglob.gl_pathc * sizeof(struct process));
for (i = 0; i < pglob.gl_pathc; i++)
{
glob_t pglob2;
unsigned int j;
char *fds;
(*process_list)[n].pid = atoi(basename(pglob.gl_pathv[i]));
/* Don't allow grabbing ourselves */
if ((*process_list)[n].pid == getpid())
continue;
/* FIXME check value of r */
int r = asprintf(&fds, "%s/fd/*", pglob.gl_pathv[i]);
(void) r;
glob(fds, GLOB_NOSORT, NULL, &pglob2);
free(fds);
for (j = 0; j < pglob2.gl_pathc; j++)
{
char path[4096];
ssize_t l = readlink(pglob2.gl_pathv[j], path, sizeof(path));
if (l <= 0)
continue;
path[l] = '\0';
if (strstr(path, "/dev/pt"))
{
char *cmdfile;
int fd;
/* FIXME check value of r */
r = asprintf(&cmdfile, "%s/cmdline", pglob.gl_pathv[i]);
(void) r;
fd = open(cmdfile, O_RDONLY);
free(cmdfile);
if (fd)
{
/* FIXME check value of r */
r = read(fd, path, sizeof(path));
(void) r;
(*process_list)[n].cmdline = strdup(path);
close(fd);
n++;
break;
}
}
}
globfree(&pglob2);
}
globfree(&pglob);
return n;
}

long select_process(struct screen_list *screen_list)
{
caca_event_t ev;
enum caca_event_type t;
int current_line = 1;
int refresh = 1;
int nb_process, i;
int ret = 0;
int start = 0;
struct process *process_list;

nb_process = list_process(&process_list);

screen_list->cv = caca_create_canvas(0, 0);
screen_list->dp = caca_create_display(screen_list->cv);
if (!screen_list->dp)
goto end;
caca_set_cursor(screen_list->dp, 0);
caca_set_display_title(screen_list->dp, PACKAGE_STRING);
while (1)
{
if (refresh)
{
caca_set_color_ansi(screen_list->cv, CACA_BLUE, CACA_BLUE);
caca_fill_box(screen_list->cv,
0, 0,
caca_get_canvas_width(screen_list->cv),
caca_get_canvas_height(screen_list->cv), '#');
caca_set_color_ansi(screen_list->cv, CACA_DEFAULT, CACA_BLUE);
caca_draw_cp437_box(screen_list->cv,
0, 0,
caca_get_canvas_width(screen_list->cv),
caca_get_canvas_height(screen_list->cv));
caca_printf(screen_list->cv, 2, 2,
"Please select a process to grab:");
for (i = 0;
i < nb_process
&& i < caca_get_canvas_height(screen_list->cv) - 4; i++)
{
if (i == current_line - 1)
{
caca_set_attr(screen_list->cv, CACA_BOLD);
caca_set_color_ansi(screen_list->cv, CACA_GREEN,
CACA_BLUE);
caca_put_char(screen_list->cv, 1, i + 3, '>');
}
else
{
caca_set_attr(screen_list->cv, 0);
caca_set_color_ansi(screen_list->cv, CACA_LIGHTGRAY,
CACA_BLUE);
caca_put_char(screen_list->cv, 1, i + 3, ' ');
}
caca_printf(screen_list->cv,
3, i + 3,
"%5d %s",
process_list[i + start].pid,
process_list[i + start].cmdline);
}
caca_refresh_display(screen_list->dp);
refresh = 0;
}

if (!caca_get_event(screen_list->dp,
CACA_EVENT_KEY_PRESS
| CACA_EVENT_RESIZE | CACA_EVENT_QUIT, &ev, 10000))
continue;

t = caca_get_event_type(&ev);

if (t & CACA_EVENT_KEY_PRESS)
{
unsigned int c = caca_get_event_key_ch(&ev);
switch (c)
{
case CACA_KEY_UP:
if (current_line > 1)
current_line--;
if (current_line < start && start > 0)
start--;
break;
case CACA_KEY_DOWN:
if (current_line < nb_process)
current_line++;
if (current_line >
start + caca_get_canvas_height(screen_list->cv) - 3)
start++;
break;
case CACA_KEY_RETURN:
ret = process_list[current_line - 1].pid;
goto end;
break;
case CACA_KEY_ESCAPE:
goto end;
break;
default:
break;
}
refresh = 1;
}
else if (t & CACA_EVENT_RESIZE)
{
refresh = 1;
}
else if (t & CACA_EVENT_QUIT)
goto end;
}

end:
if (screen_list->dp)
{
caca_free_display(screen_list->dp);
screen_list->dp = NULL;
}
if (screen_list->cv)
{
caca_free_canvas(screen_list->cv);
screen_list->cv = NULL;
}
if (nb_process > 0)
{
for (i = 0; i < nb_process; i++)
{
free(process_list[i].cmdline);
}
free(process_list);
}
return ret;
}

+ 76
- 0
neercs/old/help.c Näytä tiedosto

@@ -0,0 +1,76 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <caca.h>

#include "neercs.h"

int help_handle_key(struct screen_list *screen_list, unsigned int c)
{
if (c == CACA_KEY_ESCAPE || c == '?')
{
screen_list->modals.help = 0;
screen_list->changed = 1;
return 1;
}
else
{
return 0;
}
}

void draw_help(struct screen_list *screen_list)
{
int w = 65, h = 20;
int x = (caca_get_canvas_width(screen_list->cv) - w) / 2;
int y = (caca_get_canvas_height(screen_list->cv) - h) / 2;


caca_set_color_ansi(screen_list->cv, CACA_BLUE, CACA_BLUE);
caca_fill_box(screen_list->cv, x, y, w, h, '#');
caca_set_color_ansi(screen_list->cv, CACA_DEFAULT, CACA_BLUE);
caca_draw_cp437_box(screen_list->cv, x, y, w, h);

x += 2;
y++;
caca_printf(screen_list->cv,
(caca_get_canvas_width(screen_list->cv) -
strlen(PACKAGE_STRING)) / 2, y - 1, PACKAGE_STRING);
caca_printf(screen_list->cv, x, y++, "Copyright (c) 2006-2010");
caca_printf(screen_list->cv, x, y++, " Sam Hocevar <sam@zoy.org>");
caca_printf(screen_list->cv, x, y++, " Jean-Yves Lamoureux <jylam@lnxscene.org>");
caca_printf(screen_list->cv, x, y++, " Pascal Terjan <pterjan@linuxfr.org>");
caca_printf(screen_list->cv, x, y++, "");
caca_printf(screen_list->cv, x, y++, "");
caca_printf(screen_list->cv, x, y++, "All shortcuts are in format 'ctrl-a-X' where X is :");
caca_printf(screen_list->cv, x, y++, "n: Next window");
caca_printf(screen_list->cv, x, y++, "p: Previous window");
caca_printf(screen_list->cv, x, y++, "w: Switch window manager");
caca_printf(screen_list->cv, x, y++, "c: Create new window");
caca_printf(screen_list->cv, x, y++, "m: Thumbnails");
caca_printf(screen_list->cv, x, y++, "d: Detach");
caca_printf(screen_list->cv, x, y++, "k: Close window and kill associated process");
caca_printf(screen_list->cv, x, y++, "h: Dump screen into a file");
caca_printf(screen_list->cv, x, y++, "?: This help");
caca_printf(screen_list->cv, x, y++, "");
caca_printf(screen_list->cv, x, y++, "");
caca_printf(screen_list->cv, x, y, "See http://caca.zoy.org/wiki/neercs for more informations");
}

+ 192
- 0
neercs/old/input.c Näytä tiedosto

@@ -0,0 +1,192 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* 2008-2010 Pascal Terjan <pterjan@linuxfr.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/
#include "config.h"
#include <caca.h>
#include <string.h>
#include "neercs.h"

struct kconv
{
unsigned int key;
char *val;
int size;
};

struct kconv kconv[] = {
{CACA_KEY_UP, "\033OA", 3},
{CACA_KEY_DOWN, "\033OB", 3},
{CACA_KEY_RIGHT, "\033OC", 3},
{CACA_KEY_LEFT, "\033OD", 3},
{CACA_KEY_PAGEUP, "\033[5~", 4},
{CACA_KEY_PAGEDOWN, "\033[6~", 4},
{CACA_KEY_HOME, "\033[1~", 4},
{CACA_KEY_INSERT, "\033[2~", 4},
{CACA_KEY_DELETE, "\033[3~", 4},
{CACA_KEY_END, "\033[4~", 4},
{CACA_KEY_F1, "\033[11~", 5},
{CACA_KEY_F2, "\033[12~", 5},
{CACA_KEY_F3, "\033[13~", 5},
{CACA_KEY_F4, "\033[14~", 5},
{CACA_KEY_F5, "\033[15~", 5},
{CACA_KEY_F6, "\033[17~", 5},
{CACA_KEY_F7, "\033[18~", 5},
{CACA_KEY_F8, "\033[19~", 5},
{CACA_KEY_F9, "\033[20~", 5},
{CACA_KEY_F10, "\033[21~", 5},
{CACA_KEY_F11, "\033[23~", 5},
{CACA_KEY_F12, "\033[24~", 5},
};



void *convert_input_ansi(unsigned int *c, int *size)
{
unsigned int i;
for (i = 0; i < sizeof(kconv) / sizeof(struct kconv); i++)
{
if (*c == kconv[i].key)
{
*size = kconv[i].size;
return kconv[i].val;
}
}

*size = 1;
return c;
}



int handle_command_input(struct screen_list *screen_list, unsigned int c)
{
int refresh = 0;

debug("Key %x\n", c);
screen_list->changed = 1;

if (c >= '0' && c <= '9')
{
int n = c - 49;
if (n < screen_list->count)
{
screen_list->prevpty = screen_list->pty;
screen_list->pty = n == -1 ? 10 : n;
return 1;
}
else
{
return 0;
}
}

switch (c)
{
case 0x01: // CACA_KEY_CTRL_A:
screen_list->pty ^= screen_list->prevpty;
screen_list->prevpty ^= screen_list->pty;
screen_list->pty ^= screen_list->prevpty;
refresh = 1;
break;
case 'm':
case 0x0d: // CACA_KEY_CTRL_M:
screen_list->modals.mini = !screen_list->modals.mini;
refresh = 1;
break;
case 'n':
case ' ':
case '\0':
case 0x0e: // CACA_KEY_CTRL_N:
screen_list->prevpty = screen_list->pty;
screen_list->pty = (screen_list->pty + 1) % screen_list->count;
if (screen_list->pty != screen_list->prevpty)
{
screen_list->last_switch = get_us();
screen_list->cube.in_switch = 1;
screen_list->cube.side = 0;
}
refresh = 1;
break;
case 'p':
case 0x10: // CACA_KEY_CTRL_P:
screen_list->prevpty = screen_list->pty;
screen_list->pty =
(screen_list->pty + screen_list->count - 1) % screen_list->count;
if (screen_list->pty != screen_list->prevpty)
{
screen_list->last_switch = get_us();
screen_list->cube.in_switch = 1;
screen_list->cube.side = 1;
}
refresh = 1;
break;
case 'c':
case 0x03: // CACA_KEY_CTRL_C:
screen_list->prevpty = screen_list->pty;
screen_list->pty =
add_screen(screen_list,
create_screen(screen_list->width,
screen_list->height,
screen_list->sys.default_shell));
refresh = 1;
break;
case 'w':
case 0x17: // CACA_KEY_CTRL_W:
screen_list->wm_type = (screen_list->wm_type == (WM_MAX - 1) ?
screen_list->wm_type = 0 :
screen_list->wm_type + 1);
refresh = 1;
break;
case 'k':
case 0x0b: // CACA_KEY_CTRL_K:
add_recurrent(screen_list->recurrent_list, close_screen_recurrent,
screen_list->cv);
refresh = 1;
break;
case 'x':
case 0x18: // CACA_KEY_CTRL_X:
memset(screen_list->lock.lockpass, 0, 1024);
screen_list->lock.locked = 1;
screen_list->lock.lock_offset = 0;
refresh = 1;
break;
case 'h':
case 0x08: // CACA_KEY_CTRL_H:
dump_to_file(screen_list);
break;
case '?':
screen_list->modals.help = !screen_list->modals.help;
refresh = 1;
break;
case '"':
case 0x34: // CTRL+"
screen_list->modals.cur_in_list = screen_list->pty;
screen_list->modals.window_list = !screen_list->modals.window_list;
refresh = 1;
break;
case 'd':
case 0x04: // CACA_KEY_CTRL_D:
detach(screen_list);
break;
#ifdef USE_PYTHON
case 'e':
case 0x05:
debug("py : command is %d, setting to 1 (at %p)\n", screen_list->modals.python_command, &screen_list->modals.python_command);
screen_list->modals.python_command = 1;
refresh = 1;
break;
#endif
}
return refresh;

}

+ 221
- 0
neercs/old/lock.c Näytä tiedosto

@@ -0,0 +1,221 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <caca.h>
#include <time.h>
#include <sys/wait.h>
#include <sys/types.h>

#if defined USE_LOCK
#if defined HAVE_PAM_PAM_MISC_H
# include <pam/pam_appl.h>
# include <pam/pam_misc.h>
#else
# include <security/pam_appl.h>
# include <security/pam_misc.h>
#endif
# include <pwd.h>
#endif

#include "neercs.h"

#if defined USE_LOCK
static int convpam(int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr);
#endif

int update_lock(int c, struct screen_list *screen_list)
{
int refresh = 0;

#if defined USE_LOCK
if (!screen_list->lock.locked)
return 0;

if (c == 0x08) // BACKSPACE
{
if (screen_list->lock.lock_offset)
{
screen_list->lock.lockpass[screen_list->lock.lock_offset - 1] = 0;
screen_list->lock.lock_offset--;
}
}
else if (c == 0x0d) // RETURN
{
memset(screen_list->lock.lockmsg, 0, 1024);
if (validate_lock(screen_list, getenv("USER"), screen_list->lock.lockpass))
{
memset(screen_list->lock.lockpass, 0, 1024);
screen_list->lock.locked = 0;
screen_list->lock.lock_offset = 0;
refresh = 1;
}
else
{
memset(screen_list->lock.lockpass, 0, 1024);
screen_list->lock.lock_offset = 0;
refresh = 1;
}
}
else
{
if (screen_list->lock.lock_offset < 1023)
{
screen_list->lock.lockpass[screen_list->lock.lock_offset++] = c;
screen_list->lock.lockpass[screen_list->lock.lock_offset] = 0;
}
}
#endif

return refresh;
}

void draw_lock(struct screen_list *screen_list)
{
#if defined USE_LOCK
unsigned int i;
char buffer[1024];
caca_canvas_t *cv = screen_list->cv;

gethostname(buffer, sizeof(buffer) - 1);

int w = 65, h = 20;
int x = (caca_get_canvas_width(cv) - w) / 2;
int y = (caca_get_canvas_height(cv) - h) / 2;


caca_set_color_ansi(cv, CACA_BLUE, CACA_BLUE);
caca_fill_box(cv, x, y, w, h, '#');
caca_set_color_ansi(cv, CACA_DEFAULT, CACA_BLUE);
caca_draw_cp437_box(cv, x, y, w, h);

x += 2;
y++;
caca_printf(cv,
(caca_get_canvas_width(cv) -
strlen(PACKAGE_STRING " locked")) / 2, y - 1,
PACKAGE_STRING " locked");

caca_printf(cv, x, y++, "Please type in your password for %s@%s :",
getenv("USER"), buffer);
y += 2;

x = (caca_get_canvas_width(cv) / 2) -
((strlen(screen_list->lock.lockpass) / 2) + strlen("Password : "));
caca_printf(cv, x, y, "Password : ");
x += strlen("Password : ");
for (i = 0; i < strlen(screen_list->lock.lockpass); i++)
{
caca_put_str(cv, x, y, "*");
x++;
}


if (strlen(screen_list->lock.lockmsg))
{
x = ((caca_get_canvas_width(cv) - w) / 2) +
(strlen(screen_list->lock.lockmsg));
y += 2;
caca_set_color_ansi(cv, CACA_RED, CACA_BLUE);
caca_printf(cv, x, y, "Error : %s", screen_list->lock.lockmsg);
}
#endif
}


#if defined USE_LOCK

/* FIXME, handle this without assuming this is a password auth */
static int convpam(int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr)
{

struct pam_response *aresp;
int i;
aresp = calloc(num_msg, sizeof(*aresp));

for (i = 0; i < num_msg; ++i)
{
switch (msg[i]->msg_style)
{
case PAM_PROMPT_ECHO_ON:
case PAM_PROMPT_ECHO_OFF:
aresp[i].resp = strdup(appdata_ptr);
aresp[i].resp_retcode = 0;
break;
case PAM_ERROR_MSG:
break;
default:
printf("Unknow message type from PAM\n");
break;
}
}

*resp = aresp;
return (PAM_SUCCESS);
}
#endif

int validate_lock(struct screen_list *screen_list, char *user, char *pass)
{
#if USE_LOCK
int ret;
pam_handle_t *pamh = NULL;
char buffer[100];
const char *service = "neercs";
struct pam_conv conv = {
convpam,
pass,
};

ret = pam_start(service, user, &conv, &pamh);
if (ret != PAM_SUCCESS)
return 0;
pam_set_item(pamh, PAM_RUSER, user);

ret = gethostname(buffer, sizeof(buffer) - 1);
if (ret)
{
perror("failed to look up hostname");
ret = pam_end(pamh, PAM_ABORT);
sprintf(screen_list->lock.lockmsg, "Can't get hostname");
pam_end(pamh, PAM_SUCCESS);
return 0;
}

ret = pam_set_item(pamh, PAM_RHOST, buffer);
if (ret != PAM_SUCCESS)
{
sprintf(screen_list->lock.lockmsg, "Can't set hostname");
pam_end(pamh, PAM_SUCCESS);
return 0;
}

ret = pam_authenticate(pamh, 0);
if (ret != PAM_SUCCESS)
{
sprintf(screen_list->lock.lockmsg, "Can't authenticate");
pam_end(pamh, PAM_SUCCESS);
return 0;
}

ret = pam_end(pamh, PAM_SUCCESS);
#endif

return 1;
}

+ 324
- 0
neercs/old/main.c Näytä tiedosto

@@ -0,0 +1,324 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* 2008-2010 Pascal Terjan <pterjan@linuxfr.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <time.h>



#if !defined HAVE_GETOPT_LONG
# include "mygetopt.h"
#elif defined HAVE_GETOPT_H
# include <getopt.h>
#endif
#if defined HAVE_GETOPT_LONG
# define mygetopt getopt_long
# define myoptind optind
# define myoptarg optarg
# define myoption option
#endif
#include <errno.h>
#include <caca.h>

#include "neercs.h"


void version(void)
{
printf("%s\n", PACKAGE_STRING);
printf("Copyright (C) 2006, 2008 Sam Hocevar <sam@zoy.org>\n");
printf
(" Jean-Yves Lamoureux <jylam@lnxscene.org>\n\n");
printf
("This is free software. You may redistribute copies of it under the\n");
printf
("terms of the Do What The Fuck You Want To Public License, Version 2\n");
printf("<http://sam.zoy.org/wtfpl/>.\n");
printf("There is NO WARRANTY, to the extent permitted by law.\n");
printf("\n");
printf
("For more informations, visit http://libcaca.zoy.org/wiki/neercs\n");
}

void usage(int argc, char **argv)
{
printf("%s\n", PACKAGE_STRING);
printf("Usage : %s [command1] [command2] ... [commandN]\n", argv[0]);
printf("Example : %s zsh top \n\n", argv[0]);
printf("Options :\n");
printf("\t--config\t-c <file>\t\tuse given config file\n");
printf("\t--pid\t\t-P [pid]\t\tgrab process\n");
printf("\t\t\t-r [session]\t\treattach to a detached neercs\n");
printf
("\t\t\t-R [session]\t\treattach if possible, otherwise start a new session\n");
printf("\t\t\t-S <name>\t\tname this session <name> instead of <pid>\n");
printf("\t--lock-after\t-l [n]\t\t\tlock screen after n seconds\n");
printf("\t--version\t-v \t\t\tdisplay version and exit\n");
printf("\t--help\t\t-h \t\t\tthis help\n");
}

#if 0
int main(int argc, char **argv)
{
struct screen_list *screen_list = init_neercs(argc, argv);
if (!screen_list)
return -1;

mainloop(screen_list);
}
#endif

struct screen_list *init_neercs(int argc, char **argv)
{
struct screen_list *screen_list = NULL;
int args;

int mainret = -1;

screen_list = create_screen_list();
screen_list->sys.default_shell = getenv("SHELL");

args = argc - 1;
if (screen_list->sys.default_shell == NULL && args <= 0)
{
fprintf(stderr,
"Environment variable SHELL not set and no arguments given. kthxbye.\n");
free_screen_list(screen_list);
return NULL;
}

if (handle_command_line(argc, argv, screen_list) < 0)
{
free_screen_list(screen_list);
return NULL;
}

/* Read global configuration first */
read_configuration_file("/etc/neercsrc", screen_list);

/* Then local one */
if (screen_list->sys.user_path)
{
read_configuration_file(screen_list->sys.user_path, screen_list);
free(screen_list->sys.user_path);
}

if (screen_list->sys.attach)
{
if (screen_list->sys.nb_to_grab || screen_list->sys.to_start)
{
fprintf(stderr,
"-R can not be associated with commands or pids!\n");
free_screen_list(screen_list);
return NULL;
}

attach(screen_list);

if (screen_list->sys.forceattach && !screen_list->sys.attach)
{
free_screen_list(screen_list);
return NULL;
}
}

/* Build default session name */
if (!screen_list->comm.session_name)
{
char mypid[32]; /* FIXME Compute the length of PID_MAX ? */
snprintf(mypid, 31, "%d", getpid());
mypid[31] = '\0';
screen_list->comm.session_name = strdup(mypid);
if (!screen_list->comm.session_name)
{
fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__,
__LINE__);
free_screen_list(screen_list);
return NULL;
}
}
if (!screen_list->comm.socket_path[SOCK_CLIENT])
screen_list->comm.socket_path[SOCK_CLIENT] =
build_socket_path(screen_list->comm.socket_dir,
screen_list->comm.session_name, SOCK_CLIENT);

if (!screen_list->comm.socket_path[SOCK_SERVER])
screen_list->comm.socket_path[SOCK_SERVER] =
build_socket_path(screen_list->comm.socket_dir,
screen_list->comm.session_name, SOCK_SERVER);

/* Fork the server if needed */
if (!screen_list->sys.attach)
{
debug("Spawning a new server");
if (start_server(screen_list))
{
free_screen_list(screen_list);
return NULL;
}
if (start_client(screen_list))
{
free_screen_list(screen_list);
return NULL;
}
}

return screen_list;
}

int handle_command_line(int argc, char *argv[],
struct screen_list *screen_list)
{
int s = 0, i;
for (;;)
{
int option_index = 0;
int pidopt;
static struct myoption long_options[] = {
{"config", 1, NULL, 'c'},
#if defined USE_GRAB
{"pid", 0, NULL, 'P'},
#endif
{"lock-after", 1, NULL, 'l'},
{"help", 0, NULL, 'h'},
{"version", 0, NULL, 'v'},
{NULL, 0, NULL, 0},
};
#if defined USE_GRAB
int c =
mygetopt(argc, argv, "c:S:R::l::r::P::hv", long_options,
&option_index);
#else
int c =
mygetopt(argc, argv, "c:S:R::l::r::hv", long_options,
&option_index);
#endif
if (c == -1)
break;

switch (c)
{
case 'c': /* --config */
if (screen_list->sys.user_path)
free(screen_list->sys.user_path);
screen_list->sys.user_path = strdup(myoptarg);
s += 2;
break;
case 'S':
if (!screen_list->comm.session_name)
screen_list->comm.session_name = strdup(myoptarg);
s += 2;
break;
case 'P': /* --pid */
if (myoptarg)
{
pidopt = atoi(myoptarg);
if (pidopt <= 0)
{
fprintf(stderr, "Invalid pid %d\n", pidopt);
if (screen_list->sys.to_grab)
free(screen_list->sys.to_grab);
return -1;
}
}
else
pidopt = select_process(screen_list);
if (pidopt <= 0)
{
s += 1;
break;
}
if (!screen_list->sys.to_grab)
{
/* At most argc-1-s times -P <pid> + final 0 */
screen_list->sys.to_grab =
(int *)malloc(((argc - 1 - s) / 2 + 1) * sizeof(int));
if (!screen_list->sys.to_grab)
{
fprintf(stderr, "Can't allocate memory at %s:%d\n",
__FUNCTION__, __LINE__);
return -1;
}
}
screen_list->sys.to_grab[screen_list->sys.nb_to_grab++] = pidopt;
screen_list->sys.to_grab[screen_list->sys.nb_to_grab] = 0;
s += 2;
break;
case 'l':
screen_list->lock.autolock_timeout = atoi(myoptarg) * 1000000;
if (screen_list->lock.autolock_timeout == 0)
screen_list->lock.autolock_timeout -= 1;
break;
case 'r':
screen_list->sys.forceattach = 1;
case 'R':
if (screen_list->sys.attach)
{
fprintf(stderr, "Attaching can only be requested once\n");
return -1;
}
if (myoptarg)
{
if (screen_list->comm.session_name)
free(screen_list->comm.session_name);
screen_list->comm.session_name = strdup(myoptarg);
s += 1;
}
screen_list->sys.attach = 1;
s += 1;
break;
case 'h': /* --help */
usage(argc, argv);
return -1;
break;
case 'v': /* --version */
version();
return -1;
break;
case -2:
return -1;
default:
fprintf(stderr, "Unknown argument #%d\n", myoptind);
return -1;
break;
}
}
if (s >= 0 && s < argc - 1)
{
screen_list->sys.to_start = (char **)malloc((argc - s) * sizeof(char *));
if (!screen_list->sys.to_start)
{
fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__,
__LINE__);
return -1;
}
for (i = 0; i < (argc - 1) - s; i++)
{
screen_list->sys.to_start[i] = strdup(argv[i + s + 1]);
}
screen_list->sys.to_start[argc - 1 - s] = NULL;
}
return s;
}

+ 94
- 0
neercs/old/mini-client.c Näytä tiedosto

@@ -0,0 +1,94 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2011 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* 2008-2010 Pascal Terjan <pterjan@linuxfr.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#if defined HAVE_CONFIG_H
# include "config.h"
#endif

#include <stdio.h> /* BUFSIZ */
#include <string.h> /* strncmp() */

#include <caca.h>

#include "mini-neercs.h"
#include "mini-socket.h"

static caca_display_t *dp;
static caca_canvas_t *cv;
static nrx_socket_t *insock, *outsock;

void client_init(void)
{
int i, usec = 10000;

cv = caca_create_canvas(0, 0);
dp = caca_create_display(cv);
caca_set_display_title(dp, "Press Esc to quit");

insock = socket_open("/tmp/neercs.sock.client", 1);

for (i = 0; i < 10; i++)
{
outsock = socket_open("/tmp/neercs.sock", 0);
if (outsock)
break;
usleep(usec);
usec += usec;
}

socket_puts(outsock, "CONNECT /tmp/neercs.sock.client");
}

int client_step(void)
{
caca_event_t ev;
int ret;

/* Handle client sockets */
ret = socket_select(insock, 1000);
if (ret > 0)
{
char buf[BUFSIZ];
ssize_t bytes = socket_read(insock, buf, BUFSIZ);
if (bytes <= 0)
return 1;

/* Parse message */
if (!strncmp(buf, "OK", strlen("OK")))
{
fprintf(stderr, "neercs: connection established\n");
socket_puts(insock, "TEST insock");
}
}

/* Handle libcaca events */
if(caca_get_event(dp, CACA_EVENT_KEY_PRESS, &ev, 1000)
&& caca_get_event_key_ch(&ev) == CACA_KEY_ESCAPE)
return 0;

return 1;
}

void client_fini(void)
{
socket_puts(outsock, "QUIT /tmp/neercs.sock.client");

caca_free_display(dp);
caca_free_canvas(cv);
if (insock)
socket_close(insock);
if (outsock)
socket_close(outsock);
}


+ 52
- 0
neercs/old/mini-neercs.c Näytä tiedosto

@@ -0,0 +1,52 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* 2008-2010 Pascal Terjan <pterjan@linuxfr.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#if defined HAVE_CONFIG_H
# include "config.h"
#endif

#include <stdlib.h>
#include <stdio.h> /* perror() */
#include <unistd.h> /* fork() */

#include "mini-neercs.h"

int main(void)
{
pid_t pid;

pid = fork();

if (pid < 0)
{
perror("fork");
return EXIT_FAILURE;
}

if (pid > 0)
{
client_init();
while(client_step()) ;
client_fini();
}
else
{
server_init();
while(server_step()) ;
server_fini();
}

return EXIT_SUCCESS;
}


+ 22
- 0
neercs/old/mini-neercs.h Näytä tiedosto

@@ -0,0 +1,22 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* 2008-2010 Pascal Terjan <pterjan@linuxfr.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

void client_init(void);
int client_step(void);
void client_fini(void);

void server_init(void);
int server_step(void);
void server_fini(void);


+ 80
- 0
neercs/old/mini-server.c Näytä tiedosto

@@ -0,0 +1,80 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2011 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* 2008-2010 Pascal Terjan <pterjan@linuxfr.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#if defined HAVE_CONFIG_H
# include "config.h"
#endif

#include <stdio.h> /* BUFSIZ */
#include <string.h> /* strncmp() */

#include "mini-neercs.h"
#include "mini-socket.h"

static nrx_socket_t *insock, *outsock;

void server_init(void)
{
while (!insock)
insock = socket_open("/tmp/neercs.sock", 1);
}

int server_step(void)
{
char buf[BUFSIZ];
ssize_t bytes;
int ret;

if (outsock)
{
ret = socket_select(outsock, 1000);
if (ret <= 0)
goto nothing;

bytes = socket_read(outsock, buf, BUFSIZ);
if (bytes <= 0)
goto nothing;
}
nothing:

ret = socket_select(insock, 1000);
if (ret <= 0)
return 1;

bytes = socket_read(insock, buf, BUFSIZ);
if (bytes <= 0)
return 1;

/* Parse message */
if (!strncmp(buf, "CONNECT ", strlen("CONNECT ")))
{
outsock = socket_open(buf + strlen("CONNECT "), 0);
socket_puts(outsock, "OK");
}
else if (!strncmp(buf, "QUIT ", strlen("QUIT ")))
{
return 0;
}

return 1;
}

void server_fini(void)
{
if (insock)
socket_close(insock);
if (outsock)
socket_close(outsock);
}


+ 297
- 0
neercs/old/mini-socket.c Näytä tiedosto

@@ -0,0 +1,297 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2011 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* 2008-2010 Pascal Terjan <pterjan@linuxfr.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#if defined HAVE_CONFIG_H
# include "config.h"
#endif

#include <stdio.h> /* perror() */
#include <stdlib.h> /* malloc(), free() */
#include <unistd.h> /* unlink() */
#include <fcntl.h> /* fcntl() */
#include <string.h> /* memcpy() */
#include <sys/select.h> /* select() */
#include <sys/types.h> /* bind(), connect() */
#include <sys/socket.h> /* bind(), connect() */
#include <sys/stat.h> /* stat(), struct stat */
#include <sys/un.h> /* AF_UNIX */
#include <errno.h> /* AF_UNIX */
#include <time.h> /* time */

#include "mini-neercs.h"
#include "mini-socket.h"

#define SIZEOF_SUN_PATH (sizeof(((struct sockaddr_un *)NULL)->sun_path))

#define offsetof(s, f) ((int)(intptr_t)((s *)NULL)->f)

struct nrx_socket
{
#if 1
/* Linux sockets */
int fd;
int server;
int connected;
char path[SIZEOF_SUN_PATH];
#else
# error No socket implementation
#endif
};

#define QLEN 10

int
serv_listen(const char *name)
{
int fd, len, err, rval;
struct sockaddr_un un;

/* create a UNIX domain stream socket */
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
return(-1);
unlink(name); /* in case it already exists */

/* fill in socket address structure */
memset(&un, 0, sizeof(un));
un.sun_family = AF_UNIX;
strcpy(un.sun_path, name);
len = offsetof(struct sockaddr_un, sun_path) + strlen(name);

/* bind the name to the descriptor */
if (bind(fd, (struct sockaddr *)&un, len) < 0) {
rval = -2;
goto errout;
}
if (listen(fd, QLEN) < 0) { /* tell kernel we're a server */
rval = -3;
goto errout;
}
return(fd);

errout:
err = errno;
close(fd);
errno = err;
return(rval);
}

#define STALE 30 /* client's name can't be older than this (sec) */

/*
* Wait for a client connection to arrive, and accept it.
* We also obtain the client's user ID from the pathname
* that it must bind before calling us.
* Returns new fd if all OK, <0 on error
*/
int
serv_accept(int listenfd, uid_t *uidptr)
{
int clifd, len, err, rval;
time_t staletime;
struct sockaddr_un un;
struct stat statbuf;

len = sizeof(un);
if ((clifd = accept(listenfd, (struct sockaddr *)&un, &len)) < 0)
return(-1); /* often errno=EINTR, if signal caught */

/* obtain the client's uid from its calling address */
len -= offsetof(struct sockaddr_un, sun_path); /* len of pathname */
un.sun_path[len] = 0; /* null terminate */

if (stat(un.sun_path, &statbuf) < 0) {
rval = -2;
goto errout;
}
#ifdef S_ISSOCK /* not defined for SVR4 */
if (S_ISSOCK(statbuf.st_mode) == 0) {
rval = -3; /* not a socket */
goto errout;
}
#endif
if ((statbuf.st_mode & (S_IRWXG | S_IRWXO)) ||
(statbuf.st_mode & S_IRWXU) != S_IRWXU) {
rval = -4; /* is not rwx------ */
goto errout;
}

staletime = time(NULL) - STALE;
if (statbuf.st_atime < staletime ||
statbuf.st_ctime < staletime ||
statbuf.st_mtime < staletime) {
rval = -5; /* i-node is too old */
goto errout;
}
if (uidptr != NULL)
*uidptr = statbuf.st_uid; /* return uid of caller */
unlink(un.sun_path); /* we're done with pathname now */
return(clifd);

errout:
err = errno;
close(clifd);
errno = err;
return(rval);
}

#define CLI_PATH "/var/tmp/" /* +5 for pid = 14 chars */
#define CLI_PERM S_IRWXU /* rwx for user only */

/*
* Create a client endpoint and connect to a server.
* Returns fd if all OK, <0 on error.
*/
int
cli_conn(const char *name)
{
int fd, len, err, rval;
struct sockaddr_un un;

/* create a UNIX domain stream socket */
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
return(-1);

/* fill socket address structure with our address */
memset(&un, 0, sizeof(un));
un.sun_family = AF_UNIX;
sprintf(un.sun_path, "%s%05d", CLI_PATH, getpid());
len = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);

unlink(un.sun_path); /* in case it already exists */
if (bind(fd, (struct sockaddr *)&un, len) < 0) {
rval = -2;
goto errout;
}
if (chmod(un.sun_path, CLI_PERM) < 0) {
rval = -3;
goto errout;
}
/* fill socket address structure with server's address */
memset(&un, 0, sizeof(un));
un.sun_family = AF_UNIX;
strcpy(un.sun_path, name);
len = offsetof(struct sockaddr_un, sun_path) + strlen(name);
if (connect(fd, (struct sockaddr *)&un, len) < 0) {
rval = -4;
goto errout;
}
return(fd);

errout:
err = errno;
close(fd);
errno = err;
return(rval);
}

nrx_socket_t * socket_open(char const *path, int server)
{
nrx_socket_t * sock;
struct sockaddr_un addr;
int ret, fd;

#if 0
fd = socket(AF_UNIX, SOCK_STREAM, 0);
//fd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (fd < 0)
{
perror("socket creation");
return NULL;
}

memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, path, SIZEOF_SUN_PATH - 1);

if (server)
{
unlink(path);
ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
}
else
{
ret = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
}

if (ret < 0)
{
perror(server ? "socket binding" : "socket connection");
close(fd);
return NULL;
}

fcntl(fd, F_SETFL, O_NONBLOCK);
#endif
if (server)
fd = serv_listen(path);
else
fd = cli_conn(path);
if (fd < 0) return NULL;

sock = malloc(sizeof(*sock));
sock->fd = fd;
sock->server = server;
sock->connected = 0;
strncpy(sock->path, path, SIZEOF_SUN_PATH - 1);

return sock;
}

int socket_select(nrx_socket_t *sock, int usecs)
{
fd_set rfds;
struct timeval tv;
int ret;

FD_ZERO(&rfds);
FD_SET(sock->fd, &rfds);

tv.tv_sec = usecs / 1000000;
tv.tv_usec = usecs % 1000000;

ret = select(sock->fd + 1, &rfds, NULL, NULL, &tv);
if (ret < 0)
return -1;

if (FD_ISSET(sock->fd, &rfds))
return 1;

return 0;
}

int socket_puts(nrx_socket_t *sock, char const *str)
{
int ret;
fprintf(stderr, "pid %i sending %i bytes on %s: %s\n", getpid(), (int)strlen(str), sock->path, str);
ret = write(sock->fd, str, strlen(str));
return ret;
}

ssize_t socket_read(nrx_socket_t *sock, void *buf, size_t count)
{
int ret;
ret = read(sock->fd, buf, count);
if (ret >= 0) ((char *)buf)[ret] = 0;
if (ret >= 0) fprintf(stderr, "pid %i recving %i bytes on %s: %s\n", getpid(), ret, sock->path, (char *)buf);
return ret;
}

void socket_close(nrx_socket_t *sock)
{
close(sock->fd);
if (sock->server)
unlink(sock->path);
free(sock);
}


+ 24
- 0
neercs/old/mini-socket.h Näytä tiedosto

@@ -0,0 +1,24 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* 2008-2010 Pascal Terjan <pterjan@linuxfr.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include <sys/types.h>

typedef struct nrx_socket nrx_socket_t;

nrx_socket_t * socket_open(char const *path, int server);
int socket_select(nrx_socket_t *sock, int usecs);
int socket_puts(nrx_socket_t *sock, char const *str);
ssize_t socket_read(nrx_socket_t *sock, void *buf, size_t count);
void socket_close(nrx_socket_t *socket);


+ 125
- 0
neercs/old/mygetopt.c Näytä tiedosto

@@ -0,0 +1,125 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

/*
* mygetopt.c: getopt_long reimplementation
*/

#include "config.h"

#include <stdio.h>
#include <string.h>

#include "caca_types.h"

#include "mygetopt.h"

int myoptind = 1;
char *myoptarg = NULL;

/* XXX: this getopt_long implementation should not be trusted for other
applications without any serious peer reviewing. It “just works” with
zzuf but may fail miserably in other programs. */
int mygetopt(int argc, char *const _argv[], const char *optstring,
const struct myoption *longopts, int *longindex)
{
char **argv = (char **)(uintptr_t) _argv;
char *flag;
int i;

if (myoptind >= argc)
return -1;

flag = argv[myoptind];

if (flag[0] == '-' && flag[1] != '-')
{
char *tmp;
int ret = flag[1];

if (ret == '\0')
return -1;

tmp = strchr(optstring, ret);
if (!tmp || ret == ':')
return '?';

myoptind++;
if (tmp[1] == ':')
{
if (flag[2] != '\0')
myoptarg = flag + 2;
else if (myoptind >= argc)
{
if (tmp[2] != ':')
{
fprintf(stderr, "%s: `%s' needs an argument\n", argv[0],
flag);
return -2;
}
}
else
myoptarg = argv[myoptind++];
return ret;
}

if (flag[2] != '\0')
{
flag[1] = '-';
myoptind--;
argv[myoptind]++;
}

return ret;
}

if (flag[0] == '-' && flag[1] == '-')
{
if (flag[2] == '\0')
return -1;

for (i = 0; longopts[i].name; i++)
{
size_t l = strlen(longopts[i].name);

if (strncmp(flag + 2, longopts[i].name, l))
continue;

switch (flag[2 + l])
{
case '=':
if (!longopts[i].has_arg)
goto bad_opt;
if (longindex)
*longindex = i;
myoptind++;
myoptarg = flag + 2 + l + 1;
return longopts[i].val;
case '\0':
if (longindex)
*longindex = i;
myoptind++;
if (longopts[i].has_arg)
myoptarg = argv[myoptind++];
return longopts[i].val;
default:
break;
}
}
bad_opt:
fprintf(stderr, "%s: unrecognized option `%s'\n", argv[0], flag);
return '?';
}

return -1;
}

+ 30
- 0
neercs/old/mygetopt.h Näytä tiedosto

@@ -0,0 +1,30 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

/*
* mygetopt.h: getopt_long reimplementation
*/

struct myoption
{
const char *name;
int has_arg;
int *flag;
int val;
};

extern int myoptind;
extern char *myoptarg;

int mygetopt(int, char * const[], const char *, const struct myoption *, int *);


+ 785
- 0
neercs/old/mytrace.c Näytä tiedosto

@@ -0,0 +1,785 @@
/*
* neercs console-based window manager
* Copyright (c) 2008-2010 Pascal Terjan <pterjan@linuxfr.org>
* 2008-2010 Sam Hocevar <sam@hocevar.net>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"

#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if defined USE_GRAB
# include <sys/ioctl.h>
# include <sys/ptrace.h>
# include <sys/stat.h>
# include <sys/syscall.h>
# include <sys/user.h>
# include <sys/wait.h>
#endif

#include "neercs.h"
#include "mytrace.h"

#if defined USE_GRAB
static int memcpy_from_target(struct mytrace *t,
char *dest, long src, size_t n);
static int memcpy_into_target(struct mytrace *t,
long dest, char const *src, size_t n);
static long remote_syscall(struct mytrace *t, long call,
long arg1, long arg2, long arg3);
# if defined DEBUG
static void print_registers(pid_t pid);
# else
# define print_registers(x) do {} while(0)
# endif

#define X(x) #x
#define STRINGIFY(x) X(x)

#define SYSCALL_X86 0x80cd /* CD 80 = int $0x80 */
#define SYSCALL_X86_NEW 0xf3eb /* EB F3 = jmp <__kernel_vsyscall+0x3> */
#define SYSENTER 0x340f /* 0F 34 = sysenter */
#define SYSCALL_AMD64 0x050fL /* 0F 05 = syscall */

#if defined __x86_64__
# define RAX rax
# define RBX rbx
# define RCX rcx
# define RDX rdx
# define RSP rsp
# define RBP rbp
# define RIP rip
# define RDI rdi
# define RSI rsi
# define FMT "%016lx"
#else
# define RAX eax
# define RBX ebx
# define RCX ecx
# define RDX edx
# define RSP esp
# define RBP ebp
# define RIP eip
# define RDI edi
# define RSI esi
# define FMT "%08lx"
#endif

#define MYCALL_OPEN 0
#define MYCALL_CLOSE 1
#define MYCALL_WRITE 2
#define MYCALL_DUP2 3
#define MYCALL_SETPGID 4
#define MYCALL_SETSID 5
#define MYCALL_KILL 6
#define MYCALL_FORK 7
#define MYCALL_EXIT 8
#define MYCALL_EXECVE 9
#define MYCALL_IOCTL 10

#if defined __x86_64__
/* from unistd_32.h on an amd64 system */
int syscalls32[] = { 5, 6, 4, 63, 57, 66, 37, 2, 1, 11, 54 };

int syscalls64[] =
#else
int syscalls32[] =
#endif
{ SYS_open, SYS_close, SYS_write, SYS_dup2, SYS_setpgid, SYS_setsid,
SYS_kill, SYS_fork, SYS_exit, SYS_execve, SYS_ioctl
};

char const *syscallnames[] =
{ "open", "close", "write", "dup2", "setpgid", "setsid", "kill", "fork",
"exit", "execve", "ioctl"
};

#endif /* USE_GRAB */

struct mytrace
{
pid_t pid, child;
};

struct mytrace *mytrace_attach(long int pid)
{
#if defined USE_GRAB
struct mytrace *t;
int status;

if (ptrace(PTRACE_ATTACH, pid, 0, 0) < 0)
{
perror("PTRACE_ATTACH (attach)");
return NULL;
}
if (waitpid(pid, &status, 0) < 0)
{
perror("waitpid");
return NULL;
}
if (!WIFSTOPPED(status))
{
fprintf(stderr, "traced process was not stopped\n");
ptrace(PTRACE_DETACH, pid, 0, 0);
return NULL;
}

t = malloc(sizeof(struct mytrace));
t->pid = pid;
t->child = 0;

return t;
#else
errno = ENOSYS;
return NULL;
#endif
}

struct mytrace *mytrace_fork(struct mytrace *t)
{
#if defined USE_GRAB
struct mytrace *child;

ptrace(PTRACE_SETOPTIONS, t->pid, NULL, PTRACE_O_TRACEFORK);
remote_syscall(t, MYCALL_FORK, 0, 0, 0);
waitpid(t->child, NULL, 0);

child = malloc(sizeof(struct mytrace));
child->pid = t->child;
child->child = 0;

return child;
#else
errno = ENOSYS;
return NULL;
#endif
}

int mytrace_detach(struct mytrace *t)
{
#if defined USE_GRAB
ptrace(PTRACE_DETACH, t->pid, 0, 0);
free(t);

return 0;
#else
errno = ENOSYS;
return -1;
#endif
}

long mytrace_getpid(struct mytrace *t)
{
#if defined USE_GRAB
return t->pid;
#else
errno = ENOSYS;
return -1;
#endif
}

int mytrace_open(struct mytrace *t, char const *path, int mode)
{
#if defined USE_GRAB
char backup_data[4096];
struct user_regs_struct regs;
size_t size = strlen(path) + 1;
int ret, err;

if (ptrace(PTRACE_GETREGS, t->pid, NULL, &regs) < 0)
{
perror("PTRACE_GETREGS (open)\n");
return -1;
}

/* Backup the data that we will use */
if (memcpy_from_target(t, backup_data, regs.RSP, size) < 0)
return -1;

memcpy_into_target(t, regs.RSP, path, size);

ret = remote_syscall(t, MYCALL_OPEN, regs.RSP, O_RDWR, 0755);
err = errno;

/* Restore the data */
memcpy_into_target(t, regs.RSP, backup_data, size);

errno = err;
return ret;
#else
errno = ENOSYS;
return -1;
#endif
}

int mytrace_close(struct mytrace *t, int fd)
{
#if defined USE_GRAB
return remote_syscall(t, MYCALL_CLOSE, fd, 0, 0);
#else
errno = ENOSYS;
return -1;
#endif
}

int mytrace_write(struct mytrace *t, int fd, char const *data, size_t len)
{
#if defined USE_GRAB
struct user_regs_struct regs;
char *backup_data;
int ret, err;

if (ptrace(PTRACE_GETREGS, t->pid, NULL, &regs) < 0)
{
perror("PTRACE_GETREGS (write)\n");
return -1;
}

backup_data = malloc(len);

/* Backup the data that we will use */
if (memcpy_from_target(t, backup_data, regs.RSP, len) < 0)
return -1;

memcpy_into_target(t, regs.RSP, data, len);

ret = remote_syscall(t, MYCALL_WRITE, fd, regs.RSP, len);
err = errno;

/* Restore the data */
memcpy_into_target(t, regs.RSP, backup_data, len);

errno = err;
return ret;
#else
errno = ENOSYS;
return -1;
#endif
}

int mytrace_dup2(struct mytrace *t, int oldfd, int newfd)
{
#if defined USE_GRAB
return remote_syscall(t, MYCALL_DUP2, oldfd, newfd, 0);
#else
errno = ENOSYS;
return -1;
#endif
}

int mytrace_setpgid(struct mytrace *t, long pid, long pgid)
{
#if defined USE_GRAB
return remote_syscall(t, MYCALL_SETPGID, pid, pgid, 0);
#else
errno = ENOSYS;
return -1;
#endif
}

int mytrace_setsid(struct mytrace *t)
{
#if defined USE_GRAB
return remote_syscall(t, MYCALL_SETSID, 0, 0, 0);
#else
errno = ENOSYS;
return -1;
#endif
}

int mytrace_kill(struct mytrace *t, long pid, int sig)
{
#if defined USE_GRAB
return remote_syscall(t, MYCALL_KILL, pid, sig, 0);
#else
errno = ENOSYS;
return -1;
#endif
}

int mytrace_exit(struct mytrace *t, int status)
{
#if defined USE_GRAB
ptrace(PTRACE_SETOPTIONS, t->pid, NULL, PTRACE_O_TRACEEXIT);
return remote_syscall(t, MYCALL_EXIT, status, 0, 0);
#else
errno = ENOSYS;
return -1;
#endif
}

int mytrace_exec(struct mytrace *t, char const *command)
{
#if defined USE_GRAB
struct user_regs_struct regs;
char *env, *p;
long p2, envaddr, argvaddr, envptraddr;
char envpath[PATH_MAX + 1];
ssize_t envsize = 16 * 1024;
int ret, fd, l, l2;
char *nullp = NULL;
ssize_t r;

ptrace(PTRACE_SETOPTIONS, t->pid, NULL, PTRACE_O_TRACEEXEC);

if (ptrace(PTRACE_GETREGS, t->pid, NULL, &regs) < 0)
{
perror("PTRACE_GETREGS (exec)\n");
return -1;
}

debug("PTRACE_GETREGS done");
env = malloc(envsize);
if (!env)
return -1;

snprintf(envpath, PATH_MAX, "/proc/%d/environ", t->pid);

fd = open(envpath, O_RDONLY);
if (fd == -1)
return -1;
r = read(fd, env, envsize);
close(fd);
if (r == -1)
return -1;
while (r == envsize)
{
free(env);
env = malloc(envsize);
if (!env)
return -1;
fd = open(envpath, O_RDONLY);
r = read(fd, env, envsize);
close(fd);
if (r == -1)
return -1;
}
envsize = r;
l2 = sizeof(char *); /* Size of a pointer */
p2 = regs.RSP;

/* First argument is the command string */
l = strlen(command) + 1;
memcpy_into_target(t, p2, command, l);
p2 += l;

/* Second argument is argv */
argvaddr = p2;
/* argv[0] is a pointer to the command string */
memcpy_into_target(t, p2, (char *)&regs.RSP, l2);
p2 += l2;
/* Then follows a NULL pointer */
memcpy_into_target(t, p2, (char *)&nullp, l2);
p2 += l2;

/* Third argument is the environment */
/* First, copy all the strings */
memcpy_into_target(t, p2, env, envsize);
envaddr = p2;
p2 += envsize;
/* Then write an array of pointers to the strings */
envptraddr = p2;
p = env;
while (p < env + envsize)
{
long diffp = p - env + envaddr;
memcpy_into_target(t, p2, (char *)&diffp, l2);
p2 += l2;
p += strlen(p) + 1;
}
/* And have a NULL pointer at the end of the array */
memcpy_into_target(t, p2, (char *)&nullp, l2);
free(env);

ret = remote_syscall(t, MYCALL_EXECVE, regs.RSP, argvaddr, envptraddr);

return ret;
#else
errno = ENOSYS;
return -1;
#endif
}

int mytrace_tcgets(struct mytrace *t, int fd, struct termios *tos)
{
#if defined USE_GRAB
char backup_data[4096];
struct user_regs_struct regs;
size_t size = sizeof(struct termios);
int ret, err;

if (ptrace(PTRACE_GETREGS, t->pid, NULL, &regs) < 0)
{
perror("PTRACE_GETREGS (tcgets)\n");
return -1;
}

/* Backup the data that we will use */
if (memcpy_from_target(t, backup_data, regs.RSP, size) < 0)
return -1;

ret = remote_syscall(t, MYCALL_IOCTL, fd, TCGETS, regs.RSP);
err = errno;

memcpy_from_target(t, (char *)tos, regs.RSP, size);

/* Restore the data */
memcpy_into_target(t, regs.RSP, backup_data, size);

errno = err;
return ret;
#else
errno = ENOSYS;
return -1;
#endif
}

int mytrace_tcsets(struct mytrace *t, int fd, struct termios *tos)
{
#if defined USE_GRAB
char backup_data[4096];
struct user_regs_struct regs;
size_t size = sizeof(struct termios);
int ret, err;

if (ptrace(PTRACE_GETREGS, t->pid, NULL, &regs) < 0)
{
perror("PTRACE_GETREGS (tcsets)\n");
return -1;
}

/* Backup the data that we will use */
if (memcpy_from_target(t, backup_data, regs.RSP, size) < 0)
return -1;

memcpy_into_target(t, regs.RSP, (char *)tos, size);

ret = remote_syscall(t, MYCALL_IOCTL, fd, TCSETS, regs.RSP);
err = errno;

/* Restore the data */
memcpy_into_target(t, regs.RSP, backup_data, size);

errno = err;
return ret;
#else
errno = ENOSYS;
return -1;
#endif
}

int mytrace_sctty(struct mytrace *t, int fd)
{
#if defined USE_GRAB
ptrace(PTRACE_SETOPTIONS, t->pid, NULL, PTRACE_O_TRACEEXIT);
return remote_syscall(t, MYCALL_IOCTL, fd, TIOCSCTTY, 0);
#else
errno = ENOSYS;
return -1;
#endif
}

/*
* XXX: the following functions are local
*/

#if defined USE_GRAB
static int memcpy_from_target(struct mytrace *t,
char *dest, long src, size_t n)
{
static int const align = sizeof(long) - 1;

while (n)
{
long data;
size_t todo = sizeof(long) - (src & align);

if (n < todo)
todo = n;

data = ptrace(PTRACE_PEEKTEXT, t->pid, src - (src & align), 0);
if (errno)
{
perror("ptrace_peektext (memcpy_from_target)");
return -1;
}
memcpy(dest, (char *)&data + (src & align), todo);

dest += todo;
src += todo;
n -= todo;
}

return 0;
}

static int memcpy_into_target(struct mytrace *t,
long dest, char const *src, size_t n)
{
static int const align = sizeof(long) - 1;

while (n)
{
long data;
size_t todo = sizeof(long) - (dest & align);

if (n < todo)
todo = n;
if (todo != sizeof(long))
{
data = ptrace(PTRACE_PEEKTEXT, t->pid, dest - (dest & align), 0);
if (errno)
{
perror("ptrace_peektext (memcpy_into_target)");
return -1;
}
}

memcpy((char *)&data + (dest & align), src, todo);
if (ptrace(PTRACE_POKETEXT, t->pid, dest - (dest & align), data) < 0)
{
perror("ptrace_poketext (memcpy_into_target)");
return -1;
}

src += todo;
dest += todo;
n -= todo;
}

return 0;
}

static long remote_syscall(struct mytrace *t, long call,
long arg1, long arg2, long arg3)
{
/* Method for remote syscall: - wait until the traced application exits
from a syscall - save registers - rewind eip/rip to point on the
syscall instruction - single step: execute syscall instruction -
retrieve resulting registers - restore registers */
struct user_regs_struct regs, oldregs;
long oinst;
int bits;
int offset = 2;

if (call < 0
|| call >= (long)(sizeof(syscallnames) / sizeof(*syscallnames)))
{
fprintf(stderr, "unknown remote syscall %li\n", call);
return -1;
}

debug("remote syscall %s(0x%lx, 0x%lx, 0x%lx)",
syscallnames[call], arg1, arg2, arg3);

#if defined __x86_64__
bits = 64;
#else
bits = 32;
#endif

for (;;)
{
if (ptrace(PTRACE_GETREGS, t->pid, NULL, &oldregs) < 0)
{
perror("PTRACE_GETREGS (syscall 1)\n");
return -1;
}

oinst = ptrace(PTRACE_PEEKTEXT, t->pid, oldregs.RIP - 2, 0) & 0xffff;

#if defined __x86_64__
if (oinst == SYSCALL_AMD64)
break;
#endif
if (oinst == SYSCALL_X86 || oinst == SYSCALL_X86_NEW)
{
bits = 32;
break;
}

if (ptrace(PTRACE_SYSCALL, t->pid, NULL, 0) < 0)
{
perror("ptrace_syscall (1)");
return -1;
}
waitpid(t->pid, NULL, 0);
if (ptrace(PTRACE_SYSCALL, t->pid, NULL, 0) < 0)
{
perror("ptrace_syscall (2)");
return -1;
}
waitpid(t->pid, NULL, 0);
}

print_registers(t->pid);

if (oinst == SYSCALL_X86_NEW)
{
/* Get back to sysenter */
while ((ptrace(PTRACE_PEEKTEXT, t->pid, oldregs.RIP - offset, 0) &
0xffff) != 0x340f)
offset++;
oldregs.RBP = oldregs.RSP;
}

regs = oldregs;
regs.RIP = regs.RIP - offset;
#if defined __x86_64__
if (bits == 64)
{
regs.RAX = syscalls64[call];
regs.RDI = arg1;
regs.RSI = arg2;
regs.RDX = arg3;
}
else
#endif
{
regs.RAX = syscalls32[call];
regs.RBX = arg1;
regs.RCX = arg2;
regs.RDX = arg3;
}

if (ptrace(PTRACE_SETREGS, t->pid, NULL, &regs) < 0)
{
perror("PTRACE_SETREGS (syscall 1)\n");
return -1;
}

for (;;)
{
int status;

print_registers(t->pid);

if (ptrace(PTRACE_SINGLESTEP, t->pid, NULL, NULL) < 0)
{
perror("PTRACE_SINGLESTEP (syscall)\n");
return -1;
}
waitpid(t->pid, &status, 0);

if (WIFEXITED(status))
return 0;

if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGTRAP)
continue;

/* Fuck Linux: there is no macro for this */
switch ((status >> 16) & 0xffff)
{
case PTRACE_EVENT_FORK:
if (ptrace(PTRACE_GETEVENTMSG, t->pid, 0, &t->child) < 0)
{
perror("PTRACE_GETEVENTMSG (syscall)\n");
return -1;
}
debug("PTRACE_GETEVENTMSG %d", t->child);
continue;
case PTRACE_EVENT_EXIT:
debug("PTRACE_EVENT_EXIT");
/* The process is about to exit, don't do anything else */
return 0;
case PTRACE_EVENT_EXEC:
debug("PTRACE_EVENT_EXEC");
return 0;
}

break;
}

print_registers(t->pid);

if (ptrace(PTRACE_GETREGS, t->pid, NULL, &regs) < 0)
{
perror("PTRACE_GETREGS (syscall 2)\n");
return -1;
}

if (ptrace(PTRACE_SETREGS, t->pid, NULL, &oldregs) < 0)
{
perror("PTRACE_SETREGS (syscall 2)\n");
return -1;
}
print_registers(t->pid);

debug("syscall %s returned %ld", syscallnames[call], regs.RAX);

if ((long)regs.RAX < 0)
{
errno = -(long)regs.RAX;
perror("syscall");
return -1;
}

return regs.RAX;
}

/* For debugging purposes only. Prints register and stack information. */
#if defined DEBUG
static void print_registers(pid_t pid)
{
union
{
long int l;
unsigned char data[sizeof(long int)];
} inst;
struct user_regs_struct regs;
int i;

if (ptrace(PTRACE_GETREGS, pid, NULL, &regs) < 0)
{
perror("PTRACE_GETREGS (syscall 2)");
exit(errno);
}

fprintf(stderr, " / %s: " FMT " ", STRINGIFY(RAX), regs.RAX);
fprintf(stderr, "%s: " FMT "\n", STRINGIFY(RBX), regs.RBX);
fprintf(stderr, " | %s: " FMT " ", STRINGIFY(RCX), regs.RCX);
fprintf(stderr, "%s: " FMT "\n", STRINGIFY(RDX), regs.RDX);
fprintf(stderr, " | %s: " FMT " ", STRINGIFY(RDI), regs.RDI);
fprintf(stderr, "%s: " FMT "\n", STRINGIFY(RSI), regs.RSI);
fprintf(stderr, " | %s: " FMT " ", STRINGIFY(RSP), regs.RSP);
fprintf(stderr, "%s: " FMT "\n", STRINGIFY(RIP), regs.RIP);

inst.l = ptrace(PTRACE_PEEKTEXT, pid, regs.RIP - 4, 0);
fprintf(stderr, " | code: ... %02x %02x %02x %02x <---> ",
inst.data[0], inst.data[1], inst.data[2], inst.data[3]);
inst.l = ptrace(PTRACE_PEEKTEXT, pid, regs.RIP, 0);
fprintf(stderr, "%02x %02x %02x %02x ...\n",
inst.data[0], inst.data[1], inst.data[2], inst.data[3]);

fprintf(stderr, " \\ stack: ... ");
for (i = -16; i < 24; i += sizeof(long))
{
inst.l = ptrace(PTRACE_PEEKDATA, pid, regs.RSP + i, 0);
#if defined __x86_64__
fprintf(stderr, "%02x %02x %02x %02x %02x %02x %02x %02x ",
inst.data[0], inst.data[1], inst.data[2], inst.data[3],
inst.data[4], inst.data[5], inst.data[6], inst.data[7]);
#else
fprintf(stderr, "%02x %02x %02x %02x ",
inst.data[0], inst.data[1], inst.data[2], inst.data[3]);
#endif
if (i == 0)
fprintf(stderr, "[%s] ", STRINGIFY(RSP));
}
fprintf(stderr, "...\n");
}
#endif /* DEBUG */

#endif /* USE_GRAB */

+ 33
- 0
neercs/old/mytrace.h Näytä tiedosto

@@ -0,0 +1,33 @@
/*
* neercs console-based window manager
* Copyright (c) 2008-2010 Sam Hocevar <sam@hocevar.net>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include <termios.h>

struct mytrace;

struct mytrace* mytrace_attach(long int pid);
struct mytrace* mytrace_fork(struct mytrace *t);
int mytrace_detach(struct mytrace *t);
long mytrace_getpid(struct mytrace *t);

int mytrace_open(struct mytrace *t, char const *path, int mode);
int mytrace_write(struct mytrace *t, int fd, char const *data, size_t len);
int mytrace_close(struct mytrace *t, int fd);
int mytrace_dup2(struct mytrace *t, int oldfd, int newfd);
int mytrace_setpgid(struct mytrace *t, long pid, long pgid);
int mytrace_setsid(struct mytrace *t);
int mytrace_kill(struct mytrace *t, long pid, int sig);
int mytrace_exit(struct mytrace *t, int status);
int mytrace_exec(struct mytrace *t, char const *command);
int mytrace_tcgets(struct mytrace *t, int fd, struct termios *tos);
int mytrace_tcsets(struct mytrace *t, int fd, struct termios *tos);
int mytrace_sctty(struct mytrace *t, int fd);

+ 430
- 0
neercs/old/neercs.h Näytä tiedosto

@@ -0,0 +1,430 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#ifndef _NEERCS_H_
#define _NEERCS_H_

#include <stdint.h>
#include <caca.h>

#include "widgets.h"

enum wm_types
{
WM_FULL,
WM_CARD,
WM_HSPLIT,
WM_VSPLIT,

WM_MAX,
};

enum mouse_report
{
MOUSE_NONE,
MOUSE_X10,
MOUSE_VT200,
MOUSE_VT200_HIGHLIGHT,
MOUSE_BTN_EVENT,
MOUSE_ANY_EVENT,
};


/* ISO-2022 Conversion State */
struct iso2022_conv_state
{
/* cs = coding system/coding method: */
/* (with standard return) */
/* '@' = ISO-2022, */
/* 'G' = UTF-8 without implementation level, */
/* '8' = UTF-8 (Linux console and imitators), */
/* and many others that are rarely used; */
/* (without standard return) */
/* '/G' = UTF-8 Level 1, */
/* '/H' = UTF-8 Level 2, */
/* '/I' = UTF-8 Level 3, */
/* and many others that are rarely used */
uint32_t cs;
/* ctrl8bit = allow 8-bit controls */
uint8_t ctrl8bit;
/* cn[0] = C0 control charset (0x00 ... 0x1f):
* '@' = ISO 646,
* '~' = empty,
* and many others that are rarely used */
/* cn[1] = C1 control charset (0x80 ... 0x9f):
* 'C' = ISO 6429-1983,
* '~' = empty,
* and many others that are rarely used */
uint32_t cn[2];
/* glr[0] = GL graphic charset (94-char. 0x21 ... 0x7e,
* 94x94-char. 0x21/0x21 ... 0x7e/0x7e),
* and
* glr[1] = GR graphic charset (94-char. 0xa1 ... 0xfe,
* 96-char. 0xa0 ... 0xff,
* 94x94-char. 0xa1/0xa1 ... 0xfe/0xfe,
* 96x96-char. 0xa0/0xa0 ... 0xff/0xff):
* 0 = G0, 1 = G1, 2 = G2, 3 = G3 */
uint8_t glr[2];
/* gn[i] = G0/G1/G2/G3 graphic charset state:
* (94-char. sets)
* '0' = DEC ACS (VT100 and imitators),
* 'B' = US-ASCII,
* and many others that are rarely used for e.g. various national ASCII variations;
* (96-char. sets)
* '.A' = ISO 8859-1 "Latin 1" GR,
* '.~' = empty 96-char. set,
* and many others that are rarely used for e.g. ISO 8859-n GR;
* (double-byte 94x94-charsets)
* '$@' = Japanese Character Set ("old JIS") (JIS C 6226:1978),
* '$A' = Chinese Character Set (GB 2312),
* '$B' = Japanese Character Set (JIS X0208/JIS C 6226:1983),
* '$C' = Korean Graphic Character Set (KSC 5601:1987),
* '$D' = Supplementary Japanese Graphic Character Set (JIS X0212),
* '$E' = CCITT Chinese Set (GB 2312 + GB 8565),
* '$G' = CNS 11643 plane 1,
* '$H' = CNS 11643 plane 2,
* '$I' = CNS 11643 plane 3,
* '$J' = CNS 11643 plane 4,
* '$K' = CNS 11643 plane 5,
* '$L' = CNS 11643 plane 6,
* '$M' = CNS 11643 plane 7,
* '$O' = JIS X 0213 plane 1,
* '$P' = JIS X 0213 plane 2,
* '$Q' = JIS X 0213-2004 Plane 1,
* and many others that are rarely used for e.g. traditional
* ideographic Vietnamese and BlissSymbolics;
* (double-byte 96x96-charsets)
* none standardized or in use on terminals AFAIK (Mule does use
* some internally)
*/
uint32_t gn[4];
/* ss = single-shift state: 0 = GL, 2 = G2, 3 = G3 */
uint8_t ss;
};

struct screen
{
/* Graphics stuff */
int init;
caca_canvas_t *cv;
uint32_t clearattr;
uint8_t fg, bg; /* ANSI-context fg/bg */
uint8_t dfg, dbg; /* Default fg/bg */
uint8_t bold, blink, italics, negative, concealed, underline;
uint8_t faint, strike, proportional; /* unsupported */
struct iso2022_conv_state conv_state; /* charset mess */

/* Other stuff */
int visible; /* Draw canvas and border flag */
int fd; /* pty fd */
unsigned char *buf; /* text buffer */
long int total; /* buffer length */
char *title; /* tty title */
int bell; /* bell occuring */
unsigned int scroll, s1, s2; /* FIXME, ANSI scroll properties */
int pid; /* running program pid */
int changed; /* content was updated */

int x, y; /* Canvas position */
int w, h; /* Canvas size */

int orig_x, orig_y; /* Used by recurrents */
int orig_w, orig_h; /* Used by recurrents */

int report_mouse; /* ANSI */
};

enum socket_type
{
SOCK_SERVER=0,
SOCK_CLIENT=1
};

struct cube_props
{
int in_switch;
int side;
long long unsigned int duration;
};

struct interpreter_props
{
/* Input box */
struct input_box *box;
};

struct screensaver
{
/* ScreenSaver stuff */
long long unsigned int timeout; /* Screensaver timeout in us */
int in_screensaver;
void *data;
};

struct comm
{
/* Detaching */
int attached; /* Are we attached to a terminal or a server */
int socket[2]; /* Sockets to write to the server / to the client */
char *socket_path[2]; /* Sockets to write to the server / to the client */
char *socket_dir; /* Where to create the socket */
char *session_name; /* Name of the session */
};

struct lock
{
int locked;
int lock_offset;
int lock_on_detach;
long long unsigned int autolock_timeout;
char lockpass[1024];
char lockmsg[1024];
};

struct modals
{
/* Add-ons*/
int mini; /* Thumbnails */
int status; /* Status bar */
int help; /* Help */
int python_command; /* Python command */
int window_list; /* Window list */
int cur_in_list; /* Window list */
};

struct sys
{
char *default_shell;
char *user_path;
int *to_grab;
char **to_start;
int nb_to_grab;
int attach, forceattach;
};

struct screen_list
{
int outfd; /* Debug */
int in_bell; /* Bell occuring in a window */
int was_in_bell;
int dont_update_coords; /* Used by recurrents */
int changed; /* Global redraw (e.g. adding a screen) */
int delay; /* Minimal time between two refresh (ms) */
int requested_delay;
int force_refresh;
int need_refresh; /* If we skipped a refresh, do it next time */
int command;
int eyecandy; /* Eye Candy */

long long unsigned int last_key_time;
long long unsigned int last_refresh_time;

struct comm comm; /* Client/Server communications */
struct lock lock; /* Lock */
struct modals modals; /* Modal windows */
struct interpreter_props interpreter_props; /* Python interpreter */
struct screensaver screensaver;/* Screensaver stuff */

int pty, prevpty; /* Current and previous window */
int count; /* Window count */
int wm_type; /* Window manager type */
int border_size; /* Borders */
struct cube_props cube; /* Cube */
long long unsigned int last_switch; /* Cube */

struct screen **screen; /* Windows */
struct option *config; /* Option parsing and configuration */
struct sys sys; /* System stuff */

struct recurrent_list *recurrent_list; /* Recurrents functions */

char *title; /* Window title */
int width, height; /* caca window size */
int old_x, old_y; /* Mouse */
int mouse_button;
caca_canvas_t *cv;
caca_display_t *dp;
};

/* Configuration */
struct option
{
char *key;
char *value;

struct option *next;
};
struct config_line
{
const char name[32];
int (*set) (const char *argv, struct screen_list * screen_list);
char* (*get) (struct screen_list * screen_list);
};

/* Recurrents */
struct recurrent
{
int (*function)(struct screen_list*, struct recurrent* rec, void *user, long long unsigned int t);
void *user;
long long unsigned int start_time;
int kill_me;
};

struct recurrent_list
{
int count;
struct recurrent **recurrent;
};



void version(void);
void usage(int argc, char **argv);
struct screen_list *init_neercs(int argc, char **argv);

int handle_command_line(int argc, char *argv[], struct screen_list *screen_list);

struct screen_list *create_screen_list(void);
void free_screen_list(struct screen_list *screen_list);

int start_client(struct screen_list * screen_list);
/** \defgroup client neercs client
* @{ */
void mainloop(struct screen_list *screen_list);
int mainloop_tick(char **pbuf, struct screen_list *screen_list);
/** }@ */


int create_pty(char *cmd, unsigned int w, unsigned int h, int *cpid);
int create_pty_grab(long pid, unsigned int w, unsigned int h, int *cpid);
int grab_process(long pid, char *ptyname, int ptyfd, int *newpid);
long select_process(struct screen_list* screen_list);

long int import_term(struct screen_list *screen_list, struct screen *sc, void const *data, unsigned int size);
int set_tty_size(int fd, unsigned int w, unsigned int h);
int update_terms(struct screen_list* screen_list);
void refresh_screens(struct screen_list *screen_list);
int update_screens_contents(struct screen_list* screen_list);
int install_fds(struct screen_list *screen_list);
long long get_us(void);

void attach(struct screen_list* screen_list);
int detach(struct screen_list* screen_list);
int request_attach(struct screen_list* screen_list);
char * build_socket_path(char *socket_dir, char *session_name, enum socket_type socktype);
int create_socket(struct screen_list* screen_list, enum socket_type socktype);
char * connect_socket(struct screen_list* screen_list, enum socket_type socktype);
char ** list_sockets(char *socket_dir, char *session_name);
int start_server(struct screen_list *screen_list);
int send_event(caca_event_t ev, struct screen_list* screen_list);
int send_delay(struct screen_list* screen_list);
int send_ansi_sequence(struct screen_list *screen_list, char *str);

/* Screens management */
struct screen* create_screen(int w, int h, char *command);
struct screen* create_screen_grab(int w, int h, int pid);
int destroy_screen(struct screen *s);
int add_screen(struct screen_list *list, struct screen *s);
int remove_screen(struct screen_list *list, int n, int please_kill);
void resize_screen(struct screen *s, int z, int h);

/* Window managers */
void update_windows_props(struct screen_list *screen_list);
void update_windows_props_cards(struct screen_list *screen_list);
void update_windows_props_hsplit(struct screen_list *screen_list);
void update_windows_props_full(struct screen_list *screen_list);
void update_windows_props_vsplit(struct screen_list *screen_list);
void update_windows_props_cube(struct screen_list *screen_list);

void wm_refresh(struct screen_list *screen_list);
void wm_refresh_card(struct screen_list *screen_list);
void wm_refresh_cube(struct screen_list *screen_list);
void wm_refresh_full(struct screen_list *screen_list);
void wm_refresh_hsplit(struct screen_list *screen_list);
void wm_refresh_vsplit(struct screen_list *screen_list);
int switch_screen_recurrent(struct screen_list* screen_list, struct recurrent* rec, void *user, long long unsigned int t);


/* Effects and addons */
void draw_thumbnails(struct screen_list *screen_list);
void draw_status(struct screen_list *screen_list);
void draw_help(struct screen_list *screen_list);
int help_handle_key(struct screen_list *screen_list, unsigned int c);
int update_window_list(int c, struct screen_list *screen_list);
void draw_list(struct screen_list *screen_list);
void draw_lock(struct screen_list *screen_list);
int update_lock(int c, struct screen_list *screen_list);
int validate_lock(struct screen_list *screen_list, char *user, char *pass);

int close_screen_recurrent(struct screen_list*, struct recurrent* rec, void *user, long long unsigned int t);

/* Input to ANSI */
void *convert_input_ansi(unsigned int *c, int *size);
int handle_command_input(struct screen_list*screen_list, unsigned int c);


/* Screensavers */
void screensaver_init(struct screen_list *screen_list);
void screensaver_kill(struct screen_list *screen_list);

void draw_screensaver(struct screen_list *screen_list);
void screensaver_flying_toasters(struct screen_list *screen_list);

void screensaver_flying_toasters_init(struct screen_list *screen_list);

void screensaver_flying_toasters_kill(struct screen_list *screen_list);

/* Actions */
void dump_to_file(struct screen_list *screen_list);

/* Recurrents */
int handle_recurrents(struct screen_list* screen_list);
int add_recurrent(struct recurrent_list *list,
int (*function)(struct screen_list*, struct recurrent* rec, void *user, long long unsigned int t),
void *user);
int remove_recurrent(struct recurrent_list *list, int n);



/* Configuration file */
int read_configuration_file(char *filename, struct screen_list *screen_list);
int parse_conf_line(char *buf, int size, struct screen_list *screen_list);
int get_key_value(char *line, struct option *option);
int fill_config(struct screen_list *screen_list);
struct config_line *get_config(const char *name);
struct config_line *get_config_option(void);

/* Python interpreter */
#ifdef USE_PYTHON
int python_init(struct screen_list *sl);
int python_close(struct screen_list *sl);
int python_command_handle_key(struct screen_list *screen_list, unsigned int c);
void draw_python_command(struct screen_list *screen_list);
#endif

#if defined DEBUG
# include <stdio.h>
# include <stdarg.h>
static inline void debug(const char *format, ...)
{
va_list args;
va_start(args, format);
fprintf(stderr, "** neercs debug ** ");
vfprintf(stderr, format, args);
fprintf(stderr, "\n");
va_end(args);
}
#else
# define debug(format, ...) do {} while(0)
#endif
#endif /* _NEERCS_H_ */

+ 197
- 0
neercs/old/python/interpreter.c Näytä tiedosto

@@ -0,0 +1,197 @@
/*
* neercs console-based window manager
* Copyright (c) 2009-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"

#ifdef USE_PYTHON

#include <Python.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <fcntl.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <time.h>
#include <sys/wait.h>
#include <sys/types.h>

#include <caca.h>

#include "neercs.h"
#include "py_module.h"

static int python_execute(struct screen_list *sl);
char *getStringFromPyObject(PyObject * p);
static char *getPythonError(void);

#if ! defined HAVE_PYTHON26
static PyObject *PyUnicode_FromString(char const *str)
{
PyObject *tmp, *ret;
tmp = PyString_FromString(str);
if (!tmp)
return NULL;
ret = PyString_AsDecodedObject(tmp, "utf-8", "replace");
Py_DECREF(tmp);
return ret;
}
#endif

int python_command_handle_key(struct screen_list *screen_list, unsigned int c)
{
int ret = widget_ibox_handle_key(screen_list->interpreter_props.box, c);

if (ret == INPUT_BOX_ESC)
{
widget_ibox_destroy(screen_list->interpreter_props.box);
screen_list->interpreter_props.box = NULL;
screen_list->modals.python_command = 0;
}
else if (ret == INPUT_BOX_RET)
{
python_execute(screen_list);
}
screen_list->changed = 1;

return 1;
}

void draw_python_command(struct screen_list *screen_list)
{
if (!screen_list->interpreter_props.box)
{
screen_list->interpreter_props.box =
widget_ibox_init(screen_list->cv, 65, 6);
debug("py Init %p\n", screen_list->interpreter_props.box);
}
widget_ibox_draw(screen_list->interpreter_props.box);
}

/* Actual Python interpreter stuff */
int python_init(struct screen_list *sl)
{
initNeercsModule(sl);

return 0;
}

int python_close(struct screen_list *sl)
{
widget_ibox_destroy(sl->interpreter_props.box);
sl->interpreter_props.box = NULL;

Py_Finalize();
return 0;
}


static int python_execute(struct screen_list *sl)
{
char *command = widget_ibox_get_text(sl->interpreter_props.box);
if (!command || strlen(command) < 1)
return -1;
int err = 0;

debug("py Executing '%s'\n", command);


PyObject *pModule, *pName;

/* Module from which to call the function */
pName = PyUnicode_FromString("neercs");
if (!pName)
{
widget_ibox_set_error(sl->interpreter_props.box, getPythonError());
err = 1;
debug("py Error 1\n");
goto end;
}

pModule = PyImport_Import(pName);
Py_DECREF(pName);

if (pModule != NULL)
{
PyObject *dictionary = PyModule_GetDict(pModule);

getExportedValues(dictionary);

PyObject *o =
PyRun_String(command, Py_single_input,
dictionary, NULL);
if (!o)
{
widget_ibox_set_error(sl->interpreter_props.box, getPythonError());
err = 1;
}
else
{
setExportedValues(dictionary);

widget_ibox_set_msg(sl->interpreter_props.box, getStringFromPyObject(o));
err = 1;
}

Py_DECREF(pModule);
}
else
{
widget_ibox_set_error(sl->interpreter_props.box, getPythonError());
err = 1;
}

end:

if (!err)
{
widget_ibox_destroy(sl->interpreter_props.box);
sl->interpreter_props.box = NULL;
sl->modals.python_command = 0;
}
sl->changed = 1;

return 0;
}

static char *getPythonError(void)
{
char *err;
PyObject *type, *value, *traceback;
PyErr_Fetch(&type, &value, &traceback);

char *evalue = getStringFromPyObject(value);

int r = asprintf(&err, "%s", evalue);
(void)r;
return err;
}

char *getStringFromPyObject(PyObject * p)
{
PyObject *str = PyObject_Repr(p);
char *tmp;
#if defined HAVE_PYTHON26
tmp = PyBytes_AS_STRING(PyUnicode_AsEncodedString(str, "utf-8", "Error ~"));
#else
tmp = PyString_AsString(str);
#endif
return strdup(tmp);
}


#endif

+ 193
- 0
neercs/old/python/py_module.c Näytä tiedosto

@@ -0,0 +1,193 @@
/*
* neercs console-based window manager
* Copyright (c) 2009-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"

#ifdef USE_PYTHON

#include <Python.h>
#include "py_module.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <fcntl.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <time.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <caca.h>

#include "neercs.h"

/* FIXME : Find a way to pass a user pointer to PyModuleDef or something */
static struct screen_list *screen_list;

#if defined HAVE_PYTHON3
static PyObject *PyInit_neercs(void);
#else
static void PyInit_neercs(void);
#endif
static void removeTrailingStuff(char *b);


static void addVariableFromConfig(PyObject * dictionary,
const char *varname, const char *configname)
{
char *v = get_config(configname)->get(screen_list);
if (v != NULL)
{
PyObject *value = Py_BuildValue("s", v);
PyDict_SetItemString(dictionary, varname, value);
}

debug("py get '%s' to '%s'\n", varname,
get_config(configname)->get(screen_list));
}

static void removeTrailingStuff(char *b)
{
if(!b)
return;
if(b[0]=='\'')
{
memmove(b, &b[1], strlen(b)-1);
b[strlen(b)-2] = 0;
}
}

void setExportedValues(PyObject * dictionary)
{
struct config_line *config_option = get_config_option();
int i = 0;

while (strncmp(config_option[i].name, "last", strlen("last")))
{
/* Get variable */
PyObject *res =
PyDict_GetItemString(dictionary, config_option[i].name);

/* Got it */
if (res)
{
/* Get object representation
* FIXME : find a way to check object's type */
PyObject *str = PyObject_Repr(res);

/* Make sure it's a string */
char *err =
#if defined HAVE_PYTHON3
PyBytes_AS_STRING(PyUnicode_AsEncodedString
(str, "utf-8", "Error ~"));
#elif defined HAVE_PYTHON2
PyString_AsString(str);
#endif
/* FIXME leak leak leak */
char *s = strdup(err);

if (s != NULL)
{
/* Representation can include '' around strings */
removeTrailingStuff(s);
get_config(config_option[i].name)->set(s, screen_list);
}
}
i++;
}
}

void getExportedValues(PyObject * dictionary)
{
struct config_line *config_option = get_config_option();
int i = 0;
while (strncmp(config_option[i].name, "last", strlen("last")))
{
addVariableFromConfig(dictionary, config_option[i].name,
config_option[i].name);
i++;
}
}

static PyObject *neercs_get(PyObject * self, PyObject * args)
{
char *s = NULL;

debug("Get using list at %p", screen_list);

if (!PyArg_ParseTuple(args, "s", &s))
{
PyErr_SetString(PyExc_ValueError, "Can't parse argument");
debug("py Can't parse");
return NULL;
}
debug("py Argument : '%s'", s);
struct config_line *c = get_config(s);

if (c)
return Py_BuildValue("s", c->get(screen_list));


PyErr_SetString(PyExc_ValueError,
"Can't get value for specified variable");
return NULL;
}

static PyObject *neercs_version(PyObject * self, PyObject * args)
{
return Py_BuildValue("s", PACKAGE_VERSION);
}

static PyMethodDef NeercsMethods[] =
{
{ "version", neercs_version, METH_NOARGS, "Return the neercs version." },
{ "get", neercs_get, METH_VARARGS,
"Return the specified variable's value." },
{ NULL, NULL, 0, NULL }
};

#if defined HAVE_PYTHON3
static PyObject *PyInit_neercs(void)
{
static PyModuleDef NeercsModule =
{
PyModuleDef_HEAD_INIT, "neercs", NULL, -1, NeercsMethods,
NULL, NULL, NULL, NULL
};

return PyModule_Create(&NeercsModule);
}

#elif defined HAVE_PYTHON2
static void PyInit_neercs(void)
{
PyMethodDef *m = NeercsMethods;
PyObject *mod = PyModule_New("neercs");
PyModule_AddStringConstant(mod, "__file__", "<synthetic>");

for (m = NeercsMethods; m->ml_name; m++)
PyModule_AddObject(mod, m->ml_name, PyCFunction_New(m, NULL));
}
#endif

void initNeercsModule(struct screen_list *sl)
{
screen_list = sl;
PyImport_AppendInittab("neercs", &PyInit_neercs);
Py_Initialize();
}

#endif

+ 25
- 0
neercs/old/python/py_module.h Näytä tiedosto

@@ -0,0 +1,25 @@
/*
* neercs console-based window manager
* Copyright (c) 2009-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"

#ifdef USE_PYTHON

#include <Python.h>
#include "neercs.h"

void initNeercsModule(struct screen_list *sl);
void getExportedValues(PyObject * dictionary);
void setExportedValues(PyObject * dictionary);


#endif

+ 112
- 0
neercs/old/recurrent.c Näytä tiedosto

@@ -0,0 +1,112 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h>

#include "neercs.h"


int handle_recurrents(struct screen_list *screen_list)
{
int refresh = 0, i;
/* Recurrent functions */
for (i = 0; i < screen_list->recurrent_list->count; i++)
{
if (screen_list->recurrent_list->recurrent[i]->function)
{
refresh |=
screen_list->recurrent_list->recurrent[i]->
function(screen_list,
screen_list->recurrent_list->recurrent[i],
screen_list->recurrent_list->recurrent[i]->user,
get_us());
}
}
/* Delete recurrent functions */
for (i = 0; i < screen_list->recurrent_list->count; i++)
{
if (screen_list->recurrent_list->recurrent[i]->kill_me)
{
remove_recurrent(screen_list->recurrent_list, i);
refresh = 1;
i = 0;
}
}
return refresh;
}


/* Add recurrent function. It will be called at each main loop iteration,
unless it is removed */
int add_recurrent(struct recurrent_list *list,
int (*func) (struct screen_list *, struct recurrent * rec,
void *user, long long unsigned int t),
void *user)
{
if (list == NULL || func == NULL)
return -1;

list->recurrent = (struct recurrent **)realloc(list->recurrent,
sizeof(struct recurrent *)
* (list->count + 1));

if (!list->recurrent)
fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__,
__LINE__);

list->recurrent[list->count] = malloc(sizeof(struct recurrent));

list->recurrent[list->count]->kill_me = 0;
list->recurrent[list->count]->function = func;
list->recurrent[list->count]->user = user;
list->recurrent[list->count]->start_time = get_us();
list->count++;

return list->count - 1;
}


/* Remove recurrent. Do *NOT* call this from a recurrent function. */
int remove_recurrent(struct recurrent_list *list, int n)
{

if (n >= list->count)
return -1;

memmove(&list->recurrent[n],
&list->recurrent[n + 1],
sizeof(struct recurrent *) * (list->count - (n + 1)));

free(list->recurrent[n]);
list->recurrent = (struct recurrent **)realloc(list->recurrent,
sizeof(sizeof
(struct recurrent *))
* (list->count));
if (!list->recurrent)
fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__,
__LINE__);



list->count--;
return 0;
}

+ 216
- 0
neercs/old/screen_list.c Näytä tiedosto

@@ -0,0 +1,216 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h>
#include <pwd.h>

#include <caca.h>

#include "neercs.h"

struct screen_list *create_screen_list(void)
{

struct screen_list *screen_list = NULL;
struct passwd *user_info;
char *user_dir = NULL;

/* Create screen list */
screen_list = (struct screen_list *)malloc(sizeof(struct screen_list));
if (!screen_list)
{
fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__,
__LINE__);
return NULL;
}
screen_list->screen =
(struct screen **)malloc(sizeof(sizeof(struct screen *)));
if (!screen_list->screen)
{
fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__,
__LINE__);
free(screen_list);
return NULL;
}

screen_list->count = 0;
screen_list->modals.mini = 1;
screen_list->modals.help = 0;
screen_list->modals.status = 1;
screen_list->modals.window_list = 0;
screen_list->modals.python_command = 0;
screen_list->eyecandy = 1;
screen_list->border_size = 1;
screen_list->title = NULL;
screen_list->wm_type = WM_VSPLIT;
screen_list->in_bell = 0;
screen_list->changed = 0;
screen_list->requested_delay = 0;
screen_list->delay = 1000 / 60; /* Don't refresh more than 60 times
per second */
screen_list->pty = screen_list->prevpty = 0;
screen_list->dont_update_coords = 0;
screen_list->screensaver.timeout = (60*5) * 1000000;
screen_list->screensaver.data = NULL;
screen_list->screensaver.in_screensaver = 0;
screen_list->lock.autolock_timeout = -1;
screen_list->lock.locked = 0;
screen_list->lock.lock_offset = 0;
screen_list->lock.lock_on_detach = 0;
screen_list->comm.attached = 0;
screen_list->comm.socket[SOCK_SERVER] = 0;
screen_list->comm.socket[SOCK_CLIENT] = 0;
screen_list->comm.socket_dir = NULL;
screen_list->comm.socket_path[SOCK_SERVER] = NULL;
screen_list->comm.socket_path[SOCK_CLIENT] = NULL;
screen_list->comm.session_name = NULL;
screen_list->sys.default_shell = NULL;
screen_list->sys.user_path = NULL;
screen_list->sys.to_grab = NULL;
screen_list->sys.to_start = NULL;
screen_list->sys.nb_to_grab = 0;
screen_list->sys.attach = 0;
screen_list->sys.forceattach = 0;
screen_list->need_refresh = 0;

screen_list->force_refresh = 0;
screen_list->cube.in_switch = 0;
screen_list->cube.duration = 1000000;

screen_list->interpreter_props.box = NULL;

screen_list->recurrent_list = NULL;
screen_list->cv = NULL;
screen_list->dp = NULL;

memset(screen_list->lock.lockmsg, 0, 1024);
memset(screen_list->lock.lockpass, 0, 1024);

/* Build local config file path */
user_dir = getenv("HOME");
if (!user_dir)
{
user_info = getpwuid(getuid());
if (user_info)
{
user_dir = user_info->pw_dir;
}
}
if (user_dir)
{
screen_list->sys.user_path =
malloc(strlen(user_dir) + strlen("/.neercsrc") + 1);
sprintf(screen_list->sys.user_path, "%s/%s", user_dir, ".neercsrc");
}


screen_list->recurrent_list =
(struct recurrent_list *)malloc(sizeof(struct recurrent_list));
screen_list->recurrent_list->recurrent =
(struct recurrent **)malloc(sizeof(struct recurrent *));
if (!screen_list->recurrent_list->recurrent)
{
fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__,
__LINE__);
free(screen_list);
free(screen_list->screen);
return NULL;
}
screen_list->recurrent_list->count = 0;

return screen_list;
}

void free_screen_list(struct screen_list *screen_list)
{
int i;
struct option *option;

if (screen_list->dp)
caca_free_display(screen_list->dp);

if (screen_list->cv)
caca_free_canvas(screen_list->cv);

for (i = 0; i < screen_list->count; i++)
{
destroy_screen(screen_list->screen[i]);
}

if (screen_list->comm.socket_path[SOCK_SERVER])
{
/* FIXME test that we are the server */
if (!screen_list->dp)
unlink(screen_list->comm.socket_path[SOCK_SERVER]);
free(screen_list->comm.socket_path[SOCK_SERVER]);
}

if (screen_list->comm.socket_path[SOCK_CLIENT])
{
/* FIXME test that we are the client */
if (screen_list->dp)

unlink(screen_list->comm.socket_path[SOCK_CLIENT]);
free(screen_list->comm.socket_path[SOCK_CLIENT]);
}

if (screen_list->comm.socket[SOCK_CLIENT])
close(screen_list->comm.socket[SOCK_CLIENT]);

if (screen_list->comm.socket[SOCK_SERVER])
close(screen_list->comm.socket[SOCK_SERVER]);

if (screen_list->screen)
free(screen_list->screen);

option = screen_list->config;

while (option)
{
struct option *kromeugnon = option;
option = option->next;
if (kromeugnon->key)
free(kromeugnon->key);
if (kromeugnon->value)
free(kromeugnon->value);
free(kromeugnon);
}

for (i = 0; i < screen_list->recurrent_list->count; i++)
{
remove_recurrent(screen_list->recurrent_list, i);
i = 0;
}

if (screen_list->recurrent_list->recurrent)
free(screen_list->recurrent_list->recurrent);
if (screen_list->recurrent_list)
free(screen_list->recurrent_list);

if (screen_list->comm.session_name)
free(screen_list->comm.session_name);

if (screen_list->title)
free(screen_list->title);

free(screen_list);
}

+ 334
- 0
neercs/old/screens.c Näytä tiedosto

@@ -0,0 +1,334 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h>

#include <caca.h>

#include "neercs.h"

struct screen *create_screen_grab(int w, int h, int pid)
{
struct screen *s = (struct screen *)malloc(sizeof(struct screen));

s->cv = caca_create_canvas(w, h);
caca_set_color_ansi(s->cv, CACA_BLACK, CACA_BLACK);
caca_clear_canvas(s->cv);
s->init = 0;

s->buf = NULL;
s->title = NULL;
s->total = 0;
s->w = w;
s->h = h;
s->bell = 0;
s->report_mouse = MOUSE_NONE;

s->fd = create_pty_grab(pid, w, h, &s->pid);

if (s->fd < 0)
{
caca_free_canvas(s->cv);
free(s);
return NULL;
}
return s;
}

struct screen *create_screen(int w, int h, char *command)
{
struct screen *s = (struct screen *)malloc(sizeof(struct screen));

s->cv = caca_create_canvas(w, h);
caca_set_color_ansi(s->cv, CACA_BLACK, CACA_BLACK);
caca_clear_canvas(s->cv);
s->init = 0;

s->buf = NULL;
s->title = NULL;
s->total = 0;
s->w = w + 1;
s->h = h + 1;
s->bell = 0;
s->visible = 1;
s->scroll = 0;
s->report_mouse = MOUSE_NONE;
s->fd = create_pty(command, w, h, &s->pid);

s->orig_w = s->w;
s->orig_h = s->h;
s->orig_x = s->x;
s->orig_y = s->y;


if (s->fd < 0)
{
caca_free_canvas(s->cv);
free(s);
return NULL;
}
return s;
}

int destroy_screen(struct screen *s)
{
if (s->fd >= 0)
close(s->fd);
if (s->buf)
free(s->buf);
if (s->title)
free(s->title);
s->buf = NULL;
if (s->cv)
caca_free_canvas(s->cv);
s->cv = NULL;
free(s);
return 1;
}

int add_screen(struct screen_list *list, struct screen *s)
{
if (list == NULL || s == NULL)
return -1;

else
{
list->screen = (struct screen **)realloc(list->screen,
sizeof(sizeof
(struct screen *)) *
(list->count + 1));
if (!list->screen)
fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__,
__LINE__);
list->screen[list->count] = s;
list->count++;
}

list->changed = 1;

return list->count - 1;
}

int remove_screen(struct screen_list *list, int n, int please_kill)
{

if (n >= list->count)
return -1;

if (please_kill)
{
int status = 0;
int ret = 0;
/* FIXME */
close(list->screen[n]->fd);
list->screen[n]->fd = -1;
kill(list->screen[n]->pid, SIGINT);
ret = waitpid(list->screen[n]->pid, &status,
WNOHANG | WUNTRACED | WCONTINUED);
if (!ret)
kill(list->screen[n]->pid, SIGQUIT);
ret = waitpid(list->screen[n]->pid, &status,
WNOHANG | WUNTRACED | WCONTINUED);
if (!ret)
kill(list->screen[n]->pid, SIGABRT);
ret = waitpid(list->screen[n]->pid, &status,
WNOHANG | WUNTRACED | WCONTINUED);
if (!ret)
kill(list->screen[n]->pid, SIGKILL);

}
destroy_screen(list->screen[n]);

memmove(&list->screen[n],
&list->screen[n + 1],
sizeof(struct screen *) * (list->count - (n + 1)));

list->screen = (struct screen **)realloc(list->screen,
sizeof(sizeof(struct screen *))
* (list->count));
if (!list->screen)
fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__,
__LINE__);



list->count--;
list->changed = 1;
return 1;
}



void refresh_screens(struct screen_list *screen_list)
{
int i;

if (!screen_list->count)
return;


screen_list->width = caca_get_canvas_width(screen_list->cv);
screen_list->height =
caca_get_canvas_height(screen_list->cv) - (screen_list->modals.mini * 6) -
screen_list->modals.status;

if (!screen_list->dont_update_coords)
{
update_windows_props(screen_list);
}

if (screen_list->changed)
{
caca_set_color_ansi(screen_list->cv, CACA_DEFAULT, CACA_DEFAULT);
caca_clear_canvas(screen_list->cv);
}

wm_refresh(screen_list);

caca_gotoxy(screen_list->cv,
screen_list->screen[screen_list->pty]->x +
caca_get_cursor_x(screen_list->screen[screen_list->pty]->cv),
screen_list->screen[screen_list->pty]->y +
caca_get_cursor_y(screen_list->screen[screen_list->pty]->cv));


if (screen_list->modals.mini)
{
draw_thumbnails(screen_list);
}
if (screen_list->modals.status)
{
draw_status(screen_list);
}
if (screen_list->modals.help)
{
draw_help(screen_list);
}
if (screen_list->modals.window_list)
{
draw_list(screen_list);
}
#ifdef USE_PYTHON
debug("py : command is %d (at %p)\n", screen_list->modals.python_command, &screen_list->modals.python_command);
if(screen_list->modals.python_command)
{
draw_python_command(screen_list);
}
#endif
screen_list->changed = 0;
for (i = screen_list->count - 1; i >= 0; i--)
screen_list->screen[i]->changed = 0;
}


int update_screens_contents(struct screen_list *screen_list)
{
int i, refresh = 0;
int maxfd = 0;
struct timeval tv;
fd_set fdset;
int ret;

/* Read data, if any */
FD_ZERO(&fdset);
for (i = 0; i < screen_list->count; i++)
{
if (screen_list->screen[i]->fd >= 0)
FD_SET(screen_list->screen[i]->fd, &fdset);
if (screen_list->screen[i]->fd > maxfd)
maxfd = screen_list->screen[i]->fd;
}
tv.tv_sec = 0;
tv.tv_usec = 50000;
ret = select(maxfd + 1, &fdset, NULL, NULL, &tv);

if (ret < 0)
{
if (errno == EINTR)
; /* We probably got a SIGWINCH, ignore it */
else
{
/* FIXME: Useless since break will mean that we return 0 But I
don't know what was the purpose of this code */
for (i = 0; i < screen_list->count; i++)
if (screen_list->screen[i]->total)
break;
if (i == screen_list->count)
return 0;
}
}
else if (ret)
{

for (i = 0; i < screen_list->count; i++)
{
/* FIXME: try a new strategy: read all filedescriptors until each
of them starved at least once. */

if (screen_list->screen[i]->fd < 0 ||
!FD_ISSET(screen_list->screen[i]->fd, &fdset))
continue;

for (;;)
{
ssize_t nr;

screen_list->screen[i]->buf =
realloc(screen_list->screen[i]->buf,
screen_list->screen[i]->total + 1024);
if (!screen_list->screen[i]->buf)
fprintf(stderr, "Can't allocate memory at %s:%d\n",
__FUNCTION__, __LINE__);

nr = read(screen_list->screen[i]->fd,
screen_list->screen[i]->buf +
screen_list->screen[i]->total, 1024);

if (nr > 0)
{
screen_list->screen[i]->total += nr;
continue;
}

if (nr == 0 || errno != EWOULDBLOCK)
{
remove_screen(screen_list, i, 0);
if (i < screen_list->prevpty)
screen_list->prevpty--;
if (i == screen_list->pty)
{
screen_list->pty = screen_list->prevpty;
screen_list->prevpty = 0;
}
if (i < (screen_list->pty))
(screen_list->pty)--;
/* Don't skip the element which is now at position i */
i--;
refresh = 1;
}

break;
}
}
}
return refresh;
}

+ 187
- 0
neercs/old/screensaver.c Näytä tiedosto

@@ -0,0 +1,187 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h>

#include <caca.h>

#include "neercs.h"


void screensaver_init(struct screen_list *screen_list)
{
screensaver_flying_toasters_init(screen_list);
}

void screensaver_kill(struct screen_list *screen_list)
{
screensaver_flying_toasters_kill(screen_list);
}

void draw_screensaver(struct screen_list *screen_list)
{
screensaver_flying_toasters(screen_list);
}




/* Flying Toasters */

#define COUNT 15
#define PRECISION 100

char toaster_text[3][99] = { {
" __._ \n"
" .-'== _',\n"
" <|_= .-' |\n"
" | --| \\'.-_ \n"
" | | \\ \" _.\n"
" `-_|.-\\_.-\n"},
{
" __._ \n"
" .-'== _',\n"
" \\|_= .-' |\n"
" | --| __'-.\n"
" | | ___.-\n"
" `-_|.-\n"},
{
" _- __._\n"
" /.-'== _',_.-.\n"
" \\|_= .-'/ _.'\n"
" | --| / .-\n"
" | | _.|\n"
" `-_|.-\n"}
};

char toaster_mask[3][99] = { {

" __._ \n"
" .-'== _',\n"
" <|_=X.-'XX|\n"
" |X--|XXX\\'.-_ \n"
" |XXX|X\\XX\"X_.\n"
" `-_|.-\\_.-\n"},
{

" __._ \n"
" .-'== _',\n"
" \\|_= .-'XX|\n"
" |X--|XX__'-.\n"
" |XXX|X___.-\n"
" `-_|.-\n"},
{
" _- __._\n"
" /.-'== _',_.-.\n"
" \\|_= .-'/XX_.'\n"
" |X--|X/X.-\n"
" |XXX|XX_.|\n"
" `-_|.-\n"}
};

struct flying_toaster
{
int x[COUNT], y[COUNT], s[COUNT];
caca_canvas_t **toaster;
caca_canvas_t **mask;
};

void screensaver_flying_toasters_init(struct screen_list *screen_list)
{
struct flying_toaster *flying_toaster;
int w = caca_get_canvas_width(screen_list->cv);
int h = caca_get_canvas_height(screen_list->cv);
int i;

flying_toaster = malloc(sizeof(struct flying_toaster));
flying_toaster->toaster =
(caca_canvas_t **) malloc(sizeof(caca_canvas_t *) * 3);
flying_toaster->mask =
(caca_canvas_t **) malloc(sizeof(caca_canvas_t *) * 3);

for (i = 0; i < 3; i++)
{
flying_toaster->toaster[i] = caca_create_canvas(0, 0);
flying_toaster->mask[i] = caca_create_canvas(0, 0);
caca_import_canvas_from_memory(flying_toaster->toaster[i],
toaster_text[i],
strlen(toaster_text[i]), "utf8");
caca_import_canvas_from_memory(flying_toaster->mask[i],
toaster_mask[i],
strlen(toaster_mask[i]), "utf8");
}

for (i = 0; i < COUNT; i++)
{
flying_toaster->x[i] = (rand() % w) * PRECISION;
flying_toaster->y[i] = (rand() % h) * PRECISION;
flying_toaster->s[i] = (rand() % 3) * PRECISION;
}


screen_list->screensaver.data = flying_toaster;
}

void screensaver_flying_toasters_kill(struct screen_list *screen_list)
{
struct flying_toaster *flying_toaster = screen_list->screensaver.data;

caca_free_canvas(flying_toaster->toaster[0]);
caca_free_canvas(flying_toaster->toaster[1]);
caca_free_canvas(flying_toaster->toaster[2]);
free(flying_toaster->toaster);
free(flying_toaster);
screen_list->screensaver.data = NULL;
}

void screensaver_flying_toasters(struct screen_list *screen_list)
{
struct flying_toaster *d = screen_list->screensaver.data;
int i, w, h, x, y, s;
if (!d)
return;

w = caca_get_canvas_width(screen_list->cv);
h = caca_get_canvas_height(screen_list->cv);

caca_set_color_ansi(screen_list->cv, CACA_WHITE, CACA_BLACK);
caca_clear_canvas(screen_list->cv);

for (i = 0; i < COUNT; i++)
{
x = d->x[i] / PRECISION;
y = d->y[i] / PRECISION;
s = d->s[i] / PRECISION;

caca_blit(screen_list->cv, x, y, d->toaster[s], d->mask[s]);

d->x[i] -= 40;
d->y[i] += 10;

if (d->x[i] / PRECISION + caca_get_canvas_width(d->toaster[s]) <= 0)
d->x[i] = ((rand() % w) / 3 + w) * PRECISION;
if (d->y[i] / PRECISION >= h)
d->y[i] = ((rand() % h) / 2 - h) * PRECISION;

d->s[i] = ((d->s[i] + 24) % (3 * PRECISION));
}
}

+ 680
- 0
neercs/old/server.c Näytä tiedosto

@@ -0,0 +1,680 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* 2008-2010 Pascal Terjan <pterjan@linuxfr.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <time.h>
#include <pwd.h>

#include <errno.h>
#include <caca.h>

#include "neercs.h"

static void server_init(struct screen_list *screen_list);
static void refresh_screen(struct screen_list *screen_list, int refresh);
static int handle_key(struct screen_list *screen_list, unsigned int c,
int refresh);
static int handle_attach(struct screen_list *screen_list, char *buf);

static int send_to_client(const char *msg, int size,
struct screen_list *screen_list)
{
int ret;
if (!screen_list->comm.socket[SOCK_CLIENT])
connect_socket(screen_list, SOCK_CLIENT);
if (!screen_list->comm.socket[SOCK_CLIENT])
ret = -1;
else
ret = write(screen_list->comm.socket[SOCK_CLIENT], msg, size);
if (ret < 0 && errno != EAGAIN)
{
fprintf(stderr, "Failed to send message to client: %s\n",
strerror(errno));
if (screen_list->comm.attached)
detach(screen_list);
}
return ret;
}

static int set_title(struct screen_list *screen_list)
{
char buf[1024];
int bytes;
char *title = NULL;

if (screen_list->comm.attached)
{
if (screen_list->pty < screen_list->count &&
screen_list->screen[screen_list->pty]->title)
title = screen_list->screen[screen_list->pty]->title;
else
title = PACKAGE_STRING;
}

if (screen_list->title)
{
if (!strcmp(screen_list->title, title))
return 0;
free(screen_list->title);
}

screen_list->title = strdup(title);

bytes = snprintf(buf, sizeof(buf) - 1, "TITLE %s", title);
buf[bytes] = '\0';
return send_to_client(buf, strlen(buf), screen_list);
}

static int set_cursor(int state, struct screen_list *screen_list)
{
char buf[16];
int bytes;

bytes = snprintf(buf, sizeof(buf) - 1, "CURSOR %d", state);
buf[bytes] = '\0';

return send_to_client(buf, strlen(buf), screen_list);
}

static int request_refresh(struct screen_list *screen_list)
{
int ndirty = caca_get_dirty_rect_count(screen_list->cv);
if (!ndirty)
return 0;
if (!screen_list->comm.socket[SOCK_CLIENT])
connect_socket(screen_list, SOCK_CLIENT);
if (screen_list->comm.socket[SOCK_CLIENT])
{
size_t bufsize, towrite;
ssize_t written, ret;
socklen_t optlen = sizeof(bufsize);
size_t bytes;
void *buf;
char buf2[32];
int x, y, i;

getsockopt(screen_list->comm.socket[SOCK_CLIENT], SOL_SOCKET,
SO_SNDBUF, &bufsize, &optlen);
bufsize /= 2;
debug("bufsize=%d", bufsize);

for (i = 0; i < ndirty; i++)
{
int w, h;
caca_get_dirty_rect(screen_list->cv, i, &x, &y, &w, &h);
debug("dirty @%d,%d %dx%d [%dx%d]", x, y, w, h,
caca_get_canvas_width(screen_list->cv),
caca_get_canvas_height(screen_list->cv));
buf =
caca_export_area_to_memory(screen_list->cv, x, y, w, h, "caca",
&bytes);
debug("Requesting refresh for %d", bytes);
towrite = bytes;
written = 0;
sprintf(buf2, "UPDATE %10d %10d", x, y);
ret = send_to_client(buf2, strlen(buf2) + 1, screen_list);
if (ret < 29)
{
free(buf);
return -1;
}
/* Block to write the end of the message */
fcntl(screen_list->comm.socket[SOCK_CLIENT], F_SETFL, 0);
while (towrite > 0)
{
ssize_t n;
debug("Wrote %d, %d remaining", written, towrite);
n = send_to_client((char *)buf + written,
towrite > bufsize ? bufsize : towrite,
screen_list);
if (n < 0)
{
debug("Can't refresh (%s), with %d bytes (out of %d)",
strerror(errno),
towrite > bufsize ? bufsize : towrite, towrite);
return -1;
}
written += n;
towrite -= n;
}
fcntl(screen_list->comm.socket[SOCK_CLIENT], F_SETFL, O_NONBLOCK);
free(buf);
}
sprintf(buf2, "REFRESH %10d %10d", caca_get_cursor_x(screen_list->cv),
caca_get_cursor_y(screen_list->cv));
/* FIXME check value of r */
int r = send_to_client(buf2, strlen(buf2) + 1, screen_list);
(void)r;
caca_clear_dirty_rect_list(screen_list->cv);
}
return 0;
}

int detach(struct screen_list *screen_list)
{
screen_list->comm.attached = 0;
if (screen_list->lock.lock_on_detach)
screen_list->lock.locked = 1;
if (screen_list->comm.socket[SOCK_CLIENT])
{
send_to_client("DETACH", 6, screen_list);
close(screen_list->comm.socket[SOCK_CLIENT]);
screen_list->comm.socket[SOCK_CLIENT] = 0;
}
return 0;
}

static int server_iteration(struct screen_list *screen_list)
{
int i;
int eof = 0, refresh;

int quit = 0;
ssize_t n;
char buf[128];

/* Read program output */
refresh = update_screens_contents(screen_list);

/* Check if we got something from the client */
while (screen_list->comm.socket[SOCK_SERVER]
&& (n =
read(screen_list->comm.socket[SOCK_SERVER], buf,
sizeof(buf) - 1)) > 0)
{
buf[n] = 0;
debug("Received command %s", buf);
if (!strncmp("ATTACH ", buf, 7))
{
refresh |= handle_attach(screen_list, buf);
}
else if (!strncmp("QUIT", buf, 4))
{
quit = 1;
}
else if (!strncmp("DELAY ", buf, 6))
{
/* FIXME check the length before calling atoi */
screen_list->delay = atoi(buf + 6);
}
else if (!strncmp("RESIZE ", buf, 7))
{
caca_free_canvas(screen_list->cv);
/* FIXME check the length before calling atoi */
screen_list->cv =
caca_create_canvas(atoi(buf + 7), atoi(buf + 18));
screen_list->changed = 1;
refresh = 1;
}
else if (!strncmp("KEY ", buf, 4))
{
unsigned int c = atoi(buf + 4);
refresh |= handle_key(screen_list, c, refresh);
}
else if (!strncmp("MOUSEP ", buf, 6))
{
debug("Got mouse press '%s'\n", buf);
int x, y, b;
x = 1 + atoi(buf + 7) - screen_list->screen[screen_list->pty]->x;
y = 1 + atoi(buf + 18) - screen_list->screen[screen_list->pty]->y;
b = atoi(buf + 28);

switch (screen_list->screen[screen_list->pty]->report_mouse)
{
case MOUSE_VT200:
case MOUSE_VT200_HIGHLIGHT:
case MOUSE_BTN_EVENT:
case MOUSE_ANY_EVENT:
sprintf(buf, "\x1b[M%c%c%c", 32 + (b - 1), x + 32, y + 32);
debug("mousea send ESC[M %d %d %d", (b - 1), x + 32, y + 32);
send_ansi_sequence(screen_list, buf);
break;
case MOUSE_X10:
sprintf(buf, "\x1b[M%c%c%c", 32 + (b - 1), 32 + x, 32 + y);
debug("mousex send ESC[M %d %d %d", 32 + (b - 1), 32 + x,
32 + y);
send_ansi_sequence(screen_list, buf);
break;
case MOUSE_NONE:
break;

}
}
else if (!strncmp("MOUSER ", buf, 6))
{
debug("Got mouse release '%s'\n", buf);
int x, y, b;
x = 1 + atoi(buf + 7) - screen_list->screen[screen_list->pty]->x;
y = 1 + atoi(buf + 18) - screen_list->screen[screen_list->pty]->y;
b = atoi(buf + 28);

switch (screen_list->screen[screen_list->pty]->report_mouse)
{
case MOUSE_VT200:
case MOUSE_VT200_HIGHLIGHT:
case MOUSE_BTN_EVENT:
case MOUSE_ANY_EVENT:
sprintf(buf, "\x1b[M%c%c%c", 32 + 3, x + 32, y + 32);
send_ansi_sequence(screen_list, buf);
break;
case MOUSE_X10:
sprintf(buf, "\x1b[M%c%c%c", 32 + 3, 32 + x, 32 + y);
send_ansi_sequence(screen_list, buf);
break;
case MOUSE_NONE:
break;
}
}

else if (!strncmp("MOUSEM ", buf, 6))
{
debug("Got mouse motion '%s'\n", buf);
int x, y, b;
x = 1 + atoi(buf + 7) - screen_list->screen[screen_list->pty]->x;
y = 1 + atoi(buf + 18) - screen_list->screen[screen_list->pty]->y;
b = atoi(buf + 28);

switch (screen_list->screen[screen_list->pty]->report_mouse)
{
case MOUSE_X10: // X10 reports mouse clicks only
if (b)
{
sprintf(buf, "\x1b[M%c%c%c", 32 + (b - 1), x + 32, y + 32);
send_ansi_sequence(screen_list, buf);
}
break;
case MOUSE_VT200:
case MOUSE_VT200_HIGHLIGHT:
case MOUSE_BTN_EVENT:
if (b)
{
sprintf(buf, "\x1b[M%c%c%c", 32 + (b - 1), x + 32, y + 32);
send_ansi_sequence(screen_list, buf);
}
case MOUSE_ANY_EVENT:
sprintf(buf, "\x1b[M%c%c%c", 32 + (b - 1), x + 32, y + 32);
send_ansi_sequence(screen_list, buf);
break;
case MOUSE_NONE:
break;
}
}
else
{
fprintf(stderr, "Unknown command received: %s\n", buf);
}
}

/* No more screens, exit */
if (!screen_list->count)
return -1;

/* User requested to exit */
if (quit)
return -2;

/* Update each screen canvas */
refresh |= update_terms(screen_list);

/* Launch recurrents if any */
refresh |= handle_recurrents(screen_list);

/* Refresh screen */
refresh_screen(screen_list, refresh);

eof = 1;
for (i = 0; i < screen_list->count; i++)
if (screen_list->screen[i]->fd >= 0)
eof = 0;
if (eof)
return -3;

return 0;
}

static void server_main(struct screen_list *screen_list)
{
screen_list->last_key_time = 0;
screen_list->comm.attached = 0;
screen_list->command = 0;
screen_list->was_in_bell = 0;
screen_list->last_refresh_time = 0;

server_init(screen_list);
#ifdef USE_PYTHON
python_init(screen_list);
#endif

for (;;)
{
if (server_iteration(screen_list))
break;
}

detach(screen_list);

free_screen_list(screen_list);

#ifdef USE_PYTHON
python_close(screen_list);
#endif

exit(0);
}

static void refresh_screen(struct screen_list *screen_list, int refresh)
{
if (!screen_list->comm.attached)
{
/* No need to refresh Don't use the CPU too much Would be better to
select on terms + socket */
sleep(1);
}
else
{
long long unsigned int current_time = get_us();
long long int tdiff =
(current_time - screen_list->last_refresh_time) / 1000;

refresh |= screen_list->need_refresh;

if (screen_list->force_refresh)
{
wm_refresh(screen_list);
refresh = 1;
}

/* Draw lock window */
if (screen_list->lock.locked)
{
/* FIXME don't redraw it each iteration */
draw_lock(screen_list);
refresh = 1;
}
#ifdef USE_LOCK
else if ((current_time - screen_list->last_key_time >=
screen_list->lock.autolock_timeout))
{
screen_list->lock.locked = 1;
refresh = 1;
}
#endif
else if ((current_time - screen_list->last_key_time >=
screen_list->screensaver.timeout))
{
if (!screen_list->screensaver.in_screensaver)
{
screensaver_init(screen_list);
screen_list->screensaver.in_screensaver = 1;
set_cursor(0, screen_list);
}
draw_screensaver(screen_list);
refresh = 1;
}
else if (refresh || screen_list->was_in_bell)
{
if (tdiff >= screen_list->delay)
{
refresh_screens(screen_list);
set_title(screen_list);
refresh = 1;
}
}
if (refresh)
{
if (tdiff >= screen_list->delay)
{
request_refresh(screen_list);
screen_list->last_refresh_time = current_time;
screen_list->need_refresh = 0;
}
else
{
debug("Skipping refresh (%lld < %d)", tdiff,
screen_list->delay);
screen_list->need_refresh = 1;
}
}
}
}

static void server_init(struct screen_list *screen_list)
{
int i;
debug("Screen list at %p\n", screen_list);

/* Create socket and bind it */
create_socket(screen_list, SOCK_SERVER);

/* Connect to the client */
connect_socket(screen_list, SOCK_CLIENT);

screen_list->width = screen_list->height = 80;

/* Create main canvas */
screen_list->cv = caca_create_canvas(screen_list->width,
screen_list->height
+ screen_list->modals.mini * 6
+ screen_list->modals.status);

if (!screen_list->sys.to_grab && !screen_list->sys.to_start)
{
add_screen(screen_list,
create_screen(screen_list->width,
screen_list->height,
screen_list->sys.default_shell));
}

/* Attach processes */
if (screen_list->sys.to_grab)
{
for (i = 0; screen_list->sys.to_grab[i]; i++)
{
add_screen(screen_list,
create_screen_grab(screen_list->width,
screen_list->height,
screen_list->sys.to_grab[i]));
}
free(screen_list->sys.to_grab);
screen_list->sys.to_grab = NULL;
}

/* Launch command line processes */
if (screen_list->sys.to_start)
{
for (i = 0; screen_list->sys.to_start[i]; i++)
{
add_screen(screen_list,
create_screen(screen_list->width,
screen_list->height,
screen_list->sys.to_start[i]));
free(screen_list->sys.to_start[i]);
}
free(screen_list->sys.to_start);
screen_list->sys.to_start = NULL;
}

screen_list->last_key_time = get_us();
}

static int handle_attach(struct screen_list *screen_list, char *buf)
{
/* If we were attached to someone else, detach first */
if (screen_list->comm.attached)
detach(screen_list);
screen_list->comm.attached = 1;
caca_free_canvas(screen_list->cv);
screen_list->cv = caca_create_canvas(atoi(buf + 7), atoi(buf + 18));
screen_list->delay = atoi(buf + 29);
screen_list->changed = 1;
return 1;
}

static int handle_key(struct screen_list *screen_list, unsigned int c,
int refresh)
{
char *str = NULL;
int size = 0;

if (screen_list->modals.help)
{
return help_handle_key(screen_list, c);
}
#ifdef USE_PYTHON
if (screen_list->modals.python_command)
{
return python_command_handle_key(screen_list, c);
}
#endif

/* CTRL-A has been pressed before, handle this as a command, except that
CTRL-A a sends literal CTRL-A */
if (screen_list->command && (c != 'a'))
{
screen_list->command = 0;
refresh |= handle_command_input(screen_list, c);
}
else
{
/* Not in command mode */
screen_list->last_key_time = get_us();
set_cursor(1, screen_list);

/* Kill screensaver */
if (screen_list->screensaver.in_screensaver)
{
screensaver_kill(screen_list);
screen_list->screensaver.in_screensaver = 0;
screen_list->changed = 1;
refresh = 1;
return refresh;
}
/* Handle lock window */
if (screen_list->lock.locked)
{
refresh |= update_lock(c, screen_list);
screen_list->changed = 1;
}
else if (screen_list->modals.window_list)
{
refresh |= update_window_list(c, screen_list);
screen_list->changed = 1;
}
else
{
switch (c)
{
case 0x01: // CACA_KEY_CTRL_A:
screen_list->command = 1;
break;
default:
/* CTRL-A a sends literal CTRL-A */
if (screen_list->command && (c == 'a'))
{
c = 0x01;
}
/* Normal key, convert it if needed */
str = convert_input_ansi(&c, &size);
/* FIXME check value of r */
int r = write(screen_list->screen[screen_list->pty]->fd, str,
size);
(void)r;
break;
}
}
}
return refresh;
}

int send_ansi_sequence(struct screen_list *screen_list, char *str)
{
debug("Sending ansi '%s'\n", str);
return write(screen_list->screen[screen_list->pty]->fd, str, strlen(str));
}


int install_fds(struct screen_list *screen_list)
{
int fd;
close(0);
close(1);
close(2);
fd = open("/dev/null", O_RDWR, 0);
if (fd < 0)
{
perror("Failed to open /dev/null");
return -2;
}
dup2(fd, 0);
#ifndef DEBUG
dup2(fd, 1);
dup2(fd, 2);
if (fd > 2)
close(fd);
#else
if (fd != 0)
close(fd);
screen_list->outfd =
open("/tmp/neercs-debug.txt", O_TRUNC | O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR);
dup2(screen_list->outfd, 1);
dup2(screen_list->outfd, 2);
if (screen_list->outfd > 2)
close(screen_list->outfd);
#endif
return 0;
}

int start_server(struct screen_list *screen_list)
{
pid_t pid;

pid = fork();
if (pid < 0)
{
perror("Failed to create child process");
return -1;
}
if (pid == 0)
{
int r = install_fds(screen_list);
if (r)
return r;
setsid();

server_main(screen_list);
/* Never returns */
}

return 0;
}

long long get_us(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec * (1000000) + tv.tv_usec);
}

+ 133
- 0
neercs/old/term.c Näytä tiedosto

@@ -0,0 +1,133 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"

#define _XOPEN_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <termios.h>
#if defined HAVE_PTY_H
# include <pty.h> /* for openpty and forkpty */
#elif defined HAVE_UTIL_H
# include <util.h> /* for OS X, OpenBSD and NetBSD */
#elif defined HAVE_LIBUTIL_H
# include <libutil.h> /* for FreeBSD */
#endif
#include <unistd.h>
#include <fcntl.h>

#include <caca.h>

#include "neercs.h"


int create_pty(char *cmd, unsigned int w, unsigned int h, int *cpid)
{
char **argv;
int fd;
pid_t pid;

pid = forkpty(&fd, NULL, NULL, NULL);
if (pid < 0)
{
fprintf(stderr, "forkpty() error\n");
return -1;
}
else if (pid == 0)
{
set_tty_size(0, w, h);
putenv("CACA_DRIVER=slang");
putenv("TERM=xterm");
argv = malloc(2 * sizeof(char *));
if (!argv)
{
fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__,
__LINE__);
return -1;
}
argv[0] = cmd;
argv[1] = NULL;
execvp(cmd, argv);
fprintf(stderr, "execvp() error\n");
return -1;
}

*cpid = pid;

fcntl(fd, F_SETFL, O_NDELAY);
return fd;
}

int create_pty_grab(long pid, unsigned int w, unsigned int h, int *newpid)
{
int fdm, fds;

int ret = openpty(&fdm, &fds, NULL, NULL, NULL);

if (ret < 0)
{
fprintf(stderr, "open() error\n");
return -1;
}

set_tty_size(0, w, h);
grab_process(pid, ptsname(fdm), fds, newpid);

fcntl(fdm, F_SETFL, O_NDELAY);
return fdm;
}

int set_tty_size(int fd, unsigned int w, unsigned int h)
{
struct winsize ws;

memset(&ws, 0, sizeof(ws));
ws.ws_row = h;
ws.ws_col = w;
ioctl(fd, TIOCSWINSZ, (char *)&ws);

return 0;
}



int update_terms(struct screen_list *screen_list)
{
int i, refresh = 0;
for (i = 0; i < screen_list->count; i++)
{
if (screen_list->screen[i]->total && !screen_list->dont_update_coords)
{
unsigned long int bytes;

bytes = import_term(screen_list,
screen_list->screen[i],
screen_list->screen[i]->buf,
screen_list->screen[i]->total);

if (bytes > 0)
{
screen_list->screen[i]->total -= bytes;
memmove(screen_list->screen[i]->buf,
screen_list->screen[i]->buf + bytes,
screen_list->screen[i]->total);
if (screen_list->screen[i]->visible || screen_list->modals.mini)
refresh = 1;
}
}
}
return refresh;
}

+ 176
- 0
neercs/old/widgets.c Näytä tiedosto

@@ -0,0 +1,176 @@
/*
* neercs console-based window manager
* Copyright (c) 2009-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/


#include "widgets.h"

static void widget_ibox_add_char(struct input_box *box, unsigned int c);
static void widget_ibox_del_char(struct input_box *box);

struct input_box *widget_ibox_init(caca_canvas_t *cv, int w, int h)
{
struct input_box *box = malloc(sizeof(struct input_box));
if (!box)
return NULL;
box->cv = cv;
box->w = w;
box->h = h;
box->command = NULL;
box->output_err = NULL;
box->output_res = NULL;

return box;
}


int widget_ibox_draw(struct input_box *box)
{
int x = (caca_get_canvas_width(box->cv) - box->w) / 2;
int y = (caca_get_canvas_height(box->cv) - box->h) / 2;

caca_set_color_ansi(box->cv, CACA_BLUE, CACA_BLUE);
caca_fill_box(box->cv, x, y, box->w, box->h, '#');
caca_set_color_ansi(box->cv, CACA_DEFAULT, CACA_BLUE);
caca_draw_cp437_box(box->cv, x, y, box->w, box->h);
caca_printf(box->cv, x, y, "Mini-command");

caca_printf(box->cv, x + 2, y + 2,
"[___________________________________________________________]");

if (box->command)
{
caca_printf(box->cv, x + 3, y + 2, "%s", box->command);
caca_gotoxy(box->cv, x + 3 + box->x, y + 2);
}
else
{
caca_gotoxy(box->cv, x + 3, y + 2);
}

if (box->output_err)
{
caca_set_color_ansi(box->cv, CACA_RED, CACA_BLUE);
caca_printf(box->cv, x + 2, y + 4, box->output_err);
}
if (box->output_res)
{
caca_set_color_ansi(box->cv, CACA_LIGHTGREEN, CACA_BLUE);
caca_printf(box->cv, x + 2, y + 4, box->output_res);
}

return 0;
}

char *widget_ibox_get_text(struct input_box *box)
{
return box->command;
}

void widget_ibox_destroy(struct input_box *box)
{
if(!box) return;
if (box->command)
free(box->command);
if (box->output_err)
free(box->output_err);
if (box->output_res)
free(box->output_res);
}

void widget_ibox_set_error(struct input_box *box, char *err)
{
box->output_err = err;
}

void widget_ibox_set_msg(struct input_box *box, char *msg)
{
box->output_res = msg;
}

int widget_ibox_handle_key(struct input_box *box, unsigned int c)
{
if (c == CACA_KEY_ESCAPE)
{
if (box->command)
{
free(box->command);
box->command = NULL;
}
return INPUT_BOX_ESC;
}
else if (c == CACA_KEY_LEFT)
{
if (box->x)
box->x--;
}
else if (c == CACA_KEY_RIGHT)
{
if (box->x < box->size - 1)
box->x++;
}
else if (c == CACA_KEY_RETURN)
{
return INPUT_BOX_RET;
}
else
{
if (c >= ' ' && c < 127)
widget_ibox_add_char(box, c);
else if (c == 8)
{
widget_ibox_del_char(box);
}
}
return INPUT_BOX_NOTHING;
}



static void widget_ibox_add_char(struct input_box *box, unsigned int c)
{
/* FIXME handle return values */
if (!box->command)
{
box->size = 1;
box->x = 0;
box->command = (char *)malloc(2);
box->command[0] = 0;
}
else
{
box->command = (char *)realloc(box->command, box->size + 1);
}
memmove(&box->command[box->x + 1],
&box->command[box->x], (box->size - box->x));

box->command[box->x] = c;
box->x++;
box->size++;
}

static void widget_ibox_del_char(struct input_box *box)
{
if (box->x < 1)
return;
if (box->size > 1)
box->size--;
else
return;

memcpy(&box->command[box->x - 1], &box->command[box->x], box->size - box->x);

box->command = (char *)realloc(box->command, box->size);

if (box->x)
box->x--;
box->command[box->size - 1] = 0;
}

+ 47
- 0
neercs/old/widgets.h Näytä tiedosto

@@ -0,0 +1,47 @@
/*
* neercs console-based window manager
* Copyright (c) 2009-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>

#include <caca.h>


enum input_box_code
{
INPUT_BOX_ESC,
INPUT_BOX_RET,
INPUT_BOX_NOTHING,
};

struct input_box
{
caca_canvas_t *cv;
int x, y;
int w, h;
int size;
char *command;
char *output_err;
char *output_res;
};

struct input_box *widget_ibox_init(caca_canvas_t * cv, int w, int h);
int widget_ibox_draw(struct input_box *box);
int widget_ibox_handle_key(struct input_box *box, unsigned int c);
char* widget_ibox_get_text(struct input_box *box);
void widget_ibox_destroy(struct input_box *box);
void widget_ibox_set_error(struct input_box *box, char *err);
void widget_ibox_set_msg(struct input_box *box, char *msg);

+ 513
- 0
neercs/old/wm.c Näytä tiedosto

@@ -0,0 +1,513 @@
/*
* neercs console-based window manager
* Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
* 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
* All Rights Reserved
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <caca.h>

#include "neercs.h"


void resize_screen(struct screen *s, int w, int h)
{
caca_canvas_t *old, *new;

if (w == s->w && h == s->h)
return;
if (w <= 0 || h <= 0)
return;

s->changed = 1;

s->w = w;
s->h = h;

/*
* caca_set_canvas_boundaries() is bugged as hell, so let's resize it by
* hands
*/
old = s->cv;
new = caca_create_canvas(w, h);
caca_blit(new, 0, 0, old, NULL);
s->cv = new;
caca_gotoxy(new, caca_get_cursor_x(old), caca_get_cursor_y(old));
caca_free_canvas(old);
set_tty_size(s->fd, w, h);

s->orig_w = s->w;
s->orig_h = s->h;
s->orig_x = s->x;
s->orig_y = s->y;
}

void update_windows_props(struct screen_list *screen_list)
{
debug("%s, %d screens, type %d\n", __FUNCTION__, screen_list->count,
screen_list->wm_type);

if (!screen_list->count)
return;

switch (screen_list->wm_type)
{
case WM_CARD:
update_windows_props_cards(screen_list);
break;
case WM_HSPLIT:
update_windows_props_hsplit(screen_list);
break;
case WM_VSPLIT:
update_windows_props_vsplit(screen_list);
break;
case WM_FULL:
default:
update_windows_props_full(screen_list);
break;
}
}

void update_windows_props_hsplit(struct screen_list *screen_list)
{
int i;
int w =
(screen_list->width / screen_list->count) -
(screen_list->border_size * 2);
int h = screen_list->height - (screen_list->border_size * 2);

for (i = 0; i < screen_list->count; i++)
{
screen_list->screen[i]->x = (i * w) + screen_list->border_size;
screen_list->screen[i]->y = screen_list->border_size;
screen_list->screen[i]->visible = 1;
if (i != screen_list->count - 1)
{
resize_screen(screen_list->screen[i], w - 1, h);
}
else
{
resize_screen(screen_list->screen[i],
screen_list->width - i * w - 2, h);
}
}
}

void update_windows_props_vsplit(struct screen_list *screen_list)
{
int i;
int w = screen_list->width - (screen_list->border_size * 2);
int h = (screen_list->height) / screen_list->count;

for (i = 0; i < screen_list->count; i++)
{
screen_list->screen[i]->x = screen_list->border_size;
screen_list->screen[i]->y = (i * h) + (screen_list->border_size);
screen_list->screen[i]->visible = 1;
if (i != screen_list->count - 1)
{
resize_screen(screen_list->screen[i], w,
h - (screen_list->border_size * 2));
}
else
{
resize_screen(screen_list->screen[i],
w,
screen_list->height - i * h -
(screen_list->border_size * 2));
}
}
}


void update_windows_props_full(struct screen_list *screen_list)
{
int i;
int w = screen_list->width - (screen_list->border_size * 2);
int h = screen_list->height - (screen_list->border_size * 2);

for (i = 0; i < screen_list->count; i++)
{
screen_list->screen[i]->visible = 0;
screen_list->screen[i]->x = screen_list->border_size;
screen_list->screen[i]->y = screen_list->border_size;

resize_screen(screen_list->screen[i], w, h);
}
screen_list->screen[screen_list->pty]->visible = 1;
}


void update_windows_props_cards(struct screen_list *screen_list)
{
int i;
int w = (screen_list->width - screen_list->count * 3) + 1;
int h = (screen_list->height - screen_list->count) - 1;
int x = 1;
int y = screen_list->count;

for (i = 0; i < screen_list->count; i++)
{
screen_list->screen[i]->visible = 1;
screen_list->screen[i]->x = x;
screen_list->screen[i]->y = y;

resize_screen(screen_list->screen[i], w, h);
x += 3;
y--;
}
}

/* Window managers refresh */

void wm_refresh(struct screen_list *screen_list)
{
/* FIXME : move set_color to a relevant place */
caca_set_color_ansi(screen_list->cv, CACA_LIGHTRED, CACA_BLACK);

switch (screen_list->wm_type)
{
case WM_CARD:
wm_refresh_card(screen_list);
break;
case WM_HSPLIT:
wm_refresh_hsplit(screen_list);
break;
case WM_VSPLIT:
wm_refresh_hsplit(screen_list);
break;
case WM_FULL:
default:
wm_refresh_cube(screen_list);
break;
}
}

static void wm_bell(struct screen_list *screen_list)
{
if (screen_list->screen[screen_list->pty]->bell)
{
caca_set_color_ansi(screen_list->cv, CACA_RED, CACA_BLACK);
screen_list->in_bell--;
screen_list->force_refresh = 1;
if (!screen_list->in_bell)
{
screen_list->was_in_bell = 1;
screen_list->screen[screen_list->pty]->bell = 0;
}
}
else
{
if (screen_list->was_in_bell)
{
screen_list->screen[screen_list->pty]->bell = 0;
screen_list->force_refresh = 1;
screen_list->was_in_bell = 0;
screen_list->changed = 1;
}
caca_set_color_ansi(screen_list->cv, CACA_LIGHTGREEN, CACA_BLACK);
}
}

static void wm_box(struct screen_list *screen_list, int pty)
{
if (!screen_list->screen[pty]->changed && !screen_list->changed)
return;

if (!screen_list->border_size)
return;

/* Color determined by wm_bell() */
caca_draw_cp437_box(screen_list->cv,
screen_list->screen[pty]->x - 1,
screen_list->screen[pty]->y - 1,
screen_list->screen[pty]->w + 2,
screen_list->screen[pty]->h + 2);

if (screen_list->screen[pty]->title)
{
caca_printf(screen_list->cv,
screen_list->screen[pty]->x,
screen_list->screen[pty]->y - 1,
" %.*s ",
screen_list->screen[pty]->w - 3,
screen_list->screen[pty]->title);
}
}

static void wm_blit_current_screen(struct screen_list *screen_list)
{
if (screen_list->screen[screen_list->pty]->changed || screen_list->changed)
caca_blit(screen_list->cv,
screen_list->screen[screen_list->pty]->x,
screen_list->screen[screen_list->pty]->y,
screen_list->screen[screen_list->pty]->cv, NULL);
}

void wm_refresh_card(struct screen_list *screen_list)
{
int i;

for (i = screen_list->count - 1; i >= 0; i--)
{
if (i != screen_list->pty && screen_list->screen[i]->visible &&
(screen_list->screen[i]->changed || screen_list->changed))
{
caca_blit(screen_list->cv,
screen_list->screen[i]->x,
screen_list->screen[i]->y,
screen_list->screen[i]->cv, NULL);

wm_box(screen_list, i);
}
}

/* Force 'changed' to force redraw */
screen_list->screen[screen_list->pty]->changed = 1;
wm_blit_current_screen(screen_list);
wm_bell(screen_list);
wm_box(screen_list, screen_list->pty);
}

void wm_refresh_full(struct screen_list *screen_list)
{
wm_blit_current_screen(screen_list);
wm_bell(screen_list);
wm_box(screen_list, screen_list->pty);
}

void wm_refresh_vsplit(struct screen_list *screen_list)
{
int i;

for (i = screen_list->count - 1; i >= 0; i--)
{
if (i != screen_list->pty && screen_list->screen[i]->visible &&
(screen_list->screen[i]->changed || screen_list->changed))
{
caca_blit(screen_list->cv,
screen_list->screen[i]->x,
screen_list->screen[i]->y,
screen_list->screen[i]->cv, NULL);

wm_box(screen_list, i);
}
}

wm_blit_current_screen(screen_list);
wm_bell(screen_list);
wm_box(screen_list, screen_list->pty);
}

void wm_refresh_hsplit(struct screen_list *screen_list)
{
int i;

for (i = screen_list->count - 1; i >= 0; i--)
{
if (i != screen_list->pty && screen_list->screen[i]->visible &&
(screen_list->screen[i]->changed || screen_list->changed))
{
caca_blit(screen_list->cv,
screen_list->screen[i]->x,
screen_list->screen[i]->y,
screen_list->screen[i]->cv, NULL);

wm_box(screen_list, i);
}
}

wm_blit_current_screen(screen_list);
wm_bell(screen_list);
wm_box(screen_list, screen_list->pty);
}


static float
get_direction(float p1x, float p1y, float p2x, float p2y, float p3x, float p3y)
{
float d1x, d1y, d2x, d2y;

d1x = p3x - p1x;
d1y = p3y - p1y;
d2x = p3x - p2x;
d2y = p3y - p2y;
return (d1x * d2y) - (d1y * d2x);
}


/* 3D Cube. Yeah I know, it's a mess. Just look anywhere else. */
static void draw_face(caca_canvas_t * cv,
int p1x, int p1y,
int p2x, int p2y,
int p3x, int p3y,
int p4x, int p4y, caca_canvas_t * tex,
int color, int borders)
{
if (get_direction(p1x, p1y, p2x, p2y, p3x, p3y) >= 0)
{
int coords[6];
float uv[6];
coords[0] = p1x;
coords[1] = p1y;
coords[2] = p2x;
coords[3] = p2y;
coords[4] = p3x;
coords[5] = p3y;
uv[0] = 1;
uv[1] = 1;
uv[2] = 0;
uv[3] = 1;
uv[4] = 0;
uv[5] = 0;
caca_fill_triangle_textured(cv, coords, tex, uv);
coords[0] = p1x;
coords[1] = p1y;
coords[2] = p3x;
coords[3] = p3y;
coords[4] = p4x;
coords[5] = p4y;
uv[0] = 1;
uv[1] = 1;
uv[2] = 0;
uv[3] = 0;
uv[4] = 1;
uv[5] = 0;
caca_fill_triangle_textured(cv, coords, tex, uv);
caca_set_color_ansi(cv, color, CACA_BLACK);
if (borders)
{
caca_draw_thin_line(cv, p1x, p1y, p2x, p2y);
caca_draw_thin_line(cv, p2x, p2y, p3x, p3y);
caca_draw_thin_line(cv, p3x, p3y, p4x, p4y);
caca_draw_thin_line(cv, p4x, p4y, p1x, p1y);
}
}
}


void wm_refresh_cube(struct screen_list *screen_list)
{
int i;

if (!screen_list->cube.in_switch || !screen_list->eyecandy)
{
wm_refresh_full(screen_list);
// screen_list->force_refresh = 0;
}
else
{
long long unsigned int cur_time = get_us() - screen_list->last_switch;

if (cur_time >= screen_list->cube.duration || screen_list->count == 1)
{
screen_list->changed = 1;
screen_list->force_refresh = 1;
screen_list->cube.in_switch = 0;
}
else
{
float cube[12][3] = {
{-1, -1, 1},
{1, -1, 1},
{1, 1, 1},
{-1, 1, 1},

{1, -1, 1},
{1, -1, -1},
{1, 1, -1},
{1, 1, 1},

{-1, -1, -1},
{-1, -1, 1},
{-1, 1, 1},
{-1, 1, -1},
};

float cube_transformed[12][3];
float cube_projected[12][2];
float fov = 0.5f;
float angle =
90.0f * ((float)cur_time / (float)screen_list->cube.duration);

angle *= (M_PI / 180.0f);

if (screen_list->cube.side == 1)
angle = -angle;

float sina = sin(angle);
float cosa = cos(angle);

for (i = 0; i < 12; i++)
{
cube_transformed[i][2] = cube[i][2] * cosa - cube[i][0] * sina;
cube_transformed[i][0] = cube[i][2] * sina + cube[i][0] * cosa;
cube_transformed[i][1] = cube[i][1];

cube_transformed[i][2] -= 3;

cube_projected[i][0] =
cube_transformed[i][0] / (cube_transformed[i][2] * fov);
cube_projected[i][1] =
cube_transformed[i][1] / (cube_transformed[i][2] * fov);

cube_projected[i][0] /= 2.0f;
cube_projected[i][1] /= 2.0f;
cube_projected[i][0] += 0.5f;
cube_projected[i][1] += 0.5f;

cube_projected[i][0] *= screen_list->width;
cube_projected[i][1] *= screen_list->height;
}

caca_set_color_ansi(screen_list->cv, CACA_WHITE, CACA_BLACK);
caca_clear_canvas(screen_list->cv);

caca_canvas_t *first =
screen_list->screen[screen_list->prevpty]->cv;
caca_canvas_t *second = screen_list->screen[screen_list->pty]->cv;

draw_face(screen_list->cv,
cube_projected[0][0], cube_projected[0][1],
cube_projected[1][0], cube_projected[1][1],
cube_projected[2][0], cube_projected[2][1],
cube_projected[3][0], cube_projected[3][1],
first, CACA_LIGHTGREEN, screen_list->border_size);


if (screen_list->cube.side)
{
draw_face(screen_list->cv,
cube_projected[4][0], cube_projected[4][1],
cube_projected[5][0], cube_projected[5][1],
cube_projected[6][0], cube_projected[6][1],
cube_projected[7][0], cube_projected[7][1],
second, CACA_LIGHTGREEN, screen_list->border_size);
}
else
{
draw_face(screen_list->cv,
cube_projected[8][0], cube_projected[8][1],
cube_projected[9][0], cube_projected[9][1],
cube_projected[10][0], cube_projected[10][1],
cube_projected[11][0], cube_projected[11][1],
second, CACA_LIGHTGREEN, screen_list->border_size);
}

screen_list->changed = 1;
screen_list->force_refresh = 1;
screen_list->cube.in_switch = 1;
}
}
}

Ladataan…
Peruuta
Tallenna