Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright  2012 Intel Corporation
      3  * Copyright  2012 Ran Benita
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the "Software"),
      7  * to deal in the Software without restriction, including without limitation
      8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      9  * and/or sell copies of the Software, and to permit persons to whom the
     10  * Software is furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice (including the next
     13  * paragraph) shall be included in all copies or substantial portions of the
     14  * Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     22  * DEALINGS IN THE SOFTWARE.
     23  *
     24  * Author: Daniel Stone <daniel (at) fooishbar.org>
     25  */
     26 
     27 #include <sys/types.h>
     28 #include <sys/stat.h>
     29 #include <errno.h>
     30 #include <unistd.h>
     31 
     32 #include "xkbcommon/xkbcommon.h"
     33 #include "utils.h"
     34 #include "context.h"
     35 
     36 unsigned int
     37 xkb_context_num_failed_include_paths(struct xkb_context *ctx)
     38 {
     39     return darray_size(ctx->failed_includes);
     40 }
     41 
     42 const char *
     43 xkb_context_failed_include_path_get(struct xkb_context *ctx,
     44                                     unsigned int idx)
     45 {
     46     if (idx >= xkb_context_num_failed_include_paths(ctx))
     47         return NULL;
     48 
     49     return darray_item(ctx->failed_includes, idx);
     50 }
     51 
     52 xkb_atom_t
     53 xkb_atom_lookup(struct xkb_context *ctx, const char *string)
     54 {
     55     return atom_lookup(ctx->atom_table, string, strlen(string));
     56 }
     57 
     58 xkb_atom_t
     59 xkb_atom_intern(struct xkb_context *ctx, const char *string, size_t len)
     60 {
     61     return atom_intern(ctx->atom_table, string, len, false);
     62 }
     63 
     64 xkb_atom_t
     65 xkb_atom_steal(struct xkb_context *ctx, char *string)
     66 {
     67     return atom_intern(ctx->atom_table, string, strlen(string), true);
     68 }
     69 
     70 const char *
     71 xkb_atom_text(struct xkb_context *ctx, xkb_atom_t atom)
     72 {
     73     return atom_text(ctx->atom_table, atom);
     74 }
     75 
     76 void
     77 xkb_log(struct xkb_context *ctx, enum xkb_log_level level, int verbosity,
     78         const char *fmt, ...)
     79 {
     80     va_list args;
     81 
     82     if (ctx->log_level < level || ctx->log_verbosity < verbosity)
     83         return;
     84 
     85     va_start(args, fmt);
     86     ctx->log_fn(ctx, level, fmt, args);
     87     va_end(args);
     88 }
     89 
     90 char *
     91 xkb_context_get_buffer(struct xkb_context *ctx, size_t size)
     92 {
     93     char *rtrn;
     94 
     95     if (size >= sizeof(ctx->text_buffer))
     96         return NULL;
     97 
     98     if (sizeof(ctx->text_buffer) - ctx->text_next <= size)
     99         ctx->text_next = 0;
    100 
    101     rtrn = &ctx->text_buffer[ctx->text_next];
    102     ctx->text_next += size;
    103 
    104     return rtrn;
    105 }
    106 
    107 #ifndef DEFAULT_XKB_VARIANT
    108 #define DEFAULT_XKB_VARIANT NULL
    109 #endif
    110 
    111 #ifndef DEFAULT_XKB_OPTIONS
    112 #define DEFAULT_XKB_OPTIONS NULL
    113 #endif
    114 
    115 static const char *
    116 xkb_context_get_default_rules(struct xkb_context *ctx)
    117 {
    118     const char *env = NULL;
    119 
    120     if (ctx->use_environment_names)
    121         env = secure_getenv("XKB_DEFAULT_RULES");
    122 
    123     return env ? env : DEFAULT_XKB_RULES;
    124 }
    125 
    126 static const char *
    127 xkb_context_get_default_model(struct xkb_context *ctx)
    128 {
    129     const char *env = NULL;
    130 
    131     if (ctx->use_environment_names)
    132         env = secure_getenv("XKB_DEFAULT_MODEL");
    133 
    134     return env ? env : DEFAULT_XKB_MODEL;
    135 }
    136 
    137 static const char *
    138 xkb_context_get_default_layout(struct xkb_context *ctx)
    139 {
    140     const char *env = NULL;
    141 
    142     if (ctx->use_environment_names)
    143         env = secure_getenv("XKB_DEFAULT_LAYOUT");
    144 
    145     return env ? env : DEFAULT_XKB_LAYOUT;
    146 }
    147 
    148 static const char *
    149 xkb_context_get_default_variant(struct xkb_context *ctx)
    150 {
    151     const char *env = NULL;
    152     const char *layout = secure_getenv("XKB_DEFAULT_LAYOUT");
    153 
    154     /* We don't want to inherit the variant if they haven't also set a
    155      * layout, since they're so closely paired. */
    156     if (layout && ctx->use_environment_names)
    157         env = secure_getenv("XKB_DEFAULT_VARIANT");
    158 
    159     return env ? env : DEFAULT_XKB_VARIANT;
    160 }
    161 
    162 static const char *
    163 xkb_context_get_default_options(struct xkb_context *ctx)
    164 {
    165     const char *env = NULL;
    166 
    167     if (ctx->use_environment_names)
    168         env = secure_getenv("XKB_DEFAULT_OPTIONS");
    169 
    170     return env ? env : DEFAULT_XKB_OPTIONS;
    171 }
    172 
    173 void
    174 xkb_context_sanitize_rule_names(struct xkb_context *ctx,
    175                                 struct xkb_rule_names *rmlvo)
    176 {
    177     if (isempty(rmlvo->rules))
    178         rmlvo->rules = xkb_context_get_default_rules(ctx);
    179     if (isempty(rmlvo->model))
    180         rmlvo->model = xkb_context_get_default_model(ctx);
    181     /* Layout and variant are tied together, so don't try to use one from
    182      * the caller and one from the environment. */
    183     if (isempty(rmlvo->layout)) {
    184         rmlvo->layout = xkb_context_get_default_layout(ctx);
    185         rmlvo->variant = xkb_context_get_default_variant(ctx);
    186     }
    187     /* Options can be empty, so respect that if passed in. */
    188     if (rmlvo->options == NULL)
    189         rmlvo->options = xkb_context_get_default_options(ctx);
    190 }
    191