You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

215 line
5.4 KiB

  1. /*
  2. * libcaca ASCII-Art library
  3. * Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
  4. * All Rights Reserved
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the Do What The Fuck You Want To
  8. * Public License, Version 2, as published by Sam Hocevar. See
  9. * http://sam.zoy.org/wtfpl/COPYING for more details.
  10. */
  11. /** \file driver_network.c
  12. * \version \$Id: driver_gl.c 330 2006-03-07 09:17:35Z sam $
  13. * \author Jean-Yves Lamoureux <jylam@lnxscene.org>
  14. * \brief Network driver
  15. *
  16. * This file contains the libcaca network input and output driver
  17. */
  18. #include "config.h"
  19. #if defined(USE_NETWORK)
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <sys/types.h>
  23. #include <sys/socket.h>
  24. #include <arpa/inet.h>
  25. #include <string.h>
  26. #if defined(HAVE_UNISTD_H)
  27. # include <unistd.h>
  28. #endif
  29. #include <stdarg.h>
  30. #include "caca.h"
  31. #include "caca_internals.h"
  32. #include "cucul.h"
  33. #include "cucul_internals.h"
  34. struct driver_private
  35. {
  36. unsigned int width, height;
  37. unsigned int port;
  38. int sockfd, new_fd;
  39. struct sockaddr_in my_addr;
  40. struct sockaddr_in remote_addr;
  41. socklen_t sin_size;
  42. int clilen;
  43. char buffer[256];
  44. };
  45. #define BACKLOG 1337 /* Number of pending connections */
  46. /* Following vars are static */
  47. static char codes[] = {0xff, 0xfb, 0x01, // WILL ECHO
  48. 0xff, 0xfb, 0x03, // WILL SUPPRESS GO AHEAD
  49. 0xff, 253, 31, // DO NAWS
  50. 0xff, 254, 31, // DON'T NAWS
  51. 0xff, 31, 250, 0, 30, 0, 0xFF, // to be replaced
  52. 0xff, 240};
  53. static int network_init_graphics(caca_t *kk)
  54. {
  55. int yes=1;
  56. printf("Initing network stack.\n");
  57. kk->drv.p = malloc(sizeof(struct driver_private));
  58. kk->drv.p->width = 80;
  59. kk->drv.p->height = 24;
  60. kk->drv.p->port = 7575; // 75 75 decimal ASCII -> KK // FIXME, sadly
  61. cucul_set_size(kk->qq, kk->drv.p->width, kk->drv.p->height);
  62. printf("socket\n");
  63. if ((kk->drv.p->sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
  64. perror("socket");
  65. return -1;
  66. }
  67. printf("setsockopt\n");
  68. if (setsockopt(kk->drv.p->sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
  69. perror("setsockopt");
  70. return -1;
  71. }
  72. kk->drv.p->my_addr.sin_family = AF_INET;
  73. kk->drv.p-> my_addr.sin_port = htons(kk->drv.p->port);
  74. kk->drv.p->my_addr.sin_addr.s_addr = INADDR_ANY;
  75. memset(&(kk->drv.p->my_addr.sin_zero), '\0', 8);
  76. printf("bind\n");
  77. if (bind(kk->drv.p->sockfd, (struct sockaddr *)&kk->drv.p->my_addr, sizeof(struct sockaddr))
  78. == -1) {
  79. perror("bind");
  80. return -1;
  81. }
  82. printf("listen\n");
  83. if (listen(kk->drv.p->sockfd, BACKLOG) == -1) {
  84. perror("listen");
  85. return -1;
  86. }
  87. printf("accept\n");
  88. kk->drv.p->clilen = sizeof(kk->drv.p->remote_addr);
  89. kk->drv.p->new_fd = accept(kk->drv.p->sockfd, (struct sockaddr *) &kk->drv.p->remote_addr, &kk->drv.p->clilen);
  90. if (kk->drv.p->new_fd < 0) {
  91. perror("ERROR on accept");
  92. return -1;
  93. }
  94. printf("Got connexion from %d.%d.%d.%d\n",
  95. (unsigned int)((kk->drv.p->remote_addr.sin_addr.s_addr)&0x000000FF),
  96. (unsigned int)((kk->drv.p->remote_addr.sin_addr.s_addr)&0x0000FF00)>>8,
  97. (unsigned int)((kk->drv.p->remote_addr.sin_addr.s_addr)&0x00FF0000)>>16,
  98. (unsigned int)((kk->drv.p->remote_addr.sin_addr.s_addr)&0xFF000000)>>24);
  99. /* FIXME, handle >255 sizes */
  100. codes[16] = (unsigned char) kk->drv.p->width&0xff;
  101. codes[18] = (unsigned char) kk->drv.p->height&0xff;
  102. /* Send basic telnet codes */
  103. if (send(kk->drv.p->new_fd, codes,sizeof(codes) , 0) == -1) {
  104. perror("send");
  105. return -1;
  106. }
  107. printf("network ok.\n");
  108. return 0;
  109. }
  110. static int network_end_graphics(caca_t *kk)
  111. {
  112. printf("network end graphics\n");
  113. return 0;
  114. }
  115. static int network_set_window_title(caca_t *kk, char const *title)
  116. {
  117. printf("network_set_window_title(%s) not implemented yet.\n", title);
  118. return 0;
  119. }
  120. static unsigned int network_get_window_width(caca_t *kk)
  121. {
  122. return kk->drv.p->width * 6;
  123. }
  124. static unsigned int network_get_window_height(caca_t *kk)
  125. {
  126. return kk->drv.p->height * 10;
  127. }
  128. static void network_display(caca_t *kk)
  129. {
  130. int size;
  131. char *to_send = cucul_get_ansi(kk->qq, 0, &size);;
  132. /* ANSI code for move(0,0)*/
  133. if (send(kk->drv.p->new_fd, "\033[1,1H", 6, 0) == -1) {
  134. perror("send");
  135. return;
  136. }
  137. if (send(kk->drv.p->new_fd, to_send, size, 0) == -1) {
  138. perror("send");
  139. return;
  140. }
  141. }
  142. static void network_handle_resize(caca_t *kk)
  143. {
  144. printf("Resize\n");
  145. }
  146. static unsigned int network_get_event(caca_t *kk)
  147. {
  148. return 0;
  149. }
  150. /*
  151. * Driver initialisation
  152. */
  153. void network_init_driver(caca_t *kk)
  154. {
  155. kk->drv.driver = CACA_DRIVER_NETWORK;
  156. kk->drv.init_graphics = network_init_graphics;
  157. kk->drv.end_graphics = network_end_graphics;
  158. kk->drv.set_window_title = network_set_window_title;
  159. kk->drv.get_window_width = network_get_window_width;
  160. kk->drv.get_window_height = network_get_window_height;
  161. kk->drv.display = network_display;
  162. kk->drv.handle_resize = network_handle_resize;
  163. kk->drv.get_event = network_get_event;
  164. }
  165. #endif // USE_NETWORK