[PATCH] First attempt at integrating brltty and Gnopernicus



Hi Guys.

OK, I sat down yesterday afternoon to look at how hard
it would be to integrate brltty's new BrlAPI as a "braille device"
into Gnopernicus.  And suprisingly, it works already.

What does that mean:
YOu can now use Gnopernicus via this new driver with
every braille display which is supported by BRLTTY.

What do you need:
You need the latest brltty from brltty's subversion repository.
The latest release (brltty 3.2) does not yet contain the
brlapi.
Compile brltty with ./configure --enable-api to enable
the compilation and installation of libbrlapi and necessary header
files.
After installation, and *before* you launch the new brltty, you need
to generate an authentification key. Easiest way to do so is
# echo some-string >/etc/brltty/brlapi-key

What is still left to do:
Someone more experienced with autoconf and automake then I could try
and integrate it such that ttybrl.c is only compiled and linked when
/brltty/brlapi.h is found in some include directory.
Currently, with below patch applied, Gnopernicus has a build
time dependency on brltty, which is perhaps not really nice.

Another problem is that the TTY which is used for
Gnopernicus in brlapi is currently hardcoded to 9 (my setup has
the X console on tty9).  I didn't find a reliable way to
determine this value.  Input on that issue would be appreciated. Maybe
we need a configuration setting for this?  See comments in code.

How to set it up:
In GNopernicus, you need to Activate Braille support, and
then change the Braille device type to "BRLTTY".

OK, be forewarned, it is far from finished, but
basic braille displaying works, and even key transportation
works fine, I haven't figured a sane way to translate
between brltty commands and gnopernicus key codes yet though, mainly
because the BRLILLE_INPUT_TYPE related stuff is a complete
mystery to me, and grep didn't turn up any useful points of reference
either.

Anyway, I'd love to receive comments.  If someone could
take the time to integrate this code into gnopernicus cvs, that would
be great!  Thanks

The patch + new file:

You need two files, the patch, which just patches
braille.c and Makefile.am, and a new file ttybrl.c, which
needs to be copied into gnopernicus/braille/libbrl (the patch also needs to be
applied there).  Here are the necessary files:

Index: Makefile.am
===================================================================
RCS file: /cvs/gnome/gnopernicus/braille/libbrl/Makefile.am,v
retrieving revision 1.10
diff -u -r1.10 Makefile.am
--- Makefile.am	11 Apr 2003 13:11:39 -0000	1.10
+++ Makefile.am	23 May 2003 08:41:16 -0000
@@ -19,6 +19,8 @@
 libbrlincludedir =$(includedir)/gnopernicus-1.0/libbrl
 libbrldir=$(libdir)/gnopernicus-1.0
 
+libbrl_la_LIBADD = -lbrlapi
+
 libbrlinclude_HEADERS = brlxmlapi.h  
 
 libbrl_la_SOURCES = baumbrl.h    \
@@ -30,6 +32,7 @@
 		    sercomm.c    \
 		    baumbrl.c    \
 		    alvabrl.c	 \
+		    ttybrl.c 	 \
 		    braille.c    \
 		    brlxml.c      
 
Index: braille.c
===================================================================
RCS file: /cvs/gnome/gnopernicus/braille/libbrl/braille.c,v
retrieving revision 1.15
diff -u -r1.15 braille.c
--- braille.c	5 May 2003 14:21:20 -0000	1.15
+++ braille.c	23 May 2003 08:41:16 -0000
@@ -48,7 +48,8 @@
   {"DM80P", "BAUM DM80 - 80 cells"},
   {"ALVA380", "ALVABRAILLE 380"},
   {"ALVA544", "ALVABRAILLE 544"},
-  {"ALVA570", "ALVABRAILLE 570"}
+  {"ALVA570", "ALVABRAILLE 570"},
+  {"BRLTTY", "BRLTTY's BrlAPI"}
 
  };
 
@@ -203,6 +204,11 @@
 							strcmp("ALVA570", DeviceName) == 0 )
 		{			
 			rv = alva_brl_open_device (DeviceName, Port, DeviceCallback, CurrentDevice);			
+		}
+		
+		else if (	strcmp("BRLTTY", DeviceName) == 0 )
+		{			
+			rv = brltty_brl_open_device (DeviceName, Port, DeviceCallback, CurrentDevice);			
 		}
 		
 		else if (strcmp("PB40", DeviceName) == 0)
/* ttybrl.c
 *
 * Copyright 2003 Mario Lang
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/*
 * This file implements an interface to BRLTTY's BrlAPI
 *
 * BrlAPI implements generic display access.  This means
 * that every display supported by BRLTTY should work via this
 * driver.
 */

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

