Intial commit with original files, docs and modified Linux source.
This commit is contained in:
Executable
+8
@@ -0,0 +1,8 @@
|
||||
|
||||
PROG = scdis
|
||||
|
||||
OBJS = ../common/hid_tokens.o ../common/macro_tokens.o $(PROG).o
|
||||
|
||||
include ../build/Makefile_prog.inc
|
||||
|
||||
|
||||
Executable
+376
@@ -0,0 +1,376 @@
|
||||
// scdis.cpp - config file disassembler for Soarer's Keyboard Converter.
|
||||
|
||||
#include "../common/global.h"
|
||||
#include "../common/hid_tokens.h"
|
||||
#include "../common/macro_tokens.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
|
||||
FILE* fout = stdout;
|
||||
|
||||
const char* get_force_set(uint8_t force)
|
||||
{
|
||||
static const char* sets[] = { "set1", "set2", "set3", "set2ext" };
|
||||
uint8_t force_set = force & 0x0F;
|
||||
if ( 1 <= force_set && force_set <= 4 ) {
|
||||
return sets[force_set - 1];
|
||||
}
|
||||
return "ERROR";
|
||||
}
|
||||
|
||||
const char* get_force_protocol(uint8_t force)
|
||||
{
|
||||
static const char* protocols[] = { "xt", "at" };
|
||||
uint8_t force_protocol = (force & 0xF0) >> 4;
|
||||
if ( 1 <= force_protocol && force_protocol <= 2 ) {
|
||||
return protocols[force_protocol - 1];
|
||||
}
|
||||
return "ERROR";
|
||||
}
|
||||
|
||||
const char* get_block_type(uint8_t blk_type)
|
||||
{
|
||||
static const char* blk_types[] = { "layerblock", "remapblock", "macroblock" };
|
||||
if ( 0 <= blk_type && blk_type <= 2 ) {
|
||||
return blk_types[blk_type];
|
||||
}
|
||||
return "ERROR";
|
||||
}
|
||||
|
||||
string get_ifset(uint8_t ifset)
|
||||
{
|
||||
static const char* sets[8] = { "set1", "set2", "set3", "set2ext", "INVALIDSET", "INVALIDSET", "INVALIDSET", "INVALIDSET" };
|
||||
if ( !ifset ) {
|
||||
return string("any");
|
||||
} else {
|
||||
string s;
|
||||
for ( int i = 0; i < 8; ++i ) {
|
||||
if ( ifset & 1 ) {
|
||||
s += sets[i];
|
||||
s += " ";
|
||||
}
|
||||
ifset = ifset >> 1;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
string get_macro_match_metas(uint8_t desired_meta, uint8_t matched_meta)
|
||||
{
|
||||
static const char* metas[4] = { "control", "shift", "alt", "gui" };
|
||||
static const char* hmetas[8] = { "lcontrol", "lshift", "lalt", "lgui", "rcontrol", "rshift", "ralt", "rgui" };
|
||||
uint8_t unhanded_meta = (desired_meta & ~matched_meta) & 0xF0;
|
||||
string s;
|
||||
for ( int i = 0; i < 4; ++i ) {
|
||||
uint8_t mask = (uint8_t)((1 << (i + 4)) | (1 << i));
|
||||
if ( unhanded_meta & mask ) {
|
||||
s += metas[i];
|
||||
s += " ";
|
||||
desired_meta &= ~mask;
|
||||
matched_meta &= ~mask;
|
||||
}
|
||||
}
|
||||
for ( int i = 0; i < 8; ++i ) {
|
||||
uint8_t mask = (uint8_t)(1 << i);
|
||||
if ( matched_meta & mask ) {
|
||||
if ( !(desired_meta & mask) ) {
|
||||
s += "-";
|
||||
}
|
||||
s += hmetas[i];
|
||||
s += " ";
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
string get_macrostep_metas(int val)
|
||||
{
|
||||
static const char* metas[8] = { "lcontrol", "lshift", "lalt", "lgui", "rcontrol", "rshift", "ralt", "rgui" };
|
||||
string s;
|
||||
for ( int i = 0; i < 8; ++i ) {
|
||||
if ( val & 1 ) {
|
||||
s += metas[i];
|
||||
s += " ";
|
||||
}
|
||||
val = val >> 1;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
string get_macrostep(int cmd, int val)
|
||||
{
|
||||
//fprintf(fout, "\t%s %d\n", lookup_macro_token(cmd), val);
|
||||
string s;
|
||||
if ( cmd & Q_PUSH_META ) {
|
||||
s = "PUSH_META ";
|
||||
}
|
||||
s += lookup_macro_token(cmd & ~Q_PUSH_META);
|
||||
s += " ";
|
||||
int argtype = get_macro_arg_type(cmd);
|
||||
char buffer[64];
|
||||
switch ( argtype ) {
|
||||
case MACRO_ARG_NONE:
|
||||
break;
|
||||
case MACRO_ARG_HID:
|
||||
s += lookup_hid_token(val);
|
||||
break;
|
||||
case MACRO_ARG_META:
|
||||
s += get_macrostep_metas(val);
|
||||
break;
|
||||
case MACRO_ARG_DELAY:
|
||||
//s += itoa(val, buffer, 10);
|
||||
sprintf(buffer, "%d", val);
|
||||
s += string(buffer);
|
||||
break;
|
||||
default:
|
||||
s += "INVALID";
|
||||
break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int process_layerblock(const uint8_t* buf, const uint8_t* bufend)
|
||||
{
|
||||
const uint8_t* p = buf;
|
||||
fprintf(fout, "layerblock\n");
|
||||
if ( bufend - p < 1 ) {
|
||||
fprintf(fout, "# ERROR: block truncated\n");
|
||||
return 1;
|
||||
}
|
||||
uint8_t n = *p++;
|
||||
fprintf(fout, "# count: %d\n", n);
|
||||
if ( bufend - p != (int)n * 2 ) {
|
||||
fprintf(fout, "# ERROR: block size mismatch\n");
|
||||
return 1;
|
||||
}
|
||||
for ( int i = 0; i < n; ++i ) {
|
||||
uint8_t fn = *p++;
|
||||
uint8_t layer = *p++;
|
||||
fprintf(fout, "\t");
|
||||
int b = 1;
|
||||
while ( fn ) {
|
||||
if ( fn & 1 ) {
|
||||
fprintf(fout, "fn%d ", b);
|
||||
}
|
||||
++b;
|
||||
fn = fn >> 1;
|
||||
}
|
||||
fprintf(fout, "%d\n", layer);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int process_remapblock(const uint8_t* buf, const uint8_t* bufend)
|
||||
{
|
||||
const uint8_t* p = buf;
|
||||
fprintf(fout, "remapblock\n");
|
||||
if ( bufend - p < 2 ) {
|
||||
fprintf(fout, "# ERROR: block truncated\n");
|
||||
return 1;
|
||||
}
|
||||
uint8_t layer = *p++;
|
||||
fprintf(fout, "layer %d\n", layer);
|
||||
uint8_t n = *p++;
|
||||
fprintf(fout, "# count: %d\n", n);
|
||||
if ( bufend - p != (int)n * 2 ) {
|
||||
fprintf(fout, "# ERROR: block size mismatch\n");
|
||||
return 1;
|
||||
}
|
||||
for ( int i = 0; i < n; ++i ) {
|
||||
uint8_t from_hid = *p++;
|
||||
uint8_t to_hid = *p++;
|
||||
fprintf(fout, "\t%s %s\n", lookup_hid_token(from_hid), lookup_hid_token(to_hid));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int process_macro(const uint8_t* buf, const uint8_t* /*bufend*/)
|
||||
{
|
||||
// todo: use bufend to check length
|
||||
const uint8_t* p = buf;
|
||||
uint8_t hid_code = *p++;
|
||||
uint8_t desired_meta = *p++;
|
||||
uint8_t matched_meta = *p++;
|
||||
uint8_t press_flags = *p++;
|
||||
uint8_t release_flags = *p++;
|
||||
size_t press_length = press_flags & 0x3F;
|
||||
size_t release_length = release_flags & 0x3F;
|
||||
string s = get_macro_match_metas(desired_meta, matched_meta);
|
||||
fprintf(fout, "macro %s %s # %02X %02X\n", lookup_hid_token(hid_code), s.c_str(), desired_meta, matched_meta);
|
||||
for ( int i = 0; i < (int)press_length; ++i ) {
|
||||
uint8_t cmd = *p++;
|
||||
uint8_t val = *p++;
|
||||
fprintf(fout, "\t%s\n", get_macrostep(cmd, val).c_str());
|
||||
}
|
||||
if ( release_length ) {
|
||||
fprintf(fout, "onbreak%s\n", (release_flags & 0x40) ? "" : " norestoremeta");
|
||||
for ( int i = 0; i < (int)release_length; ++i ) {
|
||||
uint8_t cmd = *p++;
|
||||
uint8_t val = *p++;
|
||||
fprintf(fout, "\t%s\n", get_macrostep(cmd, val).c_str());
|
||||
}
|
||||
}
|
||||
fprintf(fout, "endmacro\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int process_macroblock(const uint8_t* buf, const uint8_t* bufend)
|
||||
{
|
||||
const uint8_t* p = buf;
|
||||
fprintf(fout, "macroblock\n");
|
||||
if ( bufend - p < 1 ) {
|
||||
fprintf(fout, "# ERROR: block truncated\n");
|
||||
return 1;
|
||||
}
|
||||
uint8_t n = *p++;
|
||||
fprintf(fout, "# macro count: %d\n", n);
|
||||
for ( int i = 0; i < n; ++i ) {
|
||||
if ( bufend - p < 5 ) {
|
||||
fprintf(fout, "# ERROR: block truncated\n");
|
||||
return 1;
|
||||
}
|
||||
int press_length = p[3] & 0x3F;
|
||||
int release_length = p[4] & 0x3F;
|
||||
int macro_length = 5 + 2 * (press_length + release_length);
|
||||
if ( bufend - p < macro_length ) {
|
||||
fprintf(fout, "# ERROR: block truncated\n");
|
||||
return 1;
|
||||
}
|
||||
process_macro(p, p + macro_length);
|
||||
p += macro_length;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int process_block(const uint8_t* buf, size_t buflen)
|
||||
{
|
||||
const uint8_t* p = buf;
|
||||
const uint8_t* bufend = buf + buflen;
|
||||
if ( bufend - p < 2 ) {
|
||||
fprintf(fout, "# ERROR: block truncated\n");
|
||||
return 1;
|
||||
}
|
||||
fprintf(fout, "\n# block length: %d\n", *p++);
|
||||
uint8_t blktype = *p & 0x07;
|
||||
uint8_t blksel = (*p >> 3) & 0x07;
|
||||
uint8_t has_set = (*p & 0x40) ? 1 : 0;
|
||||
uint8_t has_id = (*p & 0x80) ? 2 : 0;
|
||||
++p;
|
||||
if ( bufend - p < has_set + has_id ) {
|
||||
fprintf(fout, "# ERROR: block truncated\n");
|
||||
return 1;
|
||||
}
|
||||
uint8_t blkset = 0;
|
||||
if ( has_set ) {
|
||||
blkset = *p++;
|
||||
}
|
||||
uint16_t blkid = 0;
|
||||
if ( has_id ) {
|
||||
blkid = (uint16_t)(*p++);
|
||||
blkid |= ((uint16_t)(*p++) << 8);
|
||||
}
|
||||
fprintf(fout, "ifset %s\n", get_ifset(blkset).c_str());
|
||||
if ( has_id ) {
|
||||
fprintf(fout, "ifkeyboard %04X\n", blkid);
|
||||
} else {
|
||||
fprintf(fout, "ifkeyboard any\n");
|
||||
}
|
||||
if ( blksel ) {
|
||||
fprintf(fout, "ifselect %d\n", blksel);
|
||||
} else {
|
||||
fprintf(fout, "ifselect any\n");
|
||||
}
|
||||
// fprintf(fout, "%s\n", get_block_type(blktype));
|
||||
int retval = 1;
|
||||
switch ( blktype ) {
|
||||
case BLOCK_LAYERDEF: retval = process_layerblock(p, bufend); break;
|
||||
case BLOCK_REMAP: retval = process_remapblock(p, bufend); break;
|
||||
case BLOCK_MACRO: retval = process_macroblock(p, bufend); break;
|
||||
}
|
||||
fprintf(fout, "endblock\n");
|
||||
return retval;
|
||||
}
|
||||
|
||||
int process_file(const uint8_t* buf, size_t buflen)
|
||||
{
|
||||
const uint8_t* p = buf;
|
||||
|
||||
fprintf(fout, "# length: %u\n", buflen);
|
||||
|
||||
// header...
|
||||
uint8_t sig1 = *p++;
|
||||
uint8_t sig2 = *p++;
|
||||
fprintf(fout, "# signature: %c %c\n", sig1, sig2);
|
||||
uint8_t ver1 = *p++;
|
||||
uint8_t ver2 = *p++;
|
||||
fprintf(fout, "# version: %d %d\n", ver1, ver2);
|
||||
if ( *p & 0x0F ) {
|
||||
fprintf(fout, "force %s\n", get_force_set(*p));
|
||||
}
|
||||
if ( *p & 0xF0 ) {
|
||||
fprintf(fout, "force %s\n", get_force_protocol(*p));
|
||||
}
|
||||
++p; // force
|
||||
++p; // reserved
|
||||
|
||||
// blocks...
|
||||
int err = 0;
|
||||
const uint8_t* pend = buf + buflen;
|
||||
while ( p < pend ) {
|
||||
uint8_t blklen = *p;
|
||||
if ( !blklen ) {
|
||||
fprintf(fout, "ERROR: block length is zero!\n");
|
||||
return 1;
|
||||
}
|
||||
err |= process_block(p, blklen);
|
||||
p += blklen;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
printf("scdis v1.10\n");
|
||||
|
||||
if ( argc != 2 && argc != 3 ) {
|
||||
fprintf(stderr, "usage: scdis <binary_config> [<text_config>]\n");
|
||||
return 1;
|
||||
}
|
||||
const size_t bufsize = 16384;
|
||||
static uint8_t buf[bufsize];
|
||||
FILE* f = fopen(argv[1], "rb");
|
||||
if ( !f ) {
|
||||
fprintf(stderr, "error: could not open input file %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
size_t buflen = fread(buf, 1, bufsize, f);
|
||||
fclose(f);
|
||||
if ( argc == 3 ) {
|
||||
fout = fopen(argv[2], "wt");
|
||||
if ( !fout ) {
|
||||
fprintf(stderr, "error: could not open output file %s\n", argv[2]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
int err = process_file(buf, buflen);
|
||||
if ( fout != stdout ) {
|
||||
fclose(fout);
|
||||
}
|
||||
if ( err ) {
|
||||
fprintf(stderr, "errors encountered, see output file\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scdis", "scdis.vcproj", "{81871EED-13AF-42FF-BB7F-88F93647B45B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
Release = Release
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{81871EED-13AF-42FF-BB7F-88F93647B45B}.Debug.ActiveCfg = Debug|Win32
|
||||
{81871EED-13AF-42FF-BB7F-88F93647B45B}.Debug.Build.0 = Debug|Win32
|
||||
{81871EED-13AF-42FF-BB7F-88F93647B45B}.Release.ActiveCfg = Release|Win32
|
||||
{81871EED-13AF-42FF-BB7F-88F93647B45B}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Executable
+147
@@ -0,0 +1,147 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="scdis"
|
||||
ProjectGUID="{81871EED-13AF-42FF-BB7F-88F93647B45B}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/scdis.exe"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/scdis.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../bin"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="4"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/scdis.exe"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="FALSE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath="..\common\hid_tokens.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\common\macro_tokens.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\scdis.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
<File
|
||||
RelativePath="..\common\global.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\common\hid_tokens.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\common\macro_tokens.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
Reference in New Issue
Block a user