Example #1
0
PLDHashOperator
pref_savePref(PLDHashTable *table, PLDHashEntryHdr *heh, PRUint32 i, void *arg)
{
    pref_saveArgs *argData = static_cast<pref_saveArgs *>(arg);
    PrefHashEntry *pref = static_cast<PrefHashEntry *>(heh);

    PR_ASSERT(pref);
    if (!pref)
        return PL_DHASH_NEXT;

    nsCAutoString prefValue;
    nsCAutoString prefPrefix;
    prefPrefix.Assign(NS_LITERAL_CSTRING("user_pref(\""));

    // where we're getting our pref from
    PrefValue* sourcePref;

    if (PREF_HAS_USER_VALUE(pref) &&
        pref_ValueChanged(pref->defaultPref,
                          pref->userPref,
                          (PrefType) PREF_TYPE(pref))) {
        sourcePref = &pref->userPref;
    } else {
        if (argData->saveTypes == SAVE_ALL_AND_DEFAULTS) {
            prefPrefix.Assign(NS_LITERAL_CSTRING("pref(\""));
            sourcePref = &pref->defaultPref;
        }
        else
            // do not save default prefs that haven't changed
            return PL_DHASH_NEXT;
    }

    // strings are in quotes!
    if (pref->flags & PREF_STRING) {
        prefValue = '\"';
        str_escape(sourcePref->stringVal, prefValue);
        prefValue += '\"';
    }

    else if (pref->flags & PREF_INT)
        prefValue.AppendInt(sourcePref->intVal);

    else if (pref->flags & PREF_BOOL)
        prefValue = (sourcePref->boolVal) ? "true" : "false";

    nsCAutoString prefName;
    str_escape(pref->key, prefName);

    argData->prefArray[i] = ToNewCString(prefPrefix +
                                         prefName +
                                         NS_LITERAL_CSTRING("\", ") +
                                         prefValue +
                                         NS_LITERAL_CSTRING(");"));

    return PL_DHASH_NEXT;
}
Example #2
0
/*
 *   This is an abbreviated parser for the HID Report Descriptor.  We
 *   know what devices we are talking to, so this is by no means meant
 *   to be generic.  We can make some safe assumptions:
 *
 *   - We know there are no LONG tags, all short
 *   - We know that we have no MAIN Feature and MAIN Output items
 *   - We know what the IRQ reports are supposed to look like.
 *
 *   The main purpose of this is to use the HID report desc to figure
 *   out the mins and maxs of the fields in the IRQ reports.  The IRQ
 *   reports for 400/401 change slightly if the max X is bigger than 64K.
 *
 */
