xref: /haiku/src/add-ons/kernel/generic/tty/tty_private.h (revision 4c8e85b316c35a9161f5a1c50ad70bc91c83a76f)
1 /*
2  * Copyright 2004-2006, Axel Dörfler, axeld@pinc-software.de.
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 #include <tty/tty_module.h>
13 
14 #include <condition_variable.h>
15 #include <fs/select_sync_pool.h>
16 #include <lock.h>
17 #include <util/DoublyLinkedList.h>
18 
19 #include "line_buffer.h"
20 
21 
22 #define TTY_BUFFER_SIZE 4096
23 
24 // The only nice Rico'ism :)
25 #define CTRL(c)	((c) - 0100)
26 
27 
28 class RequestOwner;
29 class Semaphore;
30 struct tty;
31 struct tty_cookie;
32 
33 class Request : public DoublyLinkedListLinkImpl<Request> {
34 	public:
35 		Request();
36 
37 		void Init(RequestOwner *owner, tty_cookie *cookie, size_t bytesNeeded);
38 
39 		tty_cookie *TTYCookie() const	{ return fCookie; }
40 
41 		void Notify(size_t bytesAvailable);
42 		void NotifyError(status_t error);
43 
44 		bool WasNotified() const		{ return fNotified; }
45 		bool HasError() const			{ return fError; }
46 
47 		void Dump(const char* prefix);
48 
49 	private:
50 		RequestOwner	*fOwner;
51 		tty_cookie		*fCookie;
52 		size_t			fBytesNeeded;
53 		bool			fNotified;
54 		bool			fError;
55 };
56 
57 class RequestQueue {
58 	public:
59 		RequestQueue();
60 		~RequestQueue()	{}
61 
62 		void Add(Request *request);
63 		void Remove(Request *request);
64 
65 		Request *First() const				{ return fRequests.First(); }
66 		bool IsEmpty() const				{ return fRequests.IsEmpty(); }
67 
68 		void NotifyFirst(size_t bytesAvailable);
69 		void NotifyError(status_t error);
70 		void NotifyError(tty_cookie *cookie, status_t error);
71 
72 		void Dump(const char* prefix);
73 
74 	private:
75 		typedef DoublyLinkedList<Request> RequestList;
76 
77 		RequestList	fRequests;
78 };
79 
80 class RequestOwner {
81 	public:
82 		RequestOwner();
83 
84 		void Enqueue(tty_cookie *cookie, RequestQueue *queue1,
85 			RequestQueue *queue2 = NULL);
86 		void Dequeue();
87 
88 		void SetBytesNeeded(size_t bytesNeeded);
89 		size_t BytesNeeded() const	{ return fBytesNeeded; }
90 
91 		status_t Wait(bool interruptable, bigtime_t timeout = B_INFINITE_TIMEOUT);
92 
93 		bool IsFirstInQueues();
94 
95 		void Notify(Request *request);
96 		void NotifyError(Request *request, status_t error);
97 
98 		status_t Error() const	{ return fError; }
99 
100 	private:
101 		ConditionVariable*		fConditionVariable;
102 		tty_cookie*				fCookie;
103 		status_t				fError;
104 		RequestQueue*			fRequestQueues[2];
105 		Request					fRequests[2];
106 		size_t					fBytesNeeded;
107 };
108 
109 
110 struct tty_cookie : DoublyLinkedListLinkImpl<tty_cookie> {
111 	struct tty			*tty;
112 	struct tty			*other_tty;
113 	uint32				open_mode;
114 	int32				thread_count;
115 	sem_id				blocking_semaphore;
116 	bool				closed;
117 };
118 
119 typedef DoublyLinkedList<tty_cookie> TTYCookieList;
120 
121 struct tty_settings {
122 	pid_t				pgrp_id;
123 	pid_t				session_id;
124 	struct termios		termios;
125 	struct winsize		window_size;
126 };
127 
128 struct tty {
129 	int32				ref_count;	// referenced by cookies
130 	int32				open_count;
131 	int32				opened_count;
132 	select_sync_pool*	select_pool;
133 	RequestQueue		reader_queue;
134 	RequestQueue		writer_queue;
135 	TTYCookieList		cookies;
136 	line_buffer			input_buffer;
137 	tty_service_func	service_func;
138 	uint32				pending_eof;
139 	bool				is_master;
140 	recursive_lock*		lock;
141 	tty_settings		settings;
142 	uint8				hardware_bits;
143 };
144 
145 
146 extern struct mutex gTTYCookieLock;
147 extern struct recursive_lock gTTYRequestLock;
148 
149 extern struct tty *tty_create(tty_service_func func, struct tty* masterTTY);
150 extern void tty_destroy(struct tty *tty);
151 
152 extern tty_cookie *tty_create_cookie(struct tty *tty, struct tty *otherTTY,
153 	uint32 openMode);
154 extern void tty_destroy_cookie(tty_cookie *cookie);
155 extern void tty_close_cookie(tty_cookie *cookie);
156 
157 extern status_t tty_read(tty_cookie *cookie, void *buffer, size_t *_length);
158 extern status_t tty_write(tty_cookie *sourceCookie, const void *buffer,
159 	size_t *_length);
160 extern status_t tty_control(tty_cookie *cookie, uint32 op, void *buffer,
161 	size_t length);
162 extern status_t tty_select(tty_cookie *cookie, uint8 event, uint32 ref,
163 	selectsync *sync);
164 extern status_t tty_deselect(tty_cookie *cookie, uint8 event, selectsync *sync);
165 
166 extern status_t tty_input_lock(tty_cookie* cookie, bool lock);
167 extern status_t tty_hardware_signal(tty_cookie* cookie, int signal, bool);
168 
169 #endif	/* TTY_PRIVATE_H */
170