{"id":7411,"date":"2026-02-21T00:01:52","date_gmt":"2026-02-21T08:01:52","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=7411"},"modified":"2026-02-28T10:10:58","modified_gmt":"2026-02-28T18:10:58","slug":"storing-and-interpreting-mouse-input","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=7411","title":{"rendered":"Storing and Interpreting Mouse Input"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2026\/01\/House-mouse-Mus-musculus-shutterstock_321795701-300x167.jpg\" alt=\"\" width=\"300\" height=\"167\" class=\"alignnone size-medium wp-image-7374\" srcset=\"https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2026\/01\/House-mouse-Mus-musculus-shutterstock_321795701-300x167.jpg 300w, https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2026\/01\/House-mouse-Mus-musculus-shutterstock_321795701-1024x569.jpg 1024w, https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2026\/01\/House-mouse-Mus-musculus-shutterstock_321795701-768x427.jpg 768w, https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2026\/01\/House-mouse-Mus-musculus-shutterstock_321795701-1536x853.jpg 1536w, https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2026\/01\/House-mouse-Mus-musculus-shutterstock_321795701-500x278.jpg 500w, https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2026\/01\/House-mouse-Mus-musculus-shutterstock_321795701.jpg 2000w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><br \/>\nSpewing data all over the screen might look impressive, as shown in <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7397\">last week&#8217;s Lesson<\/a>, but the point of knowing where the mouse is and what it&#8217;s doing is to capture its data and make it available to your program for interpretation.<br \/>\n<!--more--><br \/>\nThe goal is to extract relevant values from the mouse input and place it into a useful format. For me, this format is a structure containing the mouse&#8217;s location and button status. Something like this:<\/p>\n<p><code>struct mouse_data {<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;int button;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;int column;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;int row;<br \/>\n};<\/code><\/p>\n<p>The three members of the <em>mouse_data<\/em> structure represent the three integer values generated by ANSI mouse input escape sequences: the button press and the row\/column values for the mouse&#8217;s location. To obtain this data, the ANSI escape sequence string must be captured and interpreted.<\/p>\n<p>In the following code, the <em>read_mouse()<\/em> function is passed the address of a <em>mouse_data<\/em> structure and an ANSI escape string. The <em>extract()<\/em> function pulls the relevant integer data from the string, storing the proper values in the <em>mouse_data<\/em> structure. Coding this function is the topic for <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7365\">this month&#8217;s Exercise<\/a>.<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2026_02_21-Lesson.c\" rel=\"noopener\" target=\"_blank\">2026_02_21-Lesson.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;ctype.h&gt;\r\n#include &lt;termios.h&gt;\r\n#include &lt;unistd.h&gt;\r\n\r\n#define mouse_enable() printf(\"\\e[?1000h\")\r\n#define mouse_extended() printf(\"\\e[?1006h\")\r\n#define mouse_motion() printf(\"\\e[?1003h\")\r\n#define mouse_disable() printf(\"\\e[?1000l\")\r\n\r\nstruct mouse_data {\r\n    int button;\r\n    int column;\r\n    int row;\r\n};\r\n\r\n<span class=\"comments\">\/* read an integer from a string\r\n   Exercise 2026_02 *\/<\/span>\r\nchar *extract(char *s)\r\n{\r\n    static char *sp;\r\n\r\n    <span class=\"comments\">\/* check for recall *\/<\/span>\r\n    if( s != NULL )\r\n        sp = s;\r\n    else\r\n        while( isdigit(*sp) )\r\n            sp++;\r\n\r\n    <span class=\"comments\">\/* find the next digit *\/<\/span>\r\n    while( *sp != '\\0' )\r\n    {\r\n        if( isdigit(*sp) )\r\n        {\r\n            return(sp);\r\n        }\r\n        sp++;\r\n    }\r\n\r\n    return(NULL);\r\n}\r\n\r\n<span class=\"comments\">\/* obtain values from mouse data *\/<\/span>\r\nvoid read_mouse(char *b, struct mouse_data *m)\r\n{\r\n    m-&gt;button = atoi(extract(b));\r\n    m-&gt;column = atoi(extract(NULL));\r\n    m-&gt;row = atoi(extract(NULL));\r\n}\r\n\r\nint main()\r\n{\r\n    struct termios original,noecho;\r\n    struct mouse_data mickey;\r\n    char buffer[13];\r\n    int key;\r\n\r\n    <span class=\"comments\">\/* obtain terminal configuration *\/<\/span>\r\n    tcgetattr(fileno(stdin),&amp;original);\r\n    noecho = original;        <span class=\"comments\">\/* duplicate *\/<\/span>\r\n        <span class=\"comments\">\/* enable raw input *\/<\/span>\r\n    noecho.c_lflag = noecho.c_lflag ^ ICANON;\r\n        <span class=\"comments\">\/* disable full duplex *\/<\/span>\r\n    noecho.c_lflag = noecho.c_lflag ^ ECHO;\r\n        <span class=\"comments\">\/* update terminal definition *\/<\/span>\r\n    tcsetattr(fileno(stdin), TCSANOW, &amp;noecho);\r\n\r\n    <span class=\"comments\">\/* enable mouse reporting *\/<\/span>\r\n    mouse_enable();\r\n    mouse_motion();\r\n    mouse_extended();\r\n    <span class=\"comments\">\/* remove line buffering *\/<\/span>\r\n    setvbuf(stdin,NULL,_IONBF,0);\r\n\r\n    <span class=\"comments\">\/* read stdin *\/<\/span>\r\n    puts(\"Play with the mouse; press Enter to end\");\r\n    while( (key=getchar()) != '\\n' )\r\n    {\r\n        read(fileno(stdin),buffer,12);\r\n        buffer[12] = '\\0';        <span class=\"comments\">\/* make it a string *\/<\/span>\r\n        read_mouse(buffer,&amp;mickey);\r\n        printf(\"Button %2d Column %2d Row %2d\\n\",\r\n                mickey.button,\r\n                mickey.column,\r\n                mickey.row\r\n              );\r\n    }\r\n\r\n    <span class=\"comments\">\/* clean-up *\/<\/span>\r\n    mouse_disable();    <span class=\"comments\">\/* disable mouse reporting *\/<\/span>\r\n    tcsetattr(fileno(stdin), TCSANOW, &amp;original);\r\n    return 0;\r\n}<\/pre>\n<p>The code starts with the four ANSI mouse macros as described earlier in this series.<\/p>\n<p>Next comes the <code>mouse_data<\/code> structure definition. This structure must be defined globally as it&#8217;s used in several functions in the source code file.<\/p>\n<p>The <em>extract(<\/em>) function is lifted from <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7385\">this month&#8217;s Exercise solution<\/a>.<\/p>\n<p>The <em>read_mouse()<\/em> function fills a <em>mouse_data<\/em> structure with the proper values read from standard input. The structure is passed as a pointer (address), so the <code>-&gt;<\/code> operator is used to fill values in the structure.<\/p>\n<p>Differences between the <em>main()<\/em> function in this code and what was shown in last week&#8217;s Lesson are first found in the buffer definition. It&#8217;s one byte larger. The reason is that this buffer must now hold a string for proper examination by the extract() function.<\/p>\n<p>I&#8217;ve also modified the <em>while<\/em> loop: The buffer is capped with a null character to make it a string:<\/p>\n<p><code>buffer[12] = '\\0';<\/code><\/p>\n<p>Then the characters captured in <code>buffer<\/code> are passed to the <em>read_mouse()<\/em> function, along with the address of a <em>mouse_data<\/em> structure, <code>mickey<\/code>. A <em>printf()<\/em> statement outputs the data.<\/p>\n<p>Here&#8217;s a sample run:<\/p>\n<pre>Play with the mouse; press Enter to end\r\nButton 35 Column 57 Row 16\r\nButton 35 Column 58 Row 16\r\nButton  0 Column 58 Row 16\r\nButton  0 Column 58 Row 16\r\nButton 35 Column 58 Row 16\r\nButton  2 Column 58 Row 16\r\nButton  2 Column 58 Row 16\r\nButton 35 Column 58 Row 16\r\nButton 35 Column 59 Row 16\r\nButton 35 Column 60 Row 16\r\nButton 35 Column 61 Row 17\r\nButton 35 Column 62 Row 17\r\nButton 35 Column 63 Row 17<\/pre>\n<p>Button zero is the left mouse button; 2 is the right mouse button. &#8220;Button 35&#8221; means that the mouse is moving; no button is pressed.<\/p>\n<p>Remember: If mouse input isn&#8217;t disabled after the program quits, use the <em>reset<\/em> command in the terminal window.<\/p>\n<p>For <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7419\">next week&#8217;s Lesson<\/a>, I update the code so that text is output at the location where the mouse button is pressed.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Mouse input must be captured, stored, and read for a program to make use of the mouse data. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7411\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-7411","post","type-post","status-publish","format-standard","hentry","category-main"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7411","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=7411"}],"version-history":[{"count":4,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7411\/revisions"}],"predecessor-version":[{"id":7449,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7411\/revisions\/7449"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7411"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7411"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7411"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}