#include <glib.h>

#include <brltty/brldefs.h>
#include <brltty/brlapi.h>

#include "braille.h"

typedef struct
{
  int x;
  int y;

  unsigned char key_codes[512];
  unsigned char sensor_codes[32];
} BRLTTY_DEVICE_DATA;

/* Globals */

static GIOChannel *gioch = NULL;
static BRL_DEV_CALLBACK	ClientCallback = NULL;
static BRLTTY_DEVICE_DATA dd;

/* Functions */

/* function brltty_brl_send_dots
 *
 * Send array of dots of length count to brlapi.  Argument blocking is
 * ignored.
 */
int
brltty_brl_send_dots (unsigned char *dots, short count, short blocking)
{
  int len = dd.x * dd.y;
  unsigned char sendbuff[256];
  int i;
			
  if (count > len) return 0;

  /* Gnopernicus's idea of how to arrange braille dots
   * is slightly different from BRLTTY's representation.  Translate that  now
   */
  for (i=0; i < count; i++) {
    unsigned char val = 0;
    if (dots[i] & 0x01) val = val|B1;
    if (dots[i] & 0x02) val = val|B2;
    if (dots[i] & 0x04) val = val|B3;
    if (dots[i] & 0x08) val = val|B4;
    if (dots[i] & 0x10) val = val|B5;
    if (dots[i] & 0x20) val = val|B6;
    if (dots[i] & 0x40) val = val|B7;
    if (dots[i] & 0x80) val = val|B8;
    sendbuff[i] = val;
  }
  if (count < len) {
    memset (&sendbuff[count], 0, len-count);
  }

  if (brlapi_writeBrlDots(sendbuff) == 0) {
    return 1;
  } else {
    return 0;
  }
}

void
brltty_brl_close_device ()
{
  brlapi_leaveTty();
  brlapi_closeConnection();
}

static gboolean
brltty_brl_glib_cb (GIOChannel *source,
		    GIOCondition condition, gpointer data)
{
  brl_keycode_t key;

  BRAILLE_EVENT_CODE bec;
  BRAILLE_EVENT_DATA bed;

  while (brlapi_readCommand(0,&key)==1) {
    fprintf(stderr, "Received command %d\n",key);

    /* TODO: Find a better way to map brltty commands to gnopernicus keys.
     * TODO: Map CR keys to sensors in Gnopernicus. */
    sprintf(&dd.key_codes[0], "DK%02d", key);

    bec = bec_key_codes;
    bed.KeyCodes = dd.key_codes;						
    ClientCallback (bec, &bed);
  }
  return TRUE;
}

int
brltty_brl_open_device (char* DeviceName, short Port,
			BRL_DEV_CALLBACK DeviceCallback,
			BRL_DEVICE *Device)
{
  int rv = 0;
  int fd;

  if ((fd = brlapi_initializeConnection(NULL,NULL)) < 0) {
    fprintf(stderr, "Error opening brlapi connection");
    return 0;
  }

  if (brlapi_getDisplaySize(&dd.x,&dd.y) != 0) {
    fprintf(stderr, "Unable to get display size");
    return 0;
  }

  fprintf(stderr, "BrlAPI detected a %dx%d display\n", dd.x, dd.y);

  Device->CellCount = dd.x * dd.y;
  Device->DisplayCount = 1; /* No status cells implemented yet */

  Device->Displays[0].StartCell = 0;
  Device->Displays[0].Width = dd.x;
  Device->Displays[0].Type = bdt_main;

  /* fill device functions for the upper level */
  Device->send_dots = brltty_brl_send_dots;
  Device->close_device = brltty_brl_close_device;
	
  /* Setup glib polling for the socket fd of brlapi */
  gioch = g_io_channel_unix_new (fd);
  g_io_add_watch (gioch, G_IO_IN | G_IO_PRI, brltty_brl_glib_cb, NULL);

  ClientCallback = DeviceCallback;

  fprintf(stderr,"Requesting TTY 9 (currently hardcoded)");
  /* TODO: Write a function which reliably determines the TTY
     where the X server is running.  No idea how to do this, we might
     need a config setting for this? */
  brlapi_getTty(9,BRLCOMMANDS,NULL);

  return 1;
}

-- 
Happy brailling,
  Mario | Debian Developer <URL:http://debian.org/>
        | Get my public key via finger mlang db debian org
        | 1024D/7FC1A0854909BCCDBE6C102DDFFC022A6B113E44


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]