constants = { sensitivity_num = 2; sensitivity_denom = 5; }; enums = { namespaces: ["clickpad"]; }; predicates = { is_evdev = { type = "code_ns"; min = "namespaces.clickpad"; max = "namespaces.clickpad"; }; key_event = { type = "and"; args = ( "is_evdev", { type = "code_major"; min = "event_type.KEY"; max = "event_type.KEY"; } ); }; syn_event = { type = "and"; args = ( "is_evdev", { type = "code_major"; min = "event_type.SYN"; max = "event_type.SYN"; } ); }; abs_event = { type = "and"; args = ( "is_evdev", { type = "code_major"; min = "event_type.ABS"; max = "event_type.ABS"; } ); }; misc_event = { type = "and"; args = ( "is_evdev", { type = "code_major"; min = "event_type.MSC"; max = "event_type.MSC"; } ); }; btn_quadtap_event = { type = "and"; args = ( "key_event", { type = "code_minor"; min = "button_event.TOOL_QUADTAP"; max = "button_event.TOOL_QUADTAP"; } ); }; misc_timestamp = { type = "and"; args = ( "misc_event", { type = "code_minor"; min = "misc_event.TIMESTAMP"; max = "misc_event.TIMESTAMP"; } ); }; abs_x = { type = "and"; args = ( "abs_event", { type = "code_minor"; min = "absolute_axis.X"; max = "absolute_axis.X"; } ); }; abs_y = { type = "and"; args = ( "abs_event", { type = "code_minor"; min = "absolute_axis.Y"; max = "absolute_axis.Y"; } ); }; quadtap_held = { type = "accept"; inverted = 1; }; bypass = { type = "or"; args = ["syn_event", "misc_timestamp"]; }; payload_zero = { type = "payload"; min = 0; max = 0; }; payload_one = { type = "payload"; min = 1; max = 1; }; }; nodes = { clickpad = { type = "evdev"; options = { file = "/dev/input/event7"; namespace = "namespaces.clickpad"; }; }; select_interesting_events = { type = "router"; options = { predicates = ["bypass", "btn_quadtap_event", "abs_x", "abs_y"]; }; }; quadtap_subst_seq = { type = "tee"; }; morph_left_click = { type = "assign"; options = { minor = "button_event.LEFT"; }; }; morph_right_click = { type = "assign"; options = { minor = "button_event.RIGHT"; }; }; merge = { type = "tee"; }; virtual_out = { type = "uinput"; options = { name = "Quadtap gesture"; enabled_codes = ( {major: "event_type.KEY"; minor: "button_event.LEFT"} , {major: "event_type.KEY"; minor: "button_event.RIGHT"} , {major: "event_type.KEY"; minor: "button_event.MIDDLE"} , {major: "event_type.REL"; minor: "relative_axis.X"} , {major: "event_type.REL"; minor: "relative_axis.Y"} , {major: "event_type.MSC"; minor: "misc_event.TIMESTAMP"} ); properties = ["input_property.POINTER", "input_property.BUTTONPAD"]; }; }; update_quadtap_held = { type = "modify_predicate"; options = { target = "quadtap_held"; uninvert_on = "payload_one"; invert_on = "payload_zero"; }; }; differentiate_x = { type = "differentiate"; }; differentiate_y = { type = "differentiate"; }; morph_rel = { type = "assign"; options = { major = "event_type.REL"; // Preserve minor, because relative_axis.X = absolute_axis.X, relative_axis.Y = absolute_axis.Y }; }; while_quadtap_held = { type = "router"; options = { predicates = ["quadtap_held"]; }; }; sensitivity_x = { type = "scale"; options = { numerator = "sensitivity_num"; denominator = "sensitivity_denom"; amortize_rounding_error = "true"; }; }; sensitivity_y = { type = "scale"; options = { numerator = "sensitivity_num"; denominator = "sensitivity_denom"; amortize_rounding_error = "true"; }; }; }; channels = ({ from: ("clickpad", 0); to: ("select_interesting_events", 0); }, { from: ("select_interesting_events", 0); // EV_SYN to: ("merge", 0); }, { from: ("select_interesting_events", 1); // BTN_TOOL_QUADTAP to: ("quadtap_subst_seq", 0); }, { from: ("quadtap_subst_seq", 0); to: ("morph_left_click", 0); }, { from: ("quadtap_subst_seq", 1); to: ("morph_right_click", 0); }, { from: ("morph_left_click", 0); to: ("merge", 1); }, { from: ("morph_right_click", 0); to: ("merge", 2); }, { from: ("select_interesting_events", 2); // ABS_X to: ("differentiate_x", 0); }, { from: ("select_interesting_events", 3); // ABS_Y to: ("differentiate_y", 0); }, { from: ("differentiate_x", 0); to: ("sensitivity_x", 0); }, { from: ("differentiate_y", 0); to: ("sensitivity_y", 0); }, { from: ("sensitivity_x", 0); to: ("while_quadtap_held", 0); }, { from: ("sensitivity_y", 0); to: ("while_quadtap_held", 1); }, { from: ("while_quadtap_held", 0); to: ("morph_rel", 0); }, { from: ("morph_rel", 0); to: ("merge", 3); }, { from: ("merge", 0); to: ("virtual_out", 0); }, { from: ("quadtap_subst_seq", 4); to: ("update_quadtap_held", 0); }); // vim: ft=libconfig