$ git clone http://tcclient.ion.nu/tc_client.git
commit 4afd8b6d1d098899efd862622f141c464f2b5741
Author: Alicia <...>
Date:   Thu Dec 17 14:32:12 2015 +0100

    libcamera: added support for cameras on windows through the ESCAPI library.

diff --git a/ChangeLog b/ChangeLog
index 3039054..8a3f66a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,7 @@ Reimplemented announcement of people cammed up when joining.
 libcamera: added support for a virtual "Image" camera.
 tc_client-gtk: added workarounds for the camera code (with the platform-agnostic "Image" camera) to work on windows.
 libcamera: fixed compiler warnings.
+libcamera: added support for cameras on windows through the ESCAPI library.
 0.36:
 Implemented /whois <nick/ID> to check someone's username.
 Changed the /whois output to be more human-readable in cases where the user isn't logged in.
diff --git a/Makefile b/Makefile
index c3d8a8c..c974e26 100644
--- a/Makefile
+++ b/Makefile
@@ -31,6 +31,11 @@ ifdef SWSCALE_LIBS
   endif
   ifneq ($(findstring MINGW,$(shell uname -s)),)
     LDFLAGS+=-mwindows
+    # Using ESCAPI for cam support on windows, http://sol.gfxile.net/escapi/
+    ifneq ($(wildcard escapi),)
+      CFLAGS+=-DHAVE_ESCAPI
+      LIBCAMERA_OBJ+=utilities/libcamera/camera_escapi.o escapi/escapi.o
+    endif
     windowstargets: camviewer tc_client-gtk tc_client-gtk-camthread
  @echo
  @echo 'To build the core (tc_client.exe), enter this directory from cygwin (or MSYS2 non-MinGW shell) and type make'
diff --git a/utilities/libcamera/camera.c b/utilities/libcamera/camera.c
index b89c3b6..e5b2603 100644
--- a/utilities/libcamera/camera.c
+++ b/utilities/libcamera/camera.c
@@ -17,6 +17,7 @@
 #include <string.h>
 #include "camera.h"
 #include "camera_v4l2.h"
+#include "camera_escapi.h"
 #include "camera_img.h"
 
 struct CAM_t
@@ -31,6 +32,9 @@ char** cam_list(unsigned int* count)
   #ifdef HAVE_V4L2
   list=cam_list_v4l2(list, count);
   #endif
+  #ifdef HAVE_ESCAPI
+  list=cam_list_escapi(list, count);
+  #endif
   list=cam_list_img(list, count);
   return list;
 }
@@ -40,6 +44,9 @@ CAM* cam_open(const char* name)
   #ifdef HAVE_V4L2
   if(!strncmp(name, "v4l2:", 5)){return cam_open_v4l2(name);}
   #endif
+  #ifdef HAVE_ESCAPI
+  if(!strncmp(name, "escapi:", 7)){return cam_open_escapi(name);}
+  #endif
   if(!strcmp(name, "Image")){return cam_open_img();}
   return 0;
 }
@@ -51,6 +58,9 @@ void cam_resolution(CAM* cam, unsigned int* width, unsigned int* height)
     #ifdef HAVE_V4L2
     case CAMTYPE_V4L2: cam_resolution_v4l2(cam, width, height); break;
     #endif
+    #ifdef HAVE_ESCAPI
+    case CAMTYPE_ESCAPI: cam_resolution_escapi(cam, width, height); break;
+    #endif
     case CAMTYPE_IMG: cam_resolution_img(cam, width, height); break;
   }
 }
@@ -62,6 +72,9 @@ void cam_getframe(CAM* cam, void* pixmap)
     #ifdef HAVE_V4L2
     case CAMTYPE_V4L2: cam_getframe_v4l2(cam, pixmap); break;
     #endif
+    #ifdef HAVE_ESCAPI
+    case CAMTYPE_ESCAPI: cam_getframe_escapi(cam, pixmap); break;
+    #endif
     case CAMTYPE_IMG: cam_getframe_img(cam, pixmap); break;
   }
 }
@@ -73,6 +86,9 @@ void cam_close(CAM* cam)
     #ifdef HAVE_V4L2
     case CAMTYPE_V4L2: cam_close_v4l2(cam); break;
     #endif
+    #ifdef HAVE_ESCAPI
+    case CAMTYPE_ESCAPI: cam_close_escapi(cam); break;
+    #endif
     case CAMTYPE_IMG: cam_close_img(cam); break;
   }
 }
diff --git a/utilities/libcamera/camera.h b/utilities/libcamera/camera.h
index 049705d..8ec37bc 100644
--- a/utilities/libcamera/camera.h
+++ b/utilities/libcamera/camera.h
@@ -16,6 +16,7 @@
 */
 enum{
   CAMTYPE_V4L2,
+  CAMTYPE_ESCAPI,
   CAMTYPE_IMG
 };
 struct CAM_t;
