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" };
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++)
143 if(rule[i] == '\"' || rule[i] == '\'')
146 result = rulechecker_add_rule (rc, policy_type, rule);
147 if (result == RC_ERR_TOO_MANY_RULES)
149 REPLY ("Error : Too many rules were added.\n");
152 else if (result == RC_ERR_PARSE_ERROR)
154 REPLY ("Error : An error occured during parsing the rule [%s]\n", rule);
158 REPLY ("The rule was successfully added.\n\n");
159 rulechecker_print_rule (rc, reply);
162 else if (!_strcasecmp (command, "remove"))
164 const char * remove_idx;
169 REPLY ("Error : Too few arguments.\n");
173 for (i=0; i<argc - 1; i++)
175 remove_idx = argv[i+1];
177 if (!_strcasecmp (remove_idx, "all"))
179 rulechecker_destroy (rc);
180 rc = rulechecker_init();
181 REPLY ("Every rules were successfully removed.\n");
185 int index = atoi (remove_idx);
186 if (isdigit (*remove_idx) && rulechecker_remove_rule (rc, index) == 0)
187 REPLY ("The rule [%d] was successfully removed.\n", index);
189 REPLY ("Rule remove fail : No such rule [%s].\n", remove_idx);
192 rulechecker_print_rule (rc, reply);
195 else if (!_strcasecmp (command, "print"))
197 rulechecker_print_rule (rc, reply);
200 else if (!_strcasecmp (command, "help"))
202 REPLY ("%s", rulechecker_print_usage());
206 REPLY ("%s\nUnknown command : [%s].\n\n", rulechecker_print_usage(), command);
212 xDbgEvlogRuleValidate (EvlogInfo *evinfo)
214 const char *evlog_name = "";
218 rc = rulechecker_init ();
222 XDBG_LOG ("failed: create rulechecker\n");
226 cmd = xDbgEvlogGetCmd (evinfo->client.command);
228 if (evinfo->type == REQUEST)
229 evlog_name = evinfo->req.name;
230 else if (evinfo->type == EVENT)
231 evlog_name = evinfo->evt.name;
233 return rulechecker_validate_rule (rc,
242 ExtensionInfo Evlog_extensions[] = {
243 {xDbgEvlogCompositeGetBase, 0, 0, 0, NULL},
244 {xDbgEvlogDamageGetBase, 0, 0, 0, NULL},
245 {xDbgEvlogDri2GetBase, 0, 0, 0, NULL},
246 {xDbgEvlogGestureGetBase, 0, 0, 0, NULL},
247 {xDbgEvlogRandrGetBase, 0, 0, 0, NULL},
248 {xDbgEvlogXextDpmsGetBase, 0, 0, 0, NULL},
249 {xDbgEvlogXextShmGetBase, 0, 0, 0, NULL},
250 {xDbgEvlogXextSyncGetBase, 0, 0, 0, NULL},
251 {xDbgEvlogXextXtestGetBase, 0, 0, 0, NULL},
252 {xDbgEvlogXextXtestExt1GetBase, 0, 0, 0, NULL},
253 {xDbgEvlogXvGetBase, 0, 0, 0, NULL}
255 ExtensionInfo* Sorted_Evlog_extensions;
256 int Extensions_size = 0;
259 _ExtensionsSwap(ExtensionInfo* first, ExtensionInfo* second)
269 _SortEvlogExtensions ()
274 Sorted_Evlog_extensions = (ExtensionInfo*)malloc(sizeof(Evlog_extensions));
275 RETURN_VAL_IF_FAIL (Sorted_Evlog_extensions != NULL, FALSE);
277 memcpy(Sorted_Evlog_extensions, Evlog_extensions, sizeof(Evlog_extensions));
279 for (i = 0 ; i < Extensions_size - 1 ; i++)
282 for (j = 1 ; j < Extensions_size - i ; j++)
284 if(Sorted_Evlog_extensions[j-1].evt_base > Sorted_Evlog_extensions[j].evt_base)
286 _ExtensionsSwap(&Sorted_Evlog_extensions[j-1], &Sorted_Evlog_extensions[j]);
298 xDbgEvlogGetExtensionEntry ()
301 static Bool success = FALSE;
308 Extensions_size = sizeof(Evlog_extensions) / sizeof (ExtensionInfo);
310 for (i = 0 ; i < Extensions_size ; i++)
312 Evlog_extensions[i].get_base_func (Evlog_extensions + i);
315 if(!_SortEvlogExtensions ())
326 xDbgEvlogFillLog (EvlogInfo *evinfo, Bool on, char *reply, int *len)
330 RETURN_IF_FAIL (evinfo->type >= 0 && (sizeof (evt_dir) / sizeof (char*)));
331 RETURN_IF_FAIL (evinfo->type >= 0 && (sizeof (evt_type) / sizeof (char*)));
333 REPLY ("[%10.3f][%5ld] %22s(%2d:%5d) %s %7s ",
334 evinfo->time / 1000.0,
336 xDbgEvlogGetCmd (evinfo->client.command),
337 evinfo->client.index,
339 evt_dir[evinfo->type],
340 evt_type[evinfo->type]);
342 if (evinfo->type == REQUEST)
345 reply = xDbgEvlogReqeust (evinfo, on, reply, len);
348 else if (evinfo->type == EVENT)
350 evinfo->evt.size = sizeof (xEvent);
352 reply = xDbgEvlogEvent (evinfo, on, reply, len);
357 const char *evlog_name = "";
358 if (evinfo->type == REQUEST)
359 evlog_name = evinfo->req.name;
360 else if (evinfo->type == EVENT)
361 evlog_name = evinfo->evt.name;
362 REPLY ("(%s)", evlog_name);
371 void xDbgDistroyAtomList (EvlogInfo *evinfo)
373 EvlogAtomTable *cur, *next;
375 if (!evinfo->evatom.init)
378 xorg_list_for_each_entry_safe(cur, next, &evinfo->evatom.list, link)
380 xorg_list_del(&cur->link);
384 evinfo->evatom.init = 0;
385 evinfo->evatom.size = 0;
388 void xDbgDistroyRegionList (EvlogInfo *evinfo)
390 EvlogRegionTable *cur, *next;
392 if (!evinfo->evregion.init)
395 xorg_list_for_each_entry_safe(cur, next, &evinfo->evregion.list, link)
397 xorg_list_del(&cur->link);
401 evinfo->evregion.init = 0;
402 evinfo->evregion.size = 0;
405 char* xDbgGetAtom(Atom atom, EvlogInfo *evinfo, char *reply, int *len)
407 EvlogAtomTable *table;
409 table = malloc (sizeof(EvlogAtomTable));
413 evinfo->mask |= EVLOG_MASK_ATOM;
416 if (!evinfo->evatom.init)
418 xorg_list_init(&evinfo->evatom.list);
419 evinfo->evatom.init = 1;
422 if (NameForAtom(atom))
423 snprintf (table->buf, XDBG_BUF_SIZE, "%s", (char*)NameForAtom(atom));
425 snprintf (table->buf, XDBG_BUF_SIZE, "0x%lx", atom);
427 xorg_list_add(&table->link, &evinfo->evatom.list);
428 evinfo->evatom.size++;
430 xorg_list_for_each_entry(table, &evinfo->evatom.list, link)
431 if(table->xid == atom)
433 REPLY ("(%s)", table->buf);
440 char* xDbgGetRegion(XserverRegion region, EvlogInfo *evinfo, char *reply, int *len)
442 EvlogRegionTable *table;
444 extern _X_EXPORT RESTYPE RegionResType;
449 int err = dixLookupResourceByType((pointer *) &pRegion, region,
450 RegionResType, (ClientPtr)evinfo->client.pClient,
453 evinfo->mask |= EVLOG_MASK_REGION;
455 if (!evinfo->evregion.init)
457 xorg_list_init(&evinfo->evregion.list);
458 evinfo->evregion.init = 1;
463 table = malloc (sizeof(EvlogAtomTable));
469 snprintf (table->buf, XDBG_BUF_SIZE, "0x%lx", region);
470 xorg_list_add(&table->link, &evinfo->evregion.list);
471 evinfo->evregion.size++;
475 nrect = RegionNumRects(pRegion);
476 rects = RegionRects(pRegion);
478 for (i = 0; i < nrect; i++)
480 table = malloc (sizeof(EvlogAtomTable));
487 s += snprintf (table->buf + s, XDBG_BUF_SIZE - s,
491 rects[i].x2 - rects[i].x1,
492 rects[i].y2 - rects[i].y1);
493 xorg_list_add(&table->link, &evinfo->evregion.list);
494 evinfo->evregion.size++;
500 xorg_list_for_each_entry(table, &evinfo->evregion.list, link)
501 if(table->xid == region)
503 REPLY ("%s", table->buf);
504 if(table != xorg_list_last_entry(&evinfo->evregion.list, EvlogRegionTable, link))