--- bluez-utils-3.8/hidd/fakehid.c 2006-12-29 18:37:41.000000000 -0500 +++ bluez-utils-3.8/hidd/fakehid.c 2007-01-08 23:13:46.000000000 -0500 @@ -522,20 +522,25 @@ } /************************ Logitech Mediapad Driver ******************************** - * (C) 2006 Tim Hentenaar * + * (C) 2006-2007 Tim Hentenaar * * Licensed under the GNU General Public License. * * The latest version of this work is available at http://hentenaar.com * * * + * Updates: * + * Thanks to Glen Rolle for suggesting the single-line write * + * mode, and for showing me a better method for writing chars * + * >= 0x80 from python. + * * * Notes: * - * 1) The i18n for the device isn't currently supported. * - * The way that the i18n works, is that when the device * - * connects, the Winblows app retrieves the respective * - * strings from the device and verifies/updates them. * + * 1) The i18n for the device isn't currently supported. * + * The way that the i18n works, is that when the device * + * connects, the Winblows app retrieves the respective * + * strings from the device and verifies/updates them. * * * - * Simple enough to do, but I'll worry about it later. * - * 2) The '000' key actually sends 3 0's and is not a special key. * - * 3) The "Copy calulator result to clipboard" requires an * - * activation packet that I haven't isolated to date. * + * Simple enough to do, but I'll worry about it later. * + * 2) The '000' key actually sends 3 0's and is not a special key. * + * 3) The "Copy calulator result to clipboard" requires an * + * activation packet that I haven't isolated to date. * * 4) Git-R-Done! * **********************************************************************************/ @@ -586,7 +591,21 @@ {{ 0xA2, 0x10, 0x00, 0x83, 0x11, 0x00, 0x00, 0x00 }, 8}, {{ 0 }, 0} }; + +struct mpcmd write_lcd_single[] = { /* Write a single line of text to the LCD */ + {{ 0xA2, 0x10, 0x00, 0x81, 0x10, 0x00, 0x00, 0x00 }, 8}, + {{ 0xA2, 0x10, 0x00, 0x80, 0x12, 0x10, 0x10, 0x10 }, 8}, + {{ 0xA2, 0x10, 0x00, 0x81, 0x10, 0x00, 0x00, 0x00 }, 8}, + {{ 0xA2, 0x11, 0x00, 0x82, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, 21}, + {{ 0xA2, 0x11, 0x00, 0x82, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, 21}, + {{ 0xA2, 0x11, 0x00, 0x82, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, 21}, + {{ 0xA2, 0x10, 0x00, 0x80, 0x12, 0x10, 0x10, 0x10 }, 8}, + {{ 0xA2, 0x10, 0x00, 0x83, 0x11, 0x00, 0x00, 0x00 }, 8}, + {{ 0 }, 0} +}; + #define N_LCDW_CMDS 14 +#define N_LCDS_CMDS 8 /* LCD Line Flags */ #define LCD_LINE_DISPLAY 0x10 @@ -646,6 +665,20 @@ " \n" " \n" " \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" " \n" " \n"; @@ -713,7 +746,6 @@ while (setclk[i].len != 0) { write(sock,setclk[i].command,setclk[i].len); i++; } } - static void write_lcd_text(int sock, char *text) { char lines[16*9]; struct mpcmd *lcdw = NULL; uint32_t i = 0,z = 0,line = 0; uint8_t f1 = LCD_LINE_DISPLAY, f2 = LCD_LINE_DISPLAY, f3 = LCD_LINE_DISPLAY; @@ -748,10 +780,44 @@ lcdw[12].command[6] = f2; lcdw[12].command[7] = f3; i = 0; while (lcdw[i].len != 0) { write(sock,lcdw[i].command,lcdw[i].len); i++; } free(lcdw); +} + +static void write_lcd_line(int sock, char *text, int lineno) { + char lines[16*3]; struct mpcmd *lcdw = NULL; uint32_t i = 0,z = 0,line = 0; uint8_t f = LCD_LINE_DISPLAY; + + if (!text || sock < 4) return; lineno = (lineno > 3) ? 3 : (lineno <= 0) ? 1 : lineno; + memset(lines,0x20,16*3); z = (strlen(text) > 16*3) ? 16*3 : strlen(text); + for (i=0;i 16) { + f |= LCD_LINE_SCROLL | LCD_2_BUFFERS; + if (z > 16*2) { f &= 0xF0; f |= LCD_3_BUFFERS; } + } + + /* Write the text */ + lcdw[1].command[4 + lineno] = LCD_LINE_INIT; + i = 0; while (lcdw[i].len != 0) { write(sock,lcdw[i].command,lcdw[i].len); i++; } free(lcdw); } int logitech_mediapad(int sock) { - DBusMessage *db_msg, *db_msg_reply; DBusConnection *db_conn = NULL; DBusError db_err; DBusMessageIter db_args; dbus_uint32_t db_u1, db_u2; + DBusMessage *db_msg, *db_msg_reply; DBusConnection *db_conn = NULL; DBusError db_err; DBusMessageIter db_args,db_sub; dbus_uint32_t db_u1, db_u2, db_u3; char buf[25], *cwtmp; struct pollfd p; int fd = 0, mode = 0, discard_keyup = 0, prev_key = 0, icons = 0, on_dbus = 0, last_dbus_poll = 0, ln = 0; memset(&p,0,sizeof(struct pollfd)); p.fd = sock; p.events = POLLIN | POLLHUP | POLLERR; @@ -827,6 +893,60 @@ } } dinovo_dbus_do_reply(db_msg); + } else if (dbus_message_is_method_call(db_msg,"com.hentenaar.Dinovo.MediaPad","WriteLine")) { + /* WriteLine(lineno, text) Max Length: 48 */ + if (dbus_message_iter_init(db_msg,&db_args)) { + if (dbus_message_iter_get_arg_type(&db_args) == DBUS_TYPE_UINT32) dbus_message_iter_get_basic(&db_args,&db_u1); + if (dbus_message_iter_has_next(&db_args)) { + dbus_message_iter_next(&db_args); + if (dbus_message_iter_get_arg_type(&db_args) == DBUS_TYPE_STRING) { + dbus_message_iter_get_basic(&db_args,&cwtmp); + if (cwtmp && strlen(cwtmp) > 0) write_lcd_line(sock,cwtmp,db_u1); + } + } + } + dinovo_dbus_do_reply(db_msg); + } else if (dbus_message_is_method_call(db_msg,"com.hentenaar.Dinovo.MediaPad","WriteTextBin")) { + /* WriteTextBin(chars) Max Length: 144 */ + if (dbus_message_iter_init(db_msg,&db_args)) { + if (dbus_message_iter_get_arg_type(&db_args) == DBUS_TYPE_ARRAY) { + dbus_message_iter_recurse(&db_args,&db_sub); + if ((cwtmp = malloc(1+(16*9)))) { + memset(cwtmp,0,1+(16*9)); + for (db_u1=0;db_u1<=16*9;db_u1++) { + dbus_message_iter_get_basic(&db_sub,&db_u2); + cwtmp[db_u1] = (char)db_u2; + if (dbus_message_iter_has_next(&db_sub)) dbus_message_iter_next(&db_sub); + else break; + } + if (db_u1 > 0) write_lcd_text(sock,cwtmp); + free(cwtmp); + } + } + } + dinovo_dbus_do_reply(db_msg); + } else if (dbus_message_is_method_call(db_msg,"com.hentenaar.Dinovo.MediaPad","WriteLineBin")) { + /* WriteLineBin(lineno, chars) Max Length: 48 */ + if (dbus_message_iter_init(db_msg,&db_args)) { + if (dbus_message_iter_get_arg_type(&db_args) == DBUS_TYPE_UINT32) dbus_message_iter_get_basic(&db_args,&db_u1); + if (dbus_message_iter_has_next(&db_args)) { + dbus_message_iter_next(&db_args); + if (dbus_message_iter_get_arg_type(&db_args) == DBUS_TYPE_ARRAY) { + dbus_message_iter_recurse(&db_args,&db_sub); + if ((cwtmp = malloc(1+(16*3)))) { + memset(cwtmp,0,1+(16*3)); + for (db_u3=0;db_u3<=16*3;db_u3++) { + dbus_message_iter_get_basic(&db_sub,&db_u2); + cwtmp[db_u3] = (char)db_u2; + if (dbus_message_iter_has_next(&db_sub)) dbus_message_iter_next(&db_sub); + else break; + } + if (db_u3 > 0) write_lcd_line(sock,cwtmp,db_u1); free(cwtmp); + } + } + } + } + dinovo_dbus_do_reply(db_msg); } else if (dbus_message_is_method_call(db_msg,"com.hentenaar.Dinovo.MediaPad","SetIndicator")) { /* SetIndicator(indicator, blink) * [ indicator := see LCD_ICON_* above ]