doorbell

annotate doorbell-client/src/main.c @ 5:f21ae31ef0e7

craptacular
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 15 Mar 2016 08:35:21 +0200
parents
children dc4018af3a40
rev   line source
nuclear@5 1 #include <stdio.h>
nuclear@5 2 #include <stdlib.h>
nuclear@5 3 #include <string.h>
nuclear@5 4 #include <errno.h>
nuclear@5 5 #include <unistd.h>
nuclear@5 6 #include <fcntl.h>
nuclear@5 7 #include <sys/select.h>
nuclear@5 8 #include <sys/socket.h>
nuclear@5 9 #include <arpa/inet.h>
nuclear@5 10 #include <netdb.h>
nuclear@5 11 #include <GL/glut.h>
nuclear@5 12 #include <GL/freeglut_ext.h>
nuclear@5 13 #include <GL/glx.h>
nuclear@5 14
nuclear@5 15 struct video_block_header {
nuclear@5 16 unsigned int magic;
nuclear@5 17 int frame;
nuclear@5 18 int x, y;
nuclear@5 19 int width, height;
nuclear@5 20 int frame_width, frame_height;
nuclear@5 21 };
nuclear@5 22
nuclear@5 23 int conn(const char *host, int port);
nuclear@5 24 void display(void);
nuclear@5 25 void reshape(int x, int y);
nuclear@5 26 void keyb(unsigned char key, int x, int y);
nuclear@5 27 int handle_conn(int s);
nuclear@5 28 void post_redisplay(void);
nuclear@5 29
nuclear@5 30 int quit;
nuclear@5 31 int srvsock;
nuclear@5 32 const char *address = "localhost";
nuclear@5 33 int port = 2828;
nuclear@5 34 unsigned int tex, tex_width, tex_height;
nuclear@5 35 int redraw_pending;
nuclear@5 36
nuclear@5 37 int main(int argc, char **argv)
nuclear@5 38 {
nuclear@5 39 Display *dpy;
nuclear@5 40 int xsock;
nuclear@5 41
nuclear@5 42 glutInit(&argc, argv);
nuclear@5 43 glutInitWindowSize(800, 600);
nuclear@5 44 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
nuclear@5 45 glutCreateWindow("doorbell");
nuclear@5 46
nuclear@5 47 glutDisplayFunc(display);
nuclear@5 48 glutReshapeFunc(reshape);
nuclear@5 49 glutKeyboardFunc(keyb);
nuclear@5 50
nuclear@5 51 dpy = glXGetCurrentDisplay();
nuclear@5 52 xsock = ConnectionNumber(dpy);
nuclear@5 53
nuclear@5 54 if((srvsock = conn(address, port)) == -1) {
nuclear@5 55 return 1;
nuclear@5 56 }
nuclear@5 57 write(srvsock, "hello", 5);
nuclear@5 58
nuclear@5 59 glGenTextures(1, &tex);
nuclear@5 60 glBindTexture(GL_TEXTURE_2D, tex);
nuclear@5 61 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
nuclear@5 62 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
nuclear@5 63
nuclear@5 64 for(;;) {
nuclear@5 65 int res;
nuclear@5 66 int maxfd = srvsock > xsock ? srvsock : xsock;
nuclear@5 67 struct timeval tv0 = {0, 0};
nuclear@5 68 fd_set rdset;
nuclear@5 69
nuclear@5 70 FD_ZERO(&rdset);
nuclear@5 71 FD_SET(xsock, &rdset);
nuclear@5 72 FD_SET(srvsock, &rdset);
nuclear@5 73
nuclear@5 74 while((res = select(maxfd + 1, &rdset, 0, 0, redraw_pending ? &tv0 : 0) == -1) && errno == EINTR);
nuclear@5 75 if(res == -1) break;
nuclear@5 76
nuclear@5 77 if(redraw_pending || FD_ISSET(xsock, &rdset)) {
nuclear@5 78 glutMainLoopEvent();
nuclear@5 79 if(quit) {
nuclear@5 80 break;
nuclear@5 81 }
nuclear@5 82 }
nuclear@5 83 if(FD_ISSET(srvsock, &rdset)) {
nuclear@5 84 if(handle_conn(srvsock) == -1) {
nuclear@5 85 break;
nuclear@5 86 }
nuclear@5 87 }
nuclear@5 88 }
nuclear@5 89
nuclear@5 90 close(srvsock);
nuclear@5 91 return 0;
nuclear@5 92 }
nuclear@5 93
nuclear@5 94
nuclear@5 95 int conn(const char *hostname, int port)
nuclear@5 96 {
nuclear@5 97 int s;
nuclear@5 98 struct sockaddr_in addr;
nuclear@5 99 struct hostent *host;
nuclear@5 100
nuclear@5 101 if((s = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
nuclear@5 102 fprintf(stderr, "failed to create socket\n");
nuclear@5 103 return -1;
nuclear@5 104 }
nuclear@5 105
nuclear@5 106 if(!(host = gethostbyname(hostname))) {
nuclear@5 107 fprintf(stderr, "failed to resolve hostname: %s\n", hostname);
nuclear@5 108 return -1;
nuclear@5 109 }
nuclear@5 110
nuclear@5 111 memset(&addr, 0, sizeof addr);
nuclear@5 112 addr.sin_family = AF_INET;
nuclear@5 113 addr.sin_port = htons(port);
nuclear@5 114 addr.sin_addr = *(struct in_addr*)host->h_addr;
nuclear@5 115
nuclear@5 116 printf("connecting to %s (%s), port %d\n", hostname, inet_ntoa(addr.sin_addr), port);
nuclear@5 117 if(connect(s, (struct sockaddr*)&addr, sizeof addr) == -1) {
nuclear@5 118 fprintf(stderr, "failed to connect\n");
nuclear@5 119 return -1;
nuclear@5 120 }
nuclear@5 121
nuclear@5 122 fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK);
nuclear@5 123 return s;
nuclear@5 124 }
nuclear@5 125
nuclear@5 126 void display(void)
nuclear@5 127 {
nuclear@5 128 redraw_pending = 0;
nuclear@5 129
nuclear@5 130 glClear(GL_COLOR_BUFFER_BIT);
nuclear@5 131
nuclear@5 132 glMatrixMode(GL_MODELVIEW);
nuclear@5 133 glLoadIdentity();
nuclear@5 134
nuclear@5 135 glPushMatrix();
nuclear@5 136 glScalef(0.75, 0.75, 0.75);
nuclear@5 137
nuclear@5 138 glBindTexture(GL_TEXTURE_2D, tex);
nuclear@5 139 glEnable(GL_TEXTURE_2D);
nuclear@5 140
nuclear@5 141 glBegin(GL_QUADS);
nuclear@5 142 glTexCoord2f(0, 0); glVertex2f(-1, -1);
nuclear@5 143 glTexCoord2f(1, 0); glVertex2f(1, -1);
nuclear@5 144 glTexCoord2f(1, 1); glVertex2f(1, 1);
nuclear@5 145 glTexCoord2f(0, 1); glVertex2f(-1, 1);
nuclear@5 146 glEnd();
nuclear@5 147
nuclear@5 148 glDisable(GL_TEXTURE_2D);
nuclear@5 149 glPopMatrix();
nuclear@5 150
nuclear@5 151 glutSwapBuffers();
nuclear@5 152 }
nuclear@5 153
nuclear@5 154 void reshape(int x, int y)
nuclear@5 155 {
nuclear@5 156 glViewport(0, 0, x, y);
nuclear@5 157 glMatrixMode(GL_PROJECTION);
nuclear@5 158 glLoadIdentity();
nuclear@5 159 }
nuclear@5 160
nuclear@5 161 void keyb(unsigned char key, int x, int y)
nuclear@5 162 {
nuclear@5 163 switch(key) {
nuclear@5 164 case 27:
nuclear@5 165 quit = 1;
nuclear@5 166 break;
nuclear@5 167 }
nuclear@5 168 }
nuclear@5 169
nuclear@5 170 int handle_conn(int s)
nuclear@5 171 {
nuclear@5 172 static int cur_frame;
nuclear@5 173 struct video_block_header hdr;
nuclear@5 174 int size;
nuclear@5 175 unsigned char *pixels;
nuclear@5 176
nuclear@5 177 if(read(s, &hdr, sizeof hdr) != sizeof hdr) {
nuclear@5 178 fprintf(stderr, "failed to read video block header\n");
nuclear@5 179 return -1;
nuclear@5 180 }
nuclear@5 181 if(hdr.frame < cur_frame) {
nuclear@5 182 printf("skipping old frame %d\n", hdr.frame);
nuclear@5 183 }
nuclear@5 184 cur_frame = hdr.frame;
nuclear@5 185 printf("updating block %dx%d%+d%+d in frame %d\n", hdr.width, hdr.height, hdr.x, hdr.y, hdr.frame);
nuclear@5 186
nuclear@5 187 size = hdr.width * hdr.height * 2;
nuclear@5 188 if(!(pixels = malloc(size))) {
nuclear@5 189 fprintf(stderr, "failed to allocate pixel block %dx%d\n", hdr.width, hdr.height);
nuclear@5 190 return -1;
nuclear@5 191 }
nuclear@5 192 if(read(s, pixels, size) != size) {
nuclear@5 193 fprintf(stderr, "failed to read pixel block\n");
nuclear@5 194 return -1;
nuclear@5 195 }
nuclear@5 196
nuclear@5 197 glBindTexture(GL_TEXTURE_2D, tex);
nuclear@5 198
nuclear@5 199 if(tex_width < hdr.frame_width || tex_height < hdr.frame_height) {
nuclear@5 200 tex_width = hdr.frame_width;
nuclear@5 201 tex_height = hdr.frame_height;
nuclear@5 202 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex_width, tex_height, 0,
nuclear@5 203 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0);
nuclear@5 204 }
nuclear@5 205 glTexSubImage2D(GL_TEXTURE_2D, 0, hdr.x, hdr.y, hdr.width, hdr.height,
nuclear@5 206 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
nuclear@5 207
nuclear@5 208 post_redisplay();
nuclear@5 209 return 0;
nuclear@5 210 }
nuclear@5 211
nuclear@5 212 void post_redisplay(void)
nuclear@5 213 {
nuclear@5 214 glutPostRedisplay();
nuclear@5 215 redraw_pending = 1;
nuclear@5 216 }