diff -Nru scanbuttond-0.2.3.org/backends/Makefile.am scanbuttond-0.2.3/backends/Makefile.am
--- scanbuttond-0.2.3.org/backends/Makefile.am	2006-02-17 06:50:53.000000000 +0900
+++ scanbuttond-0.2.3/backends/Makefile.am	2007-07-31 19:54:39.063871631 +0900
@@ -4,7 +4,8 @@
 			libscanbtnd-backend_niash.la \
 			libscanbtnd-backend_plustek.la \
 			libscanbtnd-backend_plustek_umax.la \
-			libscanbtnd-backend_snapscan.la
+			libscanbtnd-backend_snapscan.la \
+			libscanbtnd-backend_epkowa.la
 
 libscanbtnd_backend_epson_la_SOURCES = epson.c epson.h
 libscanbtnd_backend_epson_la_LIBADD = ../interface/libscanbtnd-interface_usb.la
@@ -27,6 +28,9 @@
 libscanbtnd_backend_snapscan_la_SOURCES = snapscan.c snapscan.h
 libscanbtnd_backend_snapscan_la_LIBADD = ../interface/libscanbtnd-interface_usb.la
 libscanbtnd_backend_snapscan_la_LDFLAGS = -version-info 1:0:0
+libscanbtnd_backend_epkowa_la_SOURCES = epkowa.c epkowa.h
+libscanbtnd_backend_epkowa_la_LIBADD = ../interface/libscanbtnd-interface_usb.la
+libscanbtnd_backend_epkowa_la_LDFLAGS = -version-info 1:0:0
 
 pkgsysconfdir = $(sysconfdir)/$(PACKAGE)
 pkgsysconf_DATA = meta.conf
