* added support for Bamboo tablets
authorAristeu Rozanski <aris@localhost.localdomain>
Mon, 26 Jan 2009 16:26:41 +0000 (11:26 -0500)
committerAristeu Rozanski <aris@localhost.localdomain>
Mon, 26 Jan 2009 16:26:41 +0000 (11:26 -0500)
  Patch by: Karsten Festag

src-expresskeys/config_read.c
src-expresskeys/config_write.c
src-expresskeys/defines.h
src-expresskeys/event_loop.c
src-expresskeys/get_device.c
src-expresskeys/main_setup.c
src-expresskeys/mark_info.c
src-expresskeys/on_signal.c
src-expresskeys/tablet.c
src-expresskeys/tablet.h

index 40c2000..fd24144 100644 (file)
@@ -43,6 +43,7 @@ static int st2_prcurve_malloced;
 extern int be_verbose;
 extern int reread_config;
 
+extern const int bbo;
 extern const int bee;
 extern const int i3;
 extern const int i3s;
@@ -301,6 +302,7 @@ static void prune_field(char* field_begin, char* write_buffer)
 static void handle_field(FILE* errorfp, char* read_buffer, void* address,
                                                                const int model)
 {
+       struct bbo_program* pbbo;
        struct bee_program* pbee;
        struct i3_program* pi3;
        struct i3s_program* pi3s;
@@ -311,6 +313,7 @@ static void handle_field(FILE* errorfp, char* read_buffer, void* address,
        struct touch_data* tdp = NULL;
        struct wheel_data* wdp = NULL;
        struct button_data* bdp = NULL;
+       struct bbo_configstrings* cbbo;
        struct bee_configstrings* cbee;
        struct i3_configstrings* ci3;
        struct i3s_configstrings* ci3s;
@@ -322,7 +325,18 @@ static void handle_field(FILE* errorfp, char* read_buffer, void* address,
        struct wheel_string* wsp = NULL;
        struct button_string* bsp = NULL;
 
-       if (model == bee) {
+       if (model == bbo) {
+               pbbo = address;
+               cdp = &pbbo->common_data;
+               wdp = &pbbo->wheel_data;
+               tdp = &pbbo->touch_data;
+               bdp = &pbbo->button_data;
+               cbbo = bbo_configstrings;
+               csp = &cbbo->common_string;
+               tsp = &cbbo->touch_string;
+               wsp = &cbbo->wheel_string;
+               bsp = &cbbo->button_string;
+       } else if (model == bee) {
                pbee = address;
                cdp = &pbee->common_data;
                tdp = &pbee->touch_data;
@@ -451,7 +465,7 @@ static void handle_field(FILE* errorfp, char* read_buffer, void* address,
        }
 /* HandleTouchStrips TouchRepeatAfter DelayTouchRepeat
  LeftPadTouchUp LeftPadTouchDown RepeatLeftUp RepeatLeftDown */
-       if (model == i3s || model == i3 || model == bee) {
+       if (model == i3s || model == i3 || model == bee || model == bbo) {
                if (((field = (strstr(read_buffer, tsp->handle_touch))) != NULL)
                        && (((comment = (strchr(read_buffer, '#'))) == NULL)
                                                || (field < comment))) {
@@ -507,7 +521,7 @@ static void handle_field(FILE* errorfp, char* read_buffer, void* address,
                }
        }
 /* HandleScrollWheel ScrollWheelUp ScrollWheelDown */
-       if (model == g4) {
+       if (model == g4 || model == bbo) {
                if (((field = (strstr(read_buffer, wsp->handle_wheel))) != NULL)
                        && (((comment = (strchr(read_buffer, '#'))) == NULL)
                                                || (field < comment))) {
@@ -536,7 +550,7 @@ static void handle_field(FILE* errorfp, char* read_buffer, void* address,
  LeftPadButton9/LeftButton
  RepeatButton9/RepeatLeft */
        if (model == i3s || model == i3 || model == g4 || model == g4b ||
-                                                         model == bee) {
+                                         model == bbo || model == bee) {
                if (((field = (strstr(read_buffer, bsp->repeat_after)))!= NULL)
                        && (((comment = (strchr(read_buffer, '#'))) == NULL)
                                                || (field < comment))) {
@@ -585,7 +599,7 @@ static void handle_field(FILE* errorfp, char* read_buffer, void* address,
        }
 
 /* LeftPadButton11 LeftPadButton12 RepeatButton11 RepeatButton12 */
-       if (model == i3s || model == i3 || model == bee) {
+       if (model == i3s || model == i3 || model == bbo || model == bee) {
                if (((field = (strstr(read_buffer, bsp->button11))) != NULL)
                        && (((comment = (strchr(read_buffer, '#'))) == NULL)
                                                || (field < comment))) {
@@ -768,12 +782,14 @@ static void read_body(FILE* errorfp, void* address, const int model,
        st1_prcurve_malloced = 0;
        st2_prcurve_malloced = 0;
 
+       struct bbo_program* pbbo = NULL;
        struct bee_program* pbee = NULL;
        struct i3_program* pi3 = NULL;
        struct i3s_program* pi3s = NULL;
        struct g4_program* pg4 = NULL;
        struct g4b_program* pg4b = NULL;
        struct nop_program* pnop = NULL;
+       struct bbo_program* pbbo_base = NULL;
        struct bee_program* pbee_base = NULL;
        struct i3_program* pi3_base = NULL;
        struct i3s_program* pi3s_base = NULL;
@@ -781,7 +797,14 @@ static void read_body(FILE* errorfp, void* address, const int model,
        struct g4b_program* pg4b_base = NULL;
        struct nop_program* pnop_base = NULL;
 
-       if (model == bee) {
+       if (model == bbo) {
+               pbbo = address;
+               pbbo_base = pbbo;
+               if (reread_config) {
+                       pbbo->default_program = NULL;
+                       pbbo->common_data.num_record = 0;
+               }
+       } else if (model == bee) {
                pbee = address;
                pbee_base = pbee;
                if (reread_config) {
@@ -908,7 +931,9 @@ static void read_body(FILE* errorfp, void* address, const int model,
                                continue;
                        }
 
-                       if (pbee) {
+                       if (pbbo) {
+                               handle_field(errorfp, read_buffer, pbbo, model);
+                       } else if (pbee) {
                                handle_field(errorfp, read_buffer, pbee, model);
                        } else if (pi3) {
                                handle_field(errorfp, read_buffer, pi3, model);
@@ -925,7 +950,42 @@ static void read_body(FILE* errorfp, void* address, const int model,
 
 /* End field loop*/
 
-               if (pbee) {
+               if (pbbo) {
+                       if (pbbo->common_data.class_name == NULL) {
+                               revert_config = 1;
+                               if (pbbo->common_data.stylus1_presscurve
+                                                               != NULL) {
+                               free(pbbo->common_data.stylus1_presscurve);
+                               st1_prcurve_malloced = 0;
+                               pbbo->common_data.stylus1_presscurve = NULL;
+                               }
+                               if (pbbo->common_data.stylus2_presscurve
+                                                               != NULL) {
+                               free(pbbo->common_data.stylus2_presscurve);
+                               st2_prcurve_malloced = 0;
+                               pbbo->common_data.stylus2_presscurve = NULL;
+                               }
+                       }
+                       if ((pbbo->common_data.class_name != NULL)
+                               && (strcmp(pbbo->common_data.class_name,
+                                                       def_rec) == 0)) {
+                               pbbo_base->default_program = pbbo;
+                       }
+                       if (pbbo->common_data.class_name != NULL) {
+                               pgr_recname_malloced = 0;
+                               revert_config = 0;
+                               num_record++;
+                               if (pbbo->common_data.stylus1_presscurve
+                                                               != NULL) {
+                                       st1_prcurve_malloced = 0;
+                               }
+                               if (pbbo->common_data.stylus2_presscurve
+                                                               != NULL) {
+                                       st2_prcurve_malloced = 0;
+                               }
+                               pbbo++;
+                       }
+               } else if (pbee) {
                        if (pbee->common_data.class_name == NULL) {
                                revert_config = 1;
                                if (pbee->common_data.stylus1_presscurve
@@ -1142,7 +1202,13 @@ static void read_body(FILE* errorfp, void* address, const int model,
 
        fclose(fp);
 
-       if (model == bee) {
+       if (model == bbo) {
+               pbbo = address;
+               if (pbbo->default_program == NULL) {
+                       no_default = 1;
+               }
+               pbbo->common_data.num_record = num_record;
+       } else if (model == bee) {
                pbee = address;
                if (pbee->default_program == NULL) {
                        no_default = 1;
@@ -1309,6 +1375,25 @@ void read_config(FILE* errorfp)
        mip = model_list;
 
        for (i = 0; i < MAXPAD; i++, mip++) {
+               if (mip->bbo->common_data.configfile) {
+                       if (be_verbose) {
+                               fprintf(stderr, "%s %s\n", our_cnffile,
+                               mip->bbo->common_data.configfile);
+                       }
+
+                       if ((k = read_header(errorfp, write_buffer,
+                                       mip->bbo->common_data.configfile))) {
+                               mip->bbo->common_data.userconfigversion = k;
+                               if (be_verbose) {
+                                       print_device(stderr,
+                                               mip->bbo->common_data.padname,
+                                               mip->bbo->common_data.sty1name,
+                                               mip->bbo->common_data.sty2name);
+                               }
+                               read_body(errorfp, mip->bbo, bbo,
+                                       mip->bbo->common_data.configfile);
+                       }
+               }
                if (mip->bee->common_data.configfile) {
                        if (be_verbose) {
                                fprintf(stderr, "%s %s\n", our_cnffile,
index 622e700..b6e832a 100644 (file)
@@ -30,6 +30,7 @@ const char* configversion = "4";
 
 /* Externals: */
 
+extern const int bbo;
 extern const int bee;
 extern const int i3;
 extern const int i3s;
@@ -37,6 +38,7 @@ extern const int g4;
 extern const int g4b;
 extern const int nop;
 
+extern const int bbo_num_list;
 extern const int bee_num_list;
 extern const int i3_num_list;
 extern const int i3s_num_list;
@@ -47,6 +49,124 @@ extern const int nop_num_list;
 extern const char* our_prog_name;
 
 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Write a set of records tuned for a Bamboo tablet:
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+static void write_bbo(FILE* fp)
+{
+       int i;
+
+       const char* new_record =
+"%%                    # <---  ******** BEGIN NEW PROGRAM RECORD ********\n\n";
+       const char* name_tail = "# Name must be within double quotes \"\"";
+       const char* cur_tail = "# PressCurve must be within double quotes \"\"";
+       const char* sec_tail = "# Seconds (Max 10 - Min 0.01 - Or no delay)";
+       const char* tch_onoff = "# Switch 1/0 (Enable/Disable Touch Ring, not yet functional)";
+       const char* whl_onoff = "# Switch 1/0 (Enable/Disable Scroll Wheel)";
+       const char* key_tail = "# Keycodes (Max number of keys to send is";
+       const char* tht_tail = "# Switch 1/0 (Finger held at top repeat keys)";
+       const char* thb_tail="# Switch 1/0 (Finger held at bottom repeat keys)";
+       const char* but_tail= "# Switch 1/0 (Press and hold button repeat keys)";
+
+       struct bbo_program* ip;
+       ip = bbo_internal_list;
+       struct bbo_configstrings* sp;
+       sp = bbo_configstrings;
+
+       for (i = 0; i < bbo_num_list; i++, ip++) {
+
+               fprintf(fp, "%s", new_record);
+
+               fprintf(fp, "%s         \"%s\" %s\n\n",
+               sp->common_string.class_name, ip->common_data.class_name,
+                                                               name_tail);
+
+               fprintf(fp, "%s \"%s\" %s\n",
+               sp->common_string.stylus1_presscurve,
+                               ip->common_data.stylus1_presscurve, cur_tail);
+               fprintf(fp, "%s \"%s\" %s\n\n",
+               sp->common_string.stylus2_presscurve,
+                               ip->common_data.stylus2_presscurve, cur_tail);
+
+               fprintf(fp, "%s %i.%i   %s\n\n",
+               sp->common_string.keycode_delay, *ip->common_data.keycode_delay,
+                               *(ip->common_data.keycode_delay+1), sec_tail);
+
+               fprintf(fp, "%s %i.%i   %s\n",
+               sp->button_string.repeat_after, *ip->button_data.repeat_after,
+                               *(ip->button_data.repeat_after+1), sec_tail);
+               fprintf(fp, "%s %i.%i   %s\n\n",
+               sp->button_string.repeat_delay, *ip->button_data.repeat_delay,
+                               *(ip->button_data.repeat_delay+1), sec_tail);
+
+               fprintf(fp, "%s %i.%i   %s\n",
+               sp->touch_string.repeat_after, *ip->touch_data.repeat_after,
+                               *(ip->touch_data.repeat_after+1), sec_tail);
+               fprintf(fp, "%s %i.%i   %s\n\n",
+               sp->touch_string.repeat_delay, *ip->touch_data.repeat_delay,
+                               *(ip->touch_data.repeat_delay+1), sec_tail);
+
+               fprintf(fp, "%s %i      %s\n\n",
+               sp->touch_string.handle_touch,
+                               *ip->touch_data.handle_touch, tch_onoff);
+
+               fprintf(fp, "%s         %i %i   %s %i)\n",
+               sp->touch_string.left_touch_up,
+                       *ip->touch_data.left_touch_up,
+                       *(ip->touch_data.left_touch_up+1), key_tail, MAXKEYS);
+               fprintf(fp, "%s %i %i   %s %i)\n\n",
+               sp->touch_string.left_touch_down,
+                       *ip->touch_data.left_touch_down,
+                       *(ip->touch_data.left_touch_down+1), key_tail, MAXKEYS);
+
+               fprintf(fp, "%s         %i      %s\n",
+               sp->touch_string.repeat_left_up,
+                               *ip->touch_data.repeat_left_up, tht_tail);
+               fprintf(fp, "%s         %i      %s\n\n",
+               sp->touch_string.repeat_left_down,
+                               *ip->touch_data.repeat_left_down, thb_tail);
+
+               fprintf(fp, "%s %i      %s\n\n",
+               sp->wheel_string.handle_wheel,
+                               *ip->wheel_data.handle_wheel, whl_onoff);
+
+               fprintf(fp, "%s         %i %i   %s %i)\n",
+               sp->wheel_string.scroll_wheel_up,
+                       *ip->wheel_data.scroll_wheel_up,
+                       *(ip->wheel_data.scroll_wheel_up+1), key_tail, MAXKEYS);
+               fprintf(fp, "%s         %i %i   %s %i)\n\n",
+               sp->wheel_string.scroll_wheel_down,
+                       *ip->wheel_data.scroll_wheel_down,
+                       *(ip->wheel_data.scroll_wheel_down+1),key_tail,MAXKEYS);
+
+               fprintf(fp, "%s         %i %i   %s %i)\n",
+               sp->button_string.button9, *ip->button_data.button9,
+                               *(ip->button_data.button9+1), key_tail,MAXKEYS);
+               fprintf(fp, "%s         %i %i   %s %i)\n\n",
+               sp->button_string.button10, *ip->button_data.button10,
+                               *(ip->button_data.button10+1),key_tail,MAXKEYS);
+               fprintf(fp, "%s         %i %i   %s %i)\n",
+               sp->button_string.button11, *ip->button_data.button11,
+                               *(ip->button_data.button9+1), key_tail,MAXKEYS);
+               fprintf(fp, "%s         %i %i   %s %i)\n\n",
+               sp->button_string.button12, *ip->button_data.button12,
+                               *(ip->button_data.button10+1),key_tail,MAXKEYS);
+
+               fprintf(fp, "%s         %i      %s\n",
+               sp->button_string.repeat9, *ip->button_data.repeat9, but_tail);
+               fprintf(fp, "%s         %i      %s\n\n",
+               sp->button_string.repeat10, *ip->button_data.repeat10,but_tail);
+               fprintf(fp, "%s         %i      %s\n",
+               sp->button_string.repeat11, *ip->button_data.repeat11, but_tail);
+               fprintf(fp, "%s         %i      %s\n\n",
+               sp->button_string.repeat12, *ip->button_data.repeat12,but_tail);
+
+       }
+
+}
+
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  Write a set of records tuned for a Cintiq 20wsx/'bee' tablet:
  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
 
@@ -640,7 +760,24 @@ static void write_preface(FILE* fp, const int model)
 "# Some ASCII art showing the \"default\" program record:\n"
 "#\n";
 
-       const char *model_bee =
+       const char* model_bbo =
+"#      Bamboo ExpressKeys Pad\n"
+"# -------------------------------\n"
+"# |     9    / TOUCH \\    11    | \n"
+"# |---------| (WHEEL)  |----------| \n"
+"# |    10    \\ RING  /    12    | \n"
+"# -------------------------------\n"
+"# Bamboo defaults are:"
+"# Button 9  = (left) Alt + Cursor Left     = keycode 64 + 100\n"
+"# Button 10 = (left) Alt                   = keycode 64\n"
+"# Button 11 = (left) Alt + Cursor Right    = keycode 64 + 102\n"
+"# Button 12 = (left) Control               = keycode 37\n"
+"# The Touch Ring currently acts only as wheel, though\n"
+"# technically it is able to send position signals \n"
+"# depending on where you press your finger on it \n"
+"# \n";
+
+       const char* model_bee =
 "# Cintiq 20 ExpressKeys Pad\n"
 "#             Left         Right\n"
 "#           +---+---+    +---+---+\n"
@@ -758,6 +895,9 @@ static void write_preface(FILE* fp, const int model)
                fprintf(fp, "%s", model_notnop1);
        }
 
+       if (model == bbo)
+               fprintf(fp, "%s", model_bbo);
+
        if (model == bee)
                fprintf(fp, "%s", model_bee);
 
@@ -806,7 +946,9 @@ static void write_if_lacking(FILE* errorfp, const char* configfile, int model)
 
                write_preface(fp, model);
 
-               if (model == bee) {
+               if (model == bbo) {
+                       write_bbo(fp);
+               } else if (model == bee) {
                        write_bee(fp);
                } else if (model == i3) {
                        write_i3(fp);
@@ -843,9 +985,14 @@ void write_config(FILE* errorfp)
        mip = model_list;
 
        for (i = 0; i < MAXPAD; i++, mip++) {
-               if (mip->bee->common_data.configfile)
+               if (mip->bbo->common_data.configfile) {
+                       write_if_lacking(errorfp,
+                                       mip->bbo->common_data.configfile, bbo);
+               }
+               if (mip->bee->common_data.configfile) {
                        write_if_lacking(errorfp,
                                        mip->bee->common_data.configfile, bee);
+               }
                if (mip->i3->common_data.configfile) {
                        write_if_lacking(errorfp,
                                        mip->i3->common_data.configfile, i3);
index dba9f92..4ddfdfb 100644 (file)
@@ -31,8 +31,8 @@ extern void exit_on_error(FILE* errorfp, char* string1, const char* string2,
 the longest keyword (currently RightPadTouchDown + a space = 18) + 32 keycodes
 of max 4 digits length + a space between each of them (sum 178): */
 #define MAXBUFFER 180
-/* 'Models': padless, Graphire4 BlueTooth, Graphire4, Intuos3 small, Intuos3, Bee */
-#define MAXMODEL 6
+/* 'Models': padless, Graphire4 BlueTooth, Graphire4, Intuos3 small, Intuos3, Bee, Bamboo */
+#define MAXMODEL 7
 /* Max number of tablets per 'model': */
 #define MAXPAD 3
 /* Max number of styli per tablet: */
index 98cd752..b6790c3 100644 (file)
@@ -39,6 +39,7 @@ static unsigned long int* id_sty2;
 
 /* Crucial flags to keep track of the event state
  (except for the is_pad. But the future...): */
+static int is_bbo;
 static int is_bee;
 static int is_i3;
 static int is_i3s;
@@ -311,6 +312,11 @@ static void prepare_action(int fake_key, int which_action)
 
        mip = model_list;
        for (i = 0; i < MAXPAD; i++, mip++) {
+               if ((mip->bbo->common_data.sty1id != NULL)
+               && (mip->bbo->common_data.sty1id == id_sty1)) {
+                       cdp = &mip->bbo->common_data;
+                       break;
+               }
                if ((mip->bee->common_data.sty1id != NULL)
                && (mip->bee->common_data.sty1id == id_sty1)) {
                        cdp = &mip->bee->common_data;
@@ -548,6 +554,7 @@ static void do_repeat(void* base_address, void* record_address,
        XDeviceButtonEvent* tmp_button;
        XDeviceMotionEvent* tmp_motion;
 
+       struct bbo_program* pbbo;
        struct bee_program* pbee;
        struct i3_program* pi3;
        struct i3s_program* pi3s;
@@ -559,7 +566,14 @@ static void do_repeat(void* base_address, void* record_address,
        struct button_data* bdp = NULL;
        struct touch_data* tdp = NULL;
 
-       if (is_bee) {
+       if (is_bbo) {
+               pbbo = base_address;
+               base_cdp = &pbbo->common_data;
+               pbbo = record_address;
+               cdp = &pbbo->common_data;
+               bdp = &pbbo->button_data;
+               tdp = &pbbo->touch_data;
+       }else if (is_bee) {
                pbee = base_address;
                base_cdp = &pbee->common_data;
                pbee = record_address;
@@ -986,13 +1000,18 @@ static void do_motion(void* base_address, void* record_address,
                rotation = motion->axis_data[0];
        }
 
+       struct bbo_program* pbbo;
        struct bee_program* pbee;
        struct i3_program* pi3;
        struct i3s_program* pi3s;
        struct common_data* cdp = NULL;
        struct touch_data* tdp = NULL;
 
-       if (is_bee) {
+       if (is_bbo) {
+               pbbo = record_address;
+               cdp = &pbbo->common_data;
+               tdp = &pbbo->touch_data;
+       } else if (is_bee) {
                pbee = record_address;
                cdp = &pbee->common_data;
                tdp = &pbee->touch_data;
@@ -1187,6 +1206,7 @@ static void do_button(void* base_address, void* record_address,
        int repeat_button = 0;
        int ok_button = 0;
 
+       struct bbo_program* pbbo;
        struct bee_program* pbee;
        struct i3_program* pi3;
        struct i3s_program* pi3s;
@@ -1197,7 +1217,12 @@ static void do_button(void* base_address, void* record_address,
        struct button_data* bdp = NULL;
        struct wheel_data* wdp = NULL;
 
-       if (is_bee) {
+       if (is_bbo) {
+               pbbo = record_address;
+               cdp = &pbbo->common_data;
+               bdp = &pbbo->button_data;
+               wdp = &pbbo->wheel_data;
+       } else if (is_bee) {
                pbee = record_address;
                cdp = &pbee->common_data;
                bdp = &pbee->button_data;
@@ -1399,6 +1424,7 @@ configuration file *\n");
 
 static void do_stylus(void* base_address, void* record_address)
 {
+       struct bbo_program* pbbo;
        struct bee_program* pbee;
        struct i3_program* pi3;
        struct i3s_program* pi3s;
@@ -1409,7 +1435,12 @@ static void do_stylus(void* base_address, void* record_address)
        struct common_data* cdp = NULL;
        struct common_data* base_cdp = NULL;
 
-       if (is_bee) {
+       if (is_bbo) {
+               pbbo = base_address;
+               base_cdp = &pbbo->common_data;
+               pbbo = record_address;
+               cdp = &pbbo->common_data;
+       } else if (is_bee) {
                pbee = base_address;
                base_cdp = &pbee->common_data;
                pbee = record_address;
@@ -1506,6 +1537,7 @@ static void* find_focus(void* record_address, XEvent Event)
        focus_window = None;
        name_change = 0;
 
+       struct bbo_program* pbbo;
        struct bee_program* pbee;
        struct i3_program* pi3;
        struct i3s_program* pi3s;
@@ -1551,7 +1583,48 @@ static void* find_focus(void* record_address, XEvent Event)
 "--------------------------------------------------------------------------\n");
        }
 
-       if (is_bee) {
+       if (is_bbo) {
+               pbbo = record_address;
+               if ((focus_window == root) || (class_hint->res_class == NULL)) {
+                       record_address = pbbo->default_program;
+                       pbbo = record_address;
+                       if (be_verbose) {
+                               fprintf(stderr, "%s %s\n", prog_focus,
+                                               pbbo->common_data.class_name);
+                       }
+                       if (strcmp(namebuffer, pbbo->common_data.class_name)
+                                                                       != 0) {
+                               snprintf(namebuffer, MAXBUFFER, "%s",
+                                               pbbo->common_data.class_name);
+                               name_change = 1;
+                       }
+                       goto clean_up;
+               }
+               for (i = 0; i < record_num; i++, pbbo++) {
+                       if (strcmp(class_hint->res_class,
+                                       pbbo->common_data.class_name) == 0) {
+                               in_list = 1;
+                               break;
+                       }
+               }
+               if (!in_list) {
+                       pbbo = record_address;
+                       record_address = pbbo->default_program;
+                       pbbo = record_address;
+               } else {
+                       record_address = pbbo;
+               }
+               if (be_verbose) {
+                       fprintf(stderr, "%s %s\n", prog_focus,
+                                               pbbo->common_data.class_name);
+               }
+               if (strcmp(namebuffer, pbbo->common_data.class_name) != 0) {
+                       snprintf(namebuffer, MAXBUFFER, "%s",
+                                               pbbo->common_data.class_name);
+                       name_change = 1;
+               }
+               goto clean_up;
+       } else if (is_bee) {
                pbee = record_address;
                if ((focus_window == root) || (class_hint->res_class == NULL)) {
                        record_address = pbee->default_program;
@@ -1827,6 +1900,42 @@ static void* match_id(XDeviceButtonEvent* button, XDeviceMotionEvent* motion)
        if (button) {
                mip = model_list;
                for (i = 0; i < MAXPAD; i++, mip++) {
+                       if ((mip->bbo->common_data.padid != NULL
+                       && *mip->bbo->common_data.padid ==
+                                       button->deviceid)
+                       || (mip->bbo->common_data.sty1id != NULL
+                       && *mip->bbo->common_data.sty1id ==
+                                       button->deviceid)
+                       || (mip->bbo->common_data.sty2id != NULL
+                       && *mip->bbo->common_data.sty2id ==
+                                       button->deviceid)) {
+                               if (mip->bbo->default_program == NULL) {
+                                       return NULL;
+                               }
+                               if (mip->bbo->common_data.padid != NULL
+                               && *mip->bbo->common_data.padid ==
+                                                       button->deviceid) {
+                                       is_pad = 1;
+                                       id_pad = mip->bbo->common_data.padid;
+                               } else if (mip->bbo->common_data.sty1id != NULL
+                               && *mip->bbo->common_data.sty1id ==
+                                                       button->deviceid) {
+                                       is_sty1 = 1;
+                               } else if (mip->bbo->common_data.sty2id != NULL
+                               && *mip->bbo->common_data.sty2id ==
+                                                       button->deviceid) {
+                                       is_sty2 = 1;
+                               }
+                               is_bbo = 1;
+                               record_num = mip->bbo->common_data.num_record;
+                               if (mip->bbo->common_data.sty1id != NULL) {
+                                       id_sty1 = mip->bbo->common_data.sty1id;
+                               }
+                               if (mip->bbo->common_data.sty2id != NULL) {
+                                       id_sty2 = mip->bbo->common_data.sty2id;
+                               }
+                               return mip->bbo;
+                       }
                        if ((mip->bee->common_data.padid != NULL
                        && *mip->bee->common_data.padid ==
                                        button->deviceid)
@@ -2037,6 +2146,24 @@ static void* match_id(XDeviceButtonEvent* button, XDeviceMotionEvent* motion)
        } else if (motion) {
                mip = model_list;
                for (i = 0; i < MAXPAD; i++, mip++) {
+                       if ((mip->bbo->common_data.padid != NULL)
+                       && (*mip->bbo->common_data.padid
+                                       == motion->deviceid)) {
+                               if (mip->bbo->default_program == NULL) {
+                                       return NULL;
+                               }
+                               is_pad = 1;
+                               is_bbo = 1;
+                               id_pad = mip->bbo->common_data.padid;
+                               record_num = mip->bbo->common_data.num_record;
+                               if (mip->bbo->common_data.sty1id != NULL) {
+                                       id_sty1 = mip->bbo->common_data.sty1id;
+                               }
+                               if (mip->bbo->common_data.sty2id != NULL) {
+                                       id_sty2 = mip->bbo->common_data.sty2id;
+                               }
+                               return mip->bbo;
+                       }
                        if ((mip->bee->common_data.padid != NULL)
                        && (*mip->bee->common_data.padid
                                        == motion->deviceid)) {
@@ -2150,6 +2277,7 @@ void use_events()
                        }
                }
 
+               is_bbo = 0;
                is_bee = 0;
                is_i3 = 0;
                is_i3s = 0;
index f8626af..c84c7cd 100644 (file)
@@ -43,6 +43,7 @@ int proximity_in_type;
 int proximity_out_type;
 
 /* Used in many situations as identification, for math and for flow control: */
+const int bbo = 6;
 const int bee = 5;
 const int i3 = 4;
 const int i3s = 3;
@@ -143,6 +144,7 @@ static int identify_device(char* device_name)
        const char* g4_4x5 = "21"; /* 0x15 */
        const char* g4_6x8 = "22"; /* 0x16 */
        const char* g4b_6x8 = "129"; /* 0x81 */
+       const char* bamboo = "101"; /* 0x65 */
 
 /* Minimum xsetwacom version we can use is 0.0.7 */
        const int min_xsetwacom = 7;
@@ -211,6 +213,9 @@ static int identify_device(char* device_name)
 
                if (ok_value) {
                        len = strcspn(read_buffer, " \t\n");
+                       if ((strncmp(read_buffer, bamboo, len)) == 0) {
+                               return bbo;
+                       }
                        if ((strncmp(read_buffer, cintiq_20wsx, len)) == 0) {
                                return bee;
                        }
index 04be4ec..5307e3a 100644 (file)
@@ -105,7 +105,7 @@ int main(int argc, char* argv[])
 "features, or none at all, will be available.\n\n";
 
        const char* no_tablet =
-"ERROR: Tablet not attached, OR (in case of Cintiq 21UX, Intuos3\n"
+"ERROR: Tablet not attached, OR (in case of Bamboo, Cintiq 21UX, Intuos3\n"
 "and Graphire4) the 'pad' device has not been specified in xorg.conf, OR is\n"
 "lacking on the command line when using \"named devices\".\n";
 
index 7f0f948..0cc8297 100644 (file)
@@ -44,12 +44,16 @@ const char* total_file3_intuos3;
 const char* total_file1_bee;
 const char* total_file2_bee;
 const char* total_file3_bee;
+const char* total_file1_bbo;
+const char* total_file2_bbo;
+const char* total_file3_bbo;
 
 /* Externals: */
 
 extern int have_pad;
 extern int have_padless;
 
+extern const int bbo;
 extern const int bee;
 extern const int i3;
 extern const int i3s;
@@ -83,6 +87,20 @@ static void mark_device(const char* device, int row, int column,
                                                        const char* configfile)
 {
        if (device == pad_string) {
+               if (row == bbo) {
+                       struct bbo_program* p = NULL;
+                       if (column == 0) {
+                               p = bbo_1_external_list;
+                       } else if (column == 1) {
+                               p = bbo_2_external_list;
+                       } else if (column == 2) {
+                               p = bbo_3_external_list;
+                       }
+                       p->common_data.padname = pad_name[row][column];
+                       p->common_data.padid = pad_id[row][column];
+                       p->common_data.configfile = configfile;
+                       return;
+               }
                if (row == bee) {
                        struct bee_program* p = NULL;
                        if (column == 0) {
@@ -168,6 +186,31 @@ static void mark_device(const char* device, int row, int column,
        }
 
        if (device == stylus_string) {
+               if ((column == MAXPAD*bbo) || (column == (MAXPAD*bbo)+1)
+                       || (column == (MAXPAD*bbo)+2)) {
+                       struct bbo_program* p = NULL;
+                       if (column == MAXPAD*bbo) {
+                               p = bbo_1_external_list;
+                       } else if (column == (MAXPAD*bbo)+1) {
+                               p = bbo_2_external_list;
+                       } else if (column == (MAXPAD*bbo)+2) {
+                               p = bbo_3_external_list;
+                       }
+                       if (row == 0) {
+                               p->common_data.sty1name =
+                                               stylus_name[row][column];
+                               p->common_data.sty1id = stylus_id[row][column];
+                               p->common_data.sty1mode =
+                                               stylus_mode[row][column];
+                       } else if (row == 1) {
+                               p->common_data.sty2name =
+                                               stylus_name[row][column];
+                               p->common_data.sty2id = stylus_id[row][column];
+                               p->common_data.sty2mode =
+                                               stylus_mode[row][column];
+                       }
+                       return;
+               }
                if ((column == MAXPAD*bee) || (column == (MAXPAD*bee)+1)
                        || (column == (MAXPAD*bee)+2)) {
                        struct bee_program* p = NULL;
@@ -345,8 +388,35 @@ static void mark_config(const char* device, int row, int column)
        const char* file1_bee = "/cintiq20.conf1";
        const char* file2_bee = "/cintiq20.conf2";
        const char* file3_bee = "/cintiq20.conf3";
+       const char* file1_bbo = "/bamboo.conf1";
+       const char* file2_bbo = "/bamboo.conf2";
+       const char* file3_bbo = "/bamboo.conf3";
 
        switch (row) {
+/* pad Bamboo */
+       case 6:
+               switch (column) {
+               case 0:
+                       total_file1_bbo = path_malloc
+                               ((void*)total_config_dir, (void*)file1_bbo);
+                       mark_device(device, row, column, total_file1_bbo);
+                       return;
+
+               case 1:
+                       total_file2_bbo = path_malloc
+                               ((void*)total_config_dir, (void*)file2_bbo);
+                       mark_device(device, row, column, total_file2_bbo);
+                       return;
+
+               case 2:
+                       total_file3_bbo = path_malloc
+                               ((void*)total_config_dir, (void*)file3_bbo);
+                       mark_device(device, row, column, total_file3_bbo);
+                       return;
+
+               default:
+                       return;
+               }
 /* pad Cintiq 20wsx */
        case 5:
                switch (column) {
index 7b17bfa..1abed65 100644 (file)
@@ -43,6 +43,7 @@ const char* sty2str = "CurrentSty2";
 extern int ok_config;
 extern int go_daemon;
 
+extern const int bbo;
 extern const int bee;
 extern const int i3;
 extern const int i3s;
@@ -87,6 +88,9 @@ extern char* total_file3_intuos3;
 extern char* total_file1_bee;
 extern char* total_file2_bee;
 extern char* total_file3_bee;
+extern char* total_file1_bbo;
+extern char* total_file2_bbo;
+extern char* total_file3_bbo;
 
 extern void read_config(FILE* errorfp);
 
@@ -100,14 +104,15 @@ void report_header(FILE* statusfp)
 
        fprintf(statusfp,
 "\n'Models': nopad, Graphire4 BlueTooth, Graphire4, Intuos3 small, \
-Intuos3/Cintiq, Cintiq 20wsx\n");
+Intuos3/Cintiq, Cintiq 20wsx, Bamboo\n");
        fprintf(statusfp, "\n* Pad-index *\n");
        fprintf(statusfp, "%i (nop): 0 1 2\n", nop);
        fprintf(statusfp, "%i (g4b): 0 1 2\n", g4b);
        fprintf(statusfp, "%i (g4 ): 0 1 2\n", g4);
        fprintf(statusfp, "%i (i3s): 0 1 2\n", i3s);
        fprintf(statusfp, "%i (i3 ): 0 1 2\n", i3);
-       fprintf(statusfp, "%i (bee): 0 1 2\n\n", bee);
+       fprintf(statusfp, "%i (bee): 0 1 2\n", bee);
+       fprintf(statusfp, "%i (bbo): 0 1 2\n\n", bbo);
        fprintf(statusfp, "* Stylus-index *\n");
        fprintf(statusfp, "0 st1 (nop): 0 1 2 (g4b): 3 4 5 (g4): 6 7 8 \
 (i3s): 9 10 11 (i3): 12 13 14 (bee): 15 16\n");
@@ -146,6 +151,7 @@ Intuos3/Cintiq, Cintiq 20wsx\n");
 
 static void report_record(FILE* statusfp, void* address, const int model)
 {
+       struct bbo_program* pbbo;
        struct bee_program* pbee;
        struct i3_program* pi3;
        struct i3s_program* pi3s;
@@ -154,7 +160,10 @@ static void report_record(FILE* statusfp, void* address, const int model)
        struct nop_program* pnop;
        struct common_data* cdp = NULL;
 
-       if (model == bee) {
+       if (model == bbo) {
+               pbbo = address;
+               cdp = &pbbo->common_data;
+       } else if (model == bee) {
                pbee = address;
                cdp = &pbee->common_data;
        } else if (model == i3) {
@@ -215,6 +224,7 @@ static void report_common(FILE* statusfp)
        int num_record;
        const char* pgr_records = "PGR RECORDS =";
 
+       struct bbo_program* pbbo;
        struct bee_program* pbee;
        struct i3_program* pi3;
        struct i3s_program* pi3s;
@@ -226,6 +236,20 @@ static void report_common(FILE* statusfp)
        mip = model_list;
 
        for (i = 0; i < MAXPAD; i++, mip++) {
+               if (mip->bbo->common_data.num_record) {
+                       print_common(statusfp, mip->bbo->common_data.configfile,
+                                       mip->bbo->common_data.userconfigversion,
+                                               mip->bbo->common_data.padname,
+                                               mip->bbo->common_data.sty1name,
+                                               mip->bbo->common_data.sty2name);
+                       num_record = mip->bbo->common_data.num_record;
+                       pbbo = mip->bbo;
+                       for (j = 0; j < num_record; j++, pbbo++) {
+                               report_record(statusfp, pbbo, bbo);
+                       }
+                       fprintf(statusfp, "%s %i (of max %i)\n\n", pgr_records,
+                                                       num_record, MAXRECORDS);
+               }
                if (mip->bee->common_data.num_record) {
                        print_common(statusfp, mip->bee->common_data.configfile,
                                        mip->bee->common_data.userconfigversion,
@@ -390,6 +414,7 @@ void re_read_config(int signum)
 
 static void free_common(void* address, const int model)
 {
+       struct bbo_program* pbbo;
        struct bee_program* pbee;
        struct i3_program* pi3;
        struct i3s_program* pi3s;
@@ -398,7 +423,10 @@ static void free_common(void* address, const int model)
        struct nop_program* pnop;
        struct common_data* cdp = NULL;
 
-       if (model == bee) {
+       if (model == bbo) {
+               pbbo = address;
+               cdp = &pbbo->common_data;
+       } else if (model == bee) {
                pbee = address;
                cdp = &pbee->common_data;
        } else if (model == i3) {
@@ -445,6 +473,7 @@ void clean_up_exit(int signum)
 {
        int i, j;
 
+       struct bbo_program* pbbo;
        struct bee_program* pbee;
        struct i3_program* pi3;
        struct i3s_program* pi3s;
@@ -469,6 +498,12 @@ void clean_up_exit(int signum)
 
        mip = model_list;
        for (i = 0; i < MAXPAD; i++, mip++) {
+               if (mip->bbo->common_data.configfile) {
+                       pbbo = mip->bbo;
+                       for (j = 0; j < MAXRECORDS; j++, pbbo++) {
+                               free_common(pbbo, bbo);
+                       }
+               }
                if (mip->bee->common_data.configfile) {
                        pbee = mip->bee;
                        for (j = 0; j < MAXRECORDS; j++, pbee++) {
@@ -602,6 +637,18 @@ void clean_up_exit(int signum)
                free(total_file3_bee);
        }
 
+/*---*/
+
+       if (total_file1_bbo) {
+               free(total_file1_bbo);
+       }
+       if (total_file2_bbo) {
+               free(total_file2_bbo);
+       }
+       if (total_file3_bbo) {
+               free(total_file3_bbo);
+       }
+
 /* The pad devices and styli devices should not be explicitly closed by a
  call to XCloseDevice. It leaves a message from X (in the terminal where X
  is started from) saying: "ProcXCloseDevice to close or not ?" Instead we
index eb8e5de..6bc38c2 100644 (file)
 
 /* Globals: */
 
+struct bbo_program bbo_internal_list[] = {
+       {
+       .common_data = {
+               .class_name = "default",
+               .stylus1_presscurve = "0 0 100 100",
+               .stylus2_presscurve = "0 0 100 100",
+               },
+       .wheel_data = {
+               .handle_wheel = { 1 },
+               .scroll_wheel_up = { 994,0 },
+               .scroll_wheel_down = { 995,0 },
+               },
+       .touch_data = {
+               .handle_touch = { 0 },
+               .repeat_after = { 0, 6 },
+               .repeat_delay = { 0, 1 },
+               .repeat_left_up = { 1 },
+               .repeat_left_down = { 1 },
+               .left_touch_up = { 994, 0 },
+               .left_touch_down = { 995, 0 },
+               },
+       .button_data = {
+               .repeat_after = { 0, 5 },
+               .repeat_delay = { 0, 1 },
+               .button9 = { 64, 100 },
+               .button10 = { 64, 0 },
+               .button11 = { 64, 102 },
+               .button12 = { 37, 0 },
+               },
+       },
+       {
+       .common_data = {
+               .class_name = "Gimp",
+               .stylus1_presscurve = "0 0 100 100",
+               .stylus2_presscurve = "0 0 100 100",
+               },
+       .wheel_data = {
+               .handle_wheel = { 1 },
+               .scroll_wheel_up = { 86,0 },
+               .scroll_wheel_down = { 82,0 },
+               },
+       .touch_data = {
+               .handle_touch = { 0 },
+               .repeat_after = { 0, 6 },
+               .repeat_delay = { 0, 1 },
+               .left_touch_up = { 20, 0 },
+               .left_touch_down = { 61, 0 },
+               },
+       .button_data = {
+               .repeat_after = { 0, 5 },
+               .repeat_delay = { 0, 1 },
+               .button9 = { 50, 0 },
+               .button10 = { 64, 0 },
+               .button11 = { 37, 0 },
+               .button12 = { 37, 0 },
+               },
+       },
+       {
+       .common_data = {
+               .class_name = "Blender",
+               .stylus1_presscurve = "0 0 100 100",
+               .stylus2_presscurve = "0 0 100 100",
+               },
+       .wheel_data = {
+               .handle_wheel = { 1 },
+               .scroll_wheel_up = { 102,0 },
+               .scroll_wheel_down = { 100,0 },
+               },
+       .touch_data = {
+               .handle_touch = { 0 },
+               .repeat_after = { 0, 6 },
+               .repeat_delay = { 0, 1 },
+               .repeat_left_up = { 1 },
+               .repeat_left_down = { 1 },
+               .left_touch_up = { 102, 0 },
+               .left_touch_down = { 100, 0 },
+               },
+       .button_data = {
+               .repeat_after = { 0, 5 },
+               .repeat_delay = { 0, 1 },
+               .button9 = { 37, 0 },
+               .button10 = { 9, 0 },
+               .button11 = { 50, 0 },
+               .button12 = { 23, 0 },
+               },
+       },
+       {
+       .common_data = {
+               .class_name = "XTerm",
+               .stylus1_presscurve = "0 0 100 100",
+               .stylus2_presscurve = "0 0 100 100",
+               },
+       .wheel_data = {
+               .handle_wheel = { 0 },
+               .scroll_wheel_up = { 0,0 },
+               .scroll_wheel_down = { 0,0 },
+               },
+       .touch_data = {
+               .repeat_after = { 0, 6 },
+               .repeat_delay = { 0, 1 },
+               },
+       .button_data = {
+               .repeat_after = { 0, 5 },
+               .repeat_delay = { 0, 1 },
+               .button15 = { 999, 0 },
+               },
+       },
+};
+const int bbo_num_list = (sizeof bbo_internal_list / sizeof bbo_internal_list[0]);
+
+struct bbo_program bbo_1_external_list[MAXRECORDS];
+struct bbo_program bbo_2_external_list[MAXRECORDS];
+struct bbo_program bbo_3_external_list[MAXRECORDS];
+
+struct bbo_configstrings bbo_configstrings[] = {
+{{"DelayEachKeycode", "ProgramName", "Stylus1PressCurve", "Stylus2PressCurve"},
+{"HandleScrollWheel", "ScrollWheelUp", "ScrollWheelDown"},
+{"HandleTouchRing", "TouchRepeatAfter", "DelayTouchRepeat",
+"RepeatUp", "RepeatDown", NULL, NULL, "PadTouchUp", "PadTouchDown", NULL, NULL},
+{"ButtonRepeatAfter", "DelayButtonRepeat",
+"RepeatButton9", "RepeatButton10", "RepeatButton11", "RepeatButton12", NULL, NULL, NULL, NULL, NULL, NULL,
+"LeftPadButton9", "LeftPadButton10", "RightPadButton11", "RightPadButton12",  NULL, NULL, NULL, NULL, NULL, NULL}}
+};
+
 struct bee_program bee_internal_list[] = {
        {
        .common_data = {
@@ -31,7 +155,7 @@ struct bee_program bee_internal_list[] = {
                .stylus2_presscurve = "0 0 100 100",
                },
        .touch_data = {
-               .handle_touch = { 1 },
+               .handle_touch = { 0 },
                .repeat_after = { 0, 6 },
                .repeat_delay = { 0, 1 },
                .repeat_left_up = { 1 },
@@ -65,7 +189,7 @@ struct bee_program bee_internal_list[] = {
                .stylus2_presscurve = "0 0 100 100",
                },
        .touch_data = {
-               .handle_touch = { 1 },
+               .handle_touch = { 0 },
                .repeat_after = { 0, 6 },
                .repeat_delay = { 0, 1 },
                .left_touch_up = { 20, 0 },
@@ -95,7 +219,7 @@ struct bee_program bee_internal_list[] = {
                .stylus2_presscurve = "0 0 100 100",
                },
        .touch_data = {
-               .handle_touch = { 1 },
+               .handle_touch = { 0 },
                .repeat_after = { 0, 6 },
                .repeat_delay = { 0, 1 },
                .repeat_left_up = { 1 },
@@ -392,11 +516,11 @@ struct nop_configstrings nop_configstrings[] = {
 };
 
 struct model_index model_list[] = {
-       {bee_1_external_list, i3_1_external_list, i3s_1_external_list,
+       {bbo_1_external_list, bee_1_external_list, i3_1_external_list, i3s_1_external_list,
         g4_1_external_list, g4b_1_external_list, nop_1_external_list},
-       {bee_2_external_list, i3_2_external_list, i3s_2_external_list,
+       {bbo_2_external_list, bee_2_external_list, i3_2_external_list, i3s_2_external_list,
         g4_2_external_list, g4b_2_external_list, nop_2_external_list},
-       {bee_3_external_list, i3_3_external_list, i3s_3_external_list,
+       {bbo_3_external_list, bee_3_external_list, i3_3_external_list, i3s_3_external_list,
         g4_3_external_list, g4b_3_external_list, nop_3_external_list}
 };
 
index 38a0caa..6c47285 100644 (file)
@@ -91,6 +91,15 @@ extern struct button_data {
 
 /* Data structures (consolidation): */
 
+extern struct bbo_program {
+       struct bbo_program* default_program;
+       struct common_data common_data;
+       struct wheel_data wheel_data;
+       struct touch_data touch_data;
+       struct button_data button_data;
+} bbo_internal_list[], bbo_1_external_list[], bbo_2_external_list[],
+                                                       bbo_3_external_list[];
+
 extern struct bee_program {
        struct bee_program* default_program;
        struct common_data common_data;
@@ -194,6 +203,13 @@ extern struct button_string {
 
 /* String structures (consolidation): */
 
+extern struct bbo_configstrings {
+       struct common_string common_string;
+       struct wheel_string wheel_string;
+       struct touch_string touch_string;
+       struct button_string button_string;
+} bbo_configstrings[];
+
 extern struct bee_configstrings {
        struct common_string common_string;
        struct touch_string touch_string;
@@ -231,6 +247,7 @@ extern struct nop_configstrings {
 /* Data structure (final consolidation): */
 
 extern struct model_index {
+       struct bbo_program* bbo;
        struct bee_program* bee;
        struct i3_program* i3;
        struct i3s_program* i3s;