diff --git a/utilities/libcamera/camera_escapi.cpp b/utilities/libcamera/camera_escapi.cpp
new file mode 100644
index 0000000..9b81af9
--- /dev/null
+++ b/utilities/libcamera/camera_escapi.cpp
@@ -0,0 +1,109 @@
+/*
+    libcamera, a camera access abstraction library
+    Copyright (C) 2015  alicia@ion.nu
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero General Public License as published by
+    the Free Software Foundation, version 3 of the License.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "../../escapi/escapi.h"
+extern "C"
+{
+#include "camera.h"
+
+typedef struct CAM_t
+{
+  unsigned int type;
+  struct SimpleCapParams capture;
+  unsigned int device;
+  unsigned char* buf;
+  char capturing;
+} CAM;
+
+char cam_escapi_init=0;
+
+char** cam_list_escapi(char** list, unsigned int* count)
+{
+  int escapicams;
+  if(cam_escapi_init)
+  {
+    escapicams=countCaptureDevices();
+  }else{
+    cam_escapi_init=1;
+    escapicams=setupESCAPI();
+  }
+  char buf[1024];
+  unsigned int i;
+  for(i=0; i<escapicams; ++i)
+  {
+    sprintf(buf, "escapi:%u:", i);
+    getCaptureDeviceName(i, &buf[strlen(buf)], 1023-strlen(buf));
+    ++*count;
+    list=(char**)realloc(list, sizeof(char*)*(*count));
+    list[(*count)-1]=strdup(buf);
+  }
+  return list;
+}
+
+CAM* cam_open_escapi(const char* name)
+{
+  if(!cam_escapi_init)
+  {
+    cam_escapi_init=1;
+    setupESCAPI();
+  }
+  CAM* cam=(CAM*)malloc(sizeof(CAM));
+  cam->type=CAMTYPE_ESCAPI;
+  cam->capture.mWidth=640;
+  cam->capture.mHeight=480;
+  cam->buf=(unsigned char*)malloc(cam->capture.mWidth*cam->capture.mHeight*4);
+  cam->capture.mTargetBuf=(int*)cam->buf;
+  cam->device=strtoul(&name[7], 0, 10);
+  cam->capturing=initCapture(cam->device, &cam->capture);
+  return cam;
+}
+
+void cam_resolution_escapi(CAM* cam, unsigned int* width, unsigned int* height)
+{
+  if(cam->capturing){deinitCapture(cam->device);}
+  cam->capture.mWidth=*width;
+  cam->capture.mHeight=*height;
+  free(cam->buf);
+  cam->buf=(unsigned char*)malloc(cam->capture.mWidth*cam->capture.mHeight*4);
+  cam->capture.mTargetBuf=(int*)cam->buf;
+  cam->capturing=initCapture(cam->device, &cam->capture);
+}
+
+void cam_getframe_escapi(CAM* cam, void* pixmap)
+{
+  doCapture(0);
+  while(!isCaptureDone(0)){usleep(100);}
+  unsigned int pixels=cam->capture.mWidth*cam->capture.mHeight;
+  unsigned int i;
+  for(i=0; i<pixels; ++i)
+  {
+    // ABGR -> RGB
+    memcpy((unsigned char*)pixmap+(i*3)+2, cam->buf+(i*4), 1);
+    memcpy((unsigned char*)pixmap+(i*3)+1, cam->buf+(i*4)+1, 1);
+    memcpy((unsigned char*)pixmap+(i*3), cam->buf+(i*4)+2, 1);
+  }
+}
+
+void cam_close_escapi(CAM* cam)
+{
+  if(cam->capturing){deinitCapture(cam->device);}
+  free(cam);
+}
+}
diff --git a/utilities/libcamera/camera_escapi.h b/utilities/libcamera/camera_escapi.h
new file mode 100644
index 0000000..57a72ea
--- /dev/null
+++ b/utilities/libcamera/camera_escapi.h
@@ -0,0 +1,21 @@
+/*
+    libcamera, a camera access abstraction library
+    Copyright (C) 2015  alicia@ion.nu
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero General Public License as published by
+    the Free Software Foundation, version 3 of the License.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+extern char** cam_list_escapi(char** list, unsigned int* count);
+extern CAM* cam_open_escapi(const char* name);
+extern void cam_resolution_escapi(CAM* cam, unsigned int* width, unsigned int* height);
+extern void cam_getframe_escapi(CAM* cam, void* pixmap);
+extern void cam_close_escapi(CAM* cam);