diff -Nru scanbuttond-0.2.3.org/backends/epkowa.c scanbuttond-0.2.3/backends/epkowa.c
--- scanbuttond-0.2.3.org/backends/epkowa.c	1970-01-01 09:00:00.000000000 +0900
+++ scanbuttond-0.2.3/backends/epkowa.c	2007-07-31 19:56:08.028884459 +0900
@@ -0,0 +1,267 @@
+// epkowa.c: Epkowa device backend
+// This file is part of scanbuttond.
+// Copyleft )c( 2005-2006 by Bernhard Stiftner
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// 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
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <syslog.h>
+#include "scanbuttond/scanbuttond.h"
+#include "scanbuttond/libusbi.h"
+#include "epkowa.h"
+
+static char* backend_name = "Epkowa USB";
+
+#define NUM_SUPPORTED_USB_DEVICES 1
+
+static int supported_usb_devices[NUM_SUPPORTED_USB_DEVICES][3] = {
+	{ 0x04b8, 0x012d, 4 }	// Epson GT-S600/GT-F650
+};
+
+// TODO: check if this backend really works on the Epson 2580 too...
+static char* usb_device_descriptions[NUM_SUPPORTED_USB_DEVICES][2] = {
+	   { "Epson", "GT-S600/GT-F650" }
+};
+
+
+static libusb_handle_t* libusb_handle;
+static scanner_t* epkowa_scanners = NULL;
+
+
+// returns -1 if the scanner is unsupported, or the index of the
+// corresponding vendor-product pair in the supported_usb_devices array.
+int epkowa_match_libusb_scanner(libusb_device_t* device)
+{
+	int index;
+	for (index = 0; index < NUM_SUPPORTED_USB_DEVICES; index++) {
+		if (supported_usb_devices[index][0] == device->vendorID &&
+				  supported_usb_devices[index][1] == device->productID) {
+			break;
+		}
+	}
+	if (index >= NUM_SUPPORTED_USB_DEVICES) return -1;
+	return index;
+}
+
+
+void epkowa_attach_libusb_scanner(libusb_device_t* device)
+{
+	const char* descriptor_prefix = "epkowa:libusb:";
+	int index = epkowa_match_libusb_scanner(device);
+	if (index < 0) return; // unsupported
+	scanner_t* scanner = (scanner_t*)malloc(sizeof(scanner_t));
+	scanner->vendor = usb_device_descriptions[index][0];
+	scanner->product = usb_device_descriptions[index][1];
+	scanner->connection = CONNECTION_LIBUSB;
+	scanner->internal_dev_ptr = (void*)device;
+	scanner->lastbutton = 0;
+	scanner->sane_device = (char*)malloc(strlen(device->location) + 
+		strlen(descriptor_prefix) + 1);
+	strcpy(scanner->sane_device, descriptor_prefix);
+	strcat(scanner->sane_device, device->location);
+	scanner->num_buttons = supported_usb_devices[index][2];
+	scanner->is_open = 0;
+	scanner->next = epkowa_scanners;
+	epkowa_scanners = scanner;
+}
+
+
+void epkowa_detach_scanners(void)
+{
+	scanner_t* next;
+	while (epkowa_scanners != NULL) {
+		next = epkowa_scanners->next;
+		free(epkowa_scanners->sane_device);
+		free(epkowa_scanners);
+		epkowa_scanners = next;
+	}
+}
+
+
+void epkowa_scan_devices(libusb_device_t* devices)
+{
+	int index;
+	libusb_device_t* device = devices;
+	while (device != NULL) {
+		index = epkowa_match_libusb_scanner(device);
+		if (index >= 0) 
+			epkowa_attach_libusb_scanner(device);
+		device = device->next;
+	}
+}
+
+
+int epkowa_init_libusb(void)
+{
+	libusb_device_t* devices;
+
+	libusb_handle = libusb_init();
+	devices = libusb_get_devices(libusb_handle);
+	epkowa_scan_devices(devices);
+	return 0;
+}
+
+
+const char* scanbtnd_get_backend_name(void)
+{
+	return backend_name;
+}
+
+
+int scanbtnd_init(void)
+{
+	epkowa_scanners = NULL;
+
+	syslog(LOG_INFO, "epkowa-backend: init");
+	return epkowa_init_libusb();
+}
+
+
+int scanbtnd_rescan(void)
+{
+	libusb_device_t* devices;
+
+	epkowa_detach_scanners();
+	epkowa_scanners = NULL;
+	libusb_rescan(libusb_handle);
+	devices = libusb_get_devices(libusb_handle);
+	epkowa_scan_devices(devices);
+	return 0;
+}
+
+
+const scanner_t* scanbtnd_get_supported_devices(void)
+{
+	return epkowa_scanners;
+}
+
+
+int scanbtnd_open(scanner_t* scanner)
+{
+	int result = -ENOSYS;
+	if (scanner->is_open)
+		return -EINVAL;
+	switch (scanner->connection) {
+		case CONNECTION_LIBUSB:
+			// if devices have been added/removed, return -ENODEV to
+			// make scanbuttond update its device list
+			if (libusb_get_changed_device_count() != 0)
+				return -ENODEV;
+			result = libusb_open((libusb_device_t*)scanner->internal_dev_ptr);
+			break;
+	}
+	if (result == 0)
+		scanner->is_open = 1;
+	return result;
+}
+
+
+int scanbtnd_close(scanner_t* scanner)
+{
+	int result = -ENOSYS;
+	if (!scanner->is_open)
+		return -EINVAL;
+	switch (scanner->connection) {
+		case CONNECTION_LIBUSB:
+			result = libusb_close((libusb_device_t*)scanner->internal_dev_ptr);
+			break;
+	}
+	if (result == 0)
+		scanner->is_open = 0;
+	return result;
+}
+
+
+int epkowa_read(scanner_t* scanner, void* buffer, int bytecount)
+{
+	switch (scanner->connection) {
+		case CONNECTION_LIBUSB:
+			return libusb_read((libusb_device_t*)scanner->internal_dev_ptr, 
+				buffer, bytecount);
+			break;
+	}
+	return -1;
+}
+
+
+int epkowa_write(scanner_t* scanner, void* buffer, int bytecount)
+{
+	switch (scanner->connection) {
+		case CONNECTION_LIBUSB:
+			return libusb_write((libusb_device_t*)scanner->internal_dev_ptr, 
+				buffer, bytecount);
+			break;
+	}
+	return -1;
+}
+
+
+void epkowa_flush(scanner_t* scanner)
+{
+	switch (scanner->connection) {
+		case CONNECTION_LIBUSB:
+			libusb_flush((libusb_device_t*)scanner->internal_dev_ptr);
+			break;
+	}
+}
+
+
+int scanbtnd_get_button(scanner_t* scanner)
+{
+	unsigned char bytes[20];
+	int num_bytes;
+	int button = 0;
+
+	bytes[0] = 0x1e;
+	bytes[1] = 0x85;
+
+	if (!scanner->is_open)
+		return -EINVAL;
+
+	num_bytes = epkowa_write(scanner, (void*)bytes, 2);
+	if (num_bytes != 2) {
+		epkowa_flush(scanner);
+		return 0;
+	}
+
+	num_bytes = epkowa_read(scanner, (void*)bytes, 1);
+	if (num_bytes != 1) {
+		epkowa_flush(scanner);
+		return 0;
+	} 
+
+	button = bytes[0];
+
+	return button;
+}
+
+
+const char* scanbtnd_get_sane_device_descriptor(scanner_t* scanner)
+{
+	return scanner->sane_device;
+}
+
+
+int scanbtnd_exit(void)
+{
+	syslog(LOG_INFO, "epkowa-backend: exit");
+	epkowa_detach_scanners();
+	libusb_exit(libusb_handle);
+	return 0;
+}
diff -Nru scanbuttond-0.2.3.org/backends/epkowa.h scanbuttond-0.2.3/backends/epkowa.h
--- scanbuttond-0.2.3.org/backends/epkowa.h	1970-01-01 09:00:00.000000000 +0900
+++ scanbuttond-0.2.3/backends/epkowa.h	2007-07-31 19:56:01.117116535 +0900
@@ -0,0 +1,24 @@
+// snapscan.h: Snapscan device backend
+// This file is part of scanbuttond.
+// Copyleft )c( 2005 by Bernhard Stiftner
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// 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
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#ifndef __EPSONKOWA_H_INCLUDED
+#define __EPSONKOWA_H_INCLUDED
+
+#include "scanbuttond/backend.h"
+
+#endif
diff -Nru scanbuttond-0.2.3.org/backends/meta.conf scanbuttond-0.2.3/backends/meta.conf
--- scanbuttond-0.2.3.org/backends/meta.conf	2006-02-16 01:43:54.000000000 +0900
+++ scanbuttond-0.2.3/backends/meta.conf	2007-07-31 19:52:59.047229825 +0900
@@ -4,3 +4,4 @@
 libscanbtnd-backend_snapscan.so
 libscanbtnd-backend_niash.so
 libscanbtnd-backend_mustek.so
+libscanbtnd-backend_epkowa.so
