Hoa central
Tput.php
Go to the documentation of this file.
1 <?php
2 
37 namespace Hoa\Console;
38 
50 class Tput
51 {
57  protected static $_booleans = [
58  'auto_left_margin',
59  'auto_right_margin',
60  'no_esc_ctlc',
61  'ceol_standout_glitch',
62  'eat_newline_glitch',
63  'erase_overstrike',
64  'generic_type',
65  'hard_copy',
66  'meta_key', // originally has_meta_key
67  'status_line', // originally has_status_line
68  'insert_null_glitch',
69  'memory_above',
70  'memory_below',
71  'move_insert_mode',
72  'move_standout_mode',
73  'over_strike',
74  'status_line_esc_ok',
75  'dest_tabs_magic_smso',
76  'tilde_glitch',
77  'transparent_underline',
78  'xon_xoff',
79  'needs_xon_xoff',
80  'prtr_silent',
81  'hard_cursor',
82  'non_rev_rmcup',
83  'no_pad_char',
84  'non_dest_scroll_region',
85  'can_change',
86  'back_color_erase',
87  'hue_lightness_saturation',
88  'col_addr_glitch',
89  'cr_cancels_micro_mode',
90  'print_wheel', // originally has_print_wheel
91  'row_addr_glitch',
92  'semi_auto_right_margin',
93  'cpi_changes_res',
94  'lpi_changes_res',
95  // #ifdef __INTERNAL_CAPS_VISIBLE
96  'backspaces_with_bs',
97  'crt_no_scrolling',
98  'no_correctly_working_cr',
99  'gnu_meta_key', // originally gnu_has_meta_key
100  'linefeed_is_newline',
101  'hardware_tabs', // originally has_hardware_tabs
102  'return_does_clr_eol'
103  ];
104 
110  protected static $_numbers = [
111  'columns',
112  'init_tabs',
113  'lines',
114  'lines_of_memory',
115  'magic_cookie_glitch',
116  'padding_baud_rate',
117  'virtual_terminal',
118  'width_status_line',
119  'num_labels',
120  'label_height',
121  'label_width',
122  'max_attributes',
123  'maximum_windows',
124  'max_colors',
125  'max_pairs',
126  'no_color_video',
127  'buffer_capacity',
128  'dot_vert_spacing',
129  'dot_horz_spacing',
130  'max_micro_address',
131  'max_micro_jump',
132  'micro_col_size',
133  'micro_line_size',
134  'number_of_pins',
135  'output_res_char',
136  'output_res_line',
137  'output_res_horz_inch',
138  'output_res_vert_inch',
139  'print_rate',
140  'wide_char_size',
141  'buttons',
142  'bit_image_entwining',
143  'bit_image_type',
144  // #ifdef __INTERNAL_CAPS_VISIBLE
145  'magic_cookie_glitch_ul',
146  'carriage_return_delay',
147  'new_line_delay',
148  'backspace_delay',
149  'horizontal_tab_delay',
150  'number_of_function_keys'
151  ];
152 
158  protected static $_strings = [
159  'back_tab',
160  'bell',
161  'carriage_return',
162  'change_scroll_region',
163  'clear_all_tabs',
164  'clear_screen',
165  'clr_eol',
166  'clr_eos',
167  'column_address',
168  'command_character',
169  'cursor_address',
170  'cursor_down',
171  'cursor_home',
172  'cursor_invisible',
173  'cursor_left',
174  'cursor_mem_address',
175  'cursor_normal',
176  'cursor_right',
177  'cursor_to_ll',
178  'cursor_up',
179  'cursor_visible',
180  'delete_character',
181  'delete_line',
182  'dis_status_line',
183  'down_half_line',
184  'enter_alt_charset_mode',
185  'enter_blink_mode',
186  'enter_bold_mode',
187  'enter_ca_mode',
188  'enter_delete_mode',
189  'enter_dim_mode',
190  'enter_insert_mode',
191  'enter_secure_mode',
192  'enter_protected_mode',
193  'enter_reverse_mode',
194  'enter_standout_mode',
195  'enter_underline_mode',
196  'erase_chars',
197  'exit_alt_charset_mode',
198  'exit_attribute_mode',
199  'exit_ca_mode',
200  'exit_delete_mode',
201  'exit_insert_mode',
202  'exit_standout_mode',
203  'exit_underline_mode',
204  'flash_screen',
205  'form_feed',
206  'from_status_line',
207  'init_1string',
208  'init_2string',
209  'init_3string',
210  'init_file',
211  'insert_character',
212  'insert_line',
213  'insert_padding',
214  'key_backspace',
215  'key_catab',
216  'key_clear',
217  'key_ctab',
218  'key_dc',
219  'key_dl',
220  'key_down',
221  'key_eic',
222  'key_eol',
223  'key_eos',
224  'key_f0',
225  'key_f1',
226  'key_f10',
227  'key_f2',
228  'key_f3',
229  'key_f4',
230  'key_f5',
231  'key_f6',
232  'key_f7',
233  'key_f8',
234  'key_f9',
235  'key_home',
236  'key_ic',
237  'key_il',
238  'key_left',
239  'key_ll',
240  'key_npage',
241  'key_ppage',
242  'key_right',
243  'key_sf',
244  'key_sr',
245  'key_stab',
246  'key_up',
247  'keypad_local',
248  'keypad_xmit',
249  'lab_f0',
250  'lab_f1',
251  'lab_f10',
252  'lab_f2',
253  'lab_f3',
254  'lab_f4',
255  'lab_f5',
256  'lab_f6',
257  'lab_f7',
258  'lab_f8',
259  'lab_f9',
260  'meta_off',
261  'meta_on',
262  'newline',
263  'pad_char',
264  'parm_dch',
265  'parm_delete_line',
266  'parm_down_cursor',
267  'parm_ich',
268  'parm_index',
269  'parm_insert_line',
270  'parm_left_cursor',
271  'parm_right_cursor',
272  'parm_rindex',
273  'parm_up_cursor',
274  'pkey_key',
275  'pkey_local',
276  'pkey_xmit',
277  'print_screen',
278  'prtr_off',
279  'prtr_on',
280  'repeat_char',
281  'reset_1string',
282  'reset_2string',
283  'reset_3string',
284  'reset_file',
285  'restore_cursor',
286  'row_address',
287  'save_cursor',
288  'scroll_forward',
289  'scroll_reverse',
290  'set_attributes',
291  'set_tab',
292  'set_window',
293  'tab',
294  'to_status_line',
295  'underline_char',
296  'up_half_line',
297  'init_prog',
298  'key_a1',
299  'key_a3',
300  'key_b2',
301  'key_c1',
302  'key_c3',
303  'prtr_non',
304  'char_padding',
305  'acs_chars',
306  'plab_norm',
307  'key_btab',
308  'enter_xon_mode',
309  'exit_xon_mode',
310  'enter_am_mode',
311  'exit_am_mode',
312  'xon_character',
313  'xoff_character',
314  'ena_acs',
315  'label_on',
316  'label_off',
317  'key_beg',
318  'key_cancel',
319  'key_close',
320  'key_command',
321  'key_copy',
322  'key_create',
323  'key_end',
324  'key_enter',
325  'key_exit',
326  'key_find',
327  'key_help',
328  'key_mark',
329  'key_message',
330  'key_move',
331  'key_next',
332  'key_open',
333  'key_options',
334  'key_previous',
335  'key_print',
336  'key_redo',
337  'key_reference',
338  'key_refresh',
339  'key_replace',
340  'key_restart',
341  'key_resume',
342  'key_save',
343  'key_suspend',
344  'key_undo',
345  'key_sbeg',
346  'key_scancel',
347  'key_scommand',
348  'key_scopy',
349  'key_screate',
350  'key_sdc',
351  'key_sdl',
352  'key_select',
353  'key_send',
354  'key_seol',
355  'key_sexit',
356  'key_sfind',
357  'key_shelp',
358  'key_shome',
359  'key_sic',
360  'key_sleft',
361  'key_smessage',
362  'key_smove',
363  'key_snext',
364  'key_soptions',
365  'key_sprevious',
366  'key_sprint',
367  'key_sredo',
368  'key_sreplace',
369  'key_sright',
370  'key_srsume',
371  'key_ssave',
372  'key_ssuspend',
373  'key_sundo',
374  'req_for_input',
375  'key_f11',
376  'key_f12',
377  'key_f13',
378  'key_f14',
379  'key_f15',
380  'key_f16',
381  'key_f17',
382  'key_f18',
383  'key_f19',
384  'key_f20',
385  'key_f21',
386  'key_f22',
387  'key_f23',
388  'key_f24',
389  'key_f25',
390  'key_f26',
391  'key_f27',
392  'key_f28',
393  'key_f29',
394  'key_f30',
395  'key_f31',
396  'key_f32',
397  'key_f33',
398  'key_f34',
399  'key_f35',
400  'key_f36',
401  'key_f37',
402  'key_f38',
403  'key_f39',
404  'key_f40',
405  'key_f41',
406  'key_f42',
407  'key_f43',
408  'key_f44',
409  'key_f45',
410  'key_f46',
411  'key_f47',
412  'key_f48',
413  'key_f49',
414  'key_f50',
415  'key_f51',
416  'key_f52',
417  'key_f53',
418  'key_f54',
419  'key_f55',
420  'key_f56',
421  'key_f57',
422  'key_f58',
423  'key_f59',
424  'key_f60',
425  'key_f61',
426  'key_f62',
427  'key_f63',
428  'clr_bol',
429  'clear_margins',
430  'set_left_margin',
431  'set_right_margin',
432  'label_format',
433  'set_clock',
434  'display_clock',
435  'remove_clock',
436  'create_window',
437  'goto_window',
438  'hangup',
439  'dial_phone',
440  'quick_dial',
441  'tone',
442  'pulse',
443  'flash_hook',
444  'fixed_pause',
445  'wait_tone',
446  'user0',
447  'user1',
448  'user2',
449  'user3',
450  'user4',
451  'user5',
452  'user6',
453  'user7',
454  'user8',
455  'user9',
456  'orig_pair',
457  'orig_colors',
458  'initialize_color',
459  'initialize_pair',
460  'set_color_pair',
461  'set_foreground',
462  'set_background',
463  'change_char_pitch',
464  'change_line_pitch',
465  'change_res_horz',
466  'change_res_vert',
467  'define_char',
468  'enter_doublewide_mode',
469  'enter_draft_quality',
470  'enter_italics_mode',
471  'enter_leftward_mode',
472  'enter_micro_mode',
473  'enter_near_letter_quality',
474  'enter_normal_quality',
475  'enter_shadow_mode',
476  'enter_subscript_mode',
477  'enter_superscript_mode',
478  'enter_upward_mode',
479  'exit_doublewide_mode',
480  'exit_italics_mode',
481  'exit_leftward_mode',
482  'exit_micro_mode',
483  'exit_shadow_mode',
484  'exit_subscript_mode',
485  'exit_superscript_mode',
486  'exit_upward_mode',
487  'micro_column_address',
488  'micro_down',
489  'micro_left',
490  'micro_right',
491  'micro_row_address',
492  'micro_up',
493  'order_of_pins',
494  'parm_down_micro',
495  'parm_left_micro',
496  'parm_right_micro',
497  'parm_up_micro',
498  'select_char_set',
499  'set_bottom_margin',
500  'set_bottom_margin_parm',
501  'set_left_margin_parm',
502  'set_right_margin_parm',
503  'set_top_margin',
504  'set_top_margin_parm',
505  'start_bit_image',
506  'start_char_set_def',
507  'stop_bit_image',
508  'stop_char_set_def',
509  'subscript_characters',
510  'superscript_characters',
511  'these_cause_cr',
512  'zero_motion',
513  'char_set_names',
514  'key_mouse',
515  'mouse_info',
516  'req_mouse_pos',
517  'get_mouse',
518  'set_a_foreground',
519  'set_a_background',
520  'pkey_plab',
521  'device_type',
522  'code_set_init',
523  'set0_des_seq',
524  'set1_des_seq',
525  'set2_des_seq',
526  'set3_des_seq',
527  'set_lr_margin',
528  'set_tb_margin',
529  'bit_image_repeat',
530  'bit_image_newline',
531  'bit_image_carriage_return',
532  'color_names',
533  'define_bit_image_region',
534  'end_bit_image_region',
535  'set_color_band',
536  'set_page_length',
537  'display_pc_char',
538  'enter_pc_charset_mode',
539  'exit_pc_charset_mode',
540  'enter_scancode_mode',
541  'exit_scancode_mode',
542  'pc_term_options',
543  'scancode_escape',
544  'alt_scancode_esc',
545  'enter_horizontal_hl_mode',
546  'enter_left_hl_mode',
547  'enter_low_hl_mode',
548  'enter_right_hl_mode',
549  'enter_top_hl_mode',
550  'enter_vertical_hl_mode',
551  'set_a_attributes',
552  'set_pglen_inch',
553  // #ifdef __INTERNAL_CAPS_VISIBLE
554  'termcap_init2',
555  'termcap_reset',
556  'linefeed_if_not_lf',
557  'backspace_if_not_bs',
558  'other_non_function_keys',
559  'arrow_key_map',
560  'acs_ulcorner',
561  'acs_llcorner',
562  'acs_urcorner',
563  'acs_lrcorner',
564  'acs_ltee',
565  'acs_rtee',
566  'acs_btee',
567  'acs_ttee',
568  'acs_hline',
569  'acs_vline',
570  'acs_plus',
571  'memory_lock',
572  'memory_unlock',
573  'box_chars_1'
574  ];
575 
581  protected $_informations = [];
582 
583 
584 
591  public function __construct($terminfo = null)
592  {
593  if (null === $terminfo) {
594  $terminfo = static::getTerminfo();
595  }
596 
597  $this->parse($terminfo);
598 
599  return;
600  }
601 
609  protected function parse($terminfo)
610  {
611  if (!file_exists($terminfo)) {
612  throw new Exception(
613  'Terminfo file %s does not exist.',
614  0,
615  $terminfo
616  );
617  }
618 
619  $data = file_get_contents($terminfo);
620  $length = strlen($data);
621  $out = ['file' => $terminfo];
622 
623  $headers = [
624  'data_size' => $length,
625  'header_size' => 12,
626  'magic_number' => (ord($data[ 1]) << 8) | ord($data[ 0]),
627  'names_size' => (ord($data[ 3]) << 8) | ord($data[ 2]),
628  'bool_count' => (ord($data[ 5]) << 8) | ord($data[ 4]),
629  'number_count' => (ord($data[ 7]) << 8) | ord($data[ 6]),
630  'string_count' => (ord($data[ 9]) << 8) | ord($data[ 8]),
631  'string_table_size' => (ord($data[11]) << 8) | ord($data[10]),
632  ];
633  $out['headers'] = $headers;
634 
635 
636  // Names.
637  $i = $headers['header_size'];
638 
639  list($out['name'], $out['description']) =
640  explode('|', substr($data, $i, $headers['names_size'] - 1));
641 
642  // Booleans.
643  $i += $headers['names_size'];
644  $booleans = [];
645  $booleanNames = &static::$_booleans;
646 
647  for (
648  $e = 0, $max = $i + $headers['bool_count'];
649  $i < $max;
650  ++$e, ++$i
651  ) {
652  $booleans[$booleanNames[$e]] = 1 === ord($data[$i]);
653  }
654 
655  $out['booleans'] = $booleans;
656 
657  // Numbers.
658  if (1 === ($i % 2)) {
659  ++$i;
660  }
661 
662  $numbers = [];
663  $numberNames = &static::$_numbers;
664 
665  for (
666  $e = 0, $max = $i + $headers['number_count'] * 2;
667  $i < $max;
668  ++$e, $i += 2
669  ) {
670  $name = $numberNames[$e];
671  $data_i0 = ord($data[$i ]);
672  $data_i1 = ord($data[$i + 1]);
673 
674  if ($data_i1 === 255 && $data_i0 === 255) {
675  $numbers[$name] = -1;
676  } else {
677  $numbers[$name] = ($data_i1 << 8) | $data_i0;
678  }
679  }
680 
681  $out['numbers'] = $numbers;
682 
683  // Strings.
684  $strings = [];
685  $stringNames = &static::$_strings;
686  $ii = $i + $headers['string_count'] * 2;
687 
688  for (
689  $e = 0, $max = $ii;
690  $i < $max;
691  ++$e, $i += 2
692  ) {
693  $name = $stringNames[$e];
694  $data_i0 = ord($data[$i ]);
695  $data_i1 = ord($data[$i + 1]);
696 
697  if ($data_i1 === 255 && $data_i0 === 255) {
698  continue;
699  }
700 
701  $a = ($data_i1 << 8) | $data_i0;
702  $strings[$name] = $a;
703 
704  if (65534 === $a) {
705  continue;
706  }
707 
708  $b = $ii + $a;
709  $c = $b;
710 
711  while ($c < $length && ord($data[$c])) {
712  $c++;
713  }
714 
715  $value = substr($data, $b, $c - $b);
716  $strings[$name] = false !== $value ? $value : null;
717  }
718 
719  $out['strings'] = $strings;
720 
721  return $this->_informations = $out;
722  }
723 
729  public function getInformations()
730  {
731  return $this->_informations;
732  }
733 
740  public function has($boolean)
741  {
742  if (!isset($this->_informations['booleans'][$boolean])) {
743  return false;
744  }
745 
746  return $this->_informations['booleans'][$boolean];
747  }
748 
755  public function count($number)
756  {
757  if (!isset($this->_informations['numbers'][$number])) {
758  return 0;
759  }
760 
761  return $this->_informations['numbers'][$number];
762  }
763 
770  public function get($string)
771  {
772  if (!isset($this->_informations['strings'][$string])) {
773  return null;
774  }
775 
776  return $this->_informations['strings'][$string];
777  }
778 
784  public static function getTerm()
785  {
786  return
787  isset($_SERVER['TERM'])
788  ? $_SERVER['TERM']
789  : (OS_WIN ? 'windows-ansi' : 'xterm');
790  }
791 
798  public static function getTerminfo($term = null)
799  {
800  $paths = [];
801 
802  if (isset($_SERVER['TERMINFO'])) {
803  $paths[] = $_SERVER['TERMINFO'];
804  }
805 
806  if (isset($_SERVER['HOME'])) {
807  $paths[] = $_SERVER['HOME'] . DS . '.terminfo';
808  }
809 
810  if (isset($_SERVER['TERMINFO_DIRS'])) {
811  foreach (explode(':', $_SERVER['TERMINFO_DIRS']) as $path) {
812  $paths[] = $path;
813  }
814  }
815 
816  $paths[] = '/usr/share/terminfo';
817  $paths[] = '/usr/share/lib/terminfo';
818  $paths[] = '/lib/terminfo';
819  $paths[] = '/usr/lib/terminfo';
820  $paths[] = '/usr/local/share/terminfo';
821  $paths[] = '/usr/local/share/lib/terminfo';
822  $paths[] = '/usr/local/lib/terminfo';
823  $paths[] = '/usr/local/ncurses/lib/terminfo';
824  $paths[] = 'hoa://Library/Console/Terminfo';
825 
826  $term = $term ?: static::getTerm();
827  $fileHexa = dechex(ord($term[0])) . DS . $term;
828  $fileAlpha = $term[0] . DS . $term;
829  $pathname = null;
830 
831  foreach ($paths as $path) {
832  if (file_exists($_ = $path . DS . $fileHexa) ||
833  file_exists($_ = $path . DS . $fileAlpha)) {
834  $pathname = $_;
835 
836  break;
837  }
838  }
839 
840  return $pathname;
841  }
842 }
static getTerm()
Definition: Tput.php:784
has($boolean)
Definition: Tput.php:740
static getTerminfo($term=null)
Definition: Tput.php:798
__construct($terminfo=null)
Definition: Tput.php:591
count($number)
Definition: Tput.php:755
static $_booleans
Definition: Tput.php:57
static $_strings
Definition: Tput.php:158
parse($terminfo)
Definition: Tput.php:609
static $_numbers
Definition: Tput.php:110