static void parse_hid_report_descriptor(struct gtco *device, char * report,
					int length)
{
	int   x, i = 0;

	/* Tag primitive vars */
	__u8   prefix;
	__u8   size;
	__u8   tag;
	__u8   type;
	__u8   data   = 0;
	__u16  data16 = 0;
	__u32  data32 = 0;

	/* For parsing logic */
	int   inputnum = 0;
	__u32 usage = 0;

	/* Global Values, indexed by TAG */
	__u32 globalval[TAG_GLOB_MAX];
	__u32 oldval[TAG_GLOB_MAX] = {0};

	/* Debug stuff */
	char  maintype = 'x';
	char  globtype[12];
	int   indent = 0;
	char  indentstr[10] = "";


	dbg("======>>>>>>PARSE<<<<<<======");

	/* Walk  this report and pull out the info we need */
	while (i < length) {
		prefix = report[i];

		/* Skip over prefix */
		i++;

		/* Determine data size and save the data in the proper variable */
		size = PREF_SIZE(prefix);
		switch (size) {
		case 1:
			data = report[i];
			break;
		case 2:
			data16 = get_unaligned_le16(&report[i]);
			break;
		case 3:
			size = 4;
			data32 = get_unaligned_le32(&report[i]);
			break;
		}

		/* Skip size of data */
		i += size;

		/* What we do depends on the tag type */
		tag  = PREF_TAG(prefix);
		type = PREF_TYPE(prefix);
		switch (type) {
		case TYPE_MAIN:
			strcpy(globtype, "");
			switch (tag) {

			case TAG_MAIN_INPUT:
				/*
				 * The INPUT MAIN tag signifies this is
				 * information from a report.  We need to
				 * figure out what it is and store the
				 * min/max values
				 */

				maintype = 'I';
				if (data == 2)
					strcpy(globtype, "Variable");
				else if (data == 3)
					strcpy(globtype, "Var|Const");

				dbg("::::: Saving Report: %d input #%d Max: 0x%X(%d) Min:0x%X(%d) of %d bits",
				    globalval[TAG_GLOB_REPORT_ID], inputnum,
				    globalval[TAG_GLOB_LOG_MAX], globalval[TAG_GLOB_LOG_MAX],
				    globalval[TAG_GLOB_LOG_MIN], globalval[TAG_GLOB_LOG_MIN],
				    globalval[TAG_GLOB_REPORT_SZ] * globalval[TAG_GLOB_REPORT_CNT]);


				/*
				  We can assume that the first two input items
				  are always the X and Y coordinates.  After
				  that, we look for everything else by
				  local usage value
				 */
				switch (inputnum) {
				case 0:  /* X coord */
					dbg("GER: X Usage: 0x%x", usage);
					if (device->max_X == 0) {
						device->max_X = globalval[TAG_GLOB_LOG_MAX];
						device->min_X = globalval[TAG_GLOB_LOG_MIN];
					}
					break;

				case 1:  /* Y coord */
					dbg("GER: Y Usage: 0x%x", usage);
					if (device->max_Y == 0) {
						device->max_Y = globalval[TAG_GLOB_LOG_MAX];
						device->min_Y = globalval[TAG_GLOB_LOG_MIN];
					}
					break;

				default:
					/* Tilt X */
					if (usage == DIGITIZER_USAGE_TILT_X) {
						if (device->maxtilt_X == 0) {
							device->maxtilt_X = globalval[TAG_GLOB_LOG_MAX];
							device->mintilt_X = globalval[TAG_GLOB_LOG_MIN];
						}
					}

					/* Tilt Y */
					if (usage == DIGITIZER_USAGE_TILT_Y) {
						if (device->maxtilt_Y == 0) {
							device->maxtilt_Y = globalval[TAG_GLOB_LOG_MAX];
							device->mintilt_Y = globalval[TAG_GLOB_LOG_MIN];
						}
					}

					/* Pressure */
					if (usage == DIGITIZER_USAGE_TIP_PRESSURE) {
						if (device->maxpressure == 0) {
							device->maxpressure = globalval[TAG_GLOB_LOG_MAX];
							device->minpressure = globalval[TAG_GLOB_LOG_MIN];
						}
					}

					break;
				}

				inputnum++;
				break;

			case TAG_MAIN_OUTPUT:
				maintype = 'O';
				break;

			case TAG_MAIN_FEATURE:
				maintype = 'F';
				break;

			case TAG_MAIN_COL_START:
				maintype = 'S';

				if (data == 0) {
					dbg("======>>>>>> Physical");
					strcpy(globtype, "Physical");
				} else
					dbg("======>>>>>>");

				/* Indent the debug output */
				indent++;
				for (x = 0; x < indent; x++)
					indentstr[x] = '-';
				indentstr[x] = 0;

				/* Save global tags */
				for (x = 0; x < TAG_GLOB_MAX; x++)
					oldval[x] = globalval[x];

				break;

			case TAG_MAIN_COL_END:
				dbg("<<<<<<======");
				maintype = 'E';
				indent--;
				for (x = 0; x < indent; x++)
					indentstr[x] = '-';
				indentstr[x] = 0;

				/* Copy global tags back */
				for (x = 0; x < TAG_GLOB_MAX; x++)
					globalval[x] = oldval[x];

				break;
			}

			switch (size) {
			case 1:
				dbg("%sMAINTAG:(%d) %c SIZE: %d Data: %s 0x%x",
				    indentstr, tag, maintype, size, globtype, data);
				break;

			case 2:
				dbg("%sMAINTAG:(%d) %c SIZE: %d Data: %s 0x%x",
				    indentstr, tag, maintype, size, globtype, data16);
				break;

			case 4:
				dbg("%sMAINTAG:(%d) %c SIZE: %d Data: %s 0x%x",
				    indentstr, tag, maintype, size, globtype, data32);
				break;
			}
			break;

		case TYPE_GLOBAL:
			switch (tag) {
			case TAG_GLOB_USAGE:
				/*
				 * First time we hit the global usage tag,
				 * it should tell us the type of device
				 */
				if (device->usage == 0)
					device->usage = data;

				strcpy(globtype, "USAGE");
				break;

			case TAG_GLOB_LOG_MIN:
				strcpy(globtype, "LOG_MIN");
				break;

			case TAG_GLOB_LOG_MAX:
				strcpy(globtype, "LOG_MAX");
				break;

			case TAG_GLOB_PHYS_MIN:
				strcpy(globtype, "PHYS_MIN");
				break;

			case TAG_GLOB_PHYS_MAX:
				strcpy(globtype, "PHYS_MAX");
				break;

			case TAG_GLOB_UNIT_EXP:
				strcpy(globtype, "EXP");
				break;

			case TAG_GLOB_UNIT:
				strcpy(globtype, "UNIT");
				break;

			case TAG_GLOB_REPORT_SZ:
				strcpy(globtype, "REPORT_SZ");
				break;

			case TAG_GLOB_REPORT_ID:
				strcpy(globtype, "REPORT_ID");
				/* New report, restart numbering */
				inputnum = 0;
				break;

			case TAG_GLOB_REPORT_CNT:
				strcpy(globtype, "REPORT_CNT");
				break;

			case TAG_GLOB_PUSH:
				strcpy(globtype, "PUSH");
				break;

			case TAG_GLOB_POP:
				strcpy(globtype, "POP");
				break;
			}

			/* Check to make sure we have a good tag number
			   so we don't overflow array */
			if (tag < TAG_GLOB_MAX) {
				switch (size) {
				case 1:
					dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",
					    indentstr, globtype, tag, size, data);
					globalval[tag] = data;
					break;

				case 2:
					dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",
					    indentstr, globtype, tag, size, data16);
					globalval[tag] = data16;
					break;

				case 4:
					dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",
					    indentstr, globtype, tag, size, data32);
					globalval[tag] = data32;
					break;
				}
			} else {
				dbg("%sGLOBALTAG: ILLEGAL TAG:%d SIZE: %d ",
				    indentstr, tag, size);
			}
			break;

		case TYPE_LOCAL:
			switch (tag) {
			case TAG_GLOB_USAGE:
				strcpy(globtype, "USAGE");
				/* Always 1 byte */
				usage = data;
				break;

			case TAG_GLOB_LOG_MIN:
				strcpy(globtype, "MIN");
				break;

			case TAG_GLOB_LOG_MAX:
				strcpy(globtype, "MAX");
				break;

			default:
				strcpy(globtype, "UNKNOWN");
				break;
			}

			switch (size) {
			case 1:
				dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x",
				    indentstr, tag, globtype, size, data);
				break;

			case 2:
				dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x",
				    indentstr, tag, globtype, size, data16);
				break;

			case 4:
				dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x",
				    indentstr, tag, globtype, size, data32);
				break;
			}

			break;
		}
	}
}
static void parse_hid_report_descriptor(struct gtco *device, char * report,
					int length)
{
	int   x, i = 0;

	
	__u8   prefix;
	__u8   size;
	__u8   tag;
	__u8   type;
	__u8   data   = 0;
	__u16  data16 = 0;
	__u32  data32 = 0;

	
	int   inputnum = 0;
	__u32 usage = 0;

	
	__u32 globalval[TAG_GLOB_MAX];
	__u32 oldval[TAG_GLOB_MAX];

	
	char  maintype = 'x';
	char  globtype[12];
	int   indent = 0;
	char  indentstr[10] = "";


	dbg("======>>>>>>PARSE<<<<<<======");

	
	while (i < length) {
		prefix = report[i];

		
		i++;

		
		size = PREF_SIZE(prefix);
		switch (size) {
		case 1:
			data = report[i];
			break;
		case 2:
			data16 = get_unaligned_le16(&report[i]);
			break;
		case 3:
			size = 4;
			data32 = get_unaligned_le32(&report[i]);
			break;
		}

		
		i += size;

		
		tag  = PREF_TAG(prefix);
		type = PREF_TYPE(prefix);
		switch (type) {
		case TYPE_MAIN:
			strcpy(globtype, "");
			switch (tag) {

			case TAG_MAIN_INPUT:

				maintype = 'I';
				if (data == 2)
					strcpy(globtype, "Variable");
				else if (data == 3)
					strcpy(globtype, "Var|Const");

				dbg("::::: Saving Report: %d input #%d Max: 0x%X(%d) Min:0x%X(%d) of %d bits",
				    globalval[TAG_GLOB_REPORT_ID], inputnum,
				    globalval[TAG_GLOB_LOG_MAX], globalval[TAG_GLOB_LOG_MAX],
				    globalval[TAG_GLOB_LOG_MIN], globalval[TAG_GLOB_LOG_MIN],
				    globalval[TAG_GLOB_REPORT_SZ] * globalval[TAG_GLOB_REPORT_CNT]);


				switch (inputnum) {
				case 0:  
					dbg("GER: X Usage: 0x%x", usage);
					if (device->max_X == 0) {
						device->max_X = globalval[TAG_GLOB_LOG_MAX];
						device->min_X = globalval[TAG_GLOB_LOG_MIN];
					}
					break;

				case 1:  
					dbg("GER: Y Usage: 0x%x", usage);
					if (device->max_Y == 0) {
						device->max_Y = globalval[TAG_GLOB_LOG_MAX];
						device->min_Y = globalval[TAG_GLOB_LOG_MIN];
					}
					break;

				default:
					
					if (usage == DIGITIZER_USAGE_TILT_X) {
						if (device->maxtilt_X == 0) {
							device->maxtilt_X = globalval[TAG_GLOB_LOG_MAX];
							device->mintilt_X = globalval[TAG_GLOB_LOG_MIN];
						}
					}

					
					if (usage == DIGITIZER_USAGE_TILT_Y) {
						if (device->maxtilt_Y == 0) {
							device->maxtilt_Y = globalval[TAG_GLOB_LOG_MAX];
							device->mintilt_Y = globalval[TAG_GLOB_LOG_MIN];
						}
					}

					
					if (usage == DIGITIZER_USAGE_TIP_PRESSURE) {
						if (device->maxpressure == 0) {
							device->maxpressure = globalval[TAG_GLOB_LOG_MAX];
							device->minpressure = globalval[TAG_GLOB_LOG_MIN];
						}
					}

					break;
				}

				inputnum++;
				break;

			case TAG_MAIN_OUTPUT:
				maintype = 'O';
				break;

			case TAG_MAIN_FEATURE:
				maintype = 'F';
				break;

			case TAG_MAIN_COL_START:
				maintype = 'S';

				if (data == 0) {
					dbg("======>>>>>> Physical");
					strcpy(globtype, "Physical");
				} else
					dbg("======>>>>>>");

				
				indent++;
				for (x = 0; x < indent; x++)
					indentstr[x] = '-';
				indentstr[x] = 0;

				
				for (x = 0; x < TAG_GLOB_MAX; x++)
					oldval[x] = globalval[x];

				break;

			case TAG_MAIN_COL_END:
				dbg("<<<<<<======");
				maintype = 'E';
				indent--;
				for (x = 0; x < indent; x++)
					indentstr[x] = '-';
				indentstr[x] = 0;

				
				for (x = 0; x < TAG_GLOB_MAX; x++)
					globalval[x] = oldval[x];

				break;
			}

			switch (size) {
			case 1:
				dbg("%sMAINTAG:(%d) %c SIZE: %d Data: %s 0x%x",
				    indentstr, tag, maintype, size, globtype, data);
				break;

			case 2:
				dbg("%sMAINTAG:(%d) %c SIZE: %d Data: %s 0x%x",
				    indentstr, tag, maintype, size, globtype, data16);
				break;

			case 4:
				dbg("%sMAINTAG:(%d) %c SIZE: %d Data: %s 0x%x",
				    indentstr, tag, maintype, size, globtype, data32);
				break;
			}
			break;

		case TYPE_GLOBAL:
			switch (tag) {
			case TAG_GLOB_USAGE:
				if (device->usage == 0)
					device->usage = data;

				strcpy(globtype, "USAGE");
				break;

			case TAG_GLOB_LOG_MIN:
				strcpy(globtype, "LOG_MIN");
				break;

			case TAG_GLOB_LOG_MAX:
				strcpy(globtype, "LOG_MAX");
				break;

			case TAG_GLOB_PHYS_MIN:
				strcpy(globtype, "PHYS_MIN");
				break;

			case TAG_GLOB_PHYS_MAX:
				strcpy(globtype, "PHYS_MAX");
				break;

			case TAG_GLOB_UNIT_EXP:
				strcpy(globtype, "EXP");
				break;

			case TAG_GLOB_UNIT:
				strcpy(globtype, "UNIT");
				break;

			case TAG_GLOB_REPORT_SZ:
				strcpy(globtype, "REPORT_SZ");
				break;

			case TAG_GLOB_REPORT_ID:
				strcpy(globtype, "REPORT_ID");
				
				inputnum = 0;
				break;

			case TAG_GLOB_REPORT_CNT:
				strcpy(globtype, "REPORT_CNT");
				break;

			case TAG_GLOB_PUSH:
				strcpy(globtype, "PUSH");
				break;

			case TAG_GLOB_POP:
				strcpy(globtype, "POP");
				break;
			}

			if (tag < TAG_GLOB_MAX) {
				switch (size) {
				case 1:
					dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",
					    indentstr, globtype, tag, size, data);
					globalval[tag] = data;
					break;

				case 2:
					dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",
					    indentstr, globtype, tag, size, data16);
					globalval[tag] = data16;
					break;

				case 4:
					dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",
					    indentstr, globtype, tag, size, data32);
					globalval[tag] = data32;
					break;
				}
			} else {
				dbg("%sGLOBALTAG: ILLEGAL TAG:%d SIZE: %d ",
				    indentstr, tag, size);
			}
			break;

		case TYPE_LOCAL:
			switch (tag) {
			case TAG_GLOB_USAGE:
				strcpy(globtype, "USAGE");
				
				usage = data;
				break;

			case TAG_GLOB_LOG_MIN:
				strcpy(globtype, "MIN");
				break;

			case TAG_GLOB_LOG_MAX:
				strcpy(globtype, "MAX");
				break;

			default:
				strcpy(globtype, "UNKNOWN");
				break;
			}

			switch (size) {
			case 1:
				dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x",
				    indentstr, tag, globtype, size, data);
				break;

			case 2:
				dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x",
				    indentstr, tag, globtype, size, data16);
				break;

			case 4:
				dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x",
				    indentstr, tag, globtype, size, data32);
				break;
			}

			break;
		}
	}
}