1/* 2 * Copyright 2004-2006, Axel D��rfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5#ifndef TTY_PRIVATE_H 6#define TTY_PRIVATE_H 7 8#include <termios.h> 9 10#include <Drivers.h> 11#include <KernelExport.h> 12 13#include <condition_variable.h> 14#include <fs/select_sync_pool.h> 15#include <lock.h> 16#include <util/DoublyLinkedList.h> 17 18#include "line_buffer.h" 19 20 21#define TTY_BUFFER_SIZE 4096 22 23// The only nice Rico'ism :) 24#define CTRL(c) ((c) - 0100) 25 26 27typedef status_t (*tty_service_func)(struct tty *tty, uint32 op); 28 // not yet used... 29 30 31class RequestOwner; 32class Semaphore; 33struct tty; 34struct tty_cookie; 35 36class Request : public DoublyLinkedListLinkImpl<Request> { 37 public: 38 Request(); 39 40 void Init(RequestOwner *owner, tty_cookie *cookie, size_t bytesNeeded); 41 42 tty_cookie *TTYCookie() const { return fCookie; } 43 44 void Notify(size_t bytesAvailable); 45 void NotifyError(status_t error); 46 47 bool WasNotified() const { return fNotified; } 48 bool HasError() const { return fError; } 49 50 void Dump(const char* prefix); 51 52 private: 53 RequestOwner *fOwner; 54 tty_cookie *fCookie; 55 size_t fBytesNeeded; 56 bool fNotified; 57 bool fError; 58}; 59 60class RequestQueue { 61 public: 62 RequestQueue(); 63 ~RequestQueue() {} 64 65 void Add(Request *request); 66 void Remove(Request *request); 67 68 Request *First() const { return fRequests.First(); } 69 bool IsEmpty() const { return fRequests.IsEmpty(); } 70 71 void NotifyFirst(size_t bytesAvailable); 72 void NotifyError(status_t error); 73 void NotifyError(tty_cookie *cookie, status_t error); 74 75 void Dump(const char* prefix); 76 77 private: 78 typedef DoublyLinkedList<Request> RequestList; 79 80 RequestList fRequests; 81}; 82 83class RequestOwner { 84 public: 85 RequestOwner(); 86 87 void Enqueue(tty_cookie *cookie, RequestQueue *queue1, 88 RequestQueue *queue2 = NULL); 89 void Dequeue(); 90 91 void SetBytesNeeded(size_t bytesNeeded); 92 size_t BytesNeeded() const { return fBytesNeeded; } 93 94 status_t Wait(bool interruptable, bigtime_t timeout = B_INFINITE_TIMEOUT); 95 96 bool IsFirstInQueues(); 97 98 void Notify(Request *request); 99 void NotifyError(Request *request, status_t error); 100 101 status_t Error() const { return fError; } 102 103 private: 104 ConditionVariable* fConditionVariable; 105 tty_cookie* fCookie; 106 status_t fError; 107 RequestQueue* fRequestQueues[2]; 108 Request fRequests[2]; 109 size_t fBytesNeeded; 110}; 111 112 113struct tty_cookie : DoublyLinkedListLinkImpl<tty_cookie> { 114 struct tty *tty; 115 struct tty *other_tty; 116 uint32 open_mode; 117 int32 thread_count; 118 sem_id blocking_semaphore; 119 bool closed; 120}; 121 122typedef DoublyLinkedList<tty_cookie> TTYCookieList; 123 124struct tty_settings { 125 pid_t pgrp_id; 126 pid_t session_id; 127 struct termios termios; 128 struct winsize window_size; 129}; 130 131struct tty { 132 int32 ref_count; // referenced by cookies 133 int32 open_count; 134 int32 index; 135 struct mutex* lock; 136 tty_settings* settings; 137 select_sync_pool* select_pool; 138 RequestQueue reader_queue; 139 RequestQueue writer_queue; 140 TTYCookieList cookies; 141 line_buffer input_buffer; 142 tty_service_func service_func; 143 uint32 pending_eof; 144 bool is_master; 145}; 146 147static const uint32 kNumTTYs = 64; 148 149extern char *gDeviceNames[kNumTTYs * 2 + 3]; 150 151extern tty gMasterTTYs[kNumTTYs]; 152extern tty gSlaveTTYs[kNumTTYs]; 153extern tty_settings gTTYSettings[kNumTTYs]; 154 155extern device_hooks gMasterTTYHooks; 156extern device_hooks gSlaveTTYHooks; 157 158extern struct mutex gGlobalTTYLock; 159extern struct mutex gTTYCookieLock; 160extern struct recursive_lock gTTYRequestLock; 161 162 163// functions available for master/slave TTYs 164 165extern int32 get_tty_index(const char *name); 166extern void reset_tty(struct tty *tty, int32 index, mutex* lock, bool isMaster); 167extern void reset_tty_settings(tty_settings *settings, int32 index); 168//extern status_t tty_input_putc(struct tty *tty, int c); 169extern status_t tty_input_read(tty_cookie *cookie, void *buffer, 170 size_t *_length); 171extern status_t tty_output_getc(struct tty *tty, int *_c); 172extern status_t tty_write_to_tty_master(tty_cookie *sourceCookie, 173 const void *buffer, size_t *_length); 174extern status_t tty_write_to_tty_slave(tty_cookie *sourceCookie, 175 const void *buffer, size_t *_length); 176 177extern status_t init_tty_cookie(tty_cookie *cookie, struct tty *tty, 178 struct tty *otherTTY, uint32 openMode); 179extern void uninit_tty_cookie(tty_cookie *cookie); 180extern void add_tty_cookie(tty_cookie *cookie); 181extern void tty_close_cookie(struct tty_cookie *cookie); 182 183extern status_t tty_open(struct tty *tty, tty_service_func func); 184extern status_t tty_close(struct tty *tty); 185extern status_t tty_ioctl(tty_cookie *cookie, uint32 op, void *buffer, 186 size_t length); 187extern status_t tty_select(tty_cookie *cookie, uint8 event, uint32 ref, 188 selectsync *sync); 189extern status_t tty_deselect(tty_cookie *cookie, uint8 event, selectsync *sync); 190 191extern void tty_add_debugger_commands(); 192extern void tty_remove_debugger_commands(); 193 194#endif /* TTY_PRIVATE_H */ 195