1 /**************************************************************************
5 Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
7 Contact: Boram Park <boram1288.park@samsung.com>
8 Sangjin LEE <lsj119@samsung.com>
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
35 #include <sys/types.h>
36 #include <sys/fcntl.h>
44 #include "xdbg_types.h"
45 #include "xdbg_evlog.h"
46 #include "bool_exp_rule_checker.h"
47 #include <X11/Xlibint.h>
55 static char *evt_type[] = { "Event", "Request", "Reply", "Flush", "Error" };
56 static char *evt_dir[] = { "<====", "---->", "<----", "*****", "<----"};
58 static RULE_CHECKER rc = NULL;
61 _mergeArgs (char * target, int argc, const char ** argv)
66 for (i=0; i<argc; i++)
68 len = sprintf (target, "%s", argv[i]);
77 _strcasecmp(const char *str1, const char *str2)
79 const u_char *us1 = (const u_char *) str1, *us2 = (const u_char *) str2;
81 while (tolower(*us1) == tolower(*us2)) {
87 return (tolower(*us1) - tolower(*us2));
91 xDbgEvlogGetCmd (char *path)
96 p = strrchr (path, '/');
101 xDbgEvlogRuleSet (const int argc, const char **argv, char *reply, int *len)
103 const char * command;
106 rc = rulechecker_init();
110 rulechecker_print_rule (rc, reply);
116 if (!_strcasecmp (command, "add"))
118 POLICY_TYPE policy_type;
119 RC_RESULT_TYPE result;
120 const char * policy = argv[1];
126 REPLY ("Error : Too few arguments.\n");
130 if (!_strcasecmp (policy, "ALLOW"))
132 else if (!_strcasecmp (policy, "DENY"))
136 REPLY ("Error : Unknown policy : [%s].\n Policy should be ALLOW or DENY.\n", policy);
140 _mergeArgs (rule, argc - 2, &(argv[2]));
142 for (i = 0 ; i < strlen(rule) ; i++)
144 static int apply = 0;
145 if(rule[i] == '\"' || rule[i] == '\'')
151 strcat(rule, "|| type=reply || type=error");
156 result = rulechecker_add_rule (rc, policy_type, rule);
157 if (result == RC_ERR_TOO_MANY_RULES)
159 REPLY ("Error : Too many rules were added.\n");
162 else if (result == RC_ERR_PARSE_ERROR)
164 REPLY ("Error : An error occured during parsing the rule [%s]\n", rule);
168 REPLY ("The rule was successfully added.\n\n");
169 rulechecker_print_rule (rc, reply);
172 else if (!_strcasecmp (command, "remove"))
174 const char * remove_idx;
179 REPLY ("Error : Too few arguments.\n");
183 for (i=0; i<argc - 1; i++)
185 remove_idx = argv[i+1];
187 if (!_strcasecmp (remove_idx, "all"))
189 rulechecker_destroy (rc);
190 rc = rulechecker_init();
191 REPLY ("Every rules were successfully removed.\n");
195 int index = atoi (remove_idx);
196 if (isdigit (*remove_idx) && rulechecker_remove_rule (rc, index) == 0)
197 REPLY ("The rule [%d] was successfully removed.\n", index);
199 REPLY ("Rule remove fail : No such rule [%s].\n", remove_idx);
202 rulechecker_print_rule (rc, reply);
205 else if (!_strcasecmp (command, "print"))
207 rulechecker_print_rule (rc, reply);
210 else if (!_strcasecmp (command, "help"))
212 REPLY ("%s", rulechecker_print_usage());
216 REPLY ("%s\nUnknown command : [%s].\n\n", rulechecker_print_usage(), command);
222 xDbgEvlogRuleValidate (EvlogInfo *evinfo)
224 const char *evlog_name = "";
228 rc = rulechecker_init ();
232 XDBG_LOG ("failed: create rulechecker\n");
236 cmd = xDbgEvlogGetCmd (evinfo->client.command);
238 if (evinfo->type == REQUEST)
239 evlog_name = evinfo->req.name;
240 else if (evinfo->type == EVENT)
241 evlog_name = evinfo->evt.name;
242 else if (evinfo ->type == REPLY)
243 evlog_name = evinfo->rep.name;
245 return rulechecker_validate_rule (rc,
254 ExtensionInfo Evlog_extensions[] = {
255 {xDbgEvlogCompositeGetBase, 0, 0, 0, NULL, NULL},
256 {xDbgEvlogDamageGetBase, 0, 0, 0, NULL, NULL},
257 {xDbgEvlogDri2GetBase, 0, 0, 0, NULL, NULL},
258 {xDbgEvlogGestureGetBase, 0, 0, 0, NULL, NULL},
259 {xDbgEvlogXinputGetBase, 0, 0, 0, NULL, NULL},
260 {xDbgEvlogRandrGetBase, 0, 0, 0, NULL, NULL},
261 {xDbgEvlogXextDpmsGetBase, 0, 0, 0, NULL, NULL},
262 {xDbgEvlogXextShmGetBase, 0, 0, 0, NULL, NULL},
263 {xDbgEvlogXextSyncGetBase, 0, 0, 0, NULL, NULL},
264 {xDbgEvlogXextXtestGetBase, 0, 0, 0, NULL, NULL},
265 {xDbgEvlogXextXtestExt1GetBase, 0, 0, 0, NULL, NULL},
266 {xDbgEvlogXvGetBase, 0, 0, 0, NULL, NULL}
268 ExtensionInfo* Sorted_Evlog_extensions;
269 int Extensions_size = 0;
272 _ExtensionsSwap(ExtensionInfo* first, ExtensionInfo* second)
282 _SortEvlogExtensions ()
287 Sorted_Evlog_extensions = (ExtensionInfo*)malloc(sizeof(Evlog_extensions));
288 RETURN_VAL_IF_FAIL (Sorted_Evlog_extensions != NULL, FALSE);
290 memcpy(Sorted_Evlog_extensions, Evlog_extensions, sizeof(Evlog_extensions));
292 for (i = 0 ; i < Extensions_size - 1 ; i++)
295 for (j = 1 ; j < Extensions_size - i ; j++)
297 if(Sorted_Evlog_extensions[j-1].evt_base > Sorted_Evlog_extensions[j].evt_base)
299 _ExtensionsSwap(&Sorted_Evlog_extensions[j-1], &Sorted_Evlog_extensions[j]);
311 xDbgEvlogGetExtensionEntry ()
314 static Bool success = FALSE;
321 Extensions_size = sizeof(Evlog_extensions) / sizeof (ExtensionInfo);
323 for (i = 0 ; i < Extensions_size ; i++)
325 Evlog_extensions[i].get_base_func (Evlog_extensions + i);
328 if(!_SortEvlogExtensions ())
339 xDbgEvlogFillLog (EvlogInfo *evinfo, Bool on, char *reply, int *len)
343 RETURN_IF_FAIL (evinfo->type >= 0 && (sizeof (evt_dir) / sizeof (char*)));
344 RETURN_IF_FAIL (evinfo->type >= 0 && (sizeof (evt_type) / sizeof (char*)));
346 if (evinfo->type == REPLY && !evinfo->rep.isStart)
348 if (on) // detail option is on
354 REPLY ("[%10.3f][%5ld] %22s(%2d:%5d) %s %7s ",
355 evinfo->time / 1000.0,
357 xDbgEvlogGetCmd (evinfo->client.command),
358 evinfo->client.index,
360 evt_dir[evinfo->type],
361 evt_type[evinfo->type]);
363 if (evinfo->type == REQUEST)
366 reply = xDbgEvlogReqeust (evinfo, on, reply, len);
369 else if (evinfo->type == EVENT)
371 evinfo->evt.size = sizeof (xEvent);
373 reply = xDbgEvlogEvent (evinfo, on, reply, len);
376 else if (evinfo->type == REPLY)
379 reply = xDbgEvlogReply (evinfo, on, reply, len);
382 else if (evinfo->type == ERROR)
384 REPLY("(ErrorCode(0x%02x) resourceID(0x%lx) majorCode(%d) minorCode(%d))",
385 evinfo->err.errorCode,
386 evinfo->err.resourceID,
387 evinfo->err.majorCode,
388 evinfo->err.minorCode);
392 const char *evlog_name = "";
393 if (evinfo->type == REQUEST)
394 evlog_name = evinfo->req.name;
395 else if (evinfo->type == EVENT)
396 evlog_name = evinfo->evt.name;
397 else if (evinfo->type == REPLY)
398 evlog_name = evinfo->rep.name;
399 REPLY ("(%s)", evlog_name);
408 void xDbgDistroyAtomList (EvlogInfo *evinfo)
410 EvlogAtomTable *cur, *next;
412 if (!evinfo->evatom.init)
415 xorg_list_for_each_entry_safe(cur, next, &evinfo->evatom.list, link)
417 xorg_list_del(&cur->link);
421 evinfo->evatom.init = 0;
422 evinfo->evatom.size = 0;
425 void xDbgDistroyRegionList (EvlogInfo *evinfo)
427 EvlogRegionTable *cur, *next;
429 if (!evinfo->evregion.init)
432 xorg_list_for_each_entry_safe(cur, next, &evinfo->evregion.list, link)
434 xorg_list_del(&cur->link);
438 evinfo->evregion.init = 0;
439 evinfo->evregion.size = 0;
442 char* xDbgGetAtom(Atom atom, EvlogInfo *evinfo, char *reply, int *len)
444 EvlogAtomTable *table;
446 table = malloc (sizeof(EvlogAtomTable));
450 evinfo->mask |= EVLOG_MASK_ATOM;
453 if (!evinfo->evatom.init)
455 xorg_list_init(&evinfo->evatom.list);
456 evinfo->evatom.init = 1;
459 if (NameForAtom(atom))
460 snprintf (table->buf, XDBG_BUF_SIZE, "%s", (char*)NameForAtom(atom));
462 snprintf (table->buf, XDBG_BUF_SIZE, "0x%lx", atom);
464 xorg_list_add(&table->link, &evinfo->evatom.list);
465 evinfo->evatom.size++;
467 xorg_list_for_each_entry(table, &evinfo->evatom.list, link)
468 if(table->xid == atom)
470 REPLY ("(%s)", table->buf);
477 char* xDbgGetRegion(XserverRegion region, EvlogInfo *evinfo, char *reply, int *len)
479 EvlogRegionTable *table;
481 extern _X_EXPORT RESTYPE RegionResType;
486 int err = dixLookupResourceByType((pointer *) &pRegion, region,
487 RegionResType, (ClientPtr)evinfo->client.pClient,
490 evinfo->mask |= EVLOG_MASK_REGION;
492 if (!evinfo->evregion.init)
494 xorg_list_init(&evinfo->evregion.list);
495 evinfo->evregion.init = 1;
500 table = malloc (sizeof(EvlogAtomTable));
506 snprintf (table->buf, XDBG_BUF_SIZE, "0x%lx", region);
507 xorg_list_add(&table->link, &evinfo->evregion.list);
508 evinfo->evregion.size++;
512 nrect = RegionNumRects(pRegion);
513 rects = RegionRects(pRegion);
515 for (i = 0; i < nrect; i++)
517 table = malloc (sizeof(EvlogAtomTable));
524 s += snprintf (table->buf + s, XDBG_BUF_SIZE - s,
528 rects[i].x2 - rects[i].x1,
529 rects[i].y2 - rects[i].y1);
530 xorg_list_add(&table->link, &evinfo->evregion.list);
531 evinfo->evregion.size++;
537 xorg_list_for_each_entry(table, &evinfo->evregion.list, link)
538 if(table->xid == region)
540 REPLY ("%s", table->buf);
541 if(table != xorg_list_last_entry(&evinfo->evregion.list, EvlogRegionTable, link))