libexplain  1.4.D001
libexplain/buffer/tioclinux.c
Go to the documentation of this file.
00001 /*
00002  * libexplain - Explain errno values returned by libc functions
00003  * Copyright (C) 2009, 2011, 2013 Peter Miller
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU Lesser General Public License as
00007  * published by the Free Software Foundation; either version 3 of the
00008  * License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public License
00016  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00017  */
00018 
00019 #include <libexplain/ac/linux/tiocl.h>
00020 #include <libexplain/ac/stdint.h>
00021 #include <libexplain/ac/string.h>
00022 
00023 #include <libexplain/buffer/int.h>
00024 #include <libexplain/buffer/int32_t.h>
00025 #include <libexplain/buffer/int8.h>
00026 #include <libexplain/buffer/pointer.h>
00027 #include <libexplain/buffer/tioclinux.h>
00028 #include <libexplain/parse_bits.h>
00029 #include <libexplain/is_efault.h>
00030 #include <libexplain/sizeof.h>
00031 
00032 
00033 #ifdef HAVE_LINUX_TIOCL_H
00034 
00035 static void
00036 explain_buffer_tiocl(explain_string_buffer_t *sb, int value)
00037 {
00038     static const explain_parse_bits_table_t table[] =
00039     {
00040         { "TIOCL_SETSEL", TIOCL_SETSEL },
00041         { "TIOCL_PASTESEL", TIOCL_PASTESEL },
00042         { "TIOCL_UNBLANKSCREEN", TIOCL_UNBLANKSCREEN },
00043         { "TIOCL_SELLOADLUT", TIOCL_SELLOADLUT },
00044         { "TIOCL_GETSHIFTSTATE", TIOCL_GETSHIFTSTATE },
00045         { "TIOCL_GETMOUSEREPORTING", TIOCL_GETMOUSEREPORTING },
00046         { "TIOCL_SETVESABLANK", TIOCL_SETVESABLANK },
00047         { "TIOCL_SETKMSGREDIRECT", TIOCL_SETKMSGREDIRECT },
00048         { "TIOCL_GETFGCONSOLE", TIOCL_GETFGCONSOLE },
00049         { "TIOCL_SCROLLCONSOLE", TIOCL_SCROLLCONSOLE },
00050         { "TIOCL_BLANKSCREEN", TIOCL_BLANKSCREEN },
00051         { "TIOCL_BLANKEDSCREEN", TIOCL_BLANKEDSCREEN },
00052 #ifdef TIOCL_GETKMSGREDIRECT
00053         { "TIOCL_GETKMSGREDIRECT", TIOCL_GETKMSGREDIRECT },
00054 #endif
00055     };
00056 
00057     explain_parse_bits_print_single(sb, value, table, SIZEOF(table));
00058 }
00059 
00060 
00061 static void
00062 explain_buffer_tiocl_setsel(explain_string_buffer_t *sb, int value)
00063 {
00064     static const explain_parse_bits_table_t table[] =
00065     {
00066         { "TIOCL_SELCHAR", TIOCL_SELCHAR },
00067         { "TIOCL_SELWORD", TIOCL_SELWORD },
00068         { "TIOCL_SELLINE", TIOCL_SELLINE },
00069         { "TIOCL_SELPOINTER", TIOCL_SELPOINTER },
00070         { "TIOCL_SELCLEAR", TIOCL_SELCLEAR },
00071         { "TIOCL_SELMOUSEREPORT", TIOCL_SELMOUSEREPORT },
00072         { "TIOCL_SELBUTTONMASK", TIOCL_SELBUTTONMASK },
00073     };
00074 
00075     explain_parse_bits_print_single(sb, value, table, SIZEOF(table));
00076 }
00077 
00078 
00079 void
00080 explain_buffer_tioclinux(explain_string_buffer_t *sb, const void *data)
00081 {
00082     /* See console_ioctl(4) for more information. */
00083     if (!data)
00084     {
00085         print_pointer:
00086         explain_buffer_pointer(sb, data);
00087     }
00088     else
00089     {
00090         const unsigned char *cp;
00091 
00092         cp = data;
00093         switch (*cp)
00094         {
00095         case TIOCL_SETSEL:
00096             {
00097                 struct tiocl_selection sel;
00098 
00099                 if (explain_is_efault_pointer(cp, 1 + sizeof(sel)))
00100                     goto print_pointer;
00101                 memcpy(&sel, cp + 1, sizeof(sel));
00102                 explain_buffer_tiocl(sb, cp[0]);
00103                 explain_string_buffer_puts(sb, "{ case = ");
00104                 explain_buffer_tiocl(sb, cp[0]);
00105                 explain_string_buffer_puts(sb, ", xs = ");
00106                 explain_buffer_uint(sb, sel.xs);
00107                 explain_string_buffer_puts(sb, ", ys = ");
00108                 explain_buffer_uint(sb, sel.ys);
00109                 explain_string_buffer_puts(sb, ", xe = ");
00110                 explain_buffer_uint(sb, sel.xe);
00111                 explain_string_buffer_puts(sb, ", ye = ");
00112                 explain_buffer_uint(sb, sel.ye);
00113                 explain_string_buffer_puts(sb, ", sel_mode = ");
00114                 explain_buffer_tiocl_setsel(sb, sel.sel_mode);
00115                 explain_string_buffer_puts(sb, " }");
00116             }
00117             break;
00118 
00119         case TIOCL_SETVESABLANK:
00120             if (explain_is_efault_pointer(data, 2))
00121                 goto print_pointer;
00122             explain_string_buffer_puts(sb, "{ case = ");
00123             explain_buffer_tiocl(sb, cp[0]);
00124             explain_string_buffer_puts(sb, ", value = ");
00125             explain_buffer_uint8(sb, cp[1]);
00126             explain_string_buffer_puts(sb, " }");
00127             break;
00128 
00129         case TIOCL_SELLOADLUT:
00130             {
00131                 uint32_t        lut[8];
00132 
00133                 if (explain_is_efault_pointer(data, 4 + sizeof(lut)))
00134                     goto print_pointer;
00135                 memcpy(lut, cp + 4, sizeof(lut));
00136                 explain_string_buffer_puts(sb, "{ case = ");
00137                 explain_buffer_tiocl(sb, cp[0]);
00138                 explain_string_buffer_puts(sb, ", value = ");
00139                 explain_buffer_uint32_array(sb, lut, SIZEOF(lut));
00140                 explain_string_buffer_puts(sb, " }");
00141             }
00142             break;
00143 
00144         case TIOCL_SCROLLCONSOLE:
00145             {
00146                 int32_t         value;
00147 
00148                 if (explain_is_efault_pointer(data, 4 + sizeof(value)))
00149                     goto print_pointer;
00150                 memcpy(&value, cp + 4, sizeof(value));
00151                 explain_string_buffer_puts(sb, "{ case = ");
00152                 explain_buffer_tiocl(sb, cp[0]);
00153                 explain_string_buffer_puts(sb, ", value = ");
00154                 explain_buffer_int32_t(sb, value);
00155                 explain_string_buffer_puts(sb, " }");
00156             }
00157             break;
00158 
00159         case TIOCL_GETSHIFTSTATE:
00160         case TIOCL_GETMOUSEREPORTING:
00161         case TIOCL_SETKMSGREDIRECT:
00162         case TIOCL_GETFGCONSOLE:
00163             /*
00164              * The above 4 cases return data BUT they overwrite the
00165              * control bytes, so we don't know at print_data_returned
00166              * time which code it was, and thus can't print a
00167              * representation.  Sigh.
00168              *
00169              * Fall through...
00170              */
00171 
00172         case TIOCL_BLANKEDSCREEN:
00173         case TIOCL_BLANKSCREEN:
00174         case TIOCL_PASTESEL:
00175         case TIOCL_UNBLANKSCREEN:
00176 #ifdef TIOCL_GETKMSGREDIRECT
00177         case TIOCL_GETKMSGREDIRECT:
00178 #endif
00179         default:
00180             if (explain_is_efault_pointer(data, 1))
00181                 goto print_pointer;
00182             explain_string_buffer_puts(sb, "{ case = ");
00183             explain_buffer_tiocl(sb, cp[0]);
00184             explain_string_buffer_puts(sb, " }");
00185             break;
00186         }
00187     }
00188 }
00189 
00190 #else
00191 
00192 void
00193 explain_buffer_tioclinux(explain_string_buffer_t *sb, const void *data)
00194 {
00195     explain_buffer_pointer(sb, data);
00196 }
00197 
00198 #endif
00199 
00200 
00201 /* vim: set ts=8 sw=4 et : */