Mercurial > hg > Game > Cerium
view Renderer/Engine/ps3fb/cp_vt.cc @ 1319:31455d34e502 draft
collada file reader minor changes.
author | Taiki TAIRA <e095767@ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 18 Dec 2011 09:39:14 +0900 |
parents | 9f5e6bfb1c09 |
children |
line wrap: on
line source
// cp_vt.c // // Copyright (c) 2006, Mike Acton <macton@cellperformance.com> // // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated // documentation files (the "Software"), to deal in the Software without restriction, including without // limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // the Software, and to permit persons to whom the Software is furnished to do so, subject to the following // conditions: // // The above copyright notice and this permission notice shall be included in all copies or substantial // portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO // EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN // AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. // NOTES: // From http://www.linuxjournal.com/article/2597 // // "Console ttys are used when the keyboard and monitor are directly connected to the system without running // the X Window System. Since you can have several virtual consoles, the devices are tty0 through tty63. In // theory you can have 64 virtual consoles, but most people use only a few. The device /dev/console is // identical to tty0 and is needed for historical reasons. If your system lets you log in on consoles 1 // through 6, then when you run X Windows System, X uses console 7, so you'll need /dev/tty1 through /dev/ // tty7 on your system. I recommend having files up through /dev/tty12. For more information on using // virtual consoles, see the article Keyboards, Consoles and VT Cruising by John Fisk in the November 1996 // issue of Linux Journal" #include <stdio.h> #include <stdint.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include <linux/vt.h> #include <linux/kd.h> #include "cp_vt.h" static inline const char* select_error_str( int existing_error, const char* const existing_error_str, int new_error, const char* const new_error_str ) { // Only report the first error found - any error that follows is probably just a cascading effect. const char* error_str = (char*)( (~(intptr_t)existing_error & (intptr_t)new_error & (intptr_t)new_error_str) | ((intptr_t)existing_error & (intptr_t)existing_error_str) ); return (error_str); } int cp_vt_open_graphics(cp_vt* restrict vt) { const char* error_str = NULL; int error = 0; // Open the current tty // From http://tldp.org/HOWTO/Text-Terminal-HOWTO-6.html#ss6.3 // (An excellent overview by David S. Lawyer) // // "In Linux the PC monitor is usually called the console and has several device special files associated // with it: vc/0 (tty0), vc/1 (tty1), vc/2 (tty2), etc. When you log in you are on vc/1. To go to vc/2 // (on the same screen) press down the 2 keys Alt(left)-F3. For vc/3 use Left Alt-F3, etc. These (vc/1, // vc/2, vc/3, etc.) are called "virtual terminals". vc/0 (tty0) is just an alias for the current virtual // terminal and it's where messages from the system are sent. Thus messages from the system will be seen // on the console (monitor) regardless of which virtual terminal it is displaying." const int cur_tty = open( "/dev/tty0", O_RDWR ); const int open_cur_tty_error = (cur_tty >> ((sizeof(int)*8)-1)); const char* open_cur_tty_error_str = "Could not open /dev/tty0. Check permissions."; error_str = select_error_str( error, error_str, open_cur_tty_error, open_cur_tty_error_str ); error = error | open_cur_tty_error; // From: http://www.linuxjournal.com/article/2783 // (A little out of date, but a nice primer.) // // "VT_GETSTATE returns the state of all VT's in the kernel in the structure: // // struct vt_stat { // ushort v_active; // ushort v_signal; // ushort v_state; // }; // // v_active the currently active VT // v_state mask of all the opened VT's // // v_active holds the number of the active VT (starting from 1), while v_state // holds a mask where there is a 1 for each VT that has been opened by some process. // Note that VT 0 is always opened in this scenario, since it refers to the current VT. // // Bugs: // The v_signal member is unsupported." struct vt_stat vts; const int get_state_error = ioctl( cur_tty, VT_GETSTATE, &vts ); const char* get_state_error_str = "VT_GETSTATE failed on /dev/tty0"; error_str = select_error_str( error, error_str, get_state_error, get_state_error_str ); error = error | get_state_error; vt->prev_tty_ndx = vts.v_active; // From: http://opensolaris.org/os/project/vconsole/vt.7i.txt // (Close enough to Linux and a pretty good source of documentation.) // // "VT_OPENQRY // This call is used to find an available VT. The argu- // ment to the ioctl is a pointer to an integer. The integer // will be filled in with the number of the first avail- // able VT that no other process has open (and hence, is // available to be opened). If there are no available // VTs, then -1 will be filled in." const int open_query_error = ioctl( cur_tty, VT_OPENQRY, &vt->tty_ndx); const char* open_query_error_str = "No open ttys available"; error_str = select_error_str( error, error_str, open_query_error, open_query_error_str ); error = error | open_query_error; const int close_cur_tty_error = close( cur_tty ); const char* close_cur_tty_error_str = "Could not close parent tty"; error_str = select_error_str( error, error_str, close_cur_tty_error, close_cur_tty_error_str ); error = error | close_cur_tty_error; char tty_file_name[11]; (void)snprintf( tty_file_name, 11, "/dev/tty%d", vt->tty_ndx ); const int tty = open( tty_file_name, O_RDWR ); const int open_tty_error = (cur_tty >> ((sizeof(int)*8)-1)); const char* open_tty_error_str = "Could not open tty"; error_str = select_error_str( error, error_str, open_tty_error, open_tty_error_str ); error = error | open_tty_error; vt->tty = tty; // From: http://opensolaris.org/os/project/vconsole/vt.7i.txt // (Close enough to Linux and a pretty good source of documentation.) // // "VT_ACTIVATE // This call has the effect of making the VT specified in // the argument the active VT. The VT manager will cause // a switch to occur in the same manner as if a hotkey had // initiated the switch. If the specified VT is not open // or does not exist the call will fail and errno will be // set to ENXIO." // // "VT_WAITACTIVE // If the specified VT is already active, this call // returns immediately. Otherwise, it will sleep until // the specified VT becomes active, at which point it will // return." const int activate_tty_error = ioctl( vt->tty, VT_ACTIVATE, vt->tty_ndx ); const char* activate_tty_error_str = "Could not activate tty"; error_str = select_error_str( error, error_str, activate_tty_error, activate_tty_error_str ); error = error | activate_tty_error; #if 0 const int waitactive_tty_error = ioctl( vt->tty, VT_WAITACTIVE, vt->tty_ndx ); const char* waitactive_tty_error_str = "Could not switch to tty"; error_str = select_error_str( error, error_str, waitactive_tty_error, waitactive_tty_error_str ); error = error | waitactive_tty_error; #endif // From: http://opensolaris.org/os/project/vconsole/vt.7i.txt // (Close enough to Linux and a pretty good source of documentation.) // // "KDSETMODE // This call is used to set the text/graphics mode to the VT. // // KD_TEXT indicates that console text will be displayed on the screen // with this VT. Normally KD_TEXT is combined with VT_AUTO mode for // text console terminals, so that the console text display will // automatically be saved and restored on the hot key screen switches. // // KD_GRAPHICS indicates that the user/application, usually Xserver, // will have direct control of the display for this VT in graphics // mode. Normally KD_GRAPHICS is combined with VT_PROCESS mode for // this VT indicating direct control of the display in graphics mode. // In this mode, all writes to this VT using the write system call are // ignored, and the user is responsible for saving and restoring the // display on the hot key screen switches." // Save the current VT mode. This is most likely KD_TEXT. const int kdgetmode_error = ioctl( vt->tty, KDGETMODE, &vt->prev_kdmode ); const char* kdgetmode_error_str = "Could not get mode for tty"; error_str = select_error_str( error, error_str, kdgetmode_error, kdgetmode_error_str ); error = error | kdgetmode_error; // Set VT to GRAPHICS (user draw) mode const int kdsetmode_graphics_error = ioctl( vt->tty, KDSETMODE, KD_GRAPHICS ); const char* kdsetmode_graphics_error_str = "Could not set graphics mode for tty"; error_str = select_error_str( error, error_str, kdsetmode_graphics_error, kdsetmode_graphics_error_str ); error = error | kdsetmode_graphics_error; // // Not bothering with VT_PROCESS, VT_AUTO is fine for our purposes. // // If vt blanking is active, for example when running this program from a remote terminal, // setting KD_GRAPHICS will not disable the blanking. Reset to KD_TEXT from KD_GRAPHICS will // force disable blanking. Then return to KD_GRAPHICS for drawing. // // Note: KD_TEXT (default) to KD_TEXT will do nothing, so blanking will not be disable unless // the mode is changing. i.e. the initial set to KD_GRAPHICS above is useful. const int kdsetmode_text_error = ioctl( vt->tty, KDSETMODE, KD_TEXT ); const char* kdsetmode_text_error_str = "Could not set text mode for tty"; error_str = select_error_str( error, error_str, kdsetmode_text_error, kdsetmode_text_error_str ); error = error | kdsetmode_text_error; const int kdsetmode_graphics_reset_error = ioctl( vt->tty, KDSETMODE, KD_GRAPHICS ); const char* kdsetmode_graphics_reset_error_str = "Could not reset graphics mode for tty"; error_str = select_error_str( error, error_str, kdsetmode_graphics_reset_error, kdsetmode_graphics_reset_error_str ); error = error | kdsetmode_graphics_reset_error; if ( error == -1 ) { printf("ERROR: vt_graphics_open: %s\n",error_str); return (-1); } return (0); } int cp_vt_close(cp_vt* restrict vt) { const char* error_str = NULL; int error = 0; // Reset previous mode on tty (likely KD_TEXT) const int kdsetmode_error = ioctl( vt->tty, KDSETMODE, vt->prev_kdmode ); const char* kdsetmode_error_str = "Could not reset previous mode for tty"; error_str = select_error_str( error, error_str, kdsetmode_error, kdsetmode_error_str ); error = error | kdsetmode_error; // Restore previous tty const int activate_tty_error = ioctl( vt->tty, VT_ACTIVATE, vt->prev_tty_ndx ); const char* activate_tty_error_str = "Could not activate previous tty"; error_str = select_error_str( error, error_str, activate_tty_error, activate_tty_error_str ); error = error | activate_tty_error; const int waitactive_tty_error = ioctl( vt->tty, VT_WAITACTIVE, vt->prev_tty_ndx ); const char* waitactive_tty_error_str = "Could not switch to previous tty"; error_str = select_error_str( error, error_str, waitactive_tty_error, waitactive_tty_error_str ); error = error | waitactive_tty_error; // Close tty const int close_tty_error = close( vt->tty ); const char* close_tty_error_str = "Could not close tty"; error_str = select_error_str( error, error_str, close_tty_error, close_tty_error_str ); error = error | close_tty_error; if ( error == -1 ) { printf("ERROR: vt_close: %s\n",error_str); return (-1); } return